From a48a0d1f8a2470a8fa219d9f681a34c67e8925d1 Mon Sep 17 00:00:00 2001 From: puvvadar Date: Mon, 12 Jul 2021 11:15:38 -0700 Subject: [PATCH] Fix positional desync of network objects plus related log spam Signed-off-by: puvvadar --- .../TcpTransport/TcpSocketManager_Select.cpp | 2 +- .../Editor/MultiplayerEditorConnection.cpp | 14 ++++++++++- .../Code/Source/MultiplayerSystemComponent.h | 2 +- .../EntityReplication/PropertyPublisher.cpp | 25 +++++++++++-------- .../EntityReplication/ReplicationRecord.cpp | 2 ++ 5 files changed, 31 insertions(+), 14 deletions(-) diff --git a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocketManager_Select.cpp b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocketManager_Select.cpp index 130739ca39..651eff820e 100644 --- a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocketManager_Select.cpp +++ b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocketManager_Select.cpp @@ -41,7 +41,7 @@ namespace AzNetworking void TcpSocketManager::ProcessEvents(AZ::TimeMs maxBlockMs, const SocketEventCallback& readCallback, const SocketEventCallback& writeCallback) { - if(static_cast(m_maxFd) <= 0 && m_socketFds.empty()) + if(static_cast(m_maxFd) <= 0 || m_socketFds.empty()) { // There are no available sockets to process return; diff --git a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp index 421d9875bc..bf4fd81ef1 100644 --- a/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp +++ b/Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp @@ -178,6 +178,18 @@ namespace Multiplayer void MultiplayerEditorConnection::OnDisconnect([[maybe_unused]] AzNetworking::IConnection* connection, [[maybe_unused]] DisconnectReason reason, [[maybe_unused]] TerminationEndpoint endpoint) { - ; + bool editorLaunch = false; + if (auto console = AZ::Interface::Get(); console) + { + console->GetCvarValue("editorsv_launch", editorLaunch); + } + + if (editorsv_isDedicated && editorLaunch && m_networkEditorInterface->GetConnectionSet().GetConnectionCount() == 1) + { + if (m_networkEditorInterface->GetPort() != 0) + { + m_networkEditorInterface->StopListening(); + } + } } } diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h index aae363f0d2..7977a39443 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h @@ -151,7 +151,7 @@ namespace Multiplayer AZStd::queue m_pendingConnectionTickets; AZ::TimeMs m_lastReplicatedHostTimeMs = AZ::TimeMs{ 0 }; - HostFrameId m_lastReplicatedHostFrameId = InvalidHostFrameId; + HostFrameId m_lastReplicatedHostFrameId = HostFrameId(0); double m_serverSendAccumulator = 0.0; float m_renderBlendFactor = 0.0f; diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertyPublisher.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertyPublisher.cpp index 2272f43a08..1b21dca50a 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertyPublisher.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/PropertyPublisher.cpp @@ -123,20 +123,23 @@ namespace Multiplayer bool PropertyPublisher::PrepareUpdateEntityRecord() { - // If we reach the maximum outstanding records, reset the replication state + bool didPrepare = true; if (m_sentRecords.size() >= net_EntityReplicatorRecordsMax) { - return PrepareAddEntityRecord(); + // If we reach the maximum outstanding records, reset the replication state + didPrepare = PrepareAddEntityRecord(); } - - // We need to clear out old records, and build up a list of everything that has changed since the last acked packet - m_sentRecords.push_front(m_pendingRecord); - auto iter = m_sentRecords.begin(); - ++iter; // Consider everything after the record we are going to send - for (; iter != m_sentRecords.end(); ++iter) + else { - // Sequence wasn't acked, so we need to send these bits again - m_pendingRecord.Append(*iter); + // We need to clear out old records, and build up a list of everything that has changed since the last acked packet + m_sentRecords.push_front(m_pendingRecord); + auto iter = m_sentRecords.begin(); + ++iter; // Consider everything after the record we are going to send + for (; iter != m_sentRecords.end(); ++iter) + { + // Sequence wasn't acked, so we need to send these bits again + m_pendingRecord.Append(*iter); + } } // Don't send predictable properties back to the Autonomous unless we correct them @@ -145,7 +148,7 @@ namespace Multiplayer m_pendingRecord.Subtract(m_netBindComponent->GetPredictableRecord()); } - return true; + return didPrepare; } bool PropertyPublisher::PrepareDeleteEntityRecord() diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.cpp index eecd4915e7..1c59c70867 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/ReplicationRecord.cpp @@ -191,6 +191,8 @@ namespace Multiplayer bool ReplicationRecord::ContainsAuthorityToClientBits() const { + // Check != Authority here since several modes require information about client updates + // (i.e. Autonomous when performing corrections) return (m_remoteNetEntityRole != NetEntityRole::Authority) || (m_remoteNetEntityRole == NetEntityRole::InvalidRole); }