From c8a5a22e2b3a6cd8a8a9606751987fcc59edbf14 Mon Sep 17 00:00:00 2001 From: JS Fauteux Date: Tue, 1 Jun 2021 15:23:32 -0400 Subject: [PATCH 1/7] Adding RPC Name Information through ILPP and Code Gen (MTT-802) --- .../Editor/CodeGen/NetworkBehaviourILPP.cs | 17 +++++++++++++++++ .../CodeGen/RuntimeAccessModifiersILPP.cs | 5 +++++ .../Runtime/Core/NetworkManager.cs | 3 +++ 3 files changed, 25 insertions(+) diff --git a/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs b/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs index 69b455e8b0..ceac5d328b 100644 --- a/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs +++ b/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs @@ -95,6 +95,8 @@ public override ILPostProcessResult Process(ICompiledAssembly compiledAssembly) private FieldReference m_NetworkManager_LogLevel_FieldRef; private FieldReference m_NetworkManager_ntable_FieldRef; private MethodReference m_NetworkManager_ntable_Add_MethodRef; + private FieldReference m_NetworkManager_rpc_name_table_FieldRef; + private MethodReference m_NetworkManager_rpc_name_table_Add_MethodRef; private TypeReference m_NetworkBehaviour_TypeRef; private MethodReference m_NetworkBehaviour_BeginSendServerRpc_MethodRef; private MethodReference m_NetworkBehaviour_EndSendServerRpc_MethodRef; @@ -164,6 +166,7 @@ public override ILPostProcessResult Process(ICompiledAssembly compiledAssembly) private const string k_NetworkManager_LogLevel = nameof(NetworkManager.LogLevel); #pragma warning disable 618 private const string k_NetworkManager_ntable = nameof(NetworkManager.__ntable); + private const string k_NetworkManager_rpc_name_table = nameof(NetworkManager.__rpc_name_table); private const string k_NetworkBehaviour_BeginSendServerRpc = nameof(NetworkBehaviour.__beginSendServerRpc); private const string k_NetworkBehaviour_EndSendServerRpc = nameof(NetworkBehaviour.__endSendServerRpc); @@ -235,6 +238,11 @@ private bool ImportReferences(ModuleDefinition moduleDefinition) m_NetworkManager_ntable_FieldRef = moduleDefinition.ImportReference(fieldInfo); m_NetworkManager_ntable_Add_MethodRef = moduleDefinition.ImportReference(fieldInfo.FieldType.GetMethod("Add")); break; + //IF TOOLS + case k_NetworkManager_rpc_name_table: + m_NetworkManager_rpc_name_table_FieldRef = moduleDefinition.ImportReference(fieldInfo); + m_NetworkManager_rpc_name_table_Add_MethodRef = moduleDefinition.ImportReference(fieldInfo.FieldType.GetMethod("Add")); + break; } } @@ -578,8 +586,17 @@ private void ProcessNetworkBehaviour(TypeDefinition typeDefinition) instructions.Add(processor.Create(OpCodes.Ldftn, method)); instructions.Add(processor.Create(OpCodes.Newobj, m_NetworkHandlerDelegateCtor_MethodRef)); instructions.Add(processor.Create(OpCodes.Call, m_NetworkManager_ntable_Add_MethodRef)); + + //IF TOOLS + instructions.Add(processor.Create(OpCodes.Ldsfld, m_NetworkManager_rpc_name_table_FieldRef)); + instructions.Add(processor.Create(OpCodes.Ldc_I4, unchecked((int)hash))); + //Removing __nhandler from the name of the static handler + instructions.Add(processor.Create(OpCodes.Ldstr, method.Name.Substring(0, method.Name.Length-"__nhandler".Length))); + instructions.Add(processor.Create(OpCodes.Call, m_NetworkManager_rpc_name_table_Add_MethodRef)); } + + instructions.Reverse(); instructions.ForEach(instruction => processor.Body.Instructions.Insert(0, instruction)); } diff --git a/com.unity.multiplayer.mlapi/Editor/CodeGen/RuntimeAccessModifiersILPP.cs b/com.unity.multiplayer.mlapi/Editor/CodeGen/RuntimeAccessModifiersILPP.cs index 2ba7b3a5cc..21908ca96a 100644 --- a/com.unity.multiplayer.mlapi/Editor/CodeGen/RuntimeAccessModifiersILPP.cs +++ b/com.unity.multiplayer.mlapi/Editor/CodeGen/RuntimeAccessModifiersILPP.cs @@ -89,6 +89,11 @@ private void ProcessNetworkManager(TypeDefinition typeDefinition) { fieldDefinition.IsPublic = true; } + //IF TOOLS + if (fieldDefinition.Name == nameof(NetworkManager.__rpc_name_table)) + { + fieldDefinition.IsPublic = true; + } } } diff --git a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs index 0eac75309d..c8a29f7f43 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs @@ -35,6 +35,9 @@ public class NetworkManager : MonoBehaviour, INetworkUpdateSystem, IProfilableTr #if UNITY_2020_2_OR_NEWER // RuntimeAccessModifiersILPP will make this `public` internal static readonly Dictionary> __ntable = new Dictionary>(); + // IF TOOLS + // For debug and profiling purpose only + internal static readonly Dictionary __rpc_name_table = new Dictionary(); #else [Obsolete("Please do not use, will no longer be exposed in the future versions (framework internal)")] public static readonly Dictionary> __ntable = new Dictionary>(); From f0bcc86efbde06bf9dbd3e6074646b20545e72ba Mon Sep 17 00:00:00 2001 From: JS Fauteux Date: Thu, 3 Jun 2021 11:51:23 -0400 Subject: [PATCH 2/7] Updated based on comments and feedback --- .../Editor/CodeGen/NetworkBehaviourILPP.cs | 4 +--- .../Editor/CodeGen/RuntimeAccessModifiersILPP.cs | 5 ----- com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs | 2 -- 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs b/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs index ceac5d328b..04bfa4e187 100644 --- a/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs +++ b/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs @@ -238,7 +238,6 @@ private bool ImportReferences(ModuleDefinition moduleDefinition) m_NetworkManager_ntable_FieldRef = moduleDefinition.ImportReference(fieldInfo); m_NetworkManager_ntable_Add_MethodRef = moduleDefinition.ImportReference(fieldInfo.FieldType.GetMethod("Add")); break; - //IF TOOLS case k_NetworkManager_rpc_name_table: m_NetworkManager_rpc_name_table_FieldRef = moduleDefinition.ImportReference(fieldInfo); m_NetworkManager_rpc_name_table_Add_MethodRef = moduleDefinition.ImportReference(fieldInfo.FieldType.GetMethod("Add")); @@ -587,10 +586,9 @@ private void ProcessNetworkBehaviour(TypeDefinition typeDefinition) instructions.Add(processor.Create(OpCodes.Newobj, m_NetworkHandlerDelegateCtor_MethodRef)); instructions.Add(processor.Create(OpCodes.Call, m_NetworkManager_ntable_Add_MethodRef)); - //IF TOOLS + // NetworkManager.__rpc_name_table.Add(HandlerHash, RpcNameMethod); instructions.Add(processor.Create(OpCodes.Ldsfld, m_NetworkManager_rpc_name_table_FieldRef)); instructions.Add(processor.Create(OpCodes.Ldc_I4, unchecked((int)hash))); - //Removing __nhandler from the name of the static handler instructions.Add(processor.Create(OpCodes.Ldstr, method.Name.Substring(0, method.Name.Length-"__nhandler".Length))); instructions.Add(processor.Create(OpCodes.Call, m_NetworkManager_rpc_name_table_Add_MethodRef)); } diff --git a/com.unity.multiplayer.mlapi/Editor/CodeGen/RuntimeAccessModifiersILPP.cs b/com.unity.multiplayer.mlapi/Editor/CodeGen/RuntimeAccessModifiersILPP.cs index 21908ca96a..2ba7b3a5cc 100644 --- a/com.unity.multiplayer.mlapi/Editor/CodeGen/RuntimeAccessModifiersILPP.cs +++ b/com.unity.multiplayer.mlapi/Editor/CodeGen/RuntimeAccessModifiersILPP.cs @@ -89,11 +89,6 @@ private void ProcessNetworkManager(TypeDefinition typeDefinition) { fieldDefinition.IsPublic = true; } - //IF TOOLS - if (fieldDefinition.Name == nameof(NetworkManager.__rpc_name_table)) - { - fieldDefinition.IsPublic = true; - } } } diff --git a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs index c8a29f7f43..e2e4f6db1e 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs @@ -35,8 +35,6 @@ public class NetworkManager : MonoBehaviour, INetworkUpdateSystem, IProfilableTr #if UNITY_2020_2_OR_NEWER // RuntimeAccessModifiersILPP will make this `public` internal static readonly Dictionary> __ntable = new Dictionary>(); - // IF TOOLS - // For debug and profiling purpose only internal static readonly Dictionary __rpc_name_table = new Dictionary(); #else [Obsolete("Please do not use, will no longer be exposed in the future versions (framework internal)")] From ca5029c9de327d7dbcd0e4b085bacb6e3cbf9e3b Mon Sep 17 00:00:00 2001 From: JS Fauteux Date: Thu, 3 Jun 2021 14:57:40 -0400 Subject: [PATCH 3/7] Updating comment to reflect better --- .../Editor/CodeGen/NetworkBehaviourILPP.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs b/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs index 04bfa4e187..f037328c57 100644 --- a/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs +++ b/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs @@ -586,7 +586,7 @@ private void ProcessNetworkBehaviour(TypeDefinition typeDefinition) instructions.Add(processor.Create(OpCodes.Newobj, m_NetworkHandlerDelegateCtor_MethodRef)); instructions.Add(processor.Create(OpCodes.Call, m_NetworkManager_ntable_Add_MethodRef)); - // NetworkManager.__rpc_name_table.Add(HandlerHash, RpcNameMethod); + // NetworkManager.__rpc_name_table.Add(HandlerHash, RpcMethodName); instructions.Add(processor.Create(OpCodes.Ldsfld, m_NetworkManager_rpc_name_table_FieldRef)); instructions.Add(processor.Create(OpCodes.Ldc_I4, unchecked((int)hash))); instructions.Add(processor.Create(OpCodes.Ldstr, method.Name.Substring(0, method.Name.Length-"__nhandler".Length))); From 6c65dc6d5eca442ec014e18f97b7e5c481e89276 Mon Sep 17 00:00:00 2001 From: JS Fauteux Date: Mon, 7 Jun 2021 12:33:20 -0400 Subject: [PATCH 4/7] Setup a list to avoid manipulating the string. Updated the naming around to better identify the two lists --- .../Editor/CodeGen/NetworkBehaviourILPP.cs | 23 +++++++++++-------- .../CodeGen/RuntimeAccessModifiersILPP.cs | 5 ++++ .../Runtime/Core/NetworkManager.cs | 1 + 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs b/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs index f037328c57..41c87803f2 100644 --- a/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs +++ b/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs @@ -532,7 +532,8 @@ private bool ImportReferences(ModuleDefinition moduleDefinition) private void ProcessNetworkBehaviour(TypeDefinition typeDefinition) { - var staticHandlers = new List<(uint Hash, MethodDefinition Method)>(); + var staticHandlers = new List<(uint RpcHash, MethodDefinition RpcMethod)>(); + var rpcsNameMapping = new List<(uint RpcHash, string RpcName)>(); foreach (var methodDefinition in typeDefinition.Methods) { var rpcAttribute = CheckAndGetRPCAttribute(methodDefinition); @@ -549,6 +550,7 @@ private void ProcessNetworkBehaviour(TypeDefinition typeDefinition) InjectWriteAndCallBlocks(methodDefinition, rpcAttribute, methodDefHash); staticHandlers.Add((methodDefHash, GenerateStaticHandler(methodDefinition, rpcAttribute))); + rpcsNameMapping.Add((methodDefHash, methodDefinition.Name)); } if (staticHandlers.Count > 0) @@ -569,32 +571,33 @@ private void ProcessNetworkBehaviour(TypeDefinition typeDefinition) var instructions = new List(); var processor = staticCtorMethodDef.Body.GetILProcessor(); - foreach (var (hash, method) in staticHandlers) + foreach (var (rpcHash, rpcMethod) in staticHandlers) { - if (hash == 0 || method == null) + if (rpcHash == 0 || rpcMethod == null) { continue; } - typeDefinition.Methods.Add(method); + typeDefinition.Methods.Add(rpcMethod); // NetworkManager.__ntable.Add(HandlerHash, HandlerMethod); instructions.Add(processor.Create(OpCodes.Ldsfld, m_NetworkManager_ntable_FieldRef)); - instructions.Add(processor.Create(OpCodes.Ldc_I4, unchecked((int)hash))); + instructions.Add(processor.Create(OpCodes.Ldc_I4, unchecked((int)rpcHash))); instructions.Add(processor.Create(OpCodes.Ldnull)); - instructions.Add(processor.Create(OpCodes.Ldftn, method)); + instructions.Add(processor.Create(OpCodes.Ldftn, rpcMethod)); instructions.Add(processor.Create(OpCodes.Newobj, m_NetworkHandlerDelegateCtor_MethodRef)); instructions.Add(processor.Create(OpCodes.Call, m_NetworkManager_ntable_Add_MethodRef)); + } + foreach(var (rpcHash, rpcName) in rpcsNameMapping) + { // NetworkManager.__rpc_name_table.Add(HandlerHash, RpcMethodName); instructions.Add(processor.Create(OpCodes.Ldsfld, m_NetworkManager_rpc_name_table_FieldRef)); - instructions.Add(processor.Create(OpCodes.Ldc_I4, unchecked((int)hash))); - instructions.Add(processor.Create(OpCodes.Ldstr, method.Name.Substring(0, method.Name.Length-"__nhandler".Length))); + instructions.Add(processor.Create(OpCodes.Ldc_I4, unchecked((int)rpcHash))); + instructions.Add(processor.Create(OpCodes.Ldstr, rpcName)); instructions.Add(processor.Create(OpCodes.Call, m_NetworkManager_rpc_name_table_Add_MethodRef)); } - - instructions.Reverse(); instructions.ForEach(instruction => processor.Body.Instructions.Insert(0, instruction)); } diff --git a/com.unity.multiplayer.mlapi/Editor/CodeGen/RuntimeAccessModifiersILPP.cs b/com.unity.multiplayer.mlapi/Editor/CodeGen/RuntimeAccessModifiersILPP.cs index 2ba7b3a5cc..d805309dde 100644 --- a/com.unity.multiplayer.mlapi/Editor/CodeGen/RuntimeAccessModifiersILPP.cs +++ b/com.unity.multiplayer.mlapi/Editor/CodeGen/RuntimeAccessModifiersILPP.cs @@ -89,6 +89,11 @@ private void ProcessNetworkManager(TypeDefinition typeDefinition) { fieldDefinition.IsPublic = true; } + + if (fieldDefinition.Name == nameof(NetworkManager.__rpc_name_table)) + { + fieldDefinition.IsPublic = true; + } } } diff --git a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs index e2e4f6db1e..24f7b9e8a2 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs @@ -35,6 +35,7 @@ public class NetworkManager : MonoBehaviour, INetworkUpdateSystem, IProfilableTr #if UNITY_2020_2_OR_NEWER // RuntimeAccessModifiersILPP will make this `public` internal static readonly Dictionary> __ntable = new Dictionary>(); + // RuntimeAccessModifiersILPP will make this `public` internal static readonly Dictionary __rpc_name_table = new Dictionary(); #else [Obsolete("Please do not use, will no longer be exposed in the future versions (framework internal)")] From 90c3311e3b6036db84997230a89f3ed9ac059b3c Mon Sep 17 00:00:00 2001 From: JS Fauteux Date: Mon, 7 Jun 2021 17:10:16 -0400 Subject: [PATCH 5/7] Using compiled assembly defines list instead of macros --- .../Editor/CodeGen/NetworkBehaviourILPP.cs | 38 +++++++++++++++---- .../CodeGen/RuntimeAccessModifiersILPP.cs | 12 ++++-- .../Runtime/Core/NetworkManager.cs | 8 ++++ 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs b/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs index 41c87803f2..1d22e98322 100644 --- a/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs +++ b/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs @@ -30,6 +30,8 @@ internal sealed class NetworkBehaviourILPP : ILPPInterface private readonly List m_Diagnostics = new List(); + private ICompiledAssembly m_CompiledAssembly = null; + public override ILPostProcessResult Process(ICompiledAssembly compiledAssembly) { if (!WillProcess(compiledAssembly)) @@ -51,6 +53,7 @@ public override ILPostProcessResult Process(ICompiledAssembly compiledAssembly) var mainModule = assemblyDefinition.MainModule; if (mainModule != null) { + m_CompiledAssembly = compiledAssembly; if (ImportReferences(mainModule)) { // process `NetworkBehaviour` types @@ -533,7 +536,14 @@ private bool ImportReferences(ModuleDefinition moduleDefinition) private void ProcessNetworkBehaviour(TypeDefinition typeDefinition) { var staticHandlers = new List<(uint RpcHash, MethodDefinition RpcMethod)>(); - var rpcsNameMapping = new List<(uint RpcHash, string RpcName)>(); + + bool isDebugOrInEditor = (m_CompiledAssembly.Defines.Contains("UNITY_EDITOR") || m_CompiledAssembly.Defines.Contains("DEVELOPMENT_BUILD")); + List<(uint RpcHash, string RpcName)> rpcsNameMapping = null; + if (isDebugOrInEditor) + { + rpcsNameMapping = new List<(uint RpcHash, string RpcName)>(); + } + foreach (var methodDefinition in typeDefinition.Methods) { var rpcAttribute = CheckAndGetRPCAttribute(methodDefinition); @@ -550,7 +560,10 @@ private void ProcessNetworkBehaviour(TypeDefinition typeDefinition) InjectWriteAndCallBlocks(methodDefinition, rpcAttribute, methodDefHash); staticHandlers.Add((methodDefHash, GenerateStaticHandler(methodDefinition, rpcAttribute))); - rpcsNameMapping.Add((methodDefHash, methodDefinition.Name)); + if (isDebugOrInEditor) + { + rpcsNameMapping.Add((methodDefHash, methodDefinition.Name)); + } } if (staticHandlers.Count > 0) @@ -589,15 +602,24 @@ private void ProcessNetworkBehaviour(TypeDefinition typeDefinition) instructions.Add(processor.Create(OpCodes.Call, m_NetworkManager_ntable_Add_MethodRef)); } - foreach(var (rpcHash, rpcName) in rpcsNameMapping) + if (isDebugOrInEditor) { - // NetworkManager.__rpc_name_table.Add(HandlerHash, RpcMethodName); - instructions.Add(processor.Create(OpCodes.Ldsfld, m_NetworkManager_rpc_name_table_FieldRef)); - instructions.Add(processor.Create(OpCodes.Ldc_I4, unchecked((int)rpcHash))); - instructions.Add(processor.Create(OpCodes.Ldstr, rpcName)); - instructions.Add(processor.Create(OpCodes.Call, m_NetworkManager_rpc_name_table_Add_MethodRef)); + foreach (var (rpcHash, rpcName) in rpcsNameMapping) + { + if (rpcHash == 0) + { + continue; + } + + // NetworkManager.__rpc_name_table.Add(HandlerHash, RpcMethodName); + instructions.Add(processor.Create(OpCodes.Ldsfld, m_NetworkManager_rpc_name_table_FieldRef)); + instructions.Add(processor.Create(OpCodes.Ldc_I4, unchecked((int)rpcHash))); + instructions.Add(processor.Create(OpCodes.Ldstr, rpcName)); + instructions.Add(processor.Create(OpCodes.Call, m_NetworkManager_rpc_name_table_Add_MethodRef)); + } } + instructions.Reverse(); instructions.ForEach(instruction => processor.Body.Instructions.Insert(0, instruction)); } diff --git a/com.unity.multiplayer.mlapi/Editor/CodeGen/RuntimeAccessModifiersILPP.cs b/com.unity.multiplayer.mlapi/Editor/CodeGen/RuntimeAccessModifiersILPP.cs index d805309dde..0b86b809dd 100644 --- a/com.unity.multiplayer.mlapi/Editor/CodeGen/RuntimeAccessModifiersILPP.cs +++ b/com.unity.multiplayer.mlapi/Editor/CodeGen/RuntimeAccessModifiersILPP.cs @@ -1,6 +1,7 @@ #if UNITY_2020_2_OR_NEWER using System.Collections.Generic; using System.IO; +using System.Linq; using Mono.Cecil; using Mono.Cecil.Cil; using Unity.CompilationPipeline.Common.Diagnostics; @@ -49,7 +50,7 @@ public override ILPostProcessResult Process(ICompiledAssembly compiledAssembly) switch (typeDefinition.Name) { case nameof(NetworkManager): - ProcessNetworkManager(typeDefinition); + ProcessNetworkManager(typeDefinition, compiledAssembly.Defines); break; case nameof(NetworkBehaviour): ProcessNetworkBehaviour(typeDefinition); @@ -81,7 +82,7 @@ public override ILPostProcessResult Process(ICompiledAssembly compiledAssembly) return new ILPostProcessResult(new InMemoryAssembly(pe.ToArray(), pdb.ToArray()), m_Diagnostics); } - private void ProcessNetworkManager(TypeDefinition typeDefinition) + private void ProcessNetworkManager(TypeDefinition typeDefinition, string[] assemblyDefines) { foreach (var fieldDefinition in typeDefinition.Fields) { @@ -90,9 +91,12 @@ private void ProcessNetworkManager(TypeDefinition typeDefinition) fieldDefinition.IsPublic = true; } - if (fieldDefinition.Name == nameof(NetworkManager.__rpc_name_table)) + if (assemblyDefines.Contains("UNITY_EDITOR") || assemblyDefines.Contains("DEVELOPMENT_BUILD")) { - fieldDefinition.IsPublic = true; + if (fieldDefinition.Name == nameof(NetworkManager.__rpc_name_table)) + { + fieldDefinition.IsPublic = true; + } } } } diff --git a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs index 24f7b9e8a2..687e5695d5 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs @@ -35,8 +35,16 @@ public class NetworkManager : MonoBehaviour, INetworkUpdateSystem, IProfilableTr #if UNITY_2020_2_OR_NEWER // RuntimeAccessModifiersILPP will make this `public` internal static readonly Dictionary> __ntable = new Dictionary>(); + +#if UNITY_EDITOR || DEVELOPMENT_BUILD // RuntimeAccessModifiersILPP will make this `public` internal static readonly Dictionary __rpc_name_table = new Dictionary(); +#else + // RuntimeAccessModifiersILPP will make this `public` + // The existence of this dictionary with this name is required outside of Development Build or Editor for ILPP generation + // This will never be initialized or filled here + internal static readonly Dictionary __rpc_name_table = null; +#endif #else [Obsolete("Please do not use, will no longer be exposed in the future versions (framework internal)")] public static readonly Dictionary> __ntable = new Dictionary>(); From 4e48166521013f7728f2adbd14b54544c612096f Mon Sep 17 00:00:00 2001 From: JS Fauteux Date: Tue, 8 Jun 2021 10:51:20 -0400 Subject: [PATCH 6/7] Passing defines as argument instead of storing them. Updated the comment in network manager to better reflect what is going on. --- .../Editor/CodeGen/NetworkBehaviourILPP.cs | 15 ++++++++------- .../Runtime/Core/NetworkManager.cs | 7 ++++--- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs b/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs index 1d22e98322..e3b9479041 100644 --- a/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs +++ b/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs @@ -30,7 +30,6 @@ internal sealed class NetworkBehaviourILPP : ILPPInterface private readonly List m_Diagnostics = new List(); - private ICompiledAssembly m_CompiledAssembly = null; public override ILPostProcessResult Process(ICompiledAssembly compiledAssembly) { @@ -53,14 +52,16 @@ public override ILPostProcessResult Process(ICompiledAssembly compiledAssembly) var mainModule = assemblyDefinition.MainModule; if (mainModule != null) { - m_CompiledAssembly = compiledAssembly; if (ImportReferences(mainModule)) { // process `NetworkBehaviour` types - mainModule.GetTypes() + var networkBehaviours = mainModule.GetTypes() .Where(t => t.IsSubclassOf(CodeGenHelpers.NetworkBehaviour_FullName)) - .ToList() - .ForEach(ProcessNetworkBehaviour); + .ToList(); + foreach (var networkBehaviour in networkBehaviours) + { + ProcessNetworkBehaviour(networkBehaviour, compiledAssembly.Defines); + } } else { @@ -533,11 +534,11 @@ private bool ImportReferences(ModuleDefinition moduleDefinition) return true; } - private void ProcessNetworkBehaviour(TypeDefinition typeDefinition) + private void ProcessNetworkBehaviour(TypeDefinition typeDefinition, string[] assemblyDefines) { var staticHandlers = new List<(uint RpcHash, MethodDefinition RpcMethod)>(); - bool isDebugOrInEditor = (m_CompiledAssembly.Defines.Contains("UNITY_EDITOR") || m_CompiledAssembly.Defines.Contains("DEVELOPMENT_BUILD")); + bool isDebugOrInEditor = (assemblyDefines.Contains("UNITY_EDITOR") || assemblyDefines.Contains("DEVELOPMENT_BUILD")); List<(uint RpcHash, string RpcName)> rpcsNameMapping = null; if (isDebugOrInEditor) { diff --git a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs index 567a9f7d24..86bf571ab3 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs @@ -40,9 +40,10 @@ public class NetworkManager : MonoBehaviour, INetworkUpdateSystem, IProfilableTr // RuntimeAccessModifiersILPP will make this `public` internal static readonly Dictionary __rpc_name_table = new Dictionary(); #else - // RuntimeAccessModifiersILPP will make this `public` - // The existence of this dictionary with this name is required outside of Development Build or Editor for ILPP generation - // This will never be initialized or filled here + // RuntimeAccessModifiersILPP and NetworkBehaviourILPP requires a variable with this name to exist when outside of Debug build or Editor. + // If the name doesn't exist, generation and compilation errors occurs. + // For the sake of consistency, we are using the same type. + // Final note: this variable will not be used. Since it's never initialized, it will not be in the memory footprint. internal static readonly Dictionary __rpc_name_table = null; #endif #else From ec2805533ad443799cfdc9d11feafe7ef72c4166 Mon Sep 17 00:00:00 2001 From: "M. Fatih MAR" Date: Tue, 8 Jun 2021 17:21:10 +0100 Subject: [PATCH 7/7] minor refactor --- .../Editor/CodeGen/NetworkBehaviourILPP.cs | 65 +++++++------------ .../Runtime/Core/NetworkManager.cs | 8 +-- 2 files changed, 27 insertions(+), 46 deletions(-) diff --git a/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs b/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs index e3b9479041..d7e44a3127 100644 --- a/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs +++ b/com.unity.multiplayer.mlapi/Editor/CodeGen/NetworkBehaviourILPP.cs @@ -30,7 +30,6 @@ internal sealed class NetworkBehaviourILPP : ILPPInterface private readonly List m_Diagnostics = new List(); - public override ILPostProcessResult Process(ICompiledAssembly compiledAssembly) { if (!WillProcess(compiledAssembly)) @@ -55,13 +54,10 @@ public override ILPostProcessResult Process(ICompiledAssembly compiledAssembly) if (ImportReferences(mainModule)) { // process `NetworkBehaviour` types - var networkBehaviours = mainModule.GetTypes() + mainModule.GetTypes() .Where(t => t.IsSubclassOf(CodeGenHelpers.NetworkBehaviour_FullName)) - .ToList(); - foreach (var networkBehaviour in networkBehaviours) - { - ProcessNetworkBehaviour(networkBehaviour, compiledAssembly.Defines); - } + .ToList() + .ForEach(b => ProcessNetworkBehaviour(b, compiledAssembly.Defines)); } else { @@ -536,14 +532,10 @@ private bool ImportReferences(ModuleDefinition moduleDefinition) private void ProcessNetworkBehaviour(TypeDefinition typeDefinition, string[] assemblyDefines) { - var staticHandlers = new List<(uint RpcHash, MethodDefinition RpcMethod)>(); + var rpcHandlers = new List<(uint RpcHash, MethodDefinition RpcHandler)>(); + var rpcNames = new List<(uint RpcHash, string RpcName)>(); - bool isDebugOrInEditor = (assemblyDefines.Contains("UNITY_EDITOR") || assemblyDefines.Contains("DEVELOPMENT_BUILD")); - List<(uint RpcHash, string RpcName)> rpcsNameMapping = null; - if (isDebugOrInEditor) - { - rpcsNameMapping = new List<(uint RpcHash, string RpcName)>(); - } + bool isEditorOrDevelopment = assemblyDefines.Contains("UNITY_EDITOR") || assemblyDefines.Contains("DEVELOPMENT_BUILD"); foreach (var methodDefinition in typeDefinition.Methods) { @@ -560,14 +552,16 @@ private void ProcessNetworkBehaviour(TypeDefinition typeDefinition, string[] ass } InjectWriteAndCallBlocks(methodDefinition, rpcAttribute, methodDefHash); - staticHandlers.Add((methodDefHash, GenerateStaticHandler(methodDefinition, rpcAttribute))); - if (isDebugOrInEditor) + + rpcHandlers.Add((methodDefHash, GenerateStaticHandler(methodDefinition, rpcAttribute))); + + if (isEditorOrDevelopment) { - rpcsNameMapping.Add((methodDefHash, methodDefinition.Name)); + rpcNames.Add((methodDefHash, methodDefinition.Name)); } } - if (staticHandlers.Count > 0) + if (rpcHandlers.Count > 0 || rpcNames.Count > 0) { var staticCtorMethodDef = typeDefinition.GetStaticConstructor(); if (staticCtorMethodDef == null) @@ -585,42 +579,29 @@ private void ProcessNetworkBehaviour(TypeDefinition typeDefinition, string[] ass var instructions = new List(); var processor = staticCtorMethodDef.Body.GetILProcessor(); - foreach (var (rpcHash, rpcMethod) in staticHandlers) - { - if (rpcHash == 0 || rpcMethod == null) - { - continue; - } - typeDefinition.Methods.Add(rpcMethod); + foreach (var (rpcHash, rpcHandler) in rpcHandlers) + { + typeDefinition.Methods.Add(rpcHandler); - // NetworkManager.__ntable.Add(HandlerHash, HandlerMethod); + // NetworkManager.__ntable.Add(RpcHash, HandleFunc); instructions.Add(processor.Create(OpCodes.Ldsfld, m_NetworkManager_ntable_FieldRef)); instructions.Add(processor.Create(OpCodes.Ldc_I4, unchecked((int)rpcHash))); instructions.Add(processor.Create(OpCodes.Ldnull)); - instructions.Add(processor.Create(OpCodes.Ldftn, rpcMethod)); + instructions.Add(processor.Create(OpCodes.Ldftn, rpcHandler)); instructions.Add(processor.Create(OpCodes.Newobj, m_NetworkHandlerDelegateCtor_MethodRef)); instructions.Add(processor.Create(OpCodes.Call, m_NetworkManager_ntable_Add_MethodRef)); } - if (isDebugOrInEditor) + foreach (var (rpcHash, rpcName) in rpcNames) { - foreach (var (rpcHash, rpcName) in rpcsNameMapping) - { - if (rpcHash == 0) - { - continue; - } - - // NetworkManager.__rpc_name_table.Add(HandlerHash, RpcMethodName); - instructions.Add(processor.Create(OpCodes.Ldsfld, m_NetworkManager_rpc_name_table_FieldRef)); - instructions.Add(processor.Create(OpCodes.Ldc_I4, unchecked((int)rpcHash))); - instructions.Add(processor.Create(OpCodes.Ldstr, rpcName)); - instructions.Add(processor.Create(OpCodes.Call, m_NetworkManager_rpc_name_table_Add_MethodRef)); - } + // NetworkManager.__rpc_name_table.Add(RpcHash, RpcName); + instructions.Add(processor.Create(OpCodes.Ldsfld, m_NetworkManager_rpc_name_table_FieldRef)); + instructions.Add(processor.Create(OpCodes.Ldc_I4, unchecked((int)rpcHash))); + instructions.Add(processor.Create(OpCodes.Ldstr, rpcName)); + instructions.Add(processor.Create(OpCodes.Call, m_NetworkManager_rpc_name_table_Add_MethodRef)); } - instructions.Reverse(); instructions.ForEach(instruction => processor.Body.Instructions.Insert(0, instruction)); } diff --git a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs index 86bf571ab3..37c78a3a11 100644 --- a/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs +++ b/com.unity.multiplayer.mlapi/Runtime/Core/NetworkManager.cs @@ -39,17 +39,17 @@ public class NetworkManager : MonoBehaviour, INetworkUpdateSystem, IProfilableTr #if UNITY_EDITOR || DEVELOPMENT_BUILD // RuntimeAccessModifiersILPP will make this `public` internal static readonly Dictionary __rpc_name_table = new Dictionary(); -#else +#else // !(UNITY_EDITOR || DEVELOPMENT_BUILD) // RuntimeAccessModifiersILPP and NetworkBehaviourILPP requires a variable with this name to exist when outside of Debug build or Editor. // If the name doesn't exist, generation and compilation errors occurs. // For the sake of consistency, we are using the same type. // Final note: this variable will not be used. Since it's never initialized, it will not be in the memory footprint. internal static readonly Dictionary __rpc_name_table = null; -#endif -#else +#endif // UNITY_EDITOR || DEVELOPMENT_BUILD +#else // !UNITY_2020_2_OR_NEWER [Obsolete("Please do not use, will no longer be exposed in the future versions (framework internal)")] public static readonly Dictionary> __ntable = new Dictionary>(); -#endif +#endif // UNITY_2020_2_OR_NEWER #pragma warning restore IDE1006 // restore naming rule violation check #if DEVELOPMENT_BUILD || UNITY_EDITOR