Difference between revisions of "Arma 3: Remote Execution"

From Bohemia Interactive Community
Jump to navigation Jump to search
m (More cleanup)
(33 intermediate revisions by 6 users not shown)
Line 1: Line 1:
{{GVI|A3|1.50|category}}
+
{{TOC|side}}
[[Category:Arma_3:_Editing|Remote Execution]]
 
  
 +
Remote Execution is one of the cornerstones of [[Multiplayer_Scripting|Multiplayer Scripting]] in {{arma3}}. It is primarily needed to properly use commands that have ''local effect'' ({{Icon|localEffect|32}}) or only take ''local arguments'' ({{Icon|localArgument|32}}) in multiplayer.
  
==Overview==
+
== Remote Execution Framework ==
 
+
The Remote Execution Framework currently consists of five commands:
In A3 1.48 the 2 new script commands were added to natively handle execution of code and functions on remote machines - [[remoteExec]] and [[remoteExecCall]].
 
 
 
===Links===
 
 
* [[remoteExec]]
 
* [[remoteExec]]
 
* [[remoteExecCall]]
 
* [[remoteExecCall]]
* [[CfgRemoteExec]]
+
* [[remoteExecutedOwner]]
* [[BIS_fnc_MP]]
+
* [[isRemoteExecuted]]
 +
* [[isRemoteExecutedJIP]]
 +
