This is a tutorial that will teach you how to use packets.

What are packets?

Packets are what Minecraft uses to send information between a server and client. Each packet has a packettype. Packettypes describe what kind of information a packet holds and for what purpose that information should be used. There are two main kinds of packettypes: server and client. Server packettypes describe packets that are sent to a client from the server, and client packettypes describe packets that are received by the server from the client. Every packettype has a name that looks kinda like this: play_server_player_info. Here, play is that packettypes's group (Another classification of packets that you don't need to worry about) server means that that packettype is a server packettype, and player_info is the rest of its name.

How do we get a packet?

There are two ways you can get an actual packet: intercepting one by using a packet event, or creating one yourself. Packet events are called when a packet is either sent or received. They look like this:

on packet event %packettypes%:
#do stuff

This event has the following event-values:

event-packet #(The packet being sent/received)
event-packettype #(The packettype of the packet)
event-player #(The player sending/receiving)

And can also be cancelled.

Packet creation is done using this simple expression:

new %packettype% packet

What information is stored in a packet, and how do we access and modify it?

Now that you have access to a packet, you can modify its information. Here's a list of all the different syntaxes for packet information:

%type% pinfo %number% of %packet%
%type% array pinfo %number% of %packet%
%string% pinfo %number% of %packet%
%world% pentity %number% of %packet%
byte pnum %number% of %packet%
short pnum %number% of %packet%
int pnum %number% of %packet%
long pnum %number% of %packet%
float pnum %number% of %packet%
double pnum %number% of %packet%
byte array pnum %number% of %packet%
int array pnum %number% of %packet%
%string% pjson %number% of %packet%
%string% array pjson %number% of %packet%
%string% penum %number% of %packet%

Here, %number% is the index (starting from 0) and %packet% is the packet you are getting information from.
  • The first two allow you to put in a type, like 'string', to get all the strings. Keep in mind this doesn't work for all types.
  • The third one allows you to specify the method name for getting infos of a specific type in special cases.
  • The fourth allows you to get all the entities of the packet provided you specify the world (Either player's world or the world of the player who you will send to)
  • 5 through 12 allow you to get infos of different number types.
  • The next two are for getting infos of types that aren't in Skript yet, only one of which is supported - "ChatComponent" for the first one (Not the second one). Doing things with JsonObjects should be pretty easy if you look at skUnity. If not, feel free to ask questions on the MundoSK skUnity thread.
  • The last one is for modifying enum values of packets, where %string% is the name of the enum, like "WorldBorderAction".

All these infos are setttable, which is very important, as it allows you to modify the information in the packet.

How do we send and simulate receiving packets?

To send a packet that you have created, use this effect:

send %players% packet[s] %packets%

You can simulate the server receiving a packet from a player using this effect:

receive packet[s] %packets% from %players%

Helpful Resources provides a list of packets, their fields, and what their fields represent. It can be useful for knowing what each pinfo of a packet means, however most of the packet names are different from their MundoSK names (which are based on their ProtocolLib names), and the fields aren't always 100% the same.

PacketWrapper created by one of ProtocolLib's developers is a library of wrappers for all the packets, It has methods that tell you exactly what each pinfo represents and sometimes also has int values telling you what an int pnum's different values mean. It was made for 1.11, but if you go through its history you will be able to see older versions of the wrappers for previous versions.

The PacketType class from ProtocolLib has a 100% up-to-date list of all of the packettypes available.

The EnumWrappers class from ProtocolLib has a list of all the enums/values that can be used in the penum expression.

Questions? Comments? Suggestions or improvements? Comment below!