Expose matchmaking event polling APIs and add required session notifications (#4636)

* Expose matchmaking event polling APIs and add required session notifications

Signed-off-by: onecent1101 <liug@amazon.com>
monroegm-disable-blank-issue-2
Vincent Liu 4 years ago committed by GitHub
parent eac14901b0
commit a534fccc9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -30,22 +30,42 @@ namespace AzFramework
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// OnSessionHealthCheck is fired in health check process // OnSessionHealthCheck is fired in health check process
// @return The result of all OnSessionHealthCheck // Use this notification to perform any custom health check
// @return True if OnSessionHealthCheck succeeds, false otherwise
virtual bool OnSessionHealthCheck() = 0; virtual bool OnSessionHealthCheck() = 0;
// OnCreateSessionBegin is fired at the beginning of session creation // OnCreateSessionBegin is fired at the beginning of session creation process
// Use this notification to perform any necessary configuration or initialization before
// creating session
// @param sessionConfig The properties to describe a session // @param sessionConfig The properties to describe a session
// @return The result of all OnCreateSessionBegin notifications // @return True if OnCreateSessionBegin succeeds, false otherwise
virtual bool OnCreateSessionBegin(const SessionConfig& sessionConfig) = 0; virtual bool OnCreateSessionBegin(const SessionConfig& sessionConfig) = 0;
// OnDestroySessionBegin is fired at the beginning of session termination // OnCreateSessionEnd is fired at the end of session creation process
// @return The result of all OnDestroySessionBegin notifications // Use this notification to perform any follow-up operation after session is created and active
virtual void OnCreateSessionEnd() = 0;
// OnDestroySessionBegin is fired at the beginning of session termination process
// Use this notification to perform any cleanup operation before destroying session,
// like gracefully disconnect players, cleanup data, etc.
// @return True if OnDestroySessionBegin succeeds, false otherwise
virtual bool OnDestroySessionBegin() = 0; virtual bool OnDestroySessionBegin() = 0;
// OnUpdateSessionBegin is fired at the beginning of session update // OnDestroySessionEnd is fired at the end of session termination process
// Use this notification to perform any follow-up operation after session is destroyed,
// like shutdown application process, etc.
virtual void OnDestroySessionEnd() = 0;
// OnUpdateSessionBegin is fired at the beginning of session update process
// Use this notification to perform any configuration or initialization to handle
// the session settings changing
// @param sessionConfig The properties to describe a session // @param sessionConfig The properties to describe a session
// @param updateReason The reason for session update // @param updateReason The reason for session update
virtual void OnUpdateSessionBegin(const SessionConfig& sessionConfig, const AZStd::string& updateReason) = 0; virtual void OnUpdateSessionBegin(const SessionConfig& sessionConfig, const AZStd::string& updateReason) = 0;
// OnUpdateSessionBegin is fired at the end of session update process
// Use this notification to perform any follow-up operations after session is updated
virtual void OnUpdateSessionEnd() = 0;
}; };
using SessionNotificationBus = AZ::EBus<SessionNotifications>; using SessionNotificationBus = AZ::EBus<SessionNotifications>;
} // namespace AzFramework } // namespace AzFramework

@ -94,4 +94,41 @@ namespace AWSGameLift
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
}; };
using AWSGameLiftMatchmakingRequestBus = AZ::EBus<AzFramework::IMatchmakingRequests, AWSGameLiftMatchmakingRequests>; using AWSGameLiftMatchmakingRequestBus = AZ::EBus<AzFramework::IMatchmakingRequests, AWSGameLiftMatchmakingRequests>;
//! IAWSGameLiftMatchmakingEventRequests
//! GameLift Gem matchmaking event interfaces which is used to track matchmaking ticket event
//! Developer should define the way to poll matchmaking ticket event and behavior based on the ticket status
//! Use AWSGameLiftClientLocalTicketTracker as an example, it uses continuous polling to query matchmaking ticket:
//! StartPolling - local ticket tracker starts monitor process for matchmaking ticket, and joins player
//! to the match once ticket is complete
//! StopPolling - local ticket tracker cancels ongoing matchmaking ticket and stops monitoring process
class IAWSGameLiftMatchmakingEventRequests
{
public:
AZ_RTTI(IAWSGameLiftMatchmakingEventRequests, "{C2DA440E-74E0-411E-813D-5880B50B0C9E}");
IAWSGameLiftMatchmakingEventRequests() = default;
virtual ~IAWSGameLiftMatchmakingEventRequests() = default;
//! StartPolling
//! Request to start process for polling matchmaking ticket based on given ticket id and player Id
//! @param ticketId The requested matchmaking ticket id
//! @param playerId The requested matchmaking player id
virtual void StartPolling(const AZStd::string& ticketId, const AZStd::string& playerId) = 0;
//! StopPolling
//! Request to stop process for polling matchmaking ticket
virtual void StopPolling() = 0;
};
// IAWSGameLiftMatchmakingEventRequests EBus wrapper for scripting
class AWSGameLiftMatchmakingEventRequests
: public AZ::EBusTraits
{
public:
using MutexType = AZStd::recursive_mutex;
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
};
using AWSGameLiftMatchmakingEventRequestBus = AZ::EBus<IAWSGameLiftMatchmakingEventRequests, AWSGameLiftMatchmakingEventRequests>;
} // namespace AWSGameLift } // namespace AWSGameLift

