diff --git a/Code/Framework/AzCore/AzCore/Time/ITime.h b/Code/Framework/AzCore/AzCore/Time/ITime.h index 8146065146..a97ba2319a 100644 --- a/Code/Framework/AzCore/AzCore/Time/ITime.h +++ b/Code/Framework/AzCore/AzCore/Time/ITime.h @@ -83,7 +83,7 @@ namespace AZ //! Converts from microseconds to milliseconds inline TimeMs TimeUsToMs(TimeUs value) { - return static_cast(value * static_cast(1000)); + return static_cast(value / static_cast(1000)); } //! Converts from milliseconds to seconds diff --git a/Code/Framework/AzFramework/AzFramework/Visibility/EntityBoundsUnionBus.h b/Code/Framework/AzFramework/AzFramework/Visibility/EntityBoundsUnionBus.h index b6c26e3e9e..862dea38cc 100644 --- a/Code/Framework/AzFramework/AzFramework/Visibility/EntityBoundsUnionBus.h +++ b/Code/Framework/AzFramework/AzFramework/Visibility/EntityBoundsUnionBus.h @@ -28,9 +28,12 @@ namespace AzFramework //! @note This is used to drive event driven updates to the visibility system. virtual void RefreshEntityLocalBoundsUnion(AZ::EntityId entityId) = 0; - //! Returns the cached union of all component Aabbs. + //! Returns the cached union of all component Aabbs in local entity space. virtual AZ::Aabb GetEntityLocalBoundsUnion(AZ::EntityId entityId) const = 0; + //! Returns the cached union of all component Aabbs in world space. + virtual AZ::Aabb GetEntityWorldBoundsUnion(AZ::EntityId entityId) const = 0; + //! Writes the current changes made to all entities (transforms and bounds) to the visibility system. //! @note During normal operation this is called every frame in OnTick but can //! also be called explicitly (e.g. For testing purposes). diff --git a/Code/Framework/AzFramework/AzFramework/Visibility/EntityVisibilityBoundsUnionSystem.cpp b/Code/Framework/AzFramework/AzFramework/Visibility/EntityVisibilityBoundsUnionSystem.cpp index 826570fee5..1963411147 100644 --- a/Code/Framework/AzFramework/AzFramework/Visibility/EntityVisibilityBoundsUnionSystem.cpp +++ b/Code/Framework/AzFramework/AzFramework/Visibility/EntityVisibilityBoundsUnionSystem.cpp @@ -128,6 +128,24 @@ namespace AzFramework return AZ::Aabb::CreateNull(); } + AZ::Aabb EntityVisibilityBoundsUnionSystem::GetEntityWorldBoundsUnion(const AZ::EntityId entityId) const + { + AZ::Entity* entity = AZ::Interface::Get()->FindEntity(entityId); + if (entity != nullptr) + { + // if the entity is not found in the mapping then return a null Aabb, this is to mimic + // as closely as possible the behavior of an individual GetLocalBounds call to an Entity that + // had been deleted (there would be no response, leaving the default value assigned) + if (auto instance_it = m_entityVisibilityBoundsUnionInstanceMapping.find(entity); + instance_it != m_entityVisibilityBoundsUnionInstanceMapping.end()) + { + return instance_it->second.m_localEntityBoundsUnion.GetTranslated(entity->GetTransform()->GetWorldTranslation()); + } + } + + return AZ::Aabb::CreateNull(); + } + void EntityVisibilityBoundsUnionSystem::ProcessEntityBoundsUnionRequests() { AZ_PROFILE_FUNCTION(AzFramework); diff --git a/Code/Framework/AzFramework/AzFramework/Visibility/EntityVisibilityBoundsUnionSystem.h b/Code/Framework/AzFramework/AzFramework/Visibility/EntityVisibilityBoundsUnionSystem.h index 03109f0dd2..1a3531e506 100644 --- a/Code/Framework/AzFramework/AzFramework/Visibility/EntityVisibilityBoundsUnionSystem.h +++ b/Code/Framework/AzFramework/AzFramework/Visibility/EntityVisibilityBoundsUnionSystem.h @@ -31,6 +31,7 @@ namespace AzFramework // EntityBoundsUnionRequestBus overrides ... void RefreshEntityLocalBoundsUnion(AZ::EntityId entityId) override; AZ::Aabb GetEntityLocalBoundsUnion(AZ::EntityId entityId) const override; + AZ::Aabb GetEntityWorldBoundsUnion(AZ::EntityId entityId) const override; void ProcessEntityBoundsUnionRequests() override; void OnTransformUpdated(AZ::Entity* entity) override; diff --git a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.cpp b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.cpp index f15e0c5d1a..1ccff7be50 100644 --- a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.cpp +++ b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpNetworkInterface.cpp @@ -23,14 +23,14 @@ namespace AzNetworking AZ_CVAR(bool, net_TcpTimeoutConnections, true, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Boolean value on whether we should timeout Tcp connections"); AZ_CVAR(AZ::TimeMs, net_TcpHeartbeatTimeMs, AZ::TimeMs{ 2 * 1000 }, nullptr, AZ::ConsoleFunctorFlags::Null, "Tcp connection heartbeat frequency"); - AZ_CVAR(AZ::TimeMs, net_TcpDefaultTimeoutTimeMs, AZ::TimeMs{ 10 * 1000 }, nullptr, AZ::ConsoleFunctorFlags::Null, "Time in milliseconds before we timeout an idle Tcp connection"); + AZ_CVAR(AZ::TimeMs, net_TcpDefaultTimeoutMs, AZ::TimeMs{ 10 * 1000 }, nullptr, AZ::ConsoleFunctorFlags::Null, "Time in milliseconds before we timeout an idle Tcp connection"); TcpNetworkInterface::TcpNetworkInterface(AZ::Name name, IConnectionListener& connectionListener, TrustZone trustZone, TcpListenThread& listenThread) : m_name(name) , m_trustZone(trustZone) , m_connectionListener(connectionListener) , m_listenThread(listenThread) - , m_timeoutMs(net_TcpDefaultTimeoutTimeMs) + , m_timeoutMs(net_TcpDefaultTimeoutMs) { ; } diff --git a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocket.cpp b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocket.cpp index 272683febc..da0ae4ef08 100644 --- a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocket.cpp +++ b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpSocket.cpp @@ -55,16 +55,19 @@ namespace AzNetworking if (!SocketCreateInternal()) { + Close(); return false; } if (!BindSocketForListenInternal(port)) { + Close(); return false; } if (!(SetSocketNonBlocking(m_socketFd) && SetSocketNoDelay(m_socketFd))) { + Close(); return false; } @@ -75,18 +78,11 @@ namespace AzNetworking { Close(); - if (!SocketCreateInternal()) - { - return false; - } - - if (!BindSocketForConnectInternal(address)) - { - return false; - } - - if (!(SetSocketNonBlocking(m_socketFd) && SetSocketNoDelay(m_socketFd))) + if (!SocketCreateInternal() + || !BindSocketForConnectInternal(address) + || !(SetSocketNonBlocking(m_socketFd) && SetSocketNoDelay(m_socketFd))) { + Close(); return false; } diff --git a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.cpp b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.cpp index b12d3ef845..b0e64f93e3 100644 --- a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.cpp +++ b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.cpp @@ -32,7 +32,7 @@ namespace AzNetworking AZ_CVAR(bool, net_UdpTimeoutConnections, true, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Boolean value on whether we should timeout Udp connections"); AZ_CVAR(AZ::TimeMs, net_UdpPacketTimeSliceMs, AZ::TimeMs{ 8 }, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "The number of milliseconds to allow for packet processing"); AZ_CVAR(AZ::TimeMs, net_UdpHeartbeatTimeMs, AZ::TimeMs{ 2 * 1000 }, nullptr, AZ::ConsoleFunctorFlags::Null, "Udp connection heartbeat frequency"); - AZ_CVAR(AZ::TimeMs, net_UdpDefaultTimeoutTimeMs, AZ::TimeMs{ 10 * 1000 }, nullptr, AZ::ConsoleFunctorFlags::Null, "Time in milliseconds before we timeout an idle Udp connection"); + AZ_CVAR(AZ::TimeMs, net_UdpDefaultTimeoutMs, AZ::TimeMs{ 10 * 1000 }, nullptr, AZ::ConsoleFunctorFlags::Null, "Time in milliseconds before we timeout an idle Udp connection"); AZ_CVAR(AZ::TimeMs, net_MinPacketTimeoutMs, AZ::TimeMs{ 200 }, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Minimum time to wait before timing out an unacked packet"); AZ_CVAR(int32_t, net_MaxTimeoutsPerFrame, 1000, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Maximum number of packet timeouts to allow to process in a single frame"); AZ_CVAR(float, net_RttFudgeScalar, 2.0f, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Scalar value to multiply computed Rtt by to determine an optimal packet timeout threshold"); @@ -61,7 +61,7 @@ namespace AzNetworking , m_connectionListener(connectionListener) , m_socket(net_UdpUseEncryption ? new DtlsSocket() : new UdpSocket()) , m_readerThread(readerThread) - , m_timeoutMs(net_UdpDefaultTimeoutTimeMs) + , m_timeoutMs(net_UdpDefaultTimeoutMs) { const AZ::CVarFixedString compressor = static_cast(net_UdpCompressor); const AZ::Name compressorName = AZ::Name(compressor); diff --git a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpSocket.cpp b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpSocket.cpp index 44f6562c84..300b3527fa 100644 --- a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpSocket.cpp +++ b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpSocket.cpp @@ -79,17 +79,15 @@ namespace AzNetworking { const int32_t error = GetLastNetworkError(); AZLOG_ERROR("Failed to bind UDP socket to port %u (%d:%s)", uint32_t(port), error, GetNetworkErrorDesc(error)); + Close(); return false; } } - if (!SetSocketBufferSizes(m_socketFd, net_UdpSendBufferSize, net_UdpRecvBufferSize)) - { - return false; - } - - if (!SetSocketNonBlocking(m_socketFd)) + if (!SetSocketBufferSizes(m_socketFd, net_UdpSendBufferSize, net_UdpRecvBufferSize) + || !SetSocketNonBlocking(m_socketFd)) { + Close(); return false; } diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/Components/NetBindComponent.h b/Gems/Multiplayer/Code/Include/Multiplayer/Components/NetBindComponent.h index d1f9e001b1..887aabb3fb 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/Components/NetBindComponent.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/Components/NetBindComponent.h @@ -32,7 +32,7 @@ namespace Multiplayer using EntityStopEvent = AZ::Event; using EntityDirtiedEvent = AZ::Event<>; using EntitySyncRewindEvent = AZ::Event<>; - using EntityServerMigrationEvent = AZ::Event; + using EntityServerMigrationEvent = AZ::Event; using EntityPreRenderEvent = AZ::Event; using EntityCorrectionEvent = AZ::Event<>; @@ -113,7 +113,7 @@ namespace Multiplayer void MarkDirty(); void NotifyLocalChanges(); void NotifySyncRewindState(); - void NotifyServerMigration(HostId hostId, AzNetworking::ConnectionId connectionId); + void NotifyServerMigration(const HostId& hostId, AzNetworking::ConnectionId connectionId); void NotifyPreRender(float deltaTime); void NotifyCorrection(); diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h index 021907fb7a..ff4c9106e6 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/IMultiplayer.h @@ -45,7 +45,7 @@ namespace Multiplayer using ClientMigrationStartEvent = AZ::Event; using ClientMigrationEndEvent = AZ::Event<>; using ClientDisconnectedEvent = AZ::Event<>; - using NotifyClientMigrationEvent = AZ::Event; + using NotifyClientMigrationEvent = AZ::Event; using ConnectionAcquiredEvent = AZ::Event; using SessionInitEvent = AZ::Event; using SessionShutdownEvent = AZ::Event; @@ -91,7 +91,7 @@ namespace Multiplayer //! @param remoteAddress The domain or IP to connect to //! @param port The port to connect to //! @result if a connection was successfully created - virtual bool Connect(AZStd::string remoteAddress, uint16_t port) = 0; + virtual bool Connect(const AZStd::string& remoteAddress, uint16_t port) = 0; // Disconnects all multiplayer connections, stops listening on the server and invokes handlers appropriate to network context. //! @param reason The reason for terminating connections @@ -129,7 +129,7 @@ namespace Multiplayer //! @param hostId the host id of the host the client is migrating to //! @param userIdentifier the user identifier the client will provide the new host to validate identity //! @param lastClientInputId the last processed clientInputId by the current host - virtual void SendNotifyClientMigrationEvent(HostId hostId, uint64_t userIdentifier, ClientInputId lastClientInputId); + virtual void SendNotifyClientMigrationEvent(const HostId& hostId, uint64_t userIdentifier, ClientInputId lastClientInputId) = 0; //! Sends a packet telling if entity update messages can be sent. //! @param readyForEntityUpdates Ready for entity updates or not diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerTypes.h b/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerTypes.h index 26cdf72e5f..96035083d8 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerTypes.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/MultiplayerTypes.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -25,8 +26,8 @@ namespace Multiplayer //! The default blend factor for ScopedAlterTime static constexpr float DefaultBlendFactor = 1.f; - AZ_TYPE_SAFE_INTEGRAL(HostId, uint32_t); - static constexpr HostId InvalidHostId = static_cast(-1); + using HostId = AzNetworking::IpAddress; + static const HostId InvalidHostId = HostId(); AZ_TYPE_SAFE_INTEGRAL(NetEntityId, uint32_t); static constexpr NetEntityId InvalidNetEntityId = static_cast(-1); @@ -152,7 +153,6 @@ namespace Multiplayer } } -AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(Multiplayer::HostId); AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(Multiplayer::NetEntityId); AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(Multiplayer::NetComponentId); AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(Multiplayer::PropertyIndex); @@ -162,7 +162,6 @@ AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(Multiplayer::HostFrameId); namespace AZ { - AZ_TYPE_INFO_SPECIALIZE(Multiplayer::HostId, "{D04B3363-8E1B-4193-8B2B-D2140389C9D5}"); AZ_TYPE_INFO_SPECIALIZE(Multiplayer::NetEntityId, "{05E4C08B-3A1B-4390-8144-3767D8E56A81}"); AZ_TYPE_INFO_SPECIALIZE(Multiplayer::NetComponentId, "{8AF3B382-F187-4323-9014-B380638767E3}"); AZ_TYPE_INFO_SPECIALIZE(Multiplayer::PropertyIndex, "{F4460210-024D-4B3B-A10A-04B669C34230}"); diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntity/EntityReplication/EntityReplicationManager.h b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntity/EntityReplication/EntityReplicationManager.h index 118ff0e6af..dd84c9d952 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntity/EntityReplication/EntityReplicationManager.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntity/EntityReplication/EntityReplicationManager.h @@ -56,8 +56,8 @@ namespace Multiplayer EntityReplicationManager(AzNetworking::IConnection& connection, AzNetworking::IConnectionListener& connectionListener, Mode mode); ~EntityReplicationManager() = default; - void SetRemoteHostId(HostId hostId); - HostId GetRemoteHostId() const; + void SetRemoteHostId(const HostId& hostId); + const HostId& GetRemoteHostId() const; void ActivatePendingEntities(); void SendUpdates(AZ::TimeMs hostTimeMs); @@ -127,7 +127,7 @@ namespace Multiplayer void MigrateEntityInternal(NetEntityId entityId); void OnEntityExitDomain(const ConstNetworkEntityHandle& entityHandle); - void OnPostEntityMigration(const ConstNetworkEntityHandle& entityHandle, HostId remoteHostId, AzNetworking::ConnectionId connectionId); + void OnPostEntityMigration(const ConstNetworkEntityHandle& entityHandle, const HostId& remoteHostId, AzNetworking::ConnectionId connectionId); EntityReplicator* AddEntityReplicator(const ConstNetworkEntityHandle& entityHandle, NetEntityRole netEntityRole); diff --git a/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntity/INetworkEntityManager.h b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntity/INetworkEntityManager.h index 51f432953e..ba2024bb8e 100644 --- a/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntity/INetworkEntityManager.h +++ b/Gems/Multiplayer/Code/Include/Multiplayer/NetworkEntity/INetworkEntityManager.h @@ -41,7 +41,7 @@ namespace Multiplayer //! Configures the NetworkEntityManager to operate as an authoritative host. //! @param hostId the hostId of this NetworkEntityManager //! @param entityDomain the entity domain used to determine which entities this manager has authority over - virtual void Initialize(HostId hostId, AZStd::unique_ptr entityDomain) = 0; + virtual void Initialize(const HostId& hostId, AZStd::unique_ptr entityDomain) = 0; //! Returns whether or not the network entity manager has been initialized to host. //! @return boolean true if this network entity manager has been intialized to host @@ -65,7 +65,7 @@ namespace Multiplayer //! Returns the HostId for this INetworkEntityManager instance. //! @return the HostId for this INetworkEntityManager instance - virtual HostId GetHostId() const = 0; + virtual const HostId& GetHostId() const = 0; //! Creates new entities of the given archetype //! @param prefabEntryId the name of the spawnable to spawn diff --git a/Gems/Multiplayer/Code/Source/AutoGen/Multiplayer.AutoPackets.xml b/Gems/Multiplayer/Code/Source/AutoGen/Multiplayer.AutoPackets.xml index ee0898b681..a782a7dcf2 100644 --- a/Gems/Multiplayer/Code/Source/AutoGen/Multiplayer.AutoPackets.xml +++ b/Gems/Multiplayer/Code/Source/AutoGen/Multiplayer.AutoPackets.xml @@ -13,7 +13,6 @@ - diff --git a/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp b/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp index 7d630ebe1d..524400d008 100644 --- a/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Components/NetBindComponent.cpp @@ -390,7 +390,7 @@ namespace Multiplayer m_syncRewindEvent.Signal(); } - void NetBindComponent::NotifyServerMigration(HostId hostId, AzNetworking::ConnectionId connectionId) + void NetBindComponent::NotifyServerMigration(const HostId& hostId, AzNetworking::ConnectionId connectionId) { m_entityServerMigrationEvent.Signal(m_netEntityHandle, hostId, connectionId); } diff --git a/Gems/Multiplayer/Code/Source/Components/NetworkCharacterComponent.cpp b/Gems/Multiplayer/Code/Source/Components/NetworkCharacterComponent.cpp index f34771b2c6..5c46a30a9b 100644 --- a/Gems/Multiplayer/Code/Source/Components/NetworkCharacterComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Components/NetworkCharacterComponent.cpp @@ -186,7 +186,7 @@ namespace Multiplayer // Ensure any entities that we might interact with are properly synchronized to their rewind state if (IsAuthority()) { - const AZ::Aabb entityStartBounds = AZ::Interface::Get()->GetEntityLocalBoundsUnion(GetEntity()->GetId()); + const AZ::Aabb entityStartBounds = AZ::Interface::Get()->GetEntityWorldBoundsUnion(GetEntity()->GetId()); const AZ::Aabb entityFinalBounds = entityStartBounds.GetTranslated(velocity); AZ::Aabb entitySweptBounds = entityStartBounds; entitySweptBounds.AddAabb(entityFinalBounds); diff --git a/Gems/Multiplayer/Code/Source/ConnectionData/ServerToClientConnectionData.cpp b/Gems/Multiplayer/Code/Source/ConnectionData/ServerToClientConnectionData.cpp index ad1bcb5130..218f8421d2 100644 --- a/Gems/Multiplayer/Code/Source/ConnectionData/ServerToClientConnectionData.cpp +++ b/Gems/Multiplayer/Code/Source/ConnectionData/ServerToClientConnectionData.cpp @@ -28,7 +28,7 @@ namespace Multiplayer ) : m_connection(connection) , m_controlledEntityRemovedHandler([this](const ConstNetworkEntityHandle&) { OnControlledEntityRemove(); }) - , m_controlledEntityMigrationHandler([this](const ConstNetworkEntityHandle& entityHandle, HostId remoteHostId, AzNetworking::ConnectionId connectionId) { OnControlledEntityMigration(entityHandle, remoteHostId, connectionId); }) + , m_controlledEntityMigrationHandler([this](const ConstNetworkEntityHandle& entityHandle, const HostId& remoteHostId, AzNetworking::ConnectionId connectionId) { OnControlledEntityMigration(entityHandle, remoteHostId, connectionId); }) , m_controlledEntity(controlledEntity) , m_entityReplicationManager(*connection, connectionListener, EntityReplicationManager::Mode::LocalServerToRemoteClient) { @@ -94,13 +94,10 @@ namespace Multiplayer void ServerToClientConnectionData::OnControlledEntityMigration ( [[maybe_unused]] const ConstNetworkEntityHandle& entityHandle, - [[maybe_unused]] HostId remoteHostId, + [[maybe_unused]] const HostId& remoteHostId, [[maybe_unused]] AzNetworking::ConnectionId connectionId ) { - AzNetworking::IpAddress serverAddress; - // serverAddress = GetHost(remoteHostId).GetAddress(); - ClientInputId migratedClientInputId = ClientInputId{ 0 }; if (m_controlledEntity != nullptr) { @@ -118,7 +115,7 @@ namespace Multiplayer GetMultiplayer()->SendNotifyClientMigrationEvent(remoteHostId, randomUserIdentifier, migratedClientInputId); // Tell the client who to join - MultiplayerPackets::ClientMigration clientMigration(serverAddress, randomUserIdentifier, migratedClientInputId); + MultiplayerPackets::ClientMigration clientMigration(remoteHostId, randomUserIdentifier, migratedClientInputId); GetConnection()->SendReliablePacket(clientMigration); m_controlledEntity = NetworkEntityHandle(); diff --git a/Gems/Multiplayer/Code/Source/ConnectionData/ServerToClientConnectionData.h b/Gems/Multiplayer/Code/Source/ConnectionData/ServerToClientConnectionData.h index 78ee721d97..764497430f 100644 --- a/Gems/Multiplayer/Code/Source/ConnectionData/ServerToClientConnectionData.h +++ b/Gems/Multiplayer/Code/Source/ConnectionData/ServerToClientConnectionData.h @@ -42,7 +42,7 @@ namespace Multiplayer private: void OnControlledEntityRemove(); - void OnControlledEntityMigration(const ConstNetworkEntityHandle& entityHandle, HostId remoteHostId, AzNetworking::ConnectionId connectionId); + void OnControlledEntityMigration(const ConstNetworkEntityHandle& entityHandle, const HostId& remoteHostId, AzNetworking::ConnectionId connectionId); void OnGameplayStarted(); EntityReplicationManager m_entityReplicationManager; diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp index df88af5296..eb4c2f0f0b 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp @@ -71,7 +71,7 @@ namespace Multiplayer AZ_CVAR(uint16_t, cl_clientport, 0, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "The port to bind to for game traffic when connecting to a remote host, a value of 0 will select any available port"); - AZ_CVAR(AZ::CVarFixedString, cl_serveraddr, AZ::CVarFixedString(LocalHost), nullptr, AZ::ConsoleFunctorFlags::DontReplicate, + AZ_CVAR(AZ::CVarFixedString, cl_serveraddr, AZ::CVarFixedString(LocalHost), nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "The address of the remote server or host to connect to"); AZ_CVAR(uint16_t, cl_serverport, DefaultServerPort, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "The port of the remote host to connect to for game traffic"); AZ_CVAR(uint16_t, sv_port, DefaultServerPort, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "The port that this multiplayer gem will bind to for game traffic"); @@ -92,8 +92,6 @@ namespace Multiplayer { serializeContext->Class() ->Version(1); - serializeContext->Class() - ->Version(1); serializeContext->Class() ->Version(1); serializeContext->Class() @@ -109,7 +107,6 @@ namespace Multiplayer } else if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) { - behaviorContext->Class(); behaviorContext->Class(); behaviorContext->Class(); behaviorContext->Class(); @@ -208,7 +205,7 @@ namespace Multiplayer return m_networkInterface->Listen(port); } - bool MultiplayerSystemComponent::Connect(AZStd::string remoteAddress, uint16_t port) + bool MultiplayerSystemComponent::Connect(const AZStd::string& remoteAddress, uint16_t port) { InitializeMultiplayer(MultiplayerAgentType::Client); const IpAddress address(remoteAddress.c_str(), port, m_networkInterface->GetType()); @@ -468,7 +465,7 @@ namespace Multiplayer } reinterpret_cast(connection->GetUserData())->SetProviderTicket(packet.GetTicket().c_str()); - if (connection->SendReliablePacket(MultiplayerPackets::Accept(InvalidHostId, sv_map))) + if (connection->SendReliablePacket(MultiplayerPackets::Accept(sv_map))) { m_didHandshake = true; @@ -760,7 +757,11 @@ namespace Multiplayer if (!m_networkEntityManager.IsInitialized()) { // Set up a full ownership domain if we didn't construct a domain during the initialize event - m_networkEntityManager.Initialize(InvalidHostId, AZStd::make_unique()); + const AZ::CVarFixedString serverAddr = cl_serveraddr; + const uint16_t serverPort = cl_serverport; + const AzNetworking::ProtocolType serverProtocol = sv_protocol; + const AzNetworking::IpAddress hostId = AzNetworking::IpAddress(serverAddr.c_str(), serverPort, serverProtocol); + m_networkEntityManager.Initialize(hostId, AZStd::make_unique()); } } } @@ -815,7 +816,7 @@ namespace Multiplayer handler.Connect(m_shutdownEvent); } - void MultiplayerSystemComponent::SendNotifyClientMigrationEvent(HostId hostId, uint64_t userIdentifier, ClientInputId lastClientInputId) + void MultiplayerSystemComponent::SendNotifyClientMigrationEvent(const HostId& hostId, uint64_t userIdentifier, ClientInputId lastClientInputId) { m_notifyClientMigrationEvent.Signal(hostId, userIdentifier, lastClientInputId); } @@ -1012,7 +1013,10 @@ namespace Multiplayer void host([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments) { - AZ::Interface::Get()->StartHosting(sv_port, sv_isDedicated); + if (!AZ::Interface::Get()->StartHosting(sv_port, sv_isDedicated)) + { + AZLOG_ERROR("Failed to start listening on port %u, port is in use?", static_cast(sv_port)); + } } AZ_CONSOLEFREEFUNC(host, AZ::ConsoleFunctorFlags::DontReplicate, "Opens a multiplayer connection as a host for other clients to connect to"); diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h index bdf6511409..b49ad831c1 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h @@ -106,7 +106,7 @@ namespace Multiplayer MultiplayerAgentType GetAgentType() const override; void InitializeMultiplayer(MultiplayerAgentType state) override; bool StartHosting(uint16_t port, bool isDedicated = true) override; - bool Connect(AZStd::string remoteAddress, uint16_t port) override; + bool Connect(const AZStd::string& remoteAddress, uint16_t port) override; void Terminate(AzNetworking::DisconnectReason reason) override; void AddClientMigrationStartEventHandler(ClientMigrationStartEvent::Handler& handler) override; void AddClientMigrationEndEventHandler(ClientMigrationEndEvent::Handler& handler) override; @@ -115,7 +115,7 @@ namespace Multiplayer void AddConnectionAcquiredHandler(ConnectionAcquiredEvent::Handler& handler) override; void AddSessionInitHandler(SessionInitEvent::Handler& handler) override; void AddSessionShutdownHandler(SessionShutdownEvent::Handler& handler) override; - void SendNotifyClientMigrationEvent(HostId hostId, uint64_t userIdentifier, ClientInputId lastClientInputId) override; + void SendNotifyClientMigrationEvent(const HostId& hostId, uint64_t userIdentifier, ClientInputId lastClientInputId) override; void SendReadyForEntityUpdates(bool readyForEntityUpdates) override; AZ::TimeMs GetCurrentHostTimeMs() const override; float GetCurrentBlendFactor() const override; diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp index 938b3611c5..df6be37e5e 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicationManager.cpp @@ -63,12 +63,12 @@ namespace Multiplayer } } - void EntityReplicationManager::SetRemoteHostId(HostId hostId) + void EntityReplicationManager::SetRemoteHostId(const HostId& hostId) { m_remoteHostId = hostId; } - HostId EntityReplicationManager::GetRemoteHostId() const + const HostId& EntityReplicationManager::GetRemoteHostId() const { return m_remoteHostId; } @@ -106,9 +106,9 @@ namespace Multiplayer AZLOG ( NET_ReplicationInfo, - "Sending from %u to %u, replicator count %u orphan count %u deferred reliable count %u deferred unreliable count %u", - aznumeric_cast(GetNetworkEntityManager()->GetHostId()), - aznumeric_cast(GetRemoteHostId()), + "Sending from %s to %s, replicator count %u orphan count %u deferred reliable count %u deferred unreliable count %u", + GetNetworkEntityManager()->GetHostId().GetString().c_str(), + GetRemoteHostId().GetString().c_str(), aznumeric_cast(m_entityReplicatorMap.size()), aznumeric_cast(m_orphanedEntityRpcs.Size()), aznumeric_cast(m_deferredRpcMessagesReliable.size()), @@ -250,7 +250,14 @@ namespace Multiplayer { EntityReplicatorList toSendList = GenerateEntityUpdateList(); - AZLOG(NET_ReplicationInfo, "Sending %zd updates from %d to %d", toSendList.size(), (uint8_t)GetNetworkEntityManager()->GetHostId(), (uint8_t)GetRemoteHostId()); + AZLOG + ( + NET_ReplicationInfo, + "Sending %zd updates from %s to %s", + toSendList.size(), + GetNetworkEntityManager()->GetHostId().GetString().c_str(), + GetRemoteHostId().GetString().c_str() + ); // prep a replication record for send, at this point, everything needs to be sent for (EntityReplicator* replicator : toSendList) @@ -357,7 +364,7 @@ namespace Multiplayer // Check if we changed our remote role - this can happen during server entity migration. After we migrate ownership to the new server, we hold onto our entity replicator until we are sure // the other side has received all the packets (and we haven't had to do resends). At this point, it is possible hear back from the remote side we migrated to on the old replicator prior to the timeout and cleanup on the old one const bool changedRemoteRole = (remoteNetworkRole != entityReplicator->GetRemoteNetworkRole()); - // check if we've changed our bound local role - this can occur when we gain Autonomous or lose Autonomous on a client + // Check if we've changed our bound local role - this can occur when we gain Autonomous or lose Autonomous on a client bool changedLocalRole(false); if (AZ::Entity* localEnt = entityReplicator->GetEntityHandle().GetEntity()) { @@ -377,19 +384,33 @@ namespace Multiplayer // Reset our replicator, we are establishing a new one entityReplicator->Reset(remoteNetworkRole); } - // else case is when an entity had left relevancy and come back (but it was still pending a removal) + // Else case is when an entity had left relevancy and come back (but it was still pending a removal) entityReplicator->Initialize(entityHandle); - AZLOG(NET_RepDeletes, "Reinited replicator for %u from remote manager id %d role %d", entityHandle.GetNetEntityId(), aznumeric_cast(GetRemoteHostId()), aznumeric_cast(remoteNetworkRole)); + AZLOG + ( + NET_RepDeletes, + "Reinited replicator for %u from remote host %s role %d", + entityHandle.GetNetEntityId(), + GetRemoteHostId().GetString().c_str(), + aznumeric_cast(remoteNetworkRole) + ); } else { - // haven't seen him before, let's add him + // Haven't seen him before, let's add him AZ_Assert(entityHandle.GetNetBindComponent(), "No NetBindComponent"); AZStd::unique_ptr newEntityReplicator = AZStd::make_unique(*this, &m_connection, remoteNetworkRole, entityHandle); newEntityReplicator->Initialize(entityHandle); entityReplicator = newEntityReplicator.get(); m_entityReplicatorMap.emplace(entityHandle.GetNetEntityId(), AZStd::move(newEntityReplicator)); - AZLOG(NET_RepDeletes, "Added replicator for %u from remote manager id %d role %d", entityHandle.GetNetEntityId(), aznumeric_cast(GetRemoteHostId()), aznumeric_cast(remoteNetworkRole)); + AZLOG + ( + NET_RepDeletes, + "Added replicator for %u from remote host %s role %d", + entityHandle.GetNetEntityId(), + GetRemoteHostId().GetString().c_str(), + aznumeric_cast(remoteNetworkRole) + ); } } else @@ -483,18 +504,18 @@ namespace Multiplayer { if (entityReplicator->IsMarkedForRemoval()) { - AZLOG(NET_RepDeletes, "Got a replicator delete message that is a duplicate id %u remote manager id %d", updateMessage.GetEntityId(), aznumeric_cast(GetRemoteHostId())); + AZLOG(NET_RepDeletes, "Got a replicator delete message that is a duplicate id %u remote host %s", updateMessage.GetEntityId(), GetRemoteHostId().GetString().c_str()); } else if (entityReplicator->OwnsReplicatorLifetime()) { // This can occur if we migrate entities quickly - if this is a replicator from C to A, A migrates to B, B then migrates to C, and A's delete replicator has not arrived at C - AZLOG(NET_RepDeletes, "Got a replicator delete message for a replicator we own id %u remote manager id %d", updateMessage.GetEntityId(), aznumeric_cast(GetRemoteHostId())); + AZLOG(NET_RepDeletes, "Got a replicator delete message for a replicator we own id %u remote host %s", updateMessage.GetEntityId(), GetRemoteHostId().GetString().c_str()); } else { shouldDeleteEntity = true; entityReplicator->MarkForRemoval(); - AZLOG(NET_RepDeletes, "Deleting replicater for entity id %u remote manager id %d", updateMessage.GetEntityId(), aznumeric_cast(GetRemoteHostId())); + AZLOG(NET_RepDeletes, "Deleting replicater for entity id %u remote host %s", updateMessage.GetEntityId(), GetRemoteHostId().GetString().c_str()); } } else @@ -510,17 +531,17 @@ namespace Multiplayer { if (updateMessage.GetWasMigrated()) { - AZLOG(NET_RepDeletes, "Leaving id %u using timeout remote manager id %d", entity.GetNetEntityId(), aznumeric_cast(GetRemoteHostId())); + AZLOG(NET_RepDeletes, "Leaving id %u using timeout remote host %s", entity.GetNetEntityId(), GetRemoteHostId().GetString().c_str()); } else { - AZLOG(NET_RepDeletes, "Deleting entity id %u remote manager id %d", entity.GetNetEntityId(), aznumeric_cast(GetRemoteHostId())); + AZLOG(NET_RepDeletes, "Deleting entity id %u remote host %s", entity.GetNetEntityId(), GetRemoteHostId().GetString().c_str()); GetNetworkEntityManager()->MarkForRemoval(entity); } } else { - AZLOG(NET_RepDeletes, "Trying to delete entity id %u remote manager id %d, but it has been removed", entity.GetNetEntityId(), aznumeric_cast(GetRemoteHostId())); + AZLOG(NET_RepDeletes, "Trying to delete entity id %u remote host %s, but it has been removed", entity.GetNetEntityId(), GetRemoteHostId().GetString().c_str()); } } @@ -689,8 +710,8 @@ namespace Multiplayer AZLOG_WARN ( "Dropping Packet and LocalServerToRemoteClient connection, unexpected packet " - "LocalShard=%u EntityId=%u RemoteNetworkRole=%u BoundLocalNetworkRole=%u ActualNetworkRole=%u IsMarkedForRemoval=%s", - aznumeric_cast(GetNetworkEntityManager()->GetHostId()), + "LocalShard=%s EntityId=%u RemoteNetworkRole=%u BoundLocalNetworkRole=%u ActualNetworkRole=%u IsMarkedForRemoval=%s", + GetNetworkEntityManager()->GetHostId().GetString().c_str(), aznumeric_cast(entityReplicator->GetEntityHandle().GetNetEntityId()), aznumeric_cast(entityReplicator->GetRemoteNetworkRole()), aznumeric_cast(entityReplicator->GetBoundLocalNetworkRole()), @@ -741,13 +762,13 @@ namespace Multiplayer result = UpdateValidationResult::DropMessage; if (updateMessage.GetIsDelete()) { - AZLOG(NET_RepDeletes, "EntityReplicationManager: Received old DeleteProxy message for entity id %u, sequence %d latest sequence %d from remote manager id %d", - updateMessage.GetEntityId(), (uint32_t)packetId, (uint32_t)propSubscriber->GetLastReceivedPacketId(), aznumeric_cast(GetRemoteHostId())); + AZLOG(NET_RepDeletes, "EntityReplicationManager: Received old DeleteProxy message for entity id %u, sequence %d latest sequence %d from remote host %s", + updateMessage.GetEntityId(), (uint32_t)packetId, (uint32_t)propSubscriber->GetLastReceivedPacketId(), GetRemoteHostId().GetString().c_str()); } else { - AZLOG(NET_RepUpdate, "EntityReplicationManager: Received old PropertyChangeMessage message for entity id %u, sequence %d latest sequence %d from remote manager id %d", - updateMessage.GetEntityId(), (uint32_t)packetId, (uint32_t)propSubscriber->GetLastReceivedPacketId(), aznumeric_cast(GetRemoteHostId())); + AZLOG(NET_RepUpdate, "EntityReplicationManager: Received old PropertyChangeMessage message for entity id %u, sequence %d latest sequence %d from remote host %s", + updateMessage.GetEntityId(), (uint32_t)packetId, (uint32_t)propSubscriber->GetLastReceivedPacketId(), GetRemoteHostId().GetString().c_str()); } } } @@ -1126,7 +1147,7 @@ namespace Multiplayer AZ_Assert(didSucceed, "Failed to migrate entity from server"); m_sendMigrateEntityEvent.Signal(m_connection, message); - AZLOG(NET_RepDeletes, "Migration packet sent %u to remote manager id %d", netEntityId, aznumeric_cast(GetRemoteHostId())); + AZLOG(NET_RepDeletes, "Migration packet sent %u to remote host %s", netEntityId, GetRemoteHostId().GetString().c_str()); // Immediately add a new replicator so that we catch RPC invocations, the remote side will make us a new one, and then remove us if needs be AddEntityReplicator(entityHandle, NetEntityRole::Authority); @@ -1179,7 +1200,7 @@ namespace Multiplayer // Change the role on the replicator AddEntityReplicator(entityHandle, NetEntityRole::Server); - AZLOG(NET_RepDeletes, "Handle Migration %u new authority from remote manager id %d", entityHandle.GetNetEntityId(), aznumeric_cast(GetRemoteHostId())); + AZLOG(NET_RepDeletes, "Handle Migration %u new authority from remote host %s", entityHandle.GetNetEntityId(), GetRemoteHostId().GetString().c_str()); return true; } @@ -1191,7 +1212,7 @@ namespace Multiplayer } } - void EntityReplicationManager::OnPostEntityMigration(const ConstNetworkEntityHandle& entityHandle, HostId remoteHostId, [[maybe_unused]] AzNetworking::ConnectionId connectionId) + void EntityReplicationManager::OnPostEntityMigration(const ConstNetworkEntityHandle& entityHandle, const HostId& remoteHostId, [[maybe_unused]] AzNetworking::ConnectionId connectionId) { if (remoteHostId == GetRemoteHostId()) { diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp index 95e2b6d12c..8329d7c9df 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/EntityReplication/EntityReplicator.cpp @@ -413,10 +413,10 @@ namespace Multiplayer AZLOG ( NET_RepDeletes, - "Sending delete replicator id %u migrated %d to remote manager id %d", + "Sending delete replicator id %u migrated %d to remote host %s", aznumeric_cast(GetEntityHandle().GetNetEntityId()), WasMigrated() ? 1 : 0, - aznumeric_cast(m_replicationManager.GetRemoteHostId()) + m_replicationManager.GetRemoteHostId().GetString().c_str() ); return NetworkEntityUpdateMessage(GetEntityHandle().GetNetEntityId(), WasMigrated(), m_propertyPublisher->IsRemoteReplicatorEstablished()); } diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityAuthorityTracker.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityAuthorityTracker.cpp index 947d303278..0a99f4b0d4 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityAuthorityTracker.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityAuthorityTracker.cpp @@ -24,7 +24,7 @@ namespace Multiplayer ; } - bool NetworkEntityAuthorityTracker::AddEntityAuthorityManager(ConstNetworkEntityHandle entityHandle, HostId newOwner) + bool NetworkEntityAuthorityTracker::AddEntityAuthorityManager(ConstNetworkEntityHandle entityHandle, const HostId& newOwner) { bool ret = false; auto timeoutData = m_timeoutDataMap.find(entityHandle.GetNetEntityId()); @@ -33,10 +33,10 @@ namespace Multiplayer AZLOG ( NET_AuthTracker, - "AuthTracker: Removing timeout for networkEntityId %u from %u, new owner is %u", + "AuthTracker: Removing timeout for networkEntityId %u from %s, new owner is %s", aznumeric_cast(entityHandle.GetNetEntityId()), - aznumeric_cast(timeoutData->second.m_previousOwner), - aznumeric_cast(newOwner) + timeoutData->second.m_previousOwner.GetString().c_str(), + newOwner.GetString().c_str() ); m_timeoutDataMap.erase(timeoutData); ret = true; @@ -48,10 +48,10 @@ namespace Multiplayer AZLOG ( NET_AuthTracker, - "AuthTracker: Assigning networkEntityId %u from %u to %u", + "AuthTracker: Assigning networkEntityId %u from %s to %s", aznumeric_cast(entityHandle.GetNetEntityId()), - aznumeric_cast(iter->second.back()), - aznumeric_cast(newOwner) + iter->second.back().GetString().c_str(), + newOwner.GetString().c_str() ); } else @@ -59,9 +59,9 @@ namespace Multiplayer AZLOG ( NET_AuthTracker, - "AuthTracker: Assigning networkEntityId %u to %u", + "AuthTracker: Assigning networkEntityId %u to %s", aznumeric_cast(entityHandle.GetNetEntityId()), - aznumeric_cast(newOwner) + newOwner.GetString().c_str() ); } @@ -69,7 +69,7 @@ namespace Multiplayer return ret; } - void NetworkEntityAuthorityTracker::RemoveEntityAuthorityManager(ConstNetworkEntityHandle entityHandle, HostId previousOwner) + void NetworkEntityAuthorityTracker::RemoveEntityAuthorityManager(ConstNetworkEntityHandle entityHandle, const HostId& previousOwner) { auto mapIter = m_entityAuthorityMap.find(entityHandle.GetNetEntityId()); if (mapIter != m_entityAuthorityMap.end()) @@ -87,7 +87,7 @@ namespace Multiplayer } } - AZLOG(NET_AuthTracker, "AuthTracker: Removing networkEntityId %u from %u", aznumeric_cast(entityHandle.GetNetEntityId()), aznumeric_cast(previousOwner)); + AZLOG(NET_AuthTracker, "AuthTracker: Removing networkEntityId %u from %s", aznumeric_cast(entityHandle.GetNetEntityId()), previousOwner.GetString().c_str()); if (auto localEnt = entityHandle.GetEntity()) { if (authorityStack.empty()) @@ -167,7 +167,7 @@ namespace Multiplayer return InvalidHostId; } - NetworkEntityAuthorityTracker::TimeoutData::TimeoutData(ConstNetworkEntityHandle entityHandle, HostId previousOwner) + NetworkEntityAuthorityTracker::TimeoutData::TimeoutData(ConstNetworkEntityHandle entityHandle, const HostId& previousOwner) : m_entityHandle(entityHandle) , m_previousOwner(previousOwner) { @@ -205,9 +205,9 @@ namespace Multiplayer { AZLOG_ERROR ( - "Timed out entity id %u during migration previous owner %u, removing it", + "Timed out entity id %u during migration previous owner %s, removing it", aznumeric_cast(entityHandle.GetNetEntityId()), - aznumeric_cast(timeoutData->second.m_previousOwner) + timeoutData->second.m_previousOwner.GetString().c_str() ); m_networkEntityManager.MarkForRemoval(entityHandle); } diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityAuthorityTracker.h b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityAuthorityTracker.h index d69edcf55b..0f4ff5665a 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityAuthorityTracker.h +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityAuthorityTracker.h @@ -24,8 +24,8 @@ namespace Multiplayer NetworkEntityAuthorityTracker(INetworkEntityManager& networkEntityManager); bool DoesEntityHaveOwner(ConstNetworkEntityHandle entityHandle) const; - bool AddEntityAuthorityManager(ConstNetworkEntityHandle entityHandle, HostId newOwner); - void RemoveEntityAuthorityManager(ConstNetworkEntityHandle entityHandle, HostId previousOwner); + bool AddEntityAuthorityManager(ConstNetworkEntityHandle entityHandle, const HostId& newOwner); + void RemoveEntityAuthorityManager(ConstNetworkEntityHandle entityHandle, const HostId& previousOwner); HostId GetEntityAuthorityManager(ConstNetworkEntityHandle entityHandle) const; private: @@ -37,7 +37,7 @@ namespace Multiplayer struct TimeoutData final { TimeoutData() = default; - TimeoutData(ConstNetworkEntityHandle entityHandle, HostId previousOwner); + TimeoutData(ConstNetworkEntityHandle entityHandle, const HostId& previousOwner); ConstNetworkEntityHandle m_entityHandle; HostId m_previousOwner = InvalidHostId; }; diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityHandle.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityHandle.cpp index 6f5819eaa3..6f3bd719e0 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityHandle.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityHandle.cpp @@ -29,9 +29,16 @@ namespace Multiplayer { AZ_Assert(networkEntityTracker, "NetworkEntityTracker is not valid"); NetBindComponent* netBindComponent = m_entity->template FindComponent(); - AZ_Assert(netBindComponent, "No Multiplayer::NetBindComponent"); - m_netBindComponent = netBindComponent; - m_netEntityId = netBindComponent->GetNetEntityId(); + if (netBindComponent != nullptr) + { + AZ_Assert(netBindComponent, "No Multiplayer::NetBindComponent"); + m_netBindComponent = netBindComponent; + m_netEntityId = netBindComponent->GetNetEntityId(); + } + else + { + *this = ConstNetworkEntityHandle(); + } } } diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp index e9866085ae..1ed2c8f6a4 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.cpp @@ -41,7 +41,7 @@ namespace Multiplayer AZ::Interface::Unregister(this); } - void NetworkEntityManager::Initialize(HostId hostId, AZStd::unique_ptr entityDomain) + void NetworkEntityManager::Initialize(const HostId& hostId, AZStd::unique_ptr entityDomain) { m_hostId = hostId; m_entityDomain = AZStd::move(entityDomain); @@ -73,7 +73,7 @@ namespace Multiplayer return &m_multiplayerComponentRegistry; } - HostId NetworkEntityManager::GetHostId() const + const HostId& NetworkEntityManager::GetHostId() const { return m_hostId; } @@ -106,8 +106,6 @@ namespace Multiplayer if (net_DebugCheckNetworkEntityManager) { AZ_Assert(entityHandle.GetNetBindComponent(), "No NetBindComponent found on networked entity"); - [[maybe_unused]] const bool isClientOnlyEntity = false;// (ServerIdFromEntityId(it->first) == InvalidHostId); - AZ_Assert(entityHandle.GetNetBindComponent()->IsNetEntityRoleAuthority() || isClientOnlyEntity, "Trying to delete a proxy entity, this will lead to issues deserializing entity updates"); } m_removeList.push_back(entityHandle.GetNetEntityId()); m_removeEntitiesEvent.Enqueue(AZ::TimeMs{ 0 }); diff --git a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.h b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.h index 804946b882..d3f296b03d 100644 --- a/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.h +++ b/Gems/Multiplayer/Code/Source/NetworkEntity/NetworkEntityManager.h @@ -33,13 +33,13 @@ namespace Multiplayer //! INetworkEntityManager overrides. //! @{ - void Initialize(HostId hostId, AZStd::unique_ptr entityDomain) override; + void Initialize(const HostId& hostId, AZStd::unique_ptr entityDomain) override; bool IsInitialized() const override; IEntityDomain* GetEntityDomain() const override; NetworkEntityTracker* GetNetworkEntityTracker() override; NetworkEntityAuthorityTracker* GetNetworkEntityAuthorityTracker() override; MultiplayerComponentRegistry* GetMultiplayerComponentRegistry() override; - HostId GetHostId() const override; + const HostId& GetHostId() const override; ConstNetworkEntityHandle GetEntity(NetEntityId netEntityId) const override; NetEntityId GetNetEntityIdById(const AZ::EntityId& entityId) const override; diff --git a/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.cpp b/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.cpp index b37f485ff4..9e69d93e16 100644 --- a/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.cpp +++ b/Gems/Multiplayer/Code/Source/NetworkTime/NetworkTime.cpp @@ -105,7 +105,7 @@ namespace Multiplayer if (visEntry->m_typeFlags & AzFramework::VisibilityEntry::TypeFlags::TYPE_Entity) { AZ::Entity* entity = static_cast(visEntry->m_userData); - const AZ::Aabb currentBounds = entityBoundsUnion->GetEntityLocalBoundsUnion(entity->GetId()); + const AZ::Aabb currentBounds = entityBoundsUnion->GetEntityWorldBoundsUnion(entity->GetId()); const AZ::Vector3 currentCenter = currentBounds.GetCenter(); NetworkTransformComponent* networkTransform = entity->template FindComponent();