/* * 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 * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace AWSGameLift { #if defined(AZ_DEBUG_BUILD) || defined(AZ_PROFILE_BUILD) AZ_CVAR(AZ::CVarFixedString, cl_gameliftLocalEndpoint, "", nullptr, AZ::ConsoleFunctorFlags::Null, "The local endpoint to test with GameLiftLocal SDK."); #endif void AWSGameLiftClientManager::ActivateManager() { AZ::Interface::Register(this); AWSGameLiftRequestBus::Handler::BusConnect(); AZ::Interface::Register(this); AWSGameLiftSessionAsyncRequestBus::Handler::BusConnect(); AZ::Interface::Register(this); AWSGameLiftSessionRequestBus::Handler::BusConnect(); AZ::Interface::Register(this); AWSGameLiftMatchmakingAsyncRequestBus::Handler::BusConnect(); AZ::Interface::Register(this); AWSGameLiftMatchmakingRequestBus::Handler::BusConnect(); } void AWSGameLiftClientManager::DeactivateManager() { AWSGameLiftMatchmakingRequestBus::Handler::BusDisconnect(); AZ::Interface::Unregister(this); AWSGameLiftMatchmakingAsyncRequestBus::Handler::BusDisconnect(); AZ::Interface::Unregister(this); AWSGameLiftSessionRequestBus::Handler::BusDisconnect(); AZ::Interface::Unregister(this); AWSGameLiftSessionAsyncRequestBus::Handler::BusDisconnect(); AZ::Interface::Unregister(this); AWSGameLiftRequestBus::Handler::BusDisconnect(); AZ::Interface::Unregister(this); } bool AWSGameLiftClientManager::ConfigureGameLiftClient(const AZStd::string& region) { AZ::Interface::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(AZ_DEBUG_BUILD) || defined(AZ_PROFILE_BUILD) localEndpoint = static_cast(cl_gameliftLocalEndpoint); #endif if (!localEndpoint.empty()) { // The attribute needs to override to interact with GameLiftLocal clientConfig.endpointOverride = localEndpoint.c_str(); } else if (!region.empty()) { clientConfig.region = region.c_str(); } else { AZStd::string clientRegion; AWSCore::AWSResourceMappingRequestBus::BroadcastResult(clientRegion, &AWSCore::AWSResourceMappingRequests::GetDefaultRegion); if (clientRegion.empty()) { AZ_Error(AWSGameLiftClientManagerName, false, AWSGameLiftClientRegionMissingErrorMessage); return false; } clientConfig.region = clientRegion.c_str(); } // Fetch AWS credential for client AWSCore::AWSCredentialResult credentialResult; AWSCore::AWSCredentialRequestBus::BroadcastResult(credentialResult, &AWSCore::AWSCredentialRequests::GetCredentialsProvider); if (!localEndpoint.empty()) { credentialResult.result = std::make_shared(); } else if (!credentialResult.result) { AZ_Error(AWSGameLiftClientManagerName, false, AWSGameLiftClientCredentialMissingErrorMessage); return false; } AZ::Interface::Get()->SetGameLiftClient( AZStd::make_shared(credentialResult.result, clientConfig)); return true; } AZStd::string AWSGameLiftClientManager::CreatePlayerId(bool includeBrackets, bool includeDashes) { return AZ::Uuid::CreateRandom().ToString(includeBrackets, includeDashes); } void AWSGameLiftClientManager::AcceptMatch(const Multiplayer::AcceptMatchRequest& acceptMatchRequest) { if (AcceptMatchActivity::ValidateAcceptMatchRequest(acceptMatchRequest)) { const AWSGameLiftAcceptMatchRequest& gameliftStartMatchmakingRequest = static_cast(acceptMatchRequest); AcceptMatchActivity::AcceptMatch(gameliftStartMatchmakingRequest); } } void AWSGameLiftClientManager::AcceptMatchAsync(const Multiplayer::AcceptMatchRequest& acceptMatchRequest) { if (!AcceptMatchActivity::ValidateAcceptMatchRequest(acceptMatchRequest)) { Multiplayer::MatchmakingAsyncRequestNotificationBus::Broadcast( &Multiplayer::MatchmakingAsyncRequestNotifications::OnAcceptMatchAsyncComplete); return; } const AWSGameLiftAcceptMatchRequest& gameliftStartMatchmakingRequest = static_cast(acceptMatchRequest); AZ::JobContext* jobContext = nullptr; AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext); AZ::Job* acceptMatchJob = AZ::CreateJobFunction( [gameliftStartMatchmakingRequest]() { AcceptMatchActivity::AcceptMatch(gameliftStartMatchmakingRequest); Multiplayer::MatchmakingAsyncRequestNotificationBus::Broadcast( &Multiplayer::MatchmakingAsyncRequestNotifications::OnAcceptMatchAsyncComplete); }, true, jobContext); acceptMatchJob->Start(); } AZStd::string AWSGameLiftClientManager::CreateSession(const Multiplayer::CreateSessionRequest& createSessionRequest) { AZStd::string result = ""; if (CreateSessionActivity::ValidateCreateSessionRequest(createSessionRequest)) { const AWSGameLiftCreateSessionRequest& gameliftCreateSessionRequest = static_cast(createSessionRequest); result = CreateSessionActivity::CreateSession(gameliftCreateSessionRequest); } else if (CreateSessionOnQueueActivity::ValidateCreateSessionOnQueueRequest(createSessionRequest)) { const AWSGameLiftCreateSessionOnQueueRequest& gameliftCreateSessionOnQueueRequest = static_cast(createSessionRequest); result = CreateSessionOnQueueActivity::CreateSessionOnQueue(gameliftCreateSessionOnQueueRequest); } else { AZ_Error(AWSGameLiftClientManagerName, false, AWSGameLiftCreateSessionRequestInvalidErrorMessage); } return result; } void AWSGameLiftClientManager::CreateSessionAsync(const Multiplayer::CreateSessionRequest& createSessionRequest) { if (CreateSessionActivity::ValidateCreateSessionRequest(createSessionRequest)) { const AWSGameLiftCreateSessionRequest& gameliftCreateSessionRequest = static_cast(createSessionRequest); AZ::JobContext* jobContext = nullptr; AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext); AZ::Job* createSessionJob = AZ::CreateJobFunction( [gameliftCreateSessionRequest]() { AZStd::string result = CreateSessionActivity::CreateSession(gameliftCreateSessionRequest); Multiplayer::SessionAsyncRequestNotificationBus::Broadcast( &Multiplayer::SessionAsyncRequestNotifications::OnCreateSessionAsyncComplete, result); }, true, jobContext); createSessionJob->Start(); } else if (CreateSessionOnQueueActivity::ValidateCreateSessionOnQueueRequest(createSessionRequest)) { const AWSGameLiftCreateSessionOnQueueRequest& gameliftCreateSessionOnQueueRequest = static_cast(createSessionRequest); AZ::JobContext* jobContext = nullptr; AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext); AZ::Job* createSessionOnQueueJob = AZ::CreateJobFunction( [gameliftCreateSessionOnQueueRequest]() { AZStd::string result = CreateSessionOnQueueActivity::CreateSessionOnQueue(gameliftCreateSessionOnQueueRequest); Multiplayer::SessionAsyncRequestNotificationBus::Broadcast( &Multiplayer::SessionAsyncRequestNotifications::OnCreateSessionAsyncComplete, result); }, true, jobContext); createSessionOnQueueJob->Start(); } else { AZ_Error(AWSGameLiftClientManagerName, false, AWSGameLiftCreateSessionRequestInvalidErrorMessage); Multiplayer::SessionAsyncRequestNotificationBus::Broadcast( &Multiplayer::SessionAsyncRequestNotifications::OnCreateSessionAsyncComplete, ""); } } bool AWSGameLiftClientManager::JoinSession(const Multiplayer::JoinSessionRequest& joinSessionRequest) { bool result = false; if (JoinSessionActivity::ValidateJoinSessionRequest(joinSessionRequest)) { const AWSGameLiftJoinSessionRequest& gameliftJoinSessionRequest = static_cast(joinSessionRequest); auto createPlayerSessionOutcome = JoinSessionActivity::CreatePlayerSession(gameliftJoinSessionRequest); result = JoinSessionActivity::RequestPlayerJoinSession(createPlayerSessionOutcome); } return result; } void AWSGameLiftClientManager::JoinSessionAsync(const Multiplayer::JoinSessionRequest& joinSessionRequest) { if (!JoinSessionActivity::ValidateJoinSessionRequest(joinSessionRequest)) { Multiplayer::SessionAsyncRequestNotificationBus::Broadcast( &Multiplayer::SessionAsyncRequestNotifications::OnJoinSessionAsyncComplete, false); return; } const AWSGameLiftJoinSessionRequest& gameliftJoinSessionRequest = static_cast(joinSessionRequest); AZ::JobContext* jobContext = nullptr; AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext); AZ::Job* joinSessionJob = AZ::CreateJobFunction( [gameliftJoinSessionRequest]() { auto createPlayerSessionOutcome = JoinSessionActivity::CreatePlayerSession(gameliftJoinSessionRequest); bool result = JoinSessionActivity::RequestPlayerJoinSession(createPlayerSessionOutcome); Multiplayer::SessionAsyncRequestNotificationBus::Broadcast( &Multiplayer::SessionAsyncRequestNotifications::OnJoinSessionAsyncComplete, result); }, true, jobContext); joinSessionJob->Start(); } void AWSGameLiftClientManager::LeaveSession() { AWSGameLift::LeaveSessionActivity::LeaveSession(); } void AWSGameLiftClientManager::LeaveSessionAsync() { AZ::JobContext* jobContext = nullptr; AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext); AZ::Job* leaveSessionJob = AZ::CreateJobFunction( [this]() { LeaveSession(); Multiplayer::SessionAsyncRequestNotificationBus::Broadcast( &Multiplayer::SessionAsyncRequestNotifications::OnLeaveSessionAsyncComplete); }, true, jobContext); leaveSessionJob->Start(); } Multiplayer::SearchSessionsResponse AWSGameLiftClientManager::SearchSessions( const Multiplayer::SearchSessionsRequest& searchSessionsRequest) const { Multiplayer::SearchSessionsResponse response; if (SearchSessionsActivity::ValidateSearchSessionsRequest(searchSessionsRequest)) { const AWSGameLiftSearchSessionsRequest& gameliftSearchSessionsRequest = static_cast(searchSessionsRequest); response = SearchSessionsActivity::SearchSessions(gameliftSearchSessionsRequest); } return response; } void AWSGameLiftClientManager::SearchSessionsAsync(const Multiplayer::SearchSessionsRequest& searchSessionsRequest) const { if (!SearchSessionsActivity::ValidateSearchSessionsRequest(searchSessionsRequest)) { Multiplayer::SessionAsyncRequestNotificationBus::Broadcast( &Multiplayer::SessionAsyncRequestNotifications::OnSearchSessionsAsyncComplete, Multiplayer::SearchSessionsResponse()); return; } const AWSGameLiftSearchSessionsRequest& gameliftSearchSessionsRequest = static_cast(searchSessionsRequest); AZ::JobContext* jobContext = nullptr; AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext); AZ::Job* searchSessionsJob = AZ::CreateJobFunction( [gameliftSearchSessionsRequest]() { Multiplayer::SearchSessionsResponse response = SearchSessionsActivity::SearchSessions(gameliftSearchSessionsRequest); Multiplayer::SessionAsyncRequestNotificationBus::Broadcast( &Multiplayer::SessionAsyncRequestNotifications::OnSearchSessionsAsyncComplete, response); }, true, jobContext); searchSessionsJob->Start(); } AZStd::string AWSGameLiftClientManager::StartMatchmaking(const Multiplayer::StartMatchmakingRequest& startMatchmakingRequest) { AZStd::string response; if (StartMatchmakingActivity::ValidateStartMatchmakingRequest(startMatchmakingRequest)) { const AWSGameLiftStartMatchmakingRequest& gameliftStartMatchmakingRequest = static_cast(startMatchmakingRequest); response = StartMatchmakingActivity::StartMatchmaking(gameliftStartMatchmakingRequest); } return response; } void AWSGameLiftClientManager::StartMatchmakingAsync(const Multiplayer::StartMatchmakingRequest& startMatchmakingRequest) { if (!StartMatchmakingActivity::ValidateStartMatchmakingRequest(startMatchmakingRequest)) { Multiplayer::MatchmakingAsyncRequestNotificationBus::Broadcast( &Multiplayer::MatchmakingAsyncRequestNotifications::OnStartMatchmakingAsyncComplete, AZStd::string{}); return; } const AWSGameLiftStartMatchmakingRequest& gameliftStartMatchmakingRequest = static_cast(startMatchmakingRequest); AZ::JobContext* jobContext = nullptr; AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext); AZ::Job* startMatchmakingJob = AZ::CreateJobFunction( [gameliftStartMatchmakingRequest]() { AZStd::string response = StartMatchmakingActivity::StartMatchmaking(gameliftStartMatchmakingRequest); Multiplayer::MatchmakingAsyncRequestNotificationBus::Broadcast( &Multiplayer::MatchmakingAsyncRequestNotifications::OnStartMatchmakingAsyncComplete, response); }, true, jobContext); startMatchmakingJob->Start(); } void AWSGameLiftClientManager::StopMatchmaking(const Multiplayer::StopMatchmakingRequest& stopMatchmakingRequest) { if (StopMatchmakingActivity::ValidateStopMatchmakingRequest(stopMatchmakingRequest)) { const AWSGameLiftStopMatchmakingRequest& gameliftStopMatchmakingRequest = static_cast(stopMatchmakingRequest); StopMatchmakingActivity::StopMatchmaking(gameliftStopMatchmakingRequest); } } void AWSGameLiftClientManager::StopMatchmakingAsync(const Multiplayer::StopMatchmakingRequest& stopMatchmakingRequest) { if (!StopMatchmakingActivity::ValidateStopMatchmakingRequest(stopMatchmakingRequest)) { Multiplayer::MatchmakingAsyncRequestNotificationBus::Broadcast( &Multiplayer::MatchmakingAsyncRequestNotifications::OnStopMatchmakingAsyncComplete); return; } const AWSGameLiftStopMatchmakingRequest& gameliftStopMatchmakingRequest = static_cast(stopMatchmakingRequest); AZ::JobContext* jobContext = nullptr; AWSCore::AWSCoreRequestBus::BroadcastResult(jobContext, &AWSCore::AWSCoreRequests::GetDefaultJobContext); AZ::Job* stopMatchmakingJob = AZ::CreateJobFunction( [gameliftStopMatchmakingRequest]() { StopMatchmakingActivity::StopMatchmaking(gameliftStopMatchmakingRequest); Multiplayer::MatchmakingAsyncRequestNotificationBus::Broadcast( &Multiplayer::MatchmakingAsyncRequestNotifications::OnStopMatchmakingAsyncComplete); }, true, jobContext); stopMatchmakingJob->Start(); } } // namespace AWSGameLift