Show pageOld revisionsBacklinksBack to top This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. {{indexmenu_n>40}} ====== Зашифрованная информация об игре (Task API) ====== ===== Зачем это нужно? ===== Если вам необходимо безопасно передать данные о текущем игроке или команде во время игры сторонним внешним сервисам (например, Telegram-боту, скрипту авторизации или кастомному сайту с флеш-игрой), используйте генерацию зашифрованной строки. В этом случае технически подкованные игроки не смогут увидеть, какие именно данные передаются в URL или параметрах скрипта, и не смогут подделать их самостоятельно. Это особенно критично на играх длинного формата (Long). ===== Как это настроить? ===== ==== 1. Генерация секретного ключа ==== * Перейдите в редактор вашей игры. * Найдите раздел **"API для внешних сайтов / телеграм ботов"**. * Нажмите кнопку **"Сгенерировать"**. Движок создаст уникальный ключ (например, ''XgHxzCvUSXwPfR7wBvdY4xHC6tSFLewx''). ==== 2. Использование плейсхолдера в задании ==== В тексте задания, подсказки или в параметрах ссылки на внешний сервис пропишите конструкцию вида: <code> !api:поле1,поле2! </code> Доступные поля для шифрования (указываются через запятую): * **''user_id''** — ID игрока. В расшифрованном JSON преобразуется в ключ **''u''**. * **''user_name''** — логин игрока. В JSON — **''un''**. * **''team_id''** — ID команды. В JSON — **''tm''**. * **''team_name''** — название команды. В JSON — **''tmn''**. * **''task_n''** — порядковый номер текущего уровня. В JSON — **''t''**. * **''task_id''** — ID текущего уровня. В JSON — **''tid''**. * **''game_id''** — ID игры. В JSON — **''gid''**. ==== Пример генерации ==== Если вы пропишете в задании: <code> !api:user_id,task_id! </code> Движок сгенерирует зашифрованную hex-строку вида: <code> 0394334e96a2f0fa738470e9a9778c684ba214990d200eab </code> Ее можно расшифровать на вашем сервере с помощью ключа игры и алгоритма Blowfish (ECB). В результате вы получите JSON: <code> {"u": 162862, "tid": 42719} </code> [[https://qeng.org/game.php?jump_to&gid=3493&task_id=42719|Пример задания в игре]] ===== Примеры расшифровки на сервере ===== ==== PHP ==== <code PHP> $data = '0394334e96a2f0fa738470e9a9778c684ba214990d200eab'; $key = 'XgHxzCvUSXwPfR7wBvdY4xHC6tSFLewx'; $decoded = json_decode( trim( openssl_decrypt( hex2bin($data), 'BF-ECB', $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING ) ), true ); // $decoded => array('u' => 162862, 'tid' => 42719) </code> ==== Python ==== *(Требуется библиотека blowfish: ''pip install blowfish'')* <code Python> import binascii import json import typing import blowfish def decrypt_qeng_data(data: str, key: str) -> typing.Dict[str, typing.Union[str, int]]: data_bytes = binascii.unhexlify(data) cipher = blowfish.Cipher(key.encode()) data_decrypted = b"".join(cipher.decrypt_ecb(data_bytes)) data_decrypted = data_decrypted.rstrip(b'\x00') return json.loads(data_decrypted) # Использование data = '0394334e96a2f0fa738470e9a9778c684ba214990d200eab' key = 'XgHxzCvUSXwPfR7wBvdY4xHC6tSFLewx' print(decrypt_qeng_data(data, key)) # => {'u': 162862, 'tid': 42719} </code> ==== Ruby ==== <code Ruby> require 'json' require 'openssl' module Blowfish def self.decrypt(data, key) crypto = OpenSSL::Cipher::Cipher.new('bf-ecb').send(:decrypt) crypto.key_len = key.length crypto.key = key crypto.padding = 0 crypto.update([data].pack("H*")) << crypto.final end end def qeng_data_decrypt(data, key) decrypted_text = Blowfish.decrypt(data, key) JSON.parse(decrypted_text, symbolize_names: true) end # Использование data = '0394334e96a2f0fa738470e9a9778c684ba214990d200eab' key = 'XgHxzCvUSXwPfR7wBvdY4xHC6tSFLewx' puts qeng_data_decrypt(data, key) # => {:u=>162862, :tid=>42719} </code> authors_main/task_editor/advanced/api_main.txt Last modified: 2026/06/15 20:57(external edit)