void ProcessClientRpc(HashSet <string> names, MethodDefinition md, CustomAttribute clientRpcAttr) { if (md.IsAbstract) { Weaver.Error("Abstract ClientRpc are currently not supported, use virtual method instead", md); return; } if (!RpcProcessor.ProcessMethodsValidateRpc(md)) { return; } if (names.Contains(md.Name)) { Weaver.Error($"Duplicate ClientRpc name {md.Name}", md); return; } names.Add(md.Name); clientRpcs.Add(md); MethodDefinition rpcCallFunc = RpcProcessor.ProcessRpcCall(netBehaviourSubclass, md, clientRpcAttr); MethodDefinition rpcFunc = RpcProcessor.ProcessRpcInvoke(netBehaviourSubclass, md, rpcCallFunc); if (rpcFunc != null) { clientRpcInvocationFuncs.Add(rpcFunc); } }
void ProcessClientRpc(HashSet <string> names, MethodDefinition md, CustomAttribute ca) { if (!RpcProcessor.ProcessMethodsValidateRpc(md, ca)) { return; } if (names.Contains(md.Name)) { Weaver.Error("Duplicate ClientRpc name [" + netBehaviourSubclass.FullName + ":" + md.Name + "]"); return; } names.Add(md.Name); clientRpcs.Add(md); MethodDefinition rpcCallFunc = RpcProcessor.ProcessRpcCall(netBehaviourSubclass, md, ca); MethodDefinition rpcFunc = RpcProcessor.ProcessRpcInvoke(netBehaviourSubclass, md, rpcCallFunc); if (rpcFunc != null) { clientRpcInvocationFuncs.Add(rpcFunc); } if (rpcCallFunc != null) { clientRpcCallFuncs.Add(rpcCallFunc); } }
public static bool WriteArguments(ILProcessor worker, MethodDefinition method, RemoteCallType callType) { // write each argument // example result /* * writer.WritePackedInt32(someNumber); * writer.WriteNetworkIdentity(someTarget); */ bool skipFirst = callType == RemoteCallType.ClientRpc && RpcProcessor.HasNetworkConnectionParameter(method); // arg of calling function, arg 0 is "this" so start counting at 1 int argNum = 1; foreach (ParameterDefinition param in method.Parameters) { // NetworkConnection is not sent via the NetworkWriter so skip it here // skip first for NetworkConnection in TargetRpc if (argNum == 1 && skipFirst) { argNum += 1; continue; } // skip SenderConnection in ServerRpc if (IsNetworkConnection(param.ParameterType)) { argNum += 1; continue; } MethodReference writeFunc = Writers.GetWriteFunc(param.ParameterType); if (writeFunc == null) { Weaver.Error($"{method.Name} has invalid parameter {param}", method); return(false); } // use built-in writer func on writer object // NetworkWriter object worker.Append(worker.Create(OpCodes.Ldloc_0)); // add argument to call worker.Append(worker.Create(OpCodes.Ldarg, argNum)); // call writer extension method worker.Append(worker.Create(OpCodes.Call, writeFunc)); argNum += 1; } return(true); }
void ProcessClientRpc(HashSet <string> names, MethodDefinition md, CustomAttribute clientRpcAttr) { if (md.IsAbstract) { Weaver.Error("Abstract ClientRpc are currently not supported, use virtual method instead", md); return; } if (!ValidateRemoteCallAndParameters(md, RemoteCallType.ClientRpc)) { return; } if (!RpcProcessor.Validate(md, clientRpcAttr)) { return; } if (names.Contains(md.Name)) { Weaver.Error($"Duplicate ClientRpc name {md.Name}", md); return; } Client clientTarget = clientRpcAttr.GetField("target", Client.Observers); bool excludeOwner = clientRpcAttr.GetField("excludeOwner", false); names.Add(md.Name); clientRpcs.Add(new ClientRpcResult { method = md, target = clientTarget, excludeOwner = excludeOwner }); MethodDefinition userCodeFunc = RpcProcessor.GenerateStub(md, clientRpcAttr); MethodDefinition skeletonFunc = RpcProcessor.GenerateSkeleton(md, userCodeFunc, clientRpcAttr); if (skeletonFunc != null) { clientRpcSkeletonFuncs.Add(skeletonFunc); } }
void ProcessClientRpc(HashSet <string> names, MethodDefinition md, CustomAttribute clientRpcAttr) { if (md.IsAbstract) { Weaver.Error("Abstract ClientRpc are currently not supported, use virtual method instead", md); return; } if (!ValidateRemoteCallAndParameters(md, RemoteCallType.ClientRpc)) { return; } if (names.Contains(md.Name)) { Weaver.Error($"Duplicate ClientRpc name {md.Name}", md); return; } bool excludeOwner = clientRpcAttr.GetField("excludeOwner", false); names.Add(md.Name); clientRpcs.Add(new ClientRpcResult { method = md, excludeOwner = excludeOwner }); MethodDefinition rpcCallFunc = RpcProcessor.ProcessRpcCall(netBehaviourSubclass, md, clientRpcAttr); // need null check here because ProcessRpcCall returns null if it can't write all the args if (rpcCallFunc == null) { return; } MethodDefinition rpcFunc = RpcProcessor.ProcessRpcInvoke(netBehaviourSubclass, md, rpcCallFunc); if (rpcFunc != null) { clientRpcInvocationFuncs.Add(rpcFunc); } }
void ProcessClientRpc(HashSet <string> names, MethodDefinition md, CustomAttribute clientRpcAttr, ref bool WeavingFailed) { if (md.IsAbstract) { Log.Error("Abstract ClientRpc are currently not supported, use virtual method instead", md); WeavingFailed = true; return; } if (!ValidateRemoteCallAndParameters(md, RemoteCallType.ClientRpc, ref WeavingFailed)) { return; } bool includeOwner = clientRpcAttr.GetField("includeOwner", true); names.Add(md.Name); clientRpcs.Add(new ClientRpcResult { method = md, includeOwner = includeOwner }); MethodDefinition rpcCallFunc = RpcProcessor.ProcessRpcCall(weaverTypes, writers, Log, netBehaviourSubclass, md, clientRpcAttr, ref WeavingFailed); // need null check here because ProcessRpcCall returns null if it can't write all the args if (rpcCallFunc == null) { return; } MethodDefinition rpcFunc = RpcProcessor.ProcessRpcInvoke(weaverTypes, writers, readers, Log, netBehaviourSubclass, md, rpcCallFunc, ref WeavingFailed); if (rpcFunc != null) { clientRpcInvocationFuncs.Add(rpcFunc); } }
void ProcessMethods() { HashSet <string> names = new HashSet <string>(); // find command and RPC functions foreach (MethodDefinition md in m_td.Methods) { Weaver.ResetRecursionCount(); foreach (CustomAttribute ca in md.CustomAttributes) { if (ca.AttributeType.FullName == Weaver.CommandType.FullName) { if (!CommandProcessor.ProcessMethodsValidateCommand(m_td, md, ca)) { return; } if (names.Contains(md.Name)) { Log.Error("Duplicate Command name [" + m_td.FullName + ":" + md.Name + "]"); Weaver.fail = true; return; } names.Add(md.Name); m_Cmds.Add(md); MethodDefinition cmdFunc = CommandProcessor.ProcessCommandInvoke(m_td, md); if (cmdFunc != null) { m_CmdInvocationFuncs.Add(cmdFunc); } MethodDefinition cmdCallFunc = CommandProcessor.ProcessCommandCall(m_td, md, ca); if (cmdCallFunc != null) { m_CmdCallFuncs.Add(cmdCallFunc); Weaver.lists.replaceMethods[md.FullName] = cmdCallFunc; } break; } if (ca.AttributeType.FullName == Weaver.TargetRpcType.FullName) { if (!TargetRpcProcessor.ProcessMethodsValidateTargetRpc(m_td, md, ca)) { return; } if (names.Contains(md.Name)) { Log.Error("Duplicate Target Rpc name [" + m_td.FullName + ":" + md.Name + "]"); Weaver.fail = true; return; } names.Add(md.Name); m_TargetRpcs.Add(md); MethodDefinition rpcFunc = TargetRpcProcessor.ProcessTargetRpcInvoke(m_td, md); if (rpcFunc != null) { m_TargetRpcInvocationFuncs.Add(rpcFunc); } MethodDefinition rpcCallFunc = TargetRpcProcessor.ProcessTargetRpcCall(m_td, md, ca); if (rpcCallFunc != null) { m_TargetRpcCallFuncs.Add(rpcCallFunc); Weaver.lists.replaceMethods[md.FullName] = rpcCallFunc; } break; } if (ca.AttributeType.FullName == Weaver.ClientRpcType.FullName) { if (!RpcProcessor.ProcessMethodsValidateRpc(m_td, md, ca)) { return; } if (names.Contains(md.Name)) { Log.Error("Duplicate ClientRpc name [" + m_td.FullName + ":" + md.Name + "]"); Weaver.fail = true; return; } names.Add(md.Name); m_Rpcs.Add(md); MethodDefinition rpcFunc = RpcProcessor.ProcessRpcInvoke(m_td, md); if (rpcFunc != null) { m_RpcInvocationFuncs.Add(rpcFunc); } MethodDefinition rpcCallFunc = RpcProcessor.ProcessRpcCall(m_td, md, ca); if (rpcCallFunc != null) { m_RpcCallFuncs.Add(rpcCallFunc); Weaver.lists.replaceMethods[md.FullName] = rpcCallFunc; } break; } } } // cmds foreach (MethodDefinition md in m_CmdInvocationFuncs) { m_td.Methods.Add(md); } foreach (MethodDefinition md in m_CmdCallFuncs) { m_td.Methods.Add(md); } // rpcs foreach (MethodDefinition md in m_RpcInvocationFuncs) { m_td.Methods.Add(md); } foreach (MethodDefinition md in m_TargetRpcInvocationFuncs) { m_td.Methods.Add(md); } foreach (MethodDefinition md in m_RpcCallFuncs) { m_td.Methods.Add(md); } foreach (MethodDefinition md in m_TargetRpcCallFuncs) { m_td.Methods.Add(md); } }