/* * // generates code like: * protected static void InvokeCmdCmdThrust(NetworkBehaviour obj, NetworkReader reader, NetworkConnection senderConnection) * { * if (!NetworkServer.active) * { * return; * } * ((ShipControl)obj).CmdThrust(reader.ReadSingle(), (int)reader.ReadPackedUInt32()); * } */ public static MethodDefinition ProcessCommandInvoke(TypeDefinition td, MethodDefinition method, MethodDefinition cmdCallFunc) { MethodDefinition cmd = new MethodDefinition(Weaver.InvokeRpcPrefix + method.Name, MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig, WeaverTypes.Import(typeof(void))); ILProcessor worker = cmd.Body.GetILProcessor(); Instruction label = worker.Create(OpCodes.Nop); NetworkBehaviourProcessor.WriteServerActiveCheck(worker, method.Name, label, "Command"); // setup for reader worker.Append(worker.Create(OpCodes.Ldarg_0)); worker.Append(worker.Create(OpCodes.Castclass, td)); if (!NetworkBehaviourProcessor.ReadArguments(method, worker, RemoteCallType.Command)) { return(null); } AddSenderConnection(method, worker); // invoke actual command function worker.Append(worker.Create(OpCodes.Callvirt, cmdCallFunc)); worker.Append(worker.Create(OpCodes.Ret)); NetworkBehaviourProcessor.AddInvokeParameters(cmd.Parameters); td.Methods.Add(cmd); return(cmd); }
/* * // generates code like: * protected static void InvokeCmdCmdThrust(NetworkBehaviour obj, NetworkReader reader) * { * if (!obj.netIdentity.server.active) * { * return; * } * ((ShipControl)obj).CmdThrust(reader.ReadSingle(), (int)reader.ReadPackedUInt32()); * } */ public static MethodDefinition ProcessCommandInvoke(TypeDefinition td, MethodDefinition md, MethodDefinition cmdCallFunc) { MethodDefinition cmd = new MethodDefinition(CmdPrefix + md.Name, MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig, Weaver.voidType); ILProcessor cmdWorker = cmd.Body.GetILProcessor(); Instruction label = cmdWorker.Create(OpCodes.Nop); NetworkBehaviourProcessor.WriteServerActiveCheck(cmdWorker, md.Name, label, "Command"); // setup for reader cmdWorker.Append(cmdWorker.Create(OpCodes.Ldarg_0)); cmdWorker.Append(cmdWorker.Create(OpCodes.Castclass, td)); if (!NetworkBehaviourProcessor.ProcessNetworkReaderParameters(md, cmdWorker, false)) { return(null); } // invoke actual command function cmdWorker.Append(cmdWorker.Create(OpCodes.Callvirt, cmdCallFunc)); cmdWorker.Append(cmdWorker.Create(OpCodes.Ret)); NetworkBehaviourProcessor.AddInvokeParameters(cmd.Parameters); return(cmd); }
/// <summary> /// Generates a skeleton for a ServerRpc /// </summary> /// <param name="td"></param> /// <param name="method"></param> /// <param name="userCodeFunc"></param> /// <returns>The newly created skeleton method</returns> /// <remarks> /// Generates code like this: /// <code> /// protected static void Skeleton_MyServerRpc(NetworkBehaviour obj, NetworkReader reader, NetworkConnection senderConnection) /// { /// if (!obj.netIdentity.server.active) /// { /// return; /// } /// ((ShipControl) obj).UserCode_Thrust(reader.ReadSingle(), (int) reader.ReadPackedUInt32()); /// } /// </code> /// </remarks> public static MethodDefinition GenerateSkeleton(MethodDefinition method, MethodDefinition userCodeFunc) { var cmd = new MethodDefinition(MethodProcessor.SkeletonPrefix + method.Name, MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig, WeaverTypes.Import(typeof(void))); ILProcessor worker = cmd.Body.GetILProcessor(); Instruction label = worker.Create(OpCodes.Nop); NetworkBehaviourProcessor.WriteServerActiveCheck(worker, method.Name, label, "ServerRpc"); // setup for reader worker.Append(worker.Create(OpCodes.Ldarg_0)); worker.Append(worker.Create(OpCodes.Castclass, method.DeclaringType)); if (!NetworkBehaviourProcessor.ReadArguments(method, worker, false)) { return(null); } AddSenderConnection(method, worker); // invoke actual ServerRpc function worker.Append(worker.Create(OpCodes.Callvirt, userCodeFunc)); worker.Append(worker.Create(OpCodes.Ret)); NetworkBehaviourProcessor.AddInvokeParameters(cmd.Parameters); method.DeclaringType.Methods.Add(cmd); return(cmd); }
/* generates code like: * public void CallRpcTest (int param) * { * if (!NetworkServer.get_active ()) { * Debug.LogError ((object)"RPC Function RpcTest called on client."); * } else { * NetworkWriter writer = new NetworkWriter (); * writer.WritePackedUInt32((uint)param); * base.SendRPCInternal(typeof(class),"RpcTest", writer, 0); * } * } */ public static MethodDefinition ProcessRpcCall(TypeDefinition td, 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, "RPC Function"); NetworkBehaviourProcessor.WriteCreateWriter(rpcWorker); // write all the arguments that the user passed to the Rpc call if (!NetworkBehaviourProcessor.WriteArguments(rpcWorker, md, "RPC", false)) { return(null); } var rpcName = md.Name; int index = rpcName.IndexOf(k_RpcPrefix); if (index > -1) { rpcName = rpcName.Substring(k_RpcPrefix.Length); } // invoke SendInternal and return rpcWorker.Append(rpcWorker.Create(OpCodes.Ldarg_0)); // this rpcWorker.Append(rpcWorker.Create(OpCodes.Ldtoken, td)); rpcWorker.Append(rpcWorker.Create(OpCodes.Call, Weaver.getTypeFromHandleReference)); // invokerClass 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.sendRpcInternal)); rpcWorker.Append(rpcWorker.Create(OpCodes.Ret)); return(rpc); }
public static MethodDefinition ProcessEventCall(TypeDefinition td, EventDefinition ed, CustomAttribute syncEventAttr) { MethodReference invoke = Resolvers.ResolveMethod(ed.EventType, Weaver.CurrentAssembly, "Invoke"); MethodDefinition evt = new MethodDefinition("Call" + ed.Name, MethodAttributes.Public | MethodAttributes.HideBySig, Weaver.voidType); // add paramters foreach (ParameterDefinition pd in invoke.Parameters) { evt.Parameters.Add(new ParameterDefinition(pd.Name, ParameterAttributes.None, pd.ParameterType)); } ILProcessor evtWorker = evt.Body.GetILProcessor(); Instruction label = evtWorker.Create(OpCodes.Nop); NetworkBehaviourProcessor.WriteSetupLocals(evtWorker); NetworkBehaviourProcessor.WriteServerActiveCheck(evtWorker, ed.Name, label, "Event"); NetworkBehaviourProcessor.WriteCreateWriter(evtWorker); // write all the arguments that the user passed to the syncevent if (!NetworkBehaviourProcessor.WriteArguments(evtWorker, invoke.Resolve(), false)) { return(null); } // invoke interal send and return // this evtWorker.Append(evtWorker.Create(OpCodes.Ldarg_0)); evtWorker.Append(evtWorker.Create(OpCodes.Ldtoken, td)); // invokerClass evtWorker.Append(evtWorker.Create(OpCodes.Call, Weaver.getTypeFromHandleReference)); evtWorker.Append(evtWorker.Create(OpCodes.Ldstr, ed.Name)); // writer evtWorker.Append(evtWorker.Create(OpCodes.Ldloc_0)); evtWorker.Append(evtWorker.Create(OpCodes.Ldc_I4, syncEventAttr.GetField("channel", 0))); evtWorker.Append(evtWorker.Create(OpCodes.Call, Weaver.sendEventInternal)); NetworkBehaviourProcessor.WriteRecycleWriter(evtWorker); evtWorker.Append(evtWorker.Create(OpCodes.Ret)); return(evt); }
/* 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, typeof(class), "TargetTest", val); * } * } */ public static MethodDefinition ProcessTargetRpcCall(TypeDefinition td, 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.Ldtoken, td)); rpcWorker.Append(rpcWorker.Create(OpCodes.Call, Weaver.getTypeFromHandleReference)); // invokerClass 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); }