Furthermore, the framework encompasses an optional config entry to manage security settings: [[Arma_3:_CfgRemoteExec|CfgRemoteExec]] (see [[#Security|Security]] to learn more).
 +
 
 +
{{Feature|Informative|While primarily designed and used for MP, [[remoteExec]] and [[remoteExecCall]] also work in SP; the behaviour is the same as in MP.}}
  
==Motivation==
 
Until A3 1.48 there was no engine based remote execution. The only officially supported way how to execute code or command on non-local machine was by using scripted remote execution framework - [[BIS_fnc_MP]]. This scripted framework, however working, suffered from several issues, mainly poor network traffic optimization and insufficient security control. The network traffic was optimized in 1.46 but the security issues could not be properly fix in the scripted framework.
 
  
To address those security issues, in A3 1.48 the remote execution was implemented into the engine. There are now 2 new script commands - [[remoteExec]] and [[remoteExecCall]], that allow for fully controlled and secure remote execution from client machines(s).
+
== Use Case Example ==
 +
To understand why remote execution is needed and what it is used for, consider the following use case example: Let's say we want to use [[hint]] to display an announcement to all the players in our MP mission at the same time.
  
==Syntax==
+
We already know how to use the [[hint]] command:
Both script commands have same syntax but differ in way how the code is executed on target machine(s). For details and explanation of the difference, see the [[#Using_remoteExec_and_remoteExecCall|next section]].
+
[[hint]] "You have 5 minutes left!"; {{cc|Normal use of [[hint]].}}
 +
The problem is that [[hint]] only has ''local effect''. This means that only the machine where [[hint]] is executed will display our "You have 5 minutes left!" message. But we do not want to display our message to just a single player, we want to display our message to every player.
  
<pre><params> remoteExec [<function>,(<target>,<isPersistent>)];
+
So in order to solve this problem, we need to make use of remote execution:
<params> remoteExecCall [<function>,(<target>,<isPersistent>)];</pre>
+
"You have 5 minutes left!" [[remoteExec]] ["hint", 0]; {{cc|Remote execution of [[hint]].}}
 +
Now all machines that are taking part in our MP session will execute {{ic|[[hint]] "You have 5 minutes left!";}}, which means that our message will be displayed to every player at the same time - and we have achieved our goal.
  
* params: ARRAY - parameters passed to the function
+
{{Feature|Informative|If it is available, information about the MP behaviour of a function / command can be found at the top of the documentation page of that function / command. Look for these icons: {{Icon|localArgument|32}}, {{Icon|globalArgument|32}}, {{Icon|localEffect|32}}, {{Icon|globalEffect|32}} and {{Icon|serverExec|32}}. You can always hover above the icons to view a tooltip explaining what each icon means.}}
* function: STRING - function name. Commands and functions defined in [[CfgRemoteExec]] are whitelisted.
 
* target: - Optional. [default: 0]
 
*: OBJECT - function will be executed only where unit is local
 
*: NUMBER - the function will be executed only on machine with the given owner ID.
 
*:: 0 - the function will be executed on each machine including the one where [[remoteExec]] was called from.
 
*:: 2 - it will be executed only by server.
 
*:: negative value - it will be executed everywhere except for machines with with the given owner ID.
 
*: SIDE - the function will be executed only on machines where the player is on the specified side
 
*: GROUP - the function will be executed only on machines where the player is in the specified group
 
*: ARRAY - array of any of types listed above
 
* isPersistent: STRING or BOOL - Optional [default: false].
 
*: If true, function generates an unique ID for the message and the message itself is added to the JIP queue with the unique ID.
 
*: If a non-empty string, it is a custom ID of the message and the message itself is added to the JIP queue overriding any [[remoteExec]] message with the same ID.
 
*: Otherwise, no ID is generated and no message is placed into the JIP queue (default state).
 
  
;Return Values:
 
: NIL in case of error.
 
: STRING otherwise. If JIP is not requested this is an empty string. Otherwise this is an unique JIP ID.
 
  
==Using remoteExec and remoteExecCall==
+
== History ==
===remoteExec===
+
Prior to {{GVI|arma3|1.50}} there was no engine based remote execution. The only officially supported way to execute code on a non-local machine was provided in the form of [[BIS_fnc_MP]]. This scripted framework suffered from several issues, mainly poor network traffic optimization and insufficient security control. The network traffic was optimized in {{GVI|arma3|1.46}}, but the security issues of the scripted framework could not be fixed properly.
Content of MP message sent by [[remoteExec]] command is executed on target machine in [[Code_Optimisation#Threads|scheduled environment]] and as such abides to the same rules and limitations as other scheduled code.
 
  
If you want to execute more complex code that needs to be processed as separate spawn use [[remoteExec]] command.  
+
To fully address these issues, remote execution was implemented directly into the game engine, with {{GVI|arma3|1.50}} introducing two new script commands - [[remoteExec]] and [[remoteExecCall]] - as well as a new [[Arma_3:_CfgRemoteExec|CfgRemoteExec]], finally allowing for proper and secure remote execution from all machines.
  
More specifically:
+
As of {{GVI|arma3|1.54}}, [[BIS_fnc_MP]] has been rewritten to internally use [[remoteExec]] and [[remoteExecCall]], retaining full backwards compatibility and enabling it to work with the updated [[Arma_3:_CfgRemoteExec|CfgRemoteExec]]. '''Despite this, [[BIS_fnc_MP]] is now deprecated and should no longer be used!'''
# If your code includes any delays (commands like sleep or waitUntil) you '''MUST''' use [[remoteExec]].
 
# If your code contains more CPU demanding operations that will take some time for the game to process, you SHOULD use [[remoteExec]], otherwise you might experience performance drops.
 
===remoteExecCall===
 
Unlike [[remoteExec]], MP messages send by [[remoteExecCall]] command are executed sequentially outside of the scheduled environment. This makes the [[remoteExecCall]] command very useful, if you need to to execute multiple codes/commands in a set sequence.
 
  
The code sent by [[remoteExecCall]] '''MUST NOT''' contain any delays and '''SHOULD NOT''' be too complex and CPU demanding.
 
  
==Security==
+
== Security ==
 
The biggest issue of previous scripted remote execution was the lack of control over what can and cannot be executed from local clients. To address this we’ve created system where content authors can define through [[CfgRemoteExec]] config how the remote execution should operate on clients.
 
The biggest issue of previous scripted remote execution was the lack of control over what can and cannot be executed from local clients. To address this we’ve created system where content authors can define through [[CfgRemoteExec]] config how the remote execution should operate on clients.
  
''Note: Server doesn’t have any limitations at place, everything is enabled and opened for him. All limitations and rules apply only for client(s).''
+
{{Feature | Informative | Server doesn’t have any limitations at place, everything is enabled and opened for it. All limitations and rules apply only for clients.}}
  
Because [[remoteExec]] and [[remoteExecCall]] can be used to remotely execute script commands (like for e.g. setDamage) as well as scripted functions (e.g. BIS_fnc_setRank) we have separated the security settings into two groups Functions and Commands. This allows people to quickly set different rules for functions and commands separately.  
+
Because [[remoteExec]] and [[remoteExecCall]] can be used to remotely execute script commands (like for e.g. [[setDamage]]) as well as scripted functions (e.g. BIS_fnc_setRank) we have separated the security settings into two groups: Functions and Commands. This allows people to quickly set different rules for functions and commands separately.  
  
 
The security rules consist of 3 security settings - operation mode, allowed targets and jip. The operation mode is very important as it defines if functions/commands can be executed remotely from client or not and ev. allows you to whitelist specific functions/commands. The allowed targets and jip are very optional and you really do not need to use them, unless you want to be super safe.  
 
The security rules consist of 3 security settings - operation mode, allowed targets and jip. The operation mode is very important as it defines if functions/commands can be executed remotely from client or not and ev. allows you to whitelist specific functions/commands. The allowed targets and jip are very optional and you really do not need to use them, unless you want to be super safe.  
Line 69: Line 48:
 
To get more info about those settings and the [[CfgRemoteExec]] config, check the subsections below.
 
To get more info about those settings and the [[CfgRemoteExec]] config, check the subsections below.
  
===Operation modes===
+
=== Operation modes ===
 
Operation mode is numeric value describing how functions or commands should be treated on server on client.
 
Operation mode is numeric value describing how functions or commands should be treated on server on client.
  
    0: remote execution is blocked
+
0: remote execution is blocked
    1: only whitelisted functions/commands are allowed for remote execution
+
1: only whitelisted functions/commands are allowed for remote execution
    2: remote execution fully opened
+
2: remote execution fully opened
  
===Allowed targets===
+
=== Allowed targets ===
 
In addition to the operation mode, in client subclass, allowed targets can be defined for individual whitelisted commands and functions. This adds another layer of security and control to the system, as it allows you to define not only who can send the execution request, but also where it can be executed.
 
In addition to the operation mode, in client subclass, allowed targets can be defined for individual whitelisted commands and functions. This adds another layer of security and control to the system, as it allows you to define not only who can send the execution request, but also where it can be executed.
  
    0: can target all machines (default)
+
0: can target all machines (default)
    1: can target only clients, execution on server is denied
+
1: can target only clients, execution on server is denied
    2: can target only server, execution on clients is denied
+
2: can target only server, execution on clients is denied
===JIP===
+
 
 +
=== JIP ===
 
To control who can add JIP message into JIP queue, we have added an optional parameter jip. This parameter can be defined in whitelisted function/command class, at the same place as allowed targets are defined or in the Functions and/or Commands classes. This parameter affects only clients (no effect if defined within Server subclass).
 
To control who can add JIP message into JIP queue, we have added an optional parameter jip. This parameter can be defined in whitelisted function/command class, at the same place as allowed targets are defined or in the Functions and/or Commands classes. This parameter affects only clients (no effect if defined within Server subclass).
  
 
If it is defined on both levels, the more local definition takes precedence (which is the value defined in the whitelisted function/command).
 
If it is defined on both levels, the more local definition takes precedence (which is the value defined in the whitelisted function/command).
  
    0: JIP flag cannot be set
+
0: JIP flag cannot be set
    1: JIP flag can be set (default)
+
1: JIP flag can be set (default)
  
===Config location===
+
=== Config location ===
 
The [[CfgRemoteExec]] class can be defined in mission description.ext, campaign description.ext or global (addon) config. As usual the more local config takes precedence. In case of more global configs exist, the mode attribute will be overridden by the last parsed config and whitelisted commands and functions will be merged.
 
The [[CfgRemoteExec]] class can be defined in mission description.ext, campaign description.ext or global (addon) config. As usual the more local config takes precedence. In case of more global configs exist, the mode attribute will be overridden by the last parsed config and whitelisted commands and functions will be merged.
  
 
Sample [[CfgRemoteExec]] definition:
 
Sample [[CfgRemoteExec]] definition:
 
+
<syntaxhighlight lang="cpp">
<pre>class CfgRemoteExec
+
class CfgRemoteExec
 
{
 
{
        class Commands
+
class Commands
        {
+
{
                mode = 1;
+
mode = 1;
  
                class setFuel {allowedTargets = 2;};           //execute only on server
+
class setFuel { allowedTargets = 2; }; // execute only on server
                class hint {jip = 0;};                         //jip is not allowed for this command
+
class hint { jip = 0; }; // jip is not allowed for this command
        };
+
};
        class Functions
 
        {
 
                mode = 0;
 
                jip = 0;                                      //no functions can use jip
 
  
                class BIS_fnc_setRank {allowedTargets = 1;};   //execute only on clients, server execution denied
+
class Functions
        };
+
{
};</pre>
+
mode = 0;
 +
jip = 0; // no functions can use jip
  
==The BIS_fnc_MP backward compatibility==
+
class BIS_fnc_setRank { allowedTargets = 1; }; // execute only on clients, server execution denied
By implementation of the engine based remote execution, the scripted solution becomes deprecated. As a result for A3 1.50 it's planned to implement [[remoteExec]] and [[remoteExecCall]] into the [[BIS_fnc_MP]]. Although the insides of the [[BIS_fnc_MP]] function will be completely rewritten, function syntax and functionality will remain 100% same. There is no need to worry about backward compatibility.
+
};
 +
};
 +
</syntaxhighlight>
  
In addition from A3 1.50 the [[BIS_fnc_MP]] function will abide the same [[CfgRemoteExec]] rules for remote execution as [[remoteExec]] and [[remoteExecCall]] commands do. Because of that the content authors that were using the [[BIS_fnc_MP]] will be able to set the security permissions for remote execution and will make their content more resilient to hacking.
 
  
==Advanced Techniques & Functionality Insight==
+
== Advanced Techniques & Functionality Insight ==
If you want to know more about how the remote execution works and handles some more complicated issues and edge cases continue reading, otherwise feel free to skip.
+
=== JIP Queue ===
===JIP queue===
+
When a command or function is executed through [[remoteExec]] or [[remoteExecCall]], it can be flagged as persistent. If it is flagged, the statement is stored in the JIP queue on the server (under its unique JIP ID). When a player joins a multiplayer session that has already started (JIP stands for ''Join-In-Progress''), all entries stored in the JIP queue are executed on that player's machine.
When command or function is executed through [[remoteExec]] or [[remoteExecCall]], it can be flagged as persistent through the isPersistent attribute. If it is flagged, the request is being stored on server in the JIP queue under the unique JIP id. When new player joins the MP session that is currently running (we call this Join-In-Progress, JIP) all the MP messages that were stored in the JIP queue are executed on him.
 
===JIP id===
 
The JIP id is a unique key under which the JIP MP message is being stored in the JIP queue on the server. When you set isPersistent flag to true, the JIP id is auto-generated on the machine the remote execution was initiated. If you set the isPersistent flag to specific string, that string is considered to be the JIP id.  
 
  
The auto-generated JIP is always unique. If the JIP is manually supplied, the content author needs to make sure it is unique, otherwise he/she will overwrite another MP msg that is currently stored in the queue under the JIP id.
+
==== Overwriting JIP message in the queue ====
===Overwriting JIP message in the queue===
 
 
Every JIP message is stored in the queue. If you need to overwrite the JIP message with another message, use the same JIP id for the new message. This way the new message will be stored in the queue under the provided id and will overwrite the previously stored message that used the same id.
 
Every JIP message is stored in the queue. If you need to overwrite the JIP message with another message, use the same JIP id for the new message. This way the new message will be stored in the queue under the provided id and will overwrite the previously stored message that used the same id.
===Deleting JIP message from the queue===
+
 
 +
==== Deleting JIP message from the queue ====
 
To remove a specific JIP message from the queue call the remoteExec with function/command name set to an empty string, the JIP id of the message you want to remove and no other params.  
 
To remove a specific JIP message from the queue call the remoteExec with function/command name set to an empty string, the JIP id of the message you want to remove and no other params.  
 +
[[remoteExec]] ["", "JIPid"];
 +
 +
=== Validity Verification ===
 +
The validity of a remote execution request is verified in two steps:
 +
# When the request is initiated (issued from a client machine)
 +
# Before the server broadcasts the request
 +
 +
If the request is initialized directly from the server, step 1 is skipped (this also applies to hosted servers).
 +
 +
A remote execution request has to meet the following criteria to be considered valid:
 +
# The input parameters must be defined properly
 +
# The function / command must exist on the machine
 +
# The function / command must be allowed by [[Arma_3:_CfgRemoteExec|CfgRemoteExec]]:
 +
#* Remote execution must either be fully open ({{ic|mode {{=}} 2}}) ...
 +
#* ... or the particular function / command must be whitelisted.
 +
# If JIP is used, JIP must be allowed by [[Arma_3:_CfgRemoteExec|CfgRemoteExec]] ({{ic|jip {{=}} 1}})
 +
 +
If any of these conditions is not met, the remote execution request is blocked.
 +
  
remoteExec ["", "JIPid"];
+
== See Also ==
===Validity verification===
+
* [[Multiplayer Scripting]]
Validity of remote execution request is verified in 2 steps:
+
* [[:Category:Command Group: Multiplayer|Multiplayer Scripting Commands]]
when the request is initiated (issued from a client machine)
 
when the server is going to broadcast the request.
 
If the request is initialized directly from the server, step 1 is skipped (this applies for hosted server admins as well).
 
  
For a remote execution request to be valid following criteria need to be met:
 
# input parameters must be properly defined
 
# function/command must exist on the machine
 
# function/command remote execution request must be allowed in [[CfgRemoteExec]]
 
#* remote execution must be either fully open (mode=2)
 
#* or the particular function/command must be whitelisted
 
#if JIP is used (isPersistent flag is not false), JIP must be allowed in [[CfgRemoteExec]] (jip=1)
 
  
If any of the aforementioned is not met remote execution is blocked.
+
{{GameCategory|arma3|Remote Execution}}
 +
[[Category:Introduced with Arma 3 version 1.50]]

Revision as of 13:16, 26 July 2021

Remote Execution is one of the cornerstones of Multiplayer Scripting in Arma 3. It is primarily needed to properly use commands that have local effect (LELocal) or only take local arguments (LALocal) in multiplayer.

Remote Execution Framework

The Remote Execution Framework currently consists of five commands:

Furthermore, the framework encompasses an optional config entry to manage security settings: CfgRemoteExec (see Security to learn more).

While primarily designed and used for MP, remoteExec and remoteExecCall also work in SP; the behaviour is the same as in MP.


Use Case Example

To understand why remote execution is needed and what it is used for, consider the following use case example: Let's say we want to use hint to display an announcement to all the players in our MP mission at the same time.

We already know how to use the hint command:

hint "You have 5 minutes left!"; // Normal use of hint.

The problem is that hint only has local effect. This means that only the machine where hint is executed will display our "You have 5 minutes left!" message. But we do not want to display our message to just a single player, we want to display our message to every player.

So in order to solve this problem, we need to make use of remote execution:

"You have 5 minutes left!" remoteExec ["hint", 0]; // Remote execution of hint.

Now all machines that are taking part in our MP session will execute hint "You have 5 minutes left!";, which means that our message will be displayed to every player at the same time - and we have achieved our goal.

If it is available, information about the MP behaviour of a function / command can be found at the top of the documentation page of that function / command. Look for these icons: LALocal, GAGlobal, LELocal, GEGlobal and SEServer. You can always hover above the icons to view a tooltip explaining what each icon means.


History

Prior to Arma 3 logo black.png1.50 there was no engine based remote execution. The only officially supported way to execute code on a non-local machine was provided in the form of BIS_fnc_MP. This scripted framework suffered from several issues, mainly poor network traffic optimization and insufficient security control. The network traffic was optimized in Arma 3 logo black.png1.46, but the security issues of the scripted framework could not be fixed properly.

To fully address these issues, remote execution was implemented directly into the game engine, with Arma 3 logo black.png1.50 introducing two new script commands - remoteExec and remoteExecCall - as well as a new CfgRemoteExec, finally allowing for proper and secure remote execution from all machines.

As of Arma 3 logo black.png1.54, BIS_fnc_MP has been rewritten to internally use remoteExec and remoteExecCall, retaining full backwards compatibility and enabling it to work with the updated CfgRemoteExec. Despite this, BIS_fnc_MP is now deprecated and should no longer be used!


Security

The biggest issue of previous scripted remote execution was the lack of control over what can and cannot be executed from local clients. To address this we’ve created system where content authors can define through CfgRemoteExec config how the remote execution should operate on clients.

Server doesn’t have any limitations at place, everything is enabled and opened for it. All limitations and rules apply only for clients.

Because remoteExec and remoteExecCall can be used to remotely execute script commands (like for e.g. setDamage) as well as scripted functions (e.g. BIS_fnc_setRank) we have separated the security settings into two groups: Functions and Commands. This allows people to quickly set different rules for functions and commands separately.

The security rules consist of 3 security settings - operation mode, allowed targets and jip. The operation mode is very important as it defines if functions/commands can be executed remotely from client or not and ev. allows you to whitelist specific functions/commands. The allowed targets and jip are very optional and you really do not need to use them, unless you want to be super safe.

To get more info about those settings and the CfgRemoteExec config, check the subsections below.

Operation modes

Operation mode is numeric value describing how functions or commands should be treated on server on client.

	0: remote execution is blocked
	1: only whitelisted functions/commands are allowed for remote execution
	2: remote execution fully opened

Allowed targets

In addition to the operation mode, in client subclass, allowed targets can be defined for individual whitelisted commands and functions. This adds another layer of security and control to the system, as it allows you to define not only who can send the execution request, but also where it can be executed.

	0: can target all machines (default)
	1: can target only clients, execution on server is denied
	2: can target only server, execution on clients is denied

JIP

To control who can add JIP message into JIP queue, we have added an optional parameter jip. This parameter can be defined in whitelisted function/command class, at the same place as allowed targets are defined or in the Functions and/or Commands classes. This parameter affects only clients (no effect if defined within Server subclass).

If it is defined on both levels, the more local definition takes precedence (which is the value defined in the whitelisted function/command).

	0: JIP flag cannot be set
	1: JIP flag can be set (default)

Config location

The CfgRemoteExec class can be defined in mission description.ext, campaign description.ext or global (addon) config. As usual the more local config takes precedence. In case of more global configs exist, the mode attribute will be overridden by the last parsed config and whitelisted commands and functions will be merged.

Sample CfgRemoteExec definition:

class CfgRemoteExec
{
	class Commands
	{
		mode = 1;

		class setFuel	{ allowedTargets = 2; };		// execute only on server
		class hint		{ jip = 0; };					// jip is not allowed for this command
	};

	class Functions
	{
		mode = 0;
		jip = 0;										// no functions can use jip

		class BIS_fnc_setRank { allowedTargets = 1; };	// execute only on clients, server execution denied
	};
};


Advanced Techniques & Functionality Insight

JIP Queue

When a command or function is executed through remoteExec or remoteExecCall, it can be flagged as persistent. If it is flagged, the statement is stored in the JIP queue on the server (under its unique JIP ID). When a player joins a multiplayer session that has already started (JIP stands for Join-In-Progress), all entries stored in the JIP queue are executed on that player's machine.

Overwriting JIP message in the queue

Every JIP message is stored in the queue. If you need to overwrite the JIP message with another message, use the same JIP id for the new message. This way the new message will be stored in the queue under the provided id and will overwrite the previously stored message that used the same id.

Deleting JIP message from the queue

To remove a specific JIP message from the queue call the remoteExec with function/command name set to an empty string, the JIP id of the message you want to remove and no other params.

remoteExec ["", "JIPid"];

Validity Verification

The validity of a remote execution request is verified in two steps:

  1. When the request is initiated (issued from a client machine)
  2. Before the server broadcasts the request

If the request is initialized directly from the server, step 1 is skipped (this also applies to hosted servers).

A remote execution request has to meet the following criteria to be considered valid:

  1. The input parameters must be defined properly
  2. The function / command must exist on the machine
  3. The function / command must be allowed by CfgRemoteExec:
    • Remote execution must either be fully open (mode = 2) ...
    • ... or the particular function / command must be whitelisted.
  4. If JIP is used, JIP must be allowed by CfgRemoteExec (jip = 1)

If any of these conditions is not met, the remote execution request is blocked.


See Also