aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj4
-rw-r--r--NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters12
-rw-r--r--NorthstarDedicatedTest/bansystem.cpp90
-rw-r--r--NorthstarDedicatedTest/bansystem.h19
-rw-r--r--NorthstarDedicatedTest/dllmain.cpp10
-rw-r--r--NorthstarDedicatedTest/logging.cpp7
-rw-r--r--NorthstarDedicatedTest/masterserver.h2
-rw-r--r--NorthstarDedicatedTest/miscserverscript.h3
-rw-r--r--NorthstarDedicatedTest/playlist.cpp2
-rw-r--r--NorthstarDedicatedTest/rpakfilesystem.cpp44
-rw-r--r--NorthstarDedicatedTest/rpakfilesystem.h4
-rw-r--r--NorthstarDedicatedTest/serverauthentication.cpp35
-rw-r--r--NorthstarDedicatedTest/serverauthentication.h3
13 files changed, 210 insertions, 25 deletions
diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj
index cabaf573..23b2cccf 100644
--- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj
+++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj
@@ -106,6 +106,7 @@
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
+ <ClInclude Include="bansystem.h" />
<ClInclude Include="chatcommand.h" />
<ClInclude Include="clientauthhooks.h" />
<ClInclude Include="concommand.h" />
@@ -529,6 +530,7 @@
<ClInclude Include="pdef.h" />
<ClInclude Include="playlist.h" />
<ClInclude Include="miscserverscript.h" />
+ <ClInclude Include="rpakfilesystem.h" />
<ClInclude Include="scriptbrowserhooks.h" />
<ClInclude Include="scriptmainmenupromos.h" />
<ClInclude Include="securitypatches.h" />
@@ -542,6 +544,7 @@
<ClInclude Include="squirrel.h" />
</ItemGroup>
<ItemGroup>
+ <ClCompile Include="bansystem.cpp" />
<ClCompile Include="chatcommand.cpp" />
<ClCompile Include="clientauthhooks.cpp" />
<ClCompile Include="concommand.cpp" />
@@ -570,6 +573,7 @@
</ClCompile>
<ClCompile Include="pdef.cpp" />
<ClCompile Include="playlist.cpp" />
+ <ClCompile Include="rpakfilesystem.cpp" />
<ClCompile Include="scriptbrowserhooks.cpp" />
<ClCompile Include="scriptmainmenupromos.cpp" />
<ClCompile Include="securitypatches.cpp" />
diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters
index ac2684a3..be15618c 100644
--- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters
+++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters
@@ -1422,6 +1422,12 @@
<ClInclude Include="include\libcurl\include\curl\urlapi.h">
<Filter>Header Files\include\libcurl</Filter>
</ClInclude>
+ <ClInclude Include="rpakfilesystem.h">
+ <Filter>Header Files\Shared</Filter>
+ </ClInclude>
+ <ClInclude Include="bansystem.h">
+ <Filter>Header Files\Server\Authentication</Filter>
+ </ClInclude>
<ClInclude Include="languagehooks.h">
<Filter>Header Files\Client</Filter>
</ClInclude>
@@ -1535,6 +1541,12 @@
<ClCompile Include="miscserverfixes.cpp">
<Filter>Source Files\Server</Filter>
</ClCompile>
+ <ClCompile Include="rpakfilesystem.cpp">
+ <Filter>Source Files\Shared</Filter>
+ </ClCompile>
+ <ClCompile Include="bansystem.cpp">
+ <Filter>Source Files\Server\Authentication</Filter>
+ </ClCompile>
<ClCompile Include="languagehooks.cpp">
<Filter>Source Files\Client</Filter>
</ClCompile>
diff --git a/NorthstarDedicatedTest/bansystem.cpp b/NorthstarDedicatedTest/bansystem.cpp
new file mode 100644
index 00000000..182506e8
--- /dev/null
+++ b/NorthstarDedicatedTest/bansystem.cpp
@@ -0,0 +1,90 @@
+#pragma once
+#include "pch.h"
+#include "bansystem.h"
+#include "serverauthentication.h"
+#include "concommand.h"
+#include "miscserverscript.h"
+#include <filesystem>
+
+const char* BANLIST_PATH = "R2Northstar/banlist.txt";
+
+ServerBanSystem* g_ServerBanSystem;
+
+void ServerBanSystem::OpenBanlist()
+{
+ std::ifstream enabledModsStream(BANLIST_PATH);
+ std::stringstream enabledModsStringStream;
+
+ if (!enabledModsStream.fail())
+ {
+ std::string line;
+ while (std::getline(enabledModsStream, line))
+ m_vBannedUids.push_back(strtoll(line.c_str(), nullptr, 10));
+
+ enabledModsStream.close();
+ }
+
+ // open write stream for banlist
+ m_sBanlistStream.open(BANLIST_PATH, std::ofstream::out | std::ofstream::binary | std::ofstream::app);
+}
+
+void ServerBanSystem::BanUID(uint64_t uid)
+{
+ m_vBannedUids.push_back(uid);
+ m_sBanlistStream << std::to_string(uid) << std::endl;
+ spdlog::info("{} was banned", uid);
+}
+
+void ServerBanSystem::UnbanUID(uint64_t uid)
+{
+ auto findResult = std::find(m_vBannedUids.begin(), m_vBannedUids.end(), uid);
+ if (findResult == m_vBannedUids.end())
+ return;
+
+ m_vBannedUids.erase(findResult);
+ spdlog::info("{} was unbanned", uid);
+ // todo: this needs to erase from the banlist file
+ // atm unsure how to do this aside from just clearing and fully rewriting the file
+}
+
+bool ServerBanSystem::IsUIDAllowed(uint64_t uid)
+{
+ return std::find(m_vBannedUids.begin(), m_vBannedUids.end(), uid) == m_vBannedUids.end();
+}
+
+void BanPlayerCommand(const CCommand& args)
+{
+ if (args.ArgC() < 2)
+ return;
+
+ // assuming maxplayers 32
+ for (int i = 0; i < 32; i++)
+ {
+ void* player = GetPlayerByIndex(i);
+
+ if (!strcmp((char*)player + 0x16, args.Arg(1)) || strcmp((char*)player + 0xF500, args.Arg(1)))
+ {
+ g_ServerBanSystem->BanUID(strtoll((char*)player + 0xF500, nullptr, 10));
+ CBaseClient__Disconnect(player, 1, "Banned from server");
+ break;
+ }
+ }
+}
+
+void UnbanPlayerCommand(const CCommand& args)
+{
+ if (args.ArgC() < 2)
+ return;
+
+ // assumedly the player being unbanned here wasn't already connected, so don't need to iterate over players or anything
+ g_ServerBanSystem->UnbanUID(strtoll(args.Arg(1), nullptr, 10));
+}
+
+void InitialiseBanSystem(HMODULE baseAddress)
+{
+ g_ServerBanSystem = new ServerBanSystem;
+ g_ServerBanSystem->OpenBanlist();
+
+ RegisterConCommand("ban", BanPlayerCommand, "bans a given player by uid or name", FCVAR_GAMEDLL);
+ RegisterConCommand("unban", UnbanPlayerCommand, "unbans a given player by uid", FCVAR_NONE);
+} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/bansystem.h b/NorthstarDedicatedTest/bansystem.h
new file mode 100644
index 00000000..a1646356
--- /dev/null
+++ b/NorthstarDedicatedTest/bansystem.h
@@ -0,0 +1,19 @@
+#pragma once
+#include <fstream>
+
+class ServerBanSystem
+{
+private:
+ std::ofstream m_sBanlistStream;
+ std::vector<uint64_t> m_vBannedUids;
+
+public:
+ void OpenBanlist();
+ void BanUID(uint64_t uid);
+ void UnbanUID(uint64_t uid);
+ bool IsUIDAllowed(uint64_t uid);
+};
+
+extern ServerBanSystem* g_ServerBanSystem;
+
+void InitialiseBanSystem(HMODULE baseAddress); \ No newline at end of file
diff --git a/NorthstarDedicatedTest/dllmain.cpp b/NorthstarDedicatedTest/dllmain.cpp
index 79f54374..cc1b0b7d 100644
--- a/NorthstarDedicatedTest/dllmain.cpp
+++ b/NorthstarDedicatedTest/dllmain.cpp
@@ -25,6 +25,8 @@
#include "scriptmainmenupromos.h"
#include "miscclientfixes.h"
#include "miscserverfixes.h"
+#include "rpakfilesystem.h"
+#include "bansystem.h"
#include "memalloc.h"
#include "languagehooks.h"
@@ -64,7 +66,7 @@ bool InitialiseNorthstar()
{
if (initialised)
{
- //spdlog::warn("Called InitialiseNorthstar more than once!");
+ //spdlog::warn("Called InitialiseNorthstar more than once!"); // it's actually 100% fine for that to happen
return false;
}
@@ -79,11 +81,9 @@ bool InitialiseNorthstar()
InitialiseInterfaceCreationHooks();
AddDllLoadCallback("tier0.dll", InitialiseTier0GameUtilFunctions);
- AddDllLoadCallback("tier0.dll", InitialiseTier0LanguageHooks);
AddDllLoadCallback("engine.dll", WaitForDebugger);
AddDllLoadCallback("engine.dll", InitialiseEngineGameUtilFunctions);
AddDllLoadCallback("server.dll", InitialiseServerGameUtilFunctions);
- AddDllLoadCallback("engine.dll", InitialiseEngineSpewFuncHooks);
// dedi patches
{
@@ -100,6 +100,7 @@ bool InitialiseNorthstar()
// client-exclusive patches
{
+ AddDllLoadCallback("tier0.dll", InitialiseTier0LanguageHooks);
AddDllLoadCallback("engine.dll", InitialiseClientEngineSecurityPatches);
AddDllLoadCallback("client.dll", InitialiseClientSquirrel);
AddDllLoadCallback("client.dll", InitialiseSourceConsole);
@@ -113,7 +114,9 @@ bool InitialiseNorthstar()
AddDllLoadCallback("client.dll", InitialiseMiscClientFixes);
}
+ AddDllLoadCallback("engine.dll", InitialiseEngineSpewFuncHooks);
AddDllLoadCallback("server.dll", InitialiseServerSquirrel);
+ AddDllLoadCallback("engine.dll", InitialiseBanSystem);
AddDllLoadCallback("engine.dll", InitialiseServerAuthentication);
AddDllLoadCallback("engine.dll", InitialiseSharedMasterServer);
AddDllLoadCallback("server.dll", InitialiseMiscServerScriptCommand);
@@ -122,6 +125,7 @@ bool InitialiseNorthstar()
AddDllLoadCallback("engine.dll", InitialisePlaylistHooks);
AddDllLoadCallback("filesystem_stdio.dll", InitialiseFilesystem);
+ AddDllLoadCallback("engine.dll", InitialiseEngineRpakFilesystem);
AddDllLoadCallback("engine.dll", InitialiseKeyValues);
// mod manager after everything else
diff --git a/NorthstarDedicatedTest/logging.cpp b/NorthstarDedicatedTest/logging.cpp
index 312d5345..7d5f7ae5 100644
--- a/NorthstarDedicatedTest/logging.cpp
+++ b/NorthstarDedicatedTest/logging.cpp
@@ -203,6 +203,8 @@ void InitialiseLogging()
spdlog::default_logger()->sinks().push_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>(stream.str(), false));
}
+ConVar* Cvar_spewlog_enable;
+
enum SpewType_t
{
SPEW_MESSAGE = 0,
@@ -218,6 +220,9 @@ EngineSpewFuncType EngineSpewFunc;
void EngineSpewFuncHook(void* engineServer, SpewType_t type, const char* format, va_list args)
{
+ if (!Cvar_spewlog_enable->m_nValue)
+ return;
+
const char* typeStr;
switch (type)
{
@@ -327,4 +332,6 @@ void InitialiseEngineSpewFuncHooks(HMODULE baseAddress)
{
HookEnabler hook;
ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x11CA80, EngineSpewFuncHook, reinterpret_cast<LPVOID*>(&EngineSpewFunc));
+
+ Cvar_spewlog_enable = RegisterConVar("spewlog_enable", "1", FCVAR_NONE, "Enables/disables whether the engine spewfunc should be logged");
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/masterserver.h b/NorthstarDedicatedTest/masterserver.h
index 694639dc..d3c83052 100644
--- a/NorthstarDedicatedTest/masterserver.h
+++ b/NorthstarDedicatedTest/masterserver.h
@@ -1,6 +1,5 @@
#pragma once
#include "convar.h"
-#include "httplib.h"
#include <WinSock2.h>
struct RemoteModInfo
@@ -67,7 +66,6 @@ class MasterServerManager
private:
bool m_requestingServerList = false;
bool m_authenticatingWithGameServer = false;
- httplib::Client* m_httpClient = nullptr;
public:
char m_ownServerId[33];
diff --git a/NorthstarDedicatedTest/miscserverscript.h b/NorthstarDedicatedTest/miscserverscript.h
index b3e0580a..8197e502 100644
--- a/NorthstarDedicatedTest/miscserverscript.h
+++ b/NorthstarDedicatedTest/miscserverscript.h
@@ -1 +1,2 @@
-void InitialiseMiscServerScriptCommand(HMODULE baseAddress); \ No newline at end of file
+void InitialiseMiscServerScriptCommand(HMODULE baseAddress);
+void* GetPlayerByIndex(int playerIndex); \ No newline at end of file
diff --git a/NorthstarDedicatedTest/playlist.cpp b/NorthstarDedicatedTest/playlist.cpp
index 1a0cff00..9cbd0c05 100644
--- a/NorthstarDedicatedTest/playlist.cpp
+++ b/NorthstarDedicatedTest/playlist.cpp
@@ -72,8 +72,6 @@ int GetCurrentGamemodeMaxPlayersHook()
return GetCurrentGamemodeMaxPlayers();
int maxPlayers = atoi(maxPlayersStr);
- spdlog::info("Overwrote max_players to {}", maxPlayers);
-
return maxPlayers;
}
diff --git a/NorthstarDedicatedTest/rpakfilesystem.cpp b/NorthstarDedicatedTest/rpakfilesystem.cpp
new file mode 100644
index 00000000..006a57c5
--- /dev/null
+++ b/NorthstarDedicatedTest/rpakfilesystem.cpp
@@ -0,0 +1,44 @@
+#include "pch.h"
+#include "rpakfilesystem.h"
+#include "hookutils.h"
+#include "modmanager.h"
+
+typedef void*(*LoadCommonPaksForMapType)(char* map);
+LoadCommonPaksForMapType LoadCommonPaksForMap;
+
+typedef void*(*LoadPakSyncType)(char* path, void* unknownSingleton, int flags);
+typedef void*(*LoadPakAsyncType)(char* path, void* unknownSingleton, int flags, void* callback0, void* callback1);
+
+// there are more i'm just too lazy to add
+struct PakLoadFuncs
+{
+ void* unknown[2];
+ LoadPakSyncType func2;
+ LoadPakAsyncType LoadPakAsync;
+};
+
+PakLoadFuncs* g_pakLoadApi;
+void** pUnknownPakLoadSingleton;
+
+void LoadPakAsync(char* path)
+{
+ g_pakLoadApi->LoadPakAsync(path, *pUnknownPakLoadSingleton, 2, nullptr, nullptr);
+}
+
+void LoadCommonPaksForMapHook(char* map)
+{
+ LoadCommonPaksForMap(map);
+
+ // for sp => mp conversions, load the sp rpaks
+ if (!strcmp(map, "mp_skyway_v1") || !strcmp(map, "mp_crashsite") || !strcmp(map, "mp_hub_timeshift"))
+ map[0] = 's';
+}
+
+void InitialiseEngineRpakFilesystem(HMODULE baseAddress)
+{
+ g_pakLoadApi = (PakLoadFuncs*)((char*)baseAddress + 0x5BED78);
+ pUnknownPakLoadSingleton = (void**)((char*)baseAddress + 0x7C5E20);
+
+ HookEnabler hook;
+ ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x15AD20, &LoadCommonPaksForMapHook, reinterpret_cast<LPVOID*>(&LoadCommonPaksForMap));
+} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/rpakfilesystem.h b/NorthstarDedicatedTest/rpakfilesystem.h
new file mode 100644
index 00000000..a9cc9a93
--- /dev/null
+++ b/NorthstarDedicatedTest/rpakfilesystem.h
@@ -0,0 +1,4 @@
+#pragma once
+
+void InitialiseEngineRpakFilesystem(HMODULE baseAddress);
+void LoadPakAsync(char* path); \ No newline at end of file
diff --git a/NorthstarDedicatedTest/serverauthentication.cpp b/NorthstarDedicatedTest/serverauthentication.cpp
index 98290b34..33a57c6a 100644
--- a/NorthstarDedicatedTest/serverauthentication.cpp
+++ b/NorthstarDedicatedTest/serverauthentication.cpp
@@ -5,6 +5,7 @@
#include "masterserver.h"
#include "httplib.h"
#include "gameutils.h"
+#include "bansystem.h"
#include <fstream>
#include <filesystem>
#include <thread>
@@ -22,7 +23,6 @@ CBaseClient__ConnectType CBaseClient__Connect;
typedef void(*CBaseClient__ActivatePlayerType)(void* self);
CBaseClient__ActivatePlayerType CBaseClient__ActivatePlayer;
-typedef void(*CBaseClient__DisconnectType)(void* self, uint32_t unknownButAlways1, const char* reason, ...);
CBaseClient__DisconnectType CBaseClient__Disconnect;
typedef char(*CGameClient__ExecuteStringCommandType)(void* self, uint32_t unknown, const char* pCommandString);
@@ -117,7 +117,6 @@ void ServerAuthenticationManager::StopPlayerAuthServer()
bool ServerAuthenticationManager::AuthenticatePlayer(void* player, int64_t uid, char* authToken)
{
std::string strUid = std::to_string(uid);
-
std::lock_guard<std::mutex> guard(m_authDataMutex);
bool authFail = true;
@@ -142,6 +141,9 @@ bool ServerAuthenticationManager::AuthenticatePlayer(void* player, int64_t uid,
if (authFail)
{
+ // set persistent data as ready, we use 0x3 internally to mark the client as using local persistence
+ *((char*)player + 0x4a0) = (char)0x3;
+
if (!CVar_ns_auth_allow_insecure->m_nValue) // no auth data and insecure connections aren't allowed, so dc the client
return false;
@@ -167,9 +169,6 @@ bool ServerAuthenticationManager::AuthenticatePlayer(void* player, int64_t uid,
pdataStream.read((char*)player + 0x4FA, length);
pdataStream.close();
-
- // set persistent data as ready, we use 0x3 internally to mark the client as using local persistence
- *((char*)player + 0x4a0) = (char)0x3;
}
return true; // auth successful, client stays on
@@ -221,7 +220,7 @@ void ServerAuthenticationManager::WritePersistentData(void* player)
// store these in vars so we can use them in CBaseClient::Connect
// this is fine because ptrs won't decay by the time we use this, just don't use it outside of cbaseclient::connect
char* nextPlayerToken;
-int64_t nextPlayerUid;
+uint64_t nextPlayerUid;
void* CBaseServer__ConnectClientHook(void* server, void* a2, void* a3, uint32_t a4, uint32_t a5, int32_t a6, void* a7, void* a8, char* serverFilter, void* a10, char a11, void* a12, char a13, char a14, int64_t uid, uint32_t a16, uint32_t a17)
{
@@ -237,6 +236,13 @@ char CBaseClient__ConnectHook(void* self, char* name, __int64 netchan_ptr_arg, c
// try to auth player, dc if it fails
// we connect irregardless of auth, because returning bad from this function can fuck client state p bad
char ret = CBaseClient__Connect(self, name, netchan_ptr_arg, b_fake_player_arg, a5, Buffer, a7);
+
+ if (!g_ServerBanSystem->IsUIDAllowed(nextPlayerUid))
+ {
+ CBaseClient__Disconnect(self, 1, "Banned from server");
+ return ret;
+ }
+
if (strlen(name) >= 64) // fix for name overflow bug
CBaseClient__Disconnect(self, 1, "Invalid name");
else if (!g_ServerAuthenticationManager->AuthenticatePlayer(self, nextPlayerUid, nextPlayerToken) && g_MasterServerManager->m_bRequireClientAuth)
@@ -329,8 +335,8 @@ char __fastcall CNetChan___ProcessMessagesHook(void* self, void* buf)
double startTime = Plat_FloatTime();
char ret = CNetChan___ProcessMessages(self, buf);
- // check processing limit
- if (Cvar_net_chan_limit_mode->m_nValue != 0)
+ // check processing limits, unless we're in a level transition
+ if (g_pHostState->m_iCurrentState == HostState_t::HS_RUN)
{
// player that sent the message
void* sender = *(void**)((char*)self + 368);
@@ -346,19 +352,14 @@ char __fastcall CNetChan___ProcessMessagesHook(void* self, void* buf)
g_ServerAuthenticationManager->m_additionalPlayerData[sender].lastNetChanProcessingLimitStart = startTime;
g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime = 0.0;
}
-
g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime += (Plat_FloatTime() * 1000) - (startTime * 1000);
- int32_t limit = Cvar_net_chan_limit_msec_per_sec->m_nValue;
- if (g_pHostState->m_iCurrentState != HostState_t::HS_RUN)
- limit *= 2; // give clients more headroom in these states, as alot of clients will tend to time out here
-
- if (g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime >= limit)
+ if (g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime >= Cvar_net_chan_limit_msec_per_sec->m_nValue)
{
spdlog::warn("Client {} hit netchan processing limit with {}ms of processing time this second (max is {})", (char*)sender + 0x16, g_ServerAuthenticationManager->m_additionalPlayerData[sender].netChanProcessingLimitTime, Cvar_net_chan_limit_msec_per_sec->m_nValue);
- // mode 1 = kick, mode 2 = log without kicking
- if (Cvar_net_chan_limit_mode->m_nValue == 1)
+ // nonzero = kick, 0 = warn
+ if (Cvar_net_chan_limit_mode->m_nValue)
{
CBaseClient__Disconnect(sender, 1, "Exceeded net channel processing limit");
return false;
@@ -434,7 +435,7 @@ void InitialiseServerAuthentication(HMODULE baseAddress)
// literally just stolen from a fix valve used in csgo
CVar_sv_quota_stringcmdspersecond = RegisterConVar("sv_quota_stringcmdspersecond", "60", FCVAR_GAMEDLL, "How many string commands per second clients are allowed to submit, 0 to disallow all string commands");
// https://blog.counter-strike.net/index.php/2019/07/24922/ but different because idk how to check what current tick number is
- Cvar_net_chan_limit_mode = RegisterConVar("net_chan_limit_mode", "0", FCVAR_GAMEDLL, "The mode for netchan processing limits: 0 = none, 1 = kick, 2 = log");
+ Cvar_net_chan_limit_mode = RegisterConVar("net_chan_limit_mode", "0", FCVAR_GAMEDLL, "The mode for netchan processing limits: 0 = log, 1 = kick");
Cvar_net_chan_limit_msec_per_sec = RegisterConVar("net_chan_limit_msec_per_sec", "0", FCVAR_GAMEDLL, "Netchannel processing is limited to so many milliseconds, abort connection if exceeding budget");
Cvar_ns_player_auth_port = RegisterConVar("ns_player_auth_port", "8081", FCVAR_GAMEDLL, "");
Cvar_sv_querylimit_per_sec = RegisterConVar("sv_querylimit_per_sec", "15", FCVAR_GAMEDLL, "");
diff --git a/NorthstarDedicatedTest/serverauthentication.h b/NorthstarDedicatedTest/serverauthentication.h
index a8863b2f..8b346f1d 100644
--- a/NorthstarDedicatedTest/serverauthentication.h
+++ b/NorthstarDedicatedTest/serverauthentication.h
@@ -94,6 +94,9 @@ public:
void WritePersistentData(void* player);
};
+typedef void(*CBaseClient__DisconnectType)(void* self, uint32_t unknownButAlways1, const char* reason, ...);
+extern CBaseClient__DisconnectType CBaseClient__Disconnect;
+
void InitialiseServerAuthentication(HMODULE baseAddress);
extern ServerAuthenticationManager* g_ServerAuthenticationManager;