diff --git a/Source/Engine/Networking/NetworkReplicator.cpp b/Source/Engine/Networking/NetworkReplicator.cpp index d20f31b0b..b66f8d4cd 100644 --- a/Source/Engine/Networking/NetworkReplicator.cpp +++ b/Source/Engine/Networking/NetworkReplicator.cpp @@ -861,7 +861,7 @@ void NetworkReplicator::DespawnObject(ScriptingObject* obj) DeleteNetworkObject(obj); } -uint32 NetworkReplicator::GetObjectOwnerClientId(ScriptingObject* obj) +uint32 NetworkReplicator::GetObjectOwnerClientId(const ScriptingObject* obj) { uint32 id = NetworkManager::ServerClientId; if (obj) @@ -870,11 +870,23 @@ uint32 NetworkReplicator::GetObjectOwnerClientId(ScriptingObject* obj) const auto it = Objects.Find(obj->GetID()); if (it != Objects.End()) id = it->Item.OwnerClientId; + else + { + for (const SpawnItem& item : SpawnQueue) + { + if (item.Object == obj) + { + if (item.HasOwnership) + id = item.OwnerClientId; + break; + } + } + } } return id; } -NetworkObjectRole NetworkReplicator::GetObjectRole(ScriptingObject* obj) +NetworkObjectRole NetworkReplicator::GetObjectRole(const ScriptingObject* obj) { NetworkObjectRole role = NetworkObjectRole::None; if (obj) @@ -883,6 +895,18 @@ NetworkObjectRole NetworkReplicator::GetObjectRole(ScriptingObject* obj) const auto it = Objects.Find(obj->GetID()); if (it != Objects.End()) role = it->Item.Role; + else + { + for (const SpawnItem& item : SpawnQueue) + { + if (item.Object == obj) + { + if (item.HasOwnership) + role = item.Role; + break; + } + } + } } return role; } @@ -901,6 +925,18 @@ void NetworkReplicator::SetObjectOwnership(ScriptingObject* obj, uint32 ownerCli auto& item = SpawnQueue[i]; if (item.Object == obj) { +#if !BUILD_RELEASE + if (ownerClientId == NetworkManager::LocalClientId) + { + // Ensure local client owns that object actually + CHECK(localRole == NetworkObjectRole::OwnedAuthoritative); + } + else + { + // Ensure local client doesn't own that object since it's owned by other client + CHECK(localRole != NetworkObjectRole::OwnedAuthoritative); + } +#endif item.HasOwnership = true; item.HierarchicalOwnership = hierarchical; item.OwnerClientId = ownerClientId; diff --git a/Source/Engine/Networking/NetworkReplicator.h b/Source/Engine/Networking/NetworkReplicator.h index e0893cc64..389350e5f 100644 --- a/Source/Engine/Networking/NetworkReplicator.h +++ b/Source/Engine/Networking/NetworkReplicator.h @@ -104,14 +104,14 @@ public: /// /// The network object. /// The Client Id. - API_FUNCTION() static uint32 GetObjectOwnerClientId(ScriptingObject* obj); + API_FUNCTION() static uint32 GetObjectOwnerClientId(const ScriptingObject* obj); /// /// Gets the role of the network object used locally (eg. to check if can simulate object). /// /// The network object. /// The object role. - API_FUNCTION() static NetworkObjectRole GetObjectRole(ScriptingObject* obj); + API_FUNCTION() static NetworkObjectRole GetObjectRole(const ScriptingObject* obj); /// /// Checks if the network object is owned locally (thus current client has authority to manage it). @@ -119,7 +119,7 @@ public: /// Equivalent to GetObjectRole == OwnedAuthoritative. /// The network object. /// True if object is owned by this client, otherwise false. - API_FUNCTION() FORCE_INLINE static bool IsObjectOwned(ScriptingObject* obj) + API_FUNCTION() FORCE_INLINE static bool IsObjectOwned(const ScriptingObject* obj) { return GetObjectRole(obj) == NetworkObjectRole::OwnedAuthoritative; } @@ -130,7 +130,7 @@ public: /// Equivalent to GetObjectRole != Replicated. /// The network object. /// True if object is simulated on this client, otherwise false. - API_FUNCTION() FORCE_INLINE static bool IsObjectSimulated(ScriptingObject* obj) + API_FUNCTION() FORCE_INLINE static bool IsObjectSimulated(const ScriptingObject* obj) { return GetObjectRole(obj) != NetworkObjectRole::Replicated; } @@ -141,7 +141,7 @@ public: /// Equivalent to (GetObjectRole == Replicated or GetObjectRole == ReplicatedAutonomous). /// The network object. /// True if object is simulated on this client, otherwise false. - API_FUNCTION() FORCE_INLINE static bool IsObjectReplicated(ScriptingObject* obj) + API_FUNCTION() FORCE_INLINE static bool IsObjectReplicated(const ScriptingObject* obj) { const NetworkObjectRole role = GetObjectRole(obj); return role == NetworkObjectRole::Replicated || role == NetworkObjectRole::ReplicatedSimulated;