From cc7b0ded08e3dc26fc970169a79c74c54e4f923b Mon Sep 17 00:00:00 2001
From: BobTheBob <32057864+BobTheBob9@users.noreply.github.com>
Date: Thu, 26 May 2022 03:16:46 +0100
Subject: lots of cleanup and starting moving to new hooking macros
---
LauncherInjector/LauncherInjector.vcxproj | 6 +
LauncherInjector/main.cpp | 17 +-
NorthstarDedicatedTest/ExploitFixes.cpp | 3 +-
.../NorthstarDedicatedTest.vcxproj | 8 +-
.../NorthstarDedicatedTest.vcxproj.filters | 8 +-
NorthstarDedicatedTest/audio.cpp | 74 ++++----
NorthstarDedicatedTest/bansystem.cpp | 4 +-
NorthstarDedicatedTest/buildainfile.cpp | 31 +---
NorthstarDedicatedTest/chatcommand.cpp | 1 -
NorthstarDedicatedTest/clientauthhooks.cpp | 20 +--
NorthstarDedicatedTest/clientchathooks.cpp | 21 +--
NorthstarDedicatedTest/clientruihooks.cpp | 1 -
NorthstarDedicatedTest/clientvideooverrides.cpp | 1 -
NorthstarDedicatedTest/commandprint.cpp | 161 -----------------
NorthstarDedicatedTest/commandprint.h | 6 -
NorthstarDedicatedTest/concommand.cpp | 4 +-
NorthstarDedicatedTest/concommand.h | 2 +-
NorthstarDedicatedTest/convar.cpp | 6 +-
NorthstarDedicatedTest/cvar.cpp | 8 +-
NorthstarDedicatedTest/cvar.h | 8 +-
NorthstarDedicatedTest/debugoverlay.cpp | 1 -
NorthstarDedicatedTest/dedicated.cpp | 49 +++--
NorthstarDedicatedTest/dedicatedmaterialsystem.cpp | 2 -
NorthstarDedicatedTest/demofixes.cpp | 6 +-
NorthstarDedicatedTest/dllmain.cpp | 1 -
NorthstarDedicatedTest/filesystem.cpp | 15 +-
NorthstarDedicatedTest/filesystem.h | 5 +-
NorthstarDedicatedTest/hooks.cpp | 198 ++++++++++----------
NorthstarDedicatedTest/hooks.h | 199 +++++++++++++++++++--
NorthstarDedicatedTest/host.cpp | 30 ++--
NorthstarDedicatedTest/keyvalues.cpp | 4 +-
NorthstarDedicatedTest/languagehooks.cpp | 2 +-
NorthstarDedicatedTest/latencyflex.cpp | 2 -
NorthstarDedicatedTest/localchatwriter.cpp | 1 -
NorthstarDedicatedTest/logging.cpp | 2 -
NorthstarDedicatedTest/mapsprint.cpp | 172 ------------------
NorthstarDedicatedTest/mapsprint.h | 2 -
NorthstarDedicatedTest/maxplayers.cpp | 1 -
NorthstarDedicatedTest/miscclientfixes.cpp | 2 -
NorthstarDedicatedTest/misccommands.cpp | 2 +-
NorthstarDedicatedTest/miscserverfixes.cpp | 2 -
NorthstarDedicatedTest/miscserverscript.cpp | 2 +-
NorthstarDedicatedTest/modlocalisation.cpp | 11 +-
NorthstarDedicatedTest/modmanager.cpp | 12 +-
NorthstarDedicatedTest/pdef.cpp | 4 +-
NorthstarDedicatedTest/playlist.cpp | 52 +++---
NorthstarDedicatedTest/playlist.h | 2 +-
NorthstarDedicatedTest/plugins.cpp | 4 +-
NorthstarDedicatedTest/printcommand.h | 6 +
NorthstarDedicatedTest/printcommands.cpp | 161 +++++++++++++++++
NorthstarDedicatedTest/printmaps.cpp | 169 +++++++++++++++++
NorthstarDedicatedTest/printmaps.h | 2 +
NorthstarDedicatedTest/r2client.cpp | 8 +-
NorthstarDedicatedTest/r2client.h | 4 +-
NorthstarDedicatedTest/rpakfilesystem.cpp | 2 -
NorthstarDedicatedTest/scriptbrowserhooks.cpp | 21 +--
NorthstarDedicatedTest/scriptmainmenupromos.cpp | 1 -
NorthstarDedicatedTest/scriptmodmenu.cpp | 1 -
NorthstarDedicatedTest/scriptserverbrowser.cpp | 4 +-
.../scriptservertoclientstringcommand.cpp | 1 -
NorthstarDedicatedTest/scriptsrson.cpp | 2 +-
NorthstarDedicatedTest/serverauthentication.cpp | 37 ++--
NorthstarDedicatedTest/serverchathooks.cpp | 9 +-
NorthstarDedicatedTest/sourceconsole.cpp | 3 +-
NorthstarDedicatedTest/sourceinterface.cpp | 2 -
NorthstarDedicatedTest/squirrel.h | 2 +-
66 files changed, 872 insertions(+), 738 deletions(-)
delete mode 100644 NorthstarDedicatedTest/commandprint.cpp
delete mode 100644 NorthstarDedicatedTest/commandprint.h
delete mode 100644 NorthstarDedicatedTest/mapsprint.cpp
delete mode 100644 NorthstarDedicatedTest/mapsprint.h
create mode 100644 NorthstarDedicatedTest/printcommand.h
create mode 100644 NorthstarDedicatedTest/printcommands.cpp
create mode 100644 NorthstarDedicatedTest/printmaps.cpp
create mode 100644 NorthstarDedicatedTest/printmaps.h
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 @@
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)
8000000
+
+ copy /Y "$(TargetPath)" "D:\origin\titanfall\Titanfall2"
+
@@ -85,6 +88,9 @@
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)
8000000
+
+ copy /Y "$(TargetPath)" "D:\origin\titanfall\Titanfall2"
+
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, "")); // 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 @@
-
+
-
+
@@ -585,7 +585,7 @@
-
+
@@ -603,7 +603,7 @@
-
+
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 @@
Header Files\Server\Dedicated
-
+
Header Files\Shared\Console
-
+
Header Files\Shared\Console
@@ -1652,13 +1652,13 @@
Source Files\Server\Scripted
-
+
Source Files\Shared\Console
Source Files\Client
-
+
Source Files\Shared\Console
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
#include
#include
#include
-#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 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_ptrsecond;
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(&LoadSampleMetadata_Original));
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x57DAD0, &MilesLog_Hook, reinterpret_cast(&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
#include "configurables.h"
+#include
+
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
#include
#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(&CAI_NetworkBuilder__Build));
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x3933A0, &LoadAINFileHook, reinterpret_cast(&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(&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
#include "squirrel.h"
#include "serverchathooks.h"
#include "localchatwriter.h"
-struct ChatTags
-{
- bool whisper;
- bool team;
- bool dead;
-};
+#include
-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(&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/commandprint.cpp b/NorthstarDedicatedTest/commandprint.cpp
deleted file mode 100644
index 5d78a1b4..00000000
--- a/NorthstarDedicatedTest/commandprint.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-#include "pch.h"
-#include "commandprint.h"
-#include "convar.h"
-#include "concommand.h"
-
-void PrintCommandHelpDialogue(const ConCommandBase* command, const char* name)
-{
- if (!command)
- {
- spdlog::info("unknown command {}", name);
- return;
- }
-
- // build string for flags if not FCVAR_NONE
- std::string flagString;
- if (command->GetFlags() != FCVAR_NONE)
- {
- flagString = "( ";
-
- for (auto& flagPair : g_PrintCommandFlags)
- {
- if (command->GetFlags() & flagPair.first)
- {
- flagString += flagPair.second;
- flagString += " ";
- }
- }
-
- flagString += ") ";
- }
-
- // temp because command->IsCommand does not currently work
- ConVar* cvar = g_pCVar->FindVar(command->m_pszName);
- if (cvar)
- spdlog::info("\"{}\" = \"{}\" {}- {}", cvar->GetBaseName(), cvar->GetString(), flagString, cvar->GetHelpText());
- else
- spdlog::info("\"{}\" {} - {}", command->m_pszName, flagString, command->GetHelpText());
-}
-
-void TryPrintCvarHelpForCommand(const char* pCommand)
-{
- // try to display help text for an inputted command string from the console
- int pCommandLen = strlen(pCommand);
- char* pCvarStr = new char[pCommandLen];
- strcpy(pCvarStr, pCommand);
-
- // trim whitespace from right
- for (int i = pCommandLen - 1; i; i--)
- {
- if (isspace(pCvarStr[i]))
- pCvarStr[i] = '\0';
- else
- break;
- }
-
- // check if we're inputting a cvar, but not setting it at all
- ConVar* cvar = g_pCVar->FindVar(pCvarStr);
- if (cvar)
- PrintCommandHelpDialogue(&cvar->m_ConCommandBase, pCvarStr);
-
- delete[] pCvarStr;
-}
-
-void ConCommand_help(const CCommand& arg)
-{
- if (arg.ArgC() < 2)
- {
- spdlog::info("Usage: help ");
- return;
- }
-
- PrintCommandHelpDialogue(g_pCVar->FindCommandBase(arg.Arg(1)), arg.Arg(1));
-}
-
-void ConCommand_find(const CCommand& arg)
-{
- if (arg.ArgC() < 2)
- {
- spdlog::info("Usage: find [...]");
- return;
- }
-
- char pTempName[256];
- char pTempSearchTerm[256];
-
- for (auto& map : g_pCVar->DumpToMap())
- {
- bool bPrintCommand = true;
- for (int i = 0; i < arg.ArgC() - 1; i++)
- {
- // make lowercase to avoid case sensitivity
- strncpy(pTempName, map.second->m_pszName, sizeof(pTempName));
- strncpy(pTempSearchTerm, arg.Arg(i + 1), sizeof(pTempSearchTerm));
-
- for (int i = 0; pTempName[i]; i++)
- pTempName[i] = tolower(pTempName[i]);
-
- for (int i = 0; pTempSearchTerm[i]; i++)
- pTempSearchTerm[i] = tolower(pTempSearchTerm[i]);
-
- if (!strstr(pTempName, pTempSearchTerm))
- {
- bPrintCommand = false;
- break;
- }
- }
-
- if (bPrintCommand)
- PrintCommandHelpDialogue(map.second, map.second->m_pszName);
- }
-}
-
-void ConCommand_findflags(const CCommand& arg)
-{
- if (arg.ArgC() < 2)
- {
- spdlog::info("Usage: findflags ");
- for (auto& flagPair : g_PrintCommandFlags)
- spdlog::info(" - {}", flagPair.second);
-
- return;
- }
-
- // convert input flag to uppercase
- char* upperFlag = new char[strlen(arg.Arg(1))];
- strcpy(upperFlag, arg.Arg(1));
-
- for (int i = 0; upperFlag[i]; i++)
- upperFlag[i] = toupper(upperFlag[i]);
-
- // resolve flag name => int flags
- int resolvedFlag = FCVAR_NONE;
- for (auto& flagPair : g_PrintCommandFlags)
- {
- if (!strcmp(flagPair.second, upperFlag))
- {
- resolvedFlag = flagPair.first;
- break;
- }
- }
-
- // print cvars
- for (auto& map : g_pCVar->DumpToMap())
- {
- if (map.second->m_nFlags & resolvedFlag)
- PrintCommandHelpDialogue(map.second, map.second->m_pszName);
- }
-
- delete[] upperFlag;
-}
-
-void InitialiseCommandPrint()
-{
- RegisterConCommand("find", ConCommand_find, "Find concommands with the specified string in their name/help text.", FCVAR_NONE);
- 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");
- helpCommand->m_nFlags = FCVAR_NONE;
- helpCommand->m_pCommandCallback = ConCommand_help;
-}
\ No newline at end of file
diff --git a/NorthstarDedicatedTest/commandprint.h b/NorthstarDedicatedTest/commandprint.h
deleted file mode 100644
index 6c3ef850..00000000
--- a/NorthstarDedicatedTest/commandprint.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#pragma once
-#include "concommand.h"
-
-void PrintCommandHelpDialogue(const ConCommandBase* command, const char* name);
-void TryPrintCvarHelpForCommand(const char* pCommand);
-void InitialiseCommandPrint();
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
//-----------------------------------------------------------------------------
@@ -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("vstdlib.dll", "VEngineCvar007");
- g_pCVar = *g_pCVarInterface;
+ R2::g_pCVarInterface = new SourceInterface("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 CCvar::DumpToMap()
return allConVars;
}
-SourceInterface* g_pCVarInterface;
-CCvar* g_pCVar;
\ No newline at end of file
+// use the R2 namespace for game funcs
+namespace R2
+{
+ SourceInterface* 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 DumpToMap();
};
-extern SourceInterface* g_pCVarInterface;
-extern CCvar* g_pCVar;
+// use the R2 namespace for game funcs
+namespace R2
+{
+ extern SourceInterface* 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>(
- 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
#include
-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* 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* 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("filesystem_stdio.dll", "VFileSystem017");
+ R2::g_pFilesystem = new SourceInterface("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* 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
@@ -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& GetDllLoadCallbacks()
+{
+ static std::vector vec = std::vector();
+ 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& GetDllLoadCallbacks()
-{
- static std::vector vec = std::vector();
- 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 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(&GetCommandLineAOriginal));
- ENABLER_CREATEHOOK(hook, &LoadLibraryExA, &LoadLibraryExAHook, reinterpret_cast(&LoadLibraryExAOriginal));
- ENABLER_CREATEHOOK(hook, &LoadLibraryA, &LoadLibraryAHook, reinterpret_cast(&LoadLibraryAOriginal));
- ENABLER_CREATEHOOK(hook, &LoadLibraryExW, &LoadLibraryExWHook, reinterpret_cast(&LoadLibraryExWOriginal));
- ENABLER_CREATEHOOK(hook, &LoadLibraryW, &LoadLibraryWHook, reinterpret_cast(&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 varName = ManualHook(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
@@ -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
#include
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
diff --git a/NorthstarDedicatedTest/mapsprint.cpp b/NorthstarDedicatedTest/mapsprint.cpp
deleted file mode 100644
index bf94c548..00000000
--- a/NorthstarDedicatedTest/mapsprint.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-#include "pch.h"
-#include "mapsprint.h"
-#include "convar.h"
-#include "concommand.h"
-#include "modmanager.h"
-#include "tier0.h"
-#include
-#include
-
-enum class MapSource_t
-{
- VPK,
- GAMEDIR,
- MOD
-};
-
-const std::unordered_map PrintMapSource = {
- {MapSource_t::VPK, "VPK"},
- {MapSource_t::MOD, "MOD"},
- {MapSource_t::GAMEDIR, "R2"}
-};
-
-struct MapVPKInfo
-{
- std::string name;
- std::string parent;
- MapSource_t source;
-};
-
-// our current list of maps in the game
-std::vector vMapList;
-
-void RefreshMapList()
-{
- vMapList.clear();
-
- // get modded maps
- // TODO: could probably check mod vpks to get mapnames from there too?
- 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
- {
- MapVPKInfo& map = vMapList.emplace_back();
- map.name = file.path.stem().string();
- map.parent = file.owningMod->Name;
- map.source = MapSource_t::MOD;
- }
- }
-
- // get maps in vpk
- {
- const int iNumRetailNonMapVpks = 1;
- static const char* 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
- static const std::regex rVpkMapRegex("englishclient_([a-zA-Z_]+)\\.bsp\\.pak000_dir\\.vpk", std::regex::icase);
-
- for (fs::directory_entry file : fs::directory_iterator("./vpk"))
- {
- std::string pathString = file.path().filename().string();
-
- bool bIsValidMapVpk = true;
- for (int i = 0; i < iNumRetailNonMapVpks; i++)
- {
- if (!pathString.compare(ppRetailNonMapVpks[i]))
- {
- bIsValidMapVpk = false;
- break;
- }
- }
-
- if (!bIsValidMapVpk)
- continue;
-
- // run our map vpk regex on the filename
- std::smatch match;
- std::regex_match(pathString, match, rVpkMapRegex);
-
- if (match.length() < 2)
- continue;
-
- std::string mapName = match[1].str();
- // special case: englishclient_mp_common contains mp_lobby, so hardcode the name here
- if (mapName == "mp_common")
- mapName = "mp_lobby";
-
- MapVPKInfo& map = vMapList.emplace_back();
- map.name = mapName;
- map.parent = pathString;
- map.source = MapSource_t::VPK;
- }
- }
-
- // get maps in game dir
- for (fs::directory_entry file : fs::directory_iterator("./r2/maps"))
- {
- if (file.path().extension() == ".bsp")
- {
- MapVPKInfo& map = vMapList.emplace_back();
- map.name = file.path().stem().string();
- map.parent = "R2";
- map.source = MapSource_t::GAMEDIR;
- }
- }
-}
-
-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])
-{
- // 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();
- flLastAutocompleteRefresh = Tier0::Plat_FloatTime();
- }
-
- // use a custom autocomplete func for all map loading command
- const int cmdLength = strlen(cmdname);
- const char* query = partial + cmdLength;
- const int queryLength = strlen(query);
-
- int numMaps = 0;
- for (int i = 0; i < COMMAND_COMPLETION_MAXITEMS && i < vMapList.size(); i++)
- {
- if (!strncmp(query, vMapList[i].name.c_str(), queryLength))
- {
- strcpy(commands[numMaps], cmdname);
- strncpy_s(
- commands[numMaps++] + cmdLength,
- COMMAND_COMPLETION_ITEM_LENGTH, &vMapList[i].name[0],
- COMMAND_COMPLETION_ITEM_LENGTH - cmdLength);
- }
- }
-
- return numMaps;
-}
-
-void ConCommand_maps(const CCommand& args)
-{
- if (args.ArgC() < 2)
- {
- spdlog::info("Usage: maps ");
- spdlog::info("maps * for full listing");
- return;
- }
-
- RefreshMapList();
-
- for (MapVPKInfo& map : vMapList) // need to figure out a nice way to include parent path without making the formatting awful
- if ((*args.Arg(1) == '*' && !args.Arg(1)[1]) || strstr(map.name.c_str(), args.Arg(1)))
- spdlog::info("({}) {}", PrintMapSource.at(map.source), map.name);
-}
-
-void InitialiseMapsPrint()
-{
- ConCommand* mapsCommand = g_pCVar->FindCommand("maps");
- mapsCommand->m_pCommandCallback = ConCommand_maps;
-
- HookEnabler hook;
- ENABLER_CREATEHOOK(
- hook,
- (char*)GetModuleHandleA("engine.dll") + 0x161AE0,
- &_Host_Map_f_CompletionFuncHook,
- reinterpret_cast(&_Host_Map_f_CompletionFunc));
-}
\ No newline at end of file
diff --git a/NorthstarDedicatedTest/mapsprint.h b/NorthstarDedicatedTest/mapsprint.h
deleted file mode 100644
index b01761c0..00000000
--- a/NorthstarDedicatedTest/mapsprint.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#pragma once
-void InitialiseMapsPrint();
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
#include
#include
-#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