aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NorthstarDedicatedTest/dedicated.cpp186
-rw-r--r--NorthstarDedicatedTest/dedicated.h26
-rw-r--r--NorthstarDedicatedTest/dedicatedmaterialsystem.cpp24
-rw-r--r--NorthstarDedicatedTest/dllmain.cpp11
-rw-r--r--NorthstarDedicatedTest/gameutils.cpp8
-rw-r--r--NorthstarDedicatedTest/gameutils.h63
-rw-r--r--NorthstarDedicatedTest/securitypatches.cpp5
7 files changed, 178 insertions, 145 deletions
diff --git a/NorthstarDedicatedTest/dedicated.cpp b/NorthstarDedicatedTest/dedicated.cpp
index 01917f50..3dca5032 100644
--- a/NorthstarDedicatedTest/dedicated.cpp
+++ b/NorthstarDedicatedTest/dedicated.cpp
@@ -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);
+}
+
+typedef bool (*CEngine__FrameType)(void* engineSelf);
+typedef void(*CHostState__InitType)(CHostState* self);
-enum HostState_t
+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
@@ -183,6 +183,33 @@ void InitialiseDedicated(HMODULE engineAddress)
}
{
+ // 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;
TempReadWrite rw(ptr);
@@ -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");
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/dedicated.h b/NorthstarDedicatedTest/dedicated.h
index ed2ae09e..96bb96c4 100644
--- a/NorthstarDedicatedTest/dedicated.h
+++ b/NorthstarDedicatedTest/dedicated.h
@@ -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); \ No newline at end of file
diff --git a/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp b/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp
index 48ade24d..e334e8fe 100644
--- a/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp
+++ b/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp
@@ -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
diff --git a/NorthstarDedicatedTest/dllmain.cpp b/NorthstarDedicatedTest/dllmain.cpp
index 3efe38c0..b801b281 100644
--- a/NorthstarDedicatedTest/dllmain.cpp
+++ b/NorthstarDedicatedTest/dllmain.cpp
@@ -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
diff --git a/NorthstarDedicatedTest/gameutils.cpp b/NorthstarDedicatedTest/gameutils.cpp
index bf9ae3e5..1f7870b0 100644
--- a/NorthstarDedicatedTest/gameutils.cpp
+++ b/NorthstarDedicatedTest/gameutils.cpp
@@ -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);
diff --git a/NorthstarDedicatedTest/gameutils.h b/NorthstarDedicatedTest/gameutils.h
index 8db63fd7..cdf9ec3b 100644
--- a/NorthstarDedicatedTest/gameutils.h
+++ b/NorthstarDedicatedTest/gameutils.h
@@ -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_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 CHostState* g_GameCHostStateSingleton;
+extern CEngine* g_pEngine;
// network stuff
diff --git a/NorthstarDedicatedTest/securitypatches.cpp b/NorthstarDedicatedTest/securitypatches.cpp
index f13d778e..cbb5a292 100644
--- a/NorthstarDedicatedTest/securitypatches.cpp
+++ b/NorthstarDedicatedTest/securitypatches.cpp
@@ -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)