About the addon

Skcrew - this is an addon for the plugin Skript , expanding the capabilities of the language.

The addon includes the following functionality:

  • working with files and folders
  • bitwise and logical operations with numbers
  • plugin support floodgate and sending forms
  • simplified creation of game GUIs
  • parsing and executing code from text
  • drawing on maps
  • editing player rights
  • execution of commands on behalf of a player with operator rights
  • implementation InventoryDragEvent and the expressions he needs
  • asynchronous/synchronous web requests
  • getting information about the technical components of the server
  • interaction with SQL-like databases
  • working with strings using regular expressions
  • plugin support ViaVersion to get the player’s version
  • work with game worlds: upload, copy, delete
  • support for proxy communication between servers ( Velocity , Bungeecord )
  • working with packets: creating, sending, receiving, editing

Subsections of About the addon

installation

Download the latest version from this link and move the downloaded file to the plugins directory inside the game server or proxy server
After launching the game or proxy server, the Skcrew folder will be created in the plugins folder, where the addon configuration file is located. In it, you can enable or disable certain modules, as well as adjust some settings, if necessary.

The standard configuration for the game server (Spigot and similar forks):

bitwise:
  enabled: true
files:
  enabled: true
floodgate:
  enabled: true
gui:
  enabled: true
interpretate:
  enabled: true
maps:
  enabled: true
other:
  enabled: true
packets:
  enabled: true
permissions:
  enabled: true
requests:
  enabled: true
runtime:
  enabled: true
sockets:
  enabled: false
  server-address: "127.0.0.1"
  server-port: 1337
  client-autoreconnect-time: 5
sql:
  enabled: true
  driver-class-name: "default"
string-utils:
  enabled: true
viaversion:
  enabled: true
world:
  enabled: true

Standard configuration for a proxy server ( Velocity or Bungeecord ):

socket-server-port: 1337

web-server-enabled: true
web-server-port: 1338
web-server-user: admin
web-server-password: admin

Supported versions of the Skript:

Addon modules and their support on different server versions:

Module1.8.81.12.21.14+
bitwise
files
floodgate
gui
interpretate
maps
other
packets
permissions
requests
runtime
sockets
sql
string-utils
viaversion
world

The module will be automatically disabled if it is not supported by the server version, so do not worry if you did something wrong

Subsections of Modules

BITWISE

This module allows you to perform logical and bitwise operations with numbers.

Special thanks to the Pesekjak for creating an addon Bitshift . Part of the code and the idea was borrowed from him.

Binary operation OR

Copies a bit to the result if it exists in both operands.

%number% | %number%

Logical operation OR

If at least one is True, then the truth will be returned.

%boolean% || %boolean%

Binary operation AND

Copies a bit if it exists in any of the operands.

%number% & %number%

Logical operation AND

If both operands are True, then true will be returned.

%boolean% && %boolean%

Binary operation XOR

Copies a bit if it is set in one operand, but not in both.

%number% ^^ %number%

Bitwise shift to the left

The value of the left operands moves to the left by the number of bits specified by the right operand.

%number% << %number%

Bitwise shift to the right

The value of the right operands moves to the right by the number of bits specified by the left operand.

%number% >> %number%

Bitwise zero shift to the right

The value of the left operands is moved to the right by the number of bits specified by the right operand, and the shifted values are filled with zeros.

%number% >>> %number%

Binary complement operation (reflection)

Each bit of the number will be inverted.

~%number% 

A number in binary notation

0(b|B)<[0-1]+>
set {_binary} to 0b22

A number in the hexadecimal system

0(x|X)<[A-Fa-f0-9]+>
set {_hexadecimal} to 0xFF

Files

This module allows you to perform operations with files.

Special thanks to the Olyno for creating an addon Skent . This module was developed due to the fact that at that moment he abandoned development, but now his addon has an option for asynchronous work with files. Part of the code was borrowed from the first version of his addon.

EXPRESSIONS
CONDITIONS
EFFECTS

Subsections of Files

EXPRESSIONS

In fact, you get either a real file, if there is one, or an abstract file that can then be created.

[the] (file[s]|dir[ector(y|ies)]) %strings%
set {_file} to file "eula.txt"

Get an absolute file

Absolute - that is, the one with the path starting from the root of the file system

absolute [(file|dir[ectory])] of %path%
%path%'s absolute [(file|dir[ectory])] 
set {_file} to absolute file of file "eula.txt"

Get all files inside a directory

It also allows you to do this recursively, getting files in the directory and in all internal directories

all [the] files and [all] [the] dir[ectorie]s (in|of|from) %path%
all [the] files (in|of|from) %path%
all [the] dir[ectorie]s (in|of|from) %path%
all [the] sub[(-| )]files and [all] [the] sub[(-| )]dir[ectorie]s (in|of|from) %path%
all [the] sub[(-| )]dir[ectorie]s (in|of|from) %path%
all [the] sub[(-| )]files (in|of|from) %path%
glob (files|dir[ectorie]s) %string% (in|of|from) %path%
loop all files from file "plugins/":
  broadcast "%loop-value%"

Get the text content of the file

[the] content of %path%
[the] %path%'s content
set {_file} to content of file "eula.txt"
replace all "false" with "true" in {_file}
set content of file "eula.txt" to {_file}

Get the name of a file or directory

[the] (file|dir[ectory])name of %path%
[the] %path%'s (file|dir[ectory])name
loop all files from file "plugins/":
  broadcast filename of loop-value

Read a line/lines of a file or change them

[the] line %number% (from|of|in) %path%
[all] [the] lines (from|of|in) %path%
set line 1 of file "eula.txt" to "eula=true"

Get the directory where the file/folder is located

