2026-02-24 22:39:26 -05:00
|
|
|
|
// 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"
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-03-01 09:29:41 -05:00
|
|
|
|
/*
|
|
|
|
|
|
struct FCommandLineArgs
|
|
|
|
|
|
{
|
|
|
|
|
|
TMap<FString,FString> Options;
|
|
|
|
|
|
TArray<FString> 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;
|
|
|
|
|
|
}
|
2026-02-24 22:39:26 -05:00
|
|
|
|
|
2026-03-01 09:29:41 -05:00
|
|
|
|
// 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;
|
|
|
|
|
|
}
|
2026-02-24 22:39:26 -05:00
|
|
|
|
|
2026-03-01 09:29:41 -05:00
|
|
|
|
// 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
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
*/
|
2026-02-24 22:39:26 -05:00
|
|
|
|
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
|
2026-03-01 09:29:41 -05:00
|
|
|
|
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);
|
2026-02-24 22:39:26 -05:00
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
};
|