Creating packets
Learning wiki.vg
This site contains a description of the packets used in the Minecraft backend.
Select the core version on the website on which the server is located and click on the link of this version.
First, we need to find the packet that we need. All packets located in the SERVERBOUND
section - packets are sent to the server players in the CLIENTBOUND
section - from the server to the player.
We are obviously interested in the packets section CLIENTBOUND
.
Let’s choose a packet
SET CAMERA , since it has not changed since version 1.8.
This packet allows you to set a camera for the player, similar to the camera that occurs when you click on an entity in observer mode.
We see the following table on the website:
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. |
This table contains the packet number, the moment of gameplay when it can be received, what the packet is linked to, and a description of its contents.
First of all, we need to find out what this packet is called on the server. To do this, we will need the first three fields:
Getting the packet name
[wrapped] packet name (by|of) id %number% [(and|,)] state %string% [(and|,)] bound %string%
ID on the site is indicated by a number in the hexadecimal, using the module
Bitwise
we can specify the value as described on the site, or convert the number from the site to the decimal (choose how convenient for you).
on load:
broadcast packet name of id 0x50 and state "play" and bound "client"
After loading script, the name of this packet will be written in the chat - PacketPlayOutCamera
.
We won’t need any more code above, it was necessary to find out the name of the packet.
Next, we need to fill the buffer with the data described in the columns Field Name
, Field Type
, Notes
.
We will fill in a new structure - ByteBuf
. It is a set of bytes into which bytes can be written and read.
Creating a buffer
The expression below is used to create an empty buffer:
Filling the buffer with data
The following expressions are used to write to the 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%
Each expression provides a specific type, described in the section
Data type on wiki.vg .
Some complex types described on the site can be made up of simple ones, so they are missing in expressions.
Packet PacketPlayOutCamera
accepts a field with the type VarInt
and a value equal to the entity ID.
To get the identifier
use the following expression .
From the table, we know that you need to write this identifier with the type VarInt
. Let’s use the necessary expression:
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}
Since the table no longer contains data, we can create a packet from the buffer by its name.
Write index
Each write to the buffer shifts its Writer index
, which is the number of bytes written inside the buffer.
Writer index
you can find out or change it using the following expression:
writer index of %bytebuf%
Creating a packet from a buffer
The expression below allows you to create a packet based on the packet name and the filled buffer for subsequent sending.
[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}
We have created our first packet, it remains only to send it to the player.
Sending packets
The following expression is used to send packets:
send packet %packets% to %players%
The expressions below allow you to send a packet without calling event
on packet
send packet %packets% without [(trigger|call)[ing]] [the] event to %players%
send packet %packets% to %players% without [(trigger|call)[ing]] [the] event
To check the operability of the code above, aim the scope at any entity, and then write the command /packet_example
.
After executing the command, you will be looking from the entity’s face, even if you are not in observer mode.
This way you can create any packet by following the steps described above.