Различия
Здесь показаны различия между двумя версиями данной страницы.
— |
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.** | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||