fix: hooks in host mode can call each other (#1017)

This commit is contained in:
Paul Pacheco 2019-08-10 15:08:20 -07:00 committed by GitHub
parent 6dd135088b
commit f27fd0bdc5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 8 deletions

View File

@ -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));

View File

@ -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");

View File

@ -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;
}
/// <summary>
/// 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;