diff --git a/Assets/Mirror/Editor/Weaver/Helpers.cs b/Assets/Mirror/Editor/Weaver/Helpers.cs index 81d01ca09..f214b89b9 100644 --- a/Assets/Mirror/Editor/Weaver/Helpers.cs +++ b/Assets/Mirror/Editor/Weaver/Helpers.cs @@ -87,7 +87,7 @@ public static string PrettyPrintType(TypeReference type) public static ReaderParameters ReaderParameters(string assemblyPath, IEnumerable extraPaths, IAssemblyResolver assemblyResolver, string unityEngineDLLPath, string mirrorNetDLLPath) { - ReaderParameters parameters = new ReaderParameters(); + ReaderParameters parameters = new ReaderParameters() {ReadWrite = true}; if (assemblyResolver == null) assemblyResolver = new DefaultAssemblyResolver(); AddSearchDirectoryHelper helper = new AddSearchDirectoryHelper(assemblyResolver); diff --git a/Assets/Mirror/Editor/Weaver/Processors/TargetRpcProcessor.cs b/Assets/Mirror/Editor/Weaver/Processors/TargetRpcProcessor.cs index 9257482d3..56a9fd9eb 100644 --- a/Assets/Mirror/Editor/Weaver/Processors/TargetRpcProcessor.cs +++ b/Assets/Mirror/Editor/Weaver/Processors/TargetRpcProcessor.cs @@ -8,6 +8,13 @@ public static class TargetRpcProcessor { const string k_TargetRpcPrefix = "InvokeTargetRpc"; + // helper functions to check if the method has a NetworkConnection parameter + public static bool HasNetworkConnectionParameter(MethodDefinition md) + { + return md.Parameters.Count > 0 && + md.Parameters[0].ParameterType.FullName == Weaver.NetworkConnectionType.FullName; + } + public static MethodDefinition ProcessTargetRpcInvoke(TypeDefinition td, MethodDefinition md) { MethodDefinition rpc = new MethodDefinition(RpcProcessor.k_RpcPrefix + md.Name, MethodAttributes.Family | @@ -24,10 +31,16 @@ public static MethodDefinition ProcessTargetRpcInvoke(TypeDefinition td, MethodD rpcWorker.Append(rpcWorker.Create(OpCodes.Ldarg_0)); rpcWorker.Append(rpcWorker.Create(OpCodes.Castclass, td)); - //ClientScene.readyconnection - rpcWorker.Append(rpcWorker.Create(OpCodes.Call, Weaver.ReadyConnectionReference)); + // NetworkConnection parameter is optional + bool hasNetworkConnection = HasNetworkConnectionParameter(md); + if (hasNetworkConnection) + { + //ClientScene.readyconnection + rpcWorker.Append(rpcWorker.Create(OpCodes.Call, Weaver.ReadyConnectionReference)); + } - if (!NetworkBehaviourProcessor.ProcessNetworkReaderParameters(td, md, rpcWorker, true)) + // process reader parameters and skip first one if first one is NetworkConnection + if (!NetworkBehaviourProcessor.ProcessNetworkReaderParameters(td, md, rpcWorker, hasNetworkConnection)) return null; // invoke actual command function @@ -46,6 +59,14 @@ public void CallTargetTest (NetworkConnection conn, int param) writer.WritePackedUInt32 ((uint)param); base.SendTargetRPCInternal (conn, typeof(class), "TargetTest", val); } + + or if optional: + public void CallTargetTest (int param) + { + NetworkWriter writer = new NetworkWriter (); + writer.WritePackedUInt32 ((uint)param); + base.SendTargetRPCInternal (null, typeof(class), "TargetTest", val); + } */ public static MethodDefinition ProcessTargetRpcCall(TypeDefinition td, MethodDefinition md, CustomAttribute ca) { @@ -53,7 +74,7 @@ public static MethodDefinition ProcessTargetRpcCall(TypeDefinition td, MethodDef MethodAttributes.HideBySig, Weaver.voidType); - // add paramters + // add parameters foreach (ParameterDefinition pd in md.Parameters) { rpc.Parameters.Add(new ParameterDefinition(pd.Name, ParameterAttributes.None, pd.ParameterType)); @@ -65,8 +86,12 @@ public static MethodDefinition ProcessTargetRpcCall(TypeDefinition td, MethodDef NetworkBehaviourProcessor.WriteCreateWriter(rpcWorker); + // NetworkConnection parameter is optional + bool hasNetworkConnection = HasNetworkConnectionParameter(md); + // write all the arguments that the user passed to the TargetRpc call - if (!NetworkBehaviourProcessor.WriteArguments(rpcWorker, md, "TargetRPC", true)) + // (skip first one if first one is NetworkConnection) + if (!NetworkBehaviourProcessor.WriteArguments(rpcWorker, md, "TargetRPC", hasNetworkConnection)) return null; var rpcName = md.Name; @@ -78,7 +103,14 @@ public static MethodDefinition ProcessTargetRpcCall(TypeDefinition td, MethodDef // invoke SendInternal and return rpcWorker.Append(rpcWorker.Create(OpCodes.Ldarg_0)); // this - rpcWorker.Append(rpcWorker.Create(OpCodes.Ldarg_1)); // connection + if (HasNetworkConnectionParameter(md)) + { + rpcWorker.Append(rpcWorker.Create(OpCodes.Ldarg_1)); // connection + } + else + { + rpcWorker.Append(rpcWorker.Create(OpCodes.Ldnull)); // null + } rpcWorker.Append(rpcWorker.Create(OpCodes.Ldtoken, td)); rpcWorker.Append(rpcWorker.Create(OpCodes.Call, Weaver.getTypeFromHandleReference)); // invokerClass rpcWorker.Append(rpcWorker.Create(OpCodes.Ldstr, rpcName)); @@ -113,18 +145,6 @@ public static bool ProcessMethodsValidateTargetRpc(TypeDefinition td, MethodDefi return false; } - if (md.Parameters.Count < 1) - { - Weaver.Error("Target Rpc function [" + td.FullName + ":" + md.Name + "] must have a NetworkConnection as the first parameter"); - return false; - } - - if (md.Parameters[0].ParameterType.FullName != Weaver.NetworkConnectionType.FullName) - { - Weaver.Error("Target Rpc function [" + td.FullName + ":" + md.Name + "] first parameter must be a NetworkConnection"); - return false; - } - // validate return NetworkBehaviourProcessor.ProcessMethodsValidateParameters(td, md, ca, "Target Rpc"); } diff --git a/Assets/Mirror/Runtime/NetworkBehaviour.cs b/Assets/Mirror/Runtime/NetworkBehaviour.cs index 9ec8099c2..9f3d32d75 100644 --- a/Assets/Mirror/Runtime/NetworkBehaviour.cs +++ b/Assets/Mirror/Runtime/NetworkBehaviour.cs @@ -151,6 +151,11 @@ protected void SendTargetRPCInternal(NetworkConnection conn, Type invokeClass, s Debug.LogError("TargetRPC Function " + rpcName + " called on client."); return; } + // connection parameter is optional. assign if null. + if (conn == null) + { + conn = connectionToClient; + } // this was in Weaver before if (conn is ULocalConnectionToServer) {