Игровая 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 c кучей опциональных данных, если возле типа ? значит может отсутствовать.
Имена классов и типы не приходят - они просто для иллюстрации.
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; // login игрока ?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.