Reverts changes to component application and adds further client migration handling hookup

Signed-off-by: kberg-amzn <karlberg@amazon.com>
This commit is contained in:
kberg-amzn
2021-09-21 19:33:59 -07:00
parent ca7de715fd
commit d28bcbe027
8 changed files with 120 additions and 92 deletions
@@ -45,6 +45,7 @@ namespace Multiplayer
using ClientMigrationStartEvent = AZ::Event<ClientInputId>;
using ClientMigrationEndEvent = AZ::Event<>;
using ClientDisconnectedEvent = AZ::Event<>;
using NotifyClientMigrationEvent = AZ::Event<HostId, uint64_t, ClientInputId>;
using ConnectionAcquiredEvent = AZ::Event<MultiplayerAgentDatum>;
using SessionInitEvent = AZ::Event<AzNetworking::INetworkInterface*>;
using SessionShutdownEvent = AZ::Event<AzNetworking::INetworkInterface*>;
@@ -80,34 +81,38 @@ namespace Multiplayer
//! @param state The state of this connection
virtual void InitializeMultiplayer(MultiplayerAgentType state) = 0;
//! Starts hosting a server
//! Starts hosting a server.
//! @param port The port to listen for connection on
//! @param isDedicated Whether the server is dedicated or client hosted
//! @return if the application successfully started hosting
virtual bool StartHosting(uint16_t port, bool isDedicated = true) = 0;
//! Connects to the specified IP as a Client
//! Connects to the specified IP as a Client.
//! @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;
// Disconnects all multiplayer connections, stops listening on the server and invokes handlers appropriate to network context
// Disconnects all multiplayer connections, stops listening on the server and invokes handlers appropriate to network context.
//! @param reason The reason for terminating connections
virtual void Terminate(AzNetworking::DisconnectReason reason) = 0;
//! Adds a ClientMigrationStartEvent Handler which is invoked at the start of a client migration
//! Adds a ClientMigrationStartEvent Handler which is invoked at the start of a client migration.
//! @param handler The ClientMigrationStartEvent Handler to add
virtual void AddClientMigrationStartEventHandler(ClientMigrationStartEvent::Handler& handler) = 0;
//! Adds a ClientMigrationEndEvent Handler which is invoked when a client completes migration
//! Adds a ClientMigrationEndEvent Handler which is invoked when a client completes migration.
//! @param handler The ClientMigrationEndEvent Handler to add
virtual void AddClientMigrationEndEventHandler(ClientMigrationEndEvent::Handler& handler) = 0;
//! Adds a ClientDisconnectedEvent Handler which is invoked on the client when a disconnection occurs
//! Adds a ClientDisconnectedEvent Handler which is invoked on the client when a disconnection occurs.
//! @param handler The ClientDisconnectedEvent Handler to add
virtual void AddClientDisconnectedHandler(ClientDisconnectedEvent::Handler& handler) = 0;
//! Adds a NotifyClientMigrationEvent Handler which is invoked when a client migrates from one host to another.
//! @param handler The NotifyClientMigrationEvent Handler to add
virtual void AddNotifyClientMigrationHandler(NotifyClientMigrationEvent::Handler& handler) = 0;
//! Adds a ConnectionAcquiredEvent Handler which is invoked when a new endpoint connects to the session.
//! @param handler The ConnectionAcquiredEvent Handler to add
virtual void AddConnectionAcquiredHandler(ConnectionAcquiredEvent::Handler& handler) = 0;
@@ -120,7 +125,13 @@ namespace Multiplayer
//! @param handler The SessionShutdownEvent handler to add
virtual void AddSessionShutdownHandler(SessionShutdownEvent::Handler& handler) = 0;
//! Sends a packet telling if entity update messages can be sent
//! Signals a NotifyClientMigrationEvent with the provided parameters.
//! @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);
//! Sends a packet telling if entity update messages can be sent.
//! @param readyForEntityUpdates Ready for entity updates or not
virtual void SendReadyForEntityUpdates(bool readyForEntityUpdates) = 0;
@@ -132,7 +143,7 @@ namespace Multiplayer
//! @return the current server time in milliseconds
virtual AZ::TimeMs GetCurrentHostTimeMs() const = 0;
//! Returns the current blend factor for client side interpolation
//! Returns the current blend factor for client side interpolation.
//! This value is only relevant on the client and is used to smooth between host frames
//! @return the current blend factor
virtual float GetCurrentBlendFactor() const = 0;
@@ -403,6 +403,8 @@ namespace {{ Component.attrib['Namespace'] }}
: public Multiplayer::MultiplayerController
{
public:
using ComponentType = {{ ComponentName }};
{{ ControllerBaseName }}({{ ComponentName }}& owner);
~{{ ControllerBaseName }}() override = default;
@@ -40,8 +40,8 @@
</Packet>
<Packet Name="ClientMigration" Desc="Tell a client to migrate to a new server">
<Member Type="uint64_t" Name="temporaryUserIdentifier" Init="0" />
<Member Type="AzNetworking::IpAddress" Name="remoteServerAddress" Init="AzNetworking::IpAddress()" />
<Member Type="AZ::TimeMs" Name="lastInputGameTimeMs" Init="AZ::TimeMs{ 0 }" />
<Member Type="AzNetworking::IpAddress" Name="remoteServerAddress" Init="AzNetworking::IpAddress()" />
<Member Type="uint64_t" Name="temporaryUserIdentifier" Init="0" />
<Member Type="Multiplayer::ClientInputId" Name="lastClientInputId" Init="Multiplayer::ClientInputId{ 0 }" />
</Packet>
</PacketGroup>
@@ -7,7 +7,10 @@
*/
#include <Source/ConnectionData/ServerToClientConnectionData.h>
#include <Source/AutoGen/Multiplayer.AutoPackets.h>
#include <Multiplayer/Components/LocalPredictionPlayerInputComponent.h>
#include <Multiplayer/IMultiplayer.h>
#include <AzNetworking/Utilities/EncryptionCommon.h>
namespace Multiplayer
{
@@ -95,36 +98,31 @@ namespace Multiplayer
[[maybe_unused]] AzNetworking::ConnectionId connectionId
)
{
//Multiplayer::ServerAddrInfo serverAddr;
//if (gNovaGame->GetMultiplayerworkAgent().GetServerToServerNetwork().GetServerAddrInfoFromConnectionId(newConnectionId, serverAddr) == false)
//{
// AZLOG_WARN("MigrateClient::Failed to find servershard address, userID:%d", static_cast<uint32_t>(GetUserId()));
// return;
//}
//
//Multiplayer::GameTimePoint migratedClientGameTimePoint;
//
//if (m_ControlledEntity != nullptr)
//{
// if (const PlayerNetworkInputComponent::Authority* pComponent = Multiplayer::FindController<PlayerNetworkInputComponent::Authority>(m_ControlledEntity))
// {
// migratedClientGameTimePoint = pComponent->GetLastInputId().GetServerGameTimePoint();
// }
//}
//
// generate crypto-rand user identifier, send to both server and client so they can negotiate the autonomous entity to assume predictive control over after migration
//const uint64_t randomUserIdentifier = 0;
//
//// Tell the server a new client is about to join
//MultiplayerPackets::NotifyClientMigration notifyClientMigration(randomUserIdentifier);
//gNovaGame->GetMultiplayerworkAgent().GetServerToServerNetwork().SendReliablePacket(newConnectionId, notifyClientMigration);
//
//// Tell the client who to join
//MultiplayerPackets::ClientMigration clientMigration(randomUserIdentifier, serverAddr, migratedClientGameTimePoint);
//GetConnection()->SendReliablePacket(clientMigration);
//
//m_controlledEntity = nullptr;
//m_canSendUpdates = false;
AzNetworking::IpAddress serverAddress;
// serverAddress = GetHost(remoteHostId).GetAddress();
ClientInputId migratedClientInputId = ClientInputId{ 0 };
if (m_controlledEntity != nullptr)
{
auto controller = m_controlledEntity.FindController<LocalPredictionPlayerInputComponentController>();
if (controller != nullptr)
{
migratedClientInputId = controller->GetLastInputId();
}
}
// Generate crypto-rand user identifier, send to both server and client so they can negotiate the autonomous entity to assume predictive control over after migration
const uint64_t randomUserIdentifier = AzNetworking::CryptoRand64();
// Tell the new host that a client is about to (re)join
GetMultiplayer()->SendNotifyClientMigrationEvent(remoteHostId, randomUserIdentifier, migratedClientInputId);
// Tell the client who to join
MultiplayerPackets::ClientMigration clientMigration(serverAddress, randomUserIdentifier, migratedClientInputId);
GetConnection()->SendReliablePacket(clientMigration);
m_controlledEntity = NetworkEntityHandle();
m_canSendUpdates = false;
}
void ServerToClientConnectionData::OnGameplayStarted()
@@ -617,7 +617,7 @@ namespace Multiplayer
auto visitor = [](IConnection& connection) { connection.Disconnect(DisconnectReason::ClientMigrated, TerminationEndpoint::Local); };
m_networkInterface->GetConnectionSet().VisitConnections(visitor);
AZLOG_INFO("Migrating to new server shard");
//m_clientMigrateStartEvent(packet.GetLastInputGameTimeMs());
m_clientMigrationStartEvent.Signal(ClientInputId{ 0 });
m_networkInterface->Connect(packet.GetRemoteServerAddress());
return true;
}
@@ -795,6 +795,11 @@ namespace Multiplayer
handler.Connect(m_clientDisconnectedEvent);
}
void MultiplayerSystemComponent::AddNotifyClientMigrationHandler(NotifyClientMigrationEvent::Handler& handler)
{
handler.Connect(m_notifyClientMigrationEvent);
}
void MultiplayerSystemComponent::AddConnectionAcquiredHandler(ConnectionAcquiredEvent::Handler& handler)
{
handler.Connect(m_connectionAcquiredEvent);
@@ -810,6 +815,11 @@ namespace Multiplayer
handler.Connect(m_shutdownEvent);
}
void MultiplayerSystemComponent::SendNotifyClientMigrationEvent(HostId hostId, uint64_t userIdentifier, ClientInputId lastClientInputId)
{
m_notifyClientMigrationEvent.Signal(hostId, userIdentifier, lastClientInputId);
}
void MultiplayerSystemComponent::SendReadyForEntityUpdates(bool readyForEntityUpdates)
{
IConnectionSet& connectionSet = m_networkInterface->GetConnectionSet();
@@ -111,9 +111,11 @@ namespace Multiplayer
void AddClientMigrationStartEventHandler(ClientMigrationStartEvent::Handler& handler) override;
void AddClientMigrationEndEventHandler(ClientMigrationEndEvent::Handler& handler) override;
void AddClientDisconnectedHandler(ClientDisconnectedEvent::Handler& handler) override;
void AddNotifyClientMigrationHandler(NotifyClientMigrationEvent::Handler& handler) override;
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 SendReadyForEntityUpdates(bool readyForEntityUpdates) override;
AZ::TimeMs GetCurrentHostTimeMs() const override;
float GetCurrentBlendFactor() const override;
@@ -154,6 +156,7 @@ namespace Multiplayer
ClientDisconnectedEvent m_clientDisconnectedEvent;
ClientMigrationStartEvent m_clientMigrationStartEvent;
ClientMigrationEndEvent m_clientMigrationEndEvent;
NotifyClientMigrationEvent m_notifyClientMigrationEvent;
AZStd::queue<AZStd::string> m_pendingConnectionTickets;