aboutsummaryrefslogtreecommitdiff
path: root/NorthstarDLL
diff options
context:
space:
mode:
Diffstat (limited to 'NorthstarDLL')
-rw-r--r--NorthstarDLL/core/convar/concommand.cpp2
-rw-r--r--NorthstarDLL/core/hooks.cpp39
-rw-r--r--NorthstarDLL/core/hooks.h71
-rw-r--r--NorthstarDLL/engine/host.cpp3
-rw-r--r--NorthstarDLL/engine/hoststate.cpp8
-rw-r--r--NorthstarDLL/engine/runframe.cpp2
-rw-r--r--NorthstarDLL/shared/playlist.cpp13
7 files changed, 90 insertions, 48 deletions
diff --git a/NorthstarDLL/core/convar/concommand.cpp b/NorthstarDLL/core/convar/concommand.cpp
index 094fa813..71e2129f 100644
--- a/NorthstarDLL/core/convar/concommand.cpp
+++ b/NorthstarDLL/core/convar/concommand.cpp
@@ -5,8 +5,6 @@
#include <iostream>
-bool (*CCommand__Tokenize)(CCommand& self, const char* pCommandString, R2::cmd_source_t commandSource);
-
//-----------------------------------------------------------------------------
// Purpose: Returns true if this is a command
// Output : bool
diff --git a/NorthstarDLL/core/hooks.cpp b/NorthstarDLL/core/hooks.cpp
index 79bcbb92..91cb9a90 100644
--- a/NorthstarDLL/core/hooks.cpp
+++ b/NorthstarDLL/core/hooks.cpp
@@ -66,6 +66,9 @@ __dllLoadCallback::__dllLoadCallback(
void __fileAutohook::Dispatch()
{
+ for (__autovar* var : vars)
+ var->Dispatch();
+
for (__autohook* hook : hooks)
hook->Dispatch();
}
@@ -115,6 +118,42 @@ bool ManualHook::Dispatch(LPVOID addr, LPVOID* orig)
return false;
}
+uintptr_t ParseDLLOffsetString(const char* pAddrString)
+{
+ // in the format server.dll + 0xDEADBEEF
+ int iDllNameEnd = 0;
+ for (; !isspace(pAddrString[iDllNameEnd]) && pAddrString[iDllNameEnd] != '+'; iDllNameEnd++)
+ ;
+
+ char* pModuleName = new char[iDllNameEnd + 1];
+ memcpy(pModuleName, pAddrString, iDllNameEnd);
+ pModuleName[iDllNameEnd] = '\0';
+
+ // get the module address
+ const HMODULE pModuleAddr = GetModuleHandleA(pModuleName);
+
+ if (!pModuleAddr)
+ return 0;
+
+ // get the offset string
+ uintptr_t iOffset = 0;
+
+ int iOffsetBegin = iDllNameEnd;
+ int iOffsetEnd = strlen(pAddrString);
+
+ // seek until we hit the start of the number offset
+ for (; !(pAddrString[iOffsetBegin] >= '0' && pAddrString[iOffsetBegin] <= '9') && pAddrString[iOffsetBegin]; iOffsetBegin++)
+ ;
+
+ bool bIsHex = pAddrString[iOffsetBegin] == '0' && (pAddrString[iOffsetBegin + 1] == 'X' || pAddrString[iOffsetBegin + 1] == 'x');
+ if (bIsHex)
+ iOffset = std::stoi(pAddrString + iOffsetBegin + 2, 0, 16);
+ else
+ iOffset = std::stoi(pAddrString + iOffsetBegin);
+
+ return ((uintptr_t)pModuleAddr + iOffset);
+}
+
// dll load callback stuff
// this allows for code to register callbacks to be run as soon as a dll is loaded, mainly to allow for patches to be made on dll load
struct DllLoadCallback
diff --git a/NorthstarDLL/core/hooks.h b/NorthstarDLL/core/hooks.h
index f47791fb..2f7e21b4 100644
--- a/NorthstarDLL/core/hooks.h
+++ b/NorthstarDLL/core/hooks.h
@@ -63,16 +63,20 @@ class __dllLoadCallback
// new macro hook stuff
class __autohook;
+class __autovar;
class __fileAutohook
{
public:
std::vector<__autohook*> hooks;
+ std::vector<__autovar*> vars;
void Dispatch();
void DispatchForModule(const char* pModuleName);
};
+uintptr_t ParseDLLOffsetString(const char* pAddrString);
+
// initialise autohooks for this file
#define AUTOHOOK_INIT() \
namespace \
@@ -187,39 +191,7 @@ class __autohook
case OFFSET_STRING:
{
- // in the format server.dll + 0xDEADBEEF
- int iDllNameEnd = 0;
- for (; !isspace(pAddrString[iDllNameEnd]) && pAddrString[iDllNameEnd] != '+'; iDllNameEnd++)
- ;
-
- char* pModuleName = new char[iDllNameEnd + 1];
- memcpy(pModuleName, pAddrString, iDllNameEnd);
- pModuleName[iDllNameEnd] = '\0';
-
- // get the module address
- const HMODULE pModuleAddr = GetModuleHandleA(pModuleName);
-
- if (!pModuleAddr)
- break;
-
- // get the offset string
- uintptr_t iOffset = 0;
-
- int iOffsetBegin = iDllNameEnd;
- int iOffsetEnd = strlen(pAddrString);
-
- // seek until we hit the start of the number offset
- for (; !(pAddrString[iOffsetBegin] >= '0' && pAddrString[iOffsetBegin] <= '9') && pAddrString[iOffsetBegin]; iOffsetBegin++)
- ;
-
- bool bIsHex =
- pAddrString[iOffsetBegin] == '0' && (pAddrString[iOffsetBegin + 1] == 'X' || pAddrString[iOffsetBegin + 1] == 'x');
- if (bIsHex)
- iOffset = std::stoi(pAddrString + iOffsetBegin + 2, 0, 16);
- else
- iOffset = std::stoi(pAddrString + iOffsetBegin);
-
- targetAddr = (LPVOID)((uintptr_t)pModuleAddr + iOffset);
+ targetAddr = (LPVOID)ParseDLLOffsetString(pAddrString);
break;
}
@@ -309,3 +281,36 @@ class ManualHook
void MakeHook(LPVOID pTarget, LPVOID pDetour, void* ppOriginal, const char* pFuncName = "");
#define MAKEHOOK(pTarget, pDetour, ppOriginal) MakeHook(pTarget, pDetour, ppOriginal, __STR(pDetour))
+
+class __autovar
+{
+ public:
+ char* m_pAddrString;
+ void** m_pTarget;
+
+ public:
+ __autovar(__fileAutohook* pAutohook, const char* pAddrString, void** pTarget)
+ {
+ m_pTarget = pTarget;
+
+ const int iAddrStrlen = strlen(pAddrString) + 1;
+ m_pAddrString = new char[iAddrStrlen];
+ memcpy(m_pAddrString, pAddrString, iAddrStrlen);
+
+ pAutohook->vars.push_back(this);
+ }
+
+ void Dispatch()
+ {
+ *m_pTarget = (void*)ParseDLLOffsetString(m_pAddrString);
+ }
+};
+
+// VAR_AT(engine.dll+0x404, ConVar*, Cvar_host_timescale)
+#define VAR_AT(addrString, type, name) \
+type name; namespace { __autovar CONCAT2(__autovar, __LINE__)(&__FILEAUTOHOOK, __STR(addrString), (void**)&name); }
+
+// FUNCTION_AT(engine.dll + 0xDEADBEEF, void, __fastcall, SomeFunc, (void* a1))
+#define FUNCTION_AT(addrString, type, callingConvention, name, args) \
+type(*callingConvention name) args; namespace { __autovar CONCAT2(__autovar, __LINE__)(&__FILEAUTOHOOK, __STR(addrString), (void**)&name); }
+
diff --git a/NorthstarDLL/engine/host.cpp b/NorthstarDLL/engine/host.cpp
index a55c8dfd..e61e8cf6 100644
--- a/NorthstarDLL/engine/host.cpp
+++ b/NorthstarDLL/engine/host.cpp
@@ -6,7 +6,9 @@
#include "shared/misccommands.h"
#include "r2engine.h"
#include "core/tier0.h"
+
AUTOHOOK_INIT()
+
// clang-format off
AUTOHOOK(Host_Init, engine.dll + 0x155EA0,
void, __fastcall, (bool bDedicated))
@@ -25,6 +27,7 @@ void, __fastcall, (bool bDedicated))
else
R2::Cbuf_AddText(R2::Cbuf_GetCurrentPlayer(), "exec autoexec_ns_client", R2::cmd_source_t::kCommandSrcCode);
}
+
ON_DLL_LOAD("engine.dll", Host_Init, (CModule module))
{
AUTOHOOK_DISPATCH()
diff --git a/NorthstarDLL/engine/hoststate.cpp b/NorthstarDLL/engine/hoststate.cpp
index 4900539b..c7775ac0 100644
--- a/NorthstarDLL/engine/hoststate.cpp
+++ b/NorthstarDLL/engine/hoststate.cpp
@@ -19,10 +19,10 @@ namespace R2
CHostState* g_pHostState;
} // namespace R2
-ConVar* Cvar_hostport;
std::string sLastMode;
-void (*_fastcall _Cmd_Exec_f)(const CCommand& arg, bool bOnlyIfExists, bool bUseWhitelists);
+VAR_AT(engine.dll + 0x13FA6070, ConVar*, Cvar_hostport);
+FUNCTION_AT(engine.dll + 0x1232C0, void, __fastcall, _Cmd_Exec_f, (const CCommand& arg, bool bOnlyIfExists, bool bUseWhitelists));
void ServerStartingOrChangingMap()
{
@@ -195,7 +195,7 @@ ON_DLL_LOAD_RELIESON("engine.dll", HostState, ConVar, (CModule module))
AUTOHOOK_DISPATCH()
g_pHostState = module.Offset(0x7CF180).As<CHostState*>();
- Cvar_hostport = module.Offset(0x13FA6070).As<ConVar*>();
+ Cvar_hostport = module.Offset().As<ConVar*>();
- _Cmd_Exec_f = module.Offset(0x1232C0).As<void (*__fastcall)(const CCommand&, bool, bool)>();
+ _Cmd_Exec_f = module.Offset().As<void (*__fastcall)(const CCommand&, bool, bool)>();
}
diff --git a/NorthstarDLL/engine/runframe.cpp b/NorthstarDLL/engine/runframe.cpp
index d81356f2..3df93f54 100644
--- a/NorthstarDLL/engine/runframe.cpp
+++ b/NorthstarDLL/engine/runframe.cpp
@@ -5,6 +5,7 @@
#include "server/serverpresence.h"
AUTOHOOK_INIT()
+
// clang-format off
AUTOHOOK(CEngine__Frame, engine.dll + 0x1C8650,
void, __fastcall, (R2::CEngine* self))
@@ -12,6 +13,7 @@ void, __fastcall, (R2::CEngine* self))
{
CEngine__Frame(self);
}
+
ON_DLL_LOAD("engine.dll", RunFrame, (CModule module))
{
AUTOHOOK_DISPATCH()
diff --git a/NorthstarDLL/shared/playlist.cpp b/NorthstarDLL/shared/playlist.cpp
index 2fb856b3..4d4c8906 100644
--- a/NorthstarDLL/shared/playlist.cpp
+++ b/NorthstarDLL/shared/playlist.cpp
@@ -11,10 +11,10 @@ AUTOHOOK_INIT()
// use the R2 namespace for game funcs
namespace R2
{
- const char* (*GetCurrentPlaylistName)();
- void (*SetCurrentPlaylist)(const char* pPlaylistName);
- void (*SetPlaylistVarOverride)(const char* pVarName, const char* pValue);
- const char* (*GetCurrentPlaylistVar)(const char* pVarName, bool bUseOverrides);
+ FUNCTION_AT(engine.dll + 0x18C640, const char*,, GetCurrentPlaylistName, ());
+ FUNCTION_AT(engine.dll + 0x18EB20, void,, SetCurrentPlaylist, (const char* pPlaylistName));
+ FUNCTION_AT(engine.dll + 0x18ED00, void,, SetPlaylistVarOverride, (const char* pVarName, const char* pValue));
+ FUNCTION_AT(engine.dll + 0x18C680, const char*,, GetCurrentPlaylistVar, (const char* pVarName, bool bUseOverrides));
} // namespace R2
ConVar* Cvar_ns_use_clc_SetPlaylistVarOverride;
@@ -104,11 +104,6 @@ ON_DLL_LOAD_RELIESON("engine.dll", PlaylistHooks, (ConCommand, ConVar), (CModule
{
AUTOHOOK_DISPATCH()
- R2::GetCurrentPlaylistName = module.Offset(0x18C640).As<const char* (*)()>();
- R2::SetCurrentPlaylist = module.Offset(0x18EB20).As<void (*)(const char*)>();
- R2::SetPlaylistVarOverride = module.Offset(0x18ED00).As<void (*)(const char*, const char*)>();
- R2::GetCurrentPlaylistVar = module.Offset(0x18C680).As<const char* (*)(const char*, bool)>();
-
// playlist is the name of the command on respawn servers, but we already use setplaylist so can't get rid of it
RegisterConCommand("playlist", ConCommand_playlist, "Sets the current playlist", FCVAR_NONE);
RegisterConCommand("setplaylist", ConCommand_playlist, "Sets the current playlist", FCVAR_NONE);