Cleanup session changes and add on connection disconnected event

monroegm-disable-blank-issue-2
puvvadar 5 years ago
parent fa55b495c4
commit cd5867d2fa

@ -45,6 +45,7 @@ namespace Multiplayer
AzNetworking::ByteBuffer<2048> m_userData;
};
using ClientDisconnectedEvent = AZ::Event<>;
using ConnectionAcquiredEvent = AZ::Event<MultiplayerAgentDatum>;
using SessionInitEvent = AZ::Event<AzNetworking::INetworkInterface*>;
using SessionShutdownEvent = AZ::Event<AzNetworking::INetworkInterface*>;
@ -65,8 +66,12 @@ namespace Multiplayer
//! @param state The state of this connection
virtual void InitializeMultiplayer(MultiplayerAgentType state) = 0;
//! Adds a ClientDisconnectedEvent Handler which is invoked on the client when a disconnectio occurs
//! @param handler The ClientDisconnectedEvent Handler to add
virtual void AddClientDisconnectedHandler(ClientDisconnectedEvent::Handler& handler) = 0;
//! Adds a ConnectionAcquiredEvent Handler which is invoked when a new endpoint connects to the session.
//! @param handler The SessionInitEvent Handler to add
//! @param handler The ConnectionAcquiredEvent Handler to add
virtual void AddConnectionAcquiredHandler(ConnectionAcquiredEvent::Handler& handler) = 0;
//! Adds a SessionInitEvent Handler which is invoked when a new network session starts.

@ -22,7 +22,7 @@ namespace Multiplayer
(
AzNetworking::IConnection* connection,
AzNetworking::IConnectionListener& connectionListener,
AZStd::string providerTicket
const AZStd::string& providerTicket
)
: m_connection(connection)
, m_entityReplicationManager(*connection, connectionListener, EntityReplicationManager::Mode::LocalClientToRemoteServer)

@ -25,7 +25,7 @@ namespace Multiplayer
(
AzNetworking::IConnection* connection,
AzNetworking::IConnectionListener& connectionListener,
AZStd::string providerTicket = ""
const AZStd::string& providerTicket = ""
);
~ClientToServerConnectionData() override;
@ -39,7 +39,7 @@ namespace Multiplayer
void SetCanSendUpdates(bool canSendUpdates) override;
//! @}
AZStd::string GetProviderTicket() const;
const AZStd::string& GetProviderTicket() const;
private:
EntityReplicationManager m_entityReplicationManager;

@ -22,7 +22,7 @@ namespace Multiplayer
m_canSendUpdates = canSendUpdates;
}
inline AZStd::string ClientToServerConnectionData::GetProviderTicket() const
inline const AZStd::string& ClientToServerConnectionData::GetProviderTicket() const
{
return m_providerTicket;
}

@ -41,7 +41,7 @@ namespace Multiplayer
NetworkEntityHandle GetPrimaryPlayerEntity();
const NetworkEntityHandle& GetPrimaryPlayerEntity() const;
AZStd::string GetProviderTicket() const;
const AZStd::string& GetProviderTicket() const;
void SetProviderTicket(AZStd::string);
private:

@ -33,7 +33,7 @@ namespace Multiplayer
return m_controlledEntity;
}
inline AZStd::string ServerToClientConnectionData::GetProviderTicket() const
inline const AZStd::string& ServerToClientConnectionData::GetProviderTicket() const
{
return m_ticket;
}

