LibRPC Examples: Difference between revisions
Line 75: | Line 75: | ||
|- | |- | ||
| Setting player's vehicle | | Setting player's vehicle | ||
| <source>FindPlayer( 0 ).Vehicle = FindVehicle( 5 )</source> | | <source lang="lua">FindPlayer( 0 ).Vehicle = FindVehicle( 5 )</source> | ||
| It has to be called serverside: <source inline>CPlayer.__setTable.Vehicle.call( FindPlayer(0), FindVehicle(5) )</source> | | It has to be called serverside: <source inline>CPlayer.__setTable.Vehicle.call( FindPlayer(0), FindVehicle(5) )</source> | ||
<poem> | <poem> |
Revision as of 12:32, 8 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, ... )
MyFunction.call(getroottable(), p1, p2, ... )
Suppose i want to callMyFunction.call(m, p1, p2, ... )
where m is a table other than roottable. Then it was not possible.
It is for this reason that new function Fa is introduced.
The Working
This 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 parameter is not "string", then it will work as expected.
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
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 ) |
It has to be called serverside: CPlayer.__setTable.Vehicle.call( FindPlayer(0), FindVehicle(5) )
func<-Fa("rawget")(Fa("rawget")(F("rawget")("CPlayer"),"__setTable"),"Vehicle"); RFCa(func)(F("FindPlayer")(0), F("FindVehicle")(5)) |