ua:api_engine_main

Различия

Здесь показаны различия между двумя версиями данной страницы.

Ссылка на это сравнение

ua:api_engine_main [2023/04/17 04:37] (текущий)
sparklingsky создано
Строка 1: Строка 1:
 +{{indexmenu_n>​30}}
 +===== Ігрова API =====
 +Ігрова API - це API для написання своєї версії фронтенду або взаємодії з інформацією про гру зсередини гри.
 +
 +Можна використовувати для телеграм-ботів,​ нативних застосунків або браузерних розширень.
 +
 +===== Точки входу =====
 +
 +Всі дії виконуються через дві точки входу:
 +
 +**game.php** - авторизація,​ отримання завдань,​ відправка відповідей,​ розблокування штрафних підказок;​
 +
 +**game_au.php** - перевірка,​ чи є нові дії від інших гравців,​ які слід відобразити. Наприклад,​ хтось вбив правильну відповідь.
 +
 +**В усі запити слід додавати GET параметр JSON. Тоді результат буде приходити у форматі JSON.**
 +
 +===== Авторизація =====
 +
 +Використовується **login.php** ​
 +
 +**POST параметри:​**
 +
 +**user** - логін гравця;​
 +
 +**pass** - пароль гравця.
 +
 +Необхідно зберегти cookie та всі їх передавати в подальші запити.
 +
 +Якщо у відповіді буде рядок із іменем **login_error** - отже, авторизація не відбулась.
 +
 +===== Дані завдання =====
 +
 +Використовується **game.php** ​
 +
 +**GET параметри:​**
 +
 +**gid** - ID гри
 +
 +**tid** - [опціонально] ID рівня ​
 +
 +У відповідь надходить JSON в utf-8 із різними даними,​ зокрема опціональними (якщо тип зазначений із "?"​ - може бути відсутній).
 +
 +**Імена класів та типи не приходять - вони просто для ілюстрації.**
 +
 +<​code>​
 +class PublicContext {
 +  int version = 1;                        // Версія протоколу
 +  ?string error   ; ​                      // Помилка
 +  ?string login_error; ​                   // Помилка при логіні
 +
 +  string domain_time_zone; ​               // Часова зона поточного домену
 +  ?int game_id; ​                          // ID гри
 +  ?int task_id; ​                          // ID поточного рівня
 +  ?int user_id; ​                          // ID залогіненого гравця
 +  ?string user_name; ​                     // Логін гравця
 +  ?int team_id; ​                          // ID команди гравця,​ в одиночних іграх може співпадати із ID поточного гравця
 +  ?int refresh_time_ms; ​                  // Час останнього оновлення сторінки,​ unix_time в мілісекундах ​
 +  ?int refresh_check_limit_ms; ​           // Проміжок часу в мілісекундах,​ протягом якого не слід без причини смикати сервер
 +
 +  PublicGame game;                        // Дані про гру
 +  /​*?​PublicGamep[]*/​ available_games; ​    // Дані про активні/​найближчі ігри домену;​ доступно,​ якщо робити запит без gid
 +  ​
 +  PublicTask task;                        // Дані про поточне завданння
 +  PublicLastAnswers last_answers; ​        // Моніторинг нещодавно введених відповідей
 +  ?​PublicAnswerResult answer_result; ​     // Результат останнього введення відповідей
 +  ?​PublicAnswerForm answer_form; ​         // Дані про форму відповідей
 +  /* ?[n => PublicCode] */ codes; ​        // Дані про коди
 +  /* ?​PublicHint[] */ hints; ​             // Підказки
 +  ?int n_bonuses; ​                        // Загальна кількість бонусів,​ якщо вони є у завданні
 +  ?int compact_n_bonuses; ​                // Загальна кількість бонусів,​ якщо автор обрав компактний режим бонусів
 +  ?int compact_bonus; ​                    // Сумарний отриманий бонус/​штраф,​ якщо автор обрав компактний режим бонусів
 +  /* ?string[] */ compact_bonus_answers; ​ // Відомі відповіді на бонуси,​ якщо автор обрав компактний режим бонусів ​
 +  /* ?string[] */ compact_bonus_hints; ​   // Підказки на введені бонуси,​ якщо автор обрав компактний режим бонусів
 +  /* ? PublicBonus[] */ bonuses; ​         // Бонуси
 +  /* ? PublicBonus[] */ global_bonuses; ​  // Наскрізні бонуси
 +  /* ?​PublicTaskButton[] */ active_tasks;​ // Доступні наразі завдання
 +  /* ?​PublicTaskButton[] */ closed_tasks;​ // Вже закриті завдання - тільки у штурмі
 +}
 +
 +class PublicGame {
 +  int id;         // ID гри
 +  string name;    // Назва гри
 +  int start_time; // Час старту гри в unix_time
 +  int end_time; ​  // Час закінчення гри в unix_time
 +  ?int type;      // Тип гри: 0 або відсутній - штурмова послідовність,​ 1 - лінійна послідовність
 +  ?bool single; ​  // Одиночна або командна гра ​
 + }
 +
 +class PublicTask {
 +
 +  int n;                 // Номер завдання ​
 +  string name;           // Назва завдання
 +  ?string task;          // Текст завдання
 +  ?string answer_format;​ // Формат відповіді
 +  ?int n_codes; ​         // Скільки всього кодів у завданні
 +  ?int need_n_codes; ​    // Скільки потрібно кодів для проходження завдання
 +  ?int start_time_ms; ​   // Час початку завдання в unix_time мілісекундах ​
 +  ?int time_left_ms; ​    // Скільки лишилось часу в мілісекундах до автопереходу
 +  ?int delay_left_ms; ​   // Затримка в мілісекундах до появи завдання
 +  int is_complete; ​      // Завдання вже закінчено
 +
 +}
 +
 +class PublicLastAnswers {
 +  /* ?​PublicLastAnswer[] */ answers; // Масив з інформацією про відповіді
 +  int last_update_ms; ​               // Час останнього оновлення в unix_time мілісекундах
 +}
 +
 +class PublicLastAnswer {
 +  int time_ms; ​   // Час у unix_time мілісекундах,​ коли відправлено відповідь
 +  ?string user;   // Хто ввів відповідь,​ в одиночних іграх відсутній
 +  string answers; // Введені відповіді через кому
 +  string type;    // Одне зі значень:​ right, wrong, repeat - правильно,​ але вже було, nonsubmit - не прийнято через блокування
 +  ?string bonus; ​ // Отриманий бонус або штраф за відповіді
 +}
 +
 +class PublicAnswerResult {
 +
 +  int task_id; ​                            // ID рівня, для якого пораховано: ​
 +  /* ?strings[] */ right_answers = [];     // правильні відповіді
 +  /* ?strings[] */ wrong_answers = [];     // неправильні
 +  /* ?strings[] */ repeat_answers = [];    // правильні,​ але повторні
 +  /* ?strings[] */ nonsubmit_answers = []; // не прийняті через блокування
 +  ?string bonus = ''; ​                     // Бонус, отриманий за відповіді
 +  ?string penalty = ''; ​                   // Штраф, отриманий за відповіді
 +}
 +
 +class PublicAnswerForm {
 +
 +  public bool show_finish_task = false; // Чи потрібно показувати кнопку,​ яка закриває завдання. Якщо потрібно,​ то завдання можна закрити,​ відправивши код !finish!
 +  bool hide_answer_form = false; ​       // Відповіді більше не прийматимуться,​ можна прибрати поле вводу
 +  ?int block_time_left_ms; ​             // Скільки часу лишилось до зняття обмеження на введення. Час у мілісекундах. Якщо penalty не 0, отже, відповіді можна вводити,​ але зі штрафом за неправильні.
 +  ?int limit_n_answers; ​                // Обмеження на кількість неправильних відповідей. Константа - як задана автором. ​
 +  ?int time_limit; ​                     // Час у секундах. За який проміжок часу враховується обмеження на кількість відповідей limit_n_answers. Якщо 0, то limit_n_answers - обмеження на весь рівень.
 +  ?int penalty; ​                        // Штраф за кожну неправильну відповідь понад дозволеного.
 +  ?int n_answers_left; ​                 // Скільки відповідей команда може вбити до того, як почне діяти обмеження. Міняється після кожного введення відповідей. Якщо 0 - обмеження активне.
 +
 +}
 +
 +class PublicCode {
 +
 +  ?string name;      // Назва коду
 +  ?string answer; ​   // Відповідь на код
 +  ?string user_name; // Хто вбив перший
 +  ?int user_id; ​     // Хто вбив перший
 +  ?int answered_ms; ​ // Коли вбив перший
 +}
 +
 +class PublicBonus {
 +
 +  ?int n;               // Номер бонусу
 +  ?int bonus; ​          // Отримуваний бонус або штраф, якщо значення відʼємне. В секундах або балах. ​
 +  ?string answer; ​      // Відповідь на бонус
 +  ?string description; ​ // Опис бонусу (загадка)
 +  ?string hint;         // Підказка,​ якщо бонус вирішено
 +  ?int time_to_open_ms;​ // Час у мілісекундах до відкриття бонусу
 +  ?int time_to_close_ms;//​ Час у мілісекундах до закриття бонусу
 +  ?bool is_closed; ​     // Час на введення бонусу вичерпаний - більше для введення відповідей він не доступний ​
 +  ?string user_name; ​   // Хто вбив перший
 +  ?int user_id; ​        // Хто вбив перший
 +  ?int answered_ms; ​    // Коли вбив перший
 +
 +}
 +
 +class PublicHint {
 +
 +  int n;                // Номер підказки
 +  ?int time_to_open_ms;​ // Час у мілісекундах до відкриття підказки
 +  ?int id;              // ID штрафної підказки - необхідно для її використання
 +  ?string description; ​ // Опис підказки
 +  ?string hint;         // Текст підказки
 +  ?int penalty; ​        // Штраф за штрафну підказку
 +  ?int any_code; ​       // Якщо є, означає,​ що підказка може відкрити будь-який код
 +  /*int[]*/ codes; ​     // Перелік кодів, які може відкрити підказка
 +
 +}
 +</​code>​
 +
 +==== Варіанти помилок ====
 +В **error** можуть прийти такі помилки:​
 +  * NO_GAME_ID - не вказаний gid
 +  * NO_GAME - неправильний gid
 +  * NO_USER - необхідно залогінитись
 +  * NO_TEAM - командна гра, а гравець не в команді
 +  * TEAM_NO_ANONYMOUS - анонімний гравець не може грати в ігри з обмеженням складу команди
 +  * TEAM_TOO_BIG - у команді більше гравців,​ ніж обмеження складу
 +  * TEAM_GAME_NOT_REQUESTED - команда не подала заявку
 +  * TEAM_GAME_NOT_ACCECPTED - команда не прийнята у гру
 +  * GAME_NOT_STARTED - гра ще не почалась
 +  * GAME_FINISHED - гра закінчилась
 +  * SEQUENCE_ERROR - помилка в призначеній автором послідовності рівнів
 +
 +
 +
 +===== Відправка відповідей =====
 +
 +Використовується **game.php** ​
 +
 +**GET параметри:​**
 +
 +**gid** - ID гри;
 +
 +**tid** - ID рівня, в який треба ввести відповідь (якщо не зазначати,​ то є ризик вбити відповідь з минулого рівня у рівень з обмеженням на введення); ​
 +
 +**a** - відповіді,​ які треба ввести,​ через кому.
 +
 +===== Взяття штрафних підказок =====
 +
 +Використовується **game.php** ​
 +
 +GET параметри:​
 +
 +**gid** - ID гри;
 +
 +**hint_id** - ID підказки,​ яку треба розблокувати;​
 +
 +**hint_code** - [опціонально] номер коду, який треба відкрити штрафною підказкою.
 +
 +===== Оновлення сторінки =====
 +
 +Використовуються **game_au.php**,​ **game.php**
 +
 +Якщо гра командна,​ то у відповіді на **game.php** приходитиме **refresh_check_limit_ms.**
 +
 +Це час у мілісекундах,​ після якого можна перевіряти,​ чи є зміни в движку від дій співкомандників.
 +
 +Якщо смикати сервер частіше,​ то є ризик отримати бан по IP на певний час.
 +
 +**refresh_check_limit_ms** - не константа і може мінятись у залежності від навантаження на сервер.
 +
 +Якщо будь-який із таймерів у грі закінчується раніше,​ ніж **refresh_check_limit_ms**,​ то слід оновити сторінку за допомогою **game.php**. При цьому **refresh_check_limit_ms** ​ можна проігнорувати.
 +
 +==== Оптимально ====
 +
 +За допомогою **game_au.php** перевіряємо,​ чи треба оновлювати сторінку.
 +
 +GET параметри:​
 +
 +**gid** - ID гри; ​
 +
 +**tid** - ID завдання; ​
 +
 +**time** - час, отриманий у **refresh_time** з відповіді **game.php**. ​
 +
 +У відповідь прийде JSON:
 +<​code>​
 +class PublicAutoUpdateResult {
 +  ?string error; ​           // Помилка
 +  ?bool refresh; ​           // Треба оновити сторінку,​ хтось вбив правильний код або взяв штрафну підказку
 +  ?bool reload; ​            // Хтось пройшов рівень
 +  ?bool refersh_monitoring;​ // Є нові неправильні відповіді в моніторингу. Можна їх завантажити,​ якщо потрібно.
 +  ?int next_check_ms; ​      // Скільки чекати (в мілісекундах) до наступної перевірки - вираховується сервером в залежності від навантаження.
 +}
 +</​code>​
 +
 +Якщо в JSON є поля refresh, reload або refersh_monitoring,​ то за допомогою **game.php** ​ оновлюємо сторінку.
 +
 +==== Не оптимально ====
 +
 +За допомогою **game.php** регулярно завантажуємо нову версію.
 +
 +**В цьому випадку період,​ з яким ви смикаєте сервер,​ беріть як refresh_check_limit_ms,​ помножений на 3.**
 +
 +
 +
 +
 +
 +
  
  • ua/api_engine_main.txt
  • Последние изменения: 2023/04/17 04:37
  • sparklingsky