Протокол обмена данными, версия 1

Протокол используется как для web-приложения, так и для отдельных клиентов. Запрос к серверу — обычный POST-запрос в кодировке UTF-8. Ответ сервера — объект, сериализованный в JSON.

Для идентификации пользователя используется идентификатор сессии. Отдельные клиенты получают сессию при авторизации. В случае с web-клиентом код сессии может внедряться в код клиента — в этом случае он не должен совпадать с кодом обычной сессии, хранящейся в куках, что служит защитой от CSRF-атак.

Версия протокола, разумеется, не последняя, в будущем наверняка появятся новые. Чтобы упростить жизнь игрокам и разработчикам клиентов, сервер, реализующий протокола версии N, обязан поддерживать работу с клиентами, реализущими версию N-1. Также желательно поддерживать и более ранние версии.

Новый сервер совместим с клиентом, использующим старую версию протокола, если:

  • сервер автоматически определяет, какую версию протокола использует клиент, и использует ту же (либо совместимую) версию;
  • либо новая версия протокола совместима со старой.

Две версии протокола совместимы, если в новой версии имеются только следующие отличия от старой:

  • добавлены новые типы запросов, использование которых не требуется;
  • в существующие типы запросов добавлены необязательные поля (или элементы полей), использование которых не требуется;
  • для полей в существующих типах запросов добавлены новые типы или возможные значения, использование которых не требуется;
  • добавлены новые типы ответов, которые могут быть выданы только на новые типы запросов;
  • в существующие типы ответов добавлены новые поля, которые клиент может игнорировать;
  • добавлены новые коды ошибок (ответ «nack»).

Для совместимости клиенты должны выполнять следующие требования:

  • клиент должен игнорировать все неизвестные ему поля ответов;
  • клиент не должен полагаться на код ошибки (поле «ErrorCode») или ее текст (поле «Error»).

Стандартные типы полей

Тип в JavaScriptТип в POST-запросе
nullпустая строка
boolean«0» (ложь) или «1» (истина)
numberстроковое представление числа
stringстрока

В случае с массивами и объектами генерируется отдельное поле запроса для каждого скалярного элемента или поля всех уровней вложенности. Имя такого поля имеет форму имя_объекта[ключ_или_индекс1][ключ_или_индекс2]… Например, год[2012][декабрь][21].

Для задания времени используется число, представляющее метку времени UNIX.

Нестандартные типы

FightList — список боев

Массив, отсортированный по убыванию времени окончания боя. Формат элемента:

КлючЗначение
FightIdидентификатор боя
FightTypeтип боя: «train» (тренировочный) или «challenge» (рейтинговый)
FightTimeвремя окончания боя
TurnLimitлимит ходов на бой
TurnCountдлительность боя
PlayerIdидентификатор игрока, «заказавшего» бой
PlayerNameимя игрока, «заказавшего» бой
Snakesсписок из 4 змей (null для отсутствующих), участвующих в бою; см. поле Snakes

Maps — карты программы

Массив, содержащий от 1 до 9 карт программы. Карта представлена в виде объекта:

ПолеОписание
Descriptionтекстовое описание карты
HeadXкоордината x головы своей змеи (0 – 6)
HeadYкоордината y головы своей змеи (0 – 6)
Linesмассив из описаний строк карты

Голова змеи всегда смотрит вверх. Описание строк карты является объектом:

ПолеОписание
Xкоордината x начала линии (0 – 6)
Yкоордината y начала линии (0 – 6)
Lineописание линии карты

Линия карты длиной n клеток задается строкой из 2×n символов. Первый символ пары задает набор элементов:

СимволЗначение
- шаблон не определен либо в данной клетке находится голова своей змеи
A – D пользовательские наборы элементов 1 – 4
S тело змеи игрока
T хвост змеи игрока
V пустая клетка
W граница поля
X голова змеи противника
Y тело змеи противника
Z хвост змеи противника

Соответствующие символы в нижнем регистре обозначают инвертированные наборы элементов; так, например, символ «t» означает «все, кроме хвоста своей змеи». Второй символ пары задает группу, к которой принадлежит шаблон:

СимволЗначение
- шаблон не определен либо в данной клетке находится голова своей змеи
0 – 3 И-группа 1 – 4
4 – 7 ИЛИ-группа 1 – 4

Строка описывает часть линии карты слева направо с координаты (X; Y). Если длина строки слишком велика, то остаток строки переносится на следующую линию с координаты (0; Y + 1). Например, объект {X: 6, Y: 2, Line: «A1B2C3»} описывает клетки с координатами (6; 2), (0; 3), (1; 3). «Переполнение» последней линии карты является ошибкой.

