Changes to get client migration partially functional
Signed-off-by: kberg-amzn <karlberg@amazon.com>
This commit is contained in:
+34
-6
@@ -47,8 +47,9 @@ namespace Multiplayer
|
||||
, m_entityExitDomainEventHandler([this](const ConstNetworkEntityHandle& entityHandle) { OnEntityExitDomain(entityHandle); })
|
||||
, m_notifyEntityMigrationHandler([this](const ConstNetworkEntityHandle& entityHandle, const HostId& remoteHostId) { OnPostEntityMigration(entityHandle, remoteHostId); })
|
||||
{
|
||||
// Set up our remote host identifier, we use the IP address of the host
|
||||
// Set up our remote host identifier, by default we use the IP address of the remote host
|
||||
m_remoteHostId = connection.GetRemoteAddress();
|
||||
m_migrateHostId = m_remoteHostId;
|
||||
|
||||
// Our max payload size is whatever is passed in, minus room for a udp packetheader
|
||||
m_maxPayloadSize = connection.GetConnectionMtu() - UdpPacketHeaderSerializeSize - ReplicationManagerPacketOverhead;
|
||||
@@ -65,7 +66,21 @@ namespace Multiplayer
|
||||
networkEntityManager->AddEntityExitDomainHandler(m_entityExitDomainEventHandler);
|
||||
}
|
||||
|
||||
GetMultiplayer()->AddNotifyEntityMigrationEventHandler(m_notifyEntityMigrationHandler);
|
||||
if (m_updateMode == Mode::LocalServerToRemoteServer)
|
||||
{
|
||||
GetMultiplayer()->AddNotifyEntityMigrationEventHandler(m_notifyEntityMigrationHandler);
|
||||
}
|
||||
}
|
||||
|
||||
void EntityReplicationManager::SetMigrateHostId(const HostId& remoteHostId)
|
||||
{
|
||||
// Allows overriding the remote HostId
|
||||
m_migrateHostId = remoteHostId;
|
||||
}
|
||||
|
||||
const HostId& EntityReplicationManager::GetMigrateHostId() const
|
||||
{
|
||||
return m_migrateHostId;
|
||||
}
|
||||
|
||||
const HostId& EntityReplicationManager::GetRemoteHostId() const
|
||||
@@ -362,15 +377,28 @@ namespace Multiplayer
|
||||
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
|
||||
bool changedLocalRole(false);
|
||||
if (AZ::Entity* localEnt = entityReplicator->GetEntityHandle().GetEntity())
|
||||
NetBindComponent* netBindComponent = entityReplicator->GetEntityHandle().GetNetBindComponent();
|
||||
if (netBindComponent != nullptr)
|
||||
{
|
||||
NetBindComponent* netBindComponent = entityReplicator->GetEntityHandle().GetNetBindComponent();
|
||||
AZ_Assert(netBindComponent != nullptr, "No NetBindComponent");
|
||||
changedLocalRole = (netBindComponent->GetNetEntityRole() != entityReplicator->GetBoundLocalNetworkRole());
|
||||
}
|
||||
|
||||
if (changedRemoteRole || changedLocalRole)
|
||||
{
|
||||
const uint32_t intEntityId = static_cast<uint32_t>(netBindComponent->GetNetEntityId());
|
||||
if (changedLocalRole)
|
||||
{
|
||||
const char* oldRoleString = GetEnumString(entityReplicator->GetRemoteNetworkRole());
|
||||
const char* newRoleString = GetEnumString(remoteNetworkRole);
|
||||
AZLOG(NET_ReplicatorRoles, "Replicator %u changed local role, old role = %s, new role = %s", intEntityId, oldRoleString, newRoleString);
|
||||
}
|
||||
if (changedRemoteRole)
|
||||
{
|
||||
const char* oldRoleString = GetEnumString(entityReplicator->GetBoundLocalNetworkRole());
|
||||
const char* newRoleString = GetEnumString(netBindComponent->GetNetEntityRole());
|
||||
AZLOG(NET_ReplicatorRoles, "Replicator %u changed remote role, old role = %s, new role = %s", intEntityId, oldRoleString, newRoleString);
|
||||
}
|
||||
|
||||
// If we changed roles, we need to reset everything
|
||||
if (!entityReplicator->IsMarkedForRemoval())
|
||||
{
|
||||
@@ -1107,7 +1135,7 @@ namespace Multiplayer
|
||||
|
||||
if (m_updateMode == EntityReplicationManager::Mode::LocalServerToRemoteServer)
|
||||
{
|
||||
netBindComponent->NotifyServerMigration(GetRemoteHostId(), GetConnection().GetConnectionId());
|
||||
netBindComponent->NotifyServerMigration(GetRemoteHostId(), GetMigrateHostId(), GetConnection().GetConnectionId());
|
||||
}
|
||||
|
||||
bool didSucceed = true;
|
||||
|
||||
@@ -176,7 +176,6 @@ namespace Multiplayer
|
||||
switch (GetBoundLocalNetworkRole())
|
||||
{
|
||||
case NetEntityRole::Authority:
|
||||
{
|
||||
if (GetRemoteNetworkRole() == NetEntityRole::Client || GetRemoteNetworkRole() == NetEntityRole::Autonomous)
|
||||
{
|
||||
m_onSendRpcHandler.Connect(netBindComponent->GetSendAuthorityToClientRpcEvent());
|
||||
@@ -189,10 +188,8 @@ namespace Multiplayer
|
||||
{
|
||||
m_onForwardRpcHandler.Connect(netBindComponent->GetSendAuthorityToClientRpcEvent());
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case NetEntityRole::Server:
|
||||
{
|
||||
if (GetRemoteNetworkRole() == NetEntityRole::Authority)
|
||||
{
|
||||
m_onSendRpcHandler.Connect(netBindComponent->GetSendServerToAuthorityRpcEvent());
|
||||
@@ -204,23 +201,21 @@ namespace Multiplayer
|
||||
// Listen for these to forward the rpc along to the other Client replicators
|
||||
m_onSendRpcHandler.Connect(netBindComponent->GetSendAuthorityToClientRpcEvent());
|
||||
}
|
||||
// NOTE: e_Autonomous is not connected to e_ServerProxy, it is always connected to an e_Authority
|
||||
AZ_Assert(GetRemoteNetworkRole() != NetEntityRole::Autonomous, "Unexpected autonomous remote role")
|
||||
}
|
||||
break;
|
||||
else if (GetRemoteNetworkRole() == NetEntityRole::Autonomous)
|
||||
{
|
||||
// NOTE: Autonomous is not connected to ServerProxy, it is always connected to an Authority
|
||||
AZ_Assert(false, "Unexpected autonomous remote role")
|
||||
}
|
||||
break;
|
||||
case NetEntityRole::Client:
|
||||
{
|
||||
// Nothing allowed, no Client to Server communication
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case NetEntityRole::Autonomous:
|
||||
{
|
||||
if (GetRemoteNetworkRole() == NetEntityRole::Authority)
|
||||
{
|
||||
m_onSendRpcHandler.Connect(netBindComponent->GetSendAutonomousToAuthorityRpcEvent());
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
AZ_Assert(false, "Unexpected network role");
|
||||
}
|
||||
@@ -255,19 +250,6 @@ namespace Multiplayer
|
||||
AZLOG_WARN("Trying to activate an entity that is not in the Init state (%u)", GetEntityHandle().GetNetEntityId());
|
||||
}
|
||||
|
||||
// First we need to make sure the transform component has been updated with the correct value prior to activation
|
||||
// This is because vanilla az components may only depend on the transform component, not the multiplayer transform component
|
||||
//if (auto* locationComponent = FindCommonComponent<LocationComponent::Common>(GetEntityHandle()))
|
||||
//{
|
||||
// AZ::Transform newTransform = locationComponent->GetTransform();
|
||||
// auto* transformComponent = entity->FindComponent<AzFramework::TransformComponent>();
|
||||
// if (transformComponent)
|
||||
// {
|
||||
// // We can't use EBus here since the TransFormBus does not get connected until the activate call below
|
||||
// transformComponent->SetWorldTM(newTransform);
|
||||
// }
|
||||
//}
|
||||
// Ugly, but this is the only time we need to call a non-const function on this entity
|
||||
entity->Activate();
|
||||
|
||||
m_replicationManager.m_orphanedEntityRpcs.DispatchOrphanedRpcs(*this);
|
||||
@@ -281,8 +263,7 @@ namespace Multiplayer
|
||||
NetBindComponent* netBindComponent = m_netBindComponent;
|
||||
AZ_Assert(netBindComponent, "No Multiplayer::NetBindComponent");
|
||||
|
||||
bool isAuthority = (GetBoundLocalNetworkRole() == NetEntityRole::Authority)
|
||||
&& (GetBoundLocalNetworkRole() == netBindComponent->GetNetEntityRole());
|
||||
bool isAuthority = (GetBoundLocalNetworkRole() == NetEntityRole::Authority) && (GetBoundLocalNetworkRole() == netBindComponent->GetNetEntityRole());
|
||||
bool isClient = GetRemoteNetworkRole() == NetEntityRole::Client;
|
||||
bool isAutonomous = GetBoundLocalNetworkRole() == NetEntityRole::Autonomous;
|
||||
if (isAuthority || isClient || isAutonomous)
|
||||
@@ -428,10 +409,8 @@ namespace Multiplayer
|
||||
if (const NetworkTransformComponent* networkTransform = entity->FindComponent<NetworkTransformComponent>())
|
||||
{
|
||||
const NetEntityId parentId = networkTransform->GetParentEntityId();
|
||||
/*
|
||||
* For root entities attached to a level, a network parent won't be set.
|
||||
* In this case, this entity is the root entity of the hierarchy and it will be activated first.
|
||||
*/
|
||||
// For root entities attached to a level, a network parent won't be set.
|
||||
// In this case, this entity is the root entity of the hierarchy and it will be activated first.
|
||||
if (parentId != InvalidNetEntityId)
|
||||
{
|
||||
ConstNetworkEntityHandle parentHandle = GetNetworkEntityManager()->GetEntity(parentId);
|
||||
@@ -552,42 +531,33 @@ namespace Multiplayer
|
||||
switch (entityRpcMessage.GetRpcDeliveryType())
|
||||
{
|
||||
case RpcDeliveryType::AuthorityToClient:
|
||||
{
|
||||
if (((GetBoundLocalNetworkRole() == NetEntityRole::Client) || (GetBoundLocalNetworkRole() == NetEntityRole::Autonomous))
|
||||
&& (GetRemoteNetworkRole() == NetEntityRole::Authority))
|
||||
{
|
||||
// We are a local client, and we are connected to server, aka AuthorityToClient
|
||||
result = RpcValidationResult::HandleRpc;
|
||||
}
|
||||
if ((GetBoundLocalNetworkRole() == NetEntityRole::Server)
|
||||
&& (GetRemoteNetworkRole() == NetEntityRole::Authority))
|
||||
if ((GetBoundLocalNetworkRole() == NetEntityRole::Server) && (GetRemoteNetworkRole() == NetEntityRole::Authority))
|
||||
{
|
||||
// We are on a server, and we received this message from another server, therefore we should forward this to any connected clients
|
||||
result = RpcValidationResult::ForwardToClient;
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case RpcDeliveryType::AuthorityToAutonomous:
|
||||
{
|
||||
if ((GetBoundLocalNetworkRole() == NetEntityRole::Autonomous)
|
||||
&& (GetRemoteNetworkRole() == NetEntityRole::Authority))
|
||||
if ((GetBoundLocalNetworkRole() == NetEntityRole::Autonomous) && (GetRemoteNetworkRole() == NetEntityRole::Authority))
|
||||
{
|
||||
// We are an autonomous client, and we are connected to server, aka AuthorityToAutonomous
|
||||
result = RpcValidationResult::HandleRpc;
|
||||
}
|
||||
if ((GetBoundLocalNetworkRole() == NetEntityRole::Authority)
|
||||
&& (GetRemoteNetworkRole() == NetEntityRole::Server))
|
||||
if ((GetBoundLocalNetworkRole() == NetEntityRole::Authority) && (GetRemoteNetworkRole() == NetEntityRole::Server))
|
||||
{
|
||||
// We are on a server, and we received this message from another server, therefore we should forward this to our autonomous player
|
||||
// This can occur if we've recently migrated
|
||||
result = RpcValidationResult::ForwardToAutonomous;
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case RpcDeliveryType::AutonomousToAuthority:
|
||||
{
|
||||
if ((GetBoundLocalNetworkRole() == NetEntityRole::Authority)
|
||||
&& (GetRemoteNetworkRole() == NetEntityRole::Autonomous))
|
||||
if ((GetBoundLocalNetworkRole() == NetEntityRole::Authority) && (GetRemoteNetworkRole() == NetEntityRole::Autonomous))
|
||||
{
|
||||
if (IsMarkedForRemoval())
|
||||
{
|
||||
@@ -609,12 +579,9 @@ namespace Multiplayer
|
||||
result = RpcValidationResult::HandleRpc;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case RpcDeliveryType::ServerToAuthority:
|
||||
{
|
||||
if ((GetBoundLocalNetworkRole() == NetEntityRole::Authority)
|
||||
&& (GetRemoteNetworkRole() == NetEntityRole::Server))
|
||||
if ((GetBoundLocalNetworkRole() == NetEntityRole::Authority) && (GetRemoteNetworkRole() == NetEntityRole::Server))
|
||||
{
|
||||
// if we're marked for removal, then we should forward to whomever now owns this entity
|
||||
if (IsMarkedForRemoval())
|
||||
@@ -637,9 +604,9 @@ namespace Multiplayer
|
||||
result = RpcValidationResult::HandleRpc;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (result == RpcValidationResult::DropRpcAndDisconnect)
|
||||
{
|
||||
bool isLocalServer = (GetBoundLocalNetworkRole() == NetEntityRole::Authority) || (GetBoundLocalNetworkRole() == NetEntityRole::Server);
|
||||
@@ -653,30 +620,29 @@ namespace Multiplayer
|
||||
{
|
||||
AZLOG_ERROR
|
||||
(
|
||||
"Dropping RPC and Connection EntityId=%u LocalRole=%u RemoteRole=%u RpcDeliveryType=%u ComponentId=%u RpcType=%u IsReliable=%s IsMarkedForRemoval=%s",
|
||||
"Dropping RPC and Connection EntityId=%u LocalRole=%s RemoteRole=%s RpcDeliveryType=%u RpcName=%s IsReliable=%s IsMarkedForRemoval=%s",
|
||||
aznumeric_cast<uint32_t>(m_entityHandle.GetNetEntityId()),
|
||||
aznumeric_cast<uint32_t>(GetBoundLocalNetworkRole()),
|
||||
aznumeric_cast<uint32_t>(GetRemoteNetworkRole()),
|
||||
GetEnumString(GetBoundLocalNetworkRole()),
|
||||
GetEnumString(GetRemoteNetworkRole()),
|
||||
aznumeric_cast<uint32_t>(entityRpcMessage.GetRpcDeliveryType()),
|
||||
aznumeric_cast<uint32_t>(entityRpcMessage.GetComponentId()),
|
||||
aznumeric_cast<uint32_t>(entityRpcMessage.GetRpcIndex()),
|
||||
GetMultiplayerComponentRegistry()->GetComponentRpcName(entityRpcMessage.GetComponentId(), entityRpcMessage.GetRpcIndex()),
|
||||
entityRpcMessage.GetReliability() == ReliabilityType::Reliable ? "true" : "false",
|
||||
IsMarkedForRemoval() ? "true" : "false"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (result == RpcValidationResult::DropRpc)
|
||||
{
|
||||
AZLOG
|
||||
(
|
||||
NET_Rpc,
|
||||
"Dropping RPC EntityId=%u LocalRole=%u RemoteRole=%u RpcDeliveryType=%u ComponentId=%u RpcType=%u IsReliable=%s IsMarkedForRemoval=%s",
|
||||
"Dropping RPC EntityId=%u LocalRole=%s RemoteRole=%s RpcDeliveryType=%u RpcName=%s IsReliable=%s IsMarkedForRemoval=%s",
|
||||
aznumeric_cast<uint32_t>(m_entityHandle.GetNetEntityId()),
|
||||
aznumeric_cast<uint32_t>(GetBoundLocalNetworkRole()),
|
||||
aznumeric_cast<uint32_t>(GetRemoteNetworkRole()),
|
||||
GetEnumString(GetBoundLocalNetworkRole()),
|
||||
GetEnumString(GetRemoteNetworkRole()),
|
||||
aznumeric_cast<uint32_t>(entityRpcMessage.GetRpcDeliveryType()),
|
||||
aznumeric_cast<uint32_t>(entityRpcMessage.GetComponentId()),
|
||||
aznumeric_cast<uint32_t>(entityRpcMessage.GetRpcIndex()),
|
||||
GetMultiplayerComponentRegistry()->GetComponentRpcName(entityRpcMessage.GetComponentId(), entityRpcMessage.GetRpcIndex()),
|
||||
entityRpcMessage.GetReliability() == ReliabilityType::Reliable ? "true" : "false",
|
||||
IsMarkedForRemoval() ? "true" : "false"
|
||||
);
|
||||
@@ -695,13 +661,12 @@ namespace Multiplayer
|
||||
{
|
||||
AZLOG_WARN
|
||||
(
|
||||
"Dropping RPC since entity deleted EntityId=%u LocalRole=%u RemoteRole=%u RpcDeliveryType=%u ComponentId=%u RpcType=%u IsReliable=%s IsMarkedForRemoval=%s",
|
||||
"Dropping RPC since entity deleted EntityId=%u LocalRole=%s RemoteRole=%s RpcDeliveryType=%u RpcName=%s IsReliable=%s IsMarkedForRemoval=%s",
|
||||
aznumeric_cast<uint32_t>(m_entityHandle.GetNetEntityId()),
|
||||
aznumeric_cast<uint32_t>(GetBoundLocalNetworkRole()),
|
||||
aznumeric_cast<uint32_t>(GetRemoteNetworkRole()),
|
||||
GetEnumString(GetBoundLocalNetworkRole()),
|
||||
GetEnumString(GetRemoteNetworkRole()),
|
||||
aznumeric_cast<uint32_t>(entityRpcMessage.GetRpcDeliveryType()),
|
||||
aznumeric_cast<uint32_t>(entityRpcMessage.GetComponentId()),
|
||||
aznumeric_cast<uint32_t>(entityRpcMessage.GetRpcIndex()),
|
||||
GetMultiplayerComponentRegistry()->GetComponentRpcName(entityRpcMessage.GetComponentId(), entityRpcMessage.GetRpcIndex()),
|
||||
entityRpcMessage.GetReliability() == ReliabilityType::Reliable ? "true" : "false",
|
||||
IsMarkedForRemoval() ? "true" : "false"
|
||||
);
|
||||
@@ -739,23 +704,23 @@ namespace Multiplayer
|
||||
case RpcValidationResult::DropRpcAndDisconnect:
|
||||
return false;
|
||||
case RpcValidationResult::ForwardToClient:
|
||||
{
|
||||
ScopedForwardingMessage forwarding(*this);
|
||||
m_netBindComponent->GetSendAuthorityToClientRpcEvent().Signal(entityRpcMessage);
|
||||
{
|
||||
ScopedForwardingMessage forwarding(*this);
|
||||
m_netBindComponent->GetSendAuthorityToClientRpcEvent().Signal(entityRpcMessage);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case RpcValidationResult::ForwardToAutonomous:
|
||||
{
|
||||
ScopedForwardingMessage forwarding(*this);
|
||||
m_netBindComponent->GetSendAuthorityToAutonomousRpcEvent().Signal(entityRpcMessage);
|
||||
{
|
||||
ScopedForwardingMessage forwarding(*this);
|
||||
m_netBindComponent->GetSendAuthorityToAutonomousRpcEvent().Signal(entityRpcMessage);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case RpcValidationResult::ForwardToAuthority:
|
||||
{
|
||||
ScopedForwardingMessage forwarding(*this);
|
||||
m_netBindComponent->GetSendServerToAuthorityRpcEvent().Signal(entityRpcMessage);
|
||||
{
|
||||
ScopedForwardingMessage forwarding(*this);
|
||||
m_netBindComponent->GetSendServerToAuthorityRpcEvent().Signal(entityRpcMessage);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user