LibRPC Examples: Difference between revisions
(19 intermediate revisions by the same user not shown) | |||
Line 9: | Line 9: | ||
</source> | </source> | ||
<poem> | <poem> | ||
On serverside, it is equivalent to <source>MyFunction.call(getroottable(), p1, p2, ... )</source | On serverside, it is equivalent to | ||
<source lang="lua">MyFunction(p1, p2,... )</source> | |||
It is for this reason that new function Fa is introduced. | Considering environments this is equal to : | ||
<source lang="lua">MyFunction.call(getroottable(), p1, p2, ... )</source>Suppose i want to call<source lang="lua">MyFunction.call(m, p1, p2, ... )</source> where m is a table '''other than''' roottable. How to do it? | |||
It is for this reason that new function Fa (different from F) is introduced. | |||
</poem> | </poem> | ||
==The Working== | ==The Working== | ||
Suppose i want to call | |||
<source lang="lua">MyFunction.call(m, p1, p2, ... ) </source> | |||
where m is any table and rest are parameters(integers, strings, etc) and the case is 'MyFunction' resides in roottable. | |||
The following leads to error: | |||
<source>Fa("MyFunction")(m, p1, p2, ... )</source> | <source>Fa("MyFunction")(m, p1, p2, ... )</source> | ||
because the key MyFunction will be looked inside table m. So if MyFunction is in roottable, the correct code will be | because the key MyFunction will be looked inside table m. So if MyFunction is in roottable, the correct code will be | ||
<source>Fa(F("rawget")("MyFunction"))(m, p1, p2, ... )</source> | <source>Fa(F("rawget")("MyFunction"))(m, p1, p2, ... )</source> | ||
When the parameter is not "string", then it will | When the first order parameter in Fa is not "string" but userdata (i.e not "MyFunction", but return value of F), then it will call the function(first order parameter) with second order parameters where the first of the second order parameter as environment. | ||
==Example One== | ==Example One== | ||
Let us see an example. Suppose that in roottable of server a table 'C' exists which has a slot named 'a' whose value is 3. | Let us see an example. Suppose that in roottable of server a table 'C' exists which has a slot named 'a' whose value is 3. | ||
Line 36: | Line 43: | ||
Alternatively, you can use this too using <source inline>KickPlayer</source> | Alternatively, you can use this too using <source inline>KickPlayer</source> | ||
<source lang="lua>RFC("KickPlayer")(F("FindPlayer")(0))</source> | <source lang="lua>RFC("KickPlayer")(F("FindPlayer")(0))</source> | ||
==Example Three: Tough One== | ==Example Three: Tough One - Setting the Cash== | ||
How will you do this: | How will you do this: | ||
<source>FindPlayer(0).Cash=2000</source> | <source>FindPlayer(0).Cash=2000</source> | ||
Line 59: | Line 66: | ||
4. The outer RFCa means we are raw calling. So The Cash function obtained in (3) is called with instance FindPlayer(0) as '''first''' parameter and cash amount: 2000 as '''second''' parameter | 4. The outer RFCa means we are raw calling. So The Cash function obtained in (3) is called with instance FindPlayer(0) as '''first''' parameter and cash amount: 2000 as '''second''' parameter | ||
</poem> | </poem> | ||
==Other Examples== | ==Other Examples== | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 81: | Line 89: | ||
The code will be:</poem><source lang="lua">func<-Fa("rawget")(Fa("rawget")(F("rawget")("CPlayer"),"__setTable"),"Vehicle"); | The code will be:</poem><source lang="lua">func<-Fa("rawget")(Fa("rawget")(F("rawget")("CPlayer"),"__setTable"),"Vehicle"); | ||
RFCa(func)(F("FindPlayer")(0), F("FindVehicle")(5))</source> | RFCa(func)(F("FindPlayer")(0), F("FindVehicle")(5))</source> | ||
<poem> | <poem>The above code can be broken down to:</poem> | ||
<source lang="lua">local myclass=F("rawget")("CPlayer"); | <source lang="lua">local myclass=F("rawget")("CPlayer"); | ||
local mytable=Fa("rawget")(myclass, "__setTable"); | local mytable=Fa("rawget")(myclass, "__setTable"); | ||
Line 87: | Line 95: | ||
RFCa(func)(F("FindPlayer")(0),F("FindVehicle")(5))</source> | RFCa(func)(F("FindPlayer")(0),F("FindVehicle")(5))</source> | ||
|} | |} | ||
==Notes== | |||
<poem> | |||
1. The functions of CPlayer class like SetWeapon, SetAnim, SetWantedLevel can be called directly (As in second row of table). | |||
2. The 'property' functions - 'Vehicle', 'Cash', 'Pos', etc are hidden in the __setTable (of CPlayer class) for setting the value and __getTable (") for getting the value. (Third row example illustrates this) | |||
3. The npc04relxx plugin which executes the codes in server given from npc only if npc is made admin in server. | |||
</poem> |
Latest revision as of 05:52, 25 June 2023
The new version of LibRPC (of this article) is about to be released
New functions Fa, RFCa was added to library for raw calling of functions with a specified environment class or instance. Earlier the 'this' was always the roottable. By using "compilestring", one do not need Fa and RFCa.
The Problem
F("MyFunction")(p1, p2, ... )
On serverside, it is equivalent to
MyFunction(p1, p2,... )
Considering environments this is equal to :
MyFunction.call(getroottable(), p1, p2, ... )Suppose i want to call
MyFunction.call(m, p1, p2, ... )where m is a table other than roottable. How to do it?
It is for this reason that new function Fa (different from F) is introduced.
The Working
Suppose i want to call
MyFunction.call(m, p1, p2, ... )
where m is any table and rest are parameters(integers, strings, etc) and the case is 'MyFunction' resides in roottable. The following leads to error:
Fa("MyFunction")(m, p1, p2, ... )
because the key MyFunction will be looked inside table m. So if MyFunction is in roottable, the correct code will be
Fa(F("rawget")("MyFunction"))(m, p1, p2, ... )
When the first order parameter in Fa is not "string" but userdata (i.e not "MyFunction", but return value of F), then it will call the function(first order parameter) with second order parameters where the first of the second order parameter as environment.
Example One
Let us see an example. Suppose that in roottable of server a table 'C' exists which has a slot named 'a' whose value is 3. Now we are printing that value on server console from npc ( npc must be admin to print. Not only print, but actually for executing any functions remotely ). On serverside, what we want is
print(C.rawget("a"))
Corresponding remote function call would be
RFC("print")( Fa("rawget")( F("rawget")("C"), "a" ) )
Note: F will rawget from roottable while Fa will rawget from its first parameter. F("rawget")("C")
will return the table C.
Example Two - Kicking the player
Calling FindPlayer(0).Kick
remotely requires
RFCa("Kick")(F("FindPlayer")(0))
Here RFCa ( parallel of RFC, as Fa is to F ) looks for key 'Kick' after pushing it's first 2nd order parameter ( FindPlayer(0) ).
Alternatively, you can use this too using KickPlayer
RFC("KickPlayer")(F("FindPlayer")(0))
Example Three: Tough One - Setting the Cash
How will you do this:
FindPlayer(0).Cash=2000
?
To understand this, let us see how the 'Cash' function is stored.
print(CPlayer.__setTable.Cash) [SCRIPT] (function : 0x033A4CC8)
and
CPlayer.__setTable.Cash.call(FindPlayer(0),2001) print(FindPlayer(0).Cash) [SCRIPT] 2001
So we got what we wanted: CPlayer.__setTable.Cash.call(instance, cash )
The corresponding remote code would be (tested):
RFCa(Fa("rawget")(Fa("rawget")(F("rawget")("CPlayer"),"__setTable"),"Cash"))(F("FindPlayer ")(0),2000)
Explanation( 3 step ):
1. The innermost 'F' is used to rawget "CPlayer" from roottable
2. The inner Fa is used to rawget '__setTable' from class CPlayer.
3. The outer Fa is used to rawget function 'Cash' from table __setTable.
4. The outer RFCa means we are raw calling. So The Cash function obtained in (3) is called with instance FindPlayer(0) as first parameter and cash amount: 2000 as second parameter
Other Examples
Remark | Serverside | npc-side |
---|---|---|
a is a global variable | a=100; |
RFC("rawset")("a", 100) |
Setting npc's weapon | FindPlayer( npcid ).SetWeapon(33, 900) |
RFCa("SetWeapon")(F("FindPlayer")(GetMyID()), 33, 900) RFCa(Fa("rawget")(F("rawget")("CPlayer"),"SetWeapon"))(F("FindPlayer")(0),32, 900) |
Setting player's vehicle | FindPlayer( 0 ).Vehicle = FindVehicle( 5 )This can be called: CPlayer.__setTable.Vehicle.call( FindPlayer(0), FindVehicle(5) ) |
The code will be: func<-Fa("rawget")(Fa("rawget")(F("rawget")("CPlayer"),"__setTable"),"Vehicle"); RFCa(func)(F("FindPlayer")(0), F("FindVehicle")(5)) The above code can be broken down to: local myclass=F("rawget")("CPlayer"); local mytable=Fa("rawget")(myclass, "__setTable"); local func=Fa("rawget")(mytable, "Vehicle" ); RFCa(func)(F("FindPlayer")(0),F("FindVehicle")(5)) |
Notes
1. The functions of CPlayer class like SetWeapon, SetAnim, SetWantedLevel can be called directly (As in second row of table).
2. The 'property' functions - 'Vehicle', 'Cash', 'Pos', etc are hidden in the __setTable (of CPlayer class) for setting the value and __getTable (") for getting the value. (Third row example illustrates this)
3. The npc04relxx plugin which executes the codes in server given from npc only if npc is made admin in server.