@ -117,6 +117,31 @@ namespace Multiplayer
behaviorContext->Class<RpcIndex>();
behaviorContext->Class<ClientInputId>();
behaviorContext->Class<HostFrameId>();
behaviorContext->Class<MultiplayerSystemComponent>("MultiplayerSystemComponent")
->Attribute(AZ::Script::Attributes::Module, "multiplayer")
->Attribute(AZ::Script::Attributes::Category, "Multiplayer")
->Method("GetOnClientDisconnectedEvent", [](AZ::EntityId id) -> AZ::Event<>*
{
AZ::Entity* entity = AZ::Interface<AZ::ComponentApplicationRequests>::Get()->FindEntity(id);
if (!entity)
{
AZ_Warning("Network Property", false, "NetworkTransformComponent GetOnScaleChangedEvent failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str())
return nullptr;
}
MultiplayerSystemComponent* mpComponent = entity->FindComponent<MultiplayerSystemComponent>();
if (!mpComponent)
{
AZ_Warning("Multiplayer Property", false, "NetworkTransformComponent GetScale failed. Entity '%s' (id: %s) is missing NetworkTransformComponent, be sure to add NetworkTransformComponent to this entity.", entity->GetName().c_str(), id.ToString().c_str())
return nullptr;
}
return &mpComponent->m_clientDisconnectedEvent;
})
->Attribute(
AZ::Script::Attributes::AzEventDescription,
AZ::BehaviorAzEventDescription{"On Client Disconnected Event"});
}
MultiplayerComponent::Reflect(context);
@ -173,12 +198,11 @@ namespace Multiplayer
bool MultiplayerSystemComponent::RequestPlayerJoinSession(const AzFramework::SessionConnectionConfig& config)
{
AZ::Interface<IMultiplayer>::Get()->InitializeMultiplayer(MultiplayerAgentType::Client);
INetworkInterface* networkInterface = AZ::Interface<INetworking>::Get()->RetrieveNetworkInterface(AZ::Name(MPNetworkInterfaceName));
const IpAddress ipAddress(config.m_ipAddress.c_str(), config.m_port, networkInterface->GetType());
ConnectionId connectionId = networkInterface->Connect(ipAddress);
const IpAddress ipAddress(config.m_ipAddress.c_str(), config.m_port, m_networkInterface->GetType());
ConnectionId connectionId = m_networkInterface->Connect(ipAddress);
AzNetworking::IConnection* connection = networkInterface->GetConnectionSet().GetConnection(connectionId);
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));
@ -188,10 +212,15 @@ namespace Multiplayer
void MultiplayerSystemComponent::RequestPlayerLeaveSession()
{
AZ::Interface<IMultiplayer>::Get()->InitializeMultiplayer(MultiplayerAgentType::Uninitialized);
INetworkInterface* networkInterface = AZ::Interface<INetworking>::Get()->RetrieveNetworkInterface(AZ::Name(MPNetworkInterfaceName));
auto visitor = [](IConnection& connection) { connection.Disconnect(DisconnectReason::TerminatedByUser, TerminationEndpoint::Local); };
networkInterface->GetConnectionSet().VisitConnections(visitor);
if (GetAgentType() == MultiplayerAgentType::Client)
{
AZ::Interface<IMultiplayer>::Get()->InitializeMultiplayer(MultiplayerAgentType::Uninitialized);
auto visitor = [](IConnection& connection)
{
connection.Disconnect(DisconnectReason::TerminatedByUser, TerminationEndpoint::Local);
};
m_networkInterface->GetConnectionSet().VisitConnections(visitor);
}
}
bool MultiplayerSystemComponent::OnSessionHealthCheck()
@ -379,19 +408,24 @@ namespace Multiplayer
[[maybe_unused]] MultiplayerPackets::Connect& packet
)
{
if (connection->SendReliablePacket(MultiplayerPackets::Accept(InvalidHostId, sv_map)))
// Validate our session with the provider if any
if (AZ::Interface<AzFramework::ISessionHandlingProviderRequests>::Get() != nullptr)
{
// 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))
{
AzFramework::PlayerConnectionConfig config;
config.m_playerConnectionId = aznumeric_cast<uint32_t>(connection->GetConnectionId());
config.m_playerSessionId = packet.GetTicket();
AZ::Interface<AzFramework::ISessionHandlingProviderRequests>::Get()->ValidatePlayerJoinSession(config);
reinterpret_cast<ServerToClientConnectionData*>(connection->GetUserData())->SetProviderTicket(packet.GetTicket().c_str());
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
ConsoleReplicator consoleReplicator(connection);
AZ::Interface<AZ::IConsole>::Get()->VisitRegisteredFunctors([&consoleReplicator](AZ::ConsoleFunctorBase* functor) { consoleReplicator.Visit(functor); });
@ -606,11 +640,16 @@ 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());
// The authority is shutting down its connection
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)
{
// The client is disconnecting
m_clientDisconnectedEvent.Signal();
}
// Clean up any multiplayer connection data we've bound to this connection instance
if (connection->GetUserData() != nullptr)
@ -679,6 +718,11 @@ namespace Multiplayer
AZLOG_INFO("Multiplayer operating in %s mode", GetEnumString(m_agentType));
}
void MultiplayerSystemComponent::AddClientDisconnectedHandler(ClientDisconnectedEvent::Handler& handler)
{
handler.Connect(m_clientDisconnectedEvent);
}
void MultiplayerSystemComponent::AddConnectionAcquiredHandler(ConnectionAcquiredEvent::Handler& handler)
{
handler.Connect(m_connAcquiredEvent);

@ -108,6 +108,7 @@ namespace Multiplayer
//! @{
MultiplayerAgentType GetAgentType() const override;
void InitializeMultiplayer(MultiplayerAgentType state) override;
void AddClientDisconnectedHandler(ClientDisconnectedEvent::Handler& handler) override;
void AddConnectionAcquiredHandler(ConnectionAcquiredEvent::Handler& handler) override;
void AddSessionInitHandler(SessionInitEvent::Handler& handler) override;
void AddSessionShutdownHandler(SessionShutdownEvent::Handler& handler) override;
@ -143,6 +144,7 @@ namespace Multiplayer
SessionInitEvent m_initEvent;
SessionShutdownEvent m_shutdownEvent;
ConnectionAcquiredEvent m_connAcquiredEvent;
ClientDisconnectedEvent m_clientDisconnectedEvent;
AZ::TimeMs m_lastReplicatedHostTimeMs = AZ::TimeMs{ 0 };
HostFrameId m_lastReplicatedHostFrameId = InvalidHostFrameId;

Loading…
Cancel
Save