diff --git a/Gems/Multiplayer/Code/Source/AutoGen/Multiplayer.AutoPackets.xml b/Gems/Multiplayer/Code/Source/AutoGen/Multiplayer.AutoPackets.xml
index 3abd2a86d9..ce8931107f 100644
--- a/Gems/Multiplayer/Code/Source/AutoGen/Multiplayer.AutoPackets.xml
+++ b/Gems/Multiplayer/Code/Source/AutoGen/Multiplayer.AutoPackets.xml
@@ -9,16 +9,13 @@
+
-
-
-
-
diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp
index aa5e0d7467..5f44a2cccb 100644
--- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp
+++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp
@@ -199,21 +199,10 @@ namespace Multiplayer
{
AZ::Interface::Get()->InitializeMultiplayer(MultiplayerAgentType::Client);
+ m_pendingConnectionTickets.push(config.m_playerSessionId);
AZStd::string hostname = config.m_dnsName.empty() ? config.m_ipAddress : config.m_dnsName;
const IpAddress ipAddress(hostname.c_str(), config.m_port, m_networkInterface->GetType());
- ConnectionId connectionId = m_networkInterface->Connect(ipAddress);
-
- AzNetworking::IConnection* connection = m_networkInterface->GetConnectionSet().GetConnection(connectionId);
- if (connection->GetUserData() == nullptr) // Only add user data if the connect event handler has not already done so
- {
- connection->SetUserData(new ClientToServerConnectionData(connection, *this, config.m_playerSessionId));
- }
- else
- {
- reinterpret_cast(connection->GetUserData())->SetProviderTicket(config.m_playerSessionId);
- }
-
- connection->SendReliablePacket(MultiplayerPackets::ValidateSession(config.m_playerSessionId.c_str()));
+ m_networkInterface->Connect(ipAddress);
return true;
}
@@ -416,6 +405,22 @@ namespace Multiplayer
[[maybe_unused]] MultiplayerPackets::Connect& packet
)
{
+ // Validate our session with the provider if any
+ if (AZ::Interface::Get() != nullptr)
+ {
+ AzFramework::PlayerConnectionConfig config;
+ config.m_playerConnectionId = aznumeric_cast(connection->GetConnectionId());
+ config.m_playerSessionId = packet.GetTicket();
+ if(!AZ::Interface::Get()->ValidatePlayerJoinSession(config))
+ {
+ auto visitor = [](IConnection& connection) { connection.Disconnect(DisconnectReason::TerminatedByUser, TerminationEndpoint::Local); };
+ m_networkInterface->GetConnectionSet().VisitConnections(visitor);
+ return true;
+ }
+
+ reinterpret_cast(connection->GetUserData())->SetProviderTicket(packet.GetTicket().c_str());
+ }
+
if (connection->SendReliablePacket(MultiplayerPackets::Accept(InvalidHostId, sv_map)))
{
// Sync our console
@@ -441,31 +446,6 @@ namespace Multiplayer
return true;
}
- bool MultiplayerSystemComponent::HandleRequest
- (
- [[maybe_unused]] AzNetworking::IConnection* connection,
- [[maybe_unused]] const IPacketHeader& packetHeader,
- [[maybe_unused]] MultiplayerPackets::ValidateSession& packet
- )
- {
- // Validate our session with the provider if any
- if (AZ::Interface::Get() != nullptr)
- {
- AzFramework::PlayerConnectionConfig config;
- config.m_playerConnectionId = aznumeric_cast(connection->GetConnectionId());
- config.m_playerSessionId = packet.GetTicket();
- if(!AZ::Interface::Get()->ValidatePlayerJoinSession(config))
- {
- connection->Disconnect(DisconnectReason::TerminatedByServer, TerminationEndpoint::Local);
- return false;
- }
-
- reinterpret_cast(connection->GetUserData())->SetProviderTicket(packet.GetTicket().c_str());
- }
-
- return true;
- }
-
bool MultiplayerSystemComponent::HandleRequest
(
AzNetworking::IConnection* connection,
@@ -595,10 +575,16 @@ namespace Multiplayer
datum.m_isInvited = false;
datum.m_agentType = MultiplayerAgentType::Client;
+ AZStd::string providerTicket;
if (connection->GetConnectionRole() == ConnectionRole::Connector)
{
AZLOG_INFO("New outgoing connection to remote address: %s", connection->GetRemoteAddress().GetString().c_str());
- connection->SendReliablePacket(MultiplayerPackets::Connect(0));
+ if (!m_pendingConnectionTickets.empty())
+ {
+ providerTicket = m_pendingConnectionTickets.front();
+ m_pendingConnectionTickets.pop();
+ }
+ connection->SendReliablePacket(MultiplayerPackets::Connect(0, providerTicket.c_str()));
}
else
{
@@ -628,7 +614,11 @@ namespace Multiplayer
{
if (connection->GetUserData() == nullptr) // Only add user data if the connect event handler has not already done so
{
- connection->SetUserData(new ClientToServerConnectionData(connection, *this));
+ connection->SetUserData(new ClientToServerConnectionData(connection, *this, providerTicket));
+ }
+ else
+ {
+ reinterpret_cast(connection->GetUserData())->SetProviderTicket(providerTicket);
}
AZStd::unique_ptr window = AZStd::make_unique();
@@ -652,12 +642,7 @@ namespace Multiplayer
AZStd::string reasonString = ToString(reason);
AZLOG_INFO("%s due to %s from remote address: %s", endpointString, reasonString.c_str(), connection->GetRemoteAddress().GetString().c_str());
- if (connection->GetConnectionRole() == ConnectionRole::Acceptor)
- {
- // The authority is shutting down its connection
- m_shutdownEvent.Signal(m_networkInterface);
- }
- else if (GetAgentType() == MultiplayerAgentType::Client && connection->GetConnectionRole() == ConnectionRole::Connector)
+ if (GetAgentType() == MultiplayerAgentType::Client && connection->GetConnectionRole() == ConnectionRole::Connector)
{
// The client is disconnecting
m_clientDisconnectedEvent.Signal();
@@ -675,7 +660,7 @@ namespace Multiplayer
if (m_agentType == MultiplayerAgentType::DedicatedServer || m_agentType == MultiplayerAgentType::ClientServer)
{
if (AZ::Interface::Get() != nullptr &&
- connection->GetConnectionRole() == ConnectionRole::Connector)
+ connection->GetConnectionRole() == ConnectionRole::Acceptor)
{
AzFramework::PlayerConnectionConfig config;
config.m_playerConnectionId = aznumeric_cast(connection->GetConnectionId());
@@ -686,7 +671,7 @@ namespace Multiplayer
// Signal to session management when there are no remaining players in a dedicated server for potential cleanup
// We avoid this for client server as the host itself is a user
- if (m_agentType == MultiplayerAgentType::DedicatedServer && connection->GetConnectionRole() == ConnectionRole::Connector)
+ if (m_agentType == MultiplayerAgentType::DedicatedServer && connection->GetConnectionRole() == ConnectionRole::Acceptor)
{
if (AZ::Interface::Get() != nullptr
&& m_networkInterface->GetConnectionSet().GetConnectionCount() == 0)
diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h
index 2a3fe73ff4..00313c6b65 100644
--- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h
+++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h
@@ -82,7 +82,6 @@ namespace Multiplayer
bool HandleRequest(AzNetworking::IConnection* connection, const AzNetworking::IPacketHeader& packetHeader, MultiplayerPackets::Connect& packet);
bool HandleRequest(AzNetworking::IConnection* connection, const AzNetworking::IPacketHeader& packetHeader, MultiplayerPackets::Accept& packet);
- bool HandleRequest(AzNetworking::IConnection* connection, const AzNetworking::IPacketHeader& packetHeader, MultiplayerPackets::ValidateSession& packet);
bool HandleRequest(AzNetworking::IConnection* connection, const AzNetworking::IPacketHeader& packetHeader, MultiplayerPackets::ReadyForEntityUpdates& packet);
bool HandleRequest(AzNetworking::IConnection* connection, const AzNetworking::IPacketHeader& packetHeader, MultiplayerPackets::SyncConsole& packet);
bool HandleRequest(AzNetworking::IConnection* connection, const AzNetworking::IPacketHeader& packetHeader, MultiplayerPackets::ConsoleCommand& packet);
@@ -147,6 +146,8 @@ namespace Multiplayer
ConnectionAcquiredEvent m_connAcquiredEvent;
ClientDisconnectedEvent m_clientDisconnectedEvent;
+ AZStd::queue m_pendingConnectionTickets;
+
AZ::TimeMs m_lastReplicatedHostTimeMs = AZ::TimeMs{ 0 };
HostFrameId m_lastReplicatedHostFrameId = InvalidHostFrameId;