Table of Contents

Encrypted Game Information (Task API)

Why?

If you need to pass some information about the game during the game to third-party services (Telegram bots, third-party scripts, custom auth setups etc.), it is recommended to use the generation of an encrypted string. In this case, even tech-savvy players will not be able to see what information is being passed or modify it themselves (which is especially relevant for long formats).

How?

Key Generation

You need to create a key in the game. To do this, click the “Generate” button in the game editor under the API for external websites/Telegram bots” section. This will create a key (e.g. XgHxzCvUSXwPfR7wBvdY4xHC6tSFLewx).

Use in Tasks

In tasks and game descriptions, you can use the construction:

!api:data!

The data fields needed by the external server are specified separated by commas:

Example

To get an encrypted string in the game:

!api:user_id,task_id!

This will generate the encrypted hex-string:

0394334e96a2f0fa738470e9a9778c684ba214990d200eab

which can be decrypted on your server using the game key and Blowfish (ECB mode) into:

{"u": 162862, "tid": 42719}

Example task in game

Decryption

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)

Python

*(Requires blowfish library: pip install blowfish)*

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)
 
# Usage
data = '0394334e96a2f0fa738470e9a9778c684ba214990d200eab'
key = 'XgHxzCvUSXwPfR7wBvdY4xHC6tSFLewx'
print(decrypt_qeng_data(data, key)) # => {'u': 162862, 'tid': 42719}

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
 
# Usage
data = '0394334e96a2f0fa738470e9a9778c684ba214990d200eab'
key = 'XgHxzCvUSXwPfR7wBvdY4xHC6tSFLewx'
puts qeng_data_decrypt(data, key) # => {:u=>162862, :tid=>42719}