commandline struct change, dedicated refactor

This commit is contained in:
BobTheBob 2021-09-26 15:13:45 +01:00
parent e98fc31a93
commit a4434a4db1
7 changed files with 178 additions and 145 deletions

View File

@ -4,48 +4,63 @@
#include "tier0.h"
#include "gameutils.h"
#include <iostream>
bool IsDedicated()
{
return CommandLine()->HasParm("-dedicated");
return CommandLine()->CheckParm("-dedicated");
}
enum EngineState_t
// CDedidcatedExports defs
struct CDedicatedExports; // forward declare
typedef void (*DedicatedSys_PrintfType)(CDedicatedExports* dedicated, char* msg);
typedef void (*DedicatedRunServerType)(CDedicatedExports* dedicated);
struct CDedicatedExports
{
DLL_INACTIVE = 0, // no dll
DLL_ACTIVE, // engine is focused
DLL_CLOSE, // closing down dll
DLL_RESTART, // engine is shutting down but will restart right away
DLL_PAUSED, // engine is paused, can become active from this state
void* vtable; // because it's easier, we just set this to &this, since CDedicatedExports has no props we care about other than funcs
char unused[56];
DedicatedSys_PrintfType Sys_Printf;
DedicatedRunServerType RunServer;
};
struct CEngine
void Sys_Printf(CDedicatedExports* dedicated, char* msg)
{
public:
void* vtable;
int m_nQuitting;
EngineState_t m_nDllState;
EngineState_t m_nNextDllState;
double m_flCurrentTime;
float m_flFrameTime;
double m_flPreviousTime;
float m_flFilteredTime;
float m_flMinFrameTime; // Expected duration of a frame, or zero if it is unlimited.
};
spdlog::info("[DEDICATED PRINT] {}", msg);
}
enum HostState_t
typedef bool (*CEngine__FrameType)(void* engineSelf);
typedef void(*CHostState__InitType)(CHostState* self);
void RunServer(CDedicatedExports* dedicated)
{
HS_NEW_GAME = 0,
HS_LOAD_GAME,
HS_CHANGE_LEVEL_SP,
HS_CHANGE_LEVEL_MP,
HS_RUN,
HS_GAME_SHUTDOWN,
HS_SHUTDOWN,
HS_RESTART,
};
Sys_Printf(dedicated, (char*)"CDedicatedExports::RunServer(): starting");
HMODULE engine = GetModuleHandleA("engine.dll");
CEngine__FrameType CEngine__Frame = (CEngine__FrameType)((char*)engine + 0x1C8650);
CHostState__InitType CHostState__Init = (CHostState__InitType)((char*)engine + 0x16E110);
// call once to init
CEngine__Frame(g_pEngine);
// init hoststate, if we don't do this, we get a crash later on
CHostState__Init(g_pHostState);
// set up engine and host states to allow us to enter CHostState::FrameUpdate, with the state HS_NEW_GAME
g_pEngine->m_nNextDllState = EngineState_t::DLL_ACTIVE;
g_pHostState->m_iNextState = HostState_t::HS_NEW_GAME;
strncpy(g_pHostState->m_levelName, CommandLine()->ParmValue("+map", "mp_lobby"), sizeof(g_pHostState->m_levelName)); // set map to load into
while (true)
{
CEngine__Frame(g_pEngine);
//engineApiStartSimulation(nullptr, true);
Sys_Printf(dedicated, (char*)"engine->Frame()");
Sleep(50);
}
}
void InitialiseDedicated(HMODULE engineAddress)
{
@ -54,21 +69,6 @@ void InitialiseDedicated(HMODULE engineAddress)
spdlog::info("InitialiseDedicated");
//while (!IsDebuggerPresent())
// Sleep(100);
// create binary patches
//{
// // CEngineAPI::SetStartupInfo
// // prevents englishclient_frontend from loading
//
// char* ptr = (char*)engineAddress + 0x1C7CBE;
// TempReadWrite rw(ptr);
//
// // je => jmp
// *ptr = (char)0xEB;
//}
{
// Host_Init
// prevent a particle init that relies on client dll
@ -182,6 +182,33 @@ void InitialiseDedicated(HMODULE engineAddress)
*(ptr + 8) = (char)0x90;
}
{
// CEngineAPI::Connect
char* ptr = (char*)engineAddress + 0x1C4D7D;
TempReadWrite rw(ptr);
// remove call to Shader_Connect
*ptr = 0x90;
*(ptr + 1) = (char)0x90;
*(ptr + 2) = (char)0x90;
*(ptr + 3) = (char)0x90;
*(ptr + 4) = (char)0x90;
}
// not currently using this because it's for nopping renderthread/gamewindow stuff i.e. very hard
//{
// // CEngineAPI::Init
// char* ptr = (char*)engineAddress + 0x1C60CE;
// TempReadWrite rw(ptr);
//
// // remove call to something or other that reads video settings
// *ptr = 0x90;
// *(ptr + 1) = (char)0x90;
// *(ptr + 2) = (char)0x90;
// *(ptr + 3) = (char)0x90;
// *(ptr + 4) = (char)0x90;
//}
{
// some inputsystem bullshit
char* ptr = (char*)engineAddress + 0x1CEE28;
@ -193,24 +220,14 @@ void InitialiseDedicated(HMODULE engineAddress)
*(ptr + 2) = (char)0x90;
}
CDedicatedExports* dedicatedExports = new CDedicatedExports;
dedicatedExports->vtable = dedicatedExports;
dedicatedExports->Sys_Printf = Sys_Printf;
dedicatedExports->RunServer = RunServer;
// materialsystem later:
// do materialsystem + 5f0f1 je => jmp to make material loading not die
CDedicatedExports* dedicatedApi = new CDedicatedExports;
dedicatedApi->Sys_Printf = Sys_Printf;
dedicatedApi->RunServer = RunServer;
// double ptr to dedicatedApi
intptr_t* ptr = (intptr_t*)((char*)engineAddress + 0x13F0B668);
CDedicatedExports** exports = (CDedicatedExports**)((char*)engineAddress + 0x13F0B668);
*exports = dedicatedExports;
// ptr to dedicatedApi
intptr_t* doublePtr = new intptr_t;
*doublePtr = (intptr_t)dedicatedApi;
// ptr to ptr
*ptr = (intptr_t)doublePtr;
// extra potential patches:
// nop engine.dll+1c67d1 and +1c67d8 to skip videomode creategamewindow
// also look into launcher.dll+d381, seems to cause renderthread to get made
@ -219,47 +236,6 @@ void InitialiseDedicated(HMODULE engineAddress)
// add cmdline args that are good for dedi
CommandLine()->AppendParm("-nomenuvid", 0);
CommandLine()->AppendParm("+host_preload_shaders", 0);
CommandLine()->AppendParm("-nosound", 0);
}
void Sys_Printf(CDedicatedExports* dedicated, char* msg)
{
spdlog::info("[DEDICATED PRINT] {}", msg);
}
typedef void(*CHostState__InitType)(CHostState* self);
void RunServer(CDedicatedExports* dedicated)
{
while (!IsDebuggerPresent())Sleep(100);
Sys_Printf(dedicated, (char*)"CDedicatedServerAPI::RunServer(): starting");
HMODULE engine = GetModuleHandleA("engine.dll");
CEngine__Frame engineFrame = (CEngine__Frame)((char*)engine + 0x1C8650);
CEngine* cEnginePtr = (CEngine*)((char*)engine + 0x7D70C8);
CHostState* cHostStatePtr = (CHostState*)((char*)engine + 0x7CF180);
CHostState__InitType CHostState__Init = (CHostState__InitType)((char*)engine + 0x16E110);
// call once to init
engineFrame(cEnginePtr);
// init hoststate, if we don't do this, we get a crash later on
CHostState__Init(cHostStatePtr);
// set up engine and host states to allow us to enter CHostState::FrameUpdate, with the state HS_NEW_GAME
cEnginePtr->m_nNextDllState = EngineState_t::DLL_ACTIVE;
cHostStatePtr->m_iNextState = HostState_t::HS_NEW_GAME;
strcpy(cHostStatePtr->m_levelName, "mp_lobby"); // set map to load into
while (true)
{
engineFrame(cEnginePtr);
//engineApiStartSimulation(nullptr, true);
Sys_Printf(dedicated, (char*)"engine->Frame()");
Sleep(50);
}
CommandLine()->AppendParm("+host_preload_shaders", "0");
}