@ -30,12 +30,14 @@ namespace AWSGameLift
void AWSGameLiftClientLocalTicketTracker::ActivateTracker() void AWSGameLiftClientLocalTicketTracker::ActivateTracker()
{ {
AZ::Interface<IAWSGameLiftMatchmakingInternalRequests>::Register(this); AZ::Interface<IAWSGameLiftMatchmakingEventRequests>::Register(this);
AWSGameLiftMatchmakingEventRequestBus::Handler::BusConnect();
} }
void AWSGameLiftClientLocalTicketTracker::DeactivateTracker() void AWSGameLiftClientLocalTicketTracker::DeactivateTracker()
{ {
AZ::Interface<IAWSGameLiftMatchmakingInternalRequests>::Unregister(this); AWSGameLiftMatchmakingEventRequestBus::Handler::BusDisconnect();
AZ::Interface<IAWSGameLiftMatchmakingEventRequests>::Unregister(this);
StopPolling(); StopPolling();
} }

@ -12,7 +12,7 @@
#include <AzCore/std/parallel/mutex.h> #include <AzCore/std/parallel/mutex.h>
#include <AzCore/std/parallel/thread.h> #include <AzCore/std/parallel/thread.h>
#include <Request/IAWSGameLiftMatchmakingInternalRequests.h> #include <Request/IAWSGameLiftRequests.h>
#include <aws/gamelift/model/MatchmakingTicket.h> #include <aws/gamelift/model/MatchmakingTicket.h>
@ -30,7 +30,7 @@ namespace AWSGameLift
//! For use in production, please see GameLifts guidance about matchmaking at volume. //! For use in production, please see GameLifts guidance about matchmaking at volume.
//! The continuous polling approach here is only suitable for low volume matchmaking and is meant to aid with development only //! The continuous polling approach here is only suitable for low volume matchmaking and is meant to aid with development only
class AWSGameLiftClientLocalTicketTracker class AWSGameLiftClientLocalTicketTracker
: public IAWSGameLiftMatchmakingInternalRequests : public AWSGameLiftMatchmakingEventRequestBus::Handler
{ {
public: public:
static constexpr const char AWSGameLiftClientLocalTicketTrackerName[] = "AWSGameLiftClientLocalTicketTracker"; static constexpr const char AWSGameLiftClientLocalTicketTrackerName[] = "AWSGameLiftClientLocalTicketTracker";
@ -44,7 +44,7 @@ namespace AWSGameLift
virtual void ActivateTracker(); virtual void ActivateTracker();
virtual void DeactivateTracker(); virtual void DeactivateTracker();
// IAWSGameLiftMatchmakingInternalRequests interface implementation // AWSGameLiftMatchmakingEventRequestBus interface implementation
void StartPolling(const AZStd::string& ticketId, const AZStd::string& playerId) override; void StartPolling(const AZStd::string& ticketId, const AZStd::string& playerId) override;
void StopPolling() override; void StopPolling() override;

@ -12,6 +12,7 @@
#include <AzCore/Serialization/EditContextConstants.inl> #include <AzCore/Serialization/EditContextConstants.inl>
#include <AzFramework/Session/SessionConfig.h> #include <AzFramework/Session/SessionConfig.h>
#include <AWSGameLiftClientLocalTicketTracker.h>
#include <AWSGameLiftClientManager.h> #include <AWSGameLiftClientManager.h>
#include <AWSGameLiftClientSystemComponent.h> #include <AWSGameLiftClientSystemComponent.h>
#include <Request/AWSGameLiftAcceptMatchRequest.h> #include <Request/AWSGameLiftAcceptMatchRequest.h>
@ -59,10 +60,17 @@ namespace AWSGameLift
behaviorContext->EBus<AWSGameLiftRequestBus>("AWSGameLiftRequestBus") behaviorContext->EBus<AWSGameLiftRequestBus>("AWSGameLiftRequestBus")
->Attribute(AZ::Script::Attributes::Category, "AWSGameLift") ->Attribute(AZ::Script::Attributes::Category, "AWSGameLift")
->Event("ConfigureGameLiftClient", &AWSGameLiftRequestBus::Events::ConfigureGameLiftClient, ->Event("ConfigureGameLiftClient", &AWSGameLiftRequestBus::Events::ConfigureGameLiftClient,
{{{"Region", ""}}}) { { { "Region", "" } } })
->Event("CreatePlayerId", &AWSGameLiftRequestBus::Events::CreatePlayerId, ->Event("CreatePlayerId", &AWSGameLiftRequestBus::Events::CreatePlayerId,
{{{"IncludeBrackets", ""}, { { { "IncludeBrackets", "" },
{"IncludeDashes", ""}}}); { "IncludeDashes", "" } } });
behaviorContext->EBus<AWSGameLiftMatchmakingEventRequestBus>("AWSGameLiftMatchmakingEventRequestBus")
->Attribute(AZ::Script::Attributes::Category, "AWSGameLift")
->Event("StartPolling", &AWSGameLiftMatchmakingEventRequestBus::Events::StartPolling,
{ { { "TicketId", "" },
{ "PlayerId", "" } } })
->Event("StopPolling", &AWSGameLiftMatchmakingEventRequestBus::Events::StopPolling);
} }
} }

