aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobTheBob <32057864+BobTheBob9@users.noreply.github.com>2023-02-23 00:19:48 +0000
committerGitHub <noreply@github.com>2023-02-23 00:19:48 +0000
commit32165afe41c4cf4d3b261ee7a9c69c369253cc13 (patch)
tree156844485e0e463410d76cbb4c4c7a6cd0042786
parent6aaac4cd452878acc59d9748bcd2d0e072d2a432 (diff)
downloadNorthstarLauncher-32165afe41c4cf4d3b261ee7a9c69c369253cc13.tar.gz
NorthstarLauncher-32165afe41c4cf4d3b261ee7a9c69c369253cc13.zip
Add `FUNCTION_AT` and `VAR_AT` macros (#416)
* add FUNCTION_AT and VAR_AT macros * fix build issues oops * fix formatting * add PREDEFINED_VAR_AT * change func name * fixup formatting * update to use DEFINED_VAR_AT
-rw-r--r--NorthstarDLL/core/convar/concommand.cpp2
-rw-r--r--NorthstarDLL/core/hooks.cpp39
-rw-r--r--NorthstarDLL/core/hooks.h86
-rw-r--r--NorthstarDLL/engine/host.cpp3
-rw-r--r--NorthstarDLL/engine/hoststate.cpp7
-rw-r--r--NorthstarDLL/shared/playlist.cpp13
-rw-r--r--NorthstarDLL/shared/playlist.h8
7 files changed, 105 insertions, 53 deletions
diff --git a/NorthstarDLL/core/convar/concommand.cpp b/NorthstarDLL/core/convar/concommand.cpp
index 88bd8825..67c867f8 100644
--- a/NorthstarDLL/core/convar/concommand.cpp
+++ b/NorthstarDLL/core/convar/concommand.cpp
@@ -4,8 +4,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 34b48d1d..7c70b0a5 100644
--- a/NorthstarDLL/core/hooks.cpp
+++ b/NorthstarDLL/core/hooks.cpp
@@ -65,6 +65,9 @@ __dllLoadCallback::__dllLoadCallback(
void __fileAutohook::Dispatch()
{
+ for (__autovar* var : vars)
+ var->Dispatch();
+
for (__autohook* hook : hooks)
hook->Dispatch();
}
@@ -114,6 +117,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..0144712f 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,51 @@ 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); \
+ }
+
+// int* g_pSomeInt;
+// DEFINED_VAR_AT(engine.dll + 0x5005, g_pSomeInt)
+#define DEFINED_VAR_AT(addrString, name) \
+ namespace \
+ { \
+ __autovar CONCAT2(__autovar, __LINE__)(&__FILEAUTOHOOK, __STR(addrString), (void**)&name); \
+ }
diff --git a/NorthstarDLL/engine/host.cpp b/NorthstarDLL/engine/host.cpp
index 436a169d..49cc3663 100644
--- a/NorthstarDLL/engine/host.cpp
+++ b/NorthstarDLL/engine/host.cpp
@@ -5,7 +5,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))
@@ -24,6 +26,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 5a295425..44a66113 100644
--- a/NorthstarDLL/engine/hoststate.cpp
+++ b/NorthstarDLL/engine/hoststate.cpp
@@ -18,10 +18,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()
{
@@ -194,7 +194,4 @@ 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*>();
-
- _Cmd_Exec_f = module.Offset(0x1232C0).As<void (*__fastcall)(const CCommand&, bool, bool)>();
}
diff --git a/NorthstarDLL/shared/playlist.cpp b/NorthstarDLL/shared/playlist.cpp
index 018b2a9b..ab7aab22 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);
+ DEFINED_VAR_AT(engine.dll + 0x18C640, GetCurrentPlaylistName);
+ DEFINED_VAR_AT(engine.dll + 0x18EB20, SetCurrentPlaylist);
+ DEFINED_VAR_AT(engine.dll + 0x18ED00, SetPlaylistVarOverride);
+ DEFINED_VAR_AT(engine.dll + 0x18C680, GetCurrentPlaylistVar);
} // 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);
diff --git a/NorthstarDLL/shared/playlist.h b/NorthstarDLL/shared/playlist.h
index c77b37d9..e56fdf96 100644
--- a/NorthstarDLL/shared/playlist.h
+++ b/NorthstarDLL/shared/playlist.h
@@ -3,8 +3,8 @@
// use the R2 namespace for game funcs
namespace R2
{
- extern const char* (*GetCurrentPlaylistName)();
- extern void (*SetCurrentPlaylist)(const char* pPlaylistName);
- extern void (*SetPlaylistVarOverride)(const char* pVarName, const char* pValue);
- extern const char* (*GetCurrentPlaylistVar)(const char* pVarName, bool bUseOverrides);
+ inline const char* (*GetCurrentPlaylistName)();
+ inline void (*SetCurrentPlaylist)(const char* pPlaylistName);
+ inline void (*SetPlaylistVarOverride)(const char* pVarName, const char* pValue);
+ inline const char* (*GetCurrentPlaylistVar)(const char* pVarName, bool bUseOverrides);
} // namespace R2