From 99b168b6b559161fce3e29e34845b85eebf4e4dc Mon Sep 17 00:00:00 2001 From: Norman Lansing Date: Thu, 5 Mar 2026 10:00:22 -0500 Subject: [PATCH] Added in namespace GameLiftValidators and methods --- .../Private/Game/ShooterGameMode.cpp | 113 +++++++++++++++++- .../FPSTemplate/Public/Game/ShooterGameMode.h | 53 +++++++- 2 files changed, 161 insertions(+), 5 deletions(-) diff --git a/Source/FPSTemplate/Private/Game/ShooterGameMode.cpp b/Source/FPSTemplate/Private/Game/ShooterGameMode.cpp index afeabf07..82225f6e 100644 --- a/Source/FPSTemplate/Private/Game/ShooterGameMode.cpp +++ b/Source/FPSTemplate/Private/Game/ShooterGameMode.cpp @@ -3,6 +3,7 @@ #include "Game/ShooterGameMode.h" #include "Logging/LogMacros.h" +#include "Logging/StructuredLog.h" #if WITH_GAMELIFT #include "GameLiftServerSDK.h" @@ -10,6 +11,49 @@ DEFINE_LOG_CATEGORY(LogShooterGameMode) +namespace GameLiftValidators { + const FRegexPattern FleetIdPattern(TEXT("^[a-z]*fleet-[a-zA-Z0-9\\-]+$")); + const int32 FleetIdLengthMin = 1; + const int32 FleetIdLengthMax = 128; + const FString ServerRegionPattern(TEXT("^[a-z]{2}-[a-z]+-[0-9]$")); + const int32 ServerRegionLengthMin = 3; + const int32 ServerRegionLengthMax = 16; + const FString WebSocketUrlPattern(TEXT("^(ws|wss):\\/\\/([0-9a-zA-Z.-]+)(:([1-9][0-9]{0,4}))?(\\/.*)?$")); + const int32 WebSocketUrlLengthMin = 1; + const int32 WebSocketUrlLengthMax = 128; + const FString AuthTokenPattern(TEXT("^[A-Za-z0-9+/=]+$")); + const int32 AuthTokenLengthMin = 20; + const int32 AuthTokenLengthMax = 2048; + const FString HostIdPattern(TEXT("^[a-z]*host-[a-zA-Z0-9\\-]+$")); + const int32 HostIdLengthMin = 1; + const int32 HostIdLengthMax = 128; + const int32 ServerPortMin = 1026; + const int32 ServerPortMax = 60000; + const int32 WebSocketPortMin = 1; + const int32 WebSocketPortMax = 60000; + + bool ValidateString(const FString& Value, const FRegexPattern* OptionalPattern, const int32 Min, const int32 Max) + { + if (Value.IsEmpty()) return false; + + if (OptionalPattern) + { + return FRegexMatcher(*OptionalPattern, Value).FindNext() && + Value.Len() >= Min && + Value.Len() <= Max; + } + else + { + return Value.Len() >= Min && Value.Len() <= Max; + } + } + + bool ValidateNumber(const int32 Value, const int32 Min, const int32 Max) + { + return Value >= Min && Value <= Max; + } +} + AShooterGameMode::AShooterGameMode() { UE_LOG(LogShooterGameMode, Log, TEXT("Initializing ShooterGameMode...")); @@ -27,12 +71,46 @@ void AShooterGameMode::BeginPlay() void AShooterGameMode::InitGame(const FString& MapName, const FString& Options, FString& ErrorMessage) { Super::InitGame(MapName, Options, ErrorMessage); + UE_LOG(LogShooterGameMode, Log, TEXT("[%s] Parsing CLI"), *FDateTime::UtcNow().ToString(TEXT("%Y%m%d-%H%M%S"))); CachedCommandLine = FCommandLine::Get(); - bool bIsCriticalError = false; // Parsing of Command Line bDebugMode = FParse::Param(*CachedCommandLine, TEXT("Debug")); + GameLiftConfig.bDebugMode = FParse::Param(*CachedCommandLine, TEXT("Debug")); + + if (GameLiftConfig.bDebugMode) + { + UE_LOG(LogShooterGameMode, Log, TEXT("Debug mode: ENABLED")); +#if UE_BUILD_DEBUG + UE_LOG(LogShooterGameMode, Log, TEXT("Command Line Arguments: %s"), *CachedCommandLine); +#endif + } + + GameLiftConfig.ServerPort = GetConfiguredOrDefaultPort(); + GameLiftConfig.bIsAnywhereFleet = FParse::Param(*CachedCommandLine, TEXT("glAnywhere")); + + if (GameLiftConfig.bIsAnywhereFleet) + { + UE_LOGFMT(LogShooterGameMode, Log, "GameLift Anywhere Fleet Command Line Parsing"); + UE_LOGFMT(LogShooterGameMode, Log, "======Command Line Parameters======"); + + UE_LOGFMT(LogShooterGameMode, Log, "==================================="); + } + else + { + + } + +} + +void AShooterGameMode::InitGame_original(const FString& MapName, const FString& Options, FString& ErrorMessage) +{ + Super::InitGame(MapName, Options, ErrorMessage); + + UE_LOG(LogShooterGameMode, Log, TEXT("[%s] Parsing CLI"), *FDateTime::UtcNow().ToString(TEXT("%Y%m%d-%H%M%S"))); + CachedCommandLine = FCommandLine::Get(); + bool bIsCriticalError = false; if (bDebugMode) { @@ -207,8 +285,37 @@ FString AShooterGameMode::GetSHA256Hash(const FString& Input) return FString::Printf(TEXT("Fail_%dbytes"), Input.Len()); } -void AShooterGameMode::InitGameLift() +bool AShooterGameMode::ParseAndOutputResult(const FString& InString, FString& OutValue, bool bRequired) { - //TODO: Need to write later, working on parser first. + // Returns True if it is a critical error, returns false + + if (!FParse::Value(*InString, TEXT("hostId="), HostId)) + { + UE_LOG(LogShooterGameMode, Error, TEXT("HostId Missing in Command Line")); + return bRequired; + } + else + { + UE_LOG(LogShooterGameMode, Log, TEXT("Host ID: %s"), *HostId); + return false; + } +} + +bool AShooterGameMode::ValidateFleetId(const FString& InFleetId) +{ +// FRegexMatcher Matcher(FleetIdPattern, InFleetId); +// return Matcher.IsMatch() && +// InFleetId.Len() >= 10 && +// InFleetId.Len() < 128; + return false; +} + +void AShooterGameMode::InitGameLift() +{ +#if WITH_GAMELIFT + //TODO: Need to write later, working on parser first. +#else + UE_LOGFMT(LogShooterGameMode, Warning, "GameLift disabled"); +#endif } diff --git a/Source/FPSTemplate/Public/Game/ShooterGameMode.h b/Source/FPSTemplate/Public/Game/ShooterGameMode.h index 2fdccd97..cd59e5fe 100644 --- a/Source/FPSTemplate/Public/Game/ShooterGameMode.h +++ b/Source/FPSTemplate/Public/Game/ShooterGameMode.h @@ -12,6 +12,48 @@ DECLARE_LOG_CATEGORY_EXTERN(LogShooterGameMode, Log, All); struct FProcessParameters; struct FServerParameters; +struct FGameLiftCliConfig +{ + bool bDebugMode = false; + bool bIsAnywhereFleet = false; + bool bIsCriticalError = false; + + int32 ServerPort = 0; + + FString AuthToken; + FString FleetId; + FString HostId; + FString WebSocketUrl; + FString ServerRegion; + +}; + +namespace GameLiftValidators +{ + extern const FRegexPattern FleetIdPattern; + extern const int32 FleetIdLengthMin; + extern const int32 FleetIdLengthMax; + extern const FString ServerRegionPattern; + extern const int32 ServerRegionLengthMin; + extern const int32 ServerRegionLengthMax; + extern const FString WebSocketUrlPattern; + extern const int32 WebSocketUrlLengthMin; + extern const int32 WebSocketUrlLengthMax; + extern const FString AuthTokenPattern; + extern const int32 AuthTokenLengthMin; + extern const int32 AuthTokenLengthMax; + extern const FString HostIdPattern; + extern const int32 HostIdLengthMin; + extern const int32 HostIdLengthMax; + extern const int32 ServerPortMin; + extern const int32 ServerPortMax; + extern const int32 WebSocketPortMin; + extern const int32 WebSocketPortMax; + + bool ValidateString(const FString& Value, const FRegexPattern& OptionalPattern, int32 Min, int32 Max); + bool ValidateNumber(int32 Value, int32 Min, int32 Max); +} + /** * */ @@ -51,8 +93,12 @@ protected: virtual void BeginPlay() override; virtual void InitGame(const FString& MapName, const FString& Options, FString& ErrorMessage) override; + void InitGame_original(const FString& MapName, const FString& Options, FString& ErrorMessage); private: + + FGameLiftCliConfig GameLiftConfig; + FString CachedCommandLine; TSharedPtr ProcessParameters; TSharedPtr ServerParameters; @@ -60,7 +106,10 @@ private: int32 GetConfiguredOrDefaultPort() const; static FString GetSHA256Hash(const FString& Input); -#if WITH_GAMELIFT + bool ParseAndOutputResult(const FString& InString, FString& OutValue, bool bRequired = false); + bool ParseAndValidate(const FString& InArguments, FGameLiftCliConfig& Config); + static bool ValidateFleetId(const FString& InFleetId); + void InitGameLift(); -#endif }; +