// Fill out your copyright notice in the Description page of Project Settings. #include "UI/Portal/PortalManager.h" #include "HttpModule.h" #include "JsonObjectConverter.h" #include "Data/API/APIData.h" #include "GameFramework/PlayerState.h" #include "GameplayTags/DedicatedServerTags.h" #include "Interfaces/IHttpResponse.h" #include "UI/HTTP/HTTPRequestTypes.h" void UPortalManager::JoinGameSession() { BroadcastJoinGameSessionMessage.Broadcast(TEXT("Searching for Game Session..."), false); check(APIData); TSharedPtr Request = FHttpModule::Get().CreateRequest(); Request->OnProcessRequestComplete().BindUObject(this, &UPortalManager::FindOrCreateGameSession_Response); const FString APIUrl = APIData->GetAPIEndPoint(DedicatedServersTags::GameSessionsAPI::FindOrCreateGameSession); Request->SetURL(APIUrl); Request->SetVerb("POST"); Request->SetHeader("Content-Type", "application/json"); Request->ProcessRequest(); } void UPortalManager::FindOrCreateGameSession_Response(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful) { if (!bWasSuccessful) { BroadcastJoinGameSessionMessage.Broadcast(HTTPStatusMessages::SomethingWentWrong, true); } TSharedPtr JsonObject; TSharedRef> JsonReader = TJsonReaderFactory<>::Create(Response->GetContentAsString()); if (FJsonSerializer::Deserialize(JsonReader, JsonObject)) { if (ContainsErrors(JsonObject)) { BroadcastJoinGameSessionMessage.Broadcast(HTTPStatusMessages::SomethingWentWrong, true); } if (JsonObject->HasField(TEXT("GameProperties"))) { auto PropertiesArray = JsonObject->GetArrayField(TEXT("GameProperties")); TSharedPtr FlatMapJson = MakeShareable(new FJsonObject); for (auto& PropJson : PropertiesArray) { auto PropObj = PropJson->AsObject(); FString Key = PropObj->GetStringField(TEXT("Key")); FString Value = PropObj->GetStringField(TEXT("Value")); FlatMapJson->SetStringField(Key, Value); } // Replace the array with a flat map field JsonObject->SetObjectField(TEXT("GameProperties"), FlatMapJson); } FDSGameSession GameSession; FJsonObjectConverter::JsonObjectToUStruct(JsonObject.ToSharedRef(), &GameSession); const FString GameSessionId = GameSession.GameSessionId; const FString GameSessionStatus = GameSession.Status; const FString UniquePlayerId = GetUniquePlayerId(); HandleGameSessionStatus(GameSessionId, GameSessionStatus); } } FString UPortalManager::GetUniquePlayerId() const { APlayerController* LocalPlayerController = GEngine->GetFirstLocalPlayerController(GetWorld()); if (IsValid(LocalPlayerController)) { APlayerState* LocalPlayerState = LocalPlayerController->GetPlayerState(); if (IsValid(LocalPlayerState) && LocalPlayerState->GetUniqueId().IsValid()) { return TEXT("Player_") + FString::FromInt(LocalPlayerState->GetUniqueID()); } } return FString(); } void UPortalManager::HandleGameSessionStatus(const FString& Status, const FString& SessionId) { if (Status.Equals(TEXT("ACTIVE"))) { BroadcastJoinGameSessionMessage.Broadcast(TEXT("Found Active Game Session. Creating Player Session..."), false); TryCreatePlayerSession(GetUniquePlayerId(), SessionId); } else if (Status.Equals(TEXT("ACTIVATING"))) { FTimerDelegate CreateSessionDelegate; CreateSessionDelegate.BindLambda([this]() { JoinGameSession(); }); APlayerController* LocalPlayerController = GEngine->GetFirstLocalPlayerController(GetWorld()); if (IsValid(LocalPlayerController)) { LocalPlayerController->GetWorldTimerManager().SetTimer(CreateSessionTimer, CreateSessionDelegate, 0.5f, false); } } else { BroadcastJoinGameSessionMessage.Broadcast(HTTPStatusMessages::SomethingWentWrong, true); } } void UPortalManager::TryCreatePlayerSession(const FString& PlayerId, const FString& GameSessionId) { BroadcastJoinGameSessionMessage.Broadcast(TEXT("Searching for Game Session..."), false); check(APIData); TSharedPtr Request = FHttpModule::Get().CreateRequest(); Request->OnProcessRequestComplete().BindUObject(this, &UPortalManager::FindPlayerSession_Response); const FString APIUrl = APIData->GetAPIEndPoint(DedicatedServersTags::GameSessionsAPI::CreatePlayerSession); Request->SetURL(APIUrl); Request->SetVerb("POST"); Request->SetHeader("Content-Type", "application/json"); TMap Params = { {TEXT("playerId"), PlayerId}, {TEXT("sessionId"), GameSessionId} }; Request->SetContentAsString(SerializeJsonContent(Params)); Request->ProcessRequest(); } void UPortalManager::FindPlayerSession_Response(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful) { }