Changes to make client and entity migration functional, needed in the event of a host quitting necessitating a host migration

Signed-off-by: kberg-amzn <karlberg@amazon.com>
This commit is contained in:
kberg-amzn
2021-09-17 16:48:16 -07:00
parent 7dc930b444
commit 6e84495975
34 changed files with 424 additions and 121 deletions
@@ -6,8 +6,8 @@
*
*/
#include <Source/NetworkEntity/EntityReplication/EntityReplicationManager.h>
#include <Source/NetworkEntity/EntityReplication/EntityReplicator.h>
#include <Multiplayer/NetworkEntity/EntityReplication/EntityReplicationManager.h>
#include <Multiplayer/NetworkEntity/EntityReplication/EntityReplicator.h>
#include <Source/NetworkEntity/EntityReplication/PropertyPublisher.h>
#include <Source/NetworkEntity/EntityReplication/PropertySubscriber.h>
#include <Source/AutoGen/Multiplayer.AutoPackets.h>
@@ -444,6 +444,11 @@ namespace Multiplayer
handler.Connect(m_autonomousEntityReplicatorCreated);
}
void EntityReplicationManager::AddSendMigrateEntityEventHandler(SendMigrateEntityEvent::Handler& handler)
{
handler.Connect(m_sendMigrateEntityEvent);
}
const EntityReplicator* EntityReplicationManager::GetEntityReplicator(NetEntityId netEntityId) const
{
auto it = m_entityReplicatorMap.find(netEntityId);
@@ -1094,7 +1099,7 @@ namespace Multiplayer
bool didSucceed = true;
EntityMigrationMessage message;
message.m_entityId = replicator->GetEntityHandle().GetNetEntityId();
message.m_netEntityId = replicator->GetEntityHandle().GetNetEntityId();
message.m_prefabEntityId = netBindComponent->GetPrefabEntityId();
if (localEnt->GetState() == AZ::Entity::State::Active)
@@ -1119,8 +1124,8 @@ namespace Multiplayer
message.m_propertyUpdateData.Resize(inputSerializer.GetSize());
}
AZ_Assert(didSucceed, "Failed to migrate entity from server");
// TODO: Move this to an event
//m_connection.SendReliablePacket(message);
m_sendMigrateEntityEvent.Signal(m_connection, message);
AZLOG(NET_RepDeletes, "Migration packet sent %u to remote manager id %d", netEntityId, aznumeric_cast<int32_t>(GetRemoteHostId()));
// 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
@@ -1130,7 +1135,7 @@ namespace Multiplayer
bool EntityReplicationManager::HandleEntityMigration(AzNetworking::IConnection* invokingConnection, EntityMigrationMessage& message)
{
EntityReplicator* replicator = GetEntityReplicator(message.m_entityId);
EntityReplicator* replicator = GetEntityReplicator(message.m_netEntityId);
{
if (message.m_propertyUpdateData.GetSize() > 0)
{
@@ -1140,7 +1145,7 @@ namespace Multiplayer
invokingConnection,
replicator,
AzNetworking::InvalidPacketId,
message.m_entityId,
message.m_netEntityId,
NetEntityRole::Server,
outputSerializer,
message.m_prefabEntityId
@@ -1154,7 +1159,7 @@ namespace Multiplayer
// The HandlePropertyChangeMessage will have made a replicator if we didn't have one already
if (!replicator)
{
replicator = GetEntityReplicator(message.m_entityId);
replicator = GetEntityReplicator(message.m_netEntityId);
}
AZ_Assert(replicator, "Do not have replicator after handling migration message");
@@ -8,7 +8,7 @@
#pragma once
#include <Source/NetworkEntity/EntityReplication/EntityReplicator.h>
#include <Multiplayer/NetworkEntity/EntityReplication/EntityReplicator.h>
#include <Multiplayer/Components/NetBindComponent.h>
#include <Multiplayer/EntityDomains/IEntityDomain.h>
#include <Multiplayer/NetworkEntity/INetworkEntityManager.h>
@@ -6,8 +6,8 @@
*
*/
#include <Source/NetworkEntity/EntityReplication/EntityReplicator.h>
#include <Source/NetworkEntity/EntityReplication/EntityReplicationManager.h>
#include <Multiplayer/NetworkEntity/EntityReplication/EntityReplicator.h>
#include <Multiplayer/NetworkEntity/EntityReplication/EntityReplicationManager.h>
#include <Source/NetworkEntity/EntityReplication/PropertyPublisher.h>
#include <Source/NetworkEntity/EntityReplication/PropertySubscriber.h>
#include <Source/NetworkEntity/NetworkEntityAuthorityTracker.h>
@@ -1,142 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/EBus/Event.h>
#include <AzCore/EBus/ScheduledEvent.h>
#include <AzCore/Component/Entity.h>
#include <AzCore/Component/EntityBus.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <AzCore/std/containers/ring_buffer.h>
#include <Multiplayer/Components/NetBindComponent.h>
#include <Multiplayer/NetworkEntity/NetworkEntityUpdateMessage.h>
namespace AzNetworking
{
class IConnection;
}
namespace Multiplayer
{
class EntityReplicationManager;
class NetworkEntityRpcMessage;
class NetBindComponent;
class PropertyPublisher;
class PropertySubscriber;
class EntityReplicator final
: public AZ::EntityBus::Handler
{
public:
EntityReplicator(EntityReplicationManager& replicationManager, AzNetworking::IConnection* connection, NetEntityRole remoteNetworkRole, const ConstNetworkEntityHandle& entityHandle);
virtual ~EntityReplicator();
NetEntityRole GetBoundLocalNetworkRole() const;
NetEntityRole GetRemoteNetworkRole() const;
ConstNetworkEntityHandle GetEntityHandle() const;
NetBindComponent* GetNetBindComponent();
void ActivateNetworkEntity();
const PrefabEntityId& GetPrefabEntityId() const;
bool IsPrefabEntityIdSet() const;
bool OwnsReplicatorLifetime() const;
bool RemoteManagerOwnsEntityLifetime() const;
// Interface for ReplicationManager to modify state of replication
void Initialize(const ConstNetworkEntityHandle& entityHandle);
void Reset(NetEntityRole remoteNetworkRole);
void MarkForRemoval();
bool IsMarkedForRemoval() const;
void SetPendingRemoval(AZ::TimeMs pendingRemovalTimeMs);
bool IsPendingRemoval() const;
void ClearPendingRemoval();
bool IsDeletionAcknowledged() const;
bool WasMigrated() const;
void SetWasMigrated(bool wasMigrated);
NetworkEntityUpdateMessage GenerateUpdatePacket();
AZ::TimeMs GetResendTimeoutTimeMs() const;
PropertyPublisher* GetPropertyPublisher();
const PropertyPublisher* GetPropertyPublisher() const;
PropertySubscriber* GetPropertySubscriber();
// Handlers for Rpc messages
bool HandleRpcMessage(AzNetworking::IConnection* invokingConnection, NetworkEntityRpcMessage& entityRpcMessage);
//! AZ::EntityBus overrides
//! @{
void OnEntityActivated(const AZ::EntityId&) override;
void OnEntityDestroyed(const AZ::EntityId&) override;
//! @}
private:
enum class RpcValidationResult
{
HandleRpc, // Handle Rpc message
DropRpc, // Do not handle Rpc
DropRpcAndDisconnect, // Do not handle the Rpc, it is disallowed from this endpoint we should disconnect the connection
ForwardToClient, // Forward this message to the Client
ForwardToAutonomous, // Forward this message to the Autonomous
ForwardToAuthority, // Forward this message to the Authority
};
RpcValidationResult ValidateRpcMessage(const NetworkEntityRpcMessage& entityRpcMessage) const;
// Internal state tracking
bool CanSendUpdates();
void SetPrefabEntityId(const PrefabEntityId& prefabEntityId); // cache assetId so authority doesn't need to keep sending it
// Event processing
void OnSendRpcEvent(NetworkEntityRpcMessage& message);
void OnForwardRpcEvent(NetworkEntityRpcMessage& message);
void OnEntityDirtiedEvent();
void OnEntityRemovedEvent();
void OnProxyRemovalTimedEvent();
void ActivateNetworkEntityInternal();
void AttachRPCHandlers();
void DeferRpcMessage(NetworkEntityRpcMessage& message);
AZ_DISABLE_COPY_MOVE(EntityReplicator);
// Events
RpcSendEvent::Handler m_onSendRpcHandler;
RpcSendEvent::Handler m_onForwardRpcHandler;
RpcSendEvent::Handler m_onSendAutonomousRpcHandler;
RpcSendEvent::Handler m_onForwardAutonomousRpcHandler;
EntityDirtiedEvent::Handler m_onEntityDirtiedHandler;
EntityStopEvent::Handler m_onEntityStopHandler;
AZ::ScheduledEvent m_proxyRemovalEvent;
ConstNetworkEntityHandle m_entityHandle;
PrefabEntityId m_prefabEntityId;
AZStd::unique_ptr<PropertyPublisher> m_propertyPublisher;
AZStd::unique_ptr<PropertySubscriber> m_propertySubscriber;
NetBindComponent* m_netBindComponent = nullptr;
EntityReplicationManager& m_replicationManager;
AzNetworking::IConnection* m_connection;
NetEntityRole m_boundLocalNetworkRole;
NetEntityRole m_remoteNetworkRole;
bool m_wasMigrated = false;
bool m_isForwardingRpc = false;
bool m_prefabEntityIdSet = false;
};
}
#include <Source/NetworkEntity/EntityReplication/EntityReplicator.inl>
@@ -1,68 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
namespace Multiplayer
{
inline NetEntityRole EntityReplicator::GetBoundLocalNetworkRole() const
{
return m_boundLocalNetworkRole;
}
inline NetEntityRole EntityReplicator::GetRemoteNetworkRole() const
{
return m_remoteNetworkRole;
}
inline ConstNetworkEntityHandle EntityReplicator::GetEntityHandle() const
{
return m_entityHandle;
}
inline NetBindComponent* EntityReplicator::GetNetBindComponent()
{
return m_netBindComponent;
}
inline const PrefabEntityId& EntityReplicator::GetPrefabEntityId() const
{
AZ_Assert(IsPrefabEntityIdSet(), "PrefabEntityId not set for Entity");
return m_prefabEntityId;
}
inline bool EntityReplicator::IsPrefabEntityIdSet() const
{
return m_prefabEntityIdSet;
}
inline bool EntityReplicator::WasMigrated() const
{
return m_wasMigrated;
}
inline void EntityReplicator::SetWasMigrated(bool wasMigrated)
{
m_wasMigrated = wasMigrated;
}
inline PropertyPublisher* EntityReplicator::GetPropertyPublisher()
{
return m_propertyPublisher.get();
}
inline const PropertyPublisher* EntityReplicator::GetPropertyPublisher() const
{
return m_propertyPublisher.get();
}
inline PropertySubscriber* EntityReplicator::GetPropertySubscriber()
{
return m_propertySubscriber.get();
}
}
@@ -7,7 +7,7 @@
*/
#include <Source/NetworkEntity/EntityReplication/PropertySubscriber.h>
#include <Source/NetworkEntity/EntityReplication/EntityReplicationManager.h>
#include <Multiplayer/NetworkEntity/EntityReplication/EntityReplicationManager.h>
#include <Multiplayer/Components/NetBindComponent.h>
namespace Multiplayer