aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NorthstarDedicatedTest/ExploitFixes.cpp3
-rw-r--r--NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj2
-rw-r--r--NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters18
-rw-r--r--NorthstarDedicatedTest/dedicated.cpp10
-rw-r--r--NorthstarDedicatedTest/dedicatedmaterialsystem.cpp3
-rw-r--r--NorthstarDedicatedTest/dllmain.cpp19
-rw-r--r--NorthstarDedicatedTest/gameutils.cpp58
-rw-r--r--NorthstarDedicatedTest/gameutils.h85
-rw-r--r--NorthstarDedicatedTest/languagehooks.cpp3
-rw-r--r--NorthstarDedicatedTest/masterserver.cpp32
-rw-r--r--NorthstarDedicatedTest/maxplayers.cpp3
-rw-r--r--NorthstarDedicatedTest/memalloc.cpp20
-rw-r--r--NorthstarDedicatedTest/misccommands.cpp3
-rw-r--r--NorthstarDedicatedTest/modmanager.cpp2
-rw-r--r--NorthstarDedicatedTest/pch.h1
-rw-r--r--NorthstarDedicatedTest/playlist.cpp62
-rw-r--r--NorthstarDedicatedTest/playlist.h16
-rw-r--r--NorthstarDedicatedTest/rpakfilesystem.cpp10
-rw-r--r--NorthstarDedicatedTest/rpakfilesystem.h2
-rw-r--r--NorthstarDedicatedTest/serverauthentication.cpp3
-rw-r--r--NorthstarDedicatedTest/serverchathooks.cpp2
-rw-r--r--NorthstarDedicatedTest/tier0.cpp37
-rw-r--r--NorthstarDedicatedTest/tier0.h68
23 files changed, 230 insertions, 232 deletions
diff --git a/NorthstarDedicatedTest/ExploitFixes.cpp b/NorthstarDedicatedTest/ExploitFixes.cpp
index 257ec428..cc42ab73 100644
--- a/NorthstarDedicatedTest/ExploitFixes.cpp
+++ b/NorthstarDedicatedTest/ExploitFixes.cpp
@@ -5,6 +5,7 @@
#include "hooks.h"
#include "NSMem.h"
#include "cvar.h"
+#include "tier0.h"
ConVar* ns_exploitfixes_log;
#define SHOULD_LOG (ns_exploitfixes_log->m_Value.m_nValue > 0)
@@ -324,7 +325,7 @@ INVALID_CMD:
#include "gameutils.h"
KHOOK(IsValveMod, ("engine.dll", "48 83 EC 28 48 8B 0D ? ? ? ? 48 8D 15 ? ? ? ? E8 ? ? ? ? 85 C0 74 63"), bool, __fastcall, ())
{
- return !CommandLine()->CheckParm("-norestrictservercommands");
+ return !Tier0::CommandLine()->CheckParm("-norestrictservercommands");
}
// Fix respawn's crappy UTF8 parser so it doesn't crash -_-
diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj
index 1125b87e..c523534a 100644
--- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj
+++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj
@@ -570,6 +570,7 @@
<ClInclude Include="ExploitFixes.h" />
<ClInclude Include="ExploitFixes_UTF8Parser.h" />
<ClInclude Include="NSMem.h" />
+ <ClInclude Include="tier0.h" />
<ClInclude Include="version.h" />
</ItemGroup>
<ItemGroup>
@@ -629,6 +630,7 @@
<ClCompile Include="sourceinterface.cpp" />
<ClCompile Include="squirrel.cpp" />
<ClCompile Include="ExploitFixes.cpp" />
+ <ClCompile Include="tier0.cpp" />
<ClCompile Include="version.cpp" />
</ItemGroup>
<ItemGroup>
diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters
index eb4f2a5c..1cb6cadd 100644
--- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters
+++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters
@@ -582,9 +582,6 @@
<ClInclude Include="modlocalisation.h">
<Filter>Header Files\Client</Filter>
</ClInclude>
- <ClInclude Include="playlist.h">
- <Filter>Header Files\Server</Filter>
- </ClInclude>
<ClInclude Include="dedicatedmaterialsystem.h">
<Filter>Header Files\Dedicated</Filter>
</ClInclude>
@@ -1509,6 +1506,12 @@
<ClInclude Include="ns_version.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="playlist.h">
+ <Filter>Header Files\Shared</Filter>
+ </ClInclude>
+ <ClInclude Include="tier0.h">
+ <Filter>Header Files\Shared\Game Functions</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
@@ -1580,9 +1583,6 @@
<ClCompile Include="modlocalisation.cpp">
<Filter>Source Files\Client</Filter>
</ClCompile>
- <ClCompile Include="playlist.cpp">
- <Filter>Source Files\Server</Filter>
- </ClCompile>
<ClCompile Include="dedicatedmaterialsystem.cpp">
<Filter>Source Files\Server\Dedicated</Filter>
</ClCompile>
@@ -1673,6 +1673,12 @@
<ClCompile Include="clientruihooks.cpp">
<Filter>Source Files\Client</Filter>
</ClCompile>
+ <ClCompile Include="playlist.cpp">
+ <Filter>Source Files\Shared</Filter>
+ </ClCompile>
+ <ClCompile Include="tier0.cpp">
+ <Filter>Source Files\Shared\Game Functions</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<MASM Include="audio_asm.asm">
diff --git a/NorthstarDedicatedTest/dedicated.cpp b/NorthstarDedicatedTest/dedicated.cpp
index 9430b7a6..89896195 100644
--- a/NorthstarDedicatedTest/dedicated.cpp
+++ b/NorthstarDedicatedTest/dedicated.cpp
@@ -3,9 +3,13 @@
#include "dedicated.h"
#include "hookutils.h"
#include "gameutils.h"
+#include "tier0.h"
+#include "playlist.h"
#include "serverauthentication.h"
#include "masterserver.h"
+using namespace Tier0;
+
bool IsDedicated()
{
static bool result = strstr(GetCommandLineA(), "-dedicated");
@@ -55,7 +59,7 @@ void RunServer(CDedicatedExports* dedicated)
Cbuf_Execute();
// ensure playlist initialises right, if we've not explicitly called setplaylist
- SetCurrentPlaylist(GetCurrentPlaylistName());
+ R2::SetCurrentPlaylist(R2::GetCurrentPlaylistName());
// note: we no longer manually set map and hoststate to start server in g_pHostState, we just use +map which seems to initialise stuff
// better
@@ -76,7 +80,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 = R2::GetCurrentPlaylistVar("max_players", false);
if (!maxPlayers)
maxPlayers = "6";
@@ -86,7 +90,7 @@ void RunServer(CDedicatedExports* dedicated)
g_pHostState->m_levelName,
g_ServerAuthenticationManager->m_additionalPlayerData.size(),
maxPlayers,
- GetCurrentPlaylistName())
+ R2::GetCurrentPlaylistName())
.c_str());
}
diff --git a/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp b/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp
index da6ce7d3..50f1a1b4 100644
--- a/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp
+++ b/NorthstarDedicatedTest/dedicatedmaterialsystem.cpp
@@ -5,6 +5,7 @@
#include "dedicatedmaterialsystem.h"
#include "hookutils.h"
#include "gameutils.h"
+#include "tier0.h"
#include "NSMem.h"
typedef HRESULT (*__stdcall D3D11CreateDeviceType)(
@@ -39,7 +40,7 @@ HRESULT __stdcall D3D11CreateDeviceHook(
// atm, i think the play might be to run d3d in software, and then just stub out any calls that allocate memory/use alot of resources
// (e.g. createtexture and that sorta thing)
// note: this has been succeeded by the d3d11 and gfsdk stubs, and is only being kept around for posterity and as a fallback option
- if (CommandLine()->CheckParm("-softwared3d11"))
+ if (Tier0::CommandLine()->CheckParm("-softwared3d11"))
DriverType = 5; // D3D_DRIVER_TYPE_WARP
return D3D11CreateDevice(
diff --git a/NorthstarDedicatedTest/dllmain.cpp b/NorthstarDedicatedTest/dllmain.cpp
index 01692ed4..bb6f19f3 100644
--- a/NorthstarDedicatedTest/dllmain.cpp
+++ b/NorthstarDedicatedTest/dllmain.cpp
@@ -5,6 +5,7 @@
#include "keyvalues.h"
#include "masterserver.h"
#include "gameutils.h"
+#include "tier0.h"
#include "memalloc.h"
#include "maxplayers.h"
#include "configurables.h"
@@ -38,18 +39,6 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
return TRUE;
}
-void WaitForDebugger(HMODULE baseAddress)
-{
- // earlier waitfordebugger call than is in vanilla, just so we can debug stuff a little easier
- if (CommandLine()->CheckParm("-waitfordebugger"))
- {
- spdlog::info("waiting for debugger...");
-
- while (!IsDebuggerPresent())
- Sleep(100);
- }
-}
-
void freeLibrary(HMODULE hLib)
{
if (!FreeLibrary(hLib))
@@ -157,12 +146,8 @@ bool LoadPlugins()
bool InitialiseNorthstar()
{
static bool bInitialised = false;
-
if (bInitialised)
- {
- // spdlog::warn("Called InitialiseNorthstar more than once!"); // it's actually 100% fine for that to happen
return false;
- }
bInitialised = true;
@@ -181,8 +166,6 @@ bool InitialiseNorthstar()
// Write launcher version to log
spdlog::info("NorthstarLauncher version: {}", version);
- AddDllLoadCallback("engine.dll", WaitForDebugger);
- AddDllLoadCallback("tier0.dll", InitialiseTier0GameUtilFunctions);
AddDllLoadCallback("engine.dll", InitialiseEngineGameUtilFunctions);
AddDllLoadCallback("server.dll", InitialiseServerGameUtilFunctions);
diff --git a/NorthstarDedicatedTest/gameutils.cpp b/NorthstarDedicatedTest/gameutils.cpp
index 792d8bf2..d6e5840a 100644
--- a/NorthstarDedicatedTest/gameutils.cpp
+++ b/NorthstarDedicatedTest/gameutils.cpp
@@ -2,11 +2,6 @@
#include "convar.h"
#include "gameutils.h"
-// memory
-IMemAlloc* g_pMemAllocSingleton;
-typedef IMemAlloc* (*CreateGlobalMemAllocType)();
-CreateGlobalMemAllocType CreateGlobalMemAlloc;
-
// cmd.h
Cbuf_GetCurrentPlayerType Cbuf_GetCurrentPlayer;
Cbuf_AddTextType Cbuf_AddText;
@@ -19,15 +14,6 @@ CHostState* g_pHostState;
CEngine* g_pEngine;
server_state_t* sv_m_State;
-// network stuff
-ConVar* Cvar_hostport;
-
-// playlist stuff
-GetCurrentPlaylistType GetCurrentPlaylistName;
-SetCurrentPlaylistType SetCurrentPlaylist;
-SetPlaylistVarOverrideType SetPlaylistVarOverride;
-GetCurrentPlaylistVarType GetCurrentPlaylistVar;
-
// server entity stuff
Server_GetEntityByIndexType Server_GetEntityByIndex;
@@ -36,10 +22,6 @@ char* g_LocalPlayerUserID;
char* g_LocalPlayerOriginToken;
// misc stuff
-ErrorType Error;
-CommandLineType CommandLine;
-Plat_FloatTimeType Plat_FloatTime;
-ThreadInServerFrameThreadType ThreadInServerFrameThread;
GetBaseLocalClientType GetBaseLocalClient;
void InitialiseEngineGameUtilFunctions(HMODULE baseAddress)
@@ -52,11 +34,6 @@ void InitialiseEngineGameUtilFunctions(HMODULE baseAddress)
g_pEngine = *(CEngine**)((char*)baseAddress + 0x7D70C8);
sv_m_State = (server_state_t*)((char*)baseAddress + 0x12A53D48);
- GetCurrentPlaylistName = (GetCurrentPlaylistType)((char*)baseAddress + 0x18C640);
- SetCurrentPlaylist = (SetCurrentPlaylistType)((char*)baseAddress + 0x18EB20);
- SetPlaylistVarOverride = (SetPlaylistVarOverrideType)((char*)baseAddress + 0x18ED00);
- GetCurrentPlaylistVar = (GetCurrentPlaylistVarType)((char*)baseAddress + 0x18C680);
-
g_LocalPlayerUserID = (char*)baseAddress + 0x13F8E688;
g_LocalPlayerOriginToken = (char*)baseAddress + 0x13979C80;
@@ -76,44 +53,9 @@ void InitialiseEngineGameUtilFunctions(HMODULE baseAddress)
g_pAllConVars.push_back(pConVar);
}
}*/
-
- Cvar_hostport = (ConVar*)((char*)baseAddress + 0x13FA6070);
}
void InitialiseServerGameUtilFunctions(HMODULE baseAddress)
{
Server_GetEntityByIndex = (Server_GetEntityByIndexType)((char*)baseAddress + 0xFB820);
-}
-
-void InitialiseTier0GameUtilFunctions(HMODULE baseAddress)
-{
- if (!baseAddress)
- {
- spdlog::critical("tier0 base address is null, but it should be already loaded");
- throw "tier0 base address is null, but it should be already loaded";
- }
- if (g_pMemAllocSingleton)
- return; // seems this function was already called
- CreateGlobalMemAlloc = reinterpret_cast<CreateGlobalMemAllocType>(GetProcAddress(baseAddress, "CreateGlobalMemAlloc"));
- IMemAlloc** ppMemAllocSingleton = reinterpret_cast<IMemAlloc**>(GetProcAddress(baseAddress, "g_pMemAllocSingleton"));
- if (!ppMemAllocSingleton)
- {
- spdlog::critical("Address of g_pMemAllocSingleton is a null pointer, this should never happen");
- throw "Address of g_pMemAllocSingleton is a null pointer, this should never happen";
- }
- if (!*ppMemAllocSingleton)
- {
- g_pMemAllocSingleton = CreateGlobalMemAlloc();
- *ppMemAllocSingleton = g_pMemAllocSingleton;
- spdlog::info("Created new g_pMemAllocSingleton");
- }
- else
- {
- g_pMemAllocSingleton = *ppMemAllocSingleton;
- }
-
- Error = reinterpret_cast<ErrorType>(GetProcAddress(baseAddress, "Error"));
- CommandLine = reinterpret_cast<CommandLineType>(GetProcAddress(baseAddress, "CommandLine"));
- Plat_FloatTime = reinterpret_cast<Plat_FloatTimeType>(GetProcAddress(baseAddress, "Plat_FloatTime"));
- ThreadInServerFrameThread = reinterpret_cast<ThreadInServerFrameThreadType>(GetProcAddress(baseAddress, "ThreadInServerFrameThread"));
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/gameutils.h b/NorthstarDedicatedTest/gameutils.h
index 6d625c16..4d1b8fb7 100644
--- a/NorthstarDedicatedTest/gameutils.h
+++ b/NorthstarDedicatedTest/gameutils.h
@@ -1,34 +1,6 @@
#pragma once
#include "convar.h"
-// memory
-class IMemAlloc
-{
- public:
- struct VTable
- {
- void* unknown[1]; // alloc debug
- void* (*Alloc)(IMemAlloc* memAlloc, size_t nSize);
- void* unknown2[1]; // realloc debug
- void* (*Realloc)(IMemAlloc* memAlloc, void* pMem, size_t nSize);
- void* unknown3[1]; // free #1
- void (*Free)(IMemAlloc* memAlloc, void* pMem);
- void* unknown4[2]; // nullsubs, maybe CrtSetDbgFlag
- size_t (*GetSize)(IMemAlloc* memAlloc, void* pMem);
- void* unknown5[9]; // they all do literally nothing
- void (*DumpStats)(IMemAlloc* memAlloc);
- void (*DumpStatsFileBase)(IMemAlloc* memAlloc, const char* pchFileBase);
- void* unknown6[4];
- int (*heapchk)(IMemAlloc* memAlloc);
- };
-
- VTable* m_vtable;
-};
-
-extern IMemAlloc* g_pMemAllocSingleton;
-typedef IMemAlloc* (*CreateGlobalMemAllocType)();
-extern CreateGlobalMemAllocType CreateGlobalMemAlloc;
-
// cmd.h
enum class ECommandTarget_t
{
@@ -85,33 +57,6 @@ extern Cbuf_AddTextType Cbuf_AddText;
typedef void (*Cbuf_ExecuteType)();
extern Cbuf_ExecuteType Cbuf_Execute;
-// commandline stuff
-class CCommandLine
-{
- public:
- // based on the defs in the 2013 source sdk, but for some reason has an extra function (may be another CreateCmdLine overload?)
- // these seem to line up with what they should be though
- virtual void CreateCmdLine(const char* commandline) {}
- virtual void CreateCmdLine(int argc, char** argv) {}
- virtual void unknown() {}
- virtual const char* GetCmdLine(void) const {}
-
- virtual const char* CheckParm(const char* psz, const char** ppszValue = 0) const {}
- virtual void RemoveParm() const {}
- virtual void AppendParm(const char* pszParm, const char* pszValues) {}
-
- virtual const char* ParmValue(const char* psz, const char* pDefaultVal = 0) const {}
- virtual int ParmValue(const char* psz, int nDefaultVal) const {}
- virtual float ParmValue(const char* psz, float flDefaultVal) const {}
-
- virtual int ParmCount() const {}
- virtual int FindParm(const char* psz) const {}
- virtual const char* GetParm(int nIndex) const {}
- virtual void SetParm(int nIndex, char const* pParm) {}
-
- // virtual const char** GetParms() const {}
-};
-
// hoststate stuff
enum HostState_t
{
@@ -204,22 +149,6 @@ enum server_state_t
extern server_state_t* sv_m_State;
-// network stuff
-extern ConVar* Cvar_hostport;
-
-// playlist stuff
-typedef const char* (*GetCurrentPlaylistType)();
-extern GetCurrentPlaylistType GetCurrentPlaylistName;
-
-typedef void (*SetCurrentPlaylistType)(const char* playlistName);
-extern SetCurrentPlaylistType SetCurrentPlaylist;
-
-typedef void (*SetPlaylistVarOverrideType)(const char* varName, const char* value);
-extern SetPlaylistVarOverrideType SetPlaylistVarOverride;
-
-typedef char* (*GetCurrentPlaylistVarType)(const char* varName, bool useOverrides);
-extern GetCurrentPlaylistVarType GetCurrentPlaylistVar;
-
// server entity stuff
typedef void* (*Server_GetEntityByIndexType)(int index);
extern Server_GetEntityByIndexType Server_GetEntityByIndex;
@@ -229,21 +158,9 @@ extern char* g_LocalPlayerUserID;
extern char* g_LocalPlayerOriginToken;
// misc stuff
-typedef void (*ErrorType)(const char* fmt, ...);
-extern ErrorType Error;
-
-typedef CCommandLine* (*CommandLineType)();
-extern CommandLineType CommandLine;
-
-typedef double (*Plat_FloatTimeType)();
-extern Plat_FloatTimeType Plat_FloatTime;
-
-typedef bool (*ThreadInServerFrameThreadType)();
-extern ThreadInServerFrameThreadType ThreadInServerFrameThread;
typedef void* (*GetBaseLocalClientType)();
extern GetBaseLocalClientType GetBaseLocalClient;
void InitialiseEngineGameUtilFunctions(HMODULE baseAddress);
-void InitialiseServerGameUtilFunctions(HMODULE baseAddress);
-void InitialiseTier0GameUtilFunctions(HMODULE baseAddress); \ No newline at end of file
+void InitialiseServerGameUtilFunctions(HMODULE baseAddress); \ No newline at end of file
diff --git a/NorthstarDedicatedTest/languagehooks.cpp b/NorthstarDedicatedTest/languagehooks.cpp
index 1ca22d89..5e58924e 100644
--- a/NorthstarDedicatedTest/languagehooks.cpp
+++ b/NorthstarDedicatedTest/languagehooks.cpp
@@ -2,6 +2,7 @@
#include "hooks.h"
#include "languagehooks.h"
#include "gameutils.h"
+#include "tier0.h"
#include <filesystem>
#include <regex>
@@ -61,7 +62,7 @@ char* GetGameLanguageHook()
bool& canOriginDictateLang = *(bool*)((char*)tier0Handle + 0xA9A90);
const char* forcedLanguage;
- if (CommandLine()->CheckParm("-language", &forcedLanguage))
+ if (Tier0::CommandLine()->CheckParm("-language", &forcedLanguage))
{
if (!CheckLangAudioExists((char*)forcedLanguage))
{
diff --git a/NorthstarDedicatedTest/masterserver.cpp b/NorthstarDedicatedTest/masterserver.cpp
index 9c78c71a..63915732 100644
--- a/NorthstarDedicatedTest/masterserver.cpp
+++ b/NorthstarDedicatedTest/masterserver.cpp
@@ -3,9 +3,11 @@
#include "hooks.h"
#include "concommand.h"
#include "gameutils.h"
+#include "playlist.h"
#include "hookutils.h"
#include "serverauthentication.h"
#include "gameutils.h"
+#include "tier0.h"
#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
@@ -30,6 +32,7 @@ ConVar* Cvar_ns_curl_log_enable;
// Source ConVar
ConVar* Cvar_hostname;
+ConVar* Cvar_hostport;
MasterServerManager* g_MasterServerManager;
@@ -148,7 +151,7 @@ void MasterServerManager::SetCommonHttpClientOptions(CURL* curl)
curl_easy_setopt(curl, CURLOPT_VERBOSE, Cvar_ns_curl_log_enable->GetBool());
curl_easy_setopt(curl, CURLOPT_USERAGENT, &NSUserAgent);
// curl_easy_setopt(curl, CURLOPT_STDERR, stdout);
- if (CommandLine()->FindParm("-msinsecure")) // TODO: this check doesn't seem to work
+ if (Tier0::CommandLine()->FindParm("-msinsecure")) // TODO: this check doesn't seem to work
{
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
@@ -921,11 +924,11 @@ void MasterServerManager::AddSelfToServerList(
char* escapedNameNew = curl_easy_escape(curl, g_MasterServerManager->m_sUnicodeServerName.c_str(), NULL);
char* escapedDescNew = curl_easy_escape(curl, g_MasterServerManager->m_sUnicodeServerDesc.c_str(), NULL);
char* escapedMapNew = curl_easy_escape(curl, g_pHostState->m_levelName, NULL);
- char* escapedPlaylistNew = curl_easy_escape(curl, GetCurrentPlaylistName(), NULL);
+ char* escapedPlaylistNew = curl_easy_escape(curl, R2::GetCurrentPlaylistName(), NULL);
char* escapedPasswordNew = curl_easy_escape(curl, Cvar_ns_server_password->GetString(), NULL);
int maxPlayers = 6;
- char* maxPlayersVar = GetCurrentPlaylistVar("max_players", false);
+ const char* maxPlayersVar = R2::GetCurrentPlaylistVar("max_players", false);
if (maxPlayersVar) // GetCurrentPlaylistVar can return null so protect against this
maxPlayers = std::stoi(maxPlayersVar);
@@ -1216,7 +1219,7 @@ void CHostState__State_NewGameHook(CHostState* hostState)
// need to do this to ensure we don't go to private match
if (g_ServerAuthenticationManager->m_bNeedLocalAuthForNewgame)
- SetCurrentPlaylist("tdm");
+ R2::SetCurrentPlaylist("tdm");
// net_data_block_enabled is required for sp, force it if we're on an sp map
// sucks for security but just how it be
@@ -1226,12 +1229,12 @@ void CHostState__State_NewGameHook(CHostState* hostState)
Cbuf_Execute();
}
- double dStartTime = Plat_FloatTime();
+ double dStartTime = Tier0::Plat_FloatTime();
CHostState__State_NewGame(hostState);
- spdlog::info("loading took {}s", Plat_FloatTime() - dStartTime);
+ spdlog::info("loading took {}s", Tier0::Plat_FloatTime() - dStartTime);
int maxPlayers = 6;
- char* maxPlayersVar = GetCurrentPlaylistVar("max_players", false);
+ const char* maxPlayersVar = R2::GetCurrentPlaylistVar("max_players", false);
if (maxPlayersVar) // GetCurrentPlaylistVar can return null so protect against this
maxPlayers = std::stoi(maxPlayersVar);
@@ -1246,7 +1249,7 @@ void CHostState__State_NewGameHook(CHostState* hostState)
(char*)Cvar_ns_server_name->GetString(),
(char*)Cvar_ns_server_desc->GetString(),
hostState->m_levelName,
- (char*)GetCurrentPlaylistName(),
+ (char*)R2::GetCurrentPlaylistName(),
maxPlayers,
(char*)Cvar_ns_server_password->GetString());
g_ServerAuthenticationManager->StartPlayerAuthServer();
@@ -1256,7 +1259,7 @@ void CHostState__State_NewGameHook(CHostState* hostState)
void CHostState__State_ChangeLevelMPHook(CHostState* hostState)
{
int maxPlayers = 6;
- char* maxPlayersVar = GetCurrentPlaylistVar("max_players", false);
+ const char* maxPlayersVar = R2::GetCurrentPlaylistVar("max_players", false);
if (maxPlayersVar) // GetCurrentPlaylistVar can return null so protect against this
maxPlayers = std::stoi(maxPlayersVar);
@@ -1268,11 +1271,11 @@ void CHostState__State_ChangeLevelMPHook(CHostState* hostState)
Cbuf_Execute();
}
- g_MasterServerManager->UpdateServerMapAndPlaylist(hostState->m_levelName, (char*)GetCurrentPlaylistName(), maxPlayers);
+ g_MasterServerManager->UpdateServerMapAndPlaylist(hostState->m_levelName, (char*)R2::GetCurrentPlaylistName(), maxPlayers);
- double dStartTime = Plat_FloatTime();
+ double dStartTime = Tier0::Plat_FloatTime();
CHostState__State_ChangeLevelMP(hostState);
- spdlog::info("loading took {}s", Plat_FloatTime() - dStartTime);
+ spdlog::info("loading took {}s", Tier0::Plat_FloatTime() - dStartTime);
}
void CHostState__State_ChangeLevelSPHook(CHostState* hostState)
@@ -1282,11 +1285,11 @@ void CHostState__State_ChangeLevelSPHook(CHostState* hostState)
// so idk it's fucked
int maxPlayers = 6;
- char* maxPlayersVar = GetCurrentPlaylistVar("max_players", false);
+ const char* maxPlayersVar = R2::GetCurrentPlaylistVar("max_players", false);
if (maxPlayersVar) // GetCurrentPlaylistVar can return null so protect against this
maxPlayers = std::stoi(maxPlayersVar);
- g_MasterServerManager->UpdateServerMapAndPlaylist(hostState->m_levelName, (char*)GetCurrentPlaylistName(), maxPlayers);
+ g_MasterServerManager->UpdateServerMapAndPlaylist(hostState->m_levelName, (char*)R2::GetCurrentPlaylistName(), maxPlayers);
CHostState__State_ChangeLevelSP(hostState);
}
@@ -1315,6 +1318,7 @@ ON_DLL_LOAD_RELIESON("engine.dll", MasterServer, ConCommand, (HMODULE baseAddres
Cvar_ns_curl_log_enable = new ConVar("ns_curl_log_enable", "0", FCVAR_NONE, "");
Cvar_hostname = *(ConVar**)((char*)baseAddress + 0x1315bae8);
+ Cvar_hostport = (ConVar*)((char*)baseAddress + 0x13FA6070);
g_MasterServerManager = new MasterServerManager;
diff --git a/NorthstarDedicatedTest/maxplayers.cpp b/NorthstarDedicatedTest/maxplayers.cpp
index b2219faf..15846ea8 100644
--- a/NorthstarDedicatedTest/maxplayers.cpp
+++ b/NorthstarDedicatedTest/maxplayers.cpp
@@ -2,6 +2,7 @@
#include "hooks.h"
#include "maxplayers.h"
#include "gameutils.h"
+#include "tier0.h"
// never set this to anything below 32
#define NEW_MAX_PLAYERS 64
@@ -106,7 +107,7 @@ void* StringTables_CreateStringTable_Hook(
bool MaxPlayersIncreaseEnabled()
{
- return CommandLine() && CommandLine()->CheckParm("-experimentalmaxplayersincrease");
+ return Tier0::CommandLine() && Tier0::CommandLine()->CheckParm("-experimentalmaxplayersincrease");
}
ON_DLL_LOAD("engine.dll", MaxPlayersOverride_Engine, (HMODULE baseAddress)
diff --git a/NorthstarDedicatedTest/memalloc.cpp b/NorthstarDedicatedTest/memalloc.cpp
index 4ba54c73..e00d3fc7 100644
--- a/NorthstarDedicatedTest/memalloc.cpp
+++ b/NorthstarDedicatedTest/memalloc.cpp
@@ -1,6 +1,8 @@
#include "pch.h"
#include "memalloc.h"
-#include "gameutils.h"
+#include "tier0.h"
+
+using namespace Tier0;
// TODO: rename to malloc and free after removing statically compiled .libs
@@ -8,9 +10,8 @@ extern "C" void* _malloc_base(size_t n)
{
// allocate into static buffer if g_pMemAllocSingleton isn't initialised
if (!g_pMemAllocSingleton)
- {
- InitialiseTier0GameUtilFunctions(GetModuleHandleA("tier0.dll"));
- }
+ TryCreateGlobalMemAlloc();
+
return g_pMemAllocSingleton->m_vtable->Alloc(g_pMemAllocSingleton, n);
}
@@ -22,19 +23,16 @@ extern "C" void* _malloc_base(size_t n)
extern "C" void _free_base(void* p)
{
if (!g_pMemAllocSingleton)
- {
- spdlog::warn("Trying to free something before g_pMemAllocSingleton was ready, this should never happen");
- InitialiseTier0GameUtilFunctions(GetModuleHandleA("tier0.dll"));
- }
+ TryCreateGlobalMemAlloc();
+
g_pMemAllocSingleton->m_vtable->Free(g_pMemAllocSingleton, p);
}
extern "C" void* _realloc_base(void* oldPtr, size_t size)
{
if (!g_pMemAllocSingleton)
- {
- InitialiseTier0GameUtilFunctions(GetModuleHandleA("tier0.dll"));
- }
+ TryCreateGlobalMemAlloc();
+
return g_pMemAllocSingleton->m_vtable->Realloc(g_pMemAllocSingleton, oldPtr, size);
}
diff --git a/NorthstarDedicatedTest/misccommands.cpp b/NorthstarDedicatedTest/misccommands.cpp
index 00a32c48..51891a07 100644
--- a/NorthstarDedicatedTest/misccommands.cpp
+++ b/NorthstarDedicatedTest/misccommands.cpp
@@ -2,6 +2,7 @@
#include "misccommands.h"
#include "concommand.h"
#include "gameutils.h"
+#include "playlist.h"
#include "masterserver.h"
#include "serverauthentication.h"
#include "squirrel.h"
@@ -52,7 +53,7 @@ void AddMiscConCommands()
// this won't set playlist correctly on remote clients, don't think they can set playlist until they've left which sorta
// fucks things should maybe set this in HostState_NewGame?
- SetCurrentPlaylist("tdm");
+ R2::SetCurrentPlaylist("tdm");
strcpy(g_pHostState->m_levelName, "mp_lobby");
g_pHostState->m_iNextState = HS_NEW_GAME;
}
diff --git a/NorthstarDedicatedTest/modmanager.cpp b/NorthstarDedicatedTest/modmanager.cpp
index 01f9670a..79244194 100644
--- a/NorthstarDedicatedTest/modmanager.cpp
+++ b/NorthstarDedicatedTest/modmanager.cpp
@@ -388,7 +388,7 @@ void ModManager::LoadMods()
// not using atm because we need to resolve path to rpak
// if (m_hasLoadedMods && modPak.m_bAutoLoad)
- // g_PakLoadManager->LoadPakAsync(pakName.c_str());
+ // g_pPakLoadManager->LoadPakAsync(pakName.c_str());
}
}
}
diff --git a/NorthstarDedicatedTest/pch.h b/NorthstarDedicatedTest/pch.h
index 1955071c..a67315ba 100644
--- a/NorthstarDedicatedTest/pch.h
+++ b/NorthstarDedicatedTest/pch.h
@@ -24,6 +24,7 @@
#include "include/MinHook.h"
#include "spdlog/spdlog.h"
#include "libcurl/include/curl/curl.h"
+#include "hooks.h"
#include "hookutils.h"
template <typename ReturnType, typename... Args> ReturnType CallVFunc(int index, void* thisPtr, Args... args)
diff --git a/NorthstarDedicatedTest/playlist.cpp b/NorthstarDedicatedTest/playlist.cpp
index 59798510..477b3b0a 100644
--- a/NorthstarDedicatedTest/playlist.cpp
+++ b/NorthstarDedicatedTest/playlist.cpp
@@ -8,24 +8,21 @@
#include "hookutils.h"
#include "squirrel.h"
-typedef char (*Onclc_SetPlaylistVarOverrideType)(void* a1, void* a2);
-Onclc_SetPlaylistVarOverrideType Onclc_SetPlaylistVarOverride;
-
-typedef int (*GetCurrentGamemodeMaxPlayersType)();
-GetCurrentGamemodeMaxPlayersType GetCurrentGamemodeMaxPlayers;
-
-// function type defined in gameutils.h
-SetPlaylistVarOverrideType SetPlaylistVarOverrideOriginal;
-GetCurrentPlaylistVarType GetCurrentPlaylistVarOriginal;
-
-ConVar* Cvar_ns_use_clc_SetPlaylistVarOverride;
+// use the R2 namespace for game funcs
+namespace R2
+{
+ GetCurrentPlaylistNameType GetCurrentPlaylistName;
+ SetCurrentPlaylistType SetCurrentPlaylist;
+ SetPlaylistVarOverrideType SetPlaylistVarOverride;
+ GetCurrentPlaylistVarType GetCurrentPlaylistVar;
+} // namespace R2
void SetPlaylistCommand(const CCommand& args)
{
if (args.ArgC() < 2)
return;
- SetCurrentPlaylist(args.Arg(1));
+ R2::SetCurrentPlaylist(args.Arg(1));
}
void SetPlaylistVarOverrideCommand(const CCommand& args)
@@ -34,14 +31,18 @@ void SetPlaylistVarOverrideCommand(const CCommand& args)
return;
for (int i = 1; i < args.ArgC(); i += 2)
- SetPlaylistVarOverride(args.Arg(i), args.Arg(i + 1));
+ R2::SetPlaylistVarOverride(args.Arg(i), args.Arg(i + 1));
}
+ConVar* Cvar_ns_use_clc_SetPlaylistVarOverride;
+
+typedef char (*Onclc_SetPlaylistVarOverrideType)(void* a1, void* a2);
+Onclc_SetPlaylistVarOverrideType Onclc_SetPlaylistVarOverride;
char Onclc_SetPlaylistVarOverrideHook(void* a1, void* a2)
{
// the private_match playlist is the only situation where there should be any legitimate sending of this netmessage
// todo: check mp_lobby here too
- if (!Cvar_ns_use_clc_SetPlaylistVarOverride->GetBool() || strcmp(GetCurrentPlaylistName(), "private_match"))
+ if (!Cvar_ns_use_clc_SetPlaylistVarOverride->GetBool() || strcmp(R2::GetCurrentPlaylistName(), "private_match"))
return 1;
return Onclc_SetPlaylistVarOverride(a1, a2);
@@ -52,20 +53,22 @@ void SetPlaylistVarOverrideHook(const char* varName, const char* value)
if (strlen(value) >= 64)
return;
- SetPlaylistVarOverrideOriginal(varName, value);
+ R2::SetPlaylistVarOverride(varName, value);
}
-char* GetCurrentPlaylistVarHook(const char* varName, bool useOverrides)
+const char* GetCurrentPlaylistVarHook(const char* varName, bool useOverrides)
{
if (!useOverrides && !strcmp(varName, "max_players"))
useOverrides = true;
- return GetCurrentPlaylistVarOriginal(varName, useOverrides);
+ return R2::GetCurrentPlaylistVar(varName, useOverrides);
}
+typedef int (*GetCurrentGamemodeMaxPlayersType)();
+GetCurrentGamemodeMaxPlayersType GetCurrentGamemodeMaxPlayers;
int GetCurrentGamemodeMaxPlayersHook()
{
- char* maxPlayersStr = GetCurrentPlaylistVar("max_players", 0);
+ char* maxPlayersStr = R2::GetCurrentPlaylistVar("max_players", 0);
if (!maxPlayersStr)
return GetCurrentGamemodeMaxPlayers();
@@ -75,32 +78,41 @@ int GetCurrentGamemodeMaxPlayersHook()
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", SetPlaylistCommand, "Sets the current playlist", FCVAR_NONE);
RegisterConCommand("setplaylist", SetPlaylistCommand, "Sets the current playlist", FCVAR_NONE);
RegisterConCommand("setplaylistvaroverrides", SetPlaylistVarOverrideCommand, "sets a playlist var override", FCVAR_NONE);
+
// 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
+ // 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
// compatibility
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));
ENABLER_CREATEHOOK(
- hook, (char*)baseAddress + 0x18ED00, &SetPlaylistVarOverrideHook, reinterpret_cast<LPVOID*>(&SetPlaylistVarOverrideOriginal));
+ hook, (char*)baseAddress + 0x18ED00, &SetPlaylistVarOverrideHook, reinterpret_cast<LPVOID*>(&R2::SetPlaylistVarOverride));
ENABLER_CREATEHOOK(
- hook, (char*)baseAddress + 0x18C680, &GetCurrentPlaylistVarHook, reinterpret_cast<LPVOID*>(&GetCurrentPlaylistVarOriginal));
+ hook, (char*)baseAddress + 0x18C680, &GetCurrentPlaylistVarHook, reinterpret_cast<LPVOID*>(&R2::GetCurrentPlaylistVar));
ENABLER_CREATEHOOK(
- hook, (char*)baseAddress + 0x18C430, &GetCurrentGamemodeMaxPlayersHook, reinterpret_cast<LPVOID*>(&GetCurrentGamemodeMaxPlayers));
+ hook,
+ (char*)baseAddress + 0x18C430,
+ &GetCurrentGamemodeMaxPlayersHook,
+ reinterpret_cast<LPVOID*>(&GetCurrentGamemodeMaxPlayers));
uintptr_t ba = (uintptr_t)baseAddress;
// patch to prevent clc_SetPlaylistVarOverride from being able to crash servers if we reach max overrides due to a call to Error (why is
// this possible respawn, wtf) todo: add a warning for this
- {
- NSMem::BytePatch(ba + 0x18ED8D, "C3");
- }
+ NSMem::BytePatch(ba + 0x18ED8D, "C3");
// patch to allow setplaylistvaroverride to be called before map init on dedicated and private match launched through the game
NSMem::NOP(ba + 0x18ED17, 6);
diff --git a/NorthstarDedicatedTest/playlist.h b/NorthstarDedicatedTest/playlist.h
index 7b9637ef..2ca1985f 100644
--- a/NorthstarDedicatedTest/playlist.h
+++ b/NorthstarDedicatedTest/playlist.h
@@ -1 +1,15 @@
-#pragma once \ No newline at end of file
+#pragma once
+namespace R2
+{
+ typedef const char* (*GetCurrentPlaylistNameType)();
+ extern GetCurrentPlaylistNameType GetCurrentPlaylistName;
+
+ typedef void (*SetCurrentPlaylistType)(const char* playlistName);
+ extern SetCurrentPlaylistType SetCurrentPlaylist;
+
+ typedef void (*SetPlaylistVarOverrideType)(const char* varName, const char* value);
+ extern SetPlaylistVarOverrideType SetPlaylistVarOverride;
+
+ typedef char* (*GetCurrentPlaylistVarType)(const char* varName, bool useOverrides);
+ extern GetCurrentPlaylistVarType GetCurrentPlaylistVar;
+} // namespace R2 \ No newline at end of file
diff --git a/NorthstarDedicatedTest/rpakfilesystem.cpp b/NorthstarDedicatedTest/rpakfilesystem.cpp
index c7bab5ee..fce7ddf1 100644
--- a/NorthstarDedicatedTest/rpakfilesystem.cpp
+++ b/NorthstarDedicatedTest/rpakfilesystem.cpp
@@ -28,7 +28,7 @@ struct PakLoadFuncs
PakLoadFuncs* g_pakLoadApi;
void** pUnknownPakLoadSingleton;
-PakLoadManager* g_PakLoadManager;
+PakLoadManager* g_pPakLoadManager;
void PakLoadManager::LoadPakSync(const char* path)
{
g_pakLoadApi->LoadPakSync(path, *pUnknownPakLoadSingleton, 0);
@@ -79,7 +79,7 @@ void LoadPreloadPaks()
for (ModRpakEntry& pak : mod.Rpaks)
if (pak.m_bAutoLoad)
- g_PakLoadManager->LoadPakAsync((modPakPath / pak.m_sPakName).string().c_str(), false);
+ g_pPakLoadManager->LoadPakAsync((modPakPath / pak.m_sPakName).string().c_str(), false);
}
}
@@ -114,7 +114,7 @@ void LoadCustomMapPaks(char** pakName, bool* bNeedToFreePakName)
true; // we can't free this memory until we're done with the pak, so let whatever's calling this deal with it
}
else
- g_PakLoadManager->LoadPakAsync((modPakPath / pak.m_sPakName).string().c_str(), true);
+ g_pPakLoadManager->LoadPakAsync((modPakPath / pak.m_sPakName).string().c_str(), true);
}
}
}
@@ -166,7 +166,7 @@ void* UnloadPakHook(int pakHandle, void* callback)
if (bShouldUnloadPaks)
{
bShouldUnloadPaks = false;
- g_PakLoadManager->UnloadPaks();
+ g_pPakLoadManager->UnloadPaks();
bShouldUnloadPaks = true;
}
@@ -209,7 +209,7 @@ void* ReadFullFileFromDiskHook(const char* requestedPath, void* a2)
ON_DLL_LOAD("engine.dll", RpakFilesystem, (HMODULE baseAddress)
{
- g_PakLoadManager = new PakLoadManager;
+ g_pPakLoadManager = new PakLoadManager;
g_pakLoadApi = *(PakLoadFuncs**)((char*)baseAddress + 0x5BED78);
pUnknownPakLoadSingleton = (void**)((char*)baseAddress + 0x7C5E20);
diff --git a/NorthstarDedicatedTest/rpakfilesystem.h b/NorthstarDedicatedTest/rpakfilesystem.h
index b711800e..e72ab5ff 100644
--- a/NorthstarDedicatedTest/rpakfilesystem.h
+++ b/NorthstarDedicatedTest/rpakfilesystem.h
@@ -11,4 +11,4 @@ class PakLoadManager
std::vector<int> m_pakHandlesToUnload;
};
-extern PakLoadManager* g_PakLoadManager; \ No newline at end of file
+extern PakLoadManager* g_pPakLoadManager; \ No newline at end of file
diff --git a/NorthstarDedicatedTest/serverauthentication.cpp b/NorthstarDedicatedTest/serverauthentication.cpp
index 27db8bc9..5f9f10e8 100644
--- a/NorthstarDedicatedTest/serverauthentication.cpp
+++ b/NorthstarDedicatedTest/serverauthentication.cpp
@@ -16,6 +16,9 @@
#include <thread>
#include "configurables.h"
#include "NSMem.h"
+#include "tier0.h"
+
+using namespace Tier0;
const char* AUTHSERVER_VERIFY_STRING = "I am a northstar server!";
diff --git a/NorthstarDedicatedTest/serverchathooks.cpp b/NorthstarDedicatedTest/serverchathooks.cpp
index c16b7a4b..5ac582fd 100644
--- a/NorthstarDedicatedTest/serverchathooks.cpp
+++ b/NorthstarDedicatedTest/serverchathooks.cpp
@@ -140,6 +140,7 @@ void ChatBroadcastMessage(int fromPlayerIndex, int toPlayerIndex, const char* te
CRecipientFilter__Destruct(&filter);
}
+// void function NSSendMessage( int playerIndex, string text, bool isTeam )
SQRESULT SQ_SendMessage(void* sqvm)
{
int playerIndex = g_pServerSquirrel->sq_getinteger(sqvm, 1);
@@ -151,6 +152,7 @@ SQRESULT SQ_SendMessage(void* sqvm)
return SQRESULT_NULL;
}
+// void function NSBroadcastMessage( int fromPlayerIndex, int toPlayerIndex, string text, bool isTeam, bool isDead, int messageType )
SQRESULT SQ_BroadcastMessage(void* sqvm)
{
int fromPlayerIndex = g_pServerSquirrel->sq_getinteger(sqvm, 1);
diff --git a/NorthstarDedicatedTest/tier0.cpp b/NorthstarDedicatedTest/tier0.cpp
new file mode 100644
index 00000000..1a0957ad
--- /dev/null
+++ b/NorthstarDedicatedTest/tier0.cpp
@@ -0,0 +1,37 @@
+#include "pch.h"
+#include "tier0.h"
+
+// use the Tier0 namespace for tier0 funcs
+namespace Tier0
+{
+ IMemAlloc* g_pMemAllocSingleton;
+
+ ErrorType Error;
+ CommandLineType CommandLine;
+ Plat_FloatTimeType Plat_FloatTime;
+ ThreadInServerFrameThreadType ThreadInServerFrameThread;
+} // namespace Tier0
+
+typedef Tier0::IMemAlloc* (*CreateGlobalMemAllocType)();
+CreateGlobalMemAllocType CreateGlobalMemAlloc;
+
+// needs to be a seperate function, since memalloc.cpp calls it
+void TryCreateGlobalMemAlloc()
+{
+ // init memalloc stuff
+ CreateGlobalMemAlloc = reinterpret_cast<CreateGlobalMemAllocType>(GetProcAddress(GetModuleHandleA("tier0.dll"), "CreateGlobalMemAlloc"));
+ Tier0::g_pMemAllocSingleton = CreateGlobalMemAlloc(); // if it already exists, this returns the preexisting IMemAlloc instance
+}
+
+ON_DLL_LOAD("tier0.dll", Tier0GameFuncs, (HMODULE baseAddress)
+{
+ // shouldn't be necessary, but do this just in case
+ TryCreateGlobalMemAlloc();
+
+ // setup tier0 funcs
+ Tier0::Error = reinterpret_cast<Tier0::ErrorType>(GetProcAddress(baseAddress, "Error"));
+ Tier0::CommandLine = reinterpret_cast<Tier0::CommandLineType>(GetProcAddress(baseAddress, "CommandLine"));
+ Tier0::Plat_FloatTime = reinterpret_cast<Tier0::Plat_FloatTimeType>(GetProcAddress(baseAddress, "Plat_FloatTime"));
+ Tier0::ThreadInServerFrameThread =
+ reinterpret_cast<Tier0::ThreadInServerFrameThreadType>(GetProcAddress(baseAddress, "ThreadInServerFrameThread"));
+}) \ No newline at end of file
diff --git a/NorthstarDedicatedTest/tier0.h b/NorthstarDedicatedTest/tier0.h
new file mode 100644
index 00000000..5fefc699
--- /dev/null
+++ b/NorthstarDedicatedTest/tier0.h
@@ -0,0 +1,68 @@
+#pragma once
+namespace Tier0
+{
+ class IMemAlloc
+ {
+ public:
+ struct VTable
+ {
+ void* unknown[1]; // alloc debug
+ void* (*Alloc)(IMemAlloc* memAlloc, size_t nSize);
+ void* unknown2[1]; // realloc debug
+ void* (*Realloc)(IMemAlloc* memAlloc, void* pMem, size_t nSize);
+ void* unknown3[1]; // free #1
+ void (*Free)(IMemAlloc* memAlloc, void* pMem);
+ void* unknown4[2]; // nullsubs, maybe CrtSetDbgFlag
+ size_t (*GetSize)(IMemAlloc* memAlloc, void* pMem);
+ void* unknown5[9]; // they all do literally nothing
+ void (*DumpStats)(IMemAlloc* memAlloc);
+ void (*DumpStatsFileBase)(IMemAlloc* memAlloc, const char* pchFileBase);
+ void* unknown6[4];
+ int (*heapchk)(IMemAlloc* memAlloc);
+ };
+
+ VTable* m_vtable;
+ };
+
+ class CCommandLine
+ {
+ public:
+ // based on the defs in the 2013 source sdk, but for some reason has an extra function (may be another CreateCmdLine overload?)
+ // these seem to line up with what they should be though
+ virtual void CreateCmdLine(const char* commandline) {}
+ virtual void CreateCmdLine(int argc, char** argv) {}
+ virtual void unknown() {}
+ virtual const char* GetCmdLine(void) const {}
+
+ virtual const char* CheckParm(const char* psz, const char** ppszValue = 0) const {}
+ virtual void RemoveParm() const {}
+ virtual void AppendParm(const char* pszParm, const char* pszValues) {}
+
+ virtual const char* ParmValue(const char* psz, const char* pDefaultVal = 0) const {}
+ virtual int ParmValue(const char* psz, int nDefaultVal) const {}
+ virtual float ParmValue(const char* psz, float flDefaultVal) const {}
+
+ virtual int ParmCount() const {}
+ virtual int FindParm(const char* psz) const {}
+ virtual const char* GetParm(int nIndex) const {}
+ virtual void SetParm(int nIndex, char const* pParm) {}
+
+ // virtual const char** GetParms() const {}
+ };
+
+ extern IMemAlloc* g_pMemAllocSingleton;
+
+ typedef void (*ErrorType)(const char* fmt, ...);
+ extern ErrorType Error;
+
+ typedef CCommandLine* (*CommandLineType)();
+ extern CommandLineType CommandLine;
+
+ typedef double (*Plat_FloatTimeType)();
+ extern Plat_FloatTimeType Plat_FloatTime;
+
+ typedef bool (*ThreadInServerFrameThreadType)();
+ extern ThreadInServerFrameThreadType ThreadInServerFrameThread;
+} // namespace Tier0
+
+void TryCreateGlobalMemAlloc(); \ No newline at end of file