From 40c7a6bd2d530d53a2f19d365b2639f40490f4c8 Mon Sep 17 00:00:00 2001 From: puvvadar Date: Mon, 7 Jun 2021 17:02:42 -0700 Subject: [PATCH] Integrate remaining requests and rename Handling Requests interfaces for clarity --- .../Session/ISessionHandlingRequests.h | 33 +++++---- .../Source/MultiplayerSystemComponent.cpp | 67 +++++++++++++++++++ .../Code/Source/MultiplayerSystemComponent.h | 9 +++ 3 files changed, 95 insertions(+), 14 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Session/ISessionHandlingRequests.h b/Code/Framework/AzFramework/AzFramework/Session/ISessionHandlingRequests.h index a0731626ef..2537842d8a 100644 --- a/Code/Framework/AzFramework/AzFramework/Session/ISessionHandlingRequests.h +++ b/Code/Framework/AzFramework/AzFramework/Session/ISessionHandlingRequests.h @@ -45,14 +45,14 @@ namespace AzFramework AZStd::string m_playerSessionId; }; - //! ISessionHandlingClientRequests - //! The session handling events to invoke multiplayer component handle the work on client side - class ISessionHandlingClientRequests + //! ISessionLocalUserRequests + //! Requests made to the local user to manage their connection to a session + class ISessionLocalUserRequests { public: - AZ_RTTI(ISessionHandlingClientRequests, "{41DE6BD3-72BC-4443-BFF9-5B1B9396657A}"); - ISessionHandlingClientRequests() = default; - virtual ~ISessionHandlingClientRequests() = default; + AZ_RTTI(ISessionLocalUserRequests, "{41DE6BD3-72BC-4443-BFF9-5B1B9396657A}"); + ISessionLocalUserRequests() = default; + virtual ~ISessionLocalUserRequests() = default; // Request the player join session // @param sessionConnectionConfig The required properties to handle the player join session process @@ -63,14 +63,14 @@ namespace AzFramework virtual void RequestPlayerLeaveSession() = 0; }; - //! ISessionHandlingServerRequests - //! The session handling events to invoke server provider handle the work on server side - class ISessionHandlingServerRequests + //! ISessionProviderRequests + //! Requests made to the service providing server/fleet management by the server + class ISessionProviderRequests { public: - AZ_RTTI(ISessionHandlingServerRequests, "{4F0C17BA-F470-4242-A8CB-EC7EA805257C}"); - ISessionHandlingServerRequests() = default; - virtual ~ISessionHandlingServerRequests() = default; + AZ_RTTI(ISessionProviderRequests, "{4F0C17BA-F470-4242-A8CB-EC7EA805257C}"); + ISessionProviderRequests() = default; + virtual ~ISessionProviderRequests() = default; // Handle the destroy session process virtual void HandleDestroySession() = 0; @@ -84,9 +84,14 @@ namespace AzFramework // @param playerConnectionConfig The required properties to handle the player leave session process virtual void HandlePlayerLeaveSession(const PlayerConnectionConfig& playerConnectionConfig) = 0; - // Retrieves the file location of a pem-encoded TLS certificate + // Retrieves the file location of a pem-encoded TLS certificate for Client to Server communication // @return If successful, returns the file location of TLS certificate file; if not successful, returns // empty string. - virtual AZStd::string GetSessionCertificate() = 0; + virtual AZStd::string GetExternalSessionCertificate() = 0; + + // Retrieves the file location of a pem-encoded TLS certificate for Server to Server communication + // @return If successful, returns the file location of TLS certificate file; if not successful, returns + // empty string. + virtual AZStd::string GetInternalSessionCertificate() = 0; }; } // namespace AzFramework diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp index ce4b7d8601..18d8bd6e2e 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -169,6 +170,24 @@ namespace Multiplayer AZ::TickBus::Handler::BusDisconnect(); } + bool MultiplayerSystemComponent::RequestPlayerJoinSession(const AzFramework::SessionConnectionConfig& config) + { + AZ::Interface::Get()->InitializeMultiplayer(MultiplayerAgentType::Client); + INetworkInterface* networkInterface = AZ::Interface::Get()->RetrieveNetworkInterface(AZ::Name(MPNetworkInterfaceName)); + + const IpAddress ipAddress(config.m_ipAddress.c_str(), config.m_port, networkInterface->GetType()); + networkInterface->Connect(ipAddress); + return true; + } + + void MultiplayerSystemComponent::RequestPlayerLeaveSession() + { + AZ::Interface::Get()->InitializeMultiplayer(MultiplayerAgentType::Uninitialized); + INetworkInterface* networkInterface = AZ::Interface::Get()->RetrieveNetworkInterface(AZ::Name(MPNetworkInterfaceName)); + auto visitor = [](IConnection& connection) { connection.Disconnect(DisconnectReason::TerminatedByUser, TerminationEndpoint::Local); }; + networkInterface->GetConnectionSet().VisitConnections(visitor); + } + bool MultiplayerSystemComponent::OnSessionHealthCheck() { return true; @@ -176,6 +195,21 @@ namespace Multiplayer bool MultiplayerSystemComponent::OnCreateSessionBegin(const AzFramework::SessionConfig& sessionConfig) { + // Check if session manager has a certificate for us and pass it along if so + AZ::CVarFixedString externalCertPath = AZ::CVarFixedString(AZ::Interface::Get()->GetExternalSessionCertificate()); + if (!externalCertPath.empty()) + { + AZ::CVarFixedString commandString = "net_SslExternalCertificateFile " + externalCertPath; + AZ::Interface::Get()->PerformCommand(commandString.c_str()); + } + + AZ::CVarFixedString internalCertPath = AZ::CVarFixedString(AZ::Interface::Get()->GetInternalSessionCertificate()); + if (!internalCertPath.empty()) + { + AZ::CVarFixedString commandString = "net_SslInternalCertificateFile " + internalCertPath; + AZ::Interface::Get()->PerformCommand(commandString.c_str()); + } + Multiplayer::MultiplayerAgentType serverType = sv_isDedicated ? MultiplayerAgentType::DedicatedServer : MultiplayerAgentType::ClientServer; AZ::Interface::Get()->InitializeMultiplayer(serverType); return m_networkInterface->Listen(sessionConfig.m_port); @@ -497,6 +531,10 @@ namespace Multiplayer { AZLOG_INFO("New incoming connection from remote address: %s", connection->GetRemoteAddress().GetString().c_str()); m_connAcquiredEvent.Signal(datum); + AzFramework::PlayerConnectionConfig config; + config.m_playerConnectionId = aznumeric_cast(connection->GetConnectionId()); + config.m_playerSessionId = AZStd::to_string(config.m_playerConnectionId); + AZ::Interface::Get()->ValidatePlayerJoinSession(config); } // Hosts will spawn a new default player prefab for the user that just connected @@ -558,6 +596,34 @@ namespace Multiplayer delete connectionData; connection->SetUserData(nullptr); } + + // Signal to session management that a user triggered a disconnect + if (m_agentType == MultiplayerAgentType::Client && connection->GetConnectionRole() == ConnectionRole::Connector) + { + AZ::Interface::Get()->LeaveSession(); + } + + // Signal to session management that a user has left the server + if (m_agentType == MultiplayerAgentType::DedicatedServer || m_agentType == MultiplayerAgentType::ClientServer) + { + if (connection->GetConnectionRole() == ConnectionRole::Connector) + { + AzFramework::PlayerConnectionConfig config; + config.m_playerConnectionId = aznumeric_cast(connection->GetConnectionId()); + config.m_playerSessionId = AZStd::to_string(config.m_playerConnectionId); + AZ::Interface::Get()->HandlePlayerLeaveSession(config); + } + } + + // 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) + { + if (m_networkInterface->GetConnectionSet().GetConnectionCount() == 0) + { + AZ::Interface::Get()->HandleDestroySession(); + } + } } MultiplayerAgentType MultiplayerSystemComponent::GetAgentType() const @@ -788,6 +854,7 @@ namespace Multiplayer } AZ_CONSOLEFREEFUNC(host, AZ::ConsoleFunctorFlags::DontReplicate, "Opens a multiplayer connection as a host for other clients to connect to"); + void connect([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments) { AZ::Interface::Get()->InitializeMultiplayer(MultiplayerAgentType::Client); diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h index ab3e54ad6d..505df52a6a 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include #include @@ -45,6 +47,7 @@ namespace Multiplayer : public AZ::Component , public AZ::TickBus::Handler , public AzFramework::SessionNotificationBus::Handler + , public AzFramework::ISessionLocalUserRequests , public AzNetworking::IConnectionListener , public IMultiplayer { @@ -96,6 +99,12 @@ namespace Multiplayer void OnDisconnect(AzNetworking::IConnection* connection, AzNetworking::DisconnectReason reason, AzNetworking::TerminationEndpoint endpoint) override; //! @} + //! ISessionLocalUserRequests interface + //! @{ + bool RequestPlayerJoinSession(const AzFramework::SessionConnectionConfig& sessionConnectionConfig) override; + void RequestPlayerLeaveSession() override; + //! @} + //! IMultiplayer interface //! @{ MultiplayerAgentType GetAgentType() const override;