Создание пакета
Изучение wiki.vg
Данный сайт содержит в себе описание пакетов, использующихся в серверной части Minecraft.
Выбираем на сайте версию ядра, на которой стоит сервер и переходим по ссылке этой версии.
Для начала требуется найти пакет, который нам необходим. Все пакеты, находящиеся в разделе SERVERBOUND
- отправляются игроком - серверу, пакеты в разделе CLIENTBOUND
- от сервера к игроку.
Нас, очевидно интересует раздел пакетов CLIENTBOUND
.
Выберем пакет
SET CAMERA , так как он не изменялся с версии 1.8.
Данный пакет позволяет задать игроку камеру, аналогичную камере, которая происходит при клике на сущность в режиме наблюдателя.
Перед нами предстает следующая таблица на сайте:
Packet ID | State | Bound To | Field Name | Field Type | Notes |
---|---|---|---|---|---|
0x50 | Play | Client | Camera ID | VarInt | ID of the entity to set the client’s camera to. |
Данная таблица содержит в себе номер пакета, момент игрового процесса, когда он может быть получен, к чему привязан пакет, и описание его содержимого.
Первым делом нам необходимо выяснить, как этот пакет называется на сервере. Для этого нам понадобится три первых поля:
- id
- state
- bound
Получение названия пакета
[wrapped] packet name (by|of) id %number% [(and|,)] state %string% [(and|,)] bound %string%
ID на сайте обозначено числом в шестнадцатиричной системе счисления, при помощи модуля Bitwise мы можем указать значение как описано на сайте, так и перевести число с сайта в десятичную систему счисления (выбирайте как вам удобно).
on load:
broadcast packet name of id 0x50 and state "play" and bound "client"
После загрузки скрипта, в чате будет написано название данного пакета - PacketPlayOutCamera
.
Больше код выше нам не понадобится, он был необходим чтобы узнать название пакета.
Дальше нам необходимо заполнить буфер данными, которые описаны в столбцах Field Name
, Field Type
, Notes
.
Заполнять мы будем новую структуру - ByteBuf
. Она представляет из себя набор байт, в который можно записывать байты и считывать их.
Создание буфера
Для создания пустого буфера используется выражение ниже:
empty buffer
Заполнение буфера данными
Для записи в буфер используется следующие выражения:
write bytes %bytebuf% to %bytebuf%
write bool[ean] %boolean% to %bytebuf%
write uuid %string% to %bytebuf%
write string %string% to %bytebuf%
write utf[-| ]8 %string% to %bytebuf%
write position %vector% to %bytebuf%
write position %location% to %bytebuf%
write [unsigned] byte %number% to %bytebuf%
write [unsigned] short %number% to %bytebuf%
write float %number% to %bytebuf%
write double %number% to %bytebuf%
write int[eger] %number% to %bytebuf%
write long %number% to %bytebuf%
write angle %number% to %bytebuf%
write var[iable][ ]int[eger] %number% to %bytebuf%
write var[iable][ ]long %number% to %bytebuf%
Каждое выражение предоставляет определенный тип, описанный в разделе
Data type на wiki.vg .
Некоторые сложные типы, описанные на сайте, могут быть составлены из простых, поэтому они отсутствуют в выражениях.
Пакет PacketPlayOutCamera
принимает в себя поле с типом VarInt
и значением равным идентификатору сущности.
Для получения идентификатора
воспользуемся следующим выражением .
Из таблицы, мы знаем что записать данный идентификатор нужно с типом VarInt
. Воспользуемся необходимым выражением:
command packet_example:
trigger:
set {_buffer} to empty buffer
set {_entity} to target entity of player
set {_id} to entity id of {_entity}
write varint {_id} to {_buffer}
Так как таблица больше не содержит данных, мы можем создать пакет из буфера по его названию.
Write index
Каждая запись в буфер сдвигает его Writer index
, это количество записанных байт внутри буфера.Writer index
можно узнать, или изменить при помощи следующего выражеения:
writer index of %bytebuf%
%bytebuf%'s writer index
Создание пакета из буфера
Выражение ниже позволяет по названию пакета и заполненному буферу создать пакет для последующей отправки.
[create] packet %string% (from|of|with) %bytebuf%
command packet_example:
trigger:
set {_buffer} to empty buffer
set {_entity} to target entity of player
set {_id} to entity id of {_entity}
write varint {_id} to {_buffer}
set {_packet} to create packet "PacketPlayOutCamera" with {_buffer}
Мы создали наш первый пакет, осталось только отправить его игроку.
Отправка пакетов
Для отправки пакетов используется следующее выражение:
send packet %packets% to %players%
Выражения ниже позволяют отправить пакет, без вызова события on packet
send packet %packets% without [(trigger|call)[ing]] [the] event to %players%
send packet %packets% to %players% without [(trigger|call)[ing]] [the] event
/packet_example
.
После выполнения команды, вы будете смотреть от лица сущности, даже если вы не в режиме наблюдателя.
Таким образом вы можете создать любой пакет, следуя описанным выше действиям.