-
Notifications
You must be signed in to change notification settings - Fork 1
Examples
This page lists examples of things you can do with PacketEventsSK. This page is made for you to understand the syntax and ideas of package management, do not just copy paste the listed content.
Based on PacketEventsSK v1.1.3 with SkBee v3.23.0 on Paper v26.1.2
on join:
set {_p} to player
set {_meta} to a new fake text display meta:
display billboard: center
display content: "<rainbow>WELCOME %{_p}%"
set {_display} to a new fake text display entity:
location: location 2 blocks infront of player
viewers: player
meta: {_meta}
set {_interactionMeta} to a new fake interaction meta:
interaction height: 1
interaction width: 2
set {_interactable} to a new fake interaction entity:
location: location 2 blocks infront of player
viewers: player
meta: {_interactionMeta}
set {-interactables::%{_p}'s uuid%} to fake entity id of {_interactable}
wait 5 seconds
kill fake entities {_display} and {_interactable}
clear {-interactables::%player's uuid%}
on serverbound interact entity:
set {_id} to packet field entity id of event-packet
set {_hand} to packet field hand of event-packet
set {_sneaking} to packet field sneaking state of event-packet
if all:
{_id} is {-interactables::%player's uuid%}
# this packet is sent for each hand when just regular clicking
# "main hand" is parsed as equipment slot if literal so we parse from text
{_hand} is "main hand" parsed as interaction hand
{_sneaking} is false
then:
send "<rainbow>welcome player!"Based on PacketEventsSK v1.1.4 with SkBee v3.23.0 on Paper v26.1.2
This examples can be used to hide things such as coordinates from players' f3 menus. It's a rather simple example. Full list can be found here: Debug Screen info lines (more info on entity status can be found here: Entity Statuses)
# hides certain things (including XYZ) from the f3 menu
command toggleDebug:
trigger:
set {_entityId} to protocol id of player
if {-debugMode::%player's uuid%} is true:
set {-debugMode::%player's uuid%} to false
set {_status} to 23
else:
set {-debugMode::%player's uuid%} to true
set {_status} to 22
set {_packet} to a new clientbound entity status packet:
entity id: {_entityId}
status: {_status}
send packet {_packet} to playerBased on PacketEventsSK v1.1.3 with SkBee v3.23.0 on Paper v26.1.2
Created by Crebs huge shoutout!
Confetti using text displays
function confetti(p: player):
loop 1000 times:
confettiPiece({_p})
wait 1 tick
local function emptyText(loc: location):: fake entity:
set {_meta} to text display meta data:
display content: " "
display text shadowed state: true
display billboard: center
display scale: vector(1.2,1.2,1.2)
display translation: vector(-0.03,0.65,0)
display background color: rgb(random integer between 0 and 255, random integer between 0 and 255, random integer between 0 and 255)
display view range: 1
display transform interpolation duration: 2 ticks
display interpolation delay: 0 ticks
return a new fake text display entity:
viewers: all players
location: {_loc} ~ vector(0,0.5,0)
meta: {_meta}
local function confettiPiece(p: player):
set {_loc} to {_p}'s location ~ (vector in direction of {_p})*vector(2.5, 2.25, 2.5)
set {_e} to emptyText({_loc})
set {_v} to vector(random number between -0.25 and 0.25, random number between 0.15 and 0.35, random number between -0.25 and 0.25)
set {_axis} to vector(random number between -1 and 1, random number between -1 and 1, random number between -1 and 1)
set {_angle} to random number between 0 and 360
set {_spin} to random number between 10 and 25
run 1 tick later repeating every 2 ticks:
add 1 to {_c}
if {_c} >= 70:
kill fake entity {_e}
stop
set {_v} to ({_v} * vector(0.93, 1, 0.93)) - vector(0, 0.05, 0) + vector(random number between -0.01 and 0.01, 0, random number between -0.01 and 0.01)
set {_t} to vector(-0.03, 0.65, 0) + {_v}
set meta display translation of {_e} to {_t}
add {_spin} to {_angle}
set meta display left rotation of {_e} to axisAngle({_angle}, {_axis})Based on PacketEventsSK v1.1.3 with SkBee v3.23.0 on Paper v26.1.2
This example makes use of a sign exploit described in MC-265322 and on wurst wiki. It can be used to see which mods are or aren't installed on a connected player. (and is thus very powerful for anti cheating purposes)
Basically the way it works:
- server sends a fake sign with a line having a translatable component or keybind component (
clientbound block changepacket andclientbound block entity datapacket) - server forces the client to open the editor of the sign (
clientbound open sign editorpacket) - server forces the client to close the editor (
clientbound close windowpacket) - client closes the editor and as a response sends the "new content" (which is unchanged) to the server (
serverbound update signpacket received by server on line 57) - server reads the new content: if it parsed the translatable/keybind component it has the keybind set and thus has the mod otherwise not
on load:
delete {-blackListedKeybinds::*}
add "key.freecam.toggle" to {-blackListedKeybinds::*}
add "key.freecam.playerControl" to {-blackListedKeybinds::*}
add "key.freecam.tripodReset" to {-blackListedKeybinds::*}
add "key.freecam.configGui" to {-blackListedKeybinds::*}
function createSignNBT(bind: string) :: nbt compound:
set {_nbtString} to "{front_text:{messages:[{""keybind"":""%{_bind}%""},{""text"":""""},{""text"":""""},{""text"":""""}]}}"
return nbt compound from {_nbtString}
function startKeybindChecks(p: player):
set {_uuid} to uuid of {_p}
delete {-keybindQueue::%{_uuid}%::*}
loop {-blackListedKeybinds::*}:
add loop-value to {-keybindQueue::%{_uuid}%::*}
checkNextKeybind({_p})
function checkNextKeybind(p: player):
set {_uuid} to uuid of {_p}
set {_keybind} to first element of {-keybindQueue::%{_uuid}%::*}
if {_keybind} is set:
check({_p}, {_keybind})
else:
delete {-keybindQueue::%{_uuid}%::*}
function check(p: player, keybind: string):
set {_pos} to vector of {_p}'s location
set {_blockPacket} to a new clientbound block change packet:
block position: {_pos}
block state: oak sign[]
set {_setTextPacket} to a new clientbound block entity data packet:
block position: {_pos}
block entity type: sign block entity type
nbt compound: createSignNBT({_keybind})
set {_signPacket} to clientbound open sign editor packet:
block position: {_pos}
sign side: front
set {_closeWindowPacket} to a clientbound close window packet
set {_revertBlockPacket} to new clientbound block change packet:
block position: {_pos}
block state: air[]
# Sends the packets (order sensitive)
send packet {_blockPacket}, {_setTextPacket}, {_signPacket}, {_closeWindowPacket} and {_revertBlockPacket} to {_p}
on serverbound update sign packet sync processed:
set {_p} to event-player
set {_uuid} to uuid of {_p}
if {-keybindQueue::%{_uuid}%::*} is set:
set {_firstIndex} to first element of indices of {-keybindQueue::%{_uuid}%::*}
set {_expected} to {-keybindQueue::%{_uuid}%::%{_firstIndex}%}
delete {-keybindQueue::%{_uuid}%::%{_firstIndex}%}
set {_updateSignPacket} to event-packet
set {_text} to first element of packet sign lines of event-packet
if {_text} is not {_expected}:
delete {-keybindQueue::%{_uuid}%::*}
kick {_p} due to "Unsupported client modification detected!"
else:
send "%{_p}% passed keybind check for: %{_expected}%" to console
wait 1 tick
if {_p} is online:
checkNextKeybind({_p})
on join:
wait 3 seconds
startKeybindChecks(player)Based on PacketEventsSK v1.1.3 with SkBee v3.23.0 on Paper v26.1.2
This example makes use of another unintended feature of the minecraft protocol that allows for a scrollable GUI (where the content scrolls with you)
There are multiple ways of doing this but one of the ways is intercepting a serverbound select bundle item packet and based of it's data determining in which direction the client scrolled.
Works like this:
- user scrolls, the mc vanilla client sends
serverbound select bundle item - the server receives the packet and reads it's content (on line 34-36)
- we evaluate if the user scrolled up or down based on the data (line 68-87)
- we update the GUI accordingly
on load:
set {-baseBundle} to a bundle with item flags hide additional tooltip
add stone, stone, and stone to bundle contents of {-baseBundle}
command blocks:
trigger:
openBlocks(player)
function openBlocks(p: player, scroll: integer = 0):
set {_gui} to new chest inventory with 6 rows named "Blocks"
set {-prevPlayerScroll::%{_p}'s uuid%} to {_scroll}
set {_skipAmount} to {_scroll} * 9
set {_slot} to 0
loop blocks:
if any:
loop-iteration <= {_skipAmount}
type of loop-value is air
then:
continue
if {_slot} >= 54:
stop loop
set {_i} to {-baseBundle} named proper case "&f%loop-value%"
add stone, dirt and cobblestone to bundle contents of {_i}
set item model of {_i} to "%namespaced key of loop-value%"
set slot {_slot} of {_gui} to {_i}
add 1 to {_slot}
open {_gui} to {_p}
on serverbound select bundle item sync processed:
set {_index} to packet selected item index of event-packet
set {_slotId} to packet slot id of event-packet
set {_action} to getScrollAction({-prevScroll::%{_slotId}%}, {_index}, 3)
if {_action} is "DONE":
clear {-prevScroll::%{_slotId}%}
else:
set {-prevScroll::%{_slotId}%} to {_index}
if {_action} is "UP":
clear {-prevScroll::%{_slotId}%}
openBlocks(player, {-prevPlayerScroll::%player's uuid%} + 1)
else if all:
{_action} is "DOWN"
{-prevPlayerScroll::%player's uuid%} - 1 > 0
then:
clear {-prevScroll::%{_slotId}%}
openBlocks(player, {-prevPlayerScroll::%player's uuid%} - 1)
local function getScrollAction(prevIndex: integer, newIndex: integer, maxIndex: integer) :: string:
if {_newIndex} is -1:
return "DONE"
if {_prevIndex} is not set: # first scroll
if {_newIndex} is {_maxIndex} - 1:
return "UP"
else if {_newIndex} is 0:
return "DOWN"
if all:
{_prevIndex} is {_maxIndex} - 1
{_newIndex} is 0
then:
return "DOWN"
if all:
{_prevIndex} is 0
{_newIndex} is {_maxIndex} - 1
then:
return "UP"
if {_prevIndex} > {_newIndex}:
return "UP"
else:
return "DOWN"Caution
This is no longer the supported wiki, please refer to https://docs.packeteventssk.threeadd.dev/