From 9184d56eec17d1ecfa205bed02ac8af8284500d7 Mon Sep 17 00:00:00 2001 From: MrGadget <9826063+MrGadget1024@users.noreply.github.com> Date: Wed, 20 Oct 2021 22:43:12 -0400 Subject: [PATCH] Fix ReplacePlayerForConn isLocalPlayer (#2969) - Moved `ChangeOwner` down below `OnChangeOwner` - Added `isLocalPlayer` bool to `ChangeOwnerMessage` - Added handling for `isLocalPlayer to `ChangeOwner` - Added call to `SendChangeOwnerMessage` to `ReplacePlayerForConnection` for when `keepAuthority` is true - Fixes #2968 --- Assets/Mirror/Runtime/Messages.cs | 1 + Assets/Mirror/Runtime/NetworkClient.cs | 24 ++++++++++++++++++------ Assets/Mirror/Runtime/NetworkServer.cs | 14 ++++++++++++-- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/Assets/Mirror/Runtime/Messages.cs b/Assets/Mirror/Runtime/Messages.cs index 71ac5ddeb..d3816f8ac 100644 --- a/Assets/Mirror/Runtime/Messages.cs +++ b/Assets/Mirror/Runtime/Messages.cs @@ -69,6 +69,7 @@ public struct ChangeOwnerMessage : NetworkMessage { public uint netId; public bool isOwner; + public bool isLocalPlayer; } public struct ObjectSpawnStartedMessage : NetworkMessage {} diff --git a/Assets/Mirror/Runtime/NetworkClient.cs b/Assets/Mirror/Runtime/NetworkClient.cs index 56fa46e05..bdc50c7f4 100644 --- a/Assets/Mirror/Runtime/NetworkClient.cs +++ b/Assets/Mirror/Runtime/NetworkClient.cs @@ -1020,12 +1020,6 @@ internal static void ApplySpawnPayload(NetworkIdentity identity, SpawnMessage me } } - internal static void ChangeOwner(NetworkIdentity identity, ChangeOwnerMessage message) - { - identity.hasAuthority = message.isOwner; - identity.NotifyAuthority(); - } - // Finds Existing Object with NetId or spawns a new one using AssetId or sceneId internal static bool FindOrSpawnObject(SpawnMessage message, out NetworkIdentity identity) { @@ -1286,6 +1280,24 @@ internal static void OnChangeOwner(ChangeOwnerMessage message) Debug.LogError($"OnChangeOwner: Could not find object with netId {message.netId}"); } + internal static void ChangeOwner(NetworkIdentity identity, ChangeOwnerMessage message) + { + identity.hasAuthority = message.isOwner; + identity.NotifyAuthority(); + + identity.isLocalPlayer = message.isLocalPlayer; + if (identity.isLocalPlayer) + localPlayer = identity; + else if (localPlayer == identity) + { + // localPlayer may already be assigned to something else + // so only make it null if it's this identity. + localPlayer = null; + } + + CheckForLocalPlayer(identity); + } + internal static void CheckForLocalPlayer(NetworkIdentity identity) { if (identity == localPlayer) diff --git a/Assets/Mirror/Runtime/NetworkServer.cs b/Assets/Mirror/Runtime/NetworkServer.cs index d2b7e320b..bd988b7c6 100644 --- a/Assets/Mirror/Runtime/NetworkServer.cs +++ b/Assets/Mirror/Runtime/NetworkServer.cs @@ -762,7 +762,12 @@ public static bool ReplacePlayerForConnection(NetworkConnection conn, GameObject Respawn(identity); - if (!keepAuthority) + if (keepAuthority) + // This needs to be sent to clear isLocalPlayer on + // client while keeping hasAuthority true + SendChangeOwnerMessage(previousPlayer, conn); + else + // This clears both isLocalPlayer and hasAuthority on client previousPlayer.RemoveClientAuthority(); return true; @@ -955,7 +960,12 @@ internal static void SendChangeOwnerMessage(NetworkIdentity identity, NetworkCon //Debug.Log($"Server SendChangeOwnerMessage: name={identity.name} netid={identity.netId}"); - conn.Send(new ChangeOwnerMessage { netId = identity.netId, isOwner = identity.connectionToClient == conn }); + conn.Send(new ChangeOwnerMessage + { + netId = identity.netId, + isOwner = identity.connectionToClient == conn, + isLocalPlayer = conn.identity == identity + }); } static void SpawnObject(GameObject obj, NetworkConnection ownerConnection)