parent [(file|dir[ectory])] of %path%
%path%'s parent [(file|dir[ectory])]
set {_file} to parent of file "eula.txt"

Get file size in bytes

file size of %path%
%path%'s file size

Get the last access date of a file

[last] access (date|time) of %path%
%path%'s [last] access (date|time)

Get the last modified date of a file

[last] modified (date|time) of %path%
%path%'s [last] modified (date|time)

Get file creation date

create[d] (date|time) of %path%
%path%'s create[d] (date|time)

CONDITIONS

Checking the file for its actual existence

%path% (is|does)[(n't| not)] exist[s]
if file "eula.txt" is exists:
  broadcast "Yea, file eula.txt is exists"

Checking that the file is a directory

%path% is[(n't| not)] dir[ectory]
if file "eula.txt" is not directory:
  broadcast "Yea, file eula.txt is not directory, it is regular file"

Checking that the file is a file

%path% is[(n't| not)] file
if file "eula.txt" is file:
  broadcast "Yea, file eula.txt is regular file"

EFFECTS

Copy a file or directory

It also allows you to specify a parameter for overwriting if the file already exists

copy %path% to %path% [with (replac|overwrit)(e|ing)]
copy file "plugins/Skcrew.jar" to file "./"

Create a simple file

It also allows you to specify the text content of the file being created

create %paths% [with [(text|string|content)] %strings%]
create file "eula.txt" with content "eula=true"

Delete a file or directory

delete %paths%
delete file "plugins/Skcrew.jar"

Move a file or directory

It also allows you to specify a parameter for overwriting if the file already exists

move %paths% to %path% [with (overwrit|replac)(e|ing)]
move file "plugins" to file "disabled_plugins"

Rename a file or directory

It also allows you to specify a parameter for overwriting if the file already exists

rename %paths% to %string% [with (overwrit|replac)(e|ing)]
rename file "plugins/Skript/scripts/mycoolscript.sk" to "-mycoolscript.sk"

Unpack the zip archive

It also allows you to specify a parameter for overwriting if the file already exists

unzip %path% to %path% [with (overwrit|replac)(e|ing)]
unzip file "myarchive.zip" to file "./"

Create a zip archive

It also allows you to specify a parameter for overwriting if the file already exists

zip %paths% to %path% [with (overwrit|replac)(e|ing)]
zip file "world/" to file "backupworld.zip"

FLOODGATE

This module allows you to interact with the plugin Floodgate , and also create interactive forms

A plugin is required for the module to work Floodgate

Check that the player has logged in with Bedrock Edition

%player% [(is|does)](n't| not) from floodgate

Get the localization of the player

[the] be[[drock] [edition]] (locale|language) of [the] [floodgate] %player%           
%player%'s be[[drock] [edition]] (locale|language) [of [the] floodgate]

Get the name of the player’s device

[the] [be[[drock] [edition]]] (platform|device) of [the] [floodgate] %player%
%player%'s [be[[drock] [edition]]] (platform|device) [of [the] floodgate]

Get the Bedrock version of the client

[the] be[[drock] [edition]] version of [the] [floodgate] %player%
%player%'s be[[drock] [edition]] version [of [the] floodgate]

Subsections of Floodgate

FORM TYPES

Creating a new form

It is the simplest form, which has only two buttons and a description block. The buttons are a conditional choice of ‘yes’ or ’no’.
The created form will be placed in the expression last created form

create [a] [new] modal form (with (name|title)|named) %string%
create modal form named "Modal form":
  set form content to "Please select one option"
  run on form close:
    broadcast "closed"
  run on form open:
    broadcast "opened"
  form button named "I like skript!":
    broadcast "Thank you!!!"
  form button named "I didnt like skript!":
    broadcast "USE DENIZEN INSTEAD!!!"
open last created form to player

modal form
modal form

Simple form

It is a form with buttons. There can be an unlimited number of buttons, in addition, the buttons can have images from the Internet.
The created form will be placed in the expression last created form

create [a] [new] simple form (with (name|title)|named) %string%
create simple form named "Simple form":
  form button named "button 1" with image "https://pics.clipartpng.com/Carrots_PNG_Clipart-465.png":
    broadcast "button 1 pressed"
  form button named "button 2":
    broadcast "button 2 pressed"
  form button named "button 3":
    broadcast "button 3 pressed"
open last created form to player

simple form
simple form

Custom form

It is a form with any elements except buttons. This type of forms allows you to use sliders, switches, input fields, selection fields, etc.
The processing of the form elements is carried out in the section on form result
The created form will be placed in the expression last created form

create [a] [new] custom form (with (name|title)|named) %string%
create custom form named "Custom form":
  form dropdown named "Select one value from list" with elements "one", "two", "three"
  form input named "Your password?" with placeholder "write your password"
  form label named "sample text"
  form slider named "music volume????" with minimum value 0 and maximum value 10
  form textslider named "select shit" with elements "value 1","value 2","value 3"
  form toggle named "yes or no?"
  run on form result:
    broadcast "%form toggle 1 value%"
open last created form to player

custom form
custom form

Last created form

[the] (last[ly] [(created|edited)]|(created|edited)) form

Open the form to the player

open %form% (for|to) %players%

FORM ELEMENTS

Buttons

The button is a section, the code inside of which will be executed when you click on it. After clicking on the button, the form will be automatically closed (a feature of Bedrock forms).

Can only be used in Modal form and Simple form .
The button with the image can only be used in Simple form

form(-| )button ((with (name|title))|named) %string% [with image %string%]
create modal form named "Modal form":
  form button named "My button":
    broadcast "Pressed button"
open last created form to player

Description of Modal form.

Allows you to specify or get a text description in Modal form. Allows you to specify both in an already created form and in the creation section Modal form

form['s] content
content of form 
%form%['s] content
content of %form%
create modal form named "Modal form":
  set content of form to "Sample text"
open last created form to player

Custom form Elements

Get the value of the Custom form Elements after closing, it is possible only in the section run on form result.

User Input element

Creates an element in which the user can enter any text. Allows you to specify the initial text inside the field, and the placeholder text

form(-| )input (with name|named) [%string% (with|and) [placeholder] %string%[(, | (with|and) ) [def[ault] [value]] %string%]]
Choosing from the list

Creates an element in which the user can select one of the suggested values. Allows you to specify the initial value by index.

form(-| )drop[(-| )]down (with name|named) %string% (with|and) [elements] %strings%[(, | (with|and) ) [def[ault] [(element [index]|index)]] %number%]
Label, note, text

Creates an element with text.

form(-| )label [(with (name|title)|named)] %string%
A slider with a numeric value selection

Creates an element in the form of a strip with a control in which the user can specify a value. Allows you to specify the minimum and maximum threshold of numbers, the initial value and the slider step.

form(-| )slider (with name|named) %string% [[(with|and) [min[imum] [value]] %number%[(, | (with|and) ) [max[imum] [value]] %number%[(, | (with|and) ) [def[ault] [value]] %number%[(, | (with|and) ) [[step] [value]] %number%]]]]
A slider with a selection of values

Creates an element similar to the numeric slider, but with text values. Allows you to specify the initial value by index.

form(-| )(text|step)[(-| )]slider (with name|named) %string% (with|and) [elements] %strings%[(, | (with|and) ) [def[ault] [(element [index]|index)]] %number%]
The switch element.

It has only two states, on or off. You can specify the initial state.

form(-| )toggle (with name|named) %string% [(with|and) [def[ault]] [value] %boolean%]

Processing the results

Get the player inside the form

Use this expression to get the player inside the form, instead of the usual player or any variables.

form(-| )player

Getting the type of the created form

form[(-| )]type of %form%
%form%'s form[(-| )]type

Available types of forms for comparison:

  • custom form
  • modal form
  • simple form

Execute the code when opening/closing the form

run (when|while) (open[ing]|clos(e|ing)) [[the] form]
run (when|while) [the] form (opens|closes)
run on form (open[ing]|clos(e|ing))
create modal form named "Modal form":
  run on form close:
  	broadcast "%formplayer%" #will show name of player what close form
open last created form to player

Cancel or allow closing of the form

By default, closing the form is allowed. If you disable it, the form will be reopened after the selection

cancel [the] form clos(e|ing)
uncancel [the] form clos(e|ing)

Get the reason for closing the form

This expression can only be used in the section when closing the form

[form(-| )]close reason

Available reasons for closing for comparison:

  • close
  • (submit|success)
  • invalid[ response]

Execute the code on form submit

run on form (result|submit)
create custom form named "Custom form":
  form toggle named "toggle value"
  run on form result:
    broadcast "%form toggle 1 value%"
open last created form to player

Custom form elements

This expression can only be used in the section when the form is successfully closed

[form[(-| )]](drop[(-| )]down|input|slider|step[(-| )]slider|toggle) %number% [value]
value of [form[(-| )]](drop[(-| )]down|input|slider|step[(-| )]slider|toggle) %number%

For button processing Modal form и Simple form use the button creation section

Subsections of GUI

Creating a GUI

Creating a new GUI

Creates a new GUI and puts it in the result of the expression last created GUI

create [a] [new] gui with %inventory% [(and|with) ([re]move[e]able|stealable) items] [(and|with) shape %strings%]
create a gui with chest inventory with 3 rows named "My GUI":
  #do some stuff
open last created gui to player

empty gui
empty gui

The last argument allows you to use prepared templates for the arrangement of interactive elements. For example, if we open the funnel inventory, we can specify the template “xxixx”, and then, when creating the element “x”, the first, second, fourth and fifth slots will be with this element.

create a gui with chest inventory with 3 rows named "My GUI" with shape "xxxxxxxxx","x-------x","xxxxxxxxx":
  make gui slot "x" with dirt
open last created gui to player

gui shape
gui shape

Edit an already created GUI

Allows you to redefine interactive elements inside an already created GUI

(change|edit) [gui] %gui%

Create an interactive element

When you click on this element, the code inside the section will be executed. The expression below creates an interactive element on the next empty inventory slot.

(make|format) [the] next gui [slot] (with|to) [([re]mov[e]able|stealable)] %itemtype%

The following expression allows you to specify the value from the template or the slot number to create the element.

(make|format) gui [slot[s]] %strings/numbers% (with|to) [([re]mov[e]able|stealable)] %itemtype%
create a gui with chest inventory with 3 rows named "My GUI":
  make gui slot 1 with stone named "Click for hello world!":
    broadcast "Hello world!"

Delete an interactive element

(un(make|format)|remove) [the] next gui [slot]
(un(make|format)|remove) gui [slot[s]] %strings/numbers%
(un(make|format)|remove) all [[of] the] gui [slots]

When opening the GUI

The code inside this section will be executed after opening the GUI to the player.

run (when|while) open[ing] [[the] gui]
run (when|while) [the] gui opens
run on gui open[ing]

When closing the GUI

The code inside this section will be executed after the GUI is closed by the player.

run (when|while) clos(e|ing) [[the] gui]
run (when|while) [the] gui closes
run on gui clos(e|ing)

Last created GUI

Returns the last GUI created/modified

[the] last[ly] [(created|edited)] gui

PROCESSING THE RESULTS

The player’s open GUI

Returns the currently open GUI of the player

%players%'s gui
gui of %player%'s

Check whether any GUI is open or not for the player

%players% (has|have) a gui [open]
%players% do[es](n't| not) have a gui [open]

The next GUI slot

Returns the number or letter of the template of the next GUI slot

%guis%'[s] next gui slot[s]
[the] next gui slot[s] of %guis%

Subsequent expressions can only be used in the GUI creation sections and creating an interactive element

[the] next gui slot

The name GUI inventory

%gui%'s gui(-| )name
gui(-| )name of %gui%

GUI Inventory Size

%gui%'s gui(-| )size
gui(-| )size of %gui%

GUI Template

%gui%'s gui(-| )shape
gui(-| )shape of %gui%

The ability to take items in the GUI

%gui%'s gui(-| )lock(-| )status
gui(-| )lock(-| )status of %gui%

Current, editable GUI

[the] gui

Clicked Slot

[the] gui(-| )raw(-| )slot

The hotkey of the clicked slot

[the] gui(-| )hotbar(-| )slot

GUI inventory that is being edited

[the] gui(-| )inventory

Action inside the GUI

For example, a player made a double click, which caused things to gather in the cursor slot.

[the] gui(-| )inventory(-| )action

Type of click

For example, a player made a click with the Shift key held down.

[the] gui(-| )click(-| )(type|action)

Cursor slot

[the] gui(-| )cursor[(-| )item]

The type of clicked slot

[the] gui(-| )slot(-| )type

The clicked item

[the] gui[(-| )(clicked|current)](-| )item

The expression used instead of the player inside the GUI section

[the] gui(-| )player

Be sure to use this expression inside the GUI or interactive element creation section instead of player, otherwise your code will not work as you expect it to.

Players who have a GUI open

[the] gui(-| )(viewer|player)s

ID of the clicked slot

[the] gui(-| )slot(-| )id

Subsequent expressions can only be used in the closing GUI section

Cancel the closure

Prohibits the player from closing the GUI by reopening it while preserving the GUI parameters

cancel [the] gui clos(e|ing)

Allow closure

Allows the player to close the GUI

uncancel [the] gui close(e|ing)

Interpretate

Execute a block of code from the text

Allows you to pass a list of lines of code to execute them

evalnode %strings%
evalnode "if 1 is 2:","  broadcast ""yes"""

Execute a block of code from the text

Allows you to execute independent lines of code (works faster, but not as functional)

eval[uate] %strings%
evaluate "broadcast ""yes"""

Subsections of Maps

Creating a map

Creating a canvas

Returns an object from which, later, you can get a map in the form of an object

[new|empty] drawing map

When creating a map in a folder /skcrew/maps/ A map image file will be created. The file name will match the ID of the game card.

Getting a canvas by card ID

[drawing] map (by|with) id %number%

Getting an item from the canvas

Accepts canvas as an argument, returns a game item - a map

[the] map item (from|of) %map%

Getting a canvas from an object

Accepts a map item as an argument, returns a canvas for drawing

[drawing] map (of|from) item %itemstack%

Forced saving of the canvas

save map %map%

Maps are not loaded on their own, so that they do not disappear - put the canvases of these maps in global variables.

The addon supports automatic serialization of data associated with canvases.

Painting on canvas

Get the color of a pixel on the canvas

pixel %number%(,[ ]| )%number% of %map%

It does not allow you to change the color of a pixel, use the expression paint over a pixel

Paint over a pixel

Allows you to set a specific color for a pixel based on its coordinates. The first two arguments point to the coordinates on the canvas, the subsequent ones are in RGB or RGBA format, and the last one is the canvas.

draw pixel [at] %number%(,[ ]| )%number% [with colo[u]r] %number%(,[ ]| )%number%(,[ ]| )%number%[(,[ ]| )%-number%] on [map] %map%
set {_map} to new drawing map
draw pixel at 1,1 with color 255,0,0 on map {_map}
# will draw pixel at 1,1 with pure red color

Paint over pixels

Allows you to set a specific color for pixels in the range.
The first four arguments point to the coordinates on the canvas, the next color is in RGB or RGBA format, and the last one is the canvas.

draw pixels (from|between) %number%(,[ ]| )%number% [to] %number%(,[ ]| )%number% [with colo[u]r] %number%(,[ ]| )%number%(,[ ]| )%number%[(,[ ]| )%-number%] on [map] %map%
set {_map} to new drawing map
draw pixels from 10,10 to 50,50 with color 255,0,0 on map {_map}
# will draw pure red square on map

Draw a line

Accepts similar arguments with pixel coloring.

draw line (from|between) %number%(,[ ]| )%number% [to] %number%(,[ ]| )%number% [with colo[u]r] %number%(,[ ]| )%number%(,[ ]| )%number%[(,[ ]| )%-number%] on [map] %map%

Draw a bezier curve

The first four arguments are the points between which the main part of the curve will be. The following four arguments allow you to optionally specify control points for the curve offset. The following arguments are similar to drawing a line or coloring pixels.

draw bezier curve (from|between) %number%(,[ ]| )%number% [to] %number%(,[ ]| )%number% [[with] control points] %number%(,[ ]| )%number% [and] %number%(,[ ]| )%number% [with colo[u]r] %number%(,[ ]| )%number%(,[ ]| )%number%[(,[ ]| )%-number%] on [map] %map%

Draw a circle

The first two arguments are the center of the circle, the next one is the radius of the circle. The other arguments are color and canvas.

draw circle at %number%(,[ ]| )%number% with radius %number% [with colo[u]r] %number%(,[ ]| )%number%(,[ ]| )%number%[(,[ ]| )%-number%] on [map] %map%

Draw an image

The image should be in the images/ folder of the addon. Takes the name of the image file as the first argument.

draw image %string% on [[the] map] %map%

Write text on the map

The first argument is the text to be written, the next two arguments describe the font name and font size.

draw text %string% [at] %number%(,[ ]| )%number% [with font %-string%] [with size %-number%] [with colo[u]r] %number%(,[ ]| )%number%(,[ ]| )%number%[(,[ ]| )%-number%] on [map] %map%

OTHER

Give or drop

Gives items to the player, if there is no place in his inventory, he throws them next to him

give or drop %itemtypes/experiences% to %players%

Inventory drag event

An event triggered when a player presses the mouse button to distribute items in the inventory

on inventory drag

Getting added items in this event

Returns a list of things that have been added

new items
added items

Get affected slots

Returns the slot numbers that have been changed in the same order as it returns the expression for things

changed slot[s]
event[-]slots

Subsections of Packets

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 IDStateBound ToField NameField TypeNotes
0x50PlayClientCamera IDVarIntID 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:

  • id
  • state
  • bound

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:

empty buffer
command packet_example:
  trigger:
    set {_buffer} to 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%
%bytebuf%'s writer index

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

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 {_packet} to player
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.

Packet handling

The event of receiving or sending a packet.

This event allows you to receive a packet sent by the player or sent by the server to the player.

on packet:
on packet <packet name>:

<packet name> - allows you to specify the name of the tracking packet.

The event can be canceled. In this case, the packet will not be received by the server, or sent to the player

This event has built-in expressions.

  • event-packet - to receive the packet
  • event-player - to get a player

event-packet it can be replaced with set event-packet to %packet%, provided that no execution delay was used

on packet PacketPlayOutOpenSignEditor:
  broadcast "%event-player%"
  broadcast "%event-packet%"
  cancel event

In this example, the player’s nickname and the packet name are displayed in the chat. And then cancel sending this event to the player.
The packet itself forces the player to open the text editing window of the plate.

Getting a buffer from a packet

After receiving the buffer from the packet, we can read the fields indicated on wiki.vg

buffer (of|from) %packet%
%packet%'s buffer

Reading the buffer

To get values from the buffer, the following expressions exist, similar to writing to the buffer

read bool[ean] from %bytebuf%
read uuid from %bytebuf%
read string from %bytebuf%
read position from %bytebuf%
read [unsigned] byte from %bytebuf%
read [unsigned] short from %bytebuf%
read float from %bytebuf%
read double from %bytebuf%
read int[eger] from %bytebuf%
read long from %bytebuf%
read angle from %bytebuf%
read var[iable][ ]int[eger] from %bytebuf%
read var[iable][ ]long from %bytebuf%
read utf[(-| )]8 [with [len[gth]]] %number% from %bytebuf%

To read utf-8 you must also specify the length of the text in bytes

Reading occurs in the same order as writing a packet, provided that the packet was not created by you. If you created a package and want to read it (it is not known for what reason), then move its reader index to position zero.
Consider the packet PacketPlayOutOpenSignEditor

Packet IDStateBound ToField NameField TypeNotes
0x32PlayClientLocationPosition
Is Front TextBooleanWhether the opened editor is for the front or on the back of the sign
on packet PacketPlayOutOpenSignEditor:
  set {_buffer} to buffer from event-packet
  set {_position} to read position from {_buffer}
  set {_isFrontText} to read boolean from {_buffer}
  broadcast "%{_position}%"
  cancel event

The code above will display a Vector with the coordinates of the open plate in the chat.

Reader index

Each reading of the buffer shifts its Reader index, this is the number of bytes read inside the buffer.
Reader index you can find out or change it using the following expression:

reader index of %bytebuf%
%bytebuf%'s reader index

Disabling or enabling packet handling

For any player, you can enable or disable tracking of incoming or outgoing packets.

[(handl(e|ing))|(listen[ing] [of])] (in|out)coming packets of %player%
%player%'s [(handl(e|ing))|(listen[ing] [of])] (in|out)coming packets
on join:
  set listening incoming packets of player to false

ADDITIONALLY

Get the Entity ID

Returns the unique identifier of the entity

entity id of %entity%
%entity%'s entity id

Get or change the player’s Skin value

skin value of %player%   
%player%'s skin value

Get or change a player’s Skin signature

skin signature of %player%   
%player%'s skin signature

Clear player’s skin signature and value

delete skin properties of %player%
delete %player%'s skin properties

Get text bytes

Returns a list of bytes.
It is also possible to specify the required encoding. Default is UTF-8

bytes of %string% [with charset %string%]
%string%'s bytes [with charset %string%]

PERMISSIONS

Execute a command with operator rights

[execute] [the] command %strings% [by %-commandsenders%] as op
[execute] [the] %commandsenders% command %strings% as op
(let|make) %commandsenders% execute [[the] command] %strings% as op

User Rights Management

Allows you to delete, view, add rights to the user without additional plugins

%player%'s perm[ission][s]
perm[ission][s] of %player%
add "my.cool.permission" to player's perms
remove "not.cool.permission" from player's perms
broadcast "%player's perms%"

Subsections of Requests

EXPRESSIONS

Request header

Creates a new request header in the key:meaning

request (header|property) %string% %string%

Request Header Key

%request property%'s key
key of %request property%

The value of the request header

%request property%'s value
value of %request property%

EFFECTS

Asynchronous HTTP/S request

Executes a request with the specified method to the specified site using the specified headers and the specified request body. Returns the code and the body of the response.

[async[hronously]] request [%string%] to [url] %string% [with header[s] %request properties%] [(and|with) body %string%] [and store [[the] (body|result) in %object%] [and] [code in %object%]]

async request "GET" to url "https://crewpvp.xyz" and store the result in {_data} and code in {_code}

An asynchronous request cannot be used in functions where a value is returned. The result of an asynchronous request will be <none>

Synchronous HTTP/S request

Executes a request with the specified method to the specified site using the specified headers and the specified request body. Returns the code and the body of the response.

sync[hronously] request [%string%] to [url] %string% [with header[s] %request properties%] [(and|with) body %string%] [and store [[the] (body|result) in %object%] [and] [code in %object%]]

Block the main thread for the duration of the request, use wisely.

RUNTIME

This module allows you to get information about the load and some technical information about the equipment.

Run the command in the operating system

Executes a command in the console/terminal of the operating system.

[execute] [the] system command %strings%
(let|make) system execute [[the] command] %strings%

The amount of allocated RAM per process in bytes

[the] [server['s]] max memory
max memory of server
The amount of RAM used by the process in bytes
[the] [server['s]] used memory
used memory of server

Server uptime (process lifetime)

[the] server['s] uptime
[the] uptime of server

The number of processor cores installed on the server

processor['s] cores amount
[amount of] processor cores

The load factor of the server by this process

[the] process['s] [average] load
[average] load of process

Server load factor

[the] (system|cpu)['s] [average] load
[average] load of (system|cpu)

SOCKETS

This module allows servers under the control of a proxy server to exchange information via sockets.

For the module to work, you need to install Skcrew on a proxy server ( Velocity or Bungeecord ). In the configuration file on the proxy server, specify the port for opening the server socket, on the game server specify the address of the proxy server and the port of the open server socket.

Configuration on the proxy server

socket-server-port: 1337

Configuration on the game server

sockets:
  enabled: false
  server-address: "127.0.0.1"
  server-port: 1337
  client-autoreconnect-time: 5

client-autoreconnect-time - describes the time after which the game server will try to reconnect if the proxy server is disabled.

EXPRESSIONS
CONDITIONS
EFFECTS
EVENTS
SIGNALS
WEB API

Subsections of Sockets

EXPRESSIONS

Get the current server

Returns the current game server

(current|this) server

Get the server by name

Returns the server by the name under which it is written in the proxy server configuration.
If this server is not listed in the proxy server configuration, <none> will be returned

server %string%

Get the name of the server

server[ ]name of %server%
%server%'s server[ ]name

Get a list of servers

The expression below returns a list of all servers described in the proxy server configuration.

[all] servers

Get only those servers that are enabled. In order for the server to be defined as enabled, it must be connected to a socket server.

[all] online servers

Get players from the server

Returns a list of players in the form of online players.

players (from|of|on) %servers%
%servers%'s players

Get a player on a proxy server

Accepts the player’s nickname or UUID, returns the online player, or <none> if the player is not online

network[ ]player %string%

The server player is automatically converted to OfflinePlayer if used in any expressions if necessary.

Get the player’s server

server of %networkplayer%
%networkplayer%'s server

CONDITIONS

Check that the server is online

%servers% is (online|connected)
%servers% is(n't| not) (online|connected)

Check that the player is online

Allows you to change the player’s server if it is located on a server that is connected to a proxy server

%offlineplayers% is ([online ]on|connected to) proxy
%offlineplayers% (does|is)(n't| not) ([online ]on|connected to) proxy

EFFECTS

Kick a player from a proxy server

Allows you to specify the reason. The reason may be plain text, or an AdventureAPI component ( Velocity ) or ChatComponentAPI ( Bungeecord ) in JSON format.

kick %offlineplayers% from proxy [(by reason of|because [of]|on account of|due to) %string%]

Move the player to the server

Allows you to change the player’s server if it is located on a server that is connected to a proxy server

switch %offlineplayers% to %server%

EVENTS

The player has connected to the proxy server

Called when the player has not yet connected to any server

on player (join|connect)[(ed|s)] [to] proxy [server]

The event has built-in data, using the event-player you can get the connected player in the form of an OfflinePlayer

The player disconnected from the proxy server

on player (leave|disconnect)[(ed|s)] [from] proxy [server]

The event has built-in data, using the event-player you can get the connected player in the form of an OfflinePlayer

The current server has connected to the proxy

Called after the server has been connected to the proxy.

on connect(ed|s) [to] proxy [server]
on proxy connect

The current server has disconnected from the proxy

Called after the server has been disconnected from the proxy.

on disconnect(ed|s) [from] proxy [server]
on proxy disconnect

Attempt to reconnect to the proxy

Called when the server tries to reconnect to the proxy.

on reconnect(ing|s) [to] proxy [server]
on proxy reconnect

The server has connected to the proxy

Called after any server has connected to the proxy

on server connect(ed|s) [to] proxy [server]

The event has built-in data, using the event-server you can get a connected server

The server was disconnected from the proxy

Called after any server has disconnected from the proxy

on server disconnect(ed|s) [from] proxy [server]

The event has embedded data, using the event-server you can get a disconnected server

The player has connected to the game server

It is called after the player is connected to the game server, which is connected to the proxy.

on player (join|connect)[(ed|s)] [to] (proxied|network) server

The expression below allows you to track connections only to a specific server by its name.

on player (join|connect)[(ed|s)] [to] (proxied|network) server %string%

The event has built-in data, using the event-server you can get the player’s server, and using the event-player you can get the player in the form of an OfflinePlayer

The player disconnected from the game server

It is called after the player disconnects from the game server that is connected to the proxy.

on player (leave|disconnect[e])[(d|s)] [from] (proxied|network) server

The expression below allows you to track disconnections only from a specific server by its name.

on player (leave|disconnect[e])[(d|s)] [from] (proxied|network) server %string%

The event has built-in data, using the event-server you can get the server of the player from which he left, and using the event-player you can get the player in the form of an OfflinePlayer

SIGNALS

Signals allow you to transfer the information you need between servers.

Create a signal

The signal has the form key : values, which allows you to transfer any data that can be serialized.

signal [(with key|keyed)|(with name|named)] %string% (and|with) [data] %objects%
set {_signal} to signal named "broadcast" with data "Hello world!","My name is Bjork."

Get the signal key.

(key|signal name) of %signal%
%signal%'s (signal name|key)

Get signal data

Returns a list of objects

data of %signal%
%signal%'s data

Send a signal

Allows you to send a signal to any connected server

send signal %signals% to %servers%
set {_signal} to signal named "broadcast" with data "Hello world!","My name is Bjork."
send signal {_signal} to all servers

Signal receiving event

It also allows you to track signals by key.

signal [(with key|keyed) %string%]

The event has built-in data, using the event-signal you can receive the incoming signal.

on load:
  set {_signal} to signal named "broadcast" with data "Hello world!","My name is Bjork."
  send signal {_signal} to all servers
  
on signal with key "broadcast":
  send data of event-signal to all players, console

WEB API

API allows you to get information from servers, as well as send signals from outside.
Make sure that the web server is enabled in the Screw settings of your proxy server.

web-server-enabled: true
web-server-port: 1338
web-server-user: admin
web-server-password: admin

Here you can also configure the web server port and authorization data to access the API.
Authorization is performed by passing the username and password to base64 in the request header:

Authorization: Basic base64_encode("login:password")
curl localhost:1338/players -H "Authorization: Basic YWRtaW46YWRtaW4="

Available routes for requests.

GET    /players

Allows you to get a list of all players with the name of the server they are on.
Possible parameters:

  • server:string - allows you to get players from certain servers

curl localhost:1338/players -H "Authorization: Basic YWRtaW46YWRtaW4="
{
  "data": [
    {
      "name": "Lotzy",
      "uuid": "a0970e26-b9f4-3f73-bd06-ede16c390d34",
      "join_date": 1706008310,
      "time_played": 1089,
      "server_name": "lobby"
    }
  ]
}

GET    /players/{UUID/NICKNAME}

Allows you to get a player, if he is online, by his nickname or UUID. As well as the entire server on which it is located.

curl localhost:1338/players/Lotzy -H "Authorization: Basic YWRtaW46YWRtaW4="
{
  "data": {
    "name": "Lotzy",
    "uuid": "a0970e26-b9f4-3f73-bd06-ede16c390d34",
    "join_date": 1706008310,
    "time_played": 2335,
    "server_name": "lobby",
    "server": {
      "name": "lobby",
      "address": "127.0.0.1",
      "port": 25565,
      "hostname": "127.0.0.1",
      "online": true,
      "connection_date": 1706008017,
      "uptime": 2628,
      "players_count": 1,
      "players": [
        {
          "name": "Lotzy",
          "uuid": "a0970e26-b9f4-3f73-bd06-ede16c390d34",
          "join_date": 1706008310,
          "time_played": 2335,
          "server_name": "lobby"
        }
      ]
    }
  }
}

GET  POST    /players/{UUID/NICKNAME}/kick

Allows you to kick a player from a proxy server, by his nickname or UUID.
When using a POST request, you can specify the reason for the kick. The reason can be specified either in plain text or by the AdventureAPI component ( Velocity ) or ChatComponentAPI ( Bungeecord ) in JSON format.

curl localhost:1338/players/Lotzy/kick -X POST -H "Authorization: Basic YWRtaW46YWRtaW4=" -H "Content-Type: application/json" -d '"GO OUT FROM SERVER"'
{ 
  "data":
    "Player Lotzy kicked"
}

GET    /players/{UUID/NICKNAME}/connect/{SERVER}

Allows you to move a player to another server, by his nickname or UUID.

curl localhost:1338/players/Lotzy/connect/lobby -H "Authorization: Basic YWRtaW46YWRtaW4="
{ 
  "data":
    "Player Lotzy connected to server lobby"
}

GET    /servers

Get a list of all servers and players on them.
Possible parameters:

  • online:boolean - allows you to get only those servers that are enabled

curl localhost:1338/servers?online=true -H "Authorization: Basic YWRtaW46YWRtaW4="
{
  "data": [
    {
      "name": "lobby",
      "address": "127.0.0.1",
      "port": 25565,
      "hostname": "127.0.0.1",
      "online": true,
      "connection_date": 1706008017,
      "uptime": 2132,
      "players_count": 1,
      "players": [
        {
          "name": "Lotzy",
          "uuid": "a0970e26-b9f4-3f73-bd06-ede16c390d34",
          "join_date": 1706008310,
          "time_played": 1839,
          "server_name": "lobby"
        }
      ]
    }
  ]
}

POST    /servers/{SERVER}/signal

Allows you to send a signal to the connected server.
The signal itself is transmitted in the request body.

curl localhost:1338/servers/lobby/signal -X POST -H "Authorization: Basic YWRtaW46YWRtaW4=" -H "Content-Type: application/json" -d "{'signals':[{'key':'broadcast','data':['Hello world!']}]}"
{ 
  "data": {
    "response": "Signals successfully sended to servers" 
  } 
}

POST    /signal

Allows you to send a signal to the connected servers.
The signal itself and the list of servers are transmitted in the request body.

curl localhost:1338/servers/lobby/signal -X POST -H "Authorization: Basic YWRtaW46YWRtaW4=" -H "Content-Type: application/json" -d "{'servers':['lobby'],'signals':[{'key':'broadcast','data':['Hello world!']}]}"
{ 
  "data": {
    "response": "Signals successfully sended to servers" 
  } 
}

You can see an example of implementing API access in Python at this link

SQL

This module allows you to connect to the DBMS and make synchronous and asynchronous requests.

Special thanks to the btk5h (Bryan Terce), FranKusmiruk, Govindas, TPGamesNL for the support of the addon Skript-db . Part of the code and the idea was borrowed from here.

Connecting to a DBMS

Initializes the connection to the DBMS and returns this connection. Returns an object of the type datasource (com.zaxxer.hikari.HikariDataSource class).

[the] data(base|[ ]source) [(of|at)] %string% [with [a] [max[imum]] [connection] life[ ]time of %timespan%]
set {_database} to "mysql://IP:3306/DATABASENAME?user=USERNAME&password=PASSWORD&useSSL=false"

Asynchronous request to the DBMS

[async[hronously]] execute %string% [with (data|(param[eter][s])) %objects%] (in|on) %datasource% [and store [[the] (output|result)[s]] (to|in) [the] [var[iable]] %objects%]

The first parameter - is the query being executed.
The second parameter - is the insertion of values for escaping. The first character is ? will be replaced by the first value from the passed list in the second argument, the second ? to the second from the list, etc. For example:\

execute "select * from ? where name=?" with "books","worldatwar" in {_database}

The first ? will be replaced with books before executing the request, and the second one with ‘worldatwar’.

Use value escaping for any queries where user input is used to avoid SQL-injection


The third parameter - connecting to a DBMS, an object of type datasource from a previous expression.
The last parameter - where the query result will be placed, you must specify the list variable. After the query, the column names will become indexes of this list, the column values will be stored in a new sub-list with the column name.

For example, we have the following table:

id (INT)name (VARCHAR)age (INT)
1Lotzy22
2w0w019


When executing the code:

execute "select * from table" in {_database} and store the result in {_output::*}

The list {_output::*} will look like this:

{_output::id::1} = 1  
{_output::name::1} = "Lotzy"  
{_output::age::1} = 22 
{_output::id::2} = 2  
{_output::name::2} = "w0w0"  
{_output::age::2} = 19
{_output::*} = "id", "name" and "age" 

An asynchronous request cannot be used in functions where a value is returned. The result of an asynchronous request will be <none>

Synchronous request to the DBMS

sync[hronously] execute %string% [with (data|(param[eter][s])) %objects%] (in|on) %datasource% [and store [[the] (output|result)[s]] (to|in) [the] [var[iable]] %objects%]

Block the main thread for the duration of the request, use wisely.

STRING UTILS

Check that the text matches the regular expression

%string% (does|is)[n't| not] regex match(es|ed) %string%
if "1361" is regex matches "1..1":
  broadcast "Matched"

Find groups by regular expression

regex group[s] %integer% of %string% matched to %string%
set {_group::*} to regex group 1 of "123123123123" matched to "123"

Regular expression substitution

regex replace %string% with %string% in %string%
set {_text} to regex replace "3.*" with "" in "123123123123"

Split text by regular expression

regex split %string% at %string%
set {_text::*} to regex split "123123123123" at ".3"

Mirror the text

(reverse[d]|backward(s|ed)) [(string|text)] %string%
set {_text} to reversed "321"

Split the string every N characters

%string% split [(by|at)] every %integer% (symbol|char[acter])[s]
split %string% [(by|at)] every %integer% (symbol|char[acter])[s]
set {_text::*} to "123123123123" split eveny 3 symbols

VIAVERSION

This module allows you to interact with the plugin ViaVersion

A plugin is required for the module to work ViaVersion

Get the player’s client version as text

[the] version of %player%
%player%'s version

Get the protocol number of the player’s client

[the] protocol of %player%        
%player%'s protocol

Subsections of World

EFFECTS

Load the world

Loads the world by its name. The world must be located in the root directory of the server.

load world %string%

Unload the world

Unload the world. It also allows you not to save changes when uploading.

unload [world] %world% [without save]

Load a chunk

It also allows you not to generate a world in a chunk if this chunk has not been generated.

load %chunk% [without gen[erate]]

Upload a chunk

Unload the chunk. It also allows you not to save changes when uploading.

unload [chunk] %chunk% [without save]

Create a world

It also allows you to create a flat world.

create world %string% [[with type] [super]flat]

Delete the world

delete world %world/string%

Create a copy of the world

(copy|duplicate) world %string% [(with|using)] name[d] %string%

EXPRESSIONS

Get the main server world

Returns the main world of the server, without which the server operation is impossible.

main[ ]world

Get a chunk by its coordinates

In this expression, not the coordinates of the blocks are used, but the coordinates of the chunk.
To get the coordinates of the chunk, the X and Z coordinates are divided by 16.

chunk [at] %number%[ ],[ ]%number% (in|at) %world%

Get all entities inside the chunk

entit(y|ies) (of|in) %chunk%
%chunk%'s entit(y|ies)

Get all the uploaded chunks in the world

[all [[of] the]] loaded chunks (in|at|of) %world%
%world%'s [all [[of] the]] loaded chunks

Constant loading of the chunk

Not supported on versions lower than 1.13.1

This expression supports changing the state

force load[ed] of %chunk%
%chunk%'s force load[ed]

The center of the barrier of the world

This expression supports changing the state

[world] border center of %world%
%world%'s [world] border center

The size of the world barrier

This expression supports changing the state. When changing, it is possible to specify the time in ticks for how long the barrier should change its size

[world[ ]]border size of %world% [for %-timespan%]
%world%'s [world[ ]]border size [for %-timespan%]
[the] size of %world%'s [world[ ]]border [for %-timespan%]

Conditions

Check that the chunk is loaded

%chunk% [(does|is)][(n't| not)] load[ed]

Check if there is a world

world %string% [(does|is)][(n't| not)] (exist[s]|available)