コード例 #1
0
        public static MethodDefinition ProcessRpcInvoke(TypeDefinition td, MethodDefinition md, MethodDefinition rpcCallFunc)
        {
            var rpc = new MethodDefinition(
                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, "RPC");

            // setup for reader
            rpcWorker.Append(rpcWorker.Create(OpCodes.Ldarg_0));
            rpcWorker.Append(rpcWorker.Create(OpCodes.Castclass, td));

            if (!NetworkBehaviourProcessor.ProcessNetworkReaderParameters(md, rpcWorker, false))
            {
                return(null);
            }

            // invoke actual command function
            rpcWorker.Append(rpcWorker.Create(OpCodes.Callvirt, rpcCallFunc));
            rpcWorker.Append(rpcWorker.Create(OpCodes.Ret));

            NetworkBehaviourProcessor.AddInvokeParameters(rpc.Parameters);
            td.Methods.Add(rpc);
            return(rpc);
        }
コード例 #2
0
        /*
         *  // 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);
        }
コード例 #3
0
        public static MethodDefinition ProcessRpcInvoke(WeaverTypes weaverTypes, Writers writers, Readers readers, Logger Log, TypeDefinition td, MethodDefinition md, MethodDefinition rpcCallFunc, ref bool WeavingFailed)
        {
            string rpcName = Weaver.GenerateMethodName(Weaver.InvokeRpcPrefix, md);

            MethodDefinition rpc = new MethodDefinition(rpcName, MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig,
                                                        weaverTypes.Import(typeof(void)));

            ILProcessor worker = rpc.Body.GetILProcessor();
            Instruction label  = worker.Create(OpCodes.Nop);

            NetworkBehaviourProcessor.WriteClientActiveCheck(worker, weaverTypes, md.Name, label, "RPC");

            // setup for reader
            worker.Emit(OpCodes.Ldarg_0);
            worker.Emit(OpCodes.Castclass, td);

            if (!NetworkBehaviourProcessor.ReadArguments(md, readers, Log, worker, RemoteCallType.ClientRpc, ref WeavingFailed))
            {
                return(null);
            }

            // invoke actual command function
            worker.Emit(OpCodes.Callvirt, rpcCallFunc);
            worker.Emit(OpCodes.Ret);

            NetworkBehaviourProcessor.AddInvokeParameters(weaverTypes, rpc.Parameters);
            td.Methods.Add(rpc);
            return(rpc);
        }
コード例 #4
0
        public static MethodDefinition ProcessRpcInvoke(TypeDefinition td, MethodDefinition md, MethodDefinition rpcCallFunc)
        {
            MethodDefinition rpc = new MethodDefinition(
                Weaver.InvokeRpcPrefix + md.Name,
                MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig,
                WeaverTypes.Import(typeof(void)));

            ILProcessor worker = rpc.Body.GetILProcessor();
            Instruction label  = worker.Create(OpCodes.Nop);

            NetworkBehaviourProcessor.WriteClientActiveCheck(worker, md.Name, label, "RPC");

            // setup for reader
            worker.Append(worker.Create(OpCodes.Ldarg_0));
            worker.Append(worker.Create(OpCodes.Castclass, td));

            if (!NetworkBehaviourProcessor.ReadArguments(md, worker, RemoteCallType.ClientRpc))
            {
                return(null);
            }

            // invoke actual command function
            worker.Append(worker.Create(OpCodes.Callvirt, rpcCallFunc));
            worker.Append(worker.Create(OpCodes.Ret));

            NetworkBehaviourProcessor.AddInvokeParameters(rpc.Parameters);
            td.Methods.Add(rpc);
            return(rpc);
        }
コード例 #5
0
        /*
         *  // 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);
        }
コード例 #6
0
        public static MethodDefinition ProcessEventInvoke(TypeDefinition td, EventDefinition ed)
        {
            // find the field that matches the event
            FieldDefinition eventField = null;

            foreach (FieldDefinition fd in td.Fields)
            {
                if (fd.FullName == ed.FullName)
                {
                    eventField = fd;
                    break;
                }
            }
            if (eventField == null)
            {
                Weaver.DLog(td, "ERROR: no event field?!");
                Weaver.fail = true;
                return(null);
            }

            MethodDefinition cmd = new MethodDefinition("InvokeSyncEvent" + ed.Name, MethodAttributes.Family |
                                                        MethodAttributes.Static |
                                                        MethodAttributes.HideBySig,
                                                        Weaver.voidType);

            ILProcessor cmdWorker = cmd.Body.GetILProcessor();
            Instruction label1    = cmdWorker.Create(OpCodes.Nop);
            Instruction label2    = cmdWorker.Create(OpCodes.Nop);

            NetworkBehaviourProcessor.WriteClientActiveCheck(cmdWorker, ed.Name, label1, "Event");

            // null event check
            cmdWorker.Append(cmdWorker.Create(OpCodes.Ldarg_0));
            cmdWorker.Append(cmdWorker.Create(OpCodes.Castclass, td));
            cmdWorker.Append(cmdWorker.Create(OpCodes.Ldfld, eventField));
            cmdWorker.Append(cmdWorker.Create(OpCodes.Brtrue, label2));
            cmdWorker.Append(cmdWorker.Create(OpCodes.Ret));
            cmdWorker.Append(label2);

            // setup reader
            cmdWorker.Append(cmdWorker.Create(OpCodes.Ldarg_0));
            cmdWorker.Append(cmdWorker.Create(OpCodes.Castclass, td));
            cmdWorker.Append(cmdWorker.Create(OpCodes.Ldfld, eventField));

            // read the event arguments
            MethodReference invoke = Resolvers.ResolveMethod(eventField.FieldType, Weaver.scriptDef, "Invoke");

            if (!NetworkBehaviourProcessor.ProcessNetworkReaderParameters(td, invoke.Resolve(), cmdWorker, false))
            {
                return(null);
            }

            // invoke actual event delegate function
            cmdWorker.Append(cmdWorker.Create(OpCodes.Callvirt, invoke));
            cmdWorker.Append(cmdWorker.Create(OpCodes.Ret));

            NetworkBehaviourProcessor.AddInvokeParameters(cmd.Parameters);

            return(cmd);
        }
コード例 #7
0
        public static MethodDefinition ProcessEventInvoke(TypeDefinition td, EventDefinition ed)
        {
            // find the field that matches the event
            FieldDefinition eventField = null;

            foreach (var fd in td.Fields)
            {
                if (fd.FullName == ed.FullName)
                {
                    eventField = fd;
                    break;
                }
            }

            if (eventField == null)
            {
                Weaver.Error($"{td} not found. Did you declare the event?");
                return(null);
            }

            var cmd = new MethodDefinition("InvokeSyncEvent" + ed.Name, MethodAttributes.Family |
                                           MethodAttributes.Static |
                                           MethodAttributes.HideBySig,
                                           Weaver.voidType);

            var cmdWorker = cmd.Body.GetILProcessor();
            var label1    = cmdWorker.Create(OpCodes.Nop);
            var label2    = cmdWorker.Create(OpCodes.Nop);

            NetworkBehaviourProcessor.WriteClientActiveCheck(cmdWorker, ed.Name, label1, "Event");

            // null event check
            cmdWorker.Append(cmdWorker.Create(OpCodes.Ldarg_0));
            cmdWorker.Append(cmdWorker.Create(OpCodes.Castclass, td));
            cmdWorker.Append(cmdWorker.Create(OpCodes.Ldfld, eventField));
            cmdWorker.Append(cmdWorker.Create(OpCodes.Brtrue, label2));
            cmdWorker.Append(cmdWorker.Create(OpCodes.Ret));
            cmdWorker.Append(label2);

            // setup reader
            cmdWorker.Append(cmdWorker.Create(OpCodes.Ldarg_0));
            cmdWorker.Append(cmdWorker.Create(OpCodes.Castclass, td));
            cmdWorker.Append(cmdWorker.Create(OpCodes.Ldfld, eventField));

            // read the event arguments
            var invoke = Resolvers.ResolveMethod(eventField.FieldType, Weaver.CurrentAssembly, "Invoke");

            if (!NetworkBehaviourProcessor.ProcessNetworkReaderParameters(invoke.Resolve(), cmdWorker, false))
            {
                return(null);
            }

            // invoke actual event delegate function
            cmdWorker.Append(cmdWorker.Create(OpCodes.Callvirt, invoke));
            cmdWorker.Append(cmdWorker.Create(OpCodes.Ret));

            NetworkBehaviourProcessor.AddInvokeParameters(cmd.Parameters);

            return(cmd);
        }
コード例 #8
0
        /// <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);
        }
コード例 #9
0
        public static MethodDefinition ProcessEventInvoke(TypeDefinition td, EventDefinition ed)
        {
            // find the field that matches the event
            FieldDefinition eventField = null;

            foreach (FieldDefinition fd in td.Fields)
            {
                if (fd.FullName == ed.FullName)
                {
                    eventField = fd;
                    break;
                }
            }
            if (eventField == null)
            {
                Weaver.Error($"event field not found for {ed.Name}. Did you declare it as an event?", ed);
                return(null);
            }

            MethodDefinition cmd = new MethodDefinition(Weaver.InvokeRpcPrefix + ed.Name, MethodAttributes.Family |
                                                        MethodAttributes.Static |
                                                        MethodAttributes.HideBySig,
                                                        Weaver.voidType);

            ILProcessor worker = cmd.Body.GetILProcessor();
            Instruction label1 = worker.Create(OpCodes.Nop);
            Instruction label2 = worker.Create(OpCodes.Nop);

            NetworkBehaviourProcessor.WriteClientActiveCheck(worker, ed.Name, label1, "Event");

            // null event check
            worker.Append(worker.Create(OpCodes.Ldarg_0));
            worker.Append(worker.Create(OpCodes.Castclass, td));
            worker.Append(worker.Create(OpCodes.Ldfld, eventField));
            worker.Append(worker.Create(OpCodes.Brtrue, label2));
            worker.Append(worker.Create(OpCodes.Ret));
            worker.Append(label2);

            // setup reader
            worker.Append(worker.Create(OpCodes.Ldarg_0));
            worker.Append(worker.Create(OpCodes.Castclass, td));
            worker.Append(worker.Create(OpCodes.Ldfld, eventField));

            // read the event arguments
            MethodReference invoke = Resolvers.ResolveMethod(eventField.FieldType, Weaver.CurrentAssembly, "Invoke");

            if (!NetworkBehaviourProcessor.ReadArguments(invoke.Resolve(), worker, RemoteCallType.SyncEvent))
            {
                return(null);
            }

            // invoke actual event delegate function
            worker.Append(worker.Create(OpCodes.Callvirt, invoke));
            worker.Append(worker.Create(OpCodes.Ret));

            NetworkBehaviourProcessor.AddInvokeParameters(cmd.Parameters);

            return(cmd);
        }
コード例 #10
0
ファイル: TargetRpcProcessor.cs プロジェクト: zabszk/Mirror
        public static MethodDefinition ProcessTargetRpcInvoke(WeaverTypes weaverTypes, Readers readers, Logger Log, TypeDefinition td, MethodDefinition md, MethodDefinition rpcCallFunc, ref bool WeavingFailed)
        {
            string trgName = Weaver.GenerateMethodName(Weaver.InvokeRpcPrefix, md);

            MethodDefinition rpc = new MethodDefinition(trgName, MethodAttributes.Family |
                                                        MethodAttributes.Static |
                                                        MethodAttributes.HideBySig,
                                                        weaverTypes.Import(typeof(void)));

            ILProcessor worker = rpc.Body.GetILProcessor();
            Instruction label  = worker.Create(OpCodes.Nop);

            NetworkBehaviourProcessor.WriteClientActiveCheck(worker, weaverTypes, md.Name, label, "TargetRPC");

            // setup for reader
            worker.Emit(OpCodes.Ldarg_0);
            worker.Emit(OpCodes.Castclass, td);

            // NetworkConnection parameter is optional
            if (HasNetworkConnectionParameter(md))
            {
                // on server, the NetworkConnection parameter is a connection to client.
                // when the rpc is invoked on the client, it still has the same
                // function signature. we pass in the connection to server,
                // which is cleaner than just passing null)
                //NetworkClient.readyconnection
                //
                // TODO
                // a) .connectionToServer = best solution. no doubt.
                // b) NetworkClient.connection for now. add TODO to not use static later.
                worker.Emit(OpCodes.Call, weaverTypes.NetworkClientConnectionReference);
            }

            // process reader parameters and skip first one if first one is NetworkConnection
            if (!NetworkBehaviourProcessor.ReadArguments(md, readers, Log, worker, RemoteCallType.TargetRpc, ref WeavingFailed))
            {
                return(null);
            }

            // invoke actual command function
            worker.Emit(OpCodes.Callvirt, rpcCallFunc);
            worker.Emit(OpCodes.Ret);

            NetworkBehaviourProcessor.AddInvokeParameters(weaverTypes, rpc.Parameters);
            td.Methods.Add(rpc);
            return(rpc);
        }
コード例 #11
0
        public static MethodDefinition ProcessTargetRpcInvoke(TypeDefinition td, MethodDefinition md, MethodDefinition rpcCallFunc)
        {
            var rpc = new MethodDefinition(RpcProcessor.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));

            // NetworkConnection parameter is optional
            bool hasNetworkConnection = HasNetworkConnectionParameter(md);

            if (hasNetworkConnection)
            {
                //client.connection
                rpcWorker.Append(rpcWorker.Create(OpCodes.Ldarg_0));
                rpcWorker.Append(rpcWorker.Create(OpCodes.Call, Weaver.BehaviorConnectionToServerReference));
            }

            // process reader parameters and skip first one if first one is NetworkConnection
            if (!NetworkBehaviourProcessor.ProcessNetworkReaderParameters(md, rpcWorker, hasNetworkConnection))
            {
                return(null);
            }

            // invoke actual command function
            rpcWorker.Append(rpcWorker.Create(OpCodes.Callvirt, rpcCallFunc));
            rpcWorker.Append(rpcWorker.Create(OpCodes.Ret));

            NetworkBehaviourProcessor.AddInvokeParameters(rpc.Parameters);
            td.Methods.Add(rpc);
            return(rpc);
        }
コード例 #12
0
ファイル: RpcProcessor.cs プロジェクト: skymeson/MirrorNG
        /// <summary>
        /// Generates a skeleton for an RPC
        /// </summary>
        /// <param name="td"></param>
        /// <param name="method"></param>
        /// <param name="cmdCallFunc"></param>
        /// <returns>The newly created skeleton method</returns>
        /// <remarks>
        /// Generates code like this:
        /// <code>
        /// protected static void Skeleton_Test(NetworkBehaviour obj, NetworkReader reader, NetworkConnection senderConnection)
        /// {
        ///     if (!obj.netIdentity.server.active)
        ///     {
        ///         return;
        ///     }
        ///     ((ShipControl) obj).UserCode_Test(reader.ReadSingle(), (int) reader.ReadPackedUInt32());
        /// }
        /// </code>
        /// </remarks>
        public static MethodDefinition GenerateSkeleton(MethodDefinition md, MethodDefinition userCodeFunc, CustomAttribute clientRpcAttr)
        {
            var rpc = new MethodDefinition(
                MethodProcessor.SkeletonPrefix + md.Name,
                MethodAttributes.Family | MethodAttributes.Static | MethodAttributes.HideBySig,
                WeaverTypes.Import(typeof(void)));

            ILProcessor worker = rpc.Body.GetILProcessor();
            Instruction label  = worker.Create(OpCodes.Nop);

            NetworkBehaviourProcessor.WriteClientActiveCheck(worker, md.Name, label, "RPC");

            // setup for reader
            worker.Append(worker.Create(OpCodes.Ldarg_0));
            worker.Append(worker.Create(OpCodes.Castclass, md.DeclaringType));

            // NetworkConnection parameter is only required for Client.Connection
            Client target = clientRpcAttr.GetField("target", Client.Observers);
            bool   hasNetworkConnection = target == Client.Connection && HasNetworkConnectionParameter(md);

            if (hasNetworkConnection)
            {
                //client.connection
                worker.Append(worker.Create(OpCodes.Ldarg_0));
                worker.Append(worker.Create(OpCodes.Call, WeaverTypes.BehaviorConnectionToServerReference));
            }

            if (!NetworkBehaviourProcessor.ReadArguments(md, worker, hasNetworkConnection))
            {
                return(null);
            }

            // invoke actual ServerRpc function
            worker.Append(worker.Create(OpCodes.Callvirt, userCodeFunc));
            worker.Append(worker.Create(OpCodes.Ret));

            NetworkBehaviourProcessor.AddInvokeParameters(rpc.Parameters);
            md.DeclaringType.Methods.Add(rpc);
            return(rpc);
        }
コード例 #13
0
        public static MethodDefinition ProcessTargetRpcInvoke(TypeDefinition td, MethodDefinition md, MethodDefinition rpcCallFunc)
        {
            MethodDefinition rpc = new MethodDefinition(Weaver.InvokeRpcPrefix + md.Name, MethodAttributes.Family |
                                                        MethodAttributes.Static |
                                                        MethodAttributes.HideBySig,
                                                        WeaverTypes.voidType);

            ILProcessor worker = rpc.Body.GetILProcessor();
            Instruction label  = worker.Create(OpCodes.Nop);

            NetworkBehaviourProcessor.WriteClientActiveCheck(worker, md.Name, label, "TargetRPC");

            // setup for reader
            worker.Append(worker.Create(OpCodes.Ldarg_0));
            worker.Append(worker.Create(OpCodes.Castclass, td));

            // NetworkConnection parameter is optional
            if (HasNetworkConnectionParameter(md))
            {
                // if call has NetworkConnection write clients connection as first arg
                //ClientScene.readyconnection
                worker.Append(worker.Create(OpCodes.Call, WeaverTypes.ReadyConnectionReference));
            }

            // process reader parameters and skip first one if first one is NetworkConnection
            if (!NetworkBehaviourProcessor.ReadArguments(md, worker, RemoteCallType.TargetRpc))
            {
                return(null);
            }

            // invoke actual command function
            worker.Append(worker.Create(OpCodes.Callvirt, rpcCallFunc));
            worker.Append(worker.Create(OpCodes.Ret));

            NetworkBehaviourProcessor.AddInvokeParameters(rpc.Parameters);
            td.Methods.Add(rpc);
            return(rpc);
        }