aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobTheBob <32057864+BobTheBob9@users.noreply.github.com>2022-05-26 03:16:46 +0100
committerBobTheBob <32057864+BobTheBob9@users.noreply.github.com>2022-05-26 03:16:46 +0100
commitcc7b0ded08e3dc26fc970169a79c74c54e4f923b (patch)
tree6de8896695ab89534adaa912b9fdfac9d6bf396c
parent93d540dd37298b9e9a6c1f07b5c4a8dc46a2787d (diff)
downloadNorthstarLauncher-cc7b0ded08e3dc26fc970169a79c74c54e4f923b.tar.gz
NorthstarLauncher-cc7b0ded08e3dc26fc970169a79c74c54e4f923b.zip
lots of cleanup and starting moving to new hooking macros
-rw-r--r--LauncherInjector/LauncherInjector.vcxproj6
-rw-r--r--LauncherInjector/main.cpp17
-rw-r--r--NorthstarDedicatedTest/ExploitFixes.cpp3
-rw-r--r--NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj8
-rw-r--r--NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters8
-rw-r--r--NorthstarDedicatedTest/audio.cpp74
-rw-r--r--NorthstarDedicatedTest/bansystem.cpp4
-rw-r--r--NorthstarDedicatedTest/buildainfile.cpp31
-rw-r--r--NorthstarDedicatedTest/chatcommand.cpp1
-rw-r--r--NorthstarDedicatedTest/clientauthhooks.cpp20
-rw-r--r--NorthstarDedicatedTest/clientchathooks.cpp21
-rw-r--r--NorthstarDedicatedTest/clientruihooks.cpp1
-rw-r--r--NorthstarDedicatedTest/clientvideooverrides.cpp1
-rw-r--r--NorthstarDedicatedTest/concommand.cpp4
-rw-r--r--NorthstarDedicatedTest/concommand.h2
-rw-r--r--NorthstarDedicatedTest/convar.cpp6
-rw-r--r--NorthstarDedicatedTest/cvar.cpp8
-rw-r--r--NorthstarDedicatedTest/cvar.h8
-rw-r--r--NorthstarDedicatedTest/debugoverlay.cpp1
-rw-r--r--NorthstarDedicatedTest/dedicated.cpp49
-rw-r--r--NorthstarDedicatedTest/dedicatedmaterialsystem.cpp2
-rw-r--r--NorthstarDedicatedTest/demofixes.cpp6
-rw-r--r--NorthstarDedicatedTest/dllmain.cpp1
-rw-r--r--NorthstarDedicatedTest/filesystem.cpp15
-rw-r--r--NorthstarDedicatedTest/filesystem.h5
-rw-r--r--NorthstarDedicatedTest/hooks.cpp198
-rw-r--r--NorthstarDedicatedTest/hooks.h199
-rw-r--r--NorthstarDedicatedTest/host.cpp30
-rw-r--r--NorthstarDedicatedTest/keyvalues.cpp4
-rw-r--r--NorthstarDedicatedTest/languagehooks.cpp2
-rw-r--r--NorthstarDedicatedTest/latencyflex.cpp2
-rw-r--r--NorthstarDedicatedTest/localchatwriter.cpp1
-rw-r--r--NorthstarDedicatedTest/logging.cpp2
-rw-r--r--NorthstarDedicatedTest/maxplayers.cpp1
-rw-r--r--NorthstarDedicatedTest/miscclientfixes.cpp2
-rw-r--r--NorthstarDedicatedTest/misccommands.cpp2
-rw-r--r--NorthstarDedicatedTest/miscserverfixes.cpp2
-rw-r--r--NorthstarDedicatedTest/miscserverscript.cpp2
-rw-r--r--NorthstarDedicatedTest/modlocalisation.cpp11
-rw-r--r--NorthstarDedicatedTest/modmanager.cpp12
-rw-r--r--NorthstarDedicatedTest/pdef.cpp4
-rw-r--r--NorthstarDedicatedTest/playlist.cpp52
-rw-r--r--NorthstarDedicatedTest/playlist.h2
-rw-r--r--NorthstarDedicatedTest/plugins.cpp4
-rw-r--r--NorthstarDedicatedTest/printcommand.h (renamed from NorthstarDedicatedTest/commandprint.h)0
-rw-r--r--NorthstarDedicatedTest/printcommands.cpp (renamed from NorthstarDedicatedTest/commandprint.cpp)14
-rw-r--r--NorthstarDedicatedTest/printmaps.cpp (renamed from NorthstarDedicatedTest/mapsprint.cpp)35
-rw-r--r--NorthstarDedicatedTest/printmaps.h (renamed from NorthstarDedicatedTest/mapsprint.h)0
-rw-r--r--NorthstarDedicatedTest/r2client.cpp8
-rw-r--r--NorthstarDedicatedTest/r2client.h4
-rw-r--r--NorthstarDedicatedTest/rpakfilesystem.cpp2
-rw-r--r--NorthstarDedicatedTest/scriptbrowserhooks.cpp21
-rw-r--r--NorthstarDedicatedTest/scriptmainmenupromos.cpp1
-rw-r--r--NorthstarDedicatedTest/scriptmodmenu.cpp1
-rw-r--r--NorthstarDedicatedTest/scriptserverbrowser.cpp4
-rw-r--r--NorthstarDedicatedTest/scriptservertoclientstringcommand.cpp1
-rw-r--r--NorthstarDedicatedTest/scriptsrson.cpp2
-rw-r--r--NorthstarDedicatedTest/serverauthentication.cpp37
-rw-r--r--NorthstarDedicatedTest/serverchathooks.cpp9
-rw-r--r--NorthstarDedicatedTest/sourceconsole.cpp3
-rw-r--r--NorthstarDedicatedTest/sourceinterface.cpp2
-rw-r--r--NorthstarDedicatedTest/squirrel.h2
62 files changed, 557 insertions, 423 deletions
diff --git a/LauncherInjector/LauncherInjector.vcxproj b/LauncherInjector/LauncherInjector.vcxproj
index 8870c732..0c727918 100644
--- a/LauncherInjector/LauncherInjector.vcxproj
+++ b/LauncherInjector/LauncherInjector.vcxproj
@@ -65,6 +65,9 @@
<AdditionalDependencies>shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<StackReserveSize>8000000</StackReserveSize>
</Link>
+ <PostBuildEvent>
+ <Command>copy /Y "$(TargetPath)" "D:\origin\titanfall\Titanfall2"</Command>
+ </PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
@@ -85,6 +88,9 @@
<AdditionalDependencies>shlwapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<StackReserveSize>8000000</StackReserveSize>
</Link>
+ <PostBuildEvent>
+ <Command>copy /Y "$(TargetPath)" "D:\origin\titanfall\Titanfall2"</Command>
+ </PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
diff --git a/LauncherInjector/main.cpp b/LauncherInjector/main.cpp
index 0fb025a7..99e5ba15 100644
--- a/LauncherInjector/main.cpp
+++ b/LauncherInjector/main.cpp
@@ -147,15 +147,22 @@ void AwaitOriginStartup()
std::cout << "LSX: connect()" << std::endl;
connect(sock, (struct sockaddr*)&lsxAddr, sizeof(lsxAddr));
-
+
char buf[4096];
- recv(sock, buf, 4096, 0);
- std::cout << buf << std::endl;
+ memset(buf, 0, sizeof(buf));
+
+ do
+ {
+ recv(sock, buf, 4096, 0);
+ std::cout << buf << std::endl;
- Sleep(8000);
+ // honestly really shit, this isn't needed for origin due to being able to check OriginClientService
+ // but for ea desktop we don't have anything like this, so atm we just have to wait to ensure that we start after logging in
+ Sleep(8000);
+ } while (!strstr(buf, "<LSX>")); // ensure we're actually getting data from lsx
}
- WSACleanup();
+ WSACleanup(); // cleanup sockets and such so game can contact lsx itself
}
void EnsureOriginStarted()
diff --git a/NorthstarDedicatedTest/ExploitFixes.cpp b/NorthstarDedicatedTest/ExploitFixes.cpp
index ff0af8f9..154091df 100644
--- a/NorthstarDedicatedTest/ExploitFixes.cpp
+++ b/NorthstarDedicatedTest/ExploitFixes.cpp
@@ -2,7 +2,6 @@
#include "ExploitFixes.h"
#include "ExploitFixes_UTF8Parser.h"
-#include "hooks.h"
#include "NSMem.h"
#include "cvar.h"
#include "tier0.h"
@@ -141,7 +140,7 @@ KHOOK(CClient_ProcessSetConVar, ("engine.dll", "48 8B D1 48 8B 49 18 48 8B 01 48
if (!nameValid || !valValid)
return BLOCKED_INFO("Missing null terminators");
- auto realVar = g_pCVar->FindVar(entry->name);
+ auto realVar = R2::g_pCVar->FindVar(entry->name);
if (realVar)
memcpy(
diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj
index 0c012880..d6c77de4 100644
--- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj
+++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj
@@ -117,10 +117,10 @@
<ClInclude Include="bansystem.h" />
<ClInclude Include="bitbuf.h" />
<ClInclude Include="bits.h" />
- <ClInclude Include="commandprint.h" />
+ <ClInclude Include="printcommand.h" />
<ClInclude Include="hoststate.h" />
<ClInclude Include="localchatwriter.h" />
- <ClInclude Include="mapsprint.h" />
+ <ClInclude Include="printmaps.h" />
<ClInclude Include="ns_version.h" />
<ClInclude Include="plugins.h" />
<ClInclude Include="plugin_abi.h" />
@@ -585,7 +585,7 @@
<ClCompile Include="keyvalues.cpp" />
<ClCompile Include="latencyflex.cpp" />
<ClCompile Include="localchatwriter.cpp" />
- <ClCompile Include="mapsprint.cpp" />
+ <ClCompile Include="printmaps.cpp" />
<ClCompile Include="maxplayers.cpp" />
<ClCompile Include="languagehooks.cpp" />
<ClCompile Include="memalloc.cpp" />
@@ -603,7 +603,7 @@
<ClCompile Include="pdef.cpp" />
<ClCompile Include="playlist.cpp" />
<ClCompile Include="plugins.cpp" />
- <ClCompile Include="commandprint.cpp" />
+ <ClCompile Include="printcommands.cpp" />
<ClCompile Include="r2client.cpp" />
<ClCompile Include="r2engine.cpp" />
<ClCompile Include="r2server.cpp" />
diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters
index c31b5045..3ab95494 100644
--- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters
+++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters
@@ -1467,10 +1467,10 @@
<ClInclude Include="dedicated.h">
<Filter>Header Files\Server\Dedicated</Filter>
</ClInclude>
- <ClInclude Include="commandprint.h">
+ <ClInclude Include="printcommand.h">
<Filter>Header Files\Shared\Console</Filter>
</ClInclude>
- <ClInclude Include="mapsprint.h">
+ <ClInclude Include="printmaps.h">
<Filter>Header Files\Shared\Console</Filter>
</ClInclude>
<ClInclude Include="r2engine.h">
@@ -1652,13 +1652,13 @@
<ClCompile Include="miscserverscript.cpp">
<Filter>Source Files\Server\Scripted</Filter>
</ClCompile>
- <ClCompile Include="commandprint.cpp">
+ <ClCompile Include="printcommands.cpp">
<Filter>Source Files\Shared\Console</Filter>
</ClCompile>
<ClCompile Include="demofixes.cpp">
<Filter>Source Files\Client</Filter>
</ClCompile>
- <ClCompile Include="mapsprint.cpp">
+ <ClCompile Include="printmaps.cpp">
<Filter>Source Files\Shared\Console</Filter>
</ClCompile>
<ClCompile Include="r2client.cpp">
diff --git a/NorthstarDedicatedTest/audio.cpp b/NorthstarDedicatedTest/audio.cpp
index eb493779..6f47786f 100644
--- a/NorthstarDedicatedTest/audio.cpp
+++ b/NorthstarDedicatedTest/audio.cpp
@@ -1,14 +1,15 @@
#include "pch.h"
-#include "hooks.h"
#include "audio.h"
#include "dedicated.h"
+#include "convar.h"
#include "rapidjson/error/en.h"
#include <fstream>
#include <iostream>
#include <sstream>
#include <random>
-#include "convar.h"
+
+AUTOHOOK_INIT()
extern "C"
{
@@ -328,9 +329,6 @@ void CustomAudioManager::ClearAudioOverrides()
m_loadedAudioOverridesRegex.clear();
}
-typedef bool (*LoadSampleMetadata_Type)(void* sample, void* audioBuffer, unsigned int audioBufferLength, int audioType);
-LoadSampleMetadata_Type LoadSampleMetadata_Original;
-
template <typename Iter, typename RandomGenerator> Iter select_randomly(Iter start, Iter end, RandomGenerator& g)
{
std::uniform_int_distribution<> dis(0, std::distance(start, end) - 1);
@@ -367,6 +365,24 @@ bool ShouldPlayAudioEvent(const char* eventName, const std::shared_ptr<EventOver
return true; // good to go
}
+// forward declare
+bool __declspec(noinline) __fastcall LoadSampleMetadata_Internal(
+ uintptr_t parentEvent, void* sample, void* audioBuffer, unsigned int audioBufferLength, int audioType);
+
+// DO NOT TOUCH THIS FUNCTION
+// The actual logic of it in a separate function (forcefully not inlined) to preserve the r12 register, which holds the event pointer.
+AUTOHOOK(LoadSampleMetadata, mileswin64.dll + 0xF110,
+bool, __fastcall, (void* sample, void* audioBuffer, unsigned int audioBufferLength, int audioType),
+{
+ uintptr_t parentEvent = (uintptr_t)Audio_GetParentEvent();
+
+ // Raw source, used for voice data only
+ if (audioType == 0)
+ return LoadSampleMetadata(sample, audioBuffer, audioBufferLength, audioType);
+
+ return LoadSampleMetadata_Internal(parentEvent, sample, audioBuffer, audioBufferLength, audioType);
+})
+
// DO NOT INLINE THIS FUNCTION
// See comment below.
bool __declspec(noinline) __fastcall LoadSampleMetadata_Internal(
@@ -397,7 +413,7 @@ bool __declspec(noinline) __fastcall LoadSampleMetadata_Internal(
if (!overrideData)
// not found either
- return LoadSampleMetadata_Original(sample, audioBuffer, audioBufferLength, audioType);
+ return LoadSampleMetadata(sample, audioBuffer, audioBufferLength, audioType);
else
{
// cache found pattern to improve performance
@@ -411,7 +427,7 @@ bool __declspec(noinline) __fastcall LoadSampleMetadata_Internal(
overrideData = iter->second;
if (!ShouldPlayAudioEvent(eventName, overrideData))
- return LoadSampleMetadata_Original(sample, audioBuffer, audioBufferLength, audioType);
+ return LoadSampleMetadata(sample, audioBuffer, audioBufferLength, audioType);
void* data = 0;
unsigned int dataLength = 0;
@@ -453,7 +469,7 @@ bool __declspec(noinline) __fastcall LoadSampleMetadata_Internal(
if (!data)
{
spdlog::warn("Could not fetch override sample data for event {}! Using original data instead.", eventName);
- return LoadSampleMetadata_Original(sample, audioBuffer, audioBufferLength, audioType);
+ return LoadSampleMetadata(sample, audioBuffer, audioBufferLength, audioType);
}
audioBuffer = data;
@@ -464,51 +480,23 @@ bool __declspec(noinline) __fastcall LoadSampleMetadata_Internal(
*(unsigned int*)((uintptr_t)sample + 0xF0) = audioBufferLength;
// 64 - Auto-detect sample type
- bool res = LoadSampleMetadata_Original(sample, audioBuffer, audioBufferLength, 64);
+ bool res = LoadSampleMetadata(sample, audioBuffer, audioBufferLength, 64);
if (!res)
spdlog::error("LoadSampleMetadata failed! The game will crash :(");
return res;
}
-// DO NOT TOUCH THIS FUNCTION
-// The actual logic of it in a separate function (forcefully not inlined) to preserve the r12 register, which holds the event pointer.
-bool __fastcall LoadSampleMetadata_Hook(void* sample, void* audioBuffer, unsigned int audioBufferLength, int audioType)
-{
- uintptr_t parentEvent = (uintptr_t)Audio_GetParentEvent();
-
- // Raw source, used for voice data only
- if (audioType == 0)
- return LoadSampleMetadata_Original(sample, audioBuffer, audioBufferLength, audioType);
-
- return LoadSampleMetadata_Internal(parentEvent, sample, audioBuffer, audioBufferLength, audioType);
-}
-
-typedef bool (*MilesLog_Type)(int level, const char* string);
-MilesLog_Type MilesLog_Original;
-
-void __fastcall MilesLog_Hook(int level, const char* string)
+AUTOHOOK(MilesLog, mileswin64.dll + 0x57DAD0,
+void, __fastcall, (int level, const char* string),
{
spdlog::info("[MSS] {} - {}", level, string);
-}
+})
ON_DLL_LOAD_CLIENT_RELIESON("client.dll", AudioHooks, ConVar, [](HMODULE baseAddress)
{
- Cvar_ns_print_played_sounds = new ConVar("ns_print_played_sounds", "0", FCVAR_NONE, "");
-
- if (IsDedicatedServer())
- return;
-
- uintptr_t milesAudioBase = (uintptr_t)GetModuleHandleA("mileswin64.dll");
+ AUTOHOOK_DISPATCH()
- if (!milesAudioBase)
- return spdlog::error("miles audio not found :terror:");
-
- HookEnabler hook;
-
- ENABLER_CREATEHOOK(
- hook, (char*)milesAudioBase + 0xF110, &LoadSampleMetadata_Hook, reinterpret_cast<LPVOID*>(&LoadSampleMetadata_Original));
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x57DAD0, &MilesLog_Hook, reinterpret_cast<LPVOID*>(&MilesLog_Original));
-
- MilesStopAll = (MilesStopAll_Type)((char*)baseAddress + 0x580850);
+ Cvar_ns_print_played_sounds = new ConVar("ns_print_played_sounds", "0", FCVAR_NONE, "");
+ MilesStopAll = (MilesStopAll_Type)((char*)GetModuleHandleA("mileswin64.dll") + 0x580850);
}) \ No newline at end of file
diff --git a/NorthstarDedicatedTest/bansystem.cpp b/NorthstarDedicatedTest/bansystem.cpp
index 70f4d7db..08115998 100644
--- a/NorthstarDedicatedTest/bansystem.cpp
+++ b/NorthstarDedicatedTest/bansystem.cpp
@@ -1,13 +1,13 @@
#pragma once
#include "pch.h"
#include "bansystem.h"
-#include "hooks.h"
#include "serverauthentication.h"
#include "concommand.h"
#include "miscserverscript.h"
-#include <filesystem>
#include "configurables.h"
+#include <filesystem>
+
const char* BANLIST_PATH_SUFFIX = "/banlist.txt";
ServerBanSystem* g_ServerBanSystem;
diff --git a/NorthstarDedicatedTest/buildainfile.cpp b/NorthstarDedicatedTest/buildainfile.cpp
index 39ce0323..ea9d69ef 100644
--- a/NorthstarDedicatedTest/buildainfile.cpp
+++ b/NorthstarDedicatedTest/buildainfile.cpp
@@ -1,16 +1,15 @@
#include "pch.h"
#include "convar.h"
-#include "hooks.h"
-#include "hookutils.h"
#include <fstream>
#include <filesystem>
#include "NSMem.h"
+AUTOHOOK_INIT()
+
namespace fs = std::filesystem;
const int AINET_VERSION_NUMBER = 57;
const int AINET_SCRIPT_VERSION_NUMBER = 21;
-const int MAP_VERSION_TEMP = 30;
const int PLACEHOLDER_CRC = 0;
const int MAX_HULLS = 5;
@@ -349,18 +348,16 @@ void DumpAINInfo(CAI_Network* aiNetwork)
writeStream.close();
}
-typedef void (*CAI_NetworkBuilder__BuildType)(void* builder, CAI_Network* aiNetwork, void* unknown);
-CAI_NetworkBuilder__BuildType CAI_NetworkBuilder__Build;
-void CAI_NetworkBuilder__BuildHook(void* builder, CAI_Network* aiNetwork, void* unknown)
+AUTOHOOK(CAI_NetworkBuilder__Build, server.dll + 0x385E20,
+void,, (void* builder, CAI_Network* aiNetwork, void* unknown),
{
CAI_NetworkBuilder__Build(builder, aiNetwork, unknown);
DumpAINInfo(aiNetwork);
-}
+})
-typedef void (*LoadAINFileType)(void* aimanager, void* buf, const char* filename);
-LoadAINFileType LoadAINFile;
-void LoadAINFileHook(void* aimanager, void* buf, const char* filename)
+AUTOHOOK(LoadAINFile, server.dll + 0x3933A0,
+void,, (void* aimanager, void* buf, const char* filename),
{
LoadAINFile(aimanager, buf, filename);
@@ -369,18 +366,13 @@ void LoadAINFileHook(void* aimanager, void* buf, const char* filename)
spdlog::info("running DumpAINInfo for loaded file {}", filename);
DumpAINInfo(*(CAI_Network**)((char*)aimanager + 2536));
}
-}
+})
ON_DLL_LOAD("server.dll", BuildAINFile, [](HMODULE baseAddress)
{
Cvar_ns_ai_dumpAINfileFromLoad = new ConVar(
"ns_ai_dumpAINfileFromLoad", "0", FCVAR_NONE, "For debugging: whether we should dump ain data for ains loaded from disk");
- HookEnabler hook;
- ENABLER_CREATEHOOK(
- hook, (char*)baseAddress + 0x385E20, &CAI_NetworkBuilder__BuildHook, reinterpret_cast<LPVOID*>(&CAI_NetworkBuilder__Build));
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x3933A0, &LoadAINFileHook, reinterpret_cast<LPVOID*>(&LoadAINFile));
-
pUnkStruct0Count = (int*)((char*)baseAddress + 0x1063BF8);
pppUnkNodeStruct0s = (UnkNodeStruct0***)((char*)baseAddress + 0x1063BE0);
@@ -388,11 +380,4 @@ ON_DLL_LOAD("server.dll", BuildAINFile, [](HMODULE baseAddress)
pppUnkStruct1s = (UnkLinkStruct1***)((char*)baseAddress + 0x1063A90);
pUnkServerMapversionGlobal = (char**)((char*)baseAddress + 0xBFBE08);
pMapName = (char*)baseAddress + 0x1053370;
-
- uintptr_t base = (uintptr_t)baseAddress;
-
- // remove a check that prevents a logging function in link generation from working
- // due to the sheer amount of logging this is a massive perf hit to generation, but spewlog_enable 0 exists so whatever
- NSMem::NOP(base + 0x3889B6, 6);
- NSMem::NOP(base + 0x3889BF, 6);
}); \ No newline at end of file
diff --git a/NorthstarDedicatedTest/chatcommand.cpp b/NorthstarDedicatedTest/chatcommand.cpp
index 78f4477d..86060a91 100644
--- a/NorthstarDedicatedTest/chatcommand.cpp
+++ b/NorthstarDedicatedTest/chatcommand.cpp
@@ -1,5 +1,4 @@
#include "pch.h"
-#include "hooks.h"
#include "convar.h"
#include "concommand.h"
#include "localchatwriter.h"
diff --git a/NorthstarDedicatedTest/clientauthhooks.cpp b/NorthstarDedicatedTest/clientauthhooks.cpp
index 6e1da395..7463028b 100644
--- a/NorthstarDedicatedTest/clientauthhooks.cpp
+++ b/NorthstarDedicatedTest/clientauthhooks.cpp
@@ -1,10 +1,10 @@
#include "pch.h"
-#include "hooks.h"
-#include "hookutils.h"
#include "masterserver.h"
#include "convar.h"
#include "r2client.h"
+AUTOHOOK_INIT()
+
ConVar* Cvar_ns_has_agreed_to_send_token;
// mirrored in script
@@ -12,9 +12,8 @@ const int NOT_DECIDED_TO_SEND_TOKEN = 0;
const int AGREED_TO_SEND_TOKEN = 1;
const int DISAGREED_TO_SEND_TOKEN = 2;
-typedef void (*AuthWithStryderType)(void* a1);
-AuthWithStryderType AuthWithStryder;
-void AuthWithStryderHook(void* a1)
+AUTOHOOK(AuthWithStryder, engine.dll + 0x1843A0,
+void,, (void* a1),
{
// game will call this forever, until it gets a valid auth key
// so, we need to manually invalidate our key until we're authed with northstar, then we'll allow game to auth with stryder
@@ -23,24 +22,23 @@ void AuthWithStryderHook(void* a1)
// if player has agreed to send token and we aren't already authing, try to auth
if (Cvar_ns_has_agreed_to_send_token->GetInt() == AGREED_TO_SEND_TOKEN &&
!g_MasterServerManager->m_bOriginAuthWithMasterServerInProgress)
- g_MasterServerManager->AuthenticateOriginWithMasterServer(R2::g_LocalPlayerUserID, R2::g_LocalPlayerOriginToken);
+ g_MasterServerManager->AuthenticateOriginWithMasterServer(R2::g_pLocalPlayerUserID, R2::g_pLocalPlayerOriginToken);
// invalidate key so auth will fail
- *R2::g_LocalPlayerOriginToken = 0;
+ *R2::g_pLocalPlayerOriginToken = 0;
}
AuthWithStryder(a1);
-}
+})
ON_DLL_LOAD_CLIENT_RELIESON("engine.dll", ClientAuthHooks, ConVar, [](HMODULE baseAddress)
{
+ AUTOHOOK_DISPATCH()
+
// this cvar will save to cfg once initially agreed with
Cvar_ns_has_agreed_to_send_token = new ConVar(
"ns_has_agreed_to_send_token",
"0",
FCVAR_ARCHIVE_PLAYERPROFILE,
"whether the user has agreed to send their origin token to the northstar masterserver");
-
- HookEnabler hook;
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x1843A0, &AuthWithStryderHook, reinterpret_cast<LPVOID*>(&AuthWithStryder));
}) \ No newline at end of file
diff --git a/NorthstarDedicatedTest/clientchathooks.cpp b/NorthstarDedicatedTest/clientchathooks.cpp
index a5daa2be..f778c6ee 100644
--- a/NorthstarDedicatedTest/clientchathooks.cpp
+++ b/NorthstarDedicatedTest/clientchathooks.cpp
@@ -1,20 +1,14 @@
#include "pch.h"
-#include "hooks.h"
-#include <rapidjson/document.h>
#include "squirrel.h"
#include "serverchathooks.h"
#include "localchatwriter.h"
-struct ChatTags
-{
- bool whisper;
- bool team;
- bool dead;
-};
+#include <rapidjson/document.h>
-typedef void(__fastcall* CHudChat__AddGameLineType)(void* self, const char* message, int fromPlayerId, bool isteam, bool isdead);
-CHudChat__AddGameLineType CHudChat__AddGameLine;
-static void CHudChat__AddGameLineHook(void* self, const char* message, int inboxId, bool isTeam, bool isDead)
+AUTOHOOK_INIT()
+
+AUTOHOOK(CHudChat__AddGameLine, client.dll + 0x22E580,
+void,, (void* self, const char* message, int inboxId, bool isTeam, bool isDead),
{
// This hook is called for each HUD, but we only want our logic to run once.
if (self != *CHudChat::allHuds)
@@ -51,7 +45,7 @@ static void CHudChat__AddGameLineHook(void* self, const char* message, int inbox
CHudChat__AddGameLine(hud, message, inboxId, isTeam, isDead);
}
}
-}
+})
// void NSChatWrite( int context, string str )
static SQRESULT SQ_ChatWrite(void* sqvm)
@@ -85,8 +79,7 @@ static SQRESULT SQ_ChatWriteLine(void* sqvm)
ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ClientChatHooks, ClientSquirrel, [](HMODULE baseAddress)
{
- HookEnabler hook;
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x22E580, &CHudChat__AddGameLineHook, reinterpret_cast<LPVOID*>(&CHudChat__AddGameLine));
+ AUTOHOOK_DISPATCH()
g_pClientSquirrel->AddFuncRegistration("void", "NSChatWrite", "int context, string text", "", SQ_ChatWrite);
g_pClientSquirrel->AddFuncRegistration("void", "NSChatWriteRaw", "int context, string text", "", SQ_ChatWriteRaw);
diff --git a/NorthstarDedicatedTest/clientruihooks.cpp b/NorthstarDedicatedTest/clientruihooks.cpp
index 65c85511..da556d26 100644
--- a/NorthstarDedicatedTest/clientruihooks.cpp
+++ b/NorthstarDedicatedTest/clientruihooks.cpp
@@ -1,5 +1,4 @@
#include "pch.h"
-#include "hooks.h"
#include "convar.h"
ConVar* Cvar_rui_drawEnable;
diff --git a/NorthstarDedicatedTest/clientvideooverrides.cpp b/NorthstarDedicatedTest/clientvideooverrides.cpp
index 8bed49e9..b3609fc2 100644
--- a/NorthstarDedicatedTest/clientvideooverrides.cpp
+++ b/NorthstarDedicatedTest/clientvideooverrides.cpp
@@ -1,5 +1,4 @@
#include "pch.h"
-#include "hooks.h"
#include "modmanager.h"
typedef void* (*BinkOpenType)(const char* path, uint32_t flags);
diff --git a/NorthstarDedicatedTest/concommand.cpp b/NorthstarDedicatedTest/concommand.cpp
index b5da2118..fddad088 100644
--- a/NorthstarDedicatedTest/concommand.cpp
+++ b/NorthstarDedicatedTest/concommand.cpp
@@ -1,7 +1,7 @@
#include "pch.h"
-#include "hooks.h"
#include "concommand.h"
#include "misccommands.h"
+
#include <iostream>
//-----------------------------------------------------------------------------
@@ -38,7 +38,7 @@ bool ConCommandBase::IsRegistered(void) const
//-----------------------------------------------------------------------------
bool ConCommandBase::IsFlagSet(int nFlags) const
{
- return false; // !TODO: Returning false on every query? (original implementation in Northstar before ConCommandBase refactor)
+ return m_nFlags & nFlags;
}
//-----------------------------------------------------------------------------
diff --git a/NorthstarDedicatedTest/concommand.h b/NorthstarDedicatedTest/concommand.h
index c11c7ea4..a02604f2 100644
--- a/NorthstarDedicatedTest/concommand.h
+++ b/NorthstarDedicatedTest/concommand.h
@@ -83,7 +83,7 @@ typedef void (*FnCommandCallback_t)(const CCommand& command);
//-----------------------------------------------------------------------------
// Returns 0 to COMMAND_COMPLETION_MAXITEMS worth of completion strings
//-----------------------------------------------------------------------------
-typedef int (*FnCommandCompletionCallback)(const char* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]);
+typedef int (*__fastcall FnCommandCompletionCallback)(const char* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]);
// From r5reloaded
class ConCommandBase
diff --git a/NorthstarDedicatedTest/convar.cpp b/NorthstarDedicatedTest/convar.cpp
index df570da9..1b2e0679 100644
--- a/NorthstarDedicatedTest/convar.cpp
+++ b/NorthstarDedicatedTest/convar.cpp
@@ -1,9 +1,7 @@
#include "pch.h"
-#include "hooks.h"
#include "bits.h"
#include "cvar.h"
#include "convar.h"
-#include "hookutils.h"
#include "sourceinterface.h"
typedef void (*ConVarRegisterType)(
@@ -36,8 +34,8 @@ ON_DLL_LOAD("engine.dll", ConVar, [](HMODULE baseAddress)
g_pConVar_Vtable = (char*)baseAddress + 0x67FD28;
g_pIConVar_Vtable = (char*)baseAddress + 0x67FDC8;
- g_pCVarInterface = new SourceInterface<CCvar>("vstdlib.dll", "VEngineCvar007");
- g_pCVar = *g_pCVarInterface;
+ R2::g_pCVarInterface = new SourceInterface<CCvar>("vstdlib.dll", "VEngineCvar007");
+ R2::g_pCVar = *R2::g_pCVarInterface;
})
//-----------------------------------------------------------------------------
diff --git a/NorthstarDedicatedTest/cvar.cpp b/NorthstarDedicatedTest/cvar.cpp
index 23d767fd..787790be 100644
--- a/NorthstarDedicatedTest/cvar.cpp
+++ b/NorthstarDedicatedTest/cvar.cpp
@@ -23,5 +23,9 @@ std::unordered_map<std::string, ConCommandBase*> CCvar::DumpToMap()
return allConVars;
}
-SourceInterface<CCvar>* g_pCVarInterface;
-CCvar* g_pCVar; \ No newline at end of file
+// use the R2 namespace for game funcs
+namespace R2
+{
+ SourceInterface<CCvar>* g_pCVarInterface;
+ CCvar* g_pCVar;
+} // namespace R2
diff --git a/NorthstarDedicatedTest/cvar.h b/NorthstarDedicatedTest/cvar.h
index a39df387..ead30d3e 100644
--- a/NorthstarDedicatedTest/cvar.h
+++ b/NorthstarDedicatedTest/cvar.h
@@ -35,5 +35,9 @@ class CCvar
std::unordered_map<std::string, ConCommandBase*> DumpToMap();
};
-extern SourceInterface<CCvar>* g_pCVarInterface;
-extern CCvar* g_pCVar;
+// use the R2 namespace for game funcs
+namespace R2
+{
+ extern SourceInterface<CCvar>* g_pCVarInterface;
+ extern CCvar* g_pCVar;
+} // namespace R2
diff --git a/NorthstarDedicatedTest/debugoverlay.cpp b/NorthstarDedicatedTest/debugoverlay.cpp
index 64e0d065..6cf7703f 100644
--- a/NorthstarDedicatedTest/debugoverlay.cpp
+++ b/NorthstarDedicatedTest/debugoverlay.cpp
@@ -1,5 +1,4 @@
#include "pch.h"
-#include "hooks.h"
#include "dedicated.h"
#include "cvar.h"
diff --git a/NorthstarDedicatedTest/dedicated.cpp b/NorthstarDedicatedTest/dedicated.cpp
index 5d8fedf0..25e6d24b 100644
--- a/NorthstarDedicatedTest/dedicated.cpp
+++ b/NorthstarDedicatedTest/dedicated.cpp
@@ -1,16 +1,13 @@
#include "pch.h"
-#include "hooks.h"
#include "dedicated.h"
-#include "hookutils.h"
#include "tier0.h"
#include "playlist.h"
#include "r2engine.h"
#include "hoststate.h"
#include "serverauthentication.h"
#include "masterserver.h"
-#include "commandprint.h"
+#include "printcommand.h"
-using namespace Tier0;
using namespace R2;
bool IsDedicatedServer()
@@ -46,21 +43,17 @@ typedef void (*CHostState__InitType)(CHostState* self);
void RunServer(CDedicatedExports* dedicated)
{
spdlog::info("CDedicatedExports::RunServer(): starting");
- spdlog::info(CommandLine()->GetCmdLine());
+ spdlog::info(Tier0::CommandLine()->GetCmdLine());
// initialise engine
g_pEngine->Frame();
// add +map if not present
// don't manually execute this from cbuf as users may have it in their startup args anyway, easier just to run from stuffcmds if present
- if (!CommandLine()->CheckParm("+map"))
- CommandLine()->AppendParm("+map", g_pCVar->FindVar("match_defaultMap")->GetString());
+ if (!Tier0::CommandLine()->CheckParm("+map"))
+ Tier0::CommandLine()->AppendParm("+map", g_pCVar->FindVar("match_defaultMap")->GetString());
- // ensure playlist initialises right, if we've not explicitly called setplaylist
- SetCurrentPlaylist(GetCurrentPlaylistName());
-
- // run server autoexec and re-run commandline
- Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec autoexec_ns_server", cmd_source_t::kCommandSrcCode);
+ // re-run commandline
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "stuffcmds", cmd_source_t::kCommandSrcCode);
Cbuf_Execute();
@@ -71,7 +64,7 @@ void RunServer(CDedicatedExports* dedicated)
double frameTitle = 0;
while (g_pEngine->m_nQuitting == EngineQuitState::QUIT_NOTQUITTING)
{
- double frameStart = Plat_FloatTime();
+ double frameStart = Tier0::Plat_FloatTime();
g_pEngine->Frame();
// only update the title after at least 500ms since the last update
@@ -80,7 +73,7 @@ void RunServer(CDedicatedExports* dedicated)
frameTitle = frameStart;
// this way of getting playercount/maxplayers honestly really sucks, but not got any other methods of doing it rn
- const char* maxPlayers = GetCurrentPlaylistVar("max_players", false);
+ const char* maxPlayers = GetCurrentPlaylistVar("max_players", true);
if (!maxPlayers)
maxPlayers = "6";
@@ -95,7 +88,7 @@ void RunServer(CDedicatedExports* dedicated)
}
std::this_thread::sleep_for(std::chrono::duration<double, std::ratio<1>>(
- Cvar_base_tickinterval_mp->GetFloat() - fmin(Plat_FloatTime() - frameStart, 0.25)));
+ Cvar_base_tickinterval_mp->GetFloat() - fmin(Tier0::Plat_FloatTime() - frameStart, 0.25)));
}
}
@@ -173,7 +166,6 @@ ON_DLL_LOAD_DEDI("engine.dll", DedicatedServer, [](HMODULE engineAddress)
// removing these will mess up register state when this function is over, so we'll write HS_RUN to the wrong address
// so uhh, don't do that
// NSMem::NOP(ea + 0x156B4C + 7, 8);
-
NSMem::NOP(ea + 0x156B4C + 15, 9);
// HostState_State_NewGame
@@ -243,15 +235,15 @@ ON_DLL_LOAD_DEDI("engine.dll", DedicatedServer, [](HMODULE engineAddress)
// make sure it still gets registered
// add cmdline args that are good for dedi
- CommandLine()->AppendParm("-nomenuvid", 0);
- CommandLine()->AppendParm("-nosound", 0);
- CommandLine()->AppendParm("-windowed", 0);
- CommandLine()->AppendParm("-nomessagebox", 0);
- CommandLine()->AppendParm("+host_preload_shaders", "0");
- CommandLine()->AppendParm("+net_usesocketsforloopback", "1");
+ Tier0::CommandLine()->AppendParm("-nomenuvid", 0);
+ Tier0::CommandLine()->AppendParm("-nosound", 0);
+ Tier0::CommandLine()->AppendParm("-windowed", 0);
+ Tier0::CommandLine()->AppendParm("-nomessagebox", 0);
+ Tier0::CommandLine()->AppendParm("+host_preload_shaders", "0");
+ Tier0::CommandLine()->AppendParm("+net_usesocketsforloopback", "1");
// Disable Quick Edit mode to reduce chance of user unintentionally hanging their server by selecting something.
- if (!CommandLine()->CheckParm("-bringbackquickedit"))
+ if (!Tier0::CommandLine()->CheckParm("-bringbackquickedit"))
{
HANDLE stdIn = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode = 0;
@@ -273,7 +265,7 @@ ON_DLL_LOAD_DEDI("engine.dll", DedicatedServer, [](HMODULE engineAddress)
spdlog::info("Quick Edit enabled by user request");
// create console input thread
- if (!CommandLine()->CheckParm("-noconsoleinput"))
+ if (!Tier0::CommandLine()->CheckParm("-noconsoleinput"))
consoleInputThreadHandle = CreateThread(0, 0, ConsoleInputThread, 0, 0, NULL);
else
spdlog::info("Console input disabled by user request");
@@ -285,11 +277,10 @@ ON_DLL_LOAD_DEDI("tier0.dll", DedicatedServerOrigin, [](HMODULE baseAddress)
// for any big ea lawyers, this can't be used to play the game without origin, game will throw a fit if you try to do anything without
// an origin id as a client for dedi it's fine though, game doesn't care if origin is disabled as long as there's only a server
- NSMem::BytePatch(
- (uintptr_t)GetProcAddress(GetModuleHandleA("tier0.dll"), "Tier0_InitOrigin"),
- {
- 0xC3 // ret
- });
+ NSMem::BytePatch((uintptr_t)GetProcAddress(GetModuleHandleA("tier0.dll"), "Tier0_InitOrigin"),
+ {
+ 0xC3 // ret
+ });
})
typedef void (*PrintFatalSquirrelErrorType)(void* sqvm);
diff --git a/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp b/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp
index 7142e44d..d01d381f 100644
--- a/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp
+++ b/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp
@@ -1,8 +1,6 @@
#pragma once
#include "pch.h"
-#include "hooks.h"
#include "dedicated.h"
-#include "hookutils.h"
#include "tier0.h"
#include "NSMem.h"
diff --git a/NorthstarDedicatedTest/demofixes.cpp b/NorthstarDedicatedTest/demofixes.cpp
index c2eb9b09..fba94183 100644
--- a/NorthstarDedicatedTest/demofixes.cpp
+++ b/NorthstarDedicatedTest/demofixes.cpp
@@ -10,15 +10,15 @@ ON_DLL_LOAD_CLIENT_RELIESON("client.dll", DemoFixes, ConVar, [](HMODULE baseAddr
// change default values of demo cvars to enable them by default, but not autorecord
// this is before Host_Init, the setvalue calls here will get overwritten by custom cfgs/launch options
- ConVar* Cvar_demo_enableDemos = g_pCVar->FindVar("demo_enabledemos");
+ ConVar* Cvar_demo_enableDemos = R2::g_pCVar->FindVar("demo_enabledemos");
Cvar_demo_enableDemos->m_pszDefaultValue = "1";
Cvar_demo_enableDemos->SetValue(true);
- ConVar* Cvar_demo_writeLocalFile = g_pCVar->FindVar("demo_writeLocalFile");
+ ConVar* Cvar_demo_writeLocalFile = R2::g_pCVar->FindVar("demo_writeLocalFile");
Cvar_demo_writeLocalFile->m_pszDefaultValue = "1";
Cvar_demo_writeLocalFile->SetValue(true);
- ConVar* Cvar_demo_autoRecord = g_pCVar->FindVar("demo_autoRecord");
+ ConVar* Cvar_demo_autoRecord = R2::g_pCVar->FindVar("demo_autoRecord");
Cvar_demo_autoRecord->m_pszDefaultValue = "0";
Cvar_demo_autoRecord->SetValue(false);
}) \ No newline at end of file
diff --git a/NorthstarDedicatedTest/dllmain.cpp b/NorthstarDedicatedTest/dllmain.cpp
index f097aa20..718e9413 100644
--- a/NorthstarDedicatedTest/dllmain.cpp
+++ b/NorthstarDedicatedTest/dllmain.cpp
@@ -1,5 +1,4 @@
#include "pch.h"
-#include "hooks.h"
#include "main.h"
#include "logging.h"
#include "memalloc.h"
diff --git a/NorthstarDedicatedTest/filesystem.cpp b/NorthstarDedicatedTest/filesystem.cpp
index 09bf8e97..f55fca82 100644
--- a/NorthstarDedicatedTest/filesystem.cpp
+++ b/NorthstarDedicatedTest/filesystem.cpp
@@ -1,22 +1,23 @@
#include "pch.h"
#include "filesystem.h"
-#include "hooks.h"
-#include "hookutils.h"
#include "sourceinterface.h"
#include "modmanager.h"
#include <iostream>
#include <sstream>
-using namespace R2FS;
+using namespace R2;
bool bReadingOriginalFile = false;
std::string sCurrentModPath;
ConVar* Cvar_ns_fs_log_reads;
-namespace R2FS
+// use the R2 namespace for game funcs
+namespace R2
{
+ SourceInterface<IFileSystem>* g_pFilesystem;
+
std::string ReadVPKFile(const char* path)
{
// read scripts.rson file, todo: check if this can be overwritten
@@ -44,9 +45,7 @@ namespace R2FS
return ret;
}
-
- SourceInterface<IFileSystem>* g_pFilesystem;
-}
+} // namespace R2
typedef void (*AddSearchPathType)(IFileSystem* fileSystem, const char* pPath, const char* pathID, SearchPathAdd_t addType);
AddSearchPathType AddSearchPath;
@@ -172,7 +171,7 @@ VPKData* MountVPKHook(IFileSystem* fileSystem, const char* vpkPath)
ON_DLL_LOAD("filesystem_stdio.dll", Filesystem, [](HMODULE baseAddress)
{
- R2FS::g_pFilesystem = new SourceInterface<IFileSystem>("filesystem_stdio.dll", "VFileSystem017");
+ R2::g_pFilesystem = new SourceInterface<IFileSystem>("filesystem_stdio.dll", "VFileSystem017");
// create hooks
HookEnabler hook;
diff --git a/NorthstarDedicatedTest/filesystem.h b/NorthstarDedicatedTest/filesystem.h
index 1aa4fb0c..abfdd14b 100644
--- a/NorthstarDedicatedTest/filesystem.h
+++ b/NorthstarDedicatedTest/filesystem.h
@@ -67,10 +67,11 @@ class IFileSystem
VTable2* m_vtable2;
};
-namespace R2FS
+// use the R2 namespace for game funcs
+namespace R2
{
extern SourceInterface<IFileSystem>* g_pFilesystem;
std::string ReadVPKFile(const char* path);
std::string ReadVPKOriginalFile(const char* path);
-} // namespace R2FS
+} // namespace R2
diff --git a/NorthstarDedicatedTest/hooks.cpp b/NorthstarDedicatedTest/hooks.cpp
index 32e4530c..d4608f85 100644
--- a/NorthstarDedicatedTest/hooks.cpp
+++ b/NorthstarDedicatedTest/hooks.cpp
@@ -1,7 +1,4 @@
#include "pch.h"
-#include "hooks.h"
-#include "hookutils.h"
-#include "sigscanning.h"
#include "dedicated.h"
#include <iostream>
@@ -15,6 +12,8 @@
namespace fs = std::filesystem;
+AUTOHOOK_INIT()
+
// called from the ON_DLL_LOAD macros
__dllLoadCallback::__dllLoadCallback(
eDllLoadCallbackSide side, const std::string dllName, DllLoadCallbackFuncType callback, std::string uniqueStr, std::string reliesOn)
@@ -41,6 +40,84 @@ __dllLoadCallback::__dllLoadCallback(
}
}
+void __fileAutohook::Dispatch()
+{
+ for (__autohook* hook : hooks)
+ hook->Dispatch();
+}
+
+ManualHook::ManualHook(const char* funcName, LPVOID* orig, LPVOID func) : pHookFunc(func), ppOrigFunc(orig)
+{
+ const int iFuncNameStrlen = strlen(funcName);
+ pFuncName = new char[iFuncNameStrlen];
+ memcpy(pFuncName, funcName, iFuncNameStrlen);
+}
+
+bool ManualHook::Dispatch(LPVOID addr)
+{
+ if (MH_CreateHook(addr, pHookFunc, ppOrigFunc) == MH_OK)
+ {
+ if (MH_EnableHook(addr) == MH_OK)
+ {
+ spdlog::info("Enabling hook {}", pFuncName);
+ return true;
+ }
+ else
+ spdlog::error("MH_EnableHook failed for function {}", pFuncName);
+ }
+ else
+ spdlog::error("MH_CreateHook failed for function {}", pFuncName);
+
+ return false;
+}
+
+// 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
+{
+ std::string dll;
+ DllLoadCallbackFuncType callback;
+ std::string tag;
+ std::string reliesOn;
+ bool called;
+};
+
+// HACK: declaring and initialising this vector at file scope crashes on debug builds due to static initialisation order
+// using a static var like this ensures that the vector is initialised lazily when it's used
+std::vector<DllLoadCallback>& GetDllLoadCallbacks()
+{
+ static std::vector<DllLoadCallback> vec = std::vector<DllLoadCallback>();
+ return vec;
+}
+
+void AddDllLoadCallback(std::string dll, DllLoadCallbackFuncType callback, std::string tag, std::string reliesOn)
+{
+ DllLoadCallback& callbackStruct = GetDllLoadCallbacks().emplace_back();
+
+ callbackStruct.dll = dll;
+ callbackStruct.callback = callback;
+ callbackStruct.tag = tag;
+ callbackStruct.reliesOn = reliesOn;
+ callbackStruct.called = false;
+}
+
+void AddDllLoadCallbackForDedicatedServer(
+ std::string dll, DllLoadCallbackFuncType callback, std::string tag, std::string reliesOn)
+{
+ if (!IsDedicatedServer())
+ return;
+
+ AddDllLoadCallback(dll, callback, tag, reliesOn);
+}
+
+void AddDllLoadCallbackForClient(std::string dll, DllLoadCallbackFuncType callback, std::string tag, std::string reliesOn)
+{
+ if (IsDedicatedServer())
+ return;
+
+ AddDllLoadCallback(dll, callback, tag, reliesOn);
+}
+
typedef LPSTR (*GetCommandLineAType)();
GetCommandLineAType GetCommandLineAOriginal;
LPSTR GetCommandLineAHook()
@@ -106,60 +183,12 @@ LPSTR GetCommandLineAHook()
return cmdlineModified;
}
-// 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
-{
- std::string dll;
- DllLoadCallbackFuncType callback;
- std::string tag;
- std::string reliesOn;
- bool called;
-};
-
-// for whatever reason, just declaring and initialising the vector at file scope crashes on debug builds
-// but this works, idk sucks but just how it is
-std::vector<DllLoadCallback>& GetDllLoadCallbacks()
-{
- static std::vector<DllLoadCallback> vec = std::vector<DllLoadCallback>();
- return vec;
-}
-
-void AddDllLoadCallback(std::string dll, DllLoadCallbackFuncType callback, std::string tag, std::string reliesOn)
-{
- DllLoadCallback& callbackStruct = GetDllLoadCallbacks().emplace_back(); // <-- crashes here
-
- callbackStruct.dll = dll;
- callbackStruct.callback = callback;
- callbackStruct.tag = tag;
- callbackStruct.reliesOn = reliesOn;
- callbackStruct.called = false;
-}
-
-void AddDllLoadCallbackForDedicatedServer(
- std::string dll, DllLoadCallbackFuncType callback, std::string tag, std::string reliesOn)
-{
- if (!IsDedicatedServer())
- return;
-
- AddDllLoadCallback(dll, callback, tag, reliesOn);
-}
-
-void AddDllLoadCallbackForClient(std::string dll, DllLoadCallbackFuncType callback, std::string tag, std::string reliesOn)
-{
- if (IsDedicatedServer())
- return;
-
- AddDllLoadCallback(dll, callback, tag, reliesOn);
-}
-
std::vector<std::string> calledTags;
-
void CallLoadLibraryACallbacks(LPCSTR lpLibFileName, HMODULE moduleAddress)
{
while (true)
{
- bool doneCalling = true;
+ bool bDoneCalling = true;
for (auto& callbackStruct : GetDllLoadCallbacks())
{
@@ -168,7 +197,7 @@ void CallLoadLibraryACallbacks(LPCSTR lpLibFileName, HMODULE moduleAddress)
if (callbackStruct.reliesOn != "" &&
std::find(calledTags.begin(), calledTags.end(), callbackStruct.reliesOn) == calledTags.end())
{
- doneCalling = false;
+ bDoneCalling = false;
continue;
}
@@ -178,7 +207,7 @@ void CallLoadLibraryACallbacks(LPCSTR lpLibFileName, HMODULE moduleAddress)
}
}
- if (doneCalling)
+ if (bDoneCalling)
break;
}
}
@@ -187,7 +216,7 @@ void CallLoadLibraryWCallbacks(LPCWSTR lpLibFileName, HMODULE moduleAddress)
{
while (true)
{
- bool doneCalling = true;
+ bool bDoneCalling = true;
for (auto& callbackStruct : GetDllLoadCallbacks())
{
@@ -196,7 +225,7 @@ void CallLoadLibraryWCallbacks(LPCWSTR lpLibFileName, HMODULE moduleAddress)
if (callbackStruct.reliesOn != "" &&
std::find(calledTags.begin(), calledTags.end(), callbackStruct.reliesOn) == calledTags.end())
{
- doneCalling = false;
+ bDoneCalling = false;
continue;
}
@@ -206,7 +235,7 @@ void CallLoadLibraryWCallbacks(LPCWSTR lpLibFileName, HMODULE moduleAddress)
}
}
- if (doneCalling)
+ if (bDoneCalling)
break;
}
}
@@ -234,72 +263,55 @@ void CallAllPendingDLLLoadCallbacks()
}
}
-
-typedef HMODULE (*LoadLibraryExAType)(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
-LoadLibraryExAType LoadLibraryExAOriginal;
-HMODULE LoadLibraryExAHook(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
-{
- HMODULE moduleAddress = LoadLibraryExAOriginal(lpLibFileName, hFile, dwFlags);
+AUTOHOOK_ABSOLUTEADDR(_LoadLibraryExA, LoadLibraryExA,
+HMODULE, WINAPI, (LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags),
+ {
+ HMODULE moduleAddress = _LoadLibraryExA(lpLibFileName, hFile, dwFlags);
if (moduleAddress)
- {
CallLoadLibraryACallbacks(lpLibFileName, moduleAddress);
- }
return moduleAddress;
-}
+})
+
-typedef HMODULE (*LoadLibraryAType)(LPCSTR lpLibFileName);
-LoadLibraryAType LoadLibraryAOriginal;
-HMODULE LoadLibraryAHook(LPCSTR lpLibFileName)
+AUTOHOOK_ABSOLUTEADDR(_LoadLibraryA, LoadLibraryA,
+HMODULE, WINAPI, (LPCSTR lpLibFileName),
{
- HMODULE moduleAddress = LoadLibraryAOriginal(lpLibFileName);
+ HMODULE moduleAddress = _LoadLibraryA(lpLibFileName);
if (moduleAddress)
- {
CallLoadLibraryACallbacks(lpLibFileName, moduleAddress);
- }
return moduleAddress;
-}
+})
-typedef HMODULE (*LoadLibraryExWType)(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
-LoadLibraryExWType LoadLibraryExWOriginal;
-HMODULE LoadLibraryExWHook(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
+AUTOHOOK_ABSOLUTEADDR(_LoadLibraryExW, LoadLibraryExW,
+HMODULE, WINAPI, (LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags),
{
- HMODULE moduleAddress = LoadLibraryExWOriginal(lpLibFileName, hFile, dwFlags);
+ HMODULE moduleAddress = _LoadLibraryExW(lpLibFileName, hFile, dwFlags);
if (moduleAddress)
- {
CallLoadLibraryWCallbacks(lpLibFileName, moduleAddress);
- }
return moduleAddress;
-}
+})
-typedef HMODULE (*LoadLibraryWType)(LPCWSTR lpLibFileName);
-LoadLibraryWType LoadLibraryWOriginal;
-HMODULE LoadLibraryWHook(LPCWSTR lpLibFileName)
+AUTOHOOK_ABSOLUTEADDR(_LoadLibraryW, LoadLibraryW,
+HMODULE, WINAPI, (LPCWSTR lpLibFileName),
{
- HMODULE moduleAddress = LoadLibraryWOriginal(lpLibFileName);
+ HMODULE moduleAddress = _LoadLibraryW(lpLibFileName);
if (moduleAddress)
- {
CallLoadLibraryWCallbacks(lpLibFileName, moduleAddress);
- }
return moduleAddress;
-}
+})
void InstallInitialHooks()
{
if (MH_Initialize() != MH_OK)
spdlog::error("MH_Initialize (minhook initialization) failed");
- HookEnabler hook;
- ENABLER_CREATEHOOK(hook, &GetCommandLineA, &GetCommandLineAHook, reinterpret_cast<LPVOID*>(&GetCommandLineAOriginal));
- ENABLER_CREATEHOOK(hook, &LoadLibraryExA, &LoadLibraryExAHook, reinterpret_cast<LPVOID*>(&LoadLibraryExAOriginal));
- ENABLER_CREATEHOOK(hook, &LoadLibraryA, &LoadLibraryAHook, reinterpret_cast<LPVOID*>(&LoadLibraryAOriginal));
- ENABLER_CREATEHOOK(hook, &LoadLibraryExW, &LoadLibraryExWHook, reinterpret_cast<LPVOID*>(&LoadLibraryExWOriginal));
- ENABLER_CREATEHOOK(hook, &LoadLibraryW, &LoadLibraryWHook, reinterpret_cast<LPVOID*>(&LoadLibraryWOriginal));
+ AUTOHOOK_DISPATCH()
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/hooks.h b/NorthstarDedicatedTest/hooks.h
index 182cdbc4..36c99b39 100644
--- a/NorthstarDedicatedTest/hooks.h
+++ b/NorthstarDedicatedTest/hooks.h
@@ -32,16 +32,195 @@ class __dllLoadCallback
std::string reliesOn);
};
-#define CONCAT_(x, y, z) x##y##z
-#define CONCAT(x, y, z) CONCAT_(x, y, z)
+#define __CONCAT3(x, y, z) x##y##z
+#define CONCAT3(x, y, z) __CONCAT3(x, y, z)
+#define __CONCAT2(x, y) x##y
+#define CONCAT2(x, y) __CONCAT2(x, y)
#define __STR(s) #s
-#define __ON_DLL_LOAD(dllName, func, side, counter, uniquestr, reliesOn) \
-__dllLoadCallback CONCAT(__dllLoadCallbackInstance, uniquestr, counter)(side, dllName, func, __STR(uniquestr), reliesOn);
+// adds a callback to be called when a given dll is loaded, for creating hooks and such
+#define __ON_DLL_LOAD(dllName, func, side, uniquestr, reliesOn) \
+namespace { __dllLoadCallback CONCAT2(__dllLoadCallbackInstance, __LINE__)(side, dllName, func, __STR(uniquestr), reliesOn); }
-#define ON_DLL_LOAD(dllName, uniquestr, func) __ON_DLL_LOAD(dllName, func, eDllLoadCallbackSide::UNSIDED, __LINE__, uniquestr, "")
-#define ON_DLL_LOAD_RELIESON(dllName, uniquestr, reliesOn, func) __ON_DLL_LOAD(dllName, func, eDllLoadCallbackSide::UNSIDED, __LINE__, uniquestr, __STR(reliesOn))
-#define ON_DLL_LOAD_CLIENT(dllName, uniquestr, func) __ON_DLL_LOAD(dllName, func, eDllLoadCallbackSide::CLIENT, __LINE__, uniquestr, "")
-#define ON_DLL_LOAD_CLIENT_RELIESON(dllName, uniquestr, reliesOn, func) __ON_DLL_LOAD(dllName, func, eDllLoadCallbackSide::CLIENT, __LINE__, uniquestr, __STR(reliesOn))
-#define ON_DLL_LOAD_DEDI(dllName, uniquestr, func) __ON_DLL_LOAD(dllName, func, eDllLoadCallbackSide::DEDICATED_SERVER, __LINE__, uniquestr, "")
-#define ON_DLL_LOAD_DEDI_RELIESON(dllName, uniquestr, reliesOn, func) __ON_DLL_LOAD(dllName, func, eDllLoadCallbackSide::DEDICATED_SERVER, __LINE__, uniquestr, __STR(reliesOn))
+#define ON_DLL_LOAD(dllName, uniquestr, func) __ON_DLL_LOAD(dllName, func, eDllLoadCallbackSide::UNSIDED, uniquestr, "")
+#define ON_DLL_LOAD_RELIESON(dllName, uniquestr, reliesOn, func) __ON_DLL_LOAD(dllName, func, eDllLoadCallbackSide::UNSIDED, uniquestr, __STR(reliesOn))
+#define ON_DLL_LOAD_CLIENT(dllName, uniquestr, func) __ON_DLL_LOAD(dllName, func, eDllLoadCallbackSide::CLIENT, uniquestr, "")
+#define ON_DLL_LOAD_CLIENT_RELIESON(dllName, uniquestr, reliesOn, func) __ON_DLL_LOAD(dllName, func, eDllLoadCallbackSide::CLIENT, uniquestr, __STR(reliesOn))
+#define ON_DLL_LOAD_DEDI(dllName, uniquestr, func) __ON_DLL_LOAD(dllName, func, eDllLoadCallbackSide::DEDICATED_SERVER, uniquestr, "")
+#define ON_DLL_LOAD_DEDI_RELIESON(dllName, uniquestr, reliesOn, func) __ON_DLL_LOAD(dllName, func, eDllLoadCallbackSide::DEDICATED_SERVER, uniquestr, __STR(reliesOn))
+
+// new macro hook stuff
+class __autohook;
+
+class __fileAutohook
+{
+ public:
+ std::vector<__autohook*> hooks;
+
+ void Dispatch();
+};
+
+// initialise autohooks for this file
+#define AUTOHOOK_INIT() \
+namespace { __fileAutohook __FILEAUTOHOOK; } \
+
+// dispatch all autohooks in this file
+#define AUTOHOOK_DISPATCH() \
+__FILEAUTOHOOK.Dispatch(); \
+
+class __autohook
+{
+ public:
+ enum AddressResolutionMode
+ {
+ OFFSET_STRING, // we're using a string that of the format dllname.dll + offset
+ ABSOLUTE_ADDR, // we're using an absolute address, we don't need to process it at all
+ };
+
+ char* pFuncName;
+
+ LPVOID pHookFunc;
+ LPVOID* ppOrigFunc;
+
+ // address resolution props
+ AddressResolutionMode iAddressResolutionMode;
+ char* pAddrString = nullptr; // for OFFSET_STRING
+ LPVOID iAbsoluteAddress = nullptr; // for ABSOLUTE_ADDR
+
+ public:
+ __autohook() = delete;
+
+ __autohook(__fileAutohook* autohook, const char* funcName, LPVOID absoluteAddress, LPVOID* orig, LPVOID func)
+ : pHookFunc(func), ppOrigFunc(orig), iAbsoluteAddress(absoluteAddress)
+ {
+ iAddressResolutionMode = ABSOLUTE_ADDR;
+
+ const int iFuncNameStrlen = strlen(funcName) + 1;
+ pFuncName = new char[iFuncNameStrlen];
+ memcpy(pFuncName, funcName, iFuncNameStrlen);
+
+ autohook->hooks.push_back(this);
+ }
+
+ __autohook(__fileAutohook* autohook, const char* funcName, const char* addrString, LPVOID* orig, LPVOID func)
+ : pHookFunc(func), ppOrigFunc(orig)
+ {
+ iAddressResolutionMode = OFFSET_STRING;
+
+ const int iFuncNameStrlen = strlen(funcName) + 1;
+ pFuncName = new char[iFuncNameStrlen];
+ memcpy(pFuncName, funcName, iFuncNameStrlen);
+
+ const int iAddrStrlen = strlen(addrString) + 1;
+ pAddrString = new char[iAddrStrlen];
+ memcpy(pAddrString, addrString, iAddrStrlen);
+
+ autohook->hooks.push_back(this);
+ }
+
+ ~__autohook()
+ {
+ delete[] pFuncName;
+
+ if (pAddrString)
+ delete[] pAddrString;
+ }
+
+ void Dispatch()
+ {
+ LPVOID targetAddr = nullptr;
+
+ // determine the address of the function we're hooking
+ switch (iAddressResolutionMode)
+ {
+ case ABSOLUTE_ADDR:
+ {
+ targetAddr = iAbsoluteAddress;
+ break;
+ }
+
+ 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 = (char*)pModuleAddr + iOffset;
+ break;
+ }
+ }
+
+ if (MH_CreateHook(targetAddr, pHookFunc, ppOrigFunc) == MH_OK)
+ {
+ if (MH_EnableHook(targetAddr) == MH_OK)
+ spdlog::info("Enabling hook {}", pFuncName);
+ else
+ spdlog::error("MH_EnableHook failed for function {}", pFuncName);
+ }
+ else
+ spdlog::error("MH_CreateHook failed for function {}", pFuncName);
+ }
+};
+
+// hook a function at a given offset from a dll to be dispatched with AUTOHOOK_DISPATCH()
+#define AUTOHOOK(name, addrString, type, callingConvention, args, func) \
+namespace { \
+ type(*callingConvention name) args; \
+ type callingConvention CONCAT2(__autohookfunc, name) args func \
+ __autohook CONCAT2(__autohook, __LINE__)(&__FILEAUTOHOOK, __STR(name), __STR(addrString), (LPVOID*)&name, (LPVOID)CONCAT2(__autohookfunc, name)); \
+} \
+
+// hook a function at a given absolute constant address to be dispatched with AUTOHOOK_DISPATCH()
+#define AUTOHOOK_ABSOLUTEADDR(name, addr, type, callingConvention, args, func) \
+namespace { \
+ type(*callingConvention name) args; \
+ type callingConvention CONCAT2(__autohookfunc, name) args func \
+ __autohook CONCAT2(__autohook, __LINE__)(&__FILEAUTOHOOK, __STR(name), addr, (LPVOID*)&name, (LPVOID)CONCAT2(__autohookfunc, name)); \
+} \
+
+class ManualHook
+{
+ public:
+ char* pFuncName;
+
+ LPVOID pHookFunc;
+ LPVOID* ppOrigFunc;
+
+ public:
+ ManualHook() = delete;
+ ManualHook(const char* funcName, LPVOID* orig, LPVOID func);
+ bool Dispatch(LPVOID addr);
+};
+
+// hook a function to be dispatched manually later
+#define HOOK(varName, originalFunc, type, callingConvention, args, func) \
+namespace { \
+ type(*callingConvention originalFunc) args; \
+ type callingConvention CONCAT2(__manualhookfunc, varName) args func \
+} \
+ManualHook<type(*callingConvention)args> varName = ManualHook<type(*callingConvention)args>(varName, (LPVOID*)&originalFunc, (LPVOID)CONCAT2(__manualhookfunc, varName)); \
diff --git a/NorthstarDedicatedTest/host.cpp b/NorthstarDedicatedTest/host.cpp
index d3a78877..fcc148b0 100644
--- a/NorthstarDedicatedTest/host.cpp
+++ b/NorthstarDedicatedTest/host.cpp
@@ -1,14 +1,15 @@
#include "pch.h"
#include "convar.h"
#include "modmanager.h"
-#include "commandprint.h"
-#include "mapsprint.h"
+#include "printcommand.h"
+#include "printmaps.h"
#include "r2engine.h"
typedef void (*Host_InitType)(bool bDedicated);
Host_InitType Host_Init;
void Host_InitHook(bool bDedicated)
{
+ spdlog::info("Host_Init()");
Host_Init(bDedicated);
// get all mod convars
@@ -18,8 +19,8 @@ void Host_InitHook(bool bDedicated)
vModConvarNames.push_back(cvar->Name);
// strip hidden and devonly cvar flags
- int iCvarsAltered = 0;
- for (auto& pair : g_pCVar->DumpToMap())
+ int iNumCvarsAltered = 0;
+ for (auto& pair : R2::g_pCVar->DumpToMap())
{
// don't remove from mod cvars
if (std::find(vModConvarNames.begin(), vModConvarNames.end(), pair.second->m_pszName) != vModConvarNames.end())
@@ -30,29 +31,36 @@ void Host_InitHook(bool bDedicated)
if (flags & FCVAR_DEVELOPMENTONLY)
{
flags &= ~FCVAR_DEVELOPMENTONLY;
- iCvarsAltered++;
+ iNumCvarsAltered++;
}
if (flags & FCVAR_HIDDEN)
{
flags &= ~FCVAR_HIDDEN;
- iCvarsAltered++;
+ iNumCvarsAltered++;
}
pair.second->m_nFlags = flags;
}
- spdlog::info("Removed {} hidden/devonly cvar flags", iCvarsAltered);
+ spdlog::info("Removed {} hidden/devonly cvar flags", iNumCvarsAltered);
// make servers able to run disconnect on clients
- g_pCVar->FindCommand("disconnect")->m_nFlags |= FCVAR_SERVER_CAN_EXECUTE;
+ R2::g_pCVar->FindCommand("disconnect")->m_nFlags |= FCVAR_SERVER_CAN_EXECUTE;
- // need to initialise these after host_init since they do stuff to preexisting concommands/convars
+ // make clients able to run status and ping
+ R2::g_pCVar->FindCommand("status")->m_nFlags |= FCVAR_CLIENTCMD_CAN_EXECUTE;
+ R2::g_pCVar->FindCommand("ping")->m_nFlags |= FCVAR_CLIENTCMD_CAN_EXECUTE;
+
+ // need to initialise these after host_init since they do stuff to preexisting concommands/convars without being client/server specific
InitialiseCommandPrint();
InitialiseMapsPrint();
- // run client autoexec if on client
- if (!bDedicated)
+ // client/server autoexecs on necessary platforms
+ // dedi needs autoexec_ns_server on boot, while non-dedi will run it on on listen server start
+ if (bDedicated)
+ R2::Cbuf_AddText(R2::Cbuf_GetCurrentPlayer(), "exec autoexec_ns_server", R2::cmd_source_t::kCommandSrcCode);
+ else
R2::Cbuf_AddText(R2::Cbuf_GetCurrentPlayer(), "exec autoexec_ns_client", R2::cmd_source_t::kCommandSrcCode);
}
diff --git a/NorthstarDedicatedTest/keyvalues.cpp b/NorthstarDedicatedTest/keyvalues.cpp
index 86cda483..4ba11dad 100644
--- a/NorthstarDedicatedTest/keyvalues.cpp
+++ b/NorthstarDedicatedTest/keyvalues.cpp
@@ -1,8 +1,6 @@
#include "pch.h"
#include "modmanager.h"
-#include "hooks.h"
#include "filesystem.h"
-#include "hookutils.h"
#include <fstream>
@@ -75,7 +73,7 @@ void ModManager::TryBuildKeyValues(const char* filename)
newKvs += "\"\n";
// load original file, so we can parse out the name of the root obj (e.g. WeaponData for weapons)
- std::string originalFile = R2FS::ReadVPKOriginalFile(filename);
+ std::string originalFile = R2::ReadVPKOriginalFile(filename);
if (!originalFile.length())
{
diff --git a/NorthstarDedicatedTest/languagehooks.cpp b/NorthstarDedicatedTest/languagehooks.cpp
index 42ac9b6a..ac421077 100644
--- a/NorthstarDedicatedTest/languagehooks.cpp
+++ b/NorthstarDedicatedTest/languagehooks.cpp
@@ -1,6 +1,6 @@
#include "pch.h"
-#include "hooks.h"
#include "tier0.h"
+
#include <filesystem>
#include <regex>
diff --git a/NorthstarDedicatedTest/latencyflex.cpp b/NorthstarDedicatedTest/latencyflex.cpp
index c5868aa7..87057a00 100644
--- a/NorthstarDedicatedTest/latencyflex.cpp
+++ b/NorthstarDedicatedTest/latencyflex.cpp
@@ -1,6 +1,4 @@
#include "pch.h"
-#include "hooks.h"
-#include "hookutils.h"
#include "convar.h"
ConVar* Cvar_r_latencyflex;
diff --git a/NorthstarDedicatedTest/localchatwriter.cpp b/NorthstarDedicatedTest/localchatwriter.cpp
index 81a0286a..c4bf0ea9 100644
--- a/NorthstarDedicatedTest/localchatwriter.cpp
+++ b/NorthstarDedicatedTest/localchatwriter.cpp
@@ -1,5 +1,4 @@
#include "pch.h"
-#include "hooks.h"
#include "localchatwriter.h"
class vgui_BaseRichText_vtable;
diff --git a/NorthstarDedicatedTest/logging.cpp b/NorthstarDedicatedTest/logging.cpp
index 014ef642..909d34ce 100644
--- a/NorthstarDedicatedTest/logging.cpp
+++ b/NorthstarDedicatedTest/logging.cpp
@@ -1,9 +1,7 @@
#include "pch.h"
#include "logging.h"
-#include "hooks.h"
#include "sourceconsole.h"
#include "spdlog/sinks/basic_file_sink.h"
-#include "hookutils.h"
#include "dedicated.h"
#include "convar.h"
#include <iomanip>
diff --git a/NorthstarDedicatedTest/maxplayers.cpp b/NorthstarDedicatedTest/maxplayers.cpp
index 5fa684d1..22f2f59a 100644
--- a/NorthstarDedicatedTest/maxplayers.cpp
+++ b/NorthstarDedicatedTest/maxplayers.cpp
@@ -1,5 +1,4 @@
#include "pch.h"
-#include "hooks.h"
#include "tier0.h"
// never set this to anything below 32
diff --git a/NorthstarDedicatedTest/miscclientfixes.cpp b/NorthstarDedicatedTest/miscclientfixes.cpp
index dce6b6c8..4d0e2508 100644
--- a/NorthstarDedicatedTest/miscclientfixes.cpp
+++ b/NorthstarDedicatedTest/miscclientfixes.cpp
@@ -1,7 +1,5 @@
#include "pch.h"
-#include "hooks.h"
#include "convar.h"
-#include "hookutils.h"
#include "NSMem.h"
ON_DLL_LOAD_CLIENT_RELIESON("client.dll", MiscClientFixes, ConVar, [](HMODULE baseAddress)
diff --git a/NorthstarDedicatedTest/misccommands.cpp b/NorthstarDedicatedTest/misccommands.cpp
index fd04a7fe..5a77a4f9 100644
--- a/NorthstarDedicatedTest/misccommands.cpp
+++ b/NorthstarDedicatedTest/misccommands.cpp
@@ -22,7 +22,7 @@ void ConCommand_ns_start_reauth_and_leave_to_lobby(const CCommand& arg)
{
// hack for special case where we're on a local server, so we erase our own newly created auth data on disconnect
g_MasterServerManager->m_bNewgameAfterSelfAuth = true;
- g_MasterServerManager->AuthenticateWithOwnServer(R2::g_LocalPlayerUserID, g_MasterServerManager->m_sOwnClientAuthToken);
+ g_MasterServerManager->AuthenticateWithOwnServer(R2::g_pLocalPlayerUserID, g_MasterServerManager->m_sOwnClientAuthToken);
}
void ConCommand_ns_end_reauth_and_leave_to_lobby(const CCommand& arg)
diff --git a/NorthstarDedicatedTest/miscserverfixes.cpp b/NorthstarDedicatedTest/miscserverfixes.cpp
index 455a3686..3abb28f4 100644
--- a/NorthstarDedicatedTest/miscserverfixes.cpp
+++ b/NorthstarDedicatedTest/miscserverfixes.cpp
@@ -1,6 +1,4 @@
#include "pch.h"
-#include "hooks.h"
-#include "hookutils.h"
#include "NSMem.h"
diff --git a/NorthstarDedicatedTest/miscserverscript.cpp b/NorthstarDedicatedTest/miscserverscript.cpp
index 9e8d26ff..488e071a 100644
--- a/NorthstarDedicatedTest/miscserverscript.cpp
+++ b/NorthstarDedicatedTest/miscserverscript.cpp
@@ -53,7 +53,7 @@ SQRESULT SQ_IsPlayerIndexLocalPlayer(void* sqvm)
return SQRESULT_ERROR;
}
- g_pServerSquirrel->pushbool(sqvm, !strcmp(R2::g_LocalPlayerUserID, (char*)player + 0xF500));
+ g_pServerSquirrel->pushbool(sqvm, !strcmp(R2::g_pLocalPlayerUserID, (char*)player + 0xF500));
return SQRESULT_NOTNULL;
}
diff --git a/NorthstarDedicatedTest/modlocalisation.cpp b/NorthstarDedicatedTest/modlocalisation.cpp
index 3fd96000..85df8902 100644
--- a/NorthstarDedicatedTest/modlocalisation.cpp
+++ b/NorthstarDedicatedTest/modlocalisation.cpp
@@ -1,15 +1,12 @@
#include "pch.h"
-#include "hooks.h"
-#include "hookutils.h"
#include "modmanager.h"
-
-typedef bool (*AddLocalisationFileType)(void* g_pVguiLocalize, const char* path, const char* pathId, char unknown);
+typedef bool (*AddLocalisationFileType)(void* pVguiLocalize, const char* path, const char* pathId, char unknown);
AddLocalisationFileType AddLocalisationFile;
-bool AddLocalisationFileHook(void* g_pVguiLocalize, const char* path, const char* pathId, char unknown)
+bool AddLocalisationFileHook(void* pVguiLocalize, const char* path, const char* pathId, char unknown)
{
static bool bLoadModLocalisationFiles = true;
- bool ret = AddLocalisationFile(g_pVguiLocalize, path, pathId, unknown);
+ bool ret = AddLocalisationFile(pVguiLocalize, path, pathId, unknown);
if (ret)
spdlog::info("Loaded localisation file {} successfully", path);
@@ -22,7 +19,7 @@ bool AddLocalisationFileHook(void* g_pVguiLocalize, const char* path, const char
for (Mod mod : g_pModManager->m_loadedMods)
if (mod.Enabled)
for (std::string& localisationFile : mod.LocalisationFiles)
- AddLocalisationFile(g_pVguiLocalize, localisationFile.c_str(), pathId, unknown);
+ AddLocalisationFile(pVguiLocalize, localisationFile.c_str(), pathId, unknown);
bLoadModLocalisationFiles = true;
diff --git a/NorthstarDedicatedTest/modmanager.cpp b/NorthstarDedicatedTest/modmanager.cpp
index 27576456..1a9ff1ab 100644
--- a/NorthstarDedicatedTest/modmanager.cpp
+++ b/NorthstarDedicatedTest/modmanager.cpp
@@ -1,10 +1,13 @@
#include "pch.h"
#include "modmanager.h"
-#include "hooks.h"
#include "convar.h"
#include "concommand.h"
#include "audio.h"
#include "masterserver.h"
+#include "filesystem.h"
+#include "rpakfilesystem.h"
+#include "configurables.h"
+
#include "rapidjson/error/en.h"
#include "rapidjson/document.h"
#include "rapidjson/ostreamwrapper.h"
@@ -14,9 +17,6 @@
#include <string>
#include <sstream>
#include <vector>
-#include "filesystem.h"
-#include "rpakfilesystem.h"
-#include "configurables.h"
ModManager* g_pModManager;
@@ -330,7 +330,7 @@ void ModManager::LoadMods()
// preexisting convars note: we don't delete convars if they already exist because they're used for script stuff, unfortunately this
// causes us to leak memory on reload, but not much, potentially find a way to not do this at some point
for (ModConVar* convar : mod.ConVars)
- if (!g_pCVar->FindVar(convar->Name.c_str())) // make sure convar isn't registered yet, unsure if necessary but idk what
+ if (!R2::g_pCVar->FindVar(convar->Name.c_str())) // make sure convar isn't registered yet, unsure if necessary but idk what
// behaviour is for defining same convar multiple times
new ConVar(convar->Name.c_str(), convar->DefaultValue.c_str(), convar->Flags, convar->HelpString.c_str());
@@ -376,7 +376,7 @@ void ModManager::LoadMods()
modVpk.m_sVpkPath = vpkName;
if (m_hasLoadedMods && modVpk.m_bAutoLoad)
- (*R2FS::g_pFilesystem)->m_vtable->MountVPK(*R2FS::g_pFilesystem, vpkName.c_str());
+ (*R2::g_pFilesystem)->m_vtable->MountVPK(*R2::g_pFilesystem, vpkName.c_str());
}
}
}
diff --git a/NorthstarDedicatedTest/pdef.cpp b/NorthstarDedicatedTest/pdef.cpp
index fdd1dfa4..367d1bbf 100644
--- a/NorthstarDedicatedTest/pdef.cpp
+++ b/NorthstarDedicatedTest/pdef.cpp
@@ -1,8 +1,8 @@
#include "pch.h"
#include "modmanager.h"
#include "filesystem.h"
-#include "hookutils.h"
#include "pdef.h"
+
#include <map>
#include <sstream>
#include <fstream>
@@ -14,7 +14,7 @@ void ModManager::BuildPdef()
fs::path MOD_PDEF_PATH = fs::path(GetCompiledAssetsPath() / MOD_PDEF_SUFFIX);
fs::remove(MOD_PDEF_PATH);
- std::string pdef = R2FS::ReadVPKOriginalFile(VPK_PDEF_PATH);
+ std::string pdef = R2::ReadVPKOriginalFile(VPK_PDEF_PATH);
for (Mod& mod : m_loadedMods)
{
diff --git a/NorthstarDedicatedTest/playlist.cpp b/NorthstarDedicatedTest/playlist.cpp
index e3acc490..0e0ed3c2 100644
--- a/NorthstarDedicatedTest/playlist.cpp
+++ b/NorthstarDedicatedTest/playlist.cpp
@@ -1,12 +1,12 @@
#include "pch.h"
#include "playlist.h"
#include "NSMem.h"
-#include "hooks.h"
#include "concommand.h"
#include "convar.h"
-#include "hookutils.h"
#include "squirrel.h"
+AUTOHOOK_INIT()
+
// use the R2 namespace for game funcs
namespace R2
{
@@ -16,23 +16,6 @@ namespace R2
GetCurrentPlaylistVarType GetCurrentPlaylistVar;
} // namespace R2
-void ConCommand_playlist(const CCommand& args)
-{
- if (args.ArgC() < 2)
- return;
-
- R2::SetCurrentPlaylist(args.Arg(1));
-}
-
-void ConCommand_setplaylistvaroverride(const CCommand& args)
-{
- if (args.ArgC() < 3)
- return;
-
- for (int i = 1; i < args.ArgC(); i += 2)
- R2::SetPlaylistVarOverride(args.Arg(i), args.Arg(i + 1));
-}
-
ConVar* Cvar_ns_use_clc_SetPlaylistVarOverride;
typedef char (*Onclc_SetPlaylistVarOverrideType)(void* a1, void* a2);
@@ -67,7 +50,7 @@ typedef int (*GetCurrentGamemodeMaxPlayersType)();
GetCurrentGamemodeMaxPlayersType GetCurrentGamemodeMaxPlayers;
int GetCurrentGamemodeMaxPlayersHook()
{
- char* maxPlayersStr = R2::GetCurrentPlaylistVar("max_players", 0);
+ const char* maxPlayersStr = R2::GetCurrentPlaylistVar("max_players", 0);
if (!maxPlayersStr)
return GetCurrentGamemodeMaxPlayers();
@@ -75,13 +58,35 @@ int GetCurrentGamemodeMaxPlayersHook()
return maxPlayers;
}
+void ConCommand_playlist(const CCommand& args)
+{
+ if (args.ArgC() < 2)
+ return;
+
+ R2::SetCurrentPlaylist(args.Arg(1));
+}
+
+void ConCommand_setplaylistvaroverride(const CCommand& args)
+{
+ if (args.ArgC() < 3)
+ return;
+
+ for (int i = 1; i < args.ArgC(); i += 2)
+ R2::SetPlaylistVarOverride(args.Arg(i), args.Arg(i + 1));
+}
+
ON_DLL_LOAD_RELIESON("engine.dll", PlaylistHooks, ConCommand, [](HMODULE baseAddress)
{
// 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);
RegisterConCommand("setplaylistvaroverrides", ConCommand_setplaylistvaroverride, "sets a playlist var override", FCVAR_NONE);
-
+
+ R2::GetCurrentPlaylistName = (R2::GetCurrentPlaylistNameType)((char*)baseAddress + 0x18C640);
+ R2::SetCurrentPlaylist = (R2::SetCurrentPlaylistType)((char*)baseAddress + 0x18EB20);
+ R2::SetPlaylistVarOverride = (R2::SetPlaylistVarOverrideType)((char*)baseAddress + 0x18ED00);
+ R2::GetCurrentPlaylistVar = (R2::GetCurrentPlaylistVarType)((char*)baseAddress + 0x18C680);
+
// note: clc_SetPlaylistVarOverride is pretty insecure, since it allows for entirely arbitrary playlist var overrides to be sent to the
// server, this is somewhat restricted on custom servers to prevent it being done outside of private matches, but ideally it should be
// disabled altogether, since the custom menus won't use it anyway this should only really be accepted if you want vanilla client
@@ -89,11 +94,6 @@ ON_DLL_LOAD_RELIESON("engine.dll", PlaylistHooks, ConCommand, [](HMODULE baseAdd
Cvar_ns_use_clc_SetPlaylistVarOverride = new ConVar(
"ns_use_clc_SetPlaylistVarOverride", "0", FCVAR_GAMEDLL, "Whether the server should accept clc_SetPlaylistVarOverride messages");
- R2::GetCurrentPlaylistName = (R2::GetCurrentPlaylistNameType)((char*)baseAddress + 0x18C640);
- R2::SetCurrentPlaylist = (R2::SetCurrentPlaylistType)((char*)baseAddress + 0x18EB20);
- R2::SetPlaylistVarOverride = (R2::SetPlaylistVarOverrideType)((char*)baseAddress + 0x18ED00);
- R2::GetCurrentPlaylistVar = (R2::GetCurrentPlaylistVarType)((char*)baseAddress + 0x18C680);
-
HookEnabler hook;
ENABLER_CREATEHOOK(
hook, (char*)baseAddress + 0x222180, &Onclc_SetPlaylistVarOverrideHook, reinterpret_cast<LPVOID*>(&Onclc_SetPlaylistVarOverride));
diff --git a/NorthstarDedicatedTest/playlist.h b/NorthstarDedicatedTest/playlist.h
index 28e5aa9d..4ad48ee9 100644
--- a/NorthstarDedicatedTest/playlist.h
+++ b/NorthstarDedicatedTest/playlist.h
@@ -12,6 +12,6 @@ namespace R2
typedef void (*SetPlaylistVarOverrideType)(const char* varName, const char* value);
extern SetPlaylistVarOverrideType SetPlaylistVarOverride;
- typedef char* (*GetCurrentPlaylistVarType)(const char* varName, bool useOverrides);
+ typedef const char* (*GetCurrentPlaylistVarType)(const char* varName, bool useOverrides);
extern GetCurrentPlaylistVarType GetCurrentPlaylistVar;
} // namespace R2
diff --git a/NorthstarDedicatedTest/plugins.cpp b/NorthstarDedicatedTest/plugins.cpp
index 157ac416..e7e40dad 100644
--- a/NorthstarDedicatedTest/plugins.cpp
+++ b/NorthstarDedicatedTest/plugins.cpp
@@ -1,10 +1,10 @@
#include "pch.h"
-#include "hooks.h"
#include "squirrel.h"
#include "plugins.h"
-#include <chrono>
#include "masterserver.h"
#include "convar.h"
+
+#include <chrono>
#include <windows.h>
/// <summary>
diff --git a/NorthstarDedicatedTest/commandprint.h b/NorthstarDedicatedTest/printcommand.h
index 6c3ef850..6c3ef850 100644
--- a/NorthstarDedicatedTest/commandprint.h
+++ b/NorthstarDedicatedTest/printcommand.h
diff --git a/NorthstarDedicatedTest/commandprint.cpp b/NorthstarDedicatedTest/printcommands.cpp
index 5d78a1b4..c56283a1 100644
--- a/NorthstarDedicatedTest/commandprint.cpp
+++ b/NorthstarDedicatedTest/printcommands.cpp
@@ -1,5 +1,5 @@
#include "pch.h"
-#include "commandprint.h"
+#include "printcommand.h"
#include "convar.h"
#include "concommand.h"
@@ -30,7 +30,7 @@ void PrintCommandHelpDialogue(const ConCommandBase* command, const char* name)
}
// temp because command->IsCommand does not currently work
- ConVar* cvar = g_pCVar->FindVar(command->m_pszName);
+ ConVar* cvar = R2::g_pCVar->FindVar(command->m_pszName);
if (cvar)
spdlog::info("\"{}\" = \"{}\" {}- {}", cvar->GetBaseName(), cvar->GetString(), flagString, cvar->GetHelpText());
else
@@ -54,7 +54,7 @@ void TryPrintCvarHelpForCommand(const char* pCommand)
}
// check if we're inputting a cvar, but not setting it at all
- ConVar* cvar = g_pCVar->FindVar(pCvarStr);
+ ConVar* cvar = R2::g_pCVar->FindVar(pCvarStr);
if (cvar)
PrintCommandHelpDialogue(&cvar->m_ConCommandBase, pCvarStr);
@@ -69,7 +69,7 @@ void ConCommand_help(const CCommand& arg)
return;
}
- PrintCommandHelpDialogue(g_pCVar->FindCommandBase(arg.Arg(1)), arg.Arg(1));
+ PrintCommandHelpDialogue(R2::g_pCVar->FindCommandBase(arg.Arg(1)), arg.Arg(1));
}
void ConCommand_find(const CCommand& arg)
@@ -83,7 +83,7 @@ void ConCommand_find(const CCommand& arg)
char pTempName[256];
char pTempSearchTerm[256];
- for (auto& map : g_pCVar->DumpToMap())
+ for (auto& map : R2::g_pCVar->DumpToMap())
{
bool bPrintCommand = true;
for (int i = 0; i < arg.ArgC() - 1; i++)
@@ -140,7 +140,7 @@ void ConCommand_findflags(const CCommand& arg)
}
// print cvars
- for (auto& map : g_pCVar->DumpToMap())
+ for (auto& map : R2::g_pCVar->DumpToMap())
{
if (map.second->m_nFlags & resolvedFlag)
PrintCommandHelpDialogue(map.second, map.second->m_pszName);
@@ -155,7 +155,7 @@ void InitialiseCommandPrint()
RegisterConCommand("findflags", ConCommand_findflags, "Find concommands by flags.", FCVAR_NONE);
// help is already a command, so we need to modify the preexisting command to use our func instead
// and clear the flags also
- ConCommand* helpCommand = g_pCVar->FindCommand("help");
+ ConCommand* helpCommand = R2::g_pCVar->FindCommand("help");
helpCommand->m_nFlags = FCVAR_NONE;
helpCommand->m_pCommandCallback = ConCommand_help;
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/mapsprint.cpp b/NorthstarDedicatedTest/printmaps.cpp
index bf94c548..7fbe088a 100644
--- a/NorthstarDedicatedTest/mapsprint.cpp
+++ b/NorthstarDedicatedTest/printmaps.cpp
@@ -1,12 +1,15 @@
#include "pch.h"
-#include "mapsprint.h"
+#include "printmaps.h"
#include "convar.h"
#include "concommand.h"
#include "modmanager.h"
#include "tier0.h"
+
#include <filesystem>
#include <regex>
+AUTOHOOK_INIT()
+
enum class MapSource_t
{
VPK,
@@ -39,7 +42,7 @@ void RefreshMapList()
for (auto& modFilePair : g_pModManager->m_modFiles)
{
ModOverrideFile file = modFilePair.second;
- if (file.path.extension() == ".bsp" && file.path.parent_path().string() == "maps") // only allow mods actually in /maps atm
+ if (file.path.extension() == ".bsp" && file.path.parent_path().string() == "maps") // only allow mod maps actually in /maps atm
{
MapVPKInfo& map = vMapList.emplace_back();
map.name = file.path.stem().string();
@@ -51,7 +54,7 @@ void RefreshMapList()
// get maps in vpk
{
const int iNumRetailNonMapVpks = 1;
- static const char* ppRetailNonMapVpks[] = {
+ static const char* const ppRetailNonMapVpks[] = {
"englishclient_frontend.bsp.pak000_dir.vpk"}; // don't include mp_common here as it contains mp_lobby
// matches directory vpks, and captures their map name in the first group
@@ -106,18 +109,15 @@ void RefreshMapList()
}
}
-typedef int (*__fastcall _Host_Map_f_CompletionFuncType)(
- char const* cmdname, char const* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]);
-_Host_Map_f_CompletionFuncType _Host_Map_f_CompletionFunc;
-int __fastcall _Host_Map_f_CompletionFuncHook(
- char const* cmdname, char const* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH])
+AUTOHOOK(_Host_Map_f_CompletionFunc, engine.dll + 0x161AE0,
+int, __fastcall, (const char const* cmdname, const char const* partial, char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]),
{
// don't update our map list often from this func, only refresh every 10 seconds so we avoid constantly reading fs
static double flLastAutocompleteRefresh = -999;
if (flLastAutocompleteRefresh + 10.0 < Tier0::Plat_FloatTime())
{
- RefreshMapList();
+ RefreshMapList();
flLastAutocompleteRefresh = Tier0::Plat_FloatTime();
}
@@ -134,13 +134,15 @@ int __fastcall _Host_Map_f_CompletionFuncHook(
strcpy(commands[numMaps], cmdname);
strncpy_s(
commands[numMaps++] + cmdLength,
- COMMAND_COMPLETION_ITEM_LENGTH, &vMapList[i].name[0],
+ COMMAND_COMPLETION_ITEM_LENGTH,
+ &vMapList[i].name[0],
COMMAND_COMPLETION_ITEM_LENGTH - cmdLength);
}
}
return numMaps;
-}
+})
+
void ConCommand_maps(const CCommand& args)
{
@@ -160,13 +162,8 @@ void ConCommand_maps(const CCommand& args)
void InitialiseMapsPrint()
{
- ConCommand* mapsCommand = g_pCVar->FindCommand("maps");
- mapsCommand->m_pCommandCallback = ConCommand_maps;
+ AUTOHOOK_DISPATCH()
- HookEnabler hook;
- ENABLER_CREATEHOOK(
- hook,
- (char*)GetModuleHandleA("engine.dll") + 0x161AE0,
- &_Host_Map_f_CompletionFuncHook,
- reinterpret_cast<LPVOID*>(&_Host_Map_f_CompletionFunc));
+ ConCommand* mapsCommand = R2::g_pCVar->FindCommand("maps");
+ mapsCommand->m_pCommandCallback = ConCommand_maps;
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/mapsprint.h b/NorthstarDedicatedTest/printmaps.h
index b01761c0..b01761c0 100644
--- a/NorthstarDedicatedTest/mapsprint.h
+++ b/NorthstarDedicatedTest/printmaps.h
diff --git a/NorthstarDedicatedTest/r2client.cpp b/NorthstarDedicatedTest/r2client.cpp
index 845eebf1..0d56e16f 100644
--- a/NorthstarDedicatedTest/r2client.cpp
+++ b/NorthstarDedicatedTest/r2client.cpp
@@ -6,15 +6,15 @@ using namespace R2;
// use the R2 namespace for game funcs
namespace R2
{
- char* g_LocalPlayerUserID;
- char* g_LocalPlayerOriginToken;
+ char* g_pLocalPlayerUserID;
+ char* g_pLocalPlayerOriginToken;
GetBaseLocalClientType GetBaseLocalClient;
} // namespace R2
ON_DLL_LOAD("engine.dll", R2EngineClient, [](HMODULE baseAddress)
{
- g_LocalPlayerUserID = (char*)baseAddress + 0x13F8E688;
- g_LocalPlayerOriginToken = (char*)baseAddress + 0x13979C80;
+ g_pLocalPlayerUserID = (char*)baseAddress + 0x13F8E688;
+ g_pLocalPlayerOriginToken = (char*)baseAddress + 0x13979C80;
GetBaseLocalClient = (GetBaseLocalClientType)((char*)baseAddress + 0x78200);
}) \ No newline at end of file
diff --git a/NorthstarDedicatedTest/r2client.h b/NorthstarDedicatedTest/r2client.h
index f4e0c8a8..c2de3397 100644
--- a/NorthstarDedicatedTest/r2client.h
+++ b/NorthstarDedicatedTest/r2client.h
@@ -3,8 +3,8 @@
// use the R2 namespace for game funcs
namespace R2
{
- extern char* g_LocalPlayerUserID;
- extern char* g_LocalPlayerOriginToken;
+ extern char* g_pLocalPlayerUserID;
+ extern char* g_pLocalPlayerOriginToken;
typedef void* (*GetBaseLocalClientType)();
extern GetBaseLocalClientType GetBaseLocalClient;
diff --git a/NorthstarDedicatedTest/rpakfilesystem.cpp b/NorthstarDedicatedTest/rpakfilesystem.cpp
index 4da59836..e7c88674 100644
--- a/NorthstarDedicatedTest/rpakfilesystem.cpp
+++ b/NorthstarDedicatedTest/rpakfilesystem.cpp
@@ -1,7 +1,5 @@
#include "pch.h"
#include "rpakfilesystem.h"
-#include "hooks.h"
-#include "hookutils.h"
#include "modmanager.h"
#include "dedicated.h"
diff --git a/NorthstarDedicatedTest/scriptbrowserhooks.cpp b/NorthstarDedicatedTest/scriptbrowserhooks.cpp
index bb917899..de78daf9 100644
--- a/NorthstarDedicatedTest/scriptbrowserhooks.cpp
+++ b/NorthstarDedicatedTest/scriptbrowserhooks.cpp
@@ -1,26 +1,23 @@
#include "pch.h"
-#include "hooks.h"
-#include "hookutils.h"
+
+AUTOHOOK_INIT()
bool* bIsOriginOverlayEnabled;
-typedef void (*OpenExternalWebBrowserType)(char* url, char flags);
-OpenExternalWebBrowserType OpenExternalWebBrowser;
-void OpenExternalWebBrowserHook(char* url, char flags)
+AUTOHOOK(OpenExternalWebBrowser, engine.dll + 0x184E40,
+void,, (char* pUrl, char flags),
{
bool bIsOriginOverlayEnabledOriginal = *bIsOriginOverlayEnabled;
- if (flags & 2 && !strncmp(url, "http", 4)) // custom force external browser flag
+ if (flags & 2 && !strncmp(pUrl, "http", 4)) // custom force external browser flag
*bIsOriginOverlayEnabled = false; // if this bool is false, game will use an external browser rather than the origin overlay one
- OpenExternalWebBrowser(url, flags);
+ OpenExternalWebBrowser(pUrl, flags);
*bIsOriginOverlayEnabled = bIsOriginOverlayEnabledOriginal;
-}
+})
ON_DLL_LOAD_CLIENT("engine.dll", ScriptExternalBrowserHooks, [](HMODULE baseAddress)
{
- bIsOriginOverlayEnabled = (bool*)baseAddress + 0x13978255;
+ AUTOHOOK_DISPATCH()
- HookEnabler hook;
- ENABLER_CREATEHOOK(
- hook, (char*)baseAddress + 0x184E40, &OpenExternalWebBrowserHook, reinterpret_cast<LPVOID*>(&OpenExternalWebBrowser));
+ bIsOriginOverlayEnabled = (bool*)baseAddress + 0x13978255;
}) \ No newline at end of file
diff --git a/NorthstarDedicatedTest/scriptmainmenupromos.cpp b/NorthstarDedicatedTest/scriptmainmenupromos.cpp
index 013aa8b3..a4f65dd8 100644
--- a/NorthstarDedicatedTest/scriptmainmenupromos.cpp
+++ b/NorthstarDedicatedTest/scriptmainmenupromos.cpp
@@ -1,5 +1,4 @@
#include "pch.h"
-#include "hooks.h"
#include "squirrel.h"
#include "masterserver.h"
diff --git a/NorthstarDedicatedTest/scriptmodmenu.cpp b/NorthstarDedicatedTest/scriptmodmenu.cpp
index 96789068..e1e8c7bb 100644
--- a/NorthstarDedicatedTest/scriptmodmenu.cpp
+++ b/NorthstarDedicatedTest/scriptmodmenu.cpp
@@ -1,5 +1,4 @@
#include "pch.h"
-#include "hooks.h"
#include "modmanager.h"
#include "squirrel.h"
diff --git a/NorthstarDedicatedTest/scriptserverbrowser.cpp b/NorthstarDedicatedTest/scriptserverbrowser.cpp
index 5956d0bb..e1139474 100644
--- a/NorthstarDedicatedTest/scriptserverbrowser.cpp
+++ b/NorthstarDedicatedTest/scriptserverbrowser.cpp
@@ -333,7 +333,7 @@ SQRESULT SQ_TryAuthWithServer(void* sqvm)
// do auth
g_MasterServerManager->AuthenticateWithServer(
- R2::g_LocalPlayerUserID,
+ R2::g_pLocalPlayerUserID,
g_MasterServerManager->m_sOwnClientAuthToken,
g_MasterServerManager->m_vRemoteServers[serverIndex].id,
(char*)password);
@@ -391,7 +391,7 @@ SQRESULT SQ_ConnectToAuthedServer(void* sqvm)
SQRESULT SQ_TryAuthWithLocalServer(void* sqvm)
{
// do auth request
- g_MasterServerManager->AuthenticateWithOwnServer(R2::g_LocalPlayerUserID, g_MasterServerManager->m_sOwnClientAuthToken);
+ g_MasterServerManager->AuthenticateWithOwnServer(R2::g_pLocalPlayerUserID, g_MasterServerManager->m_sOwnClientAuthToken);
return SQRESULT_NULL;
}
diff --git a/NorthstarDedicatedTest/scriptservertoclientstringcommand.cpp b/NorthstarDedicatedTest/scriptservertoclientstringcommand.cpp
index 26660c27..3bb7f60d 100644
--- a/NorthstarDedicatedTest/scriptservertoclientstringcommand.cpp
+++ b/NorthstarDedicatedTest/scriptservertoclientstringcommand.cpp
@@ -1,5 +1,4 @@
#include "pch.h"
-#include "hooks.h"
#include "squirrel.h"
#include "convar.h"
#include "concommand.h"
diff --git a/NorthstarDedicatedTest/scriptsrson.cpp b/NorthstarDedicatedTest/scriptsrson.cpp
index 6de78d12..d7df84e8 100644
--- a/NorthstarDedicatedTest/scriptsrson.cpp
+++ b/NorthstarDedicatedTest/scriptsrson.cpp
@@ -12,7 +12,7 @@ void ModManager::BuildScriptsRson()
fs::path MOD_SCRIPTS_RSON_PATH = fs::path(GetCompiledAssetsPath() / MOD_SCRIPTS_RSON_SUFFIX);
fs::remove(MOD_SCRIPTS_RSON_PATH);
- std::string scriptsRson = R2FS::ReadVPKOriginalFile(VPK_SCRIPTS_RSON_PATH);
+ std::string scriptsRson = R2::ReadVPKOriginalFile(VPK_SCRIPTS_RSON_PATH);
scriptsRson += "\n\n// START MODDED SCRIPT CONTENT\n\n"; // newline before we start custom stuff
for (Mod& mod : m_loadedMods)
diff --git a/NorthstarDedicatedTest/serverauthentication.cpp b/NorthstarDedicatedTest/serverauthentication.cpp
index a8de1a63..efecd692 100644
--- a/NorthstarDedicatedTest/serverauthentication.cpp
+++ b/NorthstarDedicatedTest/serverauthentication.cpp
@@ -21,8 +21,6 @@
#include <filesystem>
#include <thread>
-using namespace Tier0;
-
const char* AUTHSERVER_VERIFY_STRING = "I am a northstar server!";
// global vars
@@ -161,7 +159,7 @@ bool ServerAuthenticationManager::AuthenticatePlayer(void* player, int64_t uid,
strcpy((char*)player + 0xF500, strUid.c_str());
// reset from disk if we're doing that
- if (m_bForceReadLocalPlayerPersistenceFromDisk && !strcmp(authData.uid, R2::g_LocalPlayerUserID))
+ if (m_bForceReadLocalPlayerPersistenceFromDisk && !strcmp(authData.uid, R2::g_pLocalPlayerUserID))
{
std::fstream pdataStream(GetNorthstarPrefix() + "/placeholder_playerdata.pdata", std::ios_base::in);
@@ -230,7 +228,7 @@ bool ServerAuthenticationManager::RemovePlayerAuthData(void* player)
return false;
// hack for special case where we're on a local server, so we erase our own newly created auth data on disconnect
- if (m_bNeedLocalAuthForNewgame && !strcmp((char*)player + 0xF500, R2::g_LocalPlayerUserID))
+ if (m_bNeedLocalAuthForNewgame && !strcmp((char*)player + 0xF500, R2::g_pLocalPlayerUserID))
return false;
// we don't have our auth token at this point, so lookup authdata by uid
@@ -267,9 +265,9 @@ void ServerAuthenticationManager::WritePersistentData(void* player)
bool ServerAuthenticationManager::CheckPlayerChatRatelimit(void* player)
{
- if (Plat_FloatTime() - m_additionalPlayerData[player].lastSayTextLimitStart >= 1.0)
+ if (Tier0::Plat_FloatTime() - m_additionalPlayerData[player].lastSayTextLimitStart >= 1.0)
{
- m_additionalPlayerData[player].lastSayTextLimitStart = Plat_FloatTime();
+ m_additionalPlayerData[player].lastSayTextLimitStart = Tier0::Plat_FloatTime();
m_additionalPlayerData[player].sayTextLimitCount = 0;
}
@@ -432,10 +430,10 @@ char CGameClient__ExecuteStringCommandHook(void* self, uint32_t unknown, const c
{
// note: this isn't super perfect, legit clients can trigger it in lobby, mostly good enough tho imo
// https://github.com/perilouswithadollarsign/cstrike15_src/blob/f82112a2388b841d72cb62ca48ab1846dfcc11c8/engine/sv_client.cpp#L1513
- if (Plat_FloatTime() - g_ServerAuthenticationManager->m_additionalPlayerData[self].lastClientCommandQuotaStart >= 1.0)
+ if (Tier0::Plat_FloatTime() - g_ServerAuthenticationManager->m_additionalPlayerData[self].lastClientCommandQuotaStart >= 1.0)
{
// reset quota
- g_ServerAuthenticationManager->m_additionalPlayerData[self].lastClientCommandQuotaStart = Plat_FloatTime();
+ g_ServerAuthenticationManager->m_additionalPlayerData[self].lastClientCommandQuotaStart = Tier0::Plat_FloatTime();
g_ServerAuthenticationManager->m_additionalPlayerData[self].numClientCommandsInQuota = 0;
}
@@ -457,7 +455,7 @@ char CGameClient__ExecuteStringCommandHook(void* self, uint32_t unknown, const c
if (!CCommand__Tokenize(tempCommand, pCommandString, R2::cmd_source_t::kCommandSrcCode) || !tempCommand.ArgC())
return false;
- ConCommand* command = g_pCVar->FindCommand(tempCommand.Arg(0));
+ ConCommand* command = R2::g_pCVar->FindCommand(tempCommand.Arg(0));
// if the command doesn't exist pass it on to ExecuteStringCommand for script clientcommands and stuff
if (command && !command->IsFlagSet(FCVAR_CLIENTCMD_CAN_EXECUTE))
@@ -466,11 +464,10 @@ char CGameClient__ExecuteStringCommandHook(void* self, uint32_t unknown, const c
if (IsDedicatedServer())
return false;
- if (strcmp((char*)self + 0xF500, R2::g_LocalPlayerUserID))
+ if (strcmp((char*)self + 0xF500, R2::g_pLocalPlayerUserID))
return false;
}
- // todo later, basically just limit to CVar_sv_quota_stringcmdspersecond->GetInt() stringcmds per client per second
return CGameClient__ExecuteStringCommand(self, unknown, pCommandString);
}
@@ -478,11 +475,11 @@ typedef char (*__fastcall CNetChan___ProcessMessagesType)(void* self, void* buf)
CNetChan___ProcessMessagesType CNetChan___ProcessMessages;
char __fastcall CNetChan___ProcessMessagesHook(void* self, void* buf)
{
- double startTime = Plat_FloatTime();
+ double startTime = Tier0::Plat_FloatTime();
char ret = CNetChan___ProcessMessages(self, buf);
// check processing limits, unless we're in a level transition
- if (R2::g_pHostState->m_iCurrentState == R2::HostState_t::HS_RUN && ThreadInServerFrameThread())
+ if (R2::g_pHostState->m_iCurrentState == R2::HostState_t::HS_RUN && Tier0::ThreadInServerFrameThread())
{
// player that sent the message
void* sender = *(void**)((char*)self + 368);
@@ -500,7 +497,7 @@ char __fastcall CNetChan___ProcessMessagesHook(void* self, void* buf)
g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime = 0.0;
}
g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime +=
- (Plat_FloatTime() * 1000) - (startTime * 1000);
+ (Tier0::Plat_FloatTime() * 1000) - (startTime * 1000);
if (g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime >=
Cvar_net_chan_limit_msec_per_sec->GetInt())
@@ -512,7 +509,7 @@ char __fastcall CNetChan___ProcessMessagesHook(void* self, void* buf)
Cvar_net_chan_limit_msec_per_sec->GetInt());
// nonzero = kick, 0 = warn, but never kick local player
- if (Cvar_net_chan_limit_mode->GetInt() && strcmp(R2::g_LocalPlayerUserID, (char*)sender + 0xF500))
+ if (Cvar_net_chan_limit_mode->GetInt() && strcmp(R2::g_pLocalPlayerUserID, (char*)sender + 0xF500))
{
CBaseClient__Disconnect(sender, 1, "Exceeded net channel processing limit");
return false;
@@ -560,12 +557,12 @@ bool ProcessConnectionlessPacketHook(void* a1, netpacket_t* packet)
memcpy(sendData->ip, packet->adr.ip, 16);
}
- if (Plat_FloatTime() < sendData->timeoutEnd)
+ if (Tier0::Plat_FloatTime() < sendData->timeoutEnd)
return false;
- if (Plat_FloatTime() - sendData->lastQuotaStart >= 1.0)
+ if (Tier0::Plat_FloatTime() - sendData->lastQuotaStart >= 1.0)
{
- sendData->lastQuotaStart = Plat_FloatTime();
+ sendData->lastQuotaStart = Tier0::Plat_FloatTime();
sendData->packetCount = 0;
}
@@ -579,7 +576,7 @@ bool ProcessConnectionlessPacketHook(void* a1, netpacket_t* packet)
packet->data[4]);
// timeout for a minute
- sendData->timeoutEnd = Plat_FloatTime() + 60.0;
+ sendData->timeoutEnd = Tier0::Plat_FloatTime() + 60.0;
return false;
}
}
@@ -630,7 +627,7 @@ ON_DLL_LOAD_RELIESON("engine.dll", ServerAuthentication, ConCommand, [](HMODULE
Cvar_sv_querylimit_per_sec = new ConVar("sv_querylimit_per_sec", "15", FCVAR_GAMEDLL, "");
Cvar_sv_max_chat_messages_per_sec = new ConVar("sv_max_chat_messages_per_sec", "5", FCVAR_GAMEDLL, "");
- Cvar_net_datablock_enabled = g_pCVar->FindVar("net_datablock_enabled");
+ Cvar_net_datablock_enabled = R2::g_pCVar->FindVar("net_datablock_enabled");
RegisterConCommand(
"ns_resetpersistence", ConCommand_ns_resetpersistence, "resets your pdata when you next enter the lobby", FCVAR_NONE);
diff --git a/NorthstarDedicatedTest/serverchathooks.cpp b/NorthstarDedicatedTest/serverchathooks.cpp
index b2fd7111..145d691e 100644
--- a/NorthstarDedicatedTest/serverchathooks.cpp
+++ b/NorthstarDedicatedTest/serverchathooks.cpp
@@ -1,13 +1,14 @@
#include "pch.h"
#include "serverchathooks.h"
-#include "hooks.h"
-#include <rapidjson/document.h>
-#include <rapidjson/stringbuffer.h>
-#include <rapidjson/writer.h>
#include "serverauthentication.h"
#include "squirrel.h"
#include "miscserverscript.h"
+#include <rapidjson/document.h>
+#include <rapidjson/stringbuffer.h>
+#include <rapidjson/writer.h>
+
+
class CServerGameDLL;
class CBasePlayer;
diff --git a/NorthstarDedicatedTest/sourceconsole.cpp b/NorthstarDedicatedTest/sourceconsole.cpp
index e6035ac5..7627a2f1 100644
--- a/NorthstarDedicatedTest/sourceconsole.cpp
+++ b/NorthstarDedicatedTest/sourceconsole.cpp
@@ -1,10 +1,9 @@
#include "pch.h"
-#include "hooks.h"
#include "convar.h"
#include "sourceconsole.h"
#include "sourceinterface.h"
#include "concommand.h"
-#include "commandprint.h"
+#include "printcommand.h"
SourceInterface<CGameConsole>* g_SourceGameConsole;
diff --git a/NorthstarDedicatedTest/sourceinterface.cpp b/NorthstarDedicatedTest/sourceinterface.cpp
index 2ed3f592..05e83856 100644
--- a/NorthstarDedicatedTest/sourceinterface.cpp
+++ b/NorthstarDedicatedTest/sourceinterface.cpp
@@ -1,7 +1,5 @@
#include "pch.h"
#include "sourceinterface.h"
-#include "hooks.h"
-#include "hookutils.h"
#include "sourceconsole.h"
// really wanted to do a modular callback system here but honestly couldn't be bothered so hardcoding stuff for now: todo later
diff --git a/NorthstarDedicatedTest/squirrel.h b/NorthstarDedicatedTest/squirrel.h
index c654a599..9d55d8a1 100644
--- a/NorthstarDedicatedTest/squirrel.h
+++ b/NorthstarDedicatedTest/squirrel.h
@@ -162,7 +162,7 @@ template <ScriptContext context> class SquirrelManager
if (compileResult != SQRESULT_ERROR)
{
pushroottable(sqvm2);
- SQRESULT callResult = call(sqvm2, 1);
+ SQRESULT callResult = call(sqvm2, 0);
spdlog::info("sq_call returned {}", callResult);
}
}