mirror of
https://github.com/ApfelTeeSaft/UniversalSlashingSimulator.git
synced 2026-08-27 03:43:34 +00:00
350 lines
10 KiB
C++
350 lines
10 KiB
C++
/**
|
|
* UniversalSlashingSimulator - DLL Entry Point
|
|
*
|
|
* Main entry point for the DLL. Initializes all core systems
|
|
*
|
|
* Injection flow:
|
|
* 1. DLL_PROCESS_ATTACH
|
|
* 2. Create initialization thread
|
|
* 3. Initialize logging
|
|
* 4. Parse command-line arguments
|
|
* 5. Initialize engine core
|
|
* 6. Initialize STW systems (GameMode, Missions, Inventory, Building)
|
|
*
|
|
* Command-Line Arguments (USS-specific):
|
|
* -USS_Mission=<MissionBlueprint> Mission blueprint to load
|
|
* -USS_Map=<MapName> Map to load
|
|
* -USS_Difficulty=<1-140> Difficulty level
|
|
* -USS_MaxPlayers=<1-4> Maximum players
|
|
* -USS_Zone=<ZoneName> Zone name
|
|
* -USS_NoMissions Disable missions
|
|
* -USS_NoInventory Disable inventory
|
|
* -USS_NoBuilding Disable building
|
|
* -USS_Debug Enable debug mode
|
|
*/
|
|
|
|
#include "../Core/Common.h"
|
|
#include "../Core/Logging/Log.h"
|
|
#include "../Core/Diagnostics/CrashHandler.h"
|
|
#include "../Engine/EngineCore.h"
|
|
#include "../STW/GameMode/STWGameMode.h"
|
|
#include "../STW/Missions/MissionManager.h"
|
|
#include "../STW/Inventory/InventoryManager.h"
|
|
#include "../STW/Building/BuildingManager.h"
|
|
#include "../Core/Memory/PatternScanner.h"
|
|
#include <string>
|
|
#include <sstream>
|
|
|
|
namespace USS
|
|
{
|
|
// Forward declarations
|
|
DWORD WINAPI InitializationThread(LPVOID lpParam);
|
|
void ParseCommandLineArguments(FSTWGameConfig& Config);
|
|
bool GetCommandLineArg(const char* ArgName, std::string& OutValue);
|
|
bool HasCommandLineArg(const char* ArgName);
|
|
int GetCommandLineArgInt(const char* ArgName, int DefaultValue);
|
|
|
|
// Global module handle
|
|
static HMODULE g_hModule = nullptr;
|
|
|
|
// Initialization state
|
|
static bool g_bInitialized = false;
|
|
static bool g_bDebugMode = false;
|
|
|
|
/**
|
|
* Parse command-line arguments and populate game config
|
|
*/
|
|
void ParseCommandLineArguments(FSTWGameConfig& Config)
|
|
{
|
|
// Get command line
|
|
const char* CmdLine = GetCommandLineA();
|
|
if (!CmdLine)
|
|
return;
|
|
|
|
USS_LOG("Parsing command line: %s", CmdLine);
|
|
|
|
// Mission blueprint
|
|
std::string MissionArg;
|
|
if (GetCommandLineArg("-USS_Mission", MissionArg))
|
|
{
|
|
Config.MissionBlueprint = MissionArg;
|
|
USS_LOG(" Mission: %s", MissionArg.c_str());
|
|
}
|
|
|
|
// Map name
|
|
std::string MapArg;
|
|
if (GetCommandLineArg("-USS_Map", MapArg))
|
|
{
|
|
Config.MapName = MapArg;
|
|
USS_LOG(" Map: %s", MapArg.c_str());
|
|
}
|
|
|
|
// Zone name
|
|
std::string ZoneArg;
|
|
if (GetCommandLineArg("-USS_Zone", ZoneArg))
|
|
{
|
|
Config.ZoneName = ZoneArg;
|
|
USS_LOG(" Zone: %s", ZoneArg.c_str());
|
|
}
|
|
|
|
// Difficulty level
|
|
int Difficulty = GetCommandLineArgInt("-USS_Difficulty", Config.DifficultyLevel);
|
|
if (Difficulty >= 1 && Difficulty <= 140)
|
|
{
|
|
Config.DifficultyLevel = Difficulty;
|
|
Config.DefaultDifficulty = Difficulty;
|
|
USS_LOG(" Difficulty: %d", Difficulty);
|
|
}
|
|
|
|
// Max players
|
|
int MaxPlayers = GetCommandLineArgInt("-USS_MaxPlayers", Config.MaxPlayers);
|
|
if (MaxPlayers >= 1 && MaxPlayers <= 4)
|
|
{
|
|
Config.MaxPlayers = MaxPlayers;
|
|
USS_LOG(" MaxPlayers: %d", MaxPlayers);
|
|
}
|
|
|
|
// Feature flags
|
|
if (HasCommandLineArg("-USS_NoMissions"))
|
|
{
|
|
Config.bEnableMissions = false;
|
|
USS_LOG(" Missions: DISABLED");
|
|
}
|
|
|
|
if (HasCommandLineArg("-USS_NoInventory"))
|
|
{
|
|
Config.bEnableInventory = false;
|
|
USS_LOG(" Inventory: DISABLED");
|
|
}
|
|
|
|
if (HasCommandLineArg("-USS_NoBuilding"))
|
|
{
|
|
Config.bEnableBuilding = false;
|
|
USS_LOG(" Building: DISABLED");
|
|
}
|
|
|
|
if (HasCommandLineArg("-USS_Debug"))
|
|
{
|
|
g_bDebugMode = true;
|
|
USS_LOG(" Debug Mode: ENABLED");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get a command-line argument value
|
|
* Format: -ArgName=Value or -ArgName="Value With Spaces"
|
|
*/
|
|
bool GetCommandLineArg(const char* ArgName, std::string& OutValue)
|
|
{
|
|
const char* CmdLine = GetCommandLineA();
|
|
if (!CmdLine || !ArgName)
|
|
return false;
|
|
|
|
// Find argument
|
|
const char* ArgPos = strstr(CmdLine, ArgName);
|
|
if (!ArgPos)
|
|
return false;
|
|
|
|
// Skip to value (after '=')
|
|
const char* ValueStart = ArgPos + strlen(ArgName);
|
|
if (*ValueStart != '=')
|
|
return false;
|
|
|
|
ValueStart++; // Skip '='
|
|
|
|
// Handle quoted values
|
|
if (*ValueStart == '"')
|
|
{
|
|
ValueStart++;
|
|
const char* ValueEnd = strchr(ValueStart, '"');
|
|
if (ValueEnd)
|
|
{
|
|
OutValue = std::string(ValueStart, ValueEnd - ValueStart);
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Unquoted - read until space or end
|
|
const char* ValueEnd = ValueStart;
|
|
while (*ValueEnd && *ValueEnd != ' ' && *ValueEnd != '\t')
|
|
ValueEnd++;
|
|
|
|
OutValue = std::string(ValueStart, ValueEnd - ValueStart);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Check if a command-line flag is present
|
|
*/
|
|
bool HasCommandLineArg(const char* ArgName)
|
|
{
|
|
const char* CmdLine = GetCommandLineA();
|
|
if (!CmdLine || !ArgName)
|
|
return false;
|
|
|
|
return strstr(CmdLine, ArgName) != nullptr;
|
|
}
|
|
|
|
/**
|
|
* Get an integer command-line argument
|
|
*/
|
|
int GetCommandLineArgInt(const char* ArgName, int DefaultValue)
|
|
{
|
|
std::string Value;
|
|
if (!GetCommandLineArg(ArgName, Value))
|
|
return DefaultValue;
|
|
|
|
try
|
|
{
|
|
return std::stoi(Value);
|
|
}
|
|
catch (...)
|
|
{
|
|
return DefaultValue;
|
|
}
|
|
}
|
|
|
|
DWORD WINAPI InitializationThread(LPVOID lpParam)
|
|
{
|
|
// Initialize logging first
|
|
EResult Result = Log::Initialize(true, "USS_Log.txt");
|
|
if (Result != EResult::Success)
|
|
{
|
|
MessageBoxA(nullptr, "Failed to initialize logging", "USS Error", MB_ICONERROR);
|
|
return 1;
|
|
}
|
|
|
|
/*Result = FCrashHandler::Initialize();
|
|
if (Result != EResult::Success)
|
|
{
|
|
USS_WARN("Failed to initialize crash handler - crashes may not be logged");
|
|
}*/
|
|
|
|
USS_LOG("========================================");
|
|
USS_LOG(" UniversalSlashingSimulator v0.1.0");
|
|
USS_LOG(" STW Gameserver Framework");
|
|
USS_LOG("========================================");
|
|
USS_LOG("");
|
|
|
|
// Wait for game to be ready
|
|
// TODO: find trigger in log, perhaps we need a way to trick the game into going to the STW lobby in headless?
|
|
USS_LOG("Waiting for game initialization...");
|
|
Sleep(5000); // Placeholder
|
|
|
|
USS_LOG("Initializing engine core...");
|
|
Result = GetEngineCore().Initialize();
|
|
|
|
if (Result != EResult::Success)
|
|
{
|
|
USS_FATAL("Engine core initialization failed: %s", ResultToString(Result));
|
|
MessageBoxA(nullptr, "Failed to initialize engine core", "USS Error", MB_ICONERROR);
|
|
return 1;
|
|
}
|
|
|
|
// Log version info
|
|
const auto& Version = GetEngineCore().GetVersionInfo();
|
|
USS_LOG("");
|
|
USS_LOG("=== Version Information ===");
|
|
USS_LOG("Engine: UE %s", Version.GetEngineVersionString().c_str());
|
|
USS_LOG("Fortnite: %.2f", Version.FortniteVersion);
|
|
USS_LOG("CL: %u", Version.FortniteCL);
|
|
USS_LOG("Generation: %s", Version.GetGenerationName());
|
|
USS_LOG("");
|
|
USS_LOG("=== Feature Flags ===");
|
|
USS_LOG("FNamePool: %s", Version.bUseFNamePool ? "Yes" : "No");
|
|
USS_LOG("FField: %s", Version.bUseFField ? "Yes" : "No");
|
|
USS_LOG("ChunkedObjects: %s", Version.bUseChunkedObjects ? "Yes" : "No");
|
|
USS_LOG("NewFastArray: %s", Version.bUseNewFastArraySerializer ? "Yes" : "No");
|
|
USS_LOG("TObjectPtr: %s", Version.bUseTObjectPtr ? "Yes" : "No");
|
|
USS_LOG("");
|
|
|
|
//printf("0x%llX\n", (unsigned long long)PatternScanner::Get()->FindProcessEvent());
|
|
|
|
// Initialize STW systems
|
|
USS_LOG("Initializing STW systems...");
|
|
|
|
// GameMode configuration with defaults
|
|
FSTWGameConfig GameConfig;
|
|
GameConfig.bEnableMissions = true;
|
|
GameConfig.bEnableInventory = true;
|
|
GameConfig.bEnableBuilding = true;
|
|
GameConfig.MaxPlayers = 4;
|
|
GameConfig.DefaultDifficulty = 1;
|
|
GameConfig.DifficultyLevel = 1;
|
|
GameConfig.MissionType = EMissionType::FarmsteadDefense;
|
|
GameConfig.ZoneName = "Zone_Onboarding_FarmsteadFort";
|
|
GameConfig.MissionBlueprint = "Mission_FarmsteadFort_C";
|
|
|
|
// Parse command-line arguments to override defaults
|
|
USS_LOG("");
|
|
USS_LOG("=== Command Line Configuration ===");
|
|
ParseCommandLineArguments(GameConfig);
|
|
USS_LOG("");
|
|
|
|
// Initialize GameMode (this initializes all subsystems)
|
|
Result = GetSTWGameMode().Initialize(GameConfig);
|
|
if (Result != EResult::Success)
|
|
{
|
|
USS_ERROR("STW GameMode initialization failed: %s", ResultToString(Result));
|
|
// Continue anyway - partial functionality may still work
|
|
}
|
|
else
|
|
{
|
|
USS_LOG("STW systems initialized successfully");
|
|
}
|
|
|
|
USS_LOG("");
|
|
USS_LOG("UniversalSlashingSimulator initialized successfully");
|
|
USS_LOG("========================================");
|
|
|
|
g_bInitialized = true;
|
|
return 0;
|
|
}
|
|
|
|
void Shutdown()
|
|
{
|
|
if (!g_bInitialized)
|
|
return;
|
|
|
|
USS_LOG("Shutting down UniversalSlashingSimulator...");
|
|
|
|
GetSTWGameMode().Shutdown();
|
|
|
|
GetEngineCore().Shutdown();
|
|
|
|
//FCrashHandler::Shutdown();
|
|
|
|
Log::Shutdown();
|
|
|
|
g_bInitialized = false;
|
|
}
|
|
|
|
}
|
|
|
|
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
|
|
{
|
|
switch (dwReason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
DisableThreadLibraryCalls(hModule);
|
|
USS::g_hModule = hModule;
|
|
|
|
CreateThread(nullptr, 0, USS::InitializationThread, nullptr, 0, nullptr);
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
USS::Shutdown();
|
|
break;
|
|
|
|
case DLL_THREAD_ATTACH:
|
|
case DLL_THREAD_DETACH:
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|