diff --git a/Assets/Mirage/Runtime/RemoteCalls/ClientRpcSender.cs b/Assets/Mirage/Runtime/RemoteCalls/ClientRpcSender.cs index f61bae556e..5d159742b0 100644 --- a/Assets/Mirage/Runtime/RemoteCalls/ClientRpcSender.cs +++ b/Assets/Mirage/Runtime/RemoteCalls/ClientRpcSender.cs @@ -101,7 +101,7 @@ private static void Validate(NetworkBehaviour behaviour, int index) /// <param name="target"></param> /// <param name="player">player used for RpcTarget.Player</param> /// <returns></returns> - public static bool ShouldInvokeLocally(NetworkBehaviour behaviour, RpcTarget target, INetworkPlayer player) + public static bool ShouldInvokeLocally(NetworkBehaviour behaviour, RpcTarget target, INetworkPlayer player, bool excludeOwner) { // not server? error if (!behaviour.IsServer) @@ -117,7 +117,7 @@ public static bool ShouldInvokeLocally(NetworkBehaviour behaviour, RpcTarget tar switch (target) { case RpcTarget.Observers: - return IsLocalPlayerObserver(behaviour); + return IsLocalPlayerObserver(behaviour, excludeOwner); case RpcTarget.Owner: return IsLocalPlayerTarget(behaviour, behaviour.Owner); case RpcTarget.Player: @@ -134,9 +134,14 @@ public static bool ShouldInvokeLocally(NetworkBehaviour behaviour, RpcTarget tar /// </summary> /// <param name="player"></param> /// <returns></returns> - public static bool IsLocalPlayerObserver(NetworkBehaviour behaviour) + public static bool IsLocalPlayerObserver(NetworkBehaviour behaviour, bool excludeOwner) { var local = behaviour.Server.LocalPlayer; + + // if local player is the owner, skip + if (excludeOwner && behaviour.Owner == local) + return false; + return behaviour.Identity.observers.Contains(local); } diff --git a/Assets/Mirage/Weaver/Processors/ClientRpcProcessor.cs b/Assets/Mirage/Weaver/Processors/ClientRpcProcessor.cs index 93875c5b84..f53f6c4006 100644 --- a/Assets/Mirage/Weaver/Processors/ClientRpcProcessor.cs +++ b/Assets/Mirage/Weaver/Processors/ClientRpcProcessor.cs @@ -89,7 +89,7 @@ private MethodDefinition GenerateStub(MethodDefinition md, CustomAttribute clien // { // call the body // } - CallBody(worker, rpc, target); + CallBody(worker, rpc, target, excludeOwner); // NetworkWriter writer = NetworkWriterPool.GetWriter() var writer = md.AddLocal<PooledNetworkWriter>(); @@ -154,7 +154,7 @@ private static MethodReference GetSendMethod(MethodDefinition md, RpcTarget targ - private void InvokeLocally(ILProcessor worker, RpcTarget target, Action body) + private void InvokeLocally(ILProcessor worker, RpcTarget target, bool excludeOwner, Action body) { // if (IsLocalClient) { var endif = worker.Create(OpCodes.Nop); @@ -170,8 +170,9 @@ private void InvokeLocally(ILProcessor worker, RpcTarget target, Action body) else worker.Append(worker.Create(OpCodes.Ldnull)); + worker.Append(worker.Create(excludeOwner.OpCode_Ldc())); // call function - worker.Append(worker.Create(OpCodes.Call, () => ClientRpcSender.ShouldInvokeLocally(default, default, default))); + worker.Append(worker.Create(OpCodes.Call, () => ClientRpcSender.ShouldInvokeLocally(default, default, default, default))); worker.Append(worker.Create(OpCodes.Brfalse, endif)); body(); @@ -181,9 +182,9 @@ private void InvokeLocally(ILProcessor worker, RpcTarget target, Action body) } - private void CallBody(ILProcessor worker, MethodDefinition rpc, RpcTarget target) + private void CallBody(ILProcessor worker, MethodDefinition rpc, RpcTarget target, bool excludeOwner) { - InvokeLocally(worker, target, () => + InvokeLocally(worker, target, excludeOwner, () => { InvokeBody(worker, rpc); // if target is owner or player we can return after invoking locally