// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "ShooterGameModeBase.h" #if WITH_GAMELIFT #include "GameLiftServerSDK.h" #endif #include "ShooterGameMode.generated.h" /* struct FCommandLineArgs { TMap Options; TArray CmdArguments; void ParseCommandLine() { const TCHAR* CommandLine = FCommandLine::Get(); // Reserves estimated space to avoid reallocations Options.Reserve(10); CmdArguments.Reserve(10); FString Key, Value, Token; FString FlagName = FString(TEXT("")); while (FParse::Token(CommandLine, Token, true)) { // Check if token starts with '-' if (Token.StartsWith(TEXT("-"))) { // Remove the leading '-' and store the flag name FlagName = Token.Mid(1); // If it's in the form Key=Value, split it if (FlagName.Split(TEXT("="), &Key, &Value)) { Key=Key.ToLower(); Value=Value.ToLower(); // Normalize boolean values if (Value.Equals(TEXT("true"), ESearchCase::IgnoreCase) || Value.Equals(TEXT("1"))) { Options.Add(Key, TEXT("true")); } else if (Value.Equals(TEXT("false"), ESearchCase::IgnoreCase) || Value.Equals(TEXT("0"))) { Options.Add(Key, TEXT("false")); } else { Options.Add(Key, Value); } } else { // Bare flag (for // example -Debug or -NoSound) // The convention is flags starting with "No" are false if (FlagName.StartsWith(TEXT("No")) && FlagName.Len() > 2) { Key = FlagName.Mid(2).ToLower(); Options.Add(Key, TEXT("false")); } else { Key = FlagName.ToLower(); Options.Add(Key, TEXT("true")); } // Also add to Arguments array for backward compatibility CmdArguments.Add(FlagName); } } else { CmdArguments.Add(Token); } } } FString GetValueFromKey(const FString& Key, const FString& DefaultValue = TEXT("")) const { FString NormalizedKey = Key.ToLower(); const FString* ValuePtr = Options.Find(NormalizedKey); return ValuePtr ? *ValuePtr : DefaultValue; } bool TryGetValue(const FString& Key, FString& OutValue) const { FString NormalizedKey = Key.ToLower(); if (const FString* ValuePtr = Options.Find(NormalizedKey)) { OutValue = *ValuePtr; return true; } return false; } FString ToString() const { FString Result; for (const auto& Pair : Options) { Result += FString::Printf(TEXT("-%s=%s "), *Pair.Key, *Pair.Value); } for (const FString& Arg : CmdArguments) { Result += Arg + TEXT(" "); } return Result.TrimEnd(); } // Get a boolean value, returns Default if not found or invalid bool GetBool(const FString& Key, bool DefaultValue = false) const { FString Value; if (TryGetValue(Key, Value)) { if (Value.Equals(TEXT("true"), ESearchCase::IgnoreCase) || Value.Equals(TEXT("1")) || Value.Equals(TEXT("yes"), ESearchCase::IgnoreCase)) { return true; } if (Value.Equals(TEXT("false"), ESearchCase::IgnoreCase) || Value.Equals(TEXT("0")) || Value.Equals(TEXT("no"), ESearchCase::IgnoreCase)) { return false; } } return DefaultValue; } // Get an integer value, returns Default if not found or not numeric int32 GetInt(const FString& Key, int32 DefaultValue = 0) const { FString Value; if (TryGetValue(Key, Value)) { return FCString::Atoi(*Value); } return DefaultValue; } // Get a float value float GetFloat(const FString& Key, float DefaultValue = 0.0f) const { FString Value; if (TryGetValue(Key, Value)) { return FCString::Atof(*Value); } return DefaultValue; } // Get as FName (useful for modes, map names, etc.) FName GetName(const FString& Key, const FName& DefaultValue = NAME_None) const { FString Value; if (TryGetValue(Key, Value)) { return FName(*Value); } return DefaultValue; } // Set a string value (core setter used by others) void SetValue(const FString& Key, const FString& Value) { Options.Add(Key.ToLower(), Value.ToLower()); } // Set a boolean option void SetBool(const FString& Key, bool bValue) { Options.Add(Key.ToLower(), bValue ? TEXT("true") : TEXT("false")); } // Set an integer option void SetInt(const FString& Key, int32 Value) { Options.Add(Key.ToLower(), FString::FromInt(Value)); } // Set a float option (with minimal formatting) void SetFloat(const FString& Key, float Value, int32 Precision = 2) { FString FloatStr = FString::SanitizeFloat(Value, Precision); Options.Add(Key.ToLower(), FloatStr); } // Set an FName option void SetName(const FString& Key, const FName& NameValue) { Options.Add(Key.ToLower(), NameValue.ToString().ToLower()); } // Add a bare flag (true/false toggle stored for ToString output) void SetFlag(const FString& Flag, bool bEnabled = true) { FString Key = Flag.ToLower(); Options.Add(Key, bEnabled ? TEXT("true") : TEXT("false")); CmdArguments.Add(Flag); // maintain compatibility with older flag parsing } }; */ DECLARE_LOG_CATEGORY_EXTERN(LogShooterGameMode, Log, All); /** * */ UCLASS() class FPSTEMPLATE_API AShooterGameMode : public AShooterGameModeBase { GENERATED_BODY() public: AShooterGameMode(); protected: virtual void BeginPlay() override; private: void InitGameLift(); #if WITH_GAMELIFT bool SetParametersFromCommandLine(FServerParameters& OutServerParameters, FProcessParameters& OutProcessParameters); static void LogServerParameters(const FServerParameters& InServerParameters); void SetProcessIdOnServerParameters(FServerParameters& OutServerParameters); bool ValidateServerParameters(const FString& CommandLine, const FString& ParameterName, FString& OutValue, const bool bCritical = true); void LogServerSummary(const FServerParameters& InServerParameters, const FProcessParameters& InProcessParameters); void BindGameLiftCallbackFunctions(FProcessParameters& ProcessParameters, FGameLiftServerSDKModule& GameLiftSdkModule); void InitiateProcessReady(FProcessParameters& ProcessParameters, FGameLiftServerSDKModule& GameLiftSdkModule); bool InitiateConnectionWithGameLiftAgent(FServerParameters& ServerParameters, FGameLiftServerSDKModule& GameLiftSdkModule); #endif };