Weaver [TargetRpc] processing moved into NetworkBehaviourTargetRpcProcessor

This commit is contained in:
vis2k 2018-12-31 00:57:17 +01:00
parent b9963fdf4d
commit a12ac8e8b0
3 changed files with 116 additions and 106 deletions

View File

@ -70,6 +70,7 @@
<Compile Include="MonoBehaviourProcessor.cs" />
<Compile Include="NetworkBehaviourCommandProcessor.cs" />
<Compile Include="NetworkBehaviourRpcProcessor.cs" />
<Compile Include="NetworkBehaviourTargetRpcProcessor.cs" />
<Compile Include="Program.cs" />
<Compile Include="SyncListStructProcessor.cs" />
<Compile Include="NetworkBehaviourProcessor.cs" />

View File

@ -28,8 +28,6 @@ class NetworkBehaviourProcessor
const int k_SyncVarLimit = 64; // ulong = 64 bytes
readonly TypeDefinition m_td;
const string k_TargetRpcPrefix = "InvokeTargetRpc";
public NetworkBehaviourProcessor(TypeDefinition td)
{
Weaver.DLog(td, "NetworkBehaviourProcessor");
@ -821,108 +819,6 @@ public static void AddInvokeParameters(ICollection<ParameterDefinition> collecti
collection.Add(new ParameterDefinition("reader", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkReaderType)));
}
MethodDefinition ProcessTargetRpcInvoke(MethodDefinition md)
{
MethodDefinition rpc = new MethodDefinition(NetworkBehaviourRpcProcessor.k_RpcPrefix + md.Name, MethodAttributes.Family |
MethodAttributes.Static |
MethodAttributes.HideBySig,
Weaver.voidType);
ILProcessor rpcWorker = rpc.Body.GetILProcessor();
Instruction label = rpcWorker.Create(OpCodes.Nop);
WriteClientActiveCheck(rpcWorker, md.Name, label, "TargetRPC");
// setup for reader
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldarg_0));
rpcWorker.Append(rpcWorker.Create(OpCodes.Castclass, m_td));
//ClientScene.readyconnection
rpcWorker.Append(rpcWorker.Create(OpCodes.Call, Weaver.ReadyConnectionReference));
if (!ProcessNetworkReaderParameters(m_td, md, rpcWorker, true))
return null;
// invoke actual command function
rpcWorker.Append(rpcWorker.Create(OpCodes.Callvirt, md));
rpcWorker.Append(rpcWorker.Create(OpCodes.Ret));
AddInvokeParameters(rpc.Parameters);
return rpc;
}
/* generates code like:
public void CallTargetTest (NetworkConnection conn, int param)
{
if (!NetworkServer.get_active ()) {
Debug.LogError((object)"TargetRPC Function TargetTest called on client.");
} else if (((?)conn) is ULocalConnectionToServer) {
Debug.LogError((object)"TargetRPC Function TargetTest called on connection to server");
} else {
NetworkWriter writer = new NetworkWriter ();
writer.WritePackedUInt32 ((uint)param);
base.SendTargetRPCInternal (conn, "TargetTest", val);
}
}
*/
MethodDefinition ProcessTargetRpcCall(MethodDefinition md, CustomAttribute ca)
{
MethodDefinition rpc = new MethodDefinition("Call" + md.Name, MethodAttributes.Public |
MethodAttributes.HideBySig,
Weaver.voidType);
// add paramters
foreach (ParameterDefinition pd in md.Parameters)
{
rpc.Parameters.Add(new ParameterDefinition(pd.Name, ParameterAttributes.None, pd.ParameterType));
}
ILProcessor rpcWorker = rpc.Body.GetILProcessor();
Instruction label = rpcWorker.Create(OpCodes.Nop);
WriteSetupLocals(rpcWorker);
WriteServerActiveCheck(rpcWorker, md.Name, label, "TargetRPC Function");
Instruction labelConnectionCheck = rpcWorker.Create(OpCodes.Nop);
// check specifically for ULocalConnectionToServer so a host is not trying to send
// an TargetRPC to the "server" from it's local client.
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldarg_1));
rpcWorker.Append(rpcWorker.Create(OpCodes.Isinst, Weaver.ULocalConnectionToServerType));
rpcWorker.Append(rpcWorker.Create(OpCodes.Brfalse, labelConnectionCheck));
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldstr, string.Format("TargetRPC Function {0} called on connection to server", md.Name)));
rpcWorker.Append(rpcWorker.Create(OpCodes.Call, Weaver.logErrorReference));
rpcWorker.Append(rpcWorker.Create(OpCodes.Ret));
rpcWorker.Append(labelConnectionCheck);
WriteCreateWriter(rpcWorker);
// write all the arguments that the user passed to the TargetRpc call
if (!WriteArguments(rpcWorker, md, "TargetRPC", true))
return null;
var rpcName = md.Name;
int index = rpcName.IndexOf(k_TargetRpcPrefix);
if (index > -1)
{
rpcName = rpcName.Substring(k_TargetRpcPrefix.Length);
}
// invoke SendInternal and return
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldarg_0)); // this
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldarg_1)); // connection
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldstr, rpcName));
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldloc_0)); // writer
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldc_I4, GetChannelId(ca)));
rpcWorker.Append(rpcWorker.Create(OpCodes.Callvirt, Weaver.sendTargetRpcInternal));
rpcWorker.Append(rpcWorker.Create(OpCodes.Ret));
return rpc;
}
bool ProcessMethodsValidateFunction(MethodReference md, string actionType)
{
if (md.ReturnType.FullName == Weaver.IEnumeratorType.FullName)
@ -1155,13 +1051,13 @@ void ProcessMethods()
names.Add(md.Name);
m_TargetRpcs.Add(md);
MethodDefinition rpcFunc = ProcessTargetRpcInvoke(md);
MethodDefinition rpcFunc = NetworkBehaviourTargetRpcProcessor.ProcessTargetRpcInvoke(m_td, md);
if (rpcFunc != null)
{
m_TargetRpcInvocationFuncs.Add(rpcFunc);
}
MethodDefinition rpcCallFunc = ProcessTargetRpcCall(md, ca);
MethodDefinition rpcCallFunc = NetworkBehaviourTargetRpcProcessor.ProcessTargetRpcCall(md, ca);
if (rpcCallFunc != null)
{
m_TargetRpcCallFuncs.Add(rpcCallFunc);

View File

@ -0,0 +1,113 @@
// all the [TargetRpc] code from NetworkBehaviourProcessor in one place
using Mono.Cecil;
using Mono.Cecil.Cil;
namespace Mirror.Weaver
{
public class NetworkBehaviourTargetRpcProcessor
{
const string k_TargetRpcPrefix = "InvokeTargetRpc";
public static MethodDefinition ProcessTargetRpcInvoke(TypeDefinition td, MethodDefinition md)
{
MethodDefinition rpc = new MethodDefinition(NetworkBehaviourRpcProcessor.k_RpcPrefix + md.Name, MethodAttributes.Family |
MethodAttributes.Static |
MethodAttributes.HideBySig,
Weaver.voidType);
ILProcessor rpcWorker = rpc.Body.GetILProcessor();
Instruction label = rpcWorker.Create(OpCodes.Nop);
NetworkBehaviourProcessor.WriteClientActiveCheck(rpcWorker, md.Name, label, "TargetRPC");
// setup for reader
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldarg_0));
rpcWorker.Append(rpcWorker.Create(OpCodes.Castclass, td));
//ClientScene.readyconnection
rpcWorker.Append(rpcWorker.Create(OpCodes.Call, Weaver.ReadyConnectionReference));
if (!NetworkBehaviourProcessor.ProcessNetworkReaderParameters(td, md, rpcWorker, true))
return null;
// invoke actual command function
rpcWorker.Append(rpcWorker.Create(OpCodes.Callvirt, md));
rpcWorker.Append(rpcWorker.Create(OpCodes.Ret));
NetworkBehaviourProcessor.AddInvokeParameters(rpc.Parameters);
return rpc;
}
/* generates code like:
public void CallTargetTest (NetworkConnection conn, int param)
{
if (!NetworkServer.get_active ()) {
Debug.LogError((object)"TargetRPC Function TargetTest called on client.");
} else if (((?)conn) is ULocalConnectionToServer) {
Debug.LogError((object)"TargetRPC Function TargetTest called on connection to server");
} else {
NetworkWriter writer = new NetworkWriter ();
writer.WritePackedUInt32 ((uint)param);
base.SendTargetRPCInternal (conn, "TargetTest", val);
}
}
*/
public static MethodDefinition ProcessTargetRpcCall(MethodDefinition md, CustomAttribute ca)
{
MethodDefinition rpc = new MethodDefinition("Call" + md.Name, MethodAttributes.Public |
MethodAttributes.HideBySig,
Weaver.voidType);
// add paramters
foreach (ParameterDefinition pd in md.Parameters)
{
rpc.Parameters.Add(new ParameterDefinition(pd.Name, ParameterAttributes.None, pd.ParameterType));
}
ILProcessor rpcWorker = rpc.Body.GetILProcessor();
Instruction label = rpcWorker.Create(OpCodes.Nop);
NetworkBehaviourProcessor.WriteSetupLocals(rpcWorker);
NetworkBehaviourProcessor.WriteServerActiveCheck(rpcWorker, md.Name, label, "TargetRPC Function");
Instruction labelConnectionCheck = rpcWorker.Create(OpCodes.Nop);
// check specifically for ULocalConnectionToServer so a host is not trying to send
// an TargetRPC to the "server" from it's local client.
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldarg_1));
rpcWorker.Append(rpcWorker.Create(OpCodes.Isinst, Weaver.ULocalConnectionToServerType));
rpcWorker.Append(rpcWorker.Create(OpCodes.Brfalse, labelConnectionCheck));
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldstr, string.Format("TargetRPC Function {0} called on connection to server", md.Name)));
rpcWorker.Append(rpcWorker.Create(OpCodes.Call, Weaver.logErrorReference));
rpcWorker.Append(rpcWorker.Create(OpCodes.Ret));
rpcWorker.Append(labelConnectionCheck);
NetworkBehaviourProcessor.WriteCreateWriter(rpcWorker);
// write all the arguments that the user passed to the TargetRpc call
if (!NetworkBehaviourProcessor.WriteArguments(rpcWorker, md, "TargetRPC", true))
return null;
var rpcName = md.Name;
int index = rpcName.IndexOf(k_TargetRpcPrefix);
if (index > -1)
{
rpcName = rpcName.Substring(k_TargetRpcPrefix.Length);
}
// invoke SendInternal and return
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldarg_0)); // this
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldarg_1)); // connection
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldstr, rpcName));
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldloc_0)); // writer
rpcWorker.Append(rpcWorker.Create(OpCodes.Ldc_I4, NetworkBehaviourProcessor.GetChannelId(ca)));
rpcWorker.Append(rpcWorker.Create(OpCodes.Callvirt, Weaver.sendTargetRpcInternal));
rpcWorker.Append(rpcWorker.Create(OpCodes.Ret));
return rpc;
}
}
}