[Tutorial] Remote Function calling
#1

Remote Function Calling


Introduction

This tutorial will be explaining remote function calling. Remote function calling here refers to call a function as remote from another script. Remote call doesn't need the source of that function to be on the script which is calling it out, it just requires that function to be created as a "public" one. Just like timers require "public" functions which are forwarded, the functions which has to undergo remote calls must also be forwarded and it should be a "public" function.

Remote calling can be useful for creating Anti-Cheats, getting values from another script (If those are implemented on a "public" function). Suppose if the whole administration system is on the gamemode and if admin level has to be taken on a filterscript, it's pretty much easy using remote calling. But a "public" function which returns player's admin level has to be created already on the gamemode.

Tutorial

On this tutorial, CallRemoteFunction is being used. CallRemoteFunction does a remote calling. It calls out a function from any script which contains that function.

pawn Code:
native CallRemoteFunction(const function[], const format[], {Float,_}:...);
Please refer the wiki page of CallRemoteFunction to know about the specifiers and arguments to be used. A small note can be given here that you must be giving the arguments or specifiers according to that function. It must remain like how it is on the function. Because it doesn't pass any default values as it's a "public". Getting things wrong could possibly crash your server.

There's nothing much big to explain about CallRemoteFunction other than defining it. So, let me show it through examples.

• Getting a player's admin level.
I'm adding a public function to my gamemode which would return the admin level variable since the gamemode got all the source of administration system.
pawn Code:
forward GetPlayerAdminLevel(playerid);

public GetPlayerAdminLevel(playerid) return PlayerAdminLevel[playerid]; //Directly returns the admin level of the player.
Now I'm creating a new filterscript with a command which would print the player's admin level. I'm opening a new script and I'm including a_samp first.
pawn Code:
#include <a_samp>
Now to do the remote call. We can create a "stock" function which returns the remote function's return. CallRemoteFunction returns what the "public" function specified on that function returns. So here, on CallRemoteFunction we can use "GetPlayerAdminLevel" public function to return it's value and that value would be the admin level of the player.

pawn Code:
#define FILTERSCRIPT //Supposing that this is a FS.
#include <a_samp>

stock GetPlayerAdminLevel(playerid) //There's no problem if this is a "stock" and having the same name of that "public" function.
{
    return CallRemoteFunction("GetPlayerAdminLevel", "i", playerid); //Directly calls out the "public" function named GetPlayerAdminLevel from other script.
    //It will be returning the admin level of the player.
}

//The function has been created, how about a command to test it?

public OnPlayerCommandText(playerid, cmdtext[])
{
    if(!strcmp(cmdtext, "/testadmlevel", true)) {
        printf("Your admin level is : %d", GetPlayerAdminLevel(playerid)); //Calls out the stock function.
        return 1;
    }
    return 0;
}
This can be useful on cases where you've to get the admin level for any sort of commands or stuff. The same idea can also be used to check if player is on any event, DM or stuffs.
• Linking up a function on Anti-Cheats
You can also use the same idea on Anti-Cheats. Like if player's pos is being set, rather than including the functions everywhere and getting it included on every scripts, create remote functions and use the AntiCheat as a filterscript. It would link things up together. I haven't tried that on any Anti-Cheat but I'm quite sure that it would work.

Suppose, this is my supercoolanticheat.PWN which is a filterscript. It got:
pawn Code:
forward LAnti_SetPlayerPos(playerid, Float:X, Float:Y, Float:Z);
public LAnti_SetPlayerPos(playerid, Float:X, Float:Y, Float:Z)
{
    LAnti_pX[playerid] = X;
    LAnti_pY[playerid] = Y;
    LAnti_pZ[playerid] = Z;
    return SetPlayerPos(playerid, X, Y, Z);
}
Now, I've got an include which got many remote functions. Rather than that include having all these arrays, I'm going to use remote calls.

pawn Code:
stock LAnti_SetPlayerPos(playerid, Float:X, Float:Y, Float:Z)
{
    return CallRemoteFunction("LAnti_SetPlayerPos", "ifff", playerid, X, Y, Z);
}
Now this would automatically set the array's values according to the call which has been done. I just have to include my "include" on every scripts. CallRemoteFunction fetches the function from every script which got that function.
You can also call up the SA-MP callbacks or any "public" functions using CallRemoteFunction. On cases where you call local OnPlayerConnect, if it's necessary to load something else from the OnPlayerConnect of other script, you can use CallRemoteFunction.

pawn Code:
CallRemoteFunction("OnPlayerConnect", "i", playerid); //This will call OnPlayerConnect on every script which uses OnPlayerConnect
I believe there's nothing big more to explain about CallRemoteFunction if you've understood it's use from these examples. If there's any doubt regarding this, in case if it's not explained or if there's any mistake on this tutorial, please feel free to post it here and so I can get it corrected.

https://github.com/Lordzy/RemoteFunctionExamples - Here's some examples in which an include file gets or sets the player's data from the gamemode.

-Lordz
Reply
#2

Good job with the explanation!
Reply
#3

I've done a small example to check the remote function. The include calls out the remote functions and returns the value for "Get" functions. And sets the value for "set" functions.
https://github.com/Lordzy/RemoteFunctionExamples

Quote:
Originally Posted by MarcObeles20
View Post
Good job with the explanation!
Thanks!
Reply
#4

Decent explanation.Awesome tutorial.
Helped me in understanding it more than before.
Cheers!
Reply
#5

So is it possible to get a variable's address if I add a parameter to it's forwarded function and then return it accordingly?
Reply
#6

Quote:
Originally Posted by Fernado Samuel
View Post
So is it possible to get a variable's address if I add a parameter to it's forwarded function and then return it accordingly?
Yes, you're able to get a variable's value through remote calling in case if you've forwarded a function. I've done an example of kills, deaths and levels which is linked on the main post. It contains such a remote call. However, here's a small example:

my_gamemode.pwn

pawn Code:
new
    myVars[5];
   
forward GetVariableValue(var_id);
public GetVariableValue(var_id)
{
    if(var_id < 0 || var_id > 4) return 0;
    return myVars[var_id];
}
my_FS.pwn

pawn Code:
stock GetVariableValue(var_id)
{
    return CallRemoteFunction("GetVariableValue", "i", var_id);
}
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)