From f27fd0bdc570ec3ceeef433eb4991beb487d2ddb Mon Sep 17 00:00:00 2001 From: Paul Pacheco Date: Sat, 10 Aug 2019 15:08:20 -0700 Subject: [PATCH] fix: hooks in host mode can call each other (#1017) --- .../Weaver/Processors/SyncVarProcessor.cs | 9 ++++++--- Assets/Mirror/Editor/Weaver/Weaver.cs | 4 ++-- Assets/Mirror/Runtime/NetworkBehaviour.cs | 18 +++++++++++++++--- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/Assets/Mirror/Editor/Weaver/Processors/SyncVarProcessor.cs b/Assets/Mirror/Editor/Weaver/Processors/SyncVarProcessor.cs index 0738ae053..15257fcdf 100644 --- a/Assets/Mirror/Editor/Weaver/Processors/SyncVarProcessor.cs +++ b/Assets/Mirror/Editor/Weaver/Processors/SyncVarProcessor.cs @@ -114,16 +114,18 @@ public static MethodDefinition ProcessSyncVarSet(TypeDefinition td, FieldDefinit if (hookFunctionMethod != null) { - //if (NetworkServer.localClientActive && !syncVarHookGuard) + //if (NetworkServer.localClientActive && !getSyncVarHookGuard(dirtyBit)) Instruction label = setWorker.Create(OpCodes.Nop); setWorker.Append(setWorker.Create(OpCodes.Call, Weaver.NetworkServerGetLocalClientActive)); setWorker.Append(setWorker.Create(OpCodes.Brfalse, label)); setWorker.Append(setWorker.Create(OpCodes.Ldarg_0)); + setWorker.Append(setWorker.Create(OpCodes.Ldc_I8, dirtyBit)); setWorker.Append(setWorker.Create(OpCodes.Call, Weaver.getSyncVarHookGuard)); setWorker.Append(setWorker.Create(OpCodes.Brtrue, label)); - // syncVarHookGuard = true; + // setSyncVarHookGuard(dirtyBit, true); setWorker.Append(setWorker.Create(OpCodes.Ldarg_0)); + setWorker.Append(setWorker.Create(OpCodes.Ldc_I8, dirtyBit)); setWorker.Append(setWorker.Create(OpCodes.Ldc_I4_1)); setWorker.Append(setWorker.Create(OpCodes.Call, Weaver.setSyncVarHookGuard)); @@ -132,8 +134,9 @@ public static MethodDefinition ProcessSyncVarSet(TypeDefinition td, FieldDefinit setWorker.Append(setWorker.Create(OpCodes.Ldarg_1)); setWorker.Append(setWorker.Create(OpCodes.Call, hookFunctionMethod)); - // syncVarHookGuard = false; + // setSyncVarHookGuard(dirtyBit, false); setWorker.Append(setWorker.Create(OpCodes.Ldarg_0)); + setWorker.Append(setWorker.Create(OpCodes.Ldc_I8, dirtyBit)); setWorker.Append(setWorker.Create(OpCodes.Ldc_I4_0)); setWorker.Append(setWorker.Create(OpCodes.Call, Weaver.setSyncVarHookGuard)); diff --git a/Assets/Mirror/Editor/Weaver/Weaver.cs b/Assets/Mirror/Editor/Weaver/Weaver.cs index 849d48b1d..096906050 100644 --- a/Assets/Mirror/Editor/Weaver/Weaver.cs +++ b/Assets/Mirror/Editor/Weaver/Weaver.cs @@ -366,8 +366,8 @@ static void SetupTargetTypes() getBehaviourIsServer = Resolvers.ResolveMethod(NetworkBehaviourType, CurrentAssembly, "get_isServer"); setSyncVarReference = Resolvers.ResolveMethod(NetworkBehaviourType, CurrentAssembly, "SetSyncVar"); - setSyncVarHookGuard = Resolvers.ResolveMethod(NetworkBehaviourType, CurrentAssembly, "set_syncVarHookGuard"); - getSyncVarHookGuard = Resolvers.ResolveMethod(NetworkBehaviourType, CurrentAssembly, "get_syncVarHookGuard"); + setSyncVarHookGuard = Resolvers.ResolveMethod(NetworkBehaviourType, CurrentAssembly, "setSyncVarHookGuard"); + getSyncVarHookGuard = Resolvers.ResolveMethod(NetworkBehaviourType, CurrentAssembly, "getSyncVarHookGuard"); setSyncVarGameObjectReference = Resolvers.ResolveMethod(NetworkBehaviourType, CurrentAssembly, "SetSyncVarGameObject"); getSyncVarGameObjectReference = Resolvers.ResolveMethod(NetworkBehaviourType, CurrentAssembly, "GetSyncVarGameObject"); diff --git a/Assets/Mirror/Runtime/NetworkBehaviour.cs b/Assets/Mirror/Runtime/NetworkBehaviour.cs index 64c48f85e..a75549ae8 100644 --- a/Assets/Mirror/Runtime/NetworkBehaviour.cs +++ b/Assets/Mirror/Runtime/NetworkBehaviour.cs @@ -80,7 +80,19 @@ public class NetworkBehaviour : MonoBehaviour public NetworkConnection connectionToClient => netIdentity.connectionToClient; protected ulong syncVarDirtyBits { get; private set; } - protected bool syncVarHookGuard { get; set; } + private ulong syncVarHookGuard; + + protected bool getSyncVarHookGuard(ulong dirtyBit) + { + return (syncVarHookGuard & dirtyBit) != 0UL; + } + protected void setSyncVarHookGuard(ulong dirtyBit, bool value) + { + if (value) + syncVarHookGuard |= dirtyBit; + else + syncVarHookGuard &= ~dirtyBit; + } /// /// Obsolete: Use syncObjects instead. @@ -422,7 +434,7 @@ internal bool InvokeHandlerDelegate(int cmdHash, MirrorInvokeType invokeType, Ne [EditorBrowsable(EditorBrowsableState.Never)] protected void SetSyncVarGameObject(GameObject newGameObject, ref GameObject gameObjectField, ulong dirtyBit, ref uint netIdField) { - if (syncVarHookGuard) + if (getSyncVarHookGuard(dirtyBit)) return; uint newNetId = 0; @@ -471,7 +483,7 @@ protected GameObject GetSyncVarGameObject(uint netId, ref GameObject gameObjectF [EditorBrowsable(EditorBrowsableState.Never)] protected void SetSyncVarNetworkIdentity(NetworkIdentity newIdentity, ref NetworkIdentity identityField, ulong dirtyBit, ref uint netIdField) { - if (syncVarHookGuard) + if (getSyncVarHookGuard(dirtyBit)) return; uint newNetId = 0;