@ -11,12 +11,12 @@
#include <AzCore/Component/Component.h> #include <AzCore/Component/Component.h>
#include <AzCore/std/smart_ptr/unique_ptr.h> #include <AzCore/std/smart_ptr/unique_ptr.h>
#include <AWSGameLiftClientLocalTicketTracker.h>
#include <Request/IAWSGameLiftInternalRequests.h> #include <Request/IAWSGameLiftInternalRequests.h>
namespace AWSGameLift namespace AWSGameLift
{ {
class AWSGameLiftClientManager; class AWSGameLiftClientManager;
class AWSGameLiftClientLocalTicketTracker;
//! Gem client system component. Responsible for creating the gamelift client manager. //! Gem client system component. Responsible for creating the gamelift client manager.
class AWSGameLiftClientSystemComponent class AWSGameLiftClientSystemComponent

@ -1,39 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/RTTI/RTTI.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/string/string.h>
namespace AWSGameLift
{
//! IAWSGameLiftMatchmakingInternalRequests
//! GameLift Gem matchmaking internal interfaces which is used to communicate
//! with client side ticket tracker to sync matchmaking ticket data and join
//! player to the match
class IAWSGameLiftMatchmakingInternalRequests
{
public:
AZ_RTTI(IAWSGameLiftMatchmakingInternalRequests, "{C2DA440E-74E0-411E-813D-5880B50B0C9E}");
IAWSGameLiftMatchmakingInternalRequests() = default;
virtual ~IAWSGameLiftMatchmakingInternalRequests() = default;
//! StartPolling
//! Request to start process for polling matchmaking ticket based on given ticket id and player id
//! @param ticketId The requested matchmaking ticket id
//! @param playerId The requested matchmaking player id
virtual void StartPolling(const AZStd::string& ticketId, const AZStd::string& playerId) = 0;
//! StopPolling
//! Request to stop process for polling matchmaking ticket
virtual void StopPolling() = 0;
};
} // namespace AWSGameLift

@ -36,8 +36,6 @@
#include <aws/gamelift/model/StopMatchmakingRequest.h> #include <aws/gamelift/model/StopMatchmakingRequest.h>
#include <aws/gamelift/model/StopMatchmakingResult.h> #include <aws/gamelift/model/StopMatchmakingResult.h>
#include <Request/IAWSGameLiftMatchmakingInternalRequests.h>
using namespace Aws::GameLift; using namespace Aws::GameLift;
class GameLiftClientMock class GameLiftClientMock

@ -32,12 +32,12 @@ set(FILES
Source/Activity/AWSGameLiftLeaveSessionActivity.h Source/Activity/AWSGameLiftLeaveSessionActivity.h
Source/Activity/AWSGameLiftSearchSessionsActivity.cpp Source/Activity/AWSGameLiftSearchSessionsActivity.cpp
Source/Activity/AWSGameLiftSearchSessionsActivity.h Source/Activity/AWSGameLiftSearchSessionsActivity.h
Source/AWSGameLiftClientLocalTicketTracker.cpp
Source/AWSGameLiftClientLocalTicketTracker.h
Source/Activity/AWSGameLiftStartMatchmakingActivity.cpp Source/Activity/AWSGameLiftStartMatchmakingActivity.cpp
Source/Activity/AWSGameLiftStartMatchmakingActivity.h Source/Activity/AWSGameLiftStartMatchmakingActivity.h
Source/Activity/AWSGameLiftStopMatchmakingActivity.cpp Source/Activity/AWSGameLiftStopMatchmakingActivity.cpp
Source/Activity/AWSGameLiftStopMatchmakingActivity.h Source/Activity/AWSGameLiftStopMatchmakingActivity.h
Source/AWSGameLiftClientLocalTicketTracker.cpp
Source/AWSGameLiftClientLocalTicketTracker.h
Source/AWSGameLiftClientManager.cpp Source/AWSGameLiftClientManager.cpp
Source/AWSGameLiftClientManager.h Source/AWSGameLiftClientManager.h
Source/AWSGameLiftClientSystemComponent.cpp Source/AWSGameLiftClientSystemComponent.cpp
@ -50,5 +50,4 @@ set(FILES
Source/Request/AWSGameLiftStartMatchmakingRequest.cpp Source/Request/AWSGameLiftStartMatchmakingRequest.cpp
Source/Request/AWSGameLiftStopMatchmakingRequest.cpp Source/Request/AWSGameLiftStopMatchmakingRequest.cpp
Source/Request/IAWSGameLiftInternalRequests.h Source/Request/IAWSGameLiftInternalRequests.h
Source/Request/IAWSGameLiftMatchmakingInternalRequests.h
) )

@ -336,14 +336,11 @@ namespace AWSGameLift
BuildServerMatchBackfillPlayerAttributes( BuildServerMatchBackfillPlayerAttributes(
players[playerIndex][AWSGameLiftMatchmakingPlayerAttributesKeyName], outPlayer); players[playerIndex][AWSGameLiftMatchmakingPlayerAttributesKeyName], outPlayer);
} }
} return true;
else
{
return false;
} }
} }
} }
return true; return false;
} }
void AWSGameLiftServerManager::BuildServerMatchBackfillPlayerAttributes( void AWSGameLiftServerManager::BuildServerMatchBackfillPlayerAttributes(
@ -461,12 +458,16 @@ namespace AWSGameLift
AZ_TracePrintf(AWSGameLiftServerManagerName, "Notifying GameLift server process is ending ..."); AZ_TracePrintf(AWSGameLiftServerManagerName, "Notifying GameLift server process is ending ...");
Aws::GameLift::GenericOutcome processEndingOutcome = m_gameLiftServerSDKWrapper->ProcessEnding(); Aws::GameLift::GenericOutcome processEndingOutcome = m_gameLiftServerSDKWrapper->ProcessEnding();
AZ_TracePrintf(AWSGameLiftServerManagerName, "ProcessEnding request against Amazon GameLift service is complete."); if (processEndingOutcome.IsSuccess())
{
[[maybe_unused]] bool processEndingIsSuccess = processEndingOutcome.IsSuccess(); AZ_TracePrintf(AWSGameLiftServerManagerName, "ProcessEnding request against Amazon GameLift service succeeded.");
AzFramework::SessionNotificationBus::Broadcast(&AzFramework::SessionNotifications::OnDestroySessionEnd);
AZ_Error(AWSGameLiftServerManagerName, processEndingIsSuccess, AWSGameLiftServerProcessEndingErrorMessage, }
processEndingOutcome.GetError().GetErrorMessage().c_str()); else
{
AZ_Error(AWSGameLiftServerManagerName, false, AWSGameLiftServerProcessEndingErrorMessage,
processEndingOutcome.GetError().GetErrorMessage().c_str());
}
} }
void AWSGameLiftServerManager::HandlePlayerLeaveSession(const AzFramework::PlayerConnectionConfig& playerConnectionConfig) void AWSGameLiftServerManager::HandlePlayerLeaveSession(const AzFramework::PlayerConnectionConfig& playerConnectionConfig)
@ -546,15 +547,16 @@ namespace AWSGameLift
{ {
AZ_TracePrintf(AWSGameLiftServerManagerName, "Activating GameLift game session ..."); AZ_TracePrintf(AWSGameLiftServerManagerName, "Activating GameLift game session ...");
Aws::GameLift::GenericOutcome activationOutcome = m_gameLiftServerSDKWrapper->ActivateGameSession(); Aws::GameLift::GenericOutcome activationOutcome = m_gameLiftServerSDKWrapper->ActivateGameSession();
AZ_TracePrintf(AWSGameLiftServerManagerName, "ActivateGameSession request against Amazon GameLift service is complete.");
if (activationOutcome.IsSuccess()) if (activationOutcome.IsSuccess())
{ {
AZ_TracePrintf(AWSGameLiftServerManagerName, "ActivateGameSession request against Amazon GameLift service succeeded.");
// Register server manager as handler once game session has been activated // Register server manager as handler once game session has been activated
if (!AZ::Interface<AzFramework::ISessionHandlingProviderRequests>::Get()) if (!AZ::Interface<AzFramework::ISessionHandlingProviderRequests>::Get())
{ {
AZ::Interface<AzFramework::ISessionHandlingProviderRequests>::Register(this); AZ::Interface<AzFramework::ISessionHandlingProviderRequests>::Register(this);
} }
AzFramework::SessionNotificationBus::Broadcast(&AzFramework::SessionNotifications::OnCreateSessionEnd);
} }
else else
{ {
@ -588,17 +590,18 @@ namespace AWSGameLift
void AWSGameLiftServerManager::OnUpdateGameSession(const Aws::GameLift::Server::Model::UpdateGameSession& updateGameSession) void AWSGameLiftServerManager::OnUpdateGameSession(const Aws::GameLift::Server::Model::UpdateGameSession& updateGameSession)
{ {
AzFramework::SessionConfig sessionConfig = BuildSessionConfig(updateGameSession.GetGameSession());
Aws::GameLift::Server::Model::UpdateReason updateReason = updateGameSession.GetUpdateReason(); Aws::GameLift::Server::Model::UpdateReason updateReason = updateGameSession.GetUpdateReason();
AzFramework::SessionNotificationBus::Broadcast(&AzFramework::SessionNotifications::OnUpdateSessionBegin,
sessionConfig, Aws::GameLift::Server::Model::UpdateReasonMapper::GetNameForUpdateReason(updateReason).c_str());
// Update game session data locally
if (updateReason == Aws::GameLift::Server::Model::UpdateReason::MATCHMAKING_DATA_UPDATED) if (updateReason == Aws::GameLift::Server::Model::UpdateReason::MATCHMAKING_DATA_UPDATED)
{ {
UpdateGameSessionData(updateGameSession.GetGameSession()); UpdateGameSessionData(updateGameSession.GetGameSession());
} }
AzFramework::SessionConfig sessionConfig = BuildSessionConfig(updateGameSession.GetGameSession());
AzFramework::SessionNotificationBus::Broadcast( AzFramework::SessionNotificationBus::Broadcast(&AzFramework::SessionNotifications::OnUpdateSessionEnd);
&AzFramework::SessionNotifications::OnUpdateSessionBegin,
sessionConfig,
Aws::GameLift::Server::Model::UpdateReasonMapper::GetNameForUpdateReason(updateReason).c_str());
} }
bool AWSGameLiftServerManager::RemoveConnectedPlayer(uint32_t playerConnectionId, AZStd::string& outPlayerSessionId) bool AWSGameLiftServerManager::RemoveConnectedPlayer(uint32_t playerConnectionId, AZStd::string& outPlayerSessionId)
@ -654,7 +657,7 @@ namespace AWSGameLift
} }
else else
{ {
AZ_TracePrintf(AWSGameLiftServerManagerName, "StartMatchBackfill request against Amazon GameLift service is complete."); AZ_TracePrintf(AWSGameLiftServerManagerName, "StartMatchBackfill request against Amazon GameLift service succeeded.");
return true; return true;
} }
} }
@ -686,7 +689,7 @@ namespace AWSGameLift
} }
else else
{ {
AZ_TracePrintf(AWSGameLiftServerManagerName, "StopMatchBackfill request against Amazon GameLift service is complete."); AZ_TracePrintf(AWSGameLiftServerManagerName, "StopMatchBackfill request against Amazon GameLift service succeeded.");
return true; return true;
} }
} }

@ -94,7 +94,7 @@ namespace AWSGameLift
static constexpr const char AWSGameLiftMatchmakingPlayerAttributeSTypeName[] = "S"; static constexpr const char AWSGameLiftMatchmakingPlayerAttributeSTypeName[] = "S";
static constexpr const char AWSGameLiftMatchmakingPlayerAttributeSServerTypeName[] = "STRING"; static constexpr const char AWSGameLiftMatchmakingPlayerAttributeSServerTypeName[] = "STRING";
static constexpr const char AWSGameLiftMatchmakingPlayerAttributeNTypeName[] = "N"; static constexpr const char AWSGameLiftMatchmakingPlayerAttributeNTypeName[] = "N";
static constexpr const char AWSGameLiftMatchmakingPlayerAttributeNServerTypeName[] = "NUMBER"; static constexpr const char AWSGameLiftMatchmakingPlayerAttributeNServerTypeName[] = "DOUBLE";
static constexpr const char AWSGameLiftMatchmakingPlayerAttributeSLTypeName[] = "SL"; static constexpr const char AWSGameLiftMatchmakingPlayerAttributeSLTypeName[] = "SL";
static constexpr const char AWSGameLiftMatchmakingPlayerAttributeSLServerTypeName[] = "STRING_LIST"; static constexpr const char AWSGameLiftMatchmakingPlayerAttributeSLServerTypeName[] = "STRING_LIST";
static constexpr const char AWSGameLiftMatchmakingPlayerAttributeSDMTypeName[] = "SDM"; static constexpr const char AWSGameLiftMatchmakingPlayerAttributeSDMTypeName[] = "SDM";

@ -34,13 +34,20 @@ R"({
"valueAttribute":"testmode" "valueAttribute":"testmode"
}, },
"level":{ "level":{
"attributeType":"NUMBER", "attributeType":"DOUBLE",
"valueAttribute":10.0 "valueAttribute":10.0
}, },
"items":{ "items":{
"attributeType":"STRING_LIST", "attributeType":"STRING_LIST",
"valueAttribute":["test1","test2","test3"] "valueAttribute":["test1","test2","test3"]
} }
}},
{"playerId":"secondplayer",
"attributes":{
"mode":{
"attributeType":"STRING",
"valueAttribute":"testmode"
}
}} }}
]} ]}
] ]
@ -162,8 +169,11 @@ R"({
MOCK_METHOD0(OnSessionHealthCheck, bool()); MOCK_METHOD0(OnSessionHealthCheck, bool());
MOCK_METHOD1(OnCreateSessionBegin, bool(const AzFramework::SessionConfig&)); MOCK_METHOD1(OnCreateSessionBegin, bool(const AzFramework::SessionConfig&));
MOCK_METHOD0(OnCreateSessionEnd, void());
MOCK_METHOD0(OnDestroySessionBegin, bool()); MOCK_METHOD0(OnDestroySessionBegin, bool());
MOCK_METHOD0(OnDestroySessionEnd, void());
MOCK_METHOD2(OnUpdateSessionBegin, void(const AzFramework::SessionConfig&, const AZStd::string&)); MOCK_METHOD2(OnUpdateSessionBegin, void(const AzFramework::SessionConfig&, const AZStd::string&));
MOCK_METHOD0(OnUpdateSessionEnd, void());
}; };
class GameLiftServerManagerTest class GameLiftServerManagerTest
@ -254,6 +264,7 @@ R"({
EXPECT_CALL(handlerMock, OnDestroySessionBegin()).Times(1).WillOnce(testing::Return(false)); EXPECT_CALL(handlerMock, OnDestroySessionBegin()).Times(1).WillOnce(testing::Return(false));
EXPECT_CALL(*(m_serverManager->m_gameLiftServerSDKWrapperMockPtr), GetTerminationTime()).Times(1); EXPECT_CALL(*(m_serverManager->m_gameLiftServerSDKWrapperMockPtr), GetTerminationTime()).Times(1);
EXPECT_CALL(*(m_serverManager->m_gameLiftServerSDKWrapperMockPtr), ProcessEnding()).Times(0); EXPECT_CALL(*(m_serverManager->m_gameLiftServerSDKWrapperMockPtr), ProcessEnding()).Times(0);
EXPECT_CALL(handlerMock, OnDestroySessionEnd()).Times(0);
AZ_TEST_START_TRACE_SUPPRESSION; AZ_TEST_START_TRACE_SUPPRESSION;
m_serverManager->m_gameLiftServerSDKWrapperMockPtr->m_onProcessTerminateFunc(); m_serverManager->m_gameLiftServerSDKWrapperMockPtr->m_onProcessTerminateFunc();
@ -274,13 +285,40 @@ R"({
SessionNotificationsHandlerMock handlerMock; SessionNotificationsHandlerMock handlerMock;
EXPECT_CALL(handlerMock, OnDestroySessionBegin()).Times(1).WillOnce(testing::Return(true)); EXPECT_CALL(handlerMock, OnDestroySessionBegin()).Times(1).WillOnce(testing::Return(true));
EXPECT_CALL(*(m_serverManager->m_gameLiftServerSDKWrapperMockPtr), GetTerminationTime()).Times(1); EXPECT_CALL(*(m_serverManager->m_gameLiftServerSDKWrapperMockPtr), GetTerminationTime()).Times(1);
EXPECT_CALL(*(m_serverManager->m_gameLiftServerSDKWrapperMockPtr), ProcessEnding()).Times(1); EXPECT_CALL(*(m_serverManager->m_gameLiftServerSDKWrapperMockPtr), ProcessEnding())
.Times(1)
.WillOnce(testing::Return(Aws::GameLift::GenericOutcome(nullptr)));
EXPECT_CALL(handlerMock, OnDestroySessionEnd()).Times(1);
m_serverManager->m_gameLiftServerSDKWrapperMockPtr->m_onProcessTerminateFunc(); m_serverManager->m_gameLiftServerSDKWrapperMockPtr->m_onProcessTerminateFunc();
EXPECT_FALSE(AZ::Interface<AzFramework::ISessionHandlingProviderRequests>::Get()); EXPECT_FALSE(AZ::Interface<AzFramework::ISessionHandlingProviderRequests>::Get());
} }
TEST_F(GameLiftServerManagerTest, OnProcessTerminate_OnDestroySessionBeginReturnsTrue_TerminationNotificationSentButFail)
{
m_serverManager->InitializeGameLiftServerSDK();
m_serverManager->NotifyGameLiftProcessReady();
if (!AZ::Interface<AzFramework::ISessionHandlingProviderRequests>::Get())
{
AZ::Interface<AzFramework::ISessionHandlingProviderRequests>::Register(m_serverManager.get());
}
SessionNotificationsHandlerMock handlerMock;
EXPECT_CALL(handlerMock, OnDestroySessionBegin()).Times(1).WillOnce(testing::Return(true));
EXPECT_CALL(*(m_serverManager->m_gameLiftServerSDKWrapperMockPtr), GetTerminationTime()).Times(1);
EXPECT_CALL(*(m_serverManager->m_gameLiftServerSDKWrapperMockPtr), ProcessEnding())
.Times(1)
.WillOnce(testing::Return(Aws::GameLift::GenericOutcome()));
EXPECT_CALL(handlerMock, OnDestroySessionEnd()).Times(0);
AZ_TEST_START_TRACE_SUPPRESSION;
m_serverManager->m_gameLiftServerSDKWrapperMockPtr->m_onProcessTerminateFunc();
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
EXPECT_FALSE(AZ::Interface<AzFramework::ISessionHandlingProviderRequests>::Get());
}
TEST_F(GameLiftServerManagerTest, OnHealthCheck_OnSessionHealthCheckReturnsTrue_CallbackFunctionReturnsTrue) TEST_F(GameLiftServerManagerTest, OnHealthCheck_OnSessionHealthCheckReturnsTrue_CallbackFunctionReturnsTrue)
{ {
m_serverManager->InitializeGameLiftServerSDK(); m_serverManager->InitializeGameLiftServerSDK();
@ -316,6 +354,7 @@ R"({
m_serverManager->NotifyGameLiftProcessReady(); m_serverManager->NotifyGameLiftProcessReady();
SessionNotificationsHandlerMock handlerMock; SessionNotificationsHandlerMock handlerMock;
EXPECT_CALL(handlerMock, OnCreateSessionBegin(testing::_)).Times(1).WillOnce(testing::Return(false)); EXPECT_CALL(handlerMock, OnCreateSessionBegin(testing::_)).Times(1).WillOnce(testing::Return(false));
EXPECT_CALL(handlerMock, OnCreateSessionEnd()).Times(0);
EXPECT_CALL(handlerMock, OnDestroySessionBegin()).Times(1).WillOnce(testing::Return(true)); EXPECT_CALL(handlerMock, OnDestroySessionBegin()).Times(1).WillOnce(testing::Return(true));
EXPECT_CALL(*(m_serverManager->m_gameLiftServerSDKWrapperMockPtr), ProcessEnding()).Times(1); EXPECT_CALL(*(m_serverManager->m_gameLiftServerSDKWrapperMockPtr), ProcessEnding()).Times(1);
AZ_TEST_START_TRACE_SUPPRESSION; AZ_TEST_START_TRACE_SUPPRESSION;
@ -329,6 +368,7 @@ R"({
m_serverManager->NotifyGameLiftProcessReady(); m_serverManager->NotifyGameLiftProcessReady();
SessionNotificationsHandlerMock handlerMock; SessionNotificationsHandlerMock handlerMock;
EXPECT_CALL(handlerMock, OnCreateSessionBegin(testing::_)).Times(1).WillOnce(testing::Return(true)); EXPECT_CALL(handlerMock, OnCreateSessionBegin(testing::_)).Times(1).WillOnce(testing::Return(true));
EXPECT_CALL(handlerMock, OnCreateSessionEnd()).Times(1);
EXPECT_CALL(handlerMock, OnDestroySessionBegin()).Times(1).WillOnce(testing::Return(true)); EXPECT_CALL(handlerMock, OnDestroySessionBegin()).Times(1).WillOnce(testing::Return(true));
EXPECT_CALL(*(m_serverManager->m_gameLiftServerSDKWrapperMockPtr), ActivateGameSession()) EXPECT_CALL(*(m_serverManager->m_gameLiftServerSDKWrapperMockPtr), ActivateGameSession())
.Times(1) .Times(1)
@ -349,6 +389,7 @@ R"({
m_serverManager->NotifyGameLiftProcessReady(); m_serverManager->NotifyGameLiftProcessReady();
SessionNotificationsHandlerMock handlerMock; SessionNotificationsHandlerMock handlerMock;
EXPECT_CALL(handlerMock, OnCreateSessionBegin(testing::_)).Times(1).WillOnce(testing::Return(true)); EXPECT_CALL(handlerMock, OnCreateSessionBegin(testing::_)).Times(1).WillOnce(testing::Return(true));
EXPECT_CALL(handlerMock, OnCreateSessionEnd()).Times(0);
EXPECT_CALL(handlerMock, OnDestroySessionBegin()).Times(1).WillOnce(testing::Return(true)); EXPECT_CALL(handlerMock, OnDestroySessionBegin()).Times(1).WillOnce(testing::Return(true));
EXPECT_CALL(*(m_serverManager->m_gameLiftServerSDKWrapperMockPtr), ActivateGameSession()) EXPECT_CALL(*(m_serverManager->m_gameLiftServerSDKWrapperMockPtr), ActivateGameSession())
.Times(1) .Times(1)
@ -359,12 +400,13 @@ R"({
AZ_TEST_STOP_TRACE_SUPPRESSION(1); AZ_TEST_STOP_TRACE_SUPPRESSION(1);
} }
TEST_F(GameLiftServerManagerTest, OnUpdateGameSession_TriggerWithUnknownReason_OnUpdateSessionBeginGetCalledOnce) TEST_F(GameLiftServerManagerTest, OnUpdateGameSession_TriggerWithUnknownReason_OnUpdateSessionGetCalledOnce)
{ {
m_serverManager->InitializeGameLiftServerSDK(); m_serverManager->InitializeGameLiftServerSDK();
m_serverManager->NotifyGameLiftProcessReady(); m_serverManager->NotifyGameLiftProcessReady();
SessionNotificationsHandlerMock handlerMock; SessionNotificationsHandlerMock handlerMock;
EXPECT_CALL(handlerMock, OnUpdateSessionBegin(testing::_, testing::_)).Times(1); EXPECT_CALL(handlerMock, OnUpdateSessionBegin(testing::_, testing::_)).Times(1);
EXPECT_CALL(handlerMock, OnUpdateSessionEnd()).Times(1);
m_serverManager->m_gameLiftServerSDKWrapperMockPtr->m_onUpdateGameSessionFunc( m_serverManager->m_gameLiftServerSDKWrapperMockPtr->m_onUpdateGameSessionFunc(
Aws::GameLift::Server::Model::UpdateGameSession( Aws::GameLift::Server::Model::UpdateGameSession(
@ -373,12 +415,13 @@ R"({
"testticket")); "testticket"));
} }
TEST_F(GameLiftServerManagerTest, OnUpdateGameSession_TriggerWithEmptyMatchmakingData_OnUpdateSessionBeginGetCalledOnce) TEST_F(GameLiftServerManagerTest, OnUpdateGameSession_TriggerWithEmptyMatchmakingData_OnUpdateSessionGetCalledOnce)
{ {
m_serverManager->InitializeGameLiftServerSDK(); m_serverManager->InitializeGameLiftServerSDK();
m_serverManager->NotifyGameLiftProcessReady(); m_serverManager->NotifyGameLiftProcessReady();
SessionNotificationsHandlerMock handlerMock; SessionNotificationsHandlerMock handlerMock;
EXPECT_CALL(handlerMock, OnUpdateSessionBegin(testing::_, testing::_)).Times(1); EXPECT_CALL(handlerMock, OnUpdateSessionBegin(testing::_, testing::_)).Times(1);
EXPECT_CALL(handlerMock, OnUpdateSessionEnd()).Times(1);
m_serverManager->m_gameLiftServerSDKWrapperMockPtr->m_onUpdateGameSessionFunc( m_serverManager->m_gameLiftServerSDKWrapperMockPtr->m_onUpdateGameSessionFunc(
Aws::GameLift::Server::Model::UpdateGameSession( Aws::GameLift::Server::Model::UpdateGameSession(
@ -387,12 +430,13 @@ R"({
"testticket")); "testticket"));
} }
TEST_F(GameLiftServerManagerTest, OnUpdateGameSession_TriggerWithValidMatchmakingData_OnUpdateSessionBeginGetCalledOnce) TEST_F(GameLiftServerManagerTest, OnUpdateGameSession_TriggerWithValidMatchmakingData_OnUpdateSessionGetCalledOnce)
{ {
m_serverManager->InitializeGameLiftServerSDK(); m_serverManager->InitializeGameLiftServerSDK();
m_serverManager->NotifyGameLiftProcessReady(); m_serverManager->NotifyGameLiftProcessReady();
SessionNotificationsHandlerMock handlerMock; SessionNotificationsHandlerMock handlerMock;
EXPECT_CALL(handlerMock, OnUpdateSessionBegin(testing::_, testing::_)).Times(1); EXPECT_CALL(handlerMock, OnUpdateSessionBegin(testing::_, testing::_)).Times(1);
EXPECT_CALL(handlerMock, OnUpdateSessionEnd()).Times(1);
Aws::GameLift::Server::Model::GameSession gameSession; Aws::GameLift::Server::Model::GameSession gameSession;
gameSession.SetMatchmakerData(TEST_SERVER_MATCHMAKING_DATA); gameSession.SetMatchmakerData(TEST_SERVER_MATCHMAKING_DATA);
@ -401,12 +445,13 @@ R"({
gameSession, Aws::GameLift::Server::Model::UpdateReason::MATCHMAKING_DATA_UPDATED, "testticket")); gameSession, Aws::GameLift::Server::Model::UpdateReason::MATCHMAKING_DATA_UPDATED, "testticket"));
} }
TEST_F(GameLiftServerManagerTest, OnUpdateGameSession_TriggerWithInvalidMatchmakingData_OnUpdateSessionBeginGetCalledOnce) TEST_F(GameLiftServerManagerTest, OnUpdateGameSession_TriggerWithInvalidMatchmakingData_OnUpdateSessionGetCalledOnce)
{ {
m_serverManager->InitializeGameLiftServerSDK(); m_serverManager->InitializeGameLiftServerSDK();
m_serverManager->NotifyGameLiftProcessReady(); m_serverManager->NotifyGameLiftProcessReady();
SessionNotificationsHandlerMock handlerMock; SessionNotificationsHandlerMock handlerMock;
EXPECT_CALL(handlerMock, OnUpdateSessionBegin(testing::_, testing::_)).Times(1); EXPECT_CALL(handlerMock, OnUpdateSessionBegin(testing::_, testing::_)).Times(1);
EXPECT_CALL(handlerMock, OnUpdateSessionEnd()).Times(1);
Aws::GameLift::Server::Model::GameSession gameSession; Aws::GameLift::Server::Model::GameSession gameSession;
gameSession.SetMatchmakerData("{invalid}"); gameSession.SetMatchmakerData("{invalid}");

@ -288,6 +288,10 @@ namespace Multiplayer
return m_networkInterface->Listen(sessionConfig.m_port); return m_networkInterface->Listen(sessionConfig.m_port);
} }
void MultiplayerSystemComponent::OnCreateSessionEnd()
{
}
bool MultiplayerSystemComponent::OnDestroySessionBegin() bool MultiplayerSystemComponent::OnDestroySessionBegin()
{ {
// This can be triggered external from Multiplayer so only run if we are in an Initialized state // This can be triggered external from Multiplayer so only run if we are in an Initialized state
@ -308,12 +312,20 @@ namespace Multiplayer
return true; return true;
} }
void MultiplayerSystemComponent::OnDestroySessionEnd()
{
}
void MultiplayerSystemComponent::OnUpdateSessionBegin(const AzFramework::SessionConfig& sessionConfig, const AZStd::string& updateReason) void MultiplayerSystemComponent::OnUpdateSessionBegin(const AzFramework::SessionConfig& sessionConfig, const AZStd::string& updateReason)
{ {
AZ_UNUSED(sessionConfig); AZ_UNUSED(sessionConfig);
AZ_UNUSED(updateReason); AZ_UNUSED(updateReason);
} }
void MultiplayerSystemComponent::OnUpdateSessionEnd()
{
}
void MultiplayerSystemComponent::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time) void MultiplayerSystemComponent::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time)
{ {
const AZ::TimeMs deltaTimeMs = aznumeric_cast<AZ::TimeMs>(static_cast<int32_t>(deltaTime * 1000.0f)); const AZ::TimeMs deltaTimeMs = aznumeric_cast<AZ::TimeMs>(static_cast<int32_t>(deltaTime * 1000.0f));

@ -69,8 +69,11 @@ namespace Multiplayer
//! @{ //! @{
bool OnSessionHealthCheck() override; bool OnSessionHealthCheck() override;
bool OnCreateSessionBegin(const AzFramework::SessionConfig& sessionConfig) override; bool OnCreateSessionBegin(const AzFramework::SessionConfig& sessionConfig) override;
void OnCreateSessionEnd() override;
bool OnDestroySessionBegin() override; bool OnDestroySessionBegin() override;
void OnDestroySessionEnd() override;
void OnUpdateSessionBegin(const AzFramework::SessionConfig& sessionConfig, const AZStd::string& updateReason) override; void OnUpdateSessionBegin(const AzFramework::SessionConfig& sessionConfig, const AZStd::string& updateReason) override;
void OnUpdateSessionEnd() override;
//! @} //! @}
//! AZ::TickBus::Handler overrides. //! AZ::TickBus::Handler overrides.

Loading…
Cancel
Save