DayZ-CommunityFramework
DayZ-CommunityFramework copied to clipboard
RPC manager rework
- Added CF.RPC / CF_RPC as easier to use wrapper around rpcs
- Moved RPCManager to legacy folder
The main advantage is that you do not need to explicitly register your mod and function for everything you might want to send. If a mod only needs one handler you only set it up once and then every new function added does not require any interaction with CF. Additionally, the now underlying ScriptRPC allows for retransmission of the same data to multiple receivers.
What is not part of the reworked interface is the whole concept of single-player execution behavior. There are other more compact ways to switch logic for single-player testing. Either they use different functions, or within the function, you check if you are the host or not and handle the data accordingly. Besides - I have not seen much clever use of it. If someone absolutely needs it (which I doubt) they can refer to the legacy RPCManager that continues to exist until we figure out a way to update the new interface to offer that as well.
See the minimal demo of how RPC's would work with this now:
class RpcMinimalDemo
{
void RpcMinimalDemo()
{
CF.RPC.RegisterHandler(this); //This can be skipped if the handler inheris from CF_RPC_HandlerBase
}
/*
This is is the interface of functions that handle rpcs. It always has to be these 3 parameters.
Sender will return null in singleplayer.
*/
void Hello(ParamsReadContext ctx, PlayerIdentity sender, Object target)
{
PrintFormat("Hello -> ParamsReadContext %1; PlayerIdentity %2; Object %3", ctx, sender, target);
string data;
if(!ctx.Read(data)) return;
PrintFormat("Data received: %1", data);
}
void SendRpcToServer()
{
auto rpc = CF.RPC.Prepare("RpcMinimalDemo", "Hello", true);
rpc.Write("Hello from the other side!");
//Option 1 - NULL target
rpc.SendTo();
//Option 2 - explicit but still NULL target
rpc.SendTo(NULL);
//Option 3 for more readability
rpc.SendTo(CF.RPC.SERVER);
}
void SendRpcFrommServerToPlayer(PlayerIdentity player)
{
auto rpc = CF.RPC.Prepare("RpcMinimalDemo", "Hello", true);
rpc.Write("Hello Player!");
rpc.SendTo(player);
}
}
What happens when you register multiple RPC handlers of the same typename? It goes specifically by instance right? Will it send an RPC to all instances of RpcMinimalDemo?
What happens when you register multiple RPC handlers of the same typename? It goes specifically by instance right? Will it send an RPC to all instances of RpcMinimalDemo?
Registering an instance of the same type twice will result in a warning: https://github.com/Jacob-Mango/DayZ-Community-Framework/blob/f9deb5e56a43e898fb1cb63ad1a43599b4bcd765/JM/CF/Scripts/3_Game/CommunityFramework/RPC/RPC.c#L34
There can only be one handler because of the read context in the RPC. Once the first handler read the data from it, it would be empty for the next one. I do not see a way around it currently.
Needs to be able to explicitly mark the functions which can be handled. Don't want to allow any function within the handler to be called.
Needs to be able to explicitly mark the functions which can be handled. Don't want to allow any function within the handler to be called.
Maybe an optional whitelist when registering? Default would be everything is whitelisted (for the main use-case of extra handlers that ONLY contain functions to be called). And if you were to add MissionGameplay as handler instance you could restrict it to the 2-3 functions you want to be callable. I think a whitelist approach is better for the workflow than blacklisting functions you are not allowed to call?