{{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 із різними даними, зокрема опціональними (якщо тип зазначений із "?" - може бути відсутній).
**Імена класів та типи не приходять - вони просто для ілюстрації.**
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; // Перелік кодів, які може відкрити підказка
}
==== Варіанти помилок ====
В **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:
class PublicAutoUpdateResult {
?string error; // Помилка
?bool refresh; // Треба оновити сторінку, хтось вбив правильний код або взяв штрафну підказку
?bool reload; // Хтось пройшов рівень
?bool refersh_monitoring; // Є нові неправильні відповіді в моніторингу. Можна їх завантажити, якщо потрібно.
?int next_check_ms; // Скільки чекати (в мілісекундах) до наступної перевірки - вираховується сервером в залежності від навантаження.
}
Якщо в JSON є поля refresh, reload або refersh_monitoring, то за допомогою **game.php** оновлюємо сторінку.
==== Не оптимально ====
За допомогою **game.php** регулярно завантажуємо нову версію.
**В цьому випадку період, з яким ви смикаєте сервер, беріть як refresh_check_limit_ms, помножений на 3.**