Протокол сервера Classic

Протокол сервера Classic используется в Minecraft Classic Creative Multiplayer сервере.

## Связь с Minecraft.net

### Сердцебиения

Чтобы подключится к серверу Classic из окна списка серверов, он должен поддерживать связь с основным сервером minecraft.net. Акт/сеанс такой связи называется «сердцебиение» и происходит каждые несколько минут.

Главный сервер посылает такие «сердцебиения» каждые 45 секунд.

«Сердцебиение» принимает форму HTTP-запроса на http://www.minecraft.net/heartbeat.jsp. После отправки «сердцебиения», URL-адрес для сервера возвращается.

Это может быть GET или POST запрос. Таблица необходимых параметров ниже:

Имя | Описание |
---|---|

port | Номер порта сервера. Значение, как правило, 25565. |

max | Максимальное число игроков на сервере |

name | Имя сервера |

public | Общедоступный сервер, или нет (то есть видно ли его в списке серверов для всех игроков). Может принимать значения True или False.
|

version | Версия Minecraft, должно быть 7 |

salt | Случайная 16-символьная соль в base-62 |

users | Число пользователей, подключенных к серверу |


Наиболее простым способом послать сердцебиение это открыть протокол TCP для порта 80 на www.minecraft.net, и послать следующее (изменяя соответствующие части, очевидно):

**GET /heartbeat.jsp?port=25565&max=32&name=My%20Server&public=True&version=7&salt=wo6kVAHjxoJcInKx&users=0**, плюс CRLF (**Carriage-return and Line feed** — возврат каретки и перевод строки).

Убедитесь, что любые строки, типа «имя», заполнены.

Если все будет хорошо, то в теле ответа вы получите URL к серверу. В противном случае вы получите HTML сообщение об ошибке. Так как версия HTTP не определена, то отсутствуют HTML заголовки для парсинга, поскольку используется HTTP/0.9 в которой их не существует.

### Авторизация пользователя

«Ключ» который образуется при подключении пользователя к серверу можно представляет собой контрольную сумму MD5 серверной «соли» плюс имя пользователя для определения конкретного пользователя, который подключился к minecraft.net. Это полезно при блокировке или смены привилегий пользователя, поскольку гарантирует его уникальность.