View File

@ -2,28 +2,4 @@
bool IsDedicated();
struct CDedicatedExports; // forward declare
// functions for CDedicatedServerAPI
typedef void (*DedicatedSys_Printf)(CDedicatedExports* dedicated, char* msg);
typedef void (*DedicatedRunServer)(CDedicatedExports* dedicated);
void Sys_Printf(CDedicatedExports* dedicated, char* msg);
void RunServer(CDedicatedExports* dedicated);
// functions for running dedicated server
typedef bool (*CEngine__Frame)(void* engineSelf);
typedef void (*CEngineAPI__SetMap)(void* engineApiSelf, const char* pMapName);
typedef void (*CEngineAPI__ActivateSimulation)(void* engineApiSelf, bool bActive);
// struct used internally
struct CDedicatedExports
{
char unused[64];
DedicatedSys_Printf Sys_Printf; // base + 64
DedicatedRunServer RunServer; // base + 72
};
// hooking stuff
extern bool bDedicatedHooksInitialised;
void InitialiseDedicated(HMODULE moduleAddress);
void InitialiseDedicated(HMODULE moduleAddress);

View File

@ -8,6 +8,30 @@ void InitialiseDedicatedMaterialSystem(HMODULE baseAddress)
{
if (!IsDedicated())
return;
// not using these for now since they're related to nopping renderthread/gamewindow i.e. very hard
//{
// // function that launches renderthread
// char* ptr = (char*)baseAddress + 0x87047;
// TempReadWrite rw(ptr);
//
// // make it not launch renderthread
// *ptr = (char)0x90;
// *(ptr + 1) = (char)0x90;
// *(ptr + 2) = (char)0x90;
// *(ptr + 3) = (char)0x90;
// *(ptr + 4) = (char)0x90;
// *(ptr + 5) = (char)0x90;
//}
//
//{
// // some function that waits on renderthread job
// char* ptr = (char*)baseAddress + 0x87d00;
// TempReadWrite rw(ptr);
//
// // return immediately
// *ptr = (char)0xC3;
//}
{
// CMaterialSystem::FindMaterial

View File

@ -43,6 +43,16 @@ BOOL APIENTRY DllMain( HMODULE hModule,
return TRUE;
}
void WaitForDebugger(HMODULE baseAddress)
{
// earlier waitfordebugger call than is in vanilla, just so we can debug stuff a little easier
if (CommandLine()->CheckParm("-waitfordebugger"))
{
while (!IsDebuggerPresent())
Sleep(100);
}
}
// in the future this will be called from launcher instead of dllmain
void InitialiseNorthstar()
{
@ -52,6 +62,7 @@ void InitialiseNorthstar()
InstallInitialHooks();
InitialiseInterfaceCreationHooks();
AddDllLoadCallback("engine.dll", WaitForDebugger);
AddDllLoadCallback("engine.dll", InitialiseEngineGameUtilFunctions);
// dedi patches

View File

@ -9,7 +9,10 @@ Cbuf_AddTextType Cbuf_AddText;
Cbuf_ExecuteType Cbuf_Execute;
// hoststate stuff
CHostState* g_GameCHostStateSingleton;
CHostState* g_pHostState;
// cengine stuff
CEngine* g_pEngine;
// network stuff
ConVar* Cvar_hostport;
@ -27,7 +30,8 @@ void InitialiseEngineGameUtilFunctions(HMODULE baseAddress)
Cbuf_AddText = (Cbuf_AddTextType)((char*)baseAddress + 0x1203B0);
Cbuf_Execute = (Cbuf_ExecuteType)((char*)baseAddress + 0x1204B0);
g_GameCHostStateSingleton = (CHostState*)((char*)baseAddress + 0x7CF180);
g_pHostState = (CHostState*)((char*)baseAddress + 0x7CF180);
g_pEngine = (CEngine*)((char*)baseAddress + 0x7D70C8);
Cvar_hostport = (ConVar*)((char*)baseAddress + 0x13FA6070);

View File

@ -62,34 +62,48 @@ extern Cbuf_ExecuteType Cbuf_Execute;
class CCommandLine
{
public:
// based on the defs in the 2013 source sdk, but for some reason has an extra function (may be another CreateCmdLine overload?)
// these seem to line up with what they should be though
virtual void CreateCmdLine(const char* commandline) {}
virtual void CreateCmdLine(int argc, char** argv) {}
virtual void unknown() {}
virtual const char* GetCmdLine(void) const {}
virtual const char* CheckParm(const char* psz, const char** ppszValue = 0) const {}
virtual bool HasParm(const char* psz) const {}
virtual const char* CheckParm(const char* psz, const char** ppszValue = 0) const {}
virtual void RemoveParm() const {}
virtual void AppendParm(const char* pszParm, const char* pszValues) {}
virtual int ParmCount() const {}
virtual int FindParm(const char* psz) const {}
virtual const char* GetParm(int nIndex) const {}
virtual const char* ParmValue(const char* psz, const char* pDefaultVal = 0) const {}
virtual int ParmValue(const char* psz, int nDefaultVal) const {}
virtual float ParmValue(const char* psz, float flDefaultVal) const {}
virtual int ParmCount() const {}
virtual int FindParm(const char* psz) const {}
virtual const char* GetParm(int nIndex) const {}
virtual void SetParm(int nIndex, char const* pParm) {}
virtual const char** GetParms() const {}
//virtual const char** GetParms() const {}
};
// hoststate stuff
enum HostState_t
{
HS_NEW_GAME = 0,
HS_LOAD_GAME,
HS_CHANGE_LEVEL_SP,
HS_CHANGE_LEVEL_MP,
HS_RUN,
HS_GAME_SHUTDOWN,
HS_SHUTDOWN,
HS_RESTART,
};
struct CHostState
{
public:
int32_t m_iCurrentState;
int32_t m_iNextState;
HostState_t m_iCurrentState;
HostState_t m_iNextState;
float m_vecLocation[3];
float m_angLocation[3];
@ -97,9 +111,38 @@ public:
char m_levelName[32];
// not reversed past this point, struct seems weird
// pretty decent chance m_levelname is bigger, given it was 256 long in normal source
};
extern CHostState* g_GameCHostStateSingleton;
extern CHostState* g_pHostState;
// cengine stuff
enum EngineState_t
{
DLL_INACTIVE = 0, // no dll
DLL_ACTIVE, // engine is focused
DLL_CLOSE, // closing down dll
DLL_RESTART, // engine is shutting down but will restart right away
DLL_PAUSED, // engine is paused, can become active from this state
};
struct CEngine
{
public:
void* vtable;
int m_nQuitting;
EngineState_t m_nDllState;
EngineState_t m_nNextDllState;
double m_flCurrentTime;
float m_flFrameTime;
double m_flPreviousTime;
float m_flFilteredTime;
float m_flMinFrameTime; // Expected duration of a frame, or zero if it is unlimited.
};
extern CEngine* g_pEngine;
// network stuff

View File

@ -3,6 +3,7 @@
#include "hookutils.h"
#include "concommand.h"
#include "dedicated.h"
#include "tier0.h"
typedef bool(*IsValveModType)();
IsValveModType IsValveMod;
@ -12,9 +13,7 @@ bool IsValveModHook()
// basically: by default r2 isn't set as a valve mod, meaning that m_bRestrictServerCommands is false
// this is HORRIBLE for security, because it means servers can run arbitrary concommands on clients
// especially since we have script commands this could theoretically be awful
// todo: possibly have a commandline arg to disable this
return true;
return !CommandLine()->CheckParm("-norestrictservercommands");
}
void InitialiseClientEngineSecurityPatches(HMODULE baseAddress)