New Parser Completed. Verification next.
This commit is contained in:
@@ -179,6 +179,10 @@ DefaultBroadphaseSettings=(bUseMBPOnClient=False,bUseMBPOnServer=False,bUseMBPOu
|
|||||||
MinDeltaVelocityForHitEvents=0.000000
|
MinDeltaVelocityForHitEvents=0.000000
|
||||||
ChaosSettings=(DefaultThreadingModel=TaskGraph,DedicatedThreadTickMode=VariableCappedWithTarget,DedicatedThreadBufferMode=Double)
|
ChaosSettings=(DefaultThreadingModel=TaskGraph,DedicatedThreadTickMode=VariableCappedWithTarget,DedicatedThreadBufferMode=Double)
|
||||||
|
|
||||||
|
[URL]
|
||||||
|
DefaultPort=7777
|
||||||
|
|
||||||
[CoreRedirects]
|
[CoreRedirects]
|
||||||
+PropertyRedirects=(OldName="/Script/FPSTemplate.CommandLineArgs.Arguments",NewName="/Script/FPSTemplate.CommandLineArgs.CmdArguments")
|
+EnumRedirects=(OldName="/Script/FPSTemplate.EvalidationError",NewName="/Script/FPSTemplate.EValidationError")
|
||||||
|
+FunctionRedirects=(OldName="/Script/FPSTemplate.GameLiftValidators.LogValidataErrorMessage",NewName="/Script/FPSTemplate.GameLiftValidators.LogValidationErrorMessage")
|
||||||
|
;+PropertyRedirects=(OldName="/Script/FPSTemplate.CommandLineArgs.Arguments",NewName="/Script/FPSTemplate.CommandLineArgs.CmdArguments")
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
using System.IO;
|
||||||
using UnrealBuildTool;
|
using UnrealBuildTool;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
public class FPSTemplate : ModuleRules
|
public class FPSTemplate : ModuleRules
|
||||||
{
|
{
|
||||||
@@ -8,9 +10,23 @@ public class FPSTemplate : ModuleRules
|
|||||||
{
|
{
|
||||||
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
|
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||||
|
|
||||||
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput", "PhysicsCore" });
|
PublicDependencyModuleNames.AddRange(new string[]
|
||||||
|
{
|
||||||
|
"Core",
|
||||||
|
"CoreUObject",
|
||||||
|
"Engine",
|
||||||
|
"InputCore",
|
||||||
|
"EnhancedInput",
|
||||||
|
"PhysicsCore",
|
||||||
|
"OpenSSL"
|
||||||
|
});
|
||||||
|
|
||||||
PrivateDependencyModuleNames.AddRange(new string[] { "GameplayTags", "Slate", "SlateCore" });
|
PrivateDependencyModuleNames.AddRange(new string[]
|
||||||
|
{
|
||||||
|
"GameplayTags",
|
||||||
|
"Slate",
|
||||||
|
"SlateCore"
|
||||||
|
});
|
||||||
|
|
||||||
// Adds in the plugin for GameLiftServerSDK if it is the server build.
|
// Adds in the plugin for GameLiftServerSDK if it is the server build.
|
||||||
|
|
||||||
|
|||||||
@@ -1,68 +1,22 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
#include "Game/ShooterGameMode.h"
|
#include "Game/ShooterGameMode.h"
|
||||||
#include "Logging/LogMacros.h"
|
|
||||||
#include "Logging/StructuredLog.h"
|
|
||||||
|
|
||||||
#if WITH_GAMELIFT
|
#include "GameLiftClpTypes.h"
|
||||||
#include "GameLiftServerSDK.h"
|
#include "GameLift/GameLiftClp.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
DEFINE_LOG_CATEGORY(LogShooterGameMode)
|
|
||||||
|
|
||||||
namespace GameLiftValidators {
|
DEFINE_LOG_CATEGORY(LogShooterGameMode);
|
||||||
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 IsStringValid(const FString& Value, const FRegexPattern* OptionalPattern, const int32 Min, const int32 Max)
|
// Function implementations.
|
||||||
{
|
|
||||||
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 IsNumberValid(const int32 Value, const int32 Min, const int32 Max)
|
|
||||||
{
|
|
||||||
return Value >= Min && Value <= Max;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AShooterGameMode::AShooterGameMode()
|
AShooterGameMode::AShooterGameMode()
|
||||||
{
|
{
|
||||||
UE_LOG(LogShooterGameMode, Log, TEXT("Initializing ShooterGameMode..."));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AShooterGameMode::BeginPlay()
|
void AShooterGameMode::BeginPlay()
|
||||||
{
|
{
|
||||||
Super::BeginPlay();
|
Super::BeginPlay();
|
||||||
|
|
||||||
#if WITH_GAMELIFT
|
#if WITH_GAMELIFT
|
||||||
InitGameLift();
|
InitGameLift();
|
||||||
#endif
|
#endif
|
||||||
@@ -71,248 +25,114 @@ void AShooterGameMode::BeginPlay()
|
|||||||
void AShooterGameMode::InitGame(const FString& MapName, const FString& Options, FString& ErrorMessage)
|
void AShooterGameMode::InitGame(const FString& MapName, const FString& Options, FString& ErrorMessage)
|
||||||
{
|
{
|
||||||
Super::InitGame(MapName, Options, 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();
|
CachedCommandLine = FCommandLine::Get();
|
||||||
|
GameLiftConfig.ServerPort = cmdlineparser::details::GetConfiguredOrDefaultPort(CachedCommandLine, "port");
|
||||||
// Parsing of Command Line
|
if (FParse::Param(*CachedCommandLine, TEXT("-glAnywhereFleet")))
|
||||||
GameLiftConfig.bDebugMode = FParse::Param(*CachedCommandLine, TEXT("Debug"));
|
|
||||||
|
|
||||||
if (GameLiftConfig.bDebugMode)
|
|
||||||
{
|
{
|
||||||
UE_LOG(LogShooterGameMode, Log, TEXT("Debug mode: ENABLED"));
|
GameLiftConfig.bIsAnywhereFleet = true;
|
||||||
#if UE_BUILD_DEBUG
|
}
|
||||||
UE_LOG(LogShooterGameMode, Log, TEXT("Command Line Arguments: %s"), *CachedCommandLine);
|
else
|
||||||
#endif
|
{
|
||||||
|
GameLiftConfig.bIsAnywhereFleet = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GameLiftConfig.ServerPort = GetConfiguredOrDefaultPort();
|
|
||||||
GameLiftConfig.bIsAnywhereFleet = FParse::Param(*CachedCommandLine, TEXT("glAnywhere"));
|
|
||||||
|
|
||||||
if (GameLiftConfig.bIsAnywhereFleet)
|
if (GameLiftConfig.bIsAnywhereFleet)
|
||||||
{
|
{
|
||||||
UE_LOGFMT(LogShooterGameMode, Log, "GameLift Anywhere Fleet Command Line Parsing");
|
GetAnywhereFleetParameters(CachedCommandLine);
|
||||||
UE_LOGFMT(LogShooterGameMode, Log, "======Command Line Parameters======");
|
LogAnywhereFleetParameters();
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
UE_LOG(LogShooterGameMode, Log, TEXT("Debug mode: ENABLED"));
|
|
||||||
#if UE_BUILD_DEBUG
|
|
||||||
UE_LOG(LogShooterGameMode, Log, TEXT("Command Line Arguments: %s"), *CachedCommandLine);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerPort = GetConfiguredOrDefaultPort();
|
|
||||||
|
|
||||||
bIsAnywhereFleet = FParse::Param(*CachedCommandLine, TEXT("glAnywhere"));
|
|
||||||
if (bIsAnywhereFleet)
|
|
||||||
{
|
|
||||||
UE_LOG(LogShooterGameMode, Log, TEXT("GameLift Anywhere Fleet Command Line Parsing"));
|
|
||||||
UE_LOG(LogShooterGameMode, Log, TEXT("======Command Line Parameters======"));
|
|
||||||
|
|
||||||
if (!FParse::Value(*CachedCommandLine, TEXT("fleetID="), FleetId))
|
|
||||||
{
|
|
||||||
UE_LOG(LogShooterGameMode, Error, TEXT("FleetId Missing in Command Line"));
|
|
||||||
bIsCriticalError = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UE_LOG(LogShooterGameMode, Log, TEXT("Fleet ID: %s"), *FleetId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!FParse::Value(*CachedCommandLine, TEXT("authtoken="), AuthToken))
|
|
||||||
{
|
|
||||||
UE_LOG(LogShooterGameMode, Error, TEXT("AuthToken Missing in Command Line"));
|
|
||||||
bIsCriticalError = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (bDebugMode)
|
|
||||||
{
|
|
||||||
FString TokenHash = GetSHA256Hash(AuthToken);
|
|
||||||
UE_LOG(LogShooterGameMode, Log, TEXT("AuthToken: %s"), *TokenHash);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UE_LOG(LogShooterGameMode, Log, TEXT("AuthToken Length: %d"), AuthToken.Len());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!FParse::Value(*CachedCommandLine, TEXT("hostId="), HostId))
|
|
||||||
{
|
|
||||||
UE_LOG(LogShooterGameMode, Error, TEXT("HostId Missing in Command Line"));
|
|
||||||
bIsCriticalError = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UE_LOG(LogShooterGameMode, Log, TEXT("Host ID: %s"), *HostId);
|
|
||||||
}
|
|
||||||
if (!FParse::Value(*CachedCommandLine, TEXT("websocketUrl="), WebSocketUrl))
|
|
||||||
{
|
|
||||||
UE_LOG(LogShooterGameMode, Error, TEXT("WebSocketUrl Missing in Command Line"));
|
|
||||||
bIsCriticalError = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UE_LOG(LogShooterGameMode, Log, TEXT("Websocket URL: %s"), *WebSocketUrl);
|
|
||||||
|
|
||||||
bool bValidWebSocket = WebSocketUrl.StartsWith(TEXT("wss://")) || WebSocketUrl.StartsWith(TEXT("ws://"));
|
|
||||||
|
|
||||||
if (bValidWebSocket)
|
|
||||||
{
|
|
||||||
int32 ColonPos = WebSocketUrl.Find(TEXT(":"), ESearchCase::CaseSensitive);
|
|
||||||
int32 SlashPos = WebSocketUrl.Find(TEXT("/"), ESearchCase::CaseSensitive, ESearchDir::FromStart, ColonPos + 1);
|
|
||||||
|
|
||||||
int32 ParsedPort = 443; // Default wss
|
|
||||||
if (WebSocketUrl.StartsWith(TEXT("ws://"))) ParsedPort = 80;
|
|
||||||
|
|
||||||
if (ColonPos != INDEX_NONE && SlashPos != INDEX_NONE)
|
|
||||||
{
|
|
||||||
FString PortStr = WebSocketUrl.Mid(ColonPos + 1, SlashPos - ColonPos - 1);
|
|
||||||
int32 ExplicitPort = FCString::Atoi(*PortStr);
|
|
||||||
if (ExplicitPort > 1024 && ExplicitPort <= 65535) // Privileged ports OK for servers
|
|
||||||
{
|
|
||||||
ParsedPort = ExplicitPort;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bValidWebSocket = false; // Invalid explicit port
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UE_LOG(LogShooterGameMode, Log, TEXT("WebSocket Parsed Port: %d"), ParsedPort);
|
FString AShooterGameMode::GetSHA256Hash(const FString& InString)
|
||||||
}
|
{
|
||||||
|
if (InString.IsEmpty()) return TEXT("da39a3ee5e6b4b0d3255bfef95601890afd80709");
|
||||||
|
|
||||||
if (!bValidWebSocket)
|
FSHA1 Sha;
|
||||||
{
|
FTCHARToUTF8 Utf8(InString);
|
||||||
UE_LOG(LogShooterGameMode, Error, TEXT("Invalid WebSocketUrl: %s"), *WebSocketUrl);
|
Sha.Update((uint8*)Utf8.Get(), Utf8.Length() * sizeof(UTF8CHAR));
|
||||||
bIsCriticalError = true;
|
Sha.Final();
|
||||||
}
|
uint8 Hash[FSHA1::DigestSize];
|
||||||
}
|
Sha.GetHash(Hash);
|
||||||
if (ServerPort == 0)
|
|
||||||
{
|
|
||||||
UE_LOG(LogShooterGameMode, Error, TEXT("Invalid or Missing Server Port Number. Shutting Down."));
|
|
||||||
bIsCriticalError = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UE_LOG(LogShooterGameMode, Log, TEXT("Port: %d"), ServerPort);
|
|
||||||
}
|
|
||||||
if (!FParse::Value(*CachedCommandLine, TEXT("serverRegion="), ServerRegion))
|
|
||||||
{
|
|
||||||
UE_LOG(LogShooterGameMode, Warning, TEXT("ServerRegion Missing in Command Line"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UE_LOG(LogShooterGameMode, Log, TEXT(">>>Server Region: %s"), *ServerRegion);
|
|
||||||
}
|
|
||||||
|
|
||||||
UE_LOG(LogShooterGameMode, Log, TEXT("==================================="));
|
// 40-char hex (SHA1 = 160 bits)
|
||||||
}
|
return FString::Printf(TEXT("%08X%08X%08X%08X%08X"),
|
||||||
else
|
Hash[0], Hash[1], Hash[2], Hash[3], Hash[4]);
|
||||||
{
|
|
||||||
UE_LOG(LogShooterGameMode, Log, TEXT("GameLift EC2 Fleet"));
|
|
||||||
if (ServerPort == 0)
|
|
||||||
{
|
|
||||||
UE_LOG(LogShooterGameMode, Error, TEXT("Invalid or Missing Server Port Number. Shutting Down."));
|
|
||||||
bIsCriticalError = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UE_LOG(LogShooterGameMode, Log, TEXT("Port: %d"), ServerPort);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bIsCriticalError)
|
|
||||||
{
|
|
||||||
UE_LOG(LogShooterGameMode, Error, TEXT("Critical Missing or Invalid Arguments in Command Line. Shutting Down."));
|
|
||||||
FPlatformMisc::RequestExit(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UE_LOG(LogShooterGameMode, Log, TEXT("Command Line Parsed Successfully."));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 AShooterGameMode::GetConfiguredOrDefaultPort() const
|
|
||||||
{
|
|
||||||
// Default Unreal Engine listen/dedicated server port
|
|
||||||
constexpr int32 DefaultPort = 7777;
|
|
||||||
|
|
||||||
int32 CmdPort = DefaultPort;
|
|
||||||
|
|
||||||
// Check if a port was passed via command line: -port=xxxx
|
|
||||||
|
|
||||||
if (FParse::Value(*CachedCommandLine, TEXT("port="), CmdPort) &&
|
|
||||||
GameLiftValidators::IsNumberValid(CmdPort, GameLiftValidators::ServerPortMin, GameLiftValidators::ServerPortMax))
|
|
||||||
{
|
|
||||||
return CmdPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
UE_LOGFMT(LogShooterGameMode, Warning, "Invalid/Missing port in command line - using {0}", DefaultPort);
|
|
||||||
return DefaultPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
FString AShooterGameMode::GetSHA256Hash(const FString& Input)
|
|
||||||
{
|
|
||||||
FTCHARToUTF8 Utf8Input(Input);
|
|
||||||
FSHA256Signature Hash;
|
|
||||||
if (FPlatformMisc::GetSHA256Signature(reinterpret_cast<const uint8*>(Utf8Input.Get()), Utf8Input.Length(), Hash))
|
|
||||||
{
|
|
||||||
return Hash.ToString();
|
|
||||||
}
|
|
||||||
return FString::Printf(TEXT("Fail_%dbytes"), Input.Len());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AShooterGameMode::ParseAndOutputResult(const FString& InString, FString& OutValue, bool bRequired)
|
|
||||||
{
|
|
||||||
// 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()
|
void AShooterGameMode::InitGameLift()
|
||||||
{
|
{
|
||||||
#if WITH_GAMELIFT
|
GetAnywhereFleetParameters(CachedCommandLine);
|
||||||
//TODO: Need to write later, working on parser first.
|
}
|
||||||
|
|
||||||
|
bool AShooterGameMode::GetAnywhereFleetParameters(FString CommandLineString)
|
||||||
|
{
|
||||||
|
bool bAllAnywhereFleetParametersValid = true;
|
||||||
|
cmdlineparser::details::FParseResult AuthResult = cmdlineparser::GetValueOfToken(CommandLineString, cmdlineparser::details::EAvailableTokens::AuthToken);
|
||||||
|
if (AuthResult.bIsValid)
|
||||||
|
{
|
||||||
|
GameLiftConfig.AuthToken = AuthResult.Value;
|
||||||
|
#if UE_BUILD_DEBUG
|
||||||
|
UE_LOGFMT(LogShooterGameMode, Log, "AuthToken loaded: {0}", GameLiftConfig.AuthToken);
|
||||||
#else
|
#else
|
||||||
UE_LOGFMT(LogShooterGameMode, Warning, "GameLift disabled");
|
UE_LOGFMT(LogShooterGameMode, Log, "AuthToken loaded: HASH - {0}", GetSHA256Hash(GameLiftConfig.AuthToken));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bAllAnywhereFleetParametersValid = false;
|
||||||
|
#if UE_BUILD_DEBUG
|
||||||
|
UE_LOGFMT(LogShooterGameMode, Error, "AuthToken Invalid: {0}", GameLiftConfig.AuthToken);
|
||||||
|
#else
|
||||||
|
UE_LOGFMT(LogShooterGameMode, Error, "AuthToken Invalid: HASH - {0}", GetSHA256Hash(GameLiftConfig.AuthToken));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmdlineparser::details::FParseResult HostIdResult = cmdlineparser::GetValueOfToken(CommandLineString, cmdlineparser::details::EAvailableTokens::HostId);
|
||||||
|
if (HostIdResult.bIsValid)
|
||||||
|
{
|
||||||
|
GameLiftConfig.HostId = HostIdResult.Value;
|
||||||
|
UE_LOGFMT(LogShooterGameMode, Log, "HostId loaded: {0}", GameLiftConfig.HostId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bAllAnywhereFleetParametersValid = false;
|
||||||
|
UE_LOGFMT(LogShooterGameMode, Error, "HostId Invalid: {0}", HostIdResult.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdlineparser::details::FParseResult FleetIdResult = cmdlineparser::GetValueOfToken(CommandLineString, cmdlineparser::details::EAvailableTokens::FleetId);
|
||||||
|
if (FleetIdResult.bIsValid)
|
||||||
|
{
|
||||||
|
GameLiftConfig.FleetId = FleetIdResult.Value;
|
||||||
|
UE_LOGFMT(LogShooterGameMode, Log, "FleetId loaded: {0}", FleetIdResult.Value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bAllAnywhereFleetParametersValid = false;
|
||||||
|
UE_LOGFMT(LogShooterGameMode, Error, "FleetId Invalid: {0}", GameLiftConfig.HostId);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdlineparser::details::FParseResult WebSocketUrlResult = cmdlineparser::GetValueOfToken(CommandLineString, cmdlineparser::details::EAvailableTokens::WebsocketUrl);
|
||||||
|
if (WebSocketUrlResult.bIsValid)
|
||||||
|
{
|
||||||
|
GameLiftConfig.WebSocketUrl = WebSocketUrlResult.Value;
|
||||||
|
UE_LOGFMT(LogShooterGameMode, Log, "WebSocketUrl loaded: {0}", WebSocketUrlResult.Value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bAllAnywhereFleetParametersValid = false;
|
||||||
|
UE_LOGFMT(LogShooterGameMode, Error, "WebSocketUrl Invalid: {0}", WebSocketUrlResult.Value);
|
||||||
|
}
|
||||||
|
return bAllAnywhereFleetParametersValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AShooterGameMode::LogAnywhereFleetParameters()
|
||||||
|
{
|
||||||
|
UE_LOGFMT(LogShooterGameMode, Log, "Anywhere Fleet Parameters:");
|
||||||
|
UE_LOGFMT(LogShooterGameMode, Log, "AuthToken: {0}", GameLiftConfig.AuthToken);
|
||||||
|
UE_LOGFMT(LogShooterGameMode, Log, "FleetId: {0}", GameLiftConfig.FleetId);
|
||||||
|
UE_LOGFMT(LogShooterGameMode, Log, "HostId: {0}", GameLiftConfig.HostId);
|
||||||
|
UE_LOGFMT(LogShooterGameMode, Log, "WebsocketUrl: {0}", GameLiftConfig.WebSocketUrl);
|
||||||
|
UE_LOGFMT(LogShooterGameMode, Log, "Server Port: {0}", GameLiftConfig.ServerPort);
|
||||||
|
}
|
||||||
|
|||||||
78
Source/FPSTemplate/Private/GameLift/GameLiftClp.cpp
Normal file
78
Source/FPSTemplate/Private/GameLift/GameLiftClp.cpp
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
#include "GameLift/GameLiftClp.h"
|
||||||
|
|
||||||
|
int32 cmdlineparser::GetConfiguredOrDefaultPort(const FString& Token)
|
||||||
|
{
|
||||||
|
return details::GetConfiguredOrDefaultPort(FCommandLine::Get(), Token);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 cmdlineparser::GetConfiguredOrDefaultPort(const FString& CommandLine, const FString& Token)
|
||||||
|
{
|
||||||
|
return details::GetConfiguredOrDefaultPort(CommandLine, Token);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdlineparser::details::FParseResult cmdlineparser::GetValueOfToken(const FString& CommandLine, const details::EAvailableTokens Token)
|
||||||
|
{
|
||||||
|
details::FParseResult Result;
|
||||||
|
FString ValueOfToken;
|
||||||
|
Result.Token = Token;
|
||||||
|
|
||||||
|
ensure(Token < details::EAvailableTokens::MaxToken);
|
||||||
|
const bool bTokenFound = FParse::Value(
|
||||||
|
*CommandLine,
|
||||||
|
*details::EnsureEndsWith(details::CLI_TOKENS[static_cast<int32>(Token)],
|
||||||
|
TEXT("=")),
|
||||||
|
ValueOfToken
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!bTokenFound)
|
||||||
|
{
|
||||||
|
Result.Value = FString();
|
||||||
|
Result.ErrorCode = details::EErrorCodes::TokenNotFound;
|
||||||
|
Result.bIsValid = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ValueOfToken.IsEmpty())
|
||||||
|
{
|
||||||
|
Result.Value = FString();
|
||||||
|
Result.ErrorCode = details::EErrorCodes::ValueEmpty;
|
||||||
|
Result.bIsValid = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: Validation of inputs
|
||||||
|
Result.Value = ValueOfToken;
|
||||||
|
Result.ErrorCode = details::EErrorCodes::NoError;
|
||||||
|
Result.bIsValid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure(Result.ErrorCode < details::EErrorCodes::MaxCode);
|
||||||
|
FString ErrorMessage = details::ERROR_MESSAGES[static_cast<int32>(Result.ErrorCode)];
|
||||||
|
FString TokenName = details::CLI_TOKENS[static_cast<int32>(Result.Token)];
|
||||||
|
FString Value = Result.Value;
|
||||||
|
Result.ErrorMessage = FString::Format(*ErrorMessage, {FStringFormatArg(TokenName), FStringFormatArg(Value)});
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// cmdlineparser::Details namespace
|
||||||
|
|
||||||
|
FString cmdlineparser::details::EnsureEndsWith(const FString& Token, const TCHAR* Suffix)
|
||||||
|
{
|
||||||
|
return Token.EndsWith(Suffix) ? Token : Token + Suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 cmdlineparser::details::GetConfiguredOrDefaultPort(const FString& CommandLine, const FString& Token)
|
||||||
|
{
|
||||||
|
const int32 Port = FURL::UrlConfig.DefaultPort;
|
||||||
|
|
||||||
|
if (int32 CliPort; FParse::Value(*CommandLine, *EnsureEndsWith(Token, TEXT("=")), CliPort))
|
||||||
|
{
|
||||||
|
if (CliPort >= details::MIN_PORT && CliPort <= details::MAX_PORT)
|
||||||
|
{
|
||||||
|
return CliPort;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Port;
|
||||||
|
}
|
||||||
160
Source/FPSTemplate/Private/GameLift/GameLiftValidators.cpp
Normal file
160
Source/FPSTemplate/Private/GameLift/GameLiftValidators.cpp
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
|
#include "GameLift/GameLiftValidators.h"
|
||||||
|
|
||||||
|
#include "Game/ShooterGameMode.h"
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///Lazy Singleton
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
TArray<FString>& UGameLiftValidators::GetPatterns()
|
||||||
|
{
|
||||||
|
static TArray<FString> Patterns;
|
||||||
|
if (Patterns.Num() == 0)
|
||||||
|
{
|
||||||
|
Patterns.AddDefaulted(static_cast<int32>(EGameLiftParams::Max));
|
||||||
|
Patterns[static_cast<int32>(EGameLiftParams::AuthToken)] =
|
||||||
|
TEXT("^[a-zA-Z0-9\\-]+$"); // AuthToken
|
||||||
|
Patterns[static_cast<int32>(EGameLiftParams::FleetId)] =
|
||||||
|
TEXT("^[a-z]*fleet-[a-zA-Z0-9\\-]+$|^arn:.*:[a-z]*fleet\\/[a-z]*fleet-[a-zA-Z0-9\\-]+$"); // FleetId
|
||||||
|
Patterns[static_cast<int32>(EGameLiftParams::HostId)] =
|
||||||
|
TEXT("^[0-9A-Z]\\d+$"); // HostId
|
||||||
|
Patterns[static_cast<int32>(EGameLiftParams::WebSocketUrl)] =
|
||||||
|
TEXT("^wss:\\/\\/[a-zA-Z0-9.-]+(\\.amazonaws\\.com)?(\\/[^\\s]*)?$"); // WebSocketUrl
|
||||||
|
Patterns[static_cast<int32>(EGameLiftParams::ServerRegion)] =
|
||||||
|
TEXT("^[a-z]{2}-[a-z]+-[0-9]$"); // Region (ca-central-1)
|
||||||
|
}
|
||||||
|
return Patterns;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool UGameLiftValidators::IsMatchesRegex(const FString& Value, EGameLiftParams ParamType)
|
||||||
|
{
|
||||||
|
ensure(ParamType < EGameLiftParams::Max);
|
||||||
|
ensure(GetPatterns().Num() > static_cast<int32>(ParamType));
|
||||||
|
const FRegexPattern Pattern = FRegexPattern(GetPatterns()[static_cast<int32>(ParamType)]);
|
||||||
|
FRegexMatcher TestMatcher(Pattern, Value);
|
||||||
|
return TestMatcher.FindNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool UGameLiftValidators::IsStringValid(const FString& Value, EGameLiftParams ParamType)
|
||||||
|
{
|
||||||
|
// Checks to make sure the ParamType is not the sentinel
|
||||||
|
ensure(ParamType < EGameLiftParams::Max);
|
||||||
|
|
||||||
|
if (Value.IsEmpty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const int32 Len = Value.Len();
|
||||||
|
const int32 Index = static_cast<int32>(ParamType);
|
||||||
|
|
||||||
|
if (Len < MinLengths[Index] || Len > MaxLengths[Index]) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UGameLiftValidators::IsStringShort(const FString& Value, EGameLiftParams ParamType)
|
||||||
|
{
|
||||||
|
ensure(ParamType < EGameLiftParams::Max);
|
||||||
|
if (Value.IsEmpty()) return false;
|
||||||
|
const int32 Len = Value.Len();
|
||||||
|
const int32 Index = static_cast<int32>(ParamType);
|
||||||
|
if (Len < MinLengths[Index]) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UGameLiftValidators::IsStringLong(const FString& Value, EGameLiftParams ParamType)
|
||||||
|
{
|
||||||
|
ensure(ParamType < EGameLiftParams::Max);
|
||||||
|
if (Value.IsEmpty()) return false;
|
||||||
|
const int32 Len = Value.Len();
|
||||||
|
const int32 Index = static_cast<int32>(ParamType);
|
||||||
|
if (Len > MaxLengths[Index]) return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
FParamResult UGameLiftValidators::ValidateParam(const FString& Value, const EGameLiftParams ParamType)
|
||||||
|
{
|
||||||
|
ensure(ParamType < EGameLiftParams::Max);
|
||||||
|
bool bErrorTriggered = false;
|
||||||
|
FParamResult Result;
|
||||||
|
Result.ParamType = ParamType;
|
||||||
|
|
||||||
|
// Quick empty check
|
||||||
|
if (Value.IsEmpty() && !bErrorTriggered)
|
||||||
|
{
|
||||||
|
Result.bValid = false;
|
||||||
|
Result.ErrorMessage = FString::Format(TEXT("Missing {0} in command line arguments"), {GetParameterFromEnum(ParamType)});
|
||||||
|
Result.ErrorCode = EValidationError::Empty;
|
||||||
|
bErrorTriggered = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsStringShort(Value, ParamType) && !bErrorTriggered)
|
||||||
|
{
|
||||||
|
Result.bValid = false;
|
||||||
|
Result.Value = Value;
|
||||||
|
Result.ErrorMessage = FString::Format(TEXT("Parameter {0} does not meet minimum length requirements."), { GetParameterFromEnum(ParamType)} );
|
||||||
|
Result.ErrorCode = EValidationError::TooShort;
|
||||||
|
bErrorTriggered = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsStringLong(Value, ParamType) && !bErrorTriggered)
|
||||||
|
{
|
||||||
|
Result.bValid = false;
|
||||||
|
Result.Value = Value;
|
||||||
|
Result.ErrorMessage = FString::Format(TEXT("Parameter {0} does not meet maximum length requirements."), { GetParameterFromEnum(ParamType)} );
|
||||||
|
Result.ErrorCode = EValidationError::TooLong;
|
||||||
|
bErrorTriggered = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsMatchesRegex(Value, ParamType) && !bErrorTriggered)
|
||||||
|
{
|
||||||
|
Result.bValid = false;
|
||||||
|
Result.Value = Value;
|
||||||
|
Result.ErrorMessage = FString::Format(TEXT("Parameter {0} has an invalid format."), { GetParameterFromEnum(ParamType)} );
|
||||||
|
Result.ErrorCode = EValidationError::InvalidFormat;
|
||||||
|
bErrorTriggered = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bErrorTriggered)
|
||||||
|
{
|
||||||
|
Result.bValid = true;
|
||||||
|
Result.Value = Value;
|
||||||
|
Result.ErrorMessage = FString("");
|
||||||
|
Result.ErrorCode = EValidationError::None;
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
FString UGameLiftValidators::GetParameterFromEnum(const EGameLiftParams InParam)
|
||||||
|
{
|
||||||
|
ensure(InParam < EGameLiftParams::Max);
|
||||||
|
const FString FullParameter = UEnum::GetValueAsString(InParam);
|
||||||
|
FString Left, Right;
|
||||||
|
FullParameter.Split(TEXT("::"), &Left, &Right);
|
||||||
|
const FString NameOnly = Right;
|
||||||
|
return NameOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
FString UGameLiftValidators::GetErrorFromEnum(EValidationError InParam)
|
||||||
|
{
|
||||||
|
ensure(InParam <= EValidationError::NotFound);
|
||||||
|
const FString FullParameter = UEnum::GetValueAsString(InParam);
|
||||||
|
FString Left, Right;
|
||||||
|
FullParameter.Split(TEXT("::"), &Left, &Right);
|
||||||
|
const FString NameOnly = Right;
|
||||||
|
return NameOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UGameLiftValidators::LogValidationErrorMessage(FParamResult ValidationResult)
|
||||||
|
{
|
||||||
|
if (ValidationResult.ErrorCode == EValidationError::None) return; // no error logging required
|
||||||
|
UE_LOGFMT(LogShooterGameMode, Error, "{0}", ValidationResult.ErrorMessage);
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
#include "GameLift/GameLiftValidators_old.h"
|
||||||
|
|
||||||
|
namespace GameLiftValidators2
|
||||||
|
{
|
||||||
|
inline const FRegexPattern& GetPattern(ECliParam ParamType)
|
||||||
|
{
|
||||||
|
ensure(ParamType < ECliParam::Max);
|
||||||
|
static const FRegexPattern Patterns[static_cast<int32>(ECliParam::Max)] =
|
||||||
|
{
|
||||||
|
FRegexPattern(TEXT("^[a-zA-Z0-9\\-]+$")), // AuthToken
|
||||||
|
FRegexPattern(TEXT("^[a-z]*fleet-[a-zA-Z0-9\\-]+$|^arn:.*:[a-z]*fleet\\/[a-z]*fleet-[a-zA-Z0-9\\-]+$")), // FleetId
|
||||||
|
FRegexPattern(TEXT("^[0-9A-Z]\\d+$")), // HostId
|
||||||
|
FRegexPattern(TEXT("^wss:\\/\\/[a-zA-Z0-9.-]+(\\.amazonaws\\.com)?(\\/[^\\s]*)?$")), // WebSocketUrl
|
||||||
|
FRegexPattern(TEXT("^[a-z]{2}-[a-z]+-[0-9]$")), // Region (ca-central-1)
|
||||||
|
};
|
||||||
|
return Patterns[static_cast<int32>(ParamType)];
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr int32 MaxLengths[static_cast<int32>(ECliParam::Max)] =
|
||||||
|
{
|
||||||
|
64, //authToken
|
||||||
|
512, //FleetId
|
||||||
|
128, //HostId
|
||||||
|
128, //WebSocketUrl
|
||||||
|
16, //Region (ca-central-1)
|
||||||
|
};
|
||||||
|
|
||||||
|
inline int32 GetMaxLength(ECliParam ParamType)
|
||||||
|
{
|
||||||
|
ensure(ParamType < ECliParam::Max);
|
||||||
|
return MaxLengths[static_cast<int32>(ParamType)];
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr int32 MinLengths[static_cast<int32>(ECliParam::Max)] =
|
||||||
|
{
|
||||||
|
1, //authToken
|
||||||
|
1, //FleetId
|
||||||
|
1, //HostId
|
||||||
|
1, //WebSocketUrl
|
||||||
|
3, //Region (ca-central-1)
|
||||||
|
};
|
||||||
|
|
||||||
|
inline int32 GetMinLength(ECliParam ParamType)
|
||||||
|
{
|
||||||
|
ensure(ParamType < ECliParam::Max);
|
||||||
|
return MinLengths[static_cast<int32>(ParamType)];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsStringValid(const FString& Value, ECliParam ParamType)
|
||||||
|
{
|
||||||
|
|
||||||
|
ensure(ParamType < ECliParam::Max);
|
||||||
|
if (Value.IsEmpty()) return false;
|
||||||
|
|
||||||
|
if (const int32 Len = Value.Len(); (Len < GetMinLength(ParamType)) || (Len > GetMaxLength(ParamType)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const FRegexPattern& Pattern = GetPattern(ParamType);
|
||||||
|
FRegexMatcher StringMatcher(Pattern, Value);
|
||||||
|
return StringMatcher.FindNext() && StringMatcher.GetMatchEnding() == Value.Len(); // returns true on a full or partial match
|
||||||
|
}
|
||||||
|
}
|
||||||
22
Source/FPSTemplate/Private/GameLiftClpTypes.cpp
Normal file
22
Source/FPSTemplate/Private/GameLiftClpTypes.cpp
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#include "GameLiftClpTypes.h"
|
||||||
|
|
||||||
|
const TArray<FString>& cmdlineparser::details::ERROR_MESSAGES = []() -> const TArray<FString>&
|
||||||
|
{
|
||||||
|
static TArray<FString> Error_Messages;
|
||||||
|
Error_Messages.Add(TEXT("VALID: {0}: {1}"));
|
||||||
|
Error_Messages.Add(TEXT("INVALID TOKEN: [-{0}=] not found in command line arguments"));
|
||||||
|
Error_Messages.Add(TEXT("EMPTY VALUE: [-{0}=] found. No value assigned"));
|
||||||
|
Error_Messages.Add(TEXT("VALIDATION FAILED: [-{0}=] found.... Value: [-{1}=]"));
|
||||||
|
return Error_Messages;
|
||||||
|
}();
|
||||||
|
|
||||||
|
|
||||||
|
const TArray<FString>& cmdlineparser::details::CLI_TOKENS = []() -> const TArray<FString>&
|
||||||
|
{
|
||||||
|
static TArray<FString> Cli_Tokens;
|
||||||
|
Cli_Tokens.Add(TEXT("authtoken"));
|
||||||
|
Cli_Tokens.Add(TEXT("hostid"));
|
||||||
|
Cli_Tokens.Add(TEXT("fleetid"));
|
||||||
|
Cli_Tokens.Add(TEXT("websocketurl"));
|
||||||
|
return Cli_Tokens;
|
||||||
|
}();
|
||||||
@@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "ShooterGameModeBase.h"
|
#include "ShooterGameModeBase.h"
|
||||||
|
|
||||||
#include "ShooterGameMode.generated.h"
|
#include "ShooterGameMode.generated.h"
|
||||||
|
|
||||||
DECLARE_LOG_CATEGORY_EXTERN(LogShooterGameMode, Log, All);
|
DECLARE_LOG_CATEGORY_EXTERN(LogShooterGameMode, Log, All);
|
||||||
@@ -12,47 +11,27 @@ DECLARE_LOG_CATEGORY_EXTERN(LogShooterGameMode, Log, All);
|
|||||||
struct FProcessParameters;
|
struct FProcessParameters;
|
||||||
struct FServerParameters;
|
struct FServerParameters;
|
||||||
|
|
||||||
struct FGameLiftCliConfig
|
struct FGameLiftConfig
|
||||||
{
|
{
|
||||||
bool bDebugMode = false;
|
bool bDebugMode = false;
|
||||||
bool bIsAnywhereFleet = false;
|
bool bIsAnywhereFleet = false;
|
||||||
bool bIsCriticalError = false;
|
bool bIsCriticalError = false;
|
||||||
|
|
||||||
int32 ServerPort = 0;
|
int32 ServerPort;
|
||||||
|
|
||||||
FString AuthToken;
|
FString AuthToken;
|
||||||
FString FleetId;
|
FString FleetId;
|
||||||
FString HostId;
|
FString HostId;
|
||||||
FString WebSocketUrl;
|
FString WebSocketUrl;
|
||||||
FString ServerRegion;
|
FString ServerRegion;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace GameLiftValidators
|
enum ETokenStatus : uint8
|
||||||
{
|
{
|
||||||
extern const FRegexPattern FleetIdPattern;
|
Found,
|
||||||
extern const int32 FleetIdLengthMin;
|
NotFoundRequired,
|
||||||
extern const int32 FleetIdLengthMax;
|
NotFoundNotRequired
|
||||||
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 IsStringValid(const FString& Value, const FRegexPattern& OptionalPattern, int32 Min, int32 Max);
|
|
||||||
bool IsNumberValid(int32 Value, int32 Min, int32 Max);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -61,55 +40,21 @@ UCLASS()
|
|||||||
class FPSTEMPLATE_API AShooterGameMode : public AShooterGameModeBase
|
class FPSTEMPLATE_API AShooterGameMode : public AShooterGameModeBase
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
AShooterGameMode();
|
AShooterGameMode();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
UPROPERTY(Config, BlueprintReadOnly)
|
|
||||||
bool bIsAnywhereFleet = false;
|
|
||||||
|
|
||||||
UPROPERTY(Config, BlueprintReadOnly)
|
|
||||||
FString FleetId;
|
|
||||||
|
|
||||||
UPROPERTY(Config, BlueprintReadOnly)
|
|
||||||
FString AuthToken;
|
|
||||||
|
|
||||||
UPROPERTY(Config, BlueprintReadOnly)
|
|
||||||
FString HostId;
|
|
||||||
|
|
||||||
UPROPERTY(Config, BlueprintReadOnly)
|
|
||||||
FString WebSocketUrl;
|
|
||||||
|
|
||||||
UPROPERTY(Config)
|
|
||||||
FString ServerRegion;
|
|
||||||
|
|
||||||
UPROPERTY(Config, BlueprintReadOnly)
|
|
||||||
int32 ServerPort;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
|
||||||
bool bDebugMode = false;
|
|
||||||
|
|
||||||
virtual void BeginPlay() override;
|
virtual void BeginPlay() override;
|
||||||
virtual void InitGame(const FString& MapName, const FString& Options, FString& ErrorMessage) 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:
|
private:
|
||||||
|
FGameLiftConfig GameLiftConfig;
|
||||||
FGameLiftCliConfig GameLiftConfig;
|
|
||||||
|
|
||||||
FString CachedCommandLine;
|
FString CachedCommandLine;
|
||||||
TSharedPtr<FProcessParameters> ProcessParameters;
|
|
||||||
TSharedPtr<FServerParameters> ServerParameters;
|
|
||||||
|
|
||||||
int32 GetConfiguredOrDefaultPort() const;
|
|
||||||
static FString GetSHA256Hash(const FString& Input);
|
|
||||||
|
|
||||||
bool ParseAndOutputResult(const FString& InString, FString& OutValue, bool bRequired = false);
|
|
||||||
bool ParseAndValidate(const FString& InArguments, FGameLiftCliConfig& Config);
|
|
||||||
static bool ValidateFleetId(const FString& InFleetId);
|
|
||||||
|
|
||||||
|
static FString GetSHA256Hash(const FString& CommandLineString);
|
||||||
void InitGameLift();
|
void InitGameLift();
|
||||||
};
|
|
||||||
|
|
||||||
|
bool GetAnywhereFleetParameters(FString CommandLineString);
|
||||||
|
void LogAnywhereFleetParameters();
|
||||||
|
};
|
||||||
|
|||||||
23
Source/FPSTemplate/Public/GameLift/GameLiftClp.h
Normal file
23
Source/FPSTemplate/Public/GameLift/GameLiftClp.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "GameLiftClpTypes.h"
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
|
||||||
|
namespace cmdlineparser
|
||||||
|
{
|
||||||
|
// int32 GetConfiguredOrDefaultPort();
|
||||||
|
int32 GetConfiguredOrDefaultPort(const FString& Token = TEXT("port="));
|
||||||
|
int32 GetConfiguredOrDefaultPort(const FString& CommandLine, const FString& Token = TEXT("port="));
|
||||||
|
|
||||||
|
details::FParseResult GetValueOfToken(const FString& CommandLine, const details::EAvailableTokens Token);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace cmdlineparser::details
|
||||||
|
{
|
||||||
|
inline static constexpr int32 MIN_PORT = 1024;
|
||||||
|
inline static constexpr int32 MAX_PORT = 65535;
|
||||||
|
inline static constexpr const TCHAR* DEFAULT_PORT_TOKEN = TEXT("port=");
|
||||||
|
|
||||||
|
FString EnsureEndsWith(const FString& Token, const TCHAR* Suffix);
|
||||||
|
int32 GetConfiguredOrDefaultPort(const FString& CommandLine, const FString& Token);
|
||||||
|
}
|
||||||
|
|
||||||
93
Source/FPSTemplate/Public/GameLift/GameLiftValidators.h
Normal file
93
Source/FPSTemplate/Public/GameLift/GameLiftValidators.h
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||||
|
#include "GameLiftValidators.generated.h"
|
||||||
|
|
||||||
|
UENUM(BlueprintType)
|
||||||
|
enum class EGameLiftParams : uint8
|
||||||
|
{
|
||||||
|
AuthToken,
|
||||||
|
FleetId,
|
||||||
|
HostId,
|
||||||
|
ServerRegion,
|
||||||
|
WebSocketUrl,
|
||||||
|
Max // Sentry to determine length of EGameLiftParams
|
||||||
|
};
|
||||||
|
|
||||||
|
UENUM(BlueprintType)
|
||||||
|
enum class EValidationError : uint8
|
||||||
|
{
|
||||||
|
None, // Valid
|
||||||
|
Empty, // Missing Parameter
|
||||||
|
TooShort, // Too Short
|
||||||
|
TooLong, // Too long
|
||||||
|
InvalidFormat, // Invalid format
|
||||||
|
NotFound // Sentinel value, any new error codes get put above this.
|
||||||
|
};
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType)
|
||||||
|
struct FParamResult
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
EGameLiftParams ParamType;
|
||||||
|
FString Value;
|
||||||
|
bool bValid;
|
||||||
|
FString ErrorMessage;
|
||||||
|
EValidationError ErrorCode;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
UCLASS()
|
||||||
|
class FPSTEMPLATE_API UGameLiftValidators : public UBlueprintFunctionLibrary
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
private:
|
||||||
|
static TArray<FString>& GetPatterns();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static constexpr int32 MaxLengths[static_cast<int32>(EGameLiftParams::Max)] =
|
||||||
|
{
|
||||||
|
64, //authToken
|
||||||
|
512, //FleetId
|
||||||
|
128, //HostId
|
||||||
|
128, //WebSocketUrl
|
||||||
|
16, //Region (ca-central-1)
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr int32 MinLengths[static_cast<int32>(EGameLiftParams::Max)] =
|
||||||
|
{
|
||||||
|
1, //authToken
|
||||||
|
1, //FleetId
|
||||||
|
1, //HostId
|
||||||
|
1, //WebSocketUrl
|
||||||
|
3, //Region (ca-central-1)
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool IsStringValid(const FString& Value, EGameLiftParams ParamType);
|
||||||
|
static bool IsStringShort(const FString& Value, EGameLiftParams ParamType);
|
||||||
|
static bool IsStringLong(const FString& Value, EGameLiftParams ParamType);
|
||||||
|
static bool IsMatchesRegex(const FString& Value, EGameLiftParams ParamType);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "GameLift")
|
||||||
|
static FParamResult ValidateParam(const FString& Value, EGameLiftParams ParamType);
|
||||||
|
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "GameLift")
|
||||||
|
static FString GetParameterFromEnum(EGameLiftParams InParam);
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "GameLift")
|
||||||
|
static FString GetErrorFromEnum(EValidationError InParam);
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "GameLift")
|
||||||
|
static void LogValidationErrorMessage(FParamResult ValidationResult);
|
||||||
|
|
||||||
|
};
|
||||||
24
Source/FPSTemplate/Public/GameLift/GameLiftValidators_old.h
Normal file
24
Source/FPSTemplate/Public/GameLift/GameLiftValidators_old.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
|
||||||
|
struct FParamResult
|
||||||
|
{
|
||||||
|
FString Value;
|
||||||
|
bool bValid;
|
||||||
|
FString ErrorMessage;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace GameLiftValidators2
|
||||||
|
{
|
||||||
|
enum class ECliParam
|
||||||
|
{
|
||||||
|
AuthToken, FleetId, HostId, Region, WebSocketUrl, Max
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int32 GetMaxLength(ECliParam ParamType);
|
||||||
|
int32 GetMinLength(ECliParam ParamType);
|
||||||
|
|
||||||
|
bool IsStringValid(const FString& Value, ECliParam ParamType);
|
||||||
|
bool IsNumberValid(int32 Value, int32 Min, int32 Max);
|
||||||
|
}
|
||||||
35
Source/FPSTemplate/Public/GameLiftClpTypes.h
Normal file
35
Source/FPSTemplate/Public/GameLiftClpTypes.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace cmdlineparser::details
|
||||||
|
{
|
||||||
|
enum EAvailableTokens
|
||||||
|
{
|
||||||
|
AuthToken,
|
||||||
|
HostId,
|
||||||
|
FleetId,
|
||||||
|
WebsocketUrl,
|
||||||
|
MaxToken
|
||||||
|
};
|
||||||
|
|
||||||
|
enum EErrorCodes
|
||||||
|
{
|
||||||
|
NoError,
|
||||||
|
TokenNotFound,
|
||||||
|
ValueEmpty,
|
||||||
|
FailedValidation,
|
||||||
|
MaxCode
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const TArray<FString>& ERROR_MESSAGES;
|
||||||
|
extern const TArray<FString>& CLI_TOKENS;
|
||||||
|
|
||||||
|
struct FParseResult
|
||||||
|
{
|
||||||
|
EAvailableTokens Token;
|
||||||
|
FString Value;
|
||||||
|
bool bIsValid;
|
||||||
|
EErrorCodes ErrorCode;
|
||||||
|
FString ErrorMessage;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user