So you have a piece of code you want to execute on all computers for whatever reason. As a mission/mod maker you should be in charge of what is and is not allowed in your creation. One thing you definitely don’t want is to allow passing of a code over network and then letting all client machines to execute this code. Mainly because this is an invitation to all sorts of hacks and exploits and also because transferring chunks of code over network is pretty bad for bandwidth. What you really want to do is to create a custom function on each client, lock it and then be able to call it from anywhere with a set of parameters rather than passing over a bare code.
Creating function on each client is easy. When mission loads, init.sqf loads and every machine will run it once, including dedicated server. So defining function in init.sqf or any file that is called from it will do the trick. Calling it from anywhere is also easy, you just have to use a combination of publicVariable and respectful event handler. It all boils down to setting up a callback framework, i.e. the main function that will do all the calls on clients for us.
We will pass a custom function name as a string to our callback function. The string then needs to be somehow converted to actual variable holding custom function code. But whatever you do, do not use call compile format for this. I will show you why. Lets say we have constructed our bad callback framework function and defined it on every PC.
We even attempted to make it secure by prefixing called name, so that no other functions may be called but those that start with “fnc_”. Now lets define our custom function we want to call on every machine.
To make it all work we need an event handler that will call our bad callback framework, which in return will call our custom function.
And to make event handler fire in the first place we need to define and broadcast our public variable from another machine.
So after initial call compile format in our bad function we will end up with:
So it looks like everything works. Not bad, until a hacker comes and broadcasts own public variable like this:
Now call compile format result will look like this:
As you can see, our bad function will first finish the intended call, then will happily carry own executing malicious code injected by the hacker. So first thing is first, we never use call compile format combo, instead we use namespace.
You simply cannot inject code into this construction. Well, actually you can but it is no good since nothing gets compiled, so it is useless. On top we can define a fallback function that will be executed in case the passed function name is a non-existent variable, alerting us if someone is trying anything dodgy. We also have to make sure we cannot call our framework function from our framework function, creating endless loop. After all these considerations, this is what we have:
As before we need custom function and event handler.
And to send the call over network:
Just remember, public variable event handler will not be triggered on the machine you call publicVariable from, so you will need to call your custom function directly on that PC.
After it all has been tested and working as intended it is time to lock the code, so that no one can overwrite our callback framework. We are going to use compileFinal command for it (is ArmA 3 feature for now). It simply compiles passed string into a code and makes it final. It will not be possible to alter the variable containing code after this. We can either convert our functions to strings by hand or use converter I’ve made. The final result will look like this:
Would be a good idea to stop our custom function from unauthorised overwrites too.
And now the Bonus Ball!
Pages: 1 2