The following functions generate userdata (on the server) or superblob (on the client). The generated objects are executed using RemoteExec
(on the server) or PeerExec
(on the client).
Description: Generates an object that retrieves the value of a key from the root table.
Parameters:
key
: The key to retrieve. This can be a string, integer, or userdata/superblob (returned by these functions).
Generated Object Type:
On server: userdata
On client: superblob
Description: Generates an object that retrieves the value of a key from a specific object.
Parameters:
object
: The source object. This can be userdata/superblob or a supported Squirrel data type.
key
: The key to retrieve. This can be a string, integer, or userdata/superblob.
Generated Object Type:
On server: userdata
On client: superblob
Description: Generates an object that sets the value of a key in the root table.
Parameters:
key
: The key to set. This can be a string, integer, or userdata/superblob.
value
: The value to assign to the key. This can be a usual Squirrel data type (except class) or userdata/superblob.
Generated Object Type:
On server: userdata
On client: superblob
Description: Generates an object that sets the value of a key in a specific object.
Parameters:
object
: The target object. This can be userdata/superblob or a supported Squirrel data type.
key
: The key to set. This can be a string, integer, or userdata/superblob.
value
: The value to assign to the key. This can be a usual Squirrel data type (except class) or userdata/superblob.
Generated Object Type:
On server: userdata
On client: superblob
Description: Generates an object that calls a function with specified arguments.
Parameters:
func
: The function to call. This is typically retrieved using GetRemoteValue
or GetRemoteValueEx
.
arg1, arg2, ...
: Arguments to pass to the function. These can be usual Squirrel data types (except class) or userdata/superblob.
Generated Object Type:
On server: userdata
On client: superblob
Description: Generates an object that calls a function with a specific this
parameter.
Parameters:
func
: The function to call. Typically retrieved using GetRemoteValue
.
env
: The object to set as the this
parameter. Typically retrieved using GetRemoteValue
.
arg1, arg2, ...
: Arguments to pass to the function. These can be usual Squirrel data types (except class) or userdata/superblob.
Generated Object Type:
On server: userdata
On client: superblob
RemoteExec (on server): Executes a userdata
object.
Parameters:
userdata
: The object generated by one of the six functions.
player
: The target player to execute the object on.
should_return
(boolean): If true, the execution result will be sent back to the server.
callback_func
: A one-parameter function to handle the execution result. The return value of this function is ignored.
Additional Details:
The callback_func
for RemoteExec
has access to a special variable called REMEXEC_ERROR
. This variable is set to 1
if an error occurred while executing the data on the client-side. It is available only on the server-side (i.e., in RemoteExec
's callback_func
) and not in the callback function of PeerExec
.
Example:
RemoteExec(GetRemoteValue("a"), FindPlayer(0), true, function(value) { if (REMEXEC_ERROR == 1) { print("Error occurred while executing on client."); } else { print("Execution result: " + value); } });
The onRemoteExecReply
function is called when the plugin executes something on the client-side, a value or error is returned, and no callback_func
is provided in the RemoteExec
invocation.
function onRemoteExecReply(token, result)
token
(integer): An internal number used for identifying streams.
result
: The value returned from the client after execution.
When the third parameter of RemoteExec
(should_return
) is set to true
, but no callback_func
is provided as the fourth parameter, the plugin will search for a function named onRemoteExecReply
in the root table. If the function exists in the script, it will be called with the execution result.
// Define onRemoteExecReply in the root table function onRemoteExecReply(token, result) { print("Stream token: " + token); print("Execution result: " + result); } // Call RemoteExec with should_return=true and no callback RemoteExec(GetRemoteValue("a"), FindPlayer(0), true);
onRemoteExecReply
is not defined in the root table, no further action will occur.PeerExec (on client): Executes a superblob
object.
Parameters:
superblob
: The object generated by one of the six functions.
target_player_id
: The ID of the target player for execution.
callback_func
: A one-parameter function to handle the execution result. The return value of this function is ignored.
Additional Details:
The callback_func
for PeerExec
does not have access to the REMEXEC_ERROR
variable. Any errors on the client-side will need to be handled differently.
The onPeerExecute
function is invoked on the server-side whenever a client uses the PeerExec
function. This callback provides the opportunity to inspect and control the operation before it proceeds.
function onPeerExecute(sender, receiver, object)
sender
: The player instance of the client initiating the PeerExec
request.
receiver
: The player instance of the intended recipient of the PeerExec
request.
object
: A blob formatted using the remote-exec-bytecode format (e.g., 'E', 'F', 'g', etc.). This format is detailed in another file.
If the onPeerExecute
callback function exists in the root table, it is executed whenever a client invokes PeerExec
. The function can inspect the sender
, receiver
, and object
parameters and decide whether the operation should continue.
If the value returned by the callback function is false
, null
, or 0
, the server aborts the PeerExec
operation in progress. This means the object (blob) will not be sent to the receiver
.
The main purpose of this callback is to serve as a potential security feature. It allows the server to inspect and validate the PeerExec
requests before forwarding them to the recipient, helping to ensure safe and controlled operations.
// Define onPeerExecute in the root table function onPeerExecute(sender, receiver, object) { // Log the operation print("PeerExec request from: " + sender); print("PeerExec target: " + receiver); print("PeerExec object: " + object); // Allow the operation only if sender is authorized if (sender.Name == "AuthorizedPlayer") { return true; // Allow the operation } return false; // Abort the operation }
onPeerExecute
is not defined in the root table, all PeerExec
operations proceed without additional inspection or validation.PeerExec
operation initiated by a client.object
parameter follows the remote-exec-bytecode format, which should be decoded and interpreted carefully if needed.1. Parameters such as key
code>,
value
, object
, and env
can be usual Squirrel data types (except class) or userdata
/superblob
generated by these functions themselves.
2. For CallRemoteFuncEx
, env
is often retrieved using GetRemoteValue
.
3. should_return
in RemoteExec
allows the server to retrieve the result of the execution, which is passed to the callback_func
.
The userdata
(server) or superblob
(client) objects returned by the six core functions support the following metamethods in Squirrel. These allow for seamless property access, function invocation, and arithmetic operations on the objects when executed with RemoteExec
or PeerExec
.
Description: Access properties or methods on the object.
Behavior: Retrieves a property or method from the userdata
/superblob
.
Example:
Suppose "a" is an array in the client-side roottable with a length of 5. The following retrieves the first element (a[0]) on execution: RemoteExec(GetRemoteValue("a")[0], FindPlayer(0), true, function(value) { print("First element of array a: " + value); });
Description: Invoke the object or a retrieved property as a function.
Behavior: Calls the object or a property.
Example:
RemoteExec(GetRemoteValue("World").FindLocalPlayer(), FindPlayer(0), true, function(player) { print("Player object: " + player); });
Description: Perform addition operations with the object.
Behavior: Adds the object to another operand.
Example:
RemoteExec(GetRemoteValue("a") + 100, FindPlayer(0), true, function(result) { print("Result: " + result); });
Description: Perform subtraction operations with the object.
Behavior: Subtracts another operand from the object.
Example:
RemoteExec(GetRemoteValue("a") - 50, FindPlayer(0), true, function(result) { print("Result: " + result); });
Description: Perform multiplication operations with the object.
Behavior: Multiplies the object by another operand.
Example:
RemoteExec(GetRemoteValue("a") * 10, FindPlayer(0), true, function(result) { print("Result: " + result); });
Description: Perform division operations with the object.
Behavior: Divides the object by another operand.
Example:
RemoteExec(GetRemoteValue("a") / 2, FindPlayer(0), true, function(result) { print("Result: " + result); });
Description: Perform modulo operations with the object.
Behavior: Computes the remainder of division of the object by another operand.
Example:
RemoteExec(GetRemoteValue("a") % 3, FindPlayer(0), true, function(result) { print("Result: " + result); });
Description: Perform unary negation on the object.
Behavior: Changes the sign of the object’s value.
Example:
RemoteExec(-GetRemoteValue("b"), FindPlayer(0), true, function(result) { print("Negated value: " + result); });
The following functionality enables server-client communication using rprint
and rexec
. These functions simplify sending messages from the client to the server and executing scripts on the client-side.
Description:
The rprint
function is used on the client-side to send messages to the server. The server processes these messages using the onClientScriptData
function.
Add the following code to your onClientScriptData
function to process messages sent by rprint
:
function onClientScriptData( player ) { // receiving client data local stream = Stream.ReadInt(); switch ( stream ) { case 0x40ffffe5: { local message=Stream.ReadString(); print(message); } break; } }
On the client-side, use rprint
as follows:
// Client-Side rprint("Hello World");
rprint
with a string message.onClientScriptData
.// Client-Side: Send a message to the server rprint("Hello Server!"); // Server-Side: Prints "Hello Server!" to the console
Description:
The rexec
function sends a script string from the server to a specific client. The client compiles and executes the script upon receiving it.
Add the following function to your server-side script to use rexec
:
function rexec(string, name) { Stream.StartWrite(); Stream.WriteInt(0x40ffffe4); // Command identifier for executing client scripts Stream.WriteString(string); // The script string to execute Stream.SendStream(FindPlayer(name)); // Send the stream to the specified player }
string
(string): The Squirrel script to be compiled and executed on the client-side.
name
(string): The name of the target player to receive and execute the script.
0x40ffffe4
).On the server, use rexec
to execute scripts on a specific client:
// Server-Side rexec("Console.Print(\"Hello World\");", "player_name");
// Server-Side: Execute a script on the client rexec("Console.Print(\"Welcome to the server!\");", "player_name"); // Client-Side: The script is executed, and "Welcome to the server!" is printed to the client's console