fix: removed all the trash (except for kmtp itself)
This commit is contained in:
parent
87f6c8435f
commit
4440b50798
13
2e1m.typ
13
2e1m.typ
@ -1,3 +1,14 @@
|
||||
#import "head.typ" as head : *
|
||||
|
||||
#show: MyStyle
|
||||
#show: MyStyle
|
||||
|
||||
= 2 Ears 1 Mouth Specification
|
||||
|
||||
2 Ears 1 Mouth (2e1m) это договорённость о передачи аудиопотока, используемая для общения
|
||||
в играх с "proximity-voice-чатом". Клиент отправляет чистый PCM поток с одним каналом с
|
||||
семплами в формате signed 16-bit two's complement числа. Это то, что "говорит" клиент.
|
||||
Сервер отправляет клиенту чистый PCM поток такого-же формата, но с двумя каналами: первый
|
||||
соответствует тому, что левое ухо клиента "слышит", а второй соответствует сигналу,
|
||||
приходящему на правое ухо.
|
||||
|
||||
Вот и всё. В kmtp-классификации кладов 2e1m имеет кодовое имя `2e1m`.
|
46
kmon.typ
46
kmon.typ
@ -1,3 +1,47 @@
|
||||
#import "head.typ" as head : *
|
||||
|
||||
#show: MyStyle
|
||||
#show: MyStyle
|
||||
|
||||
= KMON Specification
|
||||
|
||||
KMON (KM Object Notation) это множество объектов, удобных для использования в программах с динамической типизацией.
|
||||
Этот документ описывает этом ножество объектов и как их интегрпретировать, а так же определяет биекцию между
|
||||
множеством kmon и подмножеством строк, представляющих собой запись km-объкта.
|
||||
KMON является упрощённым аналогом JSON, использующимся в KM Project. KMON это официальное название типа объектов,
|
||||
однако в самом мире игры KM он известен как SON (Suckless
|
||||
Object Notation).
|
||||
|
||||
KM-объект (объект типа kmon/KMobj) может быть одного из 5-и подтипов: null (пустой), int (число),
|
||||
str (строка), arr (массив), dict (словарь). При этом int хранит в себе целое число (со знаком),
|
||||
str хранит в себе строку байт (не обязательно корректную, это просто массив из октетов произвольной длины).
|
||||
Arr хранит массив км-объектов, Dict хранит словарь, где ключи: строки из алфавита, состоящего лишь из
|
||||
букв латинского алфавита, чисел и символов #text(fill:red)[`+` `/` `=` `-` `-`]; а значения словаря - другие
|
||||
км-объекты.
|
||||
Такие объекты, хранящиеся в другом км-объекти называются сыновьями родительского объекта.
|
||||
|
||||
Принято хранить в числовом км-объекте число от $-2^63$ до $2^63+1$.
|
||||
|
||||
Число записывается естесственным образом. null-объект записывается как литерал `null`.
|
||||
Строка `str` может записываться в формате `'{str}'`, здесь мы окружаем строку одинарной
|
||||
кавычкой. Такой способ записи может использоваться только если в строке нет символа
|
||||
одинарной кавычки. Произвольную строку можно записать вторым способом:
|
||||
`={len(str)}>{str}`, здесь мы перед строкой пишем знак равенства, указываем длину строки
|
||||
(в шестнадцатиричной системе счисления), оканчиваем размер знаком "больше" и записываем
|
||||
саму строку. Это два единственных "формальных" способа записи. Все имплементации
|
||||
десериализватора должны быть способны их прочитать. Есть ещё опциональная третья запись.
|
||||
`"str.sub('\', '\\').sub('"', '\"')"`. Здесь мы сперва экранируем в строке все двойные
|
||||
кавычки и обратные слэши, и обрамляем получившуюся строку в двойные кавычки.
|
||||
Это называется "человекочитаемый формат". Программа, посылающая км-объект в таком формате должна быть уверена, что получатель поддерживает человекочитаемый формат строк.
|
||||
|
||||
Вокруг записи км-объекта можно ставить справа и слева пробелы, смысл от этого не будет
|
||||
меняться.
|
||||
|
||||
Для записи массивов все его элементы разделяются запятыми, и полученная строка окружается
|
||||
квадратными скобками (слева левой, справа правой).
|
||||
|
||||
Запись словаря похожа на запись массива тем, что запись словаря - это разделённый
|
||||
запятыми список пар (ключ, км-объект), окруженный фигурными скобками (слева левой,
|
||||
справа правой). Пара ключ, км объект состоит из 3-ёх частей (которые можно окружать
|
||||
и разделять пробелами): ключ "по формату словарного ключа", записанный напрямую,
|
||||
потом двоеточие, после него сам км-объект, значение в словаре по данному ключу.
|
||||
Ключи не должны повторяться.
|
||||
|
87
kmtp.typ
87
kmtp.typ
@ -3,12 +3,12 @@
|
||||
#show: MyStyle
|
||||
|
||||
|
||||
= KMTP Specification
|
||||
= KMTP, Sub-KMTP Спецификация
|
||||
|
||||
== Область применения
|
||||
|
||||
KMTP это протокол, созданный специально для будущей видеоигры KM (Используется
|
||||
в рамках KM project). Он нацелен на замену чрезвычайно непрофессионального и раздутого
|
||||
в рамках KM project). Он нацелен на замену чрезвычайно раздутого
|
||||
протокола http+websocket. KMTP (KM Transport Protocol) это его официальное название,
|
||||
однако в самом мире игры KM он известен как STP (Suckless
|
||||
Transport Protocol).
|
||||
@ -28,8 +28,7 @@ KMTP применяется когда между двумя общающими
|
||||
хотя под это понятие попадает даже содержимое jpeg картинки, скачанной с файлового
|
||||
сервера.
|
||||
|
||||
В начале соединения клиент может предствиться передав "логин" и "пароль",
|
||||
а сервер может представиться, передав свой пароль.
|
||||
В начале соединения клиент может предствиться передав "логин" и "пароль".
|
||||
|
||||
Каналы связи называются
|
||||
- client's output / server's output / request channel
|
||||
@ -39,33 +38,31 @@ KMTP применяется когда между двумя общающими
|
||||
"сообщение". Они бывают двух видов: "запросы" (отправляются клиентом) и
|
||||
"ответы" (отправляются сервером). Но есть ещё одно деление: на "мастер-сообщение"
|
||||
и "суб-сообщение" (применимое к обоим типам адресанта сообщения).
|
||||
Контент каждого канала начинается с мастер-сообщения своего типа, а все
|
||||
последующие сообщения, отправленные по каналу, (если таковые есть)
|
||||
записаны в формате "суб-сообщений".
|
||||
У каждого типа есть свой формат, форматы различаются набором обязатльных "полей".
|
||||
Контент каждого канала начинается с мастер-сообщения своего типа.
|
||||
Если клиент и сервер договорились сделать "апгрейд" до sub-kmtp, то все дальнейшие
|
||||
сообщения будут записаны в формате "суб-сообщений".
|
||||
У каждого типа есть свой формат, форматы различаются набором обязательных "полей".
|
||||
|
||||
Каждый kmtp-канал содержит последовательность kmtp-сообщений. Первое сообщение -
|
||||
мастер-сообщение, остальные - суб-сообщения.
|
||||
При этом все суб-сообщения в канале как-бы считаются телом мастер-сообщения.
|
||||
Поэтому если есть поток суб-сообщений, приложенный к мастер-сообщению, то другого
|
||||
тела у мастер сообщения нет. Есть специальное поле заголовка мастер-сообщения,
|
||||
сообщающее, идёт ли после мастер-сообщения поток суб-сообщений. О поляъ расскажу позже.
|
||||
Поток суб-сообщений оканчивается когда вместо следующего сообщения отправитель передаёт
|
||||
по каналу LF (line feed). Опять же, если потока нет, о передавать этот LF
|
||||
в конце не нужно.
|
||||
Каждый канал содержит только мастер-сообщение (соответсвующего типа) и ничего более.
|
||||
Поток суб-сообений это часть местер сообщения. Естесственно, поток суб-сообщений
|
||||
будет присутсвовать только когда был произведён апгрейд до sub-kmtp.
|
||||
В этом случае сначала идёт мастер-заголовок сообщения, а всё остальное (та часть
|
||||
сообщения, называющаяся кладом) - это sub-kmtp. Вместо него, конечно же, мог бы быть
|
||||
совсем другой клад мастер сообщения.
|
||||
|
||||
Сообщения содержат заголовок, чей формат полность определён и тело, называемое "кладом".
|
||||
Клад бывает 4 типов: отсутствующий (none) - это когда клад отсутствует, "письмо" (letter) -
|
||||
Клад бывает 4 типов: "письмо" (letter) -
|
||||
это когда клад имеет заранее известный (из заголовка сообщения) конечный размер,
|
||||
"вкид" (vkid) - это когда клад продолжается до самого конца канала без возможности
|
||||
вернуться обратно к kmtp-протоколу, при чем бесконечность вкида известна заранее. А ещё есть
|
||||
"отвал" (otval) - это когда размер клада заранее неизвестен и должен быть на ходу
|
||||
определён тем, кто принимает отвал. После перехода на отвал канал ещё может обратно
|
||||
вернуться к протоколу kmtp, однако определить этот момент возврата не понимая
|
||||
вернуться к протоколу sub-kmtp, однако определить этот момент возврата не понимая
|
||||
протокола, который использует отвал - невозможно. Потому при появлении в канале отвала
|
||||
любой прокси, что не понимает протокол отвала сразу потеряет возможность распознавать весь
|
||||
дальнейший трафик.
|
||||
Поток суб-сообщений - это вклад. А именно "вкид". Чтобы указать принимающему
|
||||
дальнейший трафик. Как можно заметить практического смысла использовать отвал
|
||||
вместо вкида в мастер-kmtp сообщении нет.
|
||||
Поток суб-сообщений - это клад. А именно "отвал". Чтобы указать принимающему
|
||||
что вкид нашего мастер-сообщения это имеенно поток суб-сообщений, надо в специальное
|
||||
поле для типа клада записать "sub-kmtp". При этом если клиент отправит поле типа клада
|
||||
"sub-kmtp", все понимают, что он сейчас начнёт отправлять именно поток суб-запросов,
|
||||
@ -76,8 +73,7 @@ KMTP применяется когда между двумя общающими
|
||||
(в том же порядке, в котором соответствующие запросы были заданы). На
|
||||
мастер-запрос (master-request) приходит мастер-ответ (master-response),
|
||||
на суб-запрос (sub-request) приходит суб-ответ (sub-response).
|
||||
|
||||
Но сервер также может в любой момент времени отправить в выходной канал особый вид
|
||||
Но! Сервер также может в любой момент времени отправить в выходной канал особый вид
|
||||
сообщения, называемое "событие" (event). Событие адресовано мастер-запросу, а не
|
||||
суб-запросам. События имеют такую же структуру, что и суб-ответы, отличаются они только тем,
|
||||
что в заголовке события "поле Status" обязано быть равно "Event (DC)".
|
||||
@ -91,8 +87,6 @@ KMTP применяется когда между двумя общающими
|
||||
После блока обязательных полей следует множество именованных полей. Их число не определено,
|
||||
пользователи kmtp вольны сами придумывать эти поля.
|
||||
Оканчивается заголовок символом LF (Перевод строки). После заголовка идёт клад.
|
||||
Если клад не none и клад окончился возвращением к kmtp-протоколу, после клада
|
||||
добавляется символ LF. Он не несёт никакой пользы, но важно не забыть перепрыгнуть через него.
|
||||
|
||||
Поля имеют формат "имя" + ":"/">" + "значение" + LF. При этом есть безымянные поля, где
|
||||
"имя" пусто.
|
||||
@ -102,7 +96,7 @@ KMTP применяется когда между двумя общающими
|
||||
":" заменяется на ">". Эти поля: "Virtual-Host", "Auth-Username", "Auth-Password".
|
||||
Они отличаются от других тем, что они присутствуют только в мастер-сообщениях.
|
||||
Об этом позже будет рассказано.
|
||||
"значение" несёт в себе строку произвольного формата, но важно то, как она обёрнута.
|
||||
"Значение" несёт в себе строку произвольного формата, но важно то, как она обёрнута.
|
||||
Если надо передать строку str, значение записывается как "=" + hex(len(str)) + ">" + str,
|
||||
при этом если так получилось, что str не содержит символа `'` (ascii 0x27), то можно
|
||||
записать значение как "'" + str + "'". Семантика сообщения от выбора способа записи
|
||||
@ -118,9 +112,10 @@ KMTP применяется когда между двумя общающими
|
||||
#let master-field-name-decl(name) = bold(name)
|
||||
|
||||
Устройство блока заголовка суб-запроса:
|
||||
+ #field-name-decl[Location]: Юникс путь нужного ресурса на сервере. В мастер-запросе
|
||||
не может быть относительны путём, ведь нам неотчего отталкиваться.
|
||||
+ #field-name-decl[Function]: функцию, производимая над ресурсом.
|
||||
+ #field-name-decl[Location]: Путь нужного ресурса на сервере. В мастер-запросе
|
||||
не может быть относительным путём, ведь нам неотчего отталкиваться. Правила такие же,
|
||||
как для юникс-путя.
|
||||
+ #field-name-decl[Function]: Функция, производимая над ресурсом.
|
||||
Ближайшим аналогом будет
|
||||
поле method из http. KMTP определяет ряд функций с определённым значение,
|
||||
однако пользователи kmtp могут сами определять свои функции, если сервер
|
||||
@ -133,25 +128,23 @@ KMTP применяется когда между двумя общающими
|
||||
указания сдвига данных, передаваемых в кладе клиента (например, если клиент
|
||||
загружал большой файл, но соединение оборвалось, это поле можно использовать
|
||||
чтобы указать с какого места продолжается закачка).
|
||||
+ #field-name-decl[Client-Klad-Seek-Pos]: Формат тот же что и у Client-Klad-Sek-Pos
|
||||
+ #field-name-decl[Resource-Klad-Seek-Pos]: Формат тот же что и у Client-Klad-Sek-Pos
|
||||
(#math.penta.filled). Но здесь указывается сдвиг относительно ресурса на сервере.
|
||||
Так, к примеру, клиент может указать с какого момента продолжить скачивание большого
|
||||
файла с сервера.
|
||||
+ #field-name-decl[Body-Type]: если за сообщением следует "тело",
|
||||
то здесь указывается как
|
||||
его прочитать. Это может быть пустая строка, если тела нет, число в 16-ричной
|
||||
системе счисления, если произошел отнюх, "otval" если произошел отвал,
|
||||
"vkid", если произошел вкид (как можешь убедиться, эти 4 случая невозможно
|
||||
перепутать) #math.penta.filled. Важно! Если Body-Type пуст, то клада нет, сообщение
|
||||
оканчивается там, где оканчивается его заголовок. Но если Body-Type это "0" или
|
||||
"00 ... 0", то клад есть, го тип - письмо, и после пустого письма должен стоять
|
||||
обязательный перевод строки. Да, как бы это не было странно, но у суб-сообщений
|
||||
его прочитать. Это может быть число в 16-ричной
|
||||
системе счисления, если передано письмо, "otval" если произошел отвал,
|
||||
"vkid", если произошел вкид (как можешь убедиться, эти 3 случая невозможно
|
||||
перепутать) #math.penta.filled. Да, как бы это не было странно, но у суб-сообщений
|
||||
может быть свой клад, получается что клад суб-сообщения это клад в кладе
|
||||
мастер-сообщения.
|
||||
+ #bold[Upgrade-Name]: если тело есть, то здесь указывается узнаваемое имя протокола,
|
||||
+ #bold[Upgrade-Name]: Здесь указывается узнаваемое имя протокола,
|
||||
к которому мы переходим. На это поле наложены такие же ограничения, как
|
||||
на поле Function (используются только символы, допустимые в kmon
|
||||
ключе), поэтому кавычки не используются #math.penta.filled. Пустая строка допустима.
|
||||
Имеет смысл только если клад не пуст.
|
||||
|
||||
Для удобства мастер-запрос очень похож на суб-запрос. Различие лишь в том, что
|
||||
в мастер-запрос в начало добавляются 3 мастер-поля:
|
||||
@ -178,14 +171,14 @@ KMTP применяется когда между двумя общающими
|
||||
Не обязано быть привязано к реальному времени. Может быть пустой строкой - это
|
||||
эквивалентно нулю. #math.penta.filled. Нет ограничения на размер этого числа.
|
||||
|
||||
Мастер-ответ отличается от суб-ответа тем, что в начале присутствует одно мастер поле:
|
||||
+ #master-field-name-decl[Auth-Password]: Это то, что ты подумал.
|
||||
Мастер-ответ ничем не отличается от суб-ответа.
|
||||
|
||||
Status мастер-ответа не может быть #roman-status[DC] (Event).
|
||||
|
||||
Получается, что список обязательных полей, использующих синтаксис `=HEX>str or 'str'`,
|
||||
который дефолтен для именованных полей, довольно мал: это все мастер-поля + поле
|
||||
Location. Нужно учесть, что значение поля Location не должно содержать октета 0.
|
||||
Location. Нужно учесть, что значение поля Location не должно содержать октета 0,
|
||||
хотя это наврятле будет проверяться.
|
||||
|
||||
Этот документ сам определяет ряд именованных полей сообщения.
|
||||
Есть целый ряд незапланированных полей, вида `"Proxy-" + n + "-" + Name`,
|
||||
@ -193,6 +186,10 @@ Location. Нужно учесть, что значение поля Location н
|
||||
n-ым с конца прокси (отсчет начинается от стороны получателя). От одного прокси может
|
||||
передаваться много разных полей, поэтому можно дополнительно указать суб-имя `Name`.
|
||||
|
||||
Считается, что kmtp-прокси при прохождении через него заголовка сообщения, порядок
|
||||
всех полей, начинающихся с `"Proxy-"`, инкрементирует, а если хочет и свои поля
|
||||
добавить, Поставит в их имена префикс `"Proxy-1-"`.
|
||||
|
||||
+ #field-name-decl[Proxy-n-Address]: Адрес клиента, который видит прокси, но конечный
|
||||
сервер не видит. Здесь #field-name-decl[Proxy-n-Address] - это параметризованное имя
|
||||
поля.
|
||||
@ -216,7 +213,7 @@ n-ым с конца прокси (отсчет начинается от сто
|
||||
- #roman-status[CCCVII] (Temporary Redirect)
|
||||
- #roman-status[CCCX] (Go Back)
|
||||
|
||||
#heading(level: 3)[Коды ошибки, виноват клиент (CD...)]
|
||||
#heading(level: 3)[Ошибка когда виноват клиент (CD...)]
|
||||
- #roman-status[CD] (Bad request)
|
||||
- #roman-status[CDI] (Unauthorized)
|
||||
- #roman-status[CDIII] (Forbidden)
|
||||
@ -232,7 +229,7 @@ n-ым с конца прокси (отсчет начинается от сто
|
||||
- #roman-status[CDLXIV] (Inadmissible Body Type)
|
||||
- #roman-status[CDLXXVI] (Incorrect Seek Pos Resource Side)
|
||||
|
||||
#heading(level: 3)[Коды ошибки, виноват сервер, прокси или машина, на которой
|
||||
#heading(level: 3)[Ошибка когда виноват сервер, прокси или машина, на которой
|
||||
они работают (D...)]
|
||||
- #roman-status[D] (Internal Server Error)
|
||||
- #roman-status[DII] (Destination Unreachable)
|
||||
@ -243,13 +240,13 @@ n-ым с конца прокси (отсчет начинается от сто
|
||||
(Nuclear Reactor That Was Managed By This Computer Was Blown Up By Terrorists) \
|
||||
Упс, это спойлеры к KM.
|
||||
|
||||
#heading(level: 3)[Коды ошибки, виновато общество в котором вы живёте (DCC...)]
|
||||
#heading(level: 3)[Ошибка когда виновато общество в котором вы живёте (DCC...)]
|
||||
- #roman-status[DCCLI] (Unavailable For Legal Reasons) \
|
||||
Запрашиваемый ресурс / запрашиваямая операция над ресурсом недопустима в стране
|
||||
сервера.
|
||||
- #roman-status[DCCLII] (Cancelled For Legal Reasons)\
|
||||
Запрашиваемый ресурс / запрашиваямая операция над ресурсом недопустима в стране
|
||||
клиента. Отличие от DCCLII в том, что другим клиентам из других стран этот же
|
||||
клиента. Отличие от DCCLI в том, что другим клиентам из других стран этот же
|
||||
ресурс может быть доступен.
|
||||
|
||||
== Широко известные функции. Поле Function.
|
||||
|
Loading…
Reference in New Issue
Block a user