[LYN-7530] Fix matchmaking request type typo and add more matchmaking notifications (#4774)

* [LYN-7530] Fix matchmaking request type typo and add more matchmaking notifications

Signed-off-by: onecent1101 <liug@amazon.com>
This commit is contained in:
Vincent Liu
2021-10-20 13:11:12 -07:00
committed by GitHub
parent 60c286dafa
commit 8e797982a5
18 changed files with 303 additions and 181 deletions
@@ -43,7 +43,7 @@ namespace AzFramework
class IMatchmakingAsyncRequests
{
public:
AZ_RTTI(ISessionAsyncRequests, "{53513480-2D02-493C-B44E-96AA27F42429}");
AZ_RTTI(IMatchmakingAsyncRequests, "{53513480-2D02-493C-B44E-96AA27F42429}");
IMatchmakingAsyncRequests() = default;
virtual ~IMatchmakingAsyncRequests() = default;
@@ -60,4 +60,31 @@ namespace AzFramework
// @param stopMatchmakingRequest The request of StopMatchmaking operation
virtual void StopMatchmakingAsync(const StopMatchmakingRequest& stopMatchmakingRequest) = 0;
};
//! MatchmakingAsyncRequestNotifications
//! The notifications correspond to matchmaking async requests
class MatchmakingAsyncRequestNotifications
: public AZ::EBusTraits
{
public:
// Safeguard handler for multi-threaded use case
using MutexType = AZStd::recursive_mutex;
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
// OnAcceptMatchAsyncComplete is fired once AcceptMatchAsync completes
virtual void OnAcceptMatchAsyncComplete() = 0;
// OnStartMatchmakingAsyncComplete is fired once StartMatchmakingAsync completes
// @param matchmakingTicketId The unique identifier for the matchmaking ticket
virtual void OnStartMatchmakingAsyncComplete(const AZStd::string& matchmakingTicketId) = 0;
// OnStopMatchmakingAsyncComplete is fired once StopMatchmakingAsync completes
virtual void OnStopMatchmakingAsyncComplete() = 0;
};
using MatchmakingAsyncRequestNotificationBus = AZ::EBus<MatchmakingAsyncRequestNotifications>;
} // namespace AzFramework
@@ -13,36 +13,10 @@
namespace AzFramework
{
//! MatchmakingAsyncRequestNotifications
//! The notifications correspond to matchmaking async requests
class MatchmakingAsyncRequestNotifications
: public AZ::EBusTraits
{
public:
// Safeguard handler for multi-threaded use case
using MutexType = AZStd::recursive_mutex;
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
// OnAcceptMatchAsyncComplete is fired once AcceptMatchAsync completes
virtual void OnAcceptMatchAsyncComplete() = 0;
// OnStartMatchmakingAsyncComplete is fired once StartMatchmakingAsync completes
// @param matchmakingTicketId The unique identifier for the matchmaking ticket
virtual void OnStartMatchmakingAsyncComplete(const AZStd::string& matchmakingTicketId) = 0;
// OnStopMatchmakingAsyncComplete is fired once StopMatchmakingAsync completes
virtual void OnStopMatchmakingAsyncComplete() = 0;
};
using MatchmakingAsyncRequestNotificationBus = AZ::EBus<MatchmakingAsyncRequestNotifications>;
//! MatchmakingNotifications
//! The matchmaking notifications to listen for performing required operations
class MatchAcceptanceNotifications
//! based on matchmaking ticket event
class MatchmakingNotifications
: public AZ::EBusTraits
{
public:
@@ -55,8 +29,18 @@ namespace AzFramework
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
// OnMatchAcceptance is fired when DescribeMatchmaking ticket status is REQUIRES_ACCEPTANCE
// OnMatchAcceptance is fired when match is found and pending on acceptance
// Use this notification to accept found match
virtual void OnMatchAcceptance() = 0;
// OnMatchComplete is fired when match is complete
virtual void OnMatchComplete() = 0;
// OnMatchError is fired when match is processed with error
virtual void OnMatchError() = 0;
// OnMatchFailure is fired when match is failed to complete
virtual void OnMatchFailure() = 0;
};
using MatchAcceptanceNotificationBus = AZ::EBus<MatchAcceptanceNotifications>;
using MatchmakingNotificationBus = AZ::EBus<MatchmakingNotifications>;
} // namespace AzFramework
@@ -5,75 +5,16 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/std/string/string.h>
#include <AzFramework/Matchmaking/IMatchmakingRequests.h>
#include <AzFramework/Session/ISessionRequests.h>
namespace AWSGameLift
{
//! IAWSGameLiftRequests
//! GameLift Gem interfaces to configure client manager
class IAWSGameLiftRequests
{
public:
AZ_RTTI(IAWSGameLiftRequests, "{494167AD-1185-4AF3-8BF9-C8C37FC9C199}");
IAWSGameLiftRequests() = default;
virtual ~IAWSGameLiftRequests() = default;
//! ConfigureGameLiftClient
//! Configure GameLift client to interact with Amazon GameLift service
//! @param region Specifies the AWS region to use
//! @return True if client configuration succeeds, false otherwise
virtual bool ConfigureGameLiftClient(const AZStd::string& region) = 0;
//! CreatePlayerId
//! Create a new, random ID number for every player in every new game session.
//! @param includeBrackets Whether includes brackets in player id
//! @param includeDashes Whether includes dashes in player id
//! @return The player id to use in game session
virtual AZStd::string CreatePlayerId(bool includeBrackets, bool includeDashes) = 0;
};
// IAWSGameLiftRequests EBus wrapper for scripting
class AWSGameLiftRequests
: 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 AWSGameLiftRequestBus = AZ::EBus<IAWSGameLiftRequests, AWSGameLiftRequests>;
// ISessionAsyncRequests EBus wrapper for scripting
class AWSGameLiftSessionAsyncRequests
: 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 AWSGameLiftSessionAsyncRequestBus = AZ::EBus<AzFramework::ISessionAsyncRequests, AWSGameLiftSessionAsyncRequests>;
// ISessionRequests EBus wrapper for scripting
class AWSGameLiftSessionRequests
: 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 AWSGameLiftSessionRequestBus = AZ::EBus<AzFramework::ISessionRequests, AWSGameLiftSessionRequests>;
// IMatchmakingAsyncRequests EBus wrapper for scripting
// IMatchmakingAsyncRequests EBus wrapper
class AWSGameLiftMatchmakingAsyncRequests
: public AZ::EBusTraits
{
@@ -84,7 +25,7 @@ namespace AWSGameLift
};
using AWSGameLiftMatchmakingAsyncRequestBus = AZ::EBus<AzFramework::IMatchmakingAsyncRequests, AWSGameLiftMatchmakingAsyncRequests>;
// IMatchmakingRequests EBus wrapper for scripting
// IMatchmakingRequests EBus wrapper
class AWSGameLiftMatchmakingRequests
: public AZ::EBusTraits
{
@@ -121,7 +62,7 @@ namespace AWSGameLift
virtual void StopPolling() = 0;
};
// IAWSGameLiftMatchmakingEventRequests EBus wrapper for scripting
// IAWSGameLiftMatchmakingEventRequests EBus wrapper
class AWSGameLiftMatchmakingEventRequests
: public AZ::EBusTraits
{
@@ -0,0 +1,51 @@
/*
* 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/EBus/EBus.h>
#include <AzCore/std/string/string.h>
namespace AWSGameLift
{
//! IAWSGameLiftRequests
//! GameLift Gem interfaces to configure GameLift client and other help functions,
//! like creating random GameLift player id
class IAWSGameLiftRequests
{
public:
AZ_RTTI(IAWSGameLiftRequests, "{494167AD-1185-4AF3-8BF9-C8C37FC9C199}");
IAWSGameLiftRequests() = default;
virtual ~IAWSGameLiftRequests() = default;
//! ConfigureGameLiftClient
//! Configure GameLift client to interact with Amazon GameLift service
//! @param region Specifies the AWS region to use
//! @return True if client configuration succeeds, false otherwise
virtual bool ConfigureGameLiftClient(const AZStd::string& region) = 0;
//! CreatePlayerId
//! Create a new, random ID number for every player in every new game session.
//! @param includeBrackets Whether includes brackets in player id
//! @param includeDashes Whether includes dashes in player id
//! @return The player id to use in game session
virtual AZStd::string CreatePlayerId(bool includeBrackets, bool includeDashes) = 0;
};
// IAWSGameLiftRequests EBus wrapper
class AWSGameLiftRequests
: 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 AWSGameLiftRequestBus = AZ::EBus<IAWSGameLiftRequests, AWSGameLiftRequests>;
} // namespace AWSGameLift
@@ -0,0 +1,38 @@
/*
* 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/EBus/EBus.h>
#include <AzCore/std/string/string.h>
#include <AzFramework/Session/ISessionRequests.h>
namespace AWSGameLift
{
// ISessionAsyncRequests EBus wrapper
class AWSGameLiftSessionAsyncRequests
: 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 AWSGameLiftSessionAsyncRequestBus = AZ::EBus<AzFramework::ISessionAsyncRequests, AWSGameLiftSessionAsyncRequests>;
// ISessionRequests EBus wrapper
class AWSGameLiftSessionRequests
: 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 AWSGameLiftSessionRequestBus = AZ::EBus<AzFramework::ISessionRequests, AWSGameLiftSessionRequests>;
} // namespace AWSGameLift
@@ -97,6 +97,7 @@ namespace AWSGameLift
AZ_TracePrintf(AWSGameLiftClientLocalTicketTrackerName,
"Matchmaking ticket %s is complete.", ticket.GetTicketId().c_str());
RequestPlayerJoinMatch(ticket, playerId);
AzFramework::MatchmakingNotificationBus::Broadcast(&AzFramework::MatchmakingNotifications::OnMatchComplete);
m_status = TicketTrackerStatus::Idle;
return;
}
@@ -104,25 +105,28 @@ namespace AWSGameLift
ticket.GetStatus() == Aws::GameLift::Model::MatchmakingConfigurationStatus::FAILED ||
ticket.GetStatus() == Aws::GameLift::Model::MatchmakingConfigurationStatus::CANCELLED)
{
AZ_Error(AWSGameLiftClientLocalTicketTrackerName, false, "Matchmaking ticket %s is not complete, %s",
ticket.GetTicketId().c_str(), ticket.GetStatusReason().c_str());
AZ_Warning(AWSGameLiftClientLocalTicketTrackerName, false, "Matchmaking ticket %s is not complete, %s",
ticket.GetTicketId().c_str(), ticket.GetStatusMessage().c_str());
AzFramework::MatchmakingNotificationBus::Broadcast(&AzFramework::MatchmakingNotifications::OnMatchFailure);
m_status = TicketTrackerStatus::Idle;
return;
}
else if (ticket.GetStatus() == Aws::GameLift::Model::MatchmakingConfigurationStatus::REQUIRES_ACCEPTANCE)
{
// broadcast acceptance requires to player
AzFramework::MatchAcceptanceNotificationBus::Broadcast(&AzFramework::MatchAcceptanceNotifications::OnMatchAcceptance);
AZ_TracePrintf(AWSGameLiftClientLocalTicketTrackerName, "Matchmaking ticket %s is pending on acceptance, %s.",
ticket.GetTicketId().c_str(), ticket.GetStatusMessage().c_str());
AzFramework::MatchmakingNotificationBus::Broadcast(&AzFramework::MatchmakingNotifications::OnMatchAcceptance);
}
else
{
AZ_TracePrintf(AWSGameLiftClientLocalTicketTrackerName, "Matchmaking ticket %s is processing, %s.",
ticket.GetTicketId().c_str(), ticket.GetStatusReason().c_str());
ticket.GetTicketId().c_str(), ticket.GetStatusMessage().c_str());
}
}
else
{
AZ_Error(AWSGameLiftClientLocalTicketTrackerName, false, "Unable to find expected ticket with id %s", ticketId.c_str());
AzFramework::MatchmakingNotificationBus::Broadcast(&AzFramework::MatchmakingNotifications::OnMatchError);
}
}
else
@@ -130,11 +134,13 @@ namespace AWSGameLift
AZ_Error(AWSGameLiftClientLocalTicketTrackerName, false, AWSGameLiftErrorMessageTemplate,
describeMatchmakingOutcome.GetError().GetExceptionName().c_str(),
describeMatchmakingOutcome.GetError().GetMessage().c_str());
AzFramework::MatchmakingNotificationBus::Broadcast(&AzFramework::MatchmakingNotifications::OnMatchError);
}
}
else
{
AZ_Error(AWSGameLiftClientLocalTicketTrackerName, false, AWSGameLiftClientMissingErrorMessage);
AzFramework::MatchmakingNotificationBus::Broadcast(&AzFramework::MatchmakingNotifications::OnMatchError);
}
m_waitEvent.try_acquire_for(AZStd::chrono::milliseconds(m_pollingPeriodInMS));
}
@@ -12,7 +12,7 @@
#include <AzCore/std/parallel/mutex.h>
#include <AzCore/std/parallel/thread.h>
#include <Request/IAWSGameLiftRequests.h>
#include <Request/AWSGameLiftMatchmakingRequestBus.h>
#include <aws/gamelift/model/MatchmakingTicket.h>
@@ -14,6 +14,7 @@
#include <AWSCoreBus.h>
#include <Credential/AWSCredentialBus.h>
#include <Framework/AWSApiJobConfig.h>
#include <ResourceMapping/AWSResourceMappingBus.h>
#include <AWSGameLiftClientManager.h>
@@ -75,7 +76,15 @@ namespace AWSGameLift
bool AWSGameLiftClientManager::ConfigureGameLiftClient(const AZStd::string& region)
{
AZ::Interface<IAWSGameLiftInternalRequests>::Get()->SetGameLiftClient(nullptr);
Aws::Client::ClientConfiguration clientConfig;
AWSCore::AwsApiJobConfig* defaultConfig = nullptr;
AWSCore::AWSCoreRequestBus::BroadcastResult(defaultConfig, &AWSCore::AWSCoreRequests::GetDefaultConfig);
if (defaultConfig)
{
clientConfig = defaultConfig->GetClientConfiguration();
}
// Set up client endpoint or region
AZStd::string localEndpoint = "";
#if defined(AWSGAMELIFT_DEV)
@@ -8,10 +8,13 @@
#pragma once
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <AzFramework/Matchmaking/MatchmakingNotifications.h>
#include <Request/IAWSGameLiftRequests.h>
#include <Request/AWSGameLiftRequestBus.h>
#include <Request/AWSGameLiftSessionRequestBus.h>
#include <Request/AWSGameLiftMatchmakingRequestBus.h>
namespace AWSGameLift
{
@@ -23,22 +26,37 @@ namespace AWSGameLift
struct AWSGameLiftStartMatchmakingRequest;
struct AWSGameLiftStopMatchmakingRequest;
// MatchAcceptanceNotificationBus EBus handler for scripting
class AWSGameLiftMatchAcceptanceNotificationBusHandler
: public AzFramework::MatchAcceptanceNotificationBus::Handler
// MatchmakingNotificationBus EBus handler for scripting
class AWSGameLiftMatchmakingNotificationBusHandler
: public AzFramework::MatchmakingNotificationBus::Handler
, public AZ::BehaviorEBusHandler
{
public:
AZ_EBUS_BEHAVIOR_BINDER(
AWSGameLiftMatchAcceptanceNotificationBusHandler,
AWSGameLiftMatchmakingNotificationBusHandler,
"{CBE057D3-F5CE-46D3-B02D-8A6A1446B169}",
AZ::SystemAllocator,
OnMatchAcceptance);
OnMatchAcceptance, OnMatchComplete, OnMatchError, OnMatchFailure);
void OnMatchAcceptance() override
{
Call(FN_OnMatchAcceptance);
}
void OnMatchComplete() override
{
Call(FN_OnMatchComplete);
}
void OnMatchError() override
{
Call(FN_OnMatchError);
}
void OnMatchFailure() override
{
Call(FN_OnMatchFailure);
}
};
// MatchmakingAsyncRequestNotificationBus EBus handler for scripting
@@ -65,13 +65,6 @@ namespace AWSGameLift
->Event("CreatePlayerId", &AWSGameLiftRequestBus::Events::CreatePlayerId,
{ { { "IncludeBrackets", "" },
{ "IncludeDashes", "" } } });
behaviorContext->EBus<AWSGameLiftMatchmakingEventRequestBus>("AWSGameLiftMatchmakingEventRequestBus")
->Attribute(AZ::Script::Attributes::Category, "AWSGameLift")
->Event("StartPolling", &AWSGameLiftMatchmakingEventRequestBus::Events::StartPolling,
{ { { "TicketId", "" },
{ "PlayerId", "" } } })
->Event("StopPolling", &AWSGameLiftMatchmakingEventRequestBus::Events::StopPolling);
}
}
@@ -128,7 +121,7 @@ namespace AWSGameLift
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->EBus<AWSGameLiftMatchmakingAsyncRequestBus>("AWSGameLiftMatchmakingAsyncRequestBus")
->Attribute(AZ::Script::Attributes::Category, "AWSGameLift")
->Attribute(AZ::Script::Attributes::Category, "AWSGameLift/Matchmaking")
->Event("AcceptMatchAsync", &AWSGameLiftMatchmakingAsyncRequestBus::Events::AcceptMatchAsync,
{ { { "AcceptMatchRequest", "" } } })
->Event("StartMatchmakingAsync", &AWSGameLiftMatchmakingAsyncRequestBus::Events::StartMatchmakingAsync,
@@ -137,20 +130,28 @@ namespace AWSGameLift
{ { { "StopMatchmakingRequest", "" } } });
behaviorContext->EBus<AzFramework::MatchmakingAsyncRequestNotificationBus>("AWSGameLiftMatchmakingAsyncRequestNotificationBus")
->Attribute(AZ::Script::Attributes::Category, "AWSGameLift")
->Attribute(AZ::Script::Attributes::Category, "AWSGameLift/Matchmaking")
->Handler<AWSGameLiftMatchmakingAsyncRequestNotificationBusHandler>();
behaviorContext->EBus<AWSGameLiftMatchmakingRequestBus>("AWSGameLiftMatchmakingRequestBus")
->Attribute(AZ::Script::Attributes::Category, "AWSGameLift")
->Event("AcceptMatch", &AWSGameLiftMatchmakingRequestBus::Events::AcceptMatch, { { { "AcceptMatchRequest", "" } } })
->Attribute(AZ::Script::Attributes::Category, "AWSGameLift/Matchmaking")
->Event("AcceptMatch", &AWSGameLiftMatchmakingRequestBus::Events::AcceptMatch,
{ { { "AcceptMatchRequest", "" } } })
->Event("StartMatchmaking", &AWSGameLiftMatchmakingRequestBus::Events::StartMatchmaking,
{ { { "StartMatchmakingRequest", "" } } })
->Event("StopMatchmaking", &AWSGameLiftMatchmakingRequestBus::Events::StopMatchmaking,
{ { { "StopMatchmakingRequest", "" } } });
behaviorContext->EBus<AzFramework::MatchAcceptanceNotificationBus>("AWSGameLiftMatchAcceptanceNotificationBus")
->Attribute(AZ::Script::Attributes::Category, "AWSGameLift")
->Handler<AWSGameLiftMatchAcceptanceNotificationBusHandler>();
behaviorContext->EBus<AWSGameLiftMatchmakingEventRequestBus>("AWSGameLiftMatchmakingEventRequestBus")
->Attribute(AZ::Script::Attributes::Category, "AWSGameLift/Matchmaking")
->Event("StartPolling", &AWSGameLiftMatchmakingEventRequestBus::Events::StartPolling,
{ { { "TicketId", "" },
{ "PlayerId", "" } } })
->Event("StopPolling", &AWSGameLiftMatchmakingEventRequestBus::Events::StopPolling);
behaviorContext->EBus<AzFramework::MatchmakingNotificationBus>("AWSGameLiftMatchmakingNotificationBus")
->Attribute(AZ::Script::Attributes::Category, "AWSGameLift/Matchmaking")
->Handler<AWSGameLiftMatchmakingNotificationBusHandler>();
}
}
@@ -166,7 +167,7 @@ namespace AWSGameLift
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->EBus<AWSGameLiftSessionAsyncRequestBus>("AWSGameLiftSessionAsyncRequestBus")
->Attribute(AZ::Script::Attributes::Category, "AWSGameLift")
->Attribute(AZ::Script::Attributes::Category, "AWSGameLift/Session")
->Event("CreateSessionAsync", &AWSGameLiftSessionAsyncRequestBus::Events::CreateSessionAsync,
{ { { "CreateSessionRequest", "" } } })
->Event("JoinSessionAsync", &AWSGameLiftSessionAsyncRequestBus::Events::JoinSessionAsync, { { { "JoinSessionRequest", "" } } })
@@ -175,11 +176,11 @@ namespace AWSGameLift
->Event("LeaveSessionAsync", &AWSGameLiftSessionAsyncRequestBus::Events::LeaveSessionAsync);
behaviorContext->EBus<AzFramework::SessionAsyncRequestNotificationBus>("AWSGameLiftSessionAsyncRequestNotificationBus")
->Attribute(AZ::Script::Attributes::Category, "AWSGameLift")
->Attribute(AZ::Script::Attributes::Category, "AWSGameLift/Session")
->Handler<AWSGameLiftSessionAsyncRequestNotificationBusHandler>();
behaviorContext->EBus<AWSGameLiftSessionRequestBus>("AWSGameLiftSessionRequestBus")
->Attribute(AZ::Script::Attributes::Category, "AWSGameLift")
->Attribute(AZ::Script::Attributes::Category, "AWSGameLift/Session")
->Event("CreateSession", &AWSGameLiftSessionRequestBus::Events::CreateSession, { { { "CreateSessionRequest", "" } } })
->Event("JoinSession", &AWSGameLiftSessionRequestBus::Events::JoinSession, { { { "JoinSessionRequest", "" } } })
->Event("SearchSessions", &AWSGameLiftSessionRequestBus::Events::SearchSessions, { { { "SearchSessionsRequest", "" } } })
@@ -20,7 +20,7 @@ namespace Aws
namespace AWSGameLift
{
//! IAWSGameLiftRequests
//! IAWSGameLiftInternalRequests
//! GameLift Gem internal interface which is used to fetch gem global GameLift client
class IAWSGameLiftInternalRequests
{
@@ -82,27 +82,12 @@ protected:
m_gameliftClientMockPtr.reset();
}
void WaitForProcessFinish(uint64_t expectedNum)
void WaitForProcessFinish(AZStd::function<bool()> processFinishCondition)
{
int processingTime = 0;
while (processingTime < TEST_WAIT_MAXIMUM_TIME_MS)
{
if (::UnitTest::TestRunner::Instance().m_numAssertsFailed == expectedNum)
{
AZ_TEST_STOP_TRACE_SUPPRESSION(expectedNum);
return;
}
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(TEST_WAIT_BUFFER_TIME_MS));
processingTime += TEST_WAIT_BUFFER_TIME_MS;
}
}
void WaitForProcessFinish()
{
int processingTime = 0;
while (processingTime < TEST_WAIT_MAXIMUM_TIME_MS)
{
if (m_gameliftClientTicketTracker->IsTrackerIdle())
if (processFinishCondition())
{
return;
}
@@ -119,19 +104,27 @@ public:
TEST_F(AWSGameLiftClientLocalTicketTrackerTest, StartPolling_CallWithoutClientSetup_GetExpectedErrors)
{
AZ::Interface<IAWSGameLiftInternalRequests>::Get()->SetGameLiftClient(nullptr);
MatchmakingNotificationsHandlerMock matchmakingHandlerMock;
AZ_TEST_START_TRACE_SUPPRESSION;
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
WaitForProcessFinish(1);
WaitForProcessFinish([](){ return ::UnitTest::TestRunner::Instance().m_numAssertsFailed == 1; });
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
ASSERT_TRUE(matchmakingHandlerMock.m_numMatchError == 1);
ASSERT_FALSE(m_gameliftClientTicketTracker->IsTrackerIdle());
}
TEST_F(AWSGameLiftClientLocalTicketTrackerTest, StartPolling_MultipleCallsWithoutClientSetup_GetExpectedErrors)
{
AZ::Interface<IAWSGameLiftInternalRequests>::Get()->SetGameLiftClient(nullptr);
MatchmakingNotificationsHandlerMock matchmakingHandlerMock;
AZ_TEST_START_TRACE_SUPPRESSION;
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
WaitForProcessFinish(1);
WaitForProcessFinish([](){ return ::UnitTest::TestRunner::Instance().m_numAssertsFailed == 1; });
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
ASSERT_TRUE(matchmakingHandlerMock.m_numMatchError == 1);
ASSERT_FALSE(m_gameliftClientTicketTracker->IsTrackerIdle());
}
@@ -144,9 +137,12 @@ TEST_F(AWSGameLiftClientLocalTicketTrackerTest, StartPolling_CallButWithFailedOu
.Times(1)
.WillOnce(::testing::Return(outcome));
MatchmakingNotificationsHandlerMock matchmakingHandlerMock;
AZ_TEST_START_TRACE_SUPPRESSION;
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
WaitForProcessFinish(1);
WaitForProcessFinish([](){ return ::UnitTest::TestRunner::Instance().m_numAssertsFailed == 1; });
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
ASSERT_TRUE(matchmakingHandlerMock.m_numMatchError == 1);
ASSERT_FALSE(m_gameliftClientTicketTracker->IsTrackerIdle());
}
@@ -161,9 +157,12 @@ TEST_F(AWSGameLiftClientLocalTicketTrackerTest, StartPolling_CallWithMoreThanOne
.Times(1)
.WillOnce(::testing::Return(outcome));
MatchmakingNotificationsHandlerMock matchmakingHandlerMock;
AZ_TEST_START_TRACE_SUPPRESSION;
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
WaitForProcessFinish(1);
WaitForProcessFinish([](){ return ::UnitTest::TestRunner::Instance().m_numAssertsFailed == 1; });
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
ASSERT_TRUE(matchmakingHandlerMock.m_numMatchError == 1);
ASSERT_FALSE(m_gameliftClientTicketTracker->IsTrackerIdle());
}
@@ -189,13 +188,15 @@ TEST_F(AWSGameLiftClientLocalTicketTrackerTest, StartPolling_CallWithCompleteSta
.Times(1)
.WillOnce(::testing::Return(outcome));
SessionHandlingClientRequestsMock handlerMock;
EXPECT_CALL(handlerMock, RequestPlayerJoinSession(::testing::_))
SessionHandlingClientRequestsMock sessionHandlerMock;
EXPECT_CALL(sessionHandlerMock, RequestPlayerJoinSession(::testing::_))
.Times(1)
.WillOnce(::testing::Return(true));
MatchmakingNotificationsHandlerMock matchmakingHandlerMock;
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
WaitForProcessFinish();
WaitForProcessFinish([this](){ return m_gameliftClientTicketTracker->IsTrackerIdle(); });
ASSERT_TRUE(matchmakingHandlerMock.m_numMatchComplete == 1);
ASSERT_TRUE(m_gameliftClientTicketTracker->IsTrackerIdle());
}
@@ -217,9 +218,12 @@ TEST_F(AWSGameLiftClientLocalTicketTrackerTest, StartPolling_CallButNoPlayerSess
.Times(1)
.WillOnce(::testing::Return(outcome));
MatchmakingNotificationsHandlerMock matchmakingHandlerMock;
AZ_TEST_START_TRACE_SUPPRESSION;
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
WaitForProcessFinish(1);
WaitForProcessFinish([this](){ return m_gameliftClientTicketTracker->IsTrackerIdle(); });
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
ASSERT_TRUE(matchmakingHandlerMock.m_numMatchComplete == 1);
ASSERT_TRUE(m_gameliftClientTicketTracker->IsTrackerIdle());
}
@@ -245,14 +249,17 @@ TEST_F(AWSGameLiftClientLocalTicketTrackerTest, StartPolling_CallButFailedToJoin
.Times(1)
.WillOnce(::testing::Return(outcome));
SessionHandlingClientRequestsMock handlerMock;
EXPECT_CALL(handlerMock, RequestPlayerJoinSession(::testing::_))
SessionHandlingClientRequestsMock sessionHandlerMock;
EXPECT_CALL(sessionHandlerMock, RequestPlayerJoinSession(::testing::_))
.Times(1)
.WillOnce(::testing::Return(false));
MatchmakingNotificationsHandlerMock matchmakingHandlerMock;
AZ_TEST_START_TRACE_SUPPRESSION;
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
WaitForProcessFinish(1);
WaitForProcessFinish([this](){ return m_gameliftClientTicketTracker->IsTrackerIdle(); });
AZ_TEST_STOP_TRACE_SUPPRESSION(1);
ASSERT_TRUE(matchmakingHandlerMock.m_numMatchComplete == 1);
ASSERT_TRUE(m_gameliftClientTicketTracker->IsTrackerIdle());
}
@@ -269,9 +276,10 @@ TEST_F(AWSGameLiftClientLocalTicketTrackerTest, StartPolling_CallButTicketTimeOu
.Times(1)
.WillOnce(::testing::Return(outcome));
AZ_TEST_START_TRACE_SUPPRESSION;
MatchmakingNotificationsHandlerMock matchmakingHandlerMock;
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
WaitForProcessFinish(1);
WaitForProcessFinish([this](){ return m_gameliftClientTicketTracker->IsTrackerIdle(); });
ASSERT_TRUE(matchmakingHandlerMock.m_numMatchFailure == 1);
ASSERT_TRUE(m_gameliftClientTicketTracker->IsTrackerIdle());
}
@@ -288,9 +296,10 @@ TEST_F(AWSGameLiftClientLocalTicketTrackerTest, StartPolling_CallButTicketFailed
.Times(1)
.WillOnce(::testing::Return(outcome));
AZ_TEST_START_TRACE_SUPPRESSION;
MatchmakingNotificationsHandlerMock matchmakingHandlerMock;
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
WaitForProcessFinish(1);
WaitForProcessFinish([this](){ return m_gameliftClientTicketTracker->IsTrackerIdle(); });
ASSERT_TRUE(matchmakingHandlerMock.m_numMatchFailure == 1);
ASSERT_TRUE(m_gameliftClientTicketTracker->IsTrackerIdle());
}
@@ -307,9 +316,10 @@ TEST_F(AWSGameLiftClientLocalTicketTrackerTest, StartPolling_CallButTicketCancel
.Times(1)
.WillOnce(::testing::Return(outcome));
AZ_TEST_START_TRACE_SUPPRESSION;
MatchmakingNotificationsHandlerMock matchmakingHandlerMock;
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
WaitForProcessFinish(1);
WaitForProcessFinish([this](){ return m_gameliftClientTicketTracker->IsTrackerIdle(); });
ASSERT_TRUE(matchmakingHandlerMock.m_numMatchFailure == 1);
ASSERT_TRUE(m_gameliftClientTicketTracker->IsTrackerIdle());
}
@@ -342,13 +352,15 @@ TEST_F(AWSGameLiftClientLocalTicketTrackerTest, StartPolling_CallAndTicketComple
.WillOnce(::testing::Return(outcome1))
.WillOnce(::testing::Return(outcome2));
SessionHandlingClientRequestsMock handlerMock;
EXPECT_CALL(handlerMock, RequestPlayerJoinSession(::testing::_))
SessionHandlingClientRequestsMock sessionHandlerMock;
EXPECT_CALL(sessionHandlerMock, RequestPlayerJoinSession(::testing::_))
.Times(1)
.WillOnce(::testing::Return(true));
MatchmakingNotificationsHandlerMock matchmakingHandlerMock;
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
WaitForProcessFinish();
WaitForProcessFinish([this](){ return m_gameliftClientTicketTracker->IsTrackerIdle(); });
ASSERT_TRUE(matchmakingHandlerMock.m_numMatchComplete == 1);
ASSERT_TRUE(m_gameliftClientTicketTracker->IsTrackerIdle());
}
@@ -365,7 +377,9 @@ TEST_F(AWSGameLiftClientLocalTicketTrackerTest, StartPolling_RequiresAcceptanceA
connectionInfo.SetIpAddress("DummyIpAddress");
connectionInfo.SetPort(123);
connectionInfo.AddMatchedPlayerSessions(
Aws::GameLift::Model::MatchedPlayerSession().WithPlayerId("player1").WithPlayerSessionId("playersession1"));
Aws::GameLift::Model::MatchedPlayerSession()
.WithPlayerId("player1")
.WithPlayerSessionId("playersession1"));
Aws::GameLift::Model::MatchmakingTicket ticket2;
ticket2.SetStatus(Aws::GameLift::Model::MatchmakingConfigurationStatus::COMPLETED);
@@ -379,13 +393,15 @@ TEST_F(AWSGameLiftClientLocalTicketTrackerTest, StartPolling_RequiresAcceptanceA
.WillOnce(::testing::Return(outcome1))
.WillOnce(::testing::Return(outcome2));
MatchAcceptanceNotificationsHandlerMock handlerMock1;
EXPECT_CALL(handlerMock1, OnMatchAcceptance()).Times(1);
SessionHandlingClientRequestsMock handlerMock2;
EXPECT_CALL(handlerMock2, RequestPlayerJoinSession(::testing::_)).Times(1).WillOnce(::testing::Return(true));
SessionHandlingClientRequestsMock sessionHandlerMock;
EXPECT_CALL(sessionHandlerMock, RequestPlayerJoinSession(::testing::_))
.Times(1)
.WillOnce(::testing::Return(true));
MatchmakingNotificationsHandlerMock matchmakingHandlerMock;
m_gameliftClientTicketTracker->StartPolling("ticket1", "player1");
WaitForProcessFinish();
WaitForProcessFinish([this](){ return m_gameliftClientTicketTracker->IsTrackerIdle(); });
ASSERT_TRUE(matchmakingHandlerMock.m_numMatchAcceptance == 1);
ASSERT_TRUE(matchmakingHandlerMock.m_numMatchComplete == 1);
ASSERT_TRUE(m_gameliftClientTicketTracker->IsTrackerIdle());
}
@@ -266,6 +266,8 @@ const char* const AWSGameLiftClientManagerTest::DummyPlayerId = "dummyPlayerId";
TEST_F(AWSGameLiftClientManagerTest, ConfigureGameLiftClient_CallWithoutRegion_GetFalseAsResult)
{
AWSCoreRequestsHandlerMock coreHandlerMock;
EXPECT_CALL(coreHandlerMock, GetDefaultConfig()).Times(1).WillOnce(nullptr);
AZ_TEST_START_TRACE_SUPPRESSION;
auto result = m_gameliftClientManager->ConfigureGameLiftClient("");
AZ_TEST_STOP_TRACE_SUPPRESSION(1); // capture 1 error message
@@ -274,6 +276,8 @@ TEST_F(AWSGameLiftClientManagerTest, ConfigureGameLiftClient_CallWithoutRegion_G
TEST_F(AWSGameLiftClientManagerTest, ConfigureGameLiftClient_CallWithoutCredential_GetFalseAsResult)
{
AWSCoreRequestsHandlerMock coreHandlerMock;
EXPECT_CALL(coreHandlerMock, GetDefaultConfig()).Times(1).WillOnce(nullptr);
AWSResourceMappingRequestsHandlerMock handlerMock;
EXPECT_CALL(handlerMock, GetDefaultRegion()).Times(1).WillOnce(::testing::Return("us-west-2"));
AZ_TEST_START_TRACE_SUPPRESSION;
@@ -284,6 +288,8 @@ TEST_F(AWSGameLiftClientManagerTest, ConfigureGameLiftClient_CallWithoutCredenti
TEST_F(AWSGameLiftClientManagerTest, ConfigureGameLiftClient_CallWithRegionAndCredential_GetTrueAsResult)
{
AWSCoreRequestsHandlerMock coreHandlerMock;
EXPECT_CALL(coreHandlerMock, GetDefaultConfig()).Times(1).WillOnce(nullptr);
AWSCredentialRequestsHandlerMock handlerMock;
EXPECT_CALL(handlerMock, GetCredentialsProvider())
.Times(1)
@@ -9,9 +9,9 @@
#pragma once
#include <AzCore/Interface/Interface.h>
#include <AzFramework/Matchmaking/MatchmakingNotifications.h>
#include <AzFramework/Session/ISessionRequests.h>
#include <AzFramework/Session/ISessionHandlingRequests.h>
#include <AzFramework/Matchmaking/IMatchmakingRequests.h>
#include <AzFramework/Matchmaking/MatchmakingNotifications.h>
#include <AzTest/AzTest.h>
@@ -76,21 +76,44 @@ public:
MOCK_METHOD0(OnStopMatchmakingAsyncComplete, void());
};
class MatchAcceptanceNotificationsHandlerMock
: public AzFramework::MatchAcceptanceNotificationBus::Handler
class MatchmakingNotificationsHandlerMock
: public AzFramework::MatchmakingNotificationBus::Handler
{
public:
MatchAcceptanceNotificationsHandlerMock()
MatchmakingNotificationsHandlerMock()
{
AzFramework::MatchAcceptanceNotificationBus::Handler::BusConnect();
AzFramework::MatchmakingNotificationBus::Handler::BusConnect();
}
~MatchAcceptanceNotificationsHandlerMock()
~MatchmakingNotificationsHandlerMock()
{
AzFramework::MatchAcceptanceNotificationBus::Handler::BusDisconnect();
AzFramework::MatchmakingNotificationBus::Handler::BusDisconnect();
}
MOCK_METHOD0(OnMatchAcceptance, void());
void OnMatchAcceptance() override
{
++m_numMatchAcceptance;
}
void OnMatchComplete() override
{
++m_numMatchComplete;
}
void OnMatchError() override
{
++m_numMatchError;
}
void OnMatchFailure() override
{
++m_numMatchFailure;
}
int m_numMatchAcceptance = 0;
int m_numMatchComplete = 0;
int m_numMatchError = 0;
int m_numMatchFailure = 0;
};
class SessionAsyncRequestNotificationsHandlerMock
@@ -17,7 +17,9 @@ set(FILES
Include/Request/AWSGameLiftSearchSessionsRequest.h
Include/Request/AWSGameLiftStartMatchmakingRequest.h
Include/Request/AWSGameLiftStopMatchmakingRequest.h
Include/Request/IAWSGameLiftRequests.h
Include/Request/AWSGameLiftRequestBus.h
Include/Request/AWSGameLiftSessionRequestBus.h
Include/Request/AWSGameLiftMatchmakingRequestBus.h
Source/Activity/AWSGameLiftActivityUtils.cpp
Source/Activity/AWSGameLiftActivityUtils.h
Source/Activity/AWSGameLiftAcceptMatchActivity.cpp
@@ -5,7 +5,7 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
@@ -45,7 +45,7 @@ namespace AWSGameLift
virtual bool StopMatchBackfill(const AZStd::string& ticketId) = 0;
};
// IAWSGameLiftServerRequests EBus wrapper for scripting
// IAWSGameLiftServerRequests EBus wrapper
class AWSGameLiftServerRequests
: public AZ::EBusTraits
{
@@ -20,7 +20,7 @@
#include <AzFramework/Session/SessionConfig.h>
#include <AWSGameLiftPlayer.h>
#include <Request/IAWSGameLiftServerRequests.h>
#include <Request/AWSGameLiftServerRequestBus.h>
namespace AWSGameLift
{
@@ -10,7 +10,7 @@ set(FILES
../AWSGameLiftCommon/Include/AWSGameLiftPlayer.h
../AWSGameLiftCommon/Source/AWSGameLiftPlayer.cpp
../AWSGameLiftCommon/Source/AWSGameLiftSessionConstants.h
Include/Request/IAWSGameLiftServerRequests.h
Include/Request/AWSGameLiftServerRequestBus.h
Source/AWSGameLiftServerManager.cpp
Source/AWSGameLiftServerManager.h
Source/AWSGameLiftServerSystemComponent.cpp