{{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 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.**