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