if( player.key == md5( server.salt + player.name ) ) { // игрок подключился к minecraft.net } else { // игрок создает имя пользователя }

Это также является методом, которым Нотч предотвращает возможность подключения с пиратских клиентов к онлайн-серверу. Когда пиратский клиент старается подключится к серверу, всплывает окно с ошибкой, гласящей: «Failed to Connect: User Not Premium» *(Невозможно подключится: Отсутствует премиум-аккаунт)*

Заметка: Это указывает на то, что вы должны держать свою «соль» в секрете, и распространять только с heartbeat.jsp. Если «соль» вашего сервера видна для других игроков, они смогут создать подобие правильного «ключа» и зайти на сервер без подключения к minecraft.net.

## Пакеты протоколов

Каждый пакет начинается с байта, представляющего ID.

### Протокол типов данных

Тип | Размер [байты] | Описание |
---|---|---|

Byte | 1 | Один байт (от 0 до 255) |

SByte | 1 | Один байт со знаком (-128 to 127) |

Short | 2 | Целое число со знаком (-32768 to 32767) |

String | 64 | US-ASCII/ISO646-US кодированная строка дополняется пробелами (0x20) |

Массив байтов | 1024 | Двоичные данные дополняются пустым байтом (0x00) |


### Клиент → Сервер пакеты

ID | Назначение | Описание поля | Тип поля | Примечания |
---|---|---|---|---|

0x00 | Идентификация игрока | Пакет ID | Byte | Отправляется игроком при присоединении к серверу. |

Версия протокола | Byte | |||

Имя пользователя | String | |||

Ключ подтверждения | String | |||

Неиспользуемый | Byte | |||

0x05 | Установка блока | Пакет ID | Byte | Посылается, когда игрок изменяет блоки. Поле «Режим» показывает, создал игрок блок (0x01) или разрушил (0x00).
Тип блока — тип блока, который игрок держит (даже при удалении блоков). Клиент всегда считает, что команда была успешной, и немедленно прорисовывает новый блок. Для отмены изменения блока, сервер должен отослать пакет Set Block со старым типом блока. Координаты XYZ могут принимать только целочисленные значения, показывающие местоположение блока в пространстве (в отличие от координат игроков, которые всегда дробные). |

X | Short | |||

Y | Short | |||

Z | Short | |||

Режим | Byte | |||

Тип блока | Byte | |||

0x08 | Положение и ориентация | Пакет ID | Byte | Отсылается игроком часто (даже если не двигается) с текущей позицией игрока и ориентацией.
ID игрока всегда ровно 255. Координаты игрока представляют собой дробные значения с фиксированной точкой, причем 5 младших бит представляют дробную часть. (то есть следует разделить значения текущей позиции на 32 и получим позицию игрока в блоковом представлении). Параметр «Угол» масштабируются так, что значение 256 соответствовало бы 360 градусам. |

ID Игрока | Byte | |||

X | Short | |||

Y | Short | |||

Z | Short | |||

Отклонение (Направление) | Byte | |||

Угол | Byte | |||

0x0d | Сообщение | Пакет ID | Byte | Содержит сообщение которое игрок отправляет в чат. |

Неиспользуемый; возможно, цвет сообщения | Byte (0xFF) | |||

Текст сообщения | String |


### Сервер → Клиент пакеты

ID Пакет | Назначение | Описание поля | Тип поля | Примечания |
---|---|---|---|---|

0x00 | Идентификация сервера | Пакет ID | Byte | Ответ на вступление игрока. Пользователь указывает тип игрока ор (0x64) или нет (0x00) Текущая версия протокола 0x07. |

Версия протокола | Byte | |||

Имя сервера | String | |||

Сервер MOTD | String | |||

Тип пользователя | Byte | |||

0x01 | Пинг | Пакет ID | Byte | Отправляется клиентам периодически. На данный момент, единственным способом остановить соединение, является принудительное закрытие клиента. Пакет «пинг» используется для определения, активно ли соединение. |

0x02 | Инициализация уровня | Пакет ID | Byte | Сообщает игроку о том, что далее последуют данные уровня. |

0x03 | Блок с данными об уровне | Пакет ID | Byte | Содержит блок gzip-ованной карты (не содержимое файла level.dat). После декомпрессии игровой мир состоит из int (4 байта; целочисленное значение), в котором содержится информация про количество блоков + несжатый массив карты. (размер чанка составляет до 1024 байта, заполненный 0x00 если меньше). |

Длина чанка | Short | |||

Данные чанка | Массив байтов | |||

Процент завершения | Byte | |||

0x04 | Уровень завершения | Пакет ID | Byte | Посылается после данных про игровой мир, содержит информацию про измерения. Координата Y указывает высоту карты. |

Размер X | Short | |||

Размер Y | Short | |||

Размер Z | Short | |||

0x06 | Установка блока | Пакет ID | Byte | Отправляется для обозначения изменений блока от физики или от игроков. Если игрок изменил блок, сервер также отправит этот пакет игроку, чтобы инициализировать изменение. |

X | Short | |||

Y | Short | |||

Z | Short | |||

Тип блока | Byte | |||

0x07 | Спаун игрока | Пакет ID | Byte | Отправляется для указания места спауна нового игрока в мире. Положение и ориентация кодируются так же, как и пакет 0x08. |

ID Игрока | SByte | |||

Имя Игрока | String | |||

X | Short | |||

Y | Short | |||

Z | Short | |||

Отклонение (Направление) | Byte | |||

Угол | Byte | |||

0x08 | Положение и ориентация (Player Teleport) | Пакет ID | Byte | Отправляется с изменениями в положении игрока и вращении. Пакет про телепортацию игрока отсылается, если ID игрока ID < 0 (для его возвращения в исходную позицию на карте и /tp) |

ID Игрока | SByte | |||

X | Short | |||

Y | Short | |||

Z | Short | |||

Отклонение (Направление) | Byte | |||

Угол | Byte | |||

0x09 | Обновление положения и ориентация | Пакет ID | Byte | Отправляется с изменениями в положении игрока и вращении. Отправляется, когда положения и ориентация меняется.
Не нуждается в обработке на сервере. |

ID Игрока | SByte | |||

Изменения в X | SByte | |||

Изменения в Y | SByte | |||

Изменения в Z | SByte | |||

Отклонение (Направление) | Byte | |||

Угол | Byte | |||

0x0a | Обновление положения | Пакет ID | Byte | Отправляется с изменениями в положении игрока.
Не нуждается в обработке на сервере. |

ID Игрока | SByte | |||

Изменения в X | SByte | |||

Изменения в Y | SByte | |||

Изменения в Z | SByte | |||

0x0b | Обновление ориентации | Пакет ID | Byte | Посылается, при вращении игрока.
Не нуждается в обработке на сервере. |

ID Игрока | SByte | |||

Отклонение (Направление) | Byte | |||

Угол | Byte | |||

0x0c | Деспаун Игрока | Пакет ID | Byte | Посылается при отключении игрока. |

ID Игрока | SByte | |||

0x0d | Сообщение | Пакет ID | Byte | Сообщения, посланные в чат или с консоли. |

ID Игрока | SByte | |||

Сообщение | String | |||

0x0e | Отсоединение игрока | Пакет ID | Byte | Посылается игроку, если он исключен из сервера:
|

Причина отсоединения | String | |||

0x0f | Обновление типа пользователя | Пакет ID | Byte | Посылается, когда игрок получает/теряет привилегии оператора. |

Тип пользователя | Byte |


## Позиция игрока

### Фиксированная точка

Позиция игрока представлена через координаты X, Y, Z с фиксированной точкой. Дробная часть равна 5 битов, поэтому деление коротких целых чисел, полученных в пакетах обновления позиции на 32, будет иметь координаты с плавающей точкой для игрока. Эта позиция соответствует центру просмотра клиента.

### Стоя на объектах

Нижний край стопы игрока расположен на 1.59375 (фиксированная точка: 51) блоков ниже центра окна просмотра, поэтому для определения, правильно ли расположен игрок, можно посылать teleport-пакет (0x08), в котором бы содержалось положение головы по оси Y от нижнего блока: Y x 32 = 51.

### Ориентация

Параметр, отвечающий за рысканье при значении 0 указывает на то, что игрок смотрит в направлении Z=0 (противоположное Z). Это значение увеличивается, если игрок поворачивает взгляд в направлении часовой стрелки. Если направление, противоположное Z назвать «север», тогда значение «64» значит «восход», 128 — «юг» и 192 это «запад».

Значение 0 склонения означает линию горизонта, и это значение увеличивается в нисходящем направлении. 64 указывает на то, что игрок смотрит в точку надир (прямо под ноги), а 192 — в зенит (над головой). Интервал значений 64-191 никогда не может быть реализован, поскольку игрок не может смотреть выше или ниже чем 64 → 0, 255 → 192. Например, если игрок поворачивает камеру из надира вверх, то значение склонения будет спадать из 64 до 0, где 0 это линия горизонта. Далее, после пересечения этой линии значение изменится на 255 и будет спадать до 192. Однако клиент Minecraft Classic не делает анализ невозможных значений склонения, поэтому технически возможно обратить игрока «вверх ногами».

## Коды цветов

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

Амперсанд (`&`

), а затем шестнадцатеричное число в сообщении указывает клиенту сменить цвет при выводе текста.

Цветовое кодирование в начале сообщения будет работать только в том случае, если ID байт игрока меньше, чем 127. Если значение 127 или выше, игра автоматически добавляет `&e`

до сообщения, что делает его жёлтым. Тем не менее, цветовые коды после первого символа до сих пор работают. Если вы используете ID ниже 127, это не добавляет цветовой код, так что те, которые вы используете, будут работать.

Важно отметить, что амперсанд (`&`

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

Кроме того, `&k`

даст немного прокрутки текста, который используется в сплэшах и в финальных титрах

Также `&l`

, `&m`

, `&n`

и `&o`

создает жирный, зачеркнутый, подчеркнутый и курсив соответственно, а `&r`

сбрасывает предыдущие форматы текста.

Пример | Код | Название | Цвет текста | Цвет фона | ||||||
---|---|---|---|---|---|---|---|---|---|---|

R | G | B | HEX | R | G | B | HEX | |||

&0 | Черный | 0 | 0 | 0 | #000 | 0 | 0 | 0 | #000000 | |

&1 | Темно синий | 0 | 0 | 170 | #00A | 0 | 0 | 42 | #00002A | |

&2 | Темно зелёный | 0 | 170 | 0 | #0A0 | 0 | 42 | 0 | #002A00 | |

&3 | Аква (темный) | 0 | 170 | 170 | #0AA | 0 | 42 | 42 | #002A2A | |

&4 | Темно красный | 170 | 0 | 0 | #A00 | 42 | 0 | 0 | #2A0000 | |

&5 | Фиолетовый | 170 | 0 | 170 | #A0A | 42 | 0 | 42 | #2A002A | |

&6 | Золотой | 255 | 170 | 0 | #FA0 | 42 | 42 | 0 | #2A2A00 | |

&7 | Серый | 170 | 170 | 170 | #AAA | 42 | 42 | 42 | #2A2A2A | |

&8 | Темно серый | 85 | 85 | 85 | #555 | 21 | 21 | 21 | #151515 | |

&9 | Индиго | 85 | 85 | 255 | #55F | 21 | 21 | 63 | #15153F | |

&a | Светло зелёный | 85 | 255 | 85 | #5F5 | 21 | 63 | 21 | #153F15 | |

&b | Аква | 85 | 255 | 255 | #5FF | 21 | 63 | 63 | #153F3F | |

&c | Красный | 255 | 85 | 85 | #F55 | 63 | 21 | 21 | #3F1515 | |

&d | Розовый | 255 | 85 | 255 | #F5F | 63 | 21 | 63 | #3F153F | |

&e | Желтый | 255 | 255 | 85 | #FF5 | 63 | 63 | 21 | #3F3F15 | |

&f | Белый | 255 | 255 | 255 | #FFF | 63 | 63 | 63 | #3F3F3F |


### Коды форматирования

Текст может быть отформатирован с использованием символа `§`

, а затем буква. В настоящее время единственный способ использовать символ `§`

скопировать и вставить его. Он не может быть использован на многопользовательских серверах (сервер «кикает» пользователя, который пытается использовать символ), но он может быть использованы в книгах, хотя почти невидим.

Если код цвета используется после форматирования кода, форматирование кода будет отключено.

Будет смотреться как: X__Y__, тогда как

§nX&cY (§n X &c Y)

будет смотреться так:__X__Y



`§r`

может быть использован для сброса всех форматов текста за его пределами.

Например: `§nXXX§rYYY`

, будет рассматриваться как: __XXX__YYY

Код | Результат |
---|---|

§k | Случайный |

§l | Жирный
|

§m | |

§n | Подчеркнутый
|

§o | Курсив
|

§r | Сброс |