Files
DedicatedServerCourse/Source/DedicatedServers/Private/UI/Portal/PortalManager.cpp

182 lines
5.8 KiB
C++
Raw Normal View History

2026-03-31 07:42:56 -04:00
// Fill out your copyright notice in the Description page of Project Settings.
#include "UI/Portal/PortalManager.h"
2026-03-31 08:15:28 -04:00
#include "HttpModule.h"
#include "JsonObjectConverter.h"
#include "Data/API/APIData.h"
2026-04-05 16:43:32 -04:00
#include "GameFramework/PlayerState.h"
#include "GameplayTags/DedicatedServerTags.h"
#include "Interfaces/IHttpResponse.h"
2026-04-05 20:57:35 -04:00
#include "Kismet/GameplayStatics.h"
#include "UI/HTTP/HTTPRequestTypes.h"
2026-03-31 08:15:28 -04:00
void UPortalManager::JoinGameSession()
{
BroadcastJoinGameSessionMessage.Broadcast(TEXT("Searching for Game Session..."), false);
check(APIData);
TSharedPtr<IHttpRequest> 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<FJsonObject> JsonObject;
TSharedRef<TJsonReader<>> JsonReader = TJsonReaderFactory<>::Create(Response->GetContentAsString());
if (FJsonSerializer::Deserialize(JsonReader, JsonObject))
{
if (ContainsErrors(JsonObject))
{
BroadcastJoinGameSessionMessage.Broadcast(HTTPStatusMessages::SomethingWentWrong, true);
}
2026-04-05 16:43:32 -04:00
if (JsonObject->HasField(TEXT("GameProperties")))
{
auto PropertiesArray = JsonObject->GetArrayField(TEXT("GameProperties"));
TSharedPtr<FJsonObject> 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);
2026-04-05 16:43:32 -04:00
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<APlayerState>();
if (IsValid(LocalPlayerState) && LocalPlayerState->GetUniqueId().IsValid())
{
return TEXT("Player_") + FString::FromInt(LocalPlayerState->GetUniqueID());
}
}
return FString();
}
2026-04-05 20:20:35 -04:00
void UPortalManager::HandleGameSessionStatus(const FString& SessionId, const FString& Status)
2026-04-05 16:43:32 -04:00
{
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);
}
2026-03-31 08:15:28 -04:00
}
2026-04-05 16:43:32 -04:00
void UPortalManager::TryCreatePlayerSession(const FString& PlayerId, const FString& GameSessionId)
{
2026-04-05 17:07:48 -04:00
BroadcastJoinGameSessionMessage.Broadcast(TEXT("Searching for Game Session..."), false);
check(APIData);
TSharedPtr<IHttpRequest> 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<FString, FString> Params = {
2026-04-05 20:20:35 -04:00
{TEXT("playerId"), PlayerId },
{TEXT("gameSessionId"), GameSessionId }
2026-04-05 17:07:48 -04:00
};
2026-04-05 20:20:35 -04:00
const FString Content = SerializeJsonContent(Params);
Request->SetContentAsString(Content);
2026-04-05 17:07:48 -04:00
Request->ProcessRequest();
}
void UPortalManager::FindPlayerSession_Response(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
{
if (!bWasSuccessful)
{
BroadcastJoinGameSessionMessage.Broadcast(HTTPStatusMessages::SomethingWentWrong, true);
}
TSharedPtr<FJsonObject> JsonObject;
TSharedRef<TJsonReader<>> JsonReader = TJsonReaderFactory<>::Create(Response->GetContentAsString());
if (FJsonSerializer::Deserialize(JsonReader, JsonObject))
{
if (ContainsErrors(JsonObject))
{
BroadcastJoinGameSessionMessage.Broadcast(HTTPStatusMessages::SomethingWentWrong, true);
}
FDSPlayerSession PlayerSession;
FJsonObjectConverter::JsonObjectToUStruct(JsonObject.ToSharedRef(), &PlayerSession);
PlayerSession.Dump();
2026-04-05 20:57:35 -04:00
const FString IPAndPort = PlayerSession.IpAddress + TEXT(":") + FString::FromInt(PlayerSession.Port);
const FName Address(*IPAndPort);
APlayerController* LocalPlayerController = GEngine->GetFirstLocalPlayerController(GetWorld());
if (IsValid(LocalPlayerController))
{
FInputModeGameOnly InputModeData;
LocalPlayerController->SetInputMode(InputModeData);
LocalPlayerController->SetShowMouseCursor(false);
}
2026-04-05 20:57:35 -04:00
UGameplayStatics::OpenLevel(this, Address);
}
2026-04-05 16:43:32 -04:00
}