PlayerList — список игроков

Массив. Формат элемента:

КлючЗначение
PlayerIdидентификатор игрока
PlayerNameимя игрока
Ratingтекущий рейтинг; null, если не участвует

PlayerSnakes — список змей игрока

Массив. Формат элемента:

КлючЗначение
SnakeIdидентификатор змеи
SnakeNameимя змеи
SnakeTypeтип змеи: «B» (бот) или «N» (обычная)
SkinIdидентификатор окраски

Ratings — таблица рейтингов

Массив. Формат элемента:

КлючЗначение
PlayerIdидентификатор игрока
PlayerNameимя игрока
Ratingтекущий рейтинг игрока
SnakeIdидентификатор бойца
SnakeNameимя бойца
SkinIdидентификатор окраски бойца

SkinList — список окрасок змей

Массив, осортирован по названию окраски. Формат элемента:

КлючЗначение
SkinIdидентификатор окраски
SkinNameназвание окраски

SlotList — список сохраненных боев

Массив из 10 элементов, null для отсутствующих. Формат элемента:

КлючЗначение
SlotNameимя сохраненного боя
FightIdидентификатор боя
FightTypeтип боя
FightTimeвремя окончания боя

SnakeList — список змей

Массив. Формат элемента:

КлючЗначение
SnakeIdидентификатор змеи
SnakeNameимя змеи
SnakeTypeтип змеи: «B» (бот) или «N» (обычная)
SkinIdидентификатор окраски
PlayerIdидентификатор владельца
PlayerNameимя владельца

Snakes — информация о змеях, участвующих в бою

Массив из 4 элементов, содержащих описания змей, null для отсутствующих. Элемент является объектом:

КлючЗначение
SnakeIdидентификатор змеи, null для временной
SnakeNameимя змеи
SnakeTypeтип змеи: «B» (бот) или «N» (обычная)
SkinIdидентификатор окраски
PlayerIdидентификатор владельца
PlayerNameимя владельца

SnakeStats — результаты боя для каждой змеи

Массив из 4 элементов, содержащих информацию о змеях, участвовавших в бою, null для отсутствующих. Элемент является объектом:

КлючЗначение
Statusсостояние змеи на последнем ходу боя:
«free»змея сделала шаг
«blocked»не смогла сделать шаг (заблокирована)
«eaten»змея съедена
FinalLengthитоговая длина змеи
InitialRatingрейтинг владельца перед началом боя; отсутствует для тренировочных боев
FinalRatingрейтинг владельца по итогам боя; отсутствует для тренировочных боев
ProgramDescriptionописание программы (отсутствует для чужих обычных змей)
Templatesпользовательские шаблоны (отсутствует для чужих обычных змей); см. Templates
Mapsкарты программы (отсутствует для чужих обычных змей); см. Maps
DebugDataотладочная информация (отсутствует для чужих обычных змей)

DebugData является строкой, кодирующей последовательность решений змеи на каждом ходу. Каждый символ кодирует число в диапазоне 1 – 79, равное ASCII-коду символа минус 32 («!» – «o»). Число состоит из двух или трех полей:

Если используется карта:

БитыОписание
0 – 1ориентация карты:
0 оригинал
1 по часовой стрелке
2 перевернута
3 против часовой стрелки
2 отражение карты по вертикальной оси оригинала (0: нет, 1: есть)
3 – 6номер карты (1 – 9)

Если карта не используется:

БитыОписание
0 – 1причина:
1 нет возможных ходов, пропуск хода
2 только один возможный ход
3 нет подходящей карты
2 – 60

В случае, если отладочная информация для змеи недоступна (чужая обычная змея или в бою участвуют меньше 4 змей), то соответствующий элемент массива содержит null.

Templates — пользовательские шаблоны

Массив из 4 строк длиной от 1 до 6 различных символов. Каждая строка задает пользовательский набор элементов. Элементы кодируются следующими символами:

СимволЗначение
S тело змеи игрока
T хвост змеи игрока
V пустая клетка
W граница поля
X голова змеи противника
Y тело змеи противника
Z хвост змеи противника

Другие символы недопустимы. Порядок символов не имеет значения.

Turns — запись ходов

Массив из 1 – 1000 чисел, кодирующих очередность и направления шагов. Формат:

БитыЗначение
0 – 1 первый номер змеи (0 – 3)
2 – 3 второй номер змеи (0 – 3)
4 – 5 третий номер змеи (0 – 3)
6 – 7 направление движения первой змеи
8 – 9 направление движения второй змеи
10 – 11 направление движения третьей змеи
12 – 13 направление движения четвертой змеи

Все номера змей различны. Четвертый номер однозначно выводится из первых трех. Порядок всегда генерируется для четырех змей. Если змея с указанным номером отсутствует, то при расчете/отображении боя она пропускается.

Направление движения змеи:

ЧислоЗначение
0 не движется (нет ходов, съедена или не участвует)
1 налево
2 прямо
3 направо

Поля запросов и ответов

ПолеОписание
Compatibleминимальный номер версии клиента, совместимого с текущим
Countколичество запрашиваемых записей
Errorтекстовое описание ошибки; может содержать данные, вызвавшие ошибку, в т. ч. имя поля в формате «поле.элемент.подэлемент»
ErrorCodeчисловой код ошибки
FightIdидентификатор боя
FightListотсортированный список боев, см. выше
FightListTypeтип списка боев: «ordered» (заказанные) или «challenged» (рейтинговые, заказанные другими)
FightResultрезультат боя: «limit» (лимит ходов), «eaten» (съедены все змеи, кроме одной) или «blocked» (нет возможных ходов)
FightTimeдата и время окончания боя
FightTypeтип боя, «train» (обычный) или «challenge» (рейтинговый)
FirstIndexиндекс первого элемента списка
Hashхэш: SHA1(SHA1(SHA1(логин «:» пароль) соль) штамп); соль выдается сервером в ответе «login data»
Lifetimeвремя жизни сессии после последнего запроса к серверу, в секундах
Loginлогин пользователя, в нижнем регистре
OtherSnakeIdsмассив из 3 идентификаторов змей, null для отсутствующих
PlayerIdидентификатор игрока
PlayerIdsмассив из 3 различных идентификаторов игроков, участвующих рейтинге, кроме текущего игрока
PlayerListотсортированный список игроков, см. выше
PlayerNameимя пользователя
PlayerSnakesсписок змей игрока, см. выше
ProgramDescriptionописание программы
Ratingчисловой рейтинг игрока
Ratingsотсортированная таблица рейтингов, см. выше
Requestтип запроса
RequestIdклиентский идентификатор запроса, любой тип
Responseтип ответа
Saltсоль, используемая для генерации хэша при авторизации
Sidидентификатор сессии
SkinIdидентификатор окраски змеи, целое неотрицательное число
SkinListсписок вариантов окраски змей, см. выше
SlotIndexномер сохраненного боя (0 – 9)
SlotListотсортированный список сохраненных боев, см. выше
SlotNameописание сохраненного боя
SnakeIdидентификатор змеи, null для временной
SnakeIdsмассив из 4 идентификаторов змей, null для отсутствующих
SnakeListотсортированный список змей, см. выше
SnakeNameимя змеи
Snakesмассив из 4 описаний змей, null для отсутствующих, см. выше
SnakeStatsмассив из 4 элементов, содержащих результаты боя для каждой змеи, null для отсутствующих, см. выше
SnakeTypeтип змеи: «B» (бот) или «N» (обычная)
SnakeTypesстрока из 1 – 2 символов типов змей
SortByсписок вида [<имя_поля/>имя_поля*], задающий имена полей для сортировки и порядок их сортировки («<» — по возрастанию, «>» — по убыванию)
Templatesпользовательские шаблоны для программы, см. выше
Timestampметка времени; не должна отличаться от метки времени сервера больше, чем на 3 минуты
TotalCountобщее количество объектов (игроков, змей)
TurnLimitмаксимальное количество ходов для боя, 1 — 1000
Turnsинформация о ходах, см. выше
Versionтекущий номер версии протокола

Все имена полей и их содержимое регистрозависимы. Поля, которые не могут входить в данный запрос, игнорируются.

Все поля, перечисленные в описании запроса, обязательны (если в описании явно не указано иное). Помимо перечисленных полей запрос должен содержать поле Sid (если в описании запроса не указано иное). Также запрос может содержать необязательное поле RequestId. В этом случае ответ сервера будет содержать одноименное поле, содержимое которого совпадает с этим полем запроса.

В случае успешного выполнения запроса сервер выдает ответ, указанный в описании запроса. В случае неудачи возвращается один из следующих ответов:

  • relogin, если время жизни сессии истекло либо данные авторизации были изменены;
  • nack, если в запросе есть ошибки;
  • error, если произошла внутренняя ошибка сервера.

При авторизации используется хэш-функция SHA1, ее реализацию для JavaScript можно найти, например, здесь. На входе функции — строка в кодировке UTF-8, на выходе — шестнадцатиричное текстовое представление хэша в нижнем регистре (40 символов 0 – 9, a – f). Примеры:

SHA1(SHA1(«hello»)) == «9cf5caf6c36f5cccde8c73fad8894c958f4983da»
SHA1(SHA1(«привет»)) == «60a72cfc2aa27af4b1bda6d18cf50a27046914c4»

Запросы

Авторизация

info

получение информации о сервере

Request: «info»
Sid: не требуется (игнорируется)

ответ: «info»

whoami

получение информации о текущем пользователе

Request: «whoami»

ответ: «whoami»

login data

получение данных (соль, штамп сервера) для авторизации

Request: «login data»
Sid: не требуется (игнорируется)
Login:

ответ: «login data»

login

авторизация и открытие сессии

Request: «login»
Sid: не требуется (игнорируется)
Login:
Timestamp:
Hash:

ответ: «login»

logout

выход и закрытие сессии

Request: «logout»

ответ: «ack»

Игроки

ratings

таблица рейтингов игроков

Request: «ratings»
FirstIndex: необязательно, по умолчанию 0
Count: необязательно, 1 – 50, по умолчанию 30
SortBy: необязательно, возможные ключи: PlayerName или Rating, по умолчанию [«>Rating»]

ответ: «ratings»

player list

список игроков, отсортированный по имени

Request: «player list»
FirstIndex: необязательно, по умолчанию 0
Count: необязательно, 1 – 50, по умолчанию 30
SortBy: необязательно, возможные ключи: PlayerName, по умолчанию [«<PlayerName»]

ответ: «player list»

player info

информация об игроке

Request: «player info»
PlayerId:

ответ: «player info»

Змеи

snake list

список всех змей

Request: «snake list»
SnakeTypes: необязательно, по умолчанию «BN»
FirstIndex: необязательно, по умолчанию 0
Count: необязательно, 1 – 50, по умолчанию 30
SortBy: необязательно, возможные ключи: SnakeName или PlayerName, по умолчанию [«<SnakeName», «<PlayerName»]

ответ: «snake list»

skin list

получение списка вариантов окраски змей

Request: «skin list»

ответ: «skin list»

snake info

информация о змее

Request: «snake info»
SnakeId:

ответ: «snake info»

snake new

создание новой змеи

Request: «snake new»
SnakeName:
SnakeType:
SkinId:
ProgramDescription:
Templates:
Maps:

ответ: «snake new»

snake delete

удаление своей змеи

Request: «snake delete»
SnakeId:

ответ: «ack»

snake edit

редактирование змеи

Request: «snake edit»
SnakeId:
SnakeName: необязательно
SnakeType: необязательно
SkinId: необязательно
ProgramDescription: необязательно
Templates: необязательно
Maps: необязательно

ответ: «ack»

snake assign

назначение своей обычной змеи бойцом

Request: «snake assign»
SnakeId:

ответ: «ack»

Бои

fight list

список боев игрока

Request: «fight list»
FightListType:

ответ: «fight list»

fight info

информация о бое

Request: «fight info»
FightId:

ответ: «fight info», «fight delayed»

fight test

начать бой со временной змеей; временная змея будет первой

Request: «fight test»
TurnLimit: необязательно
SnakeName:
SkinId:
ProgramDescription:
Templates:
Maps:
OtherSnakeIds:

ответ: «fight info», «fight delayed»

fight train

начать обычный бой

Request: «fight train»
TurnLimit: необязательно
SnakeIds:

ответ: «fight info», «fight delayed»

fight challenge

начать рейтинговый бой

Request: «fight challenge»
PlayerIds:

ответ: «fight info», «fight delayed»

fight cancel

отменить бой

Request: «fight cancel»

ответ: «ack»

Сохраненные бои

slot list

список сохраненных боев

Request: «slot list»

ответ: «slot list»

slot view

загрузить информацию о сохраненном бое

Request: «slot view»
SlotIndex:

ответ: «slot view»

slot save

сохранить информацию о бое

Request: «slot save»
SlotIndex:
SlotName:
FightId:

ответ: «ack»

slot rename

изменение описания сохраненного боя

Request: «slot rename»
SlotIndex:
SlotName:

ответ: «ack»

slot delete

очистить сохраненный бой

Request: «slot delete»
SlotIndex:

ответ: «ack»

Прочее

ping

обновление сессии

Request: «ping»

ответ: «ack»

Ответы

Все поля, перечисленные в описании ответа, обязательны (если в описании явно не указано иное). Если в запросе было поле RequestId, то ответ также содержит это поле с тем же значением. В будущих версиях протокола могут появиться дополнительные поля ответов; старые версии клиентов должны игнорировать такие поля.

Ошибки

Сообщение об ошибке может быть выдано в ответ на любой запрос.

relogin

требуется заново авторизоваться (истекло время жизни сессии, изменились данные авторизации или просто указан неверный идентификатор сессии)

Response: «relogin»

nack

ошибка в запросе

Response: «nack»
ErrorCode:
Error:

error

внутренняя ошибка

Response: «error»
ErrorCode:
Error:

Прочее

ack

подтверждение выполнения запроса

Response: «ack»

Авторизация

info

информация о сервере

Response: «info»
Version:
Compatible:
Lifetime:

whoami

информация о текущем игроке

Response: «whoami»
PlayerId:
PlayerName:
FightId: текущий отложенный бой (null, если отложенных боев нет)
Rating: отсутствует, если игрок не участвует в рейтинге
SnakeId: ид бойца; отсутствует, если игрок не участвует в рейтинге
SnakeName: имя бойца; отсутствует, если игрок не участвует в рейтинге
SkinId: окраска бойца; отсутствует, если игрок не участвует в рейтинге

login data

данные для авторизации; если в запросе «login data» указан неизвестный логин, это не считается ошибкой

Response: «login data»
Login:
Salt:
Timestamp:

login

успешная авторизация

Response: «login»
PlayerId:
PlayerName:
Sid:

Игроки

ratings

таблица рейтингов

Response: «ratings»
FirstIndex:
SortBy:
TotalCount:
Ratings:

player list

список игроков

Response: «player list»
FirstIndex:
SortBy:
TotalCount:
PlayerList:

player info

информация об игроке

Response: «player info»
PlayerId:
PlayerName:
Rating:
SnakeId: идентификатор бойца или null
PlayerSnakes:

Змеи

snake list

список змей

Response: «snake list»
SnakeTypes:
FirstIndex:
SortBy:
TotalCount:
SnakeList:

skin list

список вариантов окраски

Response: «skin list»
SkinList:

snake info

информация о змее

Response: «snake info»
SnakeId:
SnakeName:
SnakeType:
SkinId:
PlayerId:
PlayerName:
ProgramDescription: необязательно, выдается только для ботов и своих змей
Templates: необязательно, выдается только для ботов и своих змей
Maps: необязательно, выдается только для ботов и своих змей

snake new

создана новая змея

Response: «snake new»
SnakeId:

Бои

fight list

список боев

Response: «fight list»
FightListType:
FightList:

fight info

информация о бое

Response: «fight info»
FightId:
FightType:
FightTime:
FightResult:
TurnLimit:
Turns:
Snakes:
SnakeStats:

fight delayed

расчет боя не завершен

Response: «fight delayed»
FightId:

Сохраненные бои

slot list

список сохраненных боев

Response: «slot list»
SlotList:

slot view

информация о сохраненном бое

Response: «slot view»
SlotIndex:
SlotName:
FightType:
FightTime:
FightResult:
TurnLimit:
Turns:
Snakes:
SnakeStats:

Коды ошибок для ответа nack

КодОписаниеТекст ошибки содержит:
0сервер временно недоступенпричина
1неизвестное имя запросасодержимое поля Request
2неизвестное имя поляимя поля
3отсутствует необходимое полеимя поля
4некорректное значение поляимя поля, содержимое поля
5слишком длинная строкаимя поля, максимальная длина
6неизвестный логин или неверный хэш
7неизвестный идентификатор игрокаидентификатор
8неизвестный идентификатор змеиидентификатор
9неизвестный идентификатор бояидентификатор
10игрок не участвует в рейтингеидентификатор
11некорректный формат поляимя поля, содержимое поля
12невозможно удалить бойца или сменить его типидентификатор змеи
13некорректная окраска змеиидентификатор змеи, указанная окраска
14невозможно назначить бойцом ботаидентификатор змеи
15сохраненный бой с указанным индексом отсутствуетиндекс
16чужая змеяидентификатор
17невозможно «заказать» бой, поскольку есть незавершенный бойидентификатор боя
18у игрока уже максимально допустимое количество змейколичество
19некорректные данные в запросеописание
20некорректное описание линии картыномер карты, номер линии, линия

В будущих версиях протокола могут появиться новые (более специфические) коды ошибок.

 
projects/snakes/protocol.txt · Последнее изменение: d.m.Y H:i — AVA12
 
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki