Files
o3de/Gems/GameLift/Code/Source/Session/GameLiftClientService.cpp
T
2021-03-08 14:30:57 -08:00

321 lines
10 KiB
C++

/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#if defined(BUILD_GAMELIFT_CLIENT)
#include <AzCore/Component/TickBus.h>
#include <AzFramework/AzFramework_Traits_Platform.h>
#include <GameLift/Session/GameLiftClientService.h>
#include <GameLift/Session/GameLiftClientSession.h>
#include <GameLift/Session/GameLiftSearch.h>
#include <GameLift/Session/GameLiftSessionRequest.h>
#include <GameLift/Session/GameLiftGameSessionPlacementRequest.h>
#include <GameLift/Session/GameLiftMatchmaking.h>
#include <GameLift/Session/GameLiftRequestInterface.h>
#include <AzCore/IO/FileIO.h>
#include <aws/core/auth/AWSCredentialsProvider.h>
#include <aws/core/utils/Outcome.h>
#include <aws/gamelift/GameLiftClient.h>
#include <aws/gamelift/model/ListBuildsRequest.h>
namespace
{
//This is used when a playerId is not specified when initializing GameLiftSDK with developer credentials.
const char* DEFAULT_PLAYER_ID = "AnonymousPlayerId";
}
namespace GridMate
{
namespace Platform
{
void ResolveCaCertFilePath(Aws::String& caFile);
}
GameLiftClientService::GameLiftClientService(const GameLiftClientServiceDesc& desc)
: SessionService(desc)
, m_serviceDesc(desc)
, m_clientStatus(GameLift_NotInited)
{
}
GameLiftClientService::~GameLiftClientService()
{
}
bool GameLiftClientService::IsReady() const
{
return m_clientStatus == GameLift_Ready;
}
AZStd::shared_ptr<Aws::GameLift::GameLiftClient> GameLiftClientService::GetClient() const
{
return m_clientSharedPtr;
}
Aws::String GameLiftClientService::GetPlayerId() const
{
return m_serviceDesc.m_playerId.c_str();
}
void GameLiftClientService::OnServiceRegistered(IGridMate* gridMate)
{
SessionService::OnServiceRegistered(gridMate);
GameLiftClientSession::RegisterReplicaChunks();
if (!StartGameLiftClient())
{
EBUS_EVENT_ID(m_gridMate, GameLiftClientServiceEventsBus, OnGameLiftSessionServiceFailed, this, "GameLift client failed to start");
}
GameLiftClientServiceBus::Handler::BusConnect(gridMate);
}
void GameLiftClientService::OnServiceUnregistered(IGridMate* gridMate)
{
GameLiftClientServiceBus::Handler::BusDisconnect();
if (m_clientStatus == GameLift_Ready)
{
m_clientSharedPtr.reset();
m_clientStatus = GameLift_NotInited;
}
SessionService::OnServiceUnregistered(gridMate);
}
void GameLiftClientService::Update()
{
if (m_listBuildsOutcomeCallable.valid() && m_listBuildsOutcomeCallable.wait_for(std::chrono::milliseconds(0)) == std::future_status::ready)
{
auto outcome = m_listBuildsOutcomeCallable.get();
if (outcome.IsSuccess())
{
AZ_TracePrintf("GameLift", "Initialized GameLift client successfully.\n");
m_clientStatus = GameLift_Ready;
EBUS_EVENT_ID(m_gridMate, GameLiftClientServiceEventsBus, OnGameLiftSessionServiceReady, this);
EBUS_DBG_EVENT(Debug::SessionDrillerBus, OnSessionServiceReady);
EBUS_EVENT_ID(m_gridMate, SessionEventBus, OnSessionServiceReady);
}
else
{
auto errorMessage = outcome.GetError().GetMessage();
AZ_TracePrintf("GameLift", "Failed to initialize GameLift client: %s\n", errorMessage.c_str());
m_clientStatus = GameLift_Failed;
// defer the notification so Gridmate doesn't destroy this service while updating
AZ::TickBus::QueueFunction([this, errorMessage]()
{
GameLiftClientServiceEventsBus::Event(m_gridMate, &GameLiftClientServiceEventsBus::Events::OnGameLiftSessionServiceFailed, this, errorMessage.c_str());
});
}
}
SessionService::Update();
}
GridSession* GameLiftClientService::JoinSessionBySearchInfo(const GameLiftSearchInfo& searchInfo, const CarrierDesc& carrierDesc)
{
if (m_clientStatus != GameLift_Ready)
{
AZ_TracePrintf("GameLift", "Client API is not initialized.\n");
return nullptr;
}
GameLiftClientSession* session = aznew GameLiftClientSession(this);
if (!session->Initialize(searchInfo, JoinParams(), carrierDesc))
{
delete session;
return nullptr;
}
return session;
}
GridSearch* GameLiftClientService::RequestSession(const GameLiftSessionRequestParams& params)
{
if (m_clientStatus != GameLift_Ready)
{
AZ_TracePrintf("GameLift", "Client API is not initialized.\n");
return nullptr;
}
AZStd::shared_ptr<GameLiftRequestInterfaceContext> context = AZStd::make_shared<GameLiftRequestInterfaceContext>();
context->m_gameLiftClient = m_clientSharedPtr;
context->m_playerId = m_serviceDesc.m_playerId.c_str();
// If queue name is set use queues to create a GameLift session. else use fleetId.
if (!params.m_queueName.empty())
{
context->m_requestParams = params;
GameLiftGameSessionPlacementRequest* request = aznew GameLiftGameSessionPlacementRequest(this, context);
if (!request->Initialize())
{
delete request;
return nullptr;
}
return request;
}
else
{
context->m_requestParams = params;
GameLiftSessionRequest* request = aznew GameLiftSessionRequest(this, context);
if (!request->Initialize())
{
delete request;
return nullptr;
}
return request;
}
}
GridSearch* GameLiftClientService::StartMatchmaking(const AZStd::string& matchmakingConfigName)
{
if (m_clientStatus != GameLift_Ready)
{
AZ_TracePrintf("GameLift", "Client API is not initialized.\n");
return nullptr;
}
AZStd::shared_ptr<GameLiftRequestInterfaceContext> context = AZStd::make_shared<GameLiftRequestInterfaceContext>();
context->m_gameLiftClient = m_clientSharedPtr;
context->m_playerId = m_serviceDesc.m_playerId.c_str();
GameLiftMatchmaking* request = aznew GameLiftMatchmaking(this, context, Aws::String(matchmakingConfigName.c_str()));
if (!request->Initialize())
{
delete request;
return nullptr;
}
return request;
}
GameLiftSearch* GameLiftClientService::StartSearch(const GameLiftSearchParams& params)
{
if (m_clientStatus != GameLift_Ready)
{
AZ_TracePrintf("GameLift", "Client API is not initialized.\n");
return nullptr;
}
AZStd::shared_ptr<GameLiftRequestInterfaceContext> context = AZStd::make_shared<GameLiftRequestInterfaceContext>();
context->m_gameLiftClient = m_clientSharedPtr;
context->m_searchParams = params;
GameLiftSearch* search = aznew GameLiftSearch(this, context);
if (!search->Initialize())
{
delete search;
return nullptr;
}
return search;
}
GameLiftClientSession* GameLiftClientService::QueryGameLiftSession(const GridSession* session)
{
for (GridSession* s : m_sessions)
{
if (s == session)
{
return static_cast<GameLiftClientSession*>(s);
}
}
return nullptr;
}
GameLiftSearch* GameLiftClientService::QueryGameLiftSearch(const GridSearch* search)
{
for (GridSearch* s : m_activeSearches)
{
if (s == search)
{
return static_cast<GameLiftSearch*>(s);
}
}
for (GridSearch* s : m_completedSearches)
{
if (s == search)
{
return static_cast<GameLiftSearch*>(s);
}
}
return nullptr;
}
bool GameLiftClientService::StartGameLiftClient()
{
if (m_clientStatus == GameLift_NotInited)
{
if (!ValidateAWSCredentials())
{
m_clientStatus = GameLift_Failed;
}
else
{
m_clientStatus = GameLift_Initing;
CreateSharedAWSGameLiftClient();
Aws::GameLift::Model::ListBuildsRequest request;
m_listBuildsOutcomeCallable = m_clientSharedPtr->ListBuildsCallable(request);
}
}
return m_clientStatus != GameLift_Failed;
}
void GameLiftClientService::CreateSharedAWSGameLiftClient()
{
Aws::Client::ClientConfiguration config;
config.enableTcpKeepAlive = AZ_TRAIT_AZFRAMEWORK_AWS_ENABLE_TCP_KEEP_ALIVE_SUPPORTED;
config.region = m_serviceDesc.m_region.c_str();
config.endpointOverride = m_serviceDesc.m_endpoint.c_str();
if (m_serviceDesc.m_useGameLiftLocalServer)
{
config.verifySSL = false;
config.scheme = Aws::Http::Scheme::HTTP;
}
else
{
config.verifySSL = true;
config.scheme = Aws::Http::Scheme::HTTPS;
Platform::ResolveCaCertFilePath(config.caFile);
}
Aws::String accessKey(m_serviceDesc.m_accessKey.c_str());
Aws::String secretKey(m_serviceDesc.m_secretKey.c_str());
Aws::Auth::AWSCredentials cred = Aws::Auth::AWSCredentials(accessKey, secretKey);
m_clientSharedPtr = AZStd::make_shared<Aws::GameLift::GameLiftClient>(cred, config);
}
bool GameLiftClientService::ValidateAWSCredentials()
{
if (m_serviceDesc.m_accessKey.empty() || m_serviceDesc.m_secretKey.empty())
{
AZ_TracePrintf("GameLift", "Initialize failed. Cannot use GameLift without access and secret key.\n");
return false;
}
return true;
}
} // namespace GridMate
#endif // BUILD_GAMELIFT_CLIENT