Rework session validation to work through Connect packet
This commit is contained in:
@@ -9,16 +9,13 @@
|
||||
|
||||
<Packet Name="Connect" Desc="Client connection packet, on success the server will reply with an Accept">
|
||||
<Member Type="uint16_t" Name="networkProtocolVersion" Init="0" />
|
||||
<Member Type="Multiplayer::LongNetworkString" Name="ticket" />
|
||||
</Packet>
|
||||
|
||||
<Packet Name="Accept" Desc="Server accept packet">
|
||||
<Member Type="Multiplayer::HostId" Name="hostId" Init="Multiplayer::InvalidHostId" />
|
||||
<Member Type="Multiplayer::LongNetworkString" Name="map" />
|
||||
</Packet>
|
||||
|
||||
<Packet Name="ValidateSession" Desc="Client validation packet, sends a ticket to the server for session verification">
|
||||
<Member Type="Multiplayer::LongNetworkString" Name="ticket" />
|
||||
</Packet>
|
||||
|
||||
<Packet Name="ReadyForEntityUpdates" Desc="Client confirming it is ready to receive entity updates">
|
||||
<Member Type="bool" Name="readyForEntityUpdates" />
|
||||
|
||||
@@ -199,21 +199,10 @@ namespace Multiplayer
|
||||
{
|
||||
AZ::Interface<IMultiplayer>::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<ClientToServerConnectionData*>(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<AzFramework::ISessionHandlingProviderRequests>::Get() != nullptr)
|
||||
{
|
||||
AzFramework::PlayerConnectionConfig config;
|
||||
config.m_playerConnectionId = aznumeric_cast<uint32_t>(connection->GetConnectionId());
|
||||
config.m_playerSessionId = packet.GetTicket();
|
||||
if(!AZ::Interface<AzFramework::ISessionHandlingProviderRequests>::Get()->ValidatePlayerJoinSession(config))
|
||||
{
|
||||
auto visitor = [](IConnection& connection) { connection.Disconnect(DisconnectReason::TerminatedByUser, TerminationEndpoint::Local); };
|
||||
m_networkInterface->GetConnectionSet().VisitConnections(visitor);
|
||||
return true;
|
||||
}
|
||||
|
||||
reinterpret_cast<ServerToClientConnectionData*>(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<AzFramework::ISessionHandlingProviderRequests>::Get() != nullptr)
|
||||
{
|
||||
AzFramework::PlayerConnectionConfig config;
|
||||
config.m_playerConnectionId = aznumeric_cast<uint32_t>(connection->GetConnectionId());
|
||||
config.m_playerSessionId = packet.GetTicket();
|
||||
if(!AZ::Interface<AzFramework::ISessionHandlingProviderRequests>::Get()->ValidatePlayerJoinSession(config))
|
||||
{
|
||||
connection->Disconnect(DisconnectReason::TerminatedByServer, TerminationEndpoint::Local);
|
||||
return false;
|
||||
}
|
||||
|
||||
reinterpret_cast<ServerToClientConnectionData*>(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<ClientToServerConnectionData*>(connection->GetUserData())->SetProviderTicket(providerTicket);
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<IReplicationWindow> window = AZStd::make_unique<NullReplicationWindow>();
|
||||
@@ -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<AzFramework::ISessionHandlingProviderRequests>::Get() != nullptr &&
|
||||
connection->GetConnectionRole() == ConnectionRole::Connector)
|
||||
connection->GetConnectionRole() == ConnectionRole::Acceptor)
|
||||
{
|
||||
AzFramework::PlayerConnectionConfig config;
|
||||
config.m_playerConnectionId = aznumeric_cast<uint32_t>(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<AzFramework::ISessionHandlingProviderRequests>::Get() != nullptr
|
||||
&& m_networkInterface->GetConnectionSet().GetConnectionCount() == 0)
|
||||
|
||||
@@ -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<AZStd::string> m_pendingConnectionTickets;
|
||||
|
||||
AZ::TimeMs m_lastReplicatedHostTimeMs = AZ::TimeMs{ 0 };
|
||||
HostFrameId m_lastReplicatedHostFrameId = InvalidHostFrameId;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user