Create and send packets - Anarchick/skript-packet GitHub Wiki

Why would you like to create then send a packet ?

Remember, packets are informations between server and client. Manipulating packet allow client/server side fake information. Some examples :

  • Send a fake block to a player
  • Make each players see enemies with red leather armor, and allies with green leather armor
  • Hide an entity for a specific player
  • Make player see an entity glowing
  • Fake Gamemode
  • Fake Weather + weather glitch
  • Fix FOV change
  • Spawn a fake entity
  • Fake biome to force snowfall

Creation of a packet to make a fake block break stage

First, to create our %packet% we need the %packettype% wich is play_server_block_break_animation. As you can see it's a packet from to server to the client.

function breakAnimation(block: block, stage: number, players: players):
    set {_stage} to (round down {_stage}) ? 0
    {_stage} is between 0 and 9
    set {_packet} to new play_server_block_break_animation packet
    ...

We have to set all fields of this packet with set field %number% of %packet% to %object% Every entities has an unique ID incrementing by 1 at each new entity spawned since the start of the server to his stop. You can get an entity ID with the property expression [entity] id of %entity% or %entity%'s [entity] id (return a Number). The field 0 is an Integer wich represent the ID of the entity digging a block. An entity can dig only 1 block at times. If you use the same entity ID for multiple block break animation, the client will only show the last block digging so we have to use different ID.

    set field 0 of {_packet} to random integer between 0 and 999999

The field 1 is the NMS block position. NMS mean "net.minecraft.server" It's the vanilla code of Minecraft and change for every version + the code is obfuscated, that's why CraftBukkit and others are needed to make plugins. To get the NMS block position you can use the expression NMS from %location% Skript-Packet include an auto-converter so you can use :

    set field 1 of {_packet} to nms from location of {_block}
# OR
    set field 1 of {_packet} to {_block}

The field 2 is the stage, need an Integer

    set field 2 of {_packet} to {_stage} as int
# OR
    set field 2 of {_packet} to {_stage}

Our 3 fields are set. You need to send the packet but you have the choice if you want to trigger the Skript event on packet event play_server_block_break_animation or not :

function breakAnimation(block: block, stage: number, receivers: players):
    set {_stage} to (round down {_stage}) ? 0
    {_stage} is between 0 and 9
    set {_packet} to new play_server_block_break_animation packet
    set field 0 of {_packet} to random integer between 0 and 999999
    set field 1 of {_packet} to {_block}
    set field 2 of {_packet} to {_stage}
    send {_receivers::*} packet {_packet} without calling event

Creation of a packet for a fake gamemode/weather

We will use play_server_game_state_change for mc 1.16.x wich contains 2 fields but one of them is class net.minecraft.server.v1_16_R3.PacketPlayOutGameStateChange$a. Skript-Packet does not provide expression for this kind of field, you have to use the addon Skript-Reflect.

import:
    net.minecraft.server.v1_16_R3.PacketPlayOutGameStateChange$a

effect change client side gamemode of %players% to %gamemode%:
    trigger:
        set {_packet} to new play_server_game_state_change packet
        set field 1 of {_packet} to 0 if "%expression-2%" is "survival"
        set field 1 of {_packet} to 1 if "%expression-2%" is "creative"
        set field 1 of {_packet} to 2 if "%expression-2%" is "adventure"
        set field 1 of {_packet} to 3 if "%expression-2%" is "spectator" 
        set field 0 of {_packet} to new a(3) # reason
        send packet {_packet} to expression-1 without calling event

effect change client weather of %players% to level %number%:
    trigger:
        set {_packet} to new play_server_game_state_change packet
        set field 0 of {_packet} to new a(7) # reason
        set field 1 of {_packet} to expression-2
        send packet {_packet} to expression-1 without calling event