aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NorthstarDedicatedTest/ExploitFixes.cpp2
-rw-r--r--NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj4
-rw-r--r--NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters90
-rw-r--r--NorthstarDedicatedTest/clientchathooks.h1
-rw-r--r--NorthstarDedicatedTest/convar.cpp16
-rw-r--r--NorthstarDedicatedTest/convar.h2
-rw-r--r--NorthstarDedicatedTest/dedicated.cpp15
-rw-r--r--NorthstarDedicatedTest/gameutils.cpp6
-rw-r--r--NorthstarDedicatedTest/gameutils.h41
-rw-r--r--NorthstarDedicatedTest/host.cpp55
-rw-r--r--NorthstarDedicatedTest/host.h1
-rw-r--r--NorthstarDedicatedTest/hoststate.cpp107
-rw-r--r--NorthstarDedicatedTest/hoststate.h45
-rw-r--r--NorthstarDedicatedTest/masterserver.cpp144
-rw-r--r--NorthstarDedicatedTest/masterserver.h35
-rw-r--r--NorthstarDedicatedTest/misccommands.cpp9
-rw-r--r--NorthstarDedicatedTest/playlist.h2
-rw-r--r--NorthstarDedicatedTest/serverauthentication.cpp3
18 files changed, 332 insertions, 246 deletions
diff --git a/NorthstarDedicatedTest/ExploitFixes.cpp b/NorthstarDedicatedTest/ExploitFixes.cpp
index 3850b5a7..3250f3b8 100644
--- a/NorthstarDedicatedTest/ExploitFixes.cpp
+++ b/NorthstarDedicatedTest/ExploitFixes.cpp
@@ -153,7 +153,7 @@ KHOOK(CClient_ProcessSetConVar, ("engine.dll", "48 8B D1 48 8B 49 18 48 8B 01 48
if (areWeServer)
{
if (realVar)
- isValidFlags = ConVar::IsFlagSet(realVar, FCVAR_USERINFO); // ConVar MUST be userinfo var
+ isValidFlags = realVar->IsFlagSet(FCVAR_USERINFO); // ConVar MUST be userinfo var
}
else
{
diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj
index c523534a..a12a10f5 100644
--- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj
+++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj
@@ -123,6 +123,8 @@
<ClInclude Include="debugoverlay.h" />
<ClInclude Include="clientruihooks.h" />
<ClInclude Include="clientvideooverrides.h" />
+ <ClInclude Include="host.h" />
+ <ClInclude Include="hoststate.h" />
<ClInclude Include="localchatwriter.h" />
<ClInclude Include="ns_version.h" />
<ClInclude Include="plugins.h" />
@@ -595,6 +597,8 @@
<ClCompile Include="gameutils.cpp" />
<ClCompile Include="hooks.cpp" />
<ClCompile Include="hookutils.cpp" />
+ <ClCompile Include="host.cpp" />
+ <ClCompile Include="hoststate.cpp" />
<ClCompile Include="keyvalues.cpp" />
<ClCompile Include="latencyflex.cpp" />
<ClCompile Include="localchatwriter.cpp" />
diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters
index 1cb6cadd..cfd9c5ef 100644
--- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters
+++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters
@@ -133,6 +133,12 @@
<Filter Include="Source Files\Shared\Mods\Compiled Assets">
<UniqueIdentifier>{14fc0931-acad-46ec-a55e-94f4469d4235}</UniqueIdentifier>
</Filter>
+ <Filter Include="Header Files\Client\Scripted">
+ <UniqueIdentifier>{9ce4bfce-f214-4bc1-9dc7-f3219900718a}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files\Client\Scripted">
+ <UniqueIdentifier>{51910ba0-2ff8-461d-9f67-8d7907b57d22}</UniqueIdentifier>
+ </Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h">
@@ -561,12 +567,6 @@
<ClInclude Include="serverauthentication.h">
<Filter>Header Files\Server\Authentication</Filter>
</ClInclude>
- <ClInclude Include="scriptmodmenu.h">
- <Filter>Header Files\Client</Filter>
- </ClInclude>
- <ClInclude Include="scriptserverbrowser.h">
- <Filter>Header Files\Client</Filter>
- </ClInclude>
<ClInclude Include="keyvalues.h">
<Filter>Header Files\Shared\Mods\Compiled</Filter>
</ClInclude>
@@ -597,18 +597,12 @@
<ClInclude Include="clientauthhooks.h">
<Filter>Header Files\Client</Filter>
</ClInclude>
- <ClInclude Include="scriptbrowserhooks.h">
- <Filter>Header Files\Client</Filter>
- </ClInclude>
<ClInclude Include="gameutils.h">
<Filter>Header Files\Shared\Game Functions</Filter>
</ClInclude>
<ClInclude Include="memalloc.h">
<Filter>Header Files\Shared</Filter>
</ClInclude>
- <ClInclude Include="scriptmainmenupromos.h">
- <Filter>Header Files\Client</Filter>
- </ClInclude>
<ClInclude Include="miscclientfixes.h">
<Filter>Header Files\Client</Filter>
</ClInclude>
@@ -1464,15 +1458,9 @@
<ClInclude Include="serverchathooks.h">
<Filter>Header Files\Server</Filter>
</ClInclude>
- <ClInclude Include="clientchathooks.h">
- <Filter>Header Files\Client</Filter>
- </ClInclude>
<ClInclude Include="localchatwriter.h">
<Filter>Header Files\Client</Filter>
</ClInclude>
- <ClInclude Include="scriptservertoclientstringcommand.h">
- <Filter>Header Files\Client</Filter>
- </ClInclude>
<ClInclude Include="plugins.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -1512,6 +1500,30 @@
<ClInclude Include="tier0.h">
<Filter>Header Files\Shared\Game Functions</Filter>
</ClInclude>
+ <ClInclude Include="clientchathooks.h">
+ <Filter>Header Files\Client\Scripted</Filter>
+ </ClInclude>
+ <ClInclude Include="scriptbrowserhooks.h">
+ <Filter>Header Files\Client\Scripted</Filter>
+ </ClInclude>
+ <ClInclude Include="scriptmainmenupromos.h">
+ <Filter>Header Files\Client\Scripted</Filter>
+ </ClInclude>
+ <ClInclude Include="scriptmodmenu.h">
+ <Filter>Header Files\Client\Scripted</Filter>
+ </ClInclude>
+ <ClInclude Include="scriptserverbrowser.h">
+ <Filter>Header Files\Client\Scripted</Filter>
+ </ClInclude>
+ <ClInclude Include="scriptservertoclientstringcommand.h">
+ <Filter>Header Files\Client\Scripted</Filter>
+ </ClInclude>
+ <ClInclude Include="host.h">
+ <Filter>Header Files\Shared</Filter>
+ </ClInclude>
+ <ClInclude Include="hoststate.h">
+ <Filter>Header Files\Shared</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
@@ -1562,12 +1574,6 @@
<ClCompile Include="serverauthentication.cpp">
<Filter>Source Files\Server\Authentication</Filter>
</ClCompile>
- <ClCompile Include="scriptmodmenu.cpp">
- <Filter>Source Files\Client</Filter>
- </ClCompile>
- <ClCompile Include="scriptserverbrowser.cpp">
- <Filter>Source Files\Client</Filter>
- </ClCompile>
<ClCompile Include="keyvalues.cpp">
<Filter>Source Files\Shared\Mods\Compiled Assets</Filter>
</ClCompile>
@@ -1598,15 +1604,9 @@
<ClCompile Include="clientauthhooks.cpp">
<Filter>Source Files\Client</Filter>
</ClCompile>
- <ClCompile Include="scriptbrowserhooks.cpp">
- <Filter>Source Files\Client</Filter>
- </ClCompile>
<ClCompile Include="memalloc.cpp">
<Filter>Source Files\Shared</Filter>
</ClCompile>
- <ClCompile Include="scriptmainmenupromos.cpp">
- <Filter>Source Files\Client</Filter>
- </ClCompile>
<ClCompile Include="miscclientfixes.cpp">
<Filter>Source Files\Client</Filter>
</ClCompile>
@@ -1646,15 +1646,9 @@
<ClCompile Include="serverchathooks.cpp">
<Filter>Source Files\Server</Filter>
</ClCompile>
- <ClCompile Include="clientchathooks.cpp">
- <Filter>Source Files\Client</Filter>
- </ClCompile>
<ClCompile Include="localchatwriter.cpp">
<Filter>Source Files\Client</Filter>
</ClCompile>
- <ClCompile Include="scriptservertoclientstringcommand.cpp">
- <Filter>Source Files\Client</Filter>
- </ClCompile>
<ClCompile Include="plugins.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -1679,6 +1673,30 @@
<ClCompile Include="tier0.cpp">
<Filter>Source Files\Shared\Game Functions</Filter>
</ClCompile>
+ <ClCompile Include="hoststate.cpp">
+ <Filter>Source Files\Shared</Filter>
+ </ClCompile>
+ <ClCompile Include="host.cpp">
+ <Filter>Source Files\Shared</Filter>
+ </ClCompile>
+ <ClCompile Include="scriptmainmenupromos.cpp">
+ <Filter>Source Files\Client\Scripted</Filter>
+ </ClCompile>
+ <ClCompile Include="clientchathooks.cpp">
+ <Filter>Source Files\Client\Scripted</Filter>
+ </ClCompile>
+ <ClCompile Include="scriptmodmenu.cpp">
+ <Filter>Source Files\Client\Scripted</Filter>
+ </ClCompile>
+ <ClCompile Include="scriptservertoclientstringcommand.cpp">
+ <Filter>Source Files\Client\Scripted</Filter>
+ </ClCompile>
+ <ClCompile Include="scriptserverbrowser.cpp">
+ <Filter>Source Files\Client\Scripted</Filter>
+ </ClCompile>
+ <ClCompile Include="scriptbrowserhooks.cpp">
+ <Filter>Source Files\Client\Scripted</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<MASM Include="audio_asm.asm">
diff --git a/NorthstarDedicatedTest/clientchathooks.h b/NorthstarDedicatedTest/clientchathooks.h
index d8f831c2..6f70f09b 100644
--- a/NorthstarDedicatedTest/clientchathooks.h
+++ b/NorthstarDedicatedTest/clientchathooks.h
@@ -1,2 +1 @@
#pragma once
-#include "pch.h" \ No newline at end of file
diff --git a/NorthstarDedicatedTest/convar.cpp b/NorthstarDedicatedTest/convar.cpp
index c8e76e47..3ae02463 100644
--- a/NorthstarDedicatedTest/convar.cpp
+++ b/NorthstarDedicatedTest/convar.cpp
@@ -26,9 +26,6 @@ ConVarMallocType conVarMalloc;
void* g_pConVar_Vtable = nullptr;
void* g_pIConVar_Vtable = nullptr;
-typedef bool (*CvarIsFlagSetType)(ConVar* self, int flags);
-CvarIsFlagSetType CvarIsFlagSet;
-
//-----------------------------------------------------------------------------
// Purpose: ConVar interface initialization
//-----------------------------------------------------------------------------
@@ -42,9 +39,6 @@ ON_DLL_LOAD("engine.dll", ConVar, [](HMODULE baseAddress)
g_pCVarInterface = new SourceInterface<CCvar>("vstdlib.dll", "VEngineCvar007");
g_pCVar = *g_pCVarInterface;
-
- HookEnabler hook;
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x417FA0, &ConVar::IsFlagSet, reinterpret_cast<LPVOID*>(&CvarIsFlagSet));
})
//-----------------------------------------------------------------------------
@@ -475,16 +469,12 @@ bool ConVar::IsCommand(void) const
//-----------------------------------------------------------------------------
// Purpose: Test each ConVar query before setting the value.
-// Input : *pConVar - nFlags
+// Input : nFlags
// Output : False if change is permitted, true if not.
//-----------------------------------------------------------------------------
-bool ConVar::IsFlagSet(ConVar* pConVar, int nFlags)
+bool ConVar::IsFlagSet(int nFlags) const
{
- // unrestrict FCVAR_DEVELOPMENTONLY and FCVAR_HIDDEN
- if (pConVar && (nFlags == FCVAR_DEVELOPMENTONLY || nFlags == FCVAR_HIDDEN))
- return false;
-
- return CvarIsFlagSet(pConVar, nFlags);
+ return m_ConCommandBase.IsFlagSet(nFlags);
}
//-----------------------------------------------------------------------------
diff --git a/NorthstarDedicatedTest/convar.h b/NorthstarDedicatedTest/convar.h
index 8dbbd07d..d766933d 100644
--- a/NorthstarDedicatedTest/convar.h
+++ b/NorthstarDedicatedTest/convar.h
@@ -161,7 +161,7 @@ class ConVar
bool IsRegistered(void) const;
bool IsCommand(void) const;
- static bool IsFlagSet(ConVar* pConVar, int nFlags);
+ bool IsFlagSet(int nFlags) const;
struct CVValue_t
{
diff --git a/NorthstarDedicatedTest/dedicated.cpp b/NorthstarDedicatedTest/dedicated.cpp
index 41de0594..646439ab 100644
--- a/NorthstarDedicatedTest/dedicated.cpp
+++ b/NorthstarDedicatedTest/dedicated.cpp
@@ -5,10 +5,12 @@
#include "gameutils.h"
#include "tier0.h"
#include "playlist.h"
+#include "hoststate.h"
#include "serverauthentication.h"
#include "masterserver.h"
using namespace Tier0;
+using namespace R2;
bool IsDedicated()
{
@@ -53,17 +55,14 @@ void RunServer(CDedicatedExports* dedicated)
if (!CommandLine()->CheckParm("+map"))
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);
Cbuf_AddText(Cbuf_GetCurrentPlayer(), "stuffcmds", cmd_source_t::kCommandSrcCode);
Cbuf_Execute();
- // ensure playlist initialises right, if we've not explicitly called setplaylist
- 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
-
// get tickinterval
ConVar* Cvar_base_tickinterval_mp = g_pCVar->FindVar("base_tickinterval_mp");
@@ -80,7 +79,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 = R2::GetCurrentPlaylistVar("max_players", false);
+ const char* maxPlayers = GetCurrentPlaylistVar("max_players", false);
if (!maxPlayers)
maxPlayers = "6";
@@ -90,7 +89,7 @@ void RunServer(CDedicatedExports* dedicated)
g_pHostState->m_levelName,
g_ServerAuthenticationManager->m_additionalPlayerData.size(),
maxPlayers,
- R2::GetCurrentPlaylistName())
+ GetCurrentPlaylistName())
.c_str());
}
diff --git a/NorthstarDedicatedTest/gameutils.cpp b/NorthstarDedicatedTest/gameutils.cpp
index d6e5840a..ce96a5e5 100644
--- a/NorthstarDedicatedTest/gameutils.cpp
+++ b/NorthstarDedicatedTest/gameutils.cpp
@@ -1,15 +1,13 @@
#include "pch.h"
#include "convar.h"
#include "gameutils.h"
+#include "hoststate.h"
// cmd.h
Cbuf_GetCurrentPlayerType Cbuf_GetCurrentPlayer;
Cbuf_AddTextType Cbuf_AddText;
Cbuf_ExecuteType Cbuf_Execute;
-// hoststate stuff
-CHostState* g_pHostState;
-
// cengine stuff
CEngine* g_pEngine;
server_state_t* sv_m_State;
@@ -30,7 +28,7 @@ void InitialiseEngineGameUtilFunctions(HMODULE baseAddress)
Cbuf_AddText = (Cbuf_AddTextType)((char*)baseAddress + 0x1203B0);
Cbuf_Execute = (Cbuf_ExecuteType)((char*)baseAddress + 0x1204B0);
- g_pHostState = (CHostState*)((char*)baseAddress + 0x7CF180);
+ R2::g_pHostState = (R2::CHostState*)((char*)baseAddress + 0x7CF180);
g_pEngine = *(CEngine**)((char*)baseAddress + 0x7D70C8);
sv_m_State = (server_state_t*)((char*)baseAddress + 0x12A53D48);
diff --git a/NorthstarDedicatedTest/gameutils.h b/NorthstarDedicatedTest/gameutils.h
index 4d1b8fb7..d53c7abe 100644
--- a/NorthstarDedicatedTest/gameutils.h
+++ b/NorthstarDedicatedTest/gameutils.h
@@ -57,47 +57,6 @@ extern Cbuf_AddTextType Cbuf_AddText;
typedef void (*Cbuf_ExecuteType)();
extern Cbuf_ExecuteType Cbuf_Execute;
-// hoststate stuff
-enum HostState_t
-{
- HS_NEW_GAME = 0,
- HS_LOAD_GAME,
- HS_CHANGE_LEVEL_SP,
- HS_CHANGE_LEVEL_MP,
- HS_RUN,
- HS_GAME_SHUTDOWN,
- HS_SHUTDOWN,
- HS_RESTART,
-};
-
-struct CHostState
-{
- public:
- HostState_t m_iCurrentState;
- HostState_t m_iNextState;
-
- float m_vecLocation[3];
- float m_angLocation[3];
-
- char m_levelName[32];
- char m_mapGroupName[32];
- char m_landmarkName[32];
- char m_saveName[32];
- float m_flShortFrameTime; // run a few one-tick frames to avoid large timesteps while loading assets
-
- bool m_activeGame;
- bool m_bRememberLocation;
- bool m_bBackgroundLevel;
- bool m_bWaitingForConnection;
- bool m_bLetToolsOverrideLoadGameEnts; // During a load game, this tells Foundry to override ents that are selected in Hammer.
- bool m_bSplitScreenConnect;
- bool m_bGameHasShutDownAndFlushedMemory; // This is false once we load a map into memory, and set to true once the map is unloaded and
- // all memory flushed
- bool m_bWorkshopMapDownloadPending;
-};
-
-extern CHostState* g_pHostState;
-
// cengine stuff
enum EngineQuitState
{
diff --git a/NorthstarDedicatedTest/host.cpp b/NorthstarDedicatedTest/host.cpp
new file mode 100644
index 00000000..9217c128
--- /dev/null
+++ b/NorthstarDedicatedTest/host.cpp
@@ -0,0 +1,55 @@
+#include "pch.h"
+#include "host.h"
+#include "convar.h"
+#include "modmanager.h"
+#include "gameutils.h"
+
+typedef void (*Host_InitType)(bool bDedicated);
+Host_InitType Host_Init;
+void Host_InitHook(bool bDedicated)
+{
+ Host_Init(bDedicated);
+
+ // get all mod convars
+ std::vector<std::string> vModConvarNames;
+ for (auto& mod : g_ModManager->m_loadedMods)
+ for (auto& cvar : mod.ConVars)
+ vModConvarNames.push_back(cvar->Name);
+
+ // strip hidden and devonly cvar flags
+ int iCvarsAltered = 0;
+ for (auto& pair : g_pCVar->DumpToMap())
+ {
+ // don't remove from mod cvars
+ if (std::find(vModConvarNames.begin(), vModConvarNames.end(), pair.second->m_pszName) != vModConvarNames.end())
+ continue;
+
+ // strip flags
+ int flags = pair.second->GetFlags();
+ if (flags & FCVAR_DEVELOPMENTONLY)
+ {
+ flags &= ~FCVAR_DEVELOPMENTONLY;
+ iCvarsAltered++;
+ }
+
+ if (flags & FCVAR_HIDDEN)
+ {
+ flags &= ~FCVAR_HIDDEN;
+ iCvarsAltered++;
+ }
+
+ pair.second->m_nFlags = flags;
+ }
+
+ spdlog::info("Removed {} hidden/devonly cvar flags", iCvarsAltered);
+
+ // run client autoexec if on client
+ if (!bDedicated)
+ Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec autoexec_ns_client", cmd_source_t::kCommandSrcCode);
+}
+
+ON_DLL_LOAD("engine.dll", Host_Init, [](HMODULE baseAddress)
+{
+ HookEnabler hook;
+ ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x155EA0, &Host_InitHook, reinterpret_cast<LPVOID*>(&Host_Init));
+}) \ No newline at end of file
diff --git a/NorthstarDedicatedTest/host.h b/NorthstarDedicatedTest/host.h
new file mode 100644
index 00000000..6f70f09b
--- /dev/null
+++ b/NorthstarDedicatedTest/host.h
@@ -0,0 +1 @@
+#pragma once
diff --git a/NorthstarDedicatedTest/hoststate.cpp b/NorthstarDedicatedTest/hoststate.cpp
new file mode 100644
index 00000000..4782b559
--- /dev/null
+++ b/NorthstarDedicatedTest/hoststate.cpp
@@ -0,0 +1,107 @@
+#include "pch.h"
+#include "hoststate.h"
+#include "masterserver.h"
+#include "serverauthentication.h"
+#include "playlist.h"
+#include "gameutils.h"
+#include "tier0.h"
+
+using namespace R2;
+
+// use the R2 namespace for game funcs
+namespace R2
+{
+ CHostState* g_pHostState;
+} // namespace R2
+
+typedef void (*CHostState__State_NewGameType)(CHostState* hostState);
+CHostState__State_NewGameType CHostState__State_NewGame;
+void CHostState__State_NewGameHook(CHostState* hostState)
+{
+ spdlog::info("HostState: NewGame");
+
+ Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec autoexec_ns_server", cmd_source_t::kCommandSrcCode);
+ Cbuf_Execute();
+
+ // need to do this to ensure we don't go to private match
+ if (g_ServerAuthenticationManager->m_bNeedLocalAuthForNewgame)
+ 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
+ if (!strncmp(g_pHostState->m_levelName, "sp_", 3))
+ g_pCVar->FindVar("net_data_block_enabled")->SetValue(true);
+
+ double dStartTime = Tier0::Plat_FloatTime();
+ CHostState__State_NewGame(hostState);
+ spdlog::info("loading took {}s", Tier0::Plat_FloatTime() - dStartTime);
+
+ int maxPlayers = 6;
+ const char* maxPlayersVar = GetCurrentPlaylistVar("max_players", false);
+ if (maxPlayersVar) // GetCurrentPlaylistVar can return null so protect against this
+ maxPlayers = std::stoi(maxPlayersVar);
+
+ // Copy new server name cvar to source
+ Cvar_hostname->SetValue(Cvar_ns_server_name->GetString());
+
+ g_MasterServerManager->AddSelfToServerList(
+ Cvar_hostport->GetInt(),
+ Cvar_ns_player_auth_port->GetInt(),
+ Cvar_ns_server_name->GetString(),
+ Cvar_ns_server_desc->GetString(),
+ hostState->m_levelName,
+ GetCurrentPlaylistName(),
+ maxPlayers,
+ Cvar_ns_server_password->GetString());
+ g_ServerAuthenticationManager->StartPlayerAuthServer();
+ g_ServerAuthenticationManager->m_bNeedLocalAuthForNewgame = false;
+}
+
+typedef void (*CHostState__State_ChangeLevelMPType)(CHostState* hostState);
+CHostState__State_ChangeLevelMPType CHostState__State_ChangeLevelMP;
+void CHostState__State_ChangeLevelMPHook(CHostState* hostState)
+{
+ spdlog::info("HostState: ChangeLevelMP");
+
+ int maxPlayers = 6;
+ const char* maxPlayersVar = GetCurrentPlaylistVar("max_players", false);
+ if (maxPlayersVar) // GetCurrentPlaylistVar can return null so protect against this
+ maxPlayers = std::stoi(maxPlayersVar);
+
+ // 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
+ if (!strncmp(g_pHostState->m_levelName, "sp_", 3))
+ g_pCVar->FindVar("net_data_block_enabled")->SetValue(true);
+
+ g_MasterServerManager->UpdateServerMapAndPlaylist(hostState->m_levelName, GetCurrentPlaylistName(), maxPlayers);
+
+ double dStartTime = Tier0::Plat_FloatTime();
+ CHostState__State_ChangeLevelMP(hostState);
+ spdlog::info("loading took {}s", Tier0::Plat_FloatTime() - dStartTime);
+}
+
+typedef void (*CHostState__State_GameShutdownType)(CHostState* hostState);
+CHostState__State_GameShutdownType CHostState__State_GameShutdown;
+void CHostState__State_GameShutdownHook(CHostState* hostState)
+{
+ spdlog::info("HostState: GameShutdown");
+
+ g_MasterServerManager->RemoveSelfFromServerList();
+ g_ServerAuthenticationManager->StopPlayerAuthServer();
+
+ CHostState__State_GameShutdown(hostState);
+}
+
+ON_DLL_LOAD_RELIESON("engine.dll", HostState, ConVar, [](HMODULE baseAddress)
+{
+ Cvar_hostname = *(ConVar**)((char*)baseAddress + 0x1315bae8);
+ Cvar_hostport = (ConVar*)((char*)baseAddress + 0x13FA6070);
+
+ HookEnabler hook;
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x16E7D0, CHostState__State_NewGameHook, reinterpret_cast<LPVOID*>(&CHostState__State_NewGame));
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x16E520, CHostState__State_ChangeLevelMPHook, reinterpret_cast<LPVOID*>(&CHostState__State_ChangeLevelMP));
+ ENABLER_CREATEHOOK(
+ hook, (char*)baseAddress + 0x16E640, CHostState__State_GameShutdownHook, reinterpret_cast<LPVOID*>(&CHostState__State_GameShutdown));
+}) \ No newline at end of file
diff --git a/NorthstarDedicatedTest/hoststate.h b/NorthstarDedicatedTest/hoststate.h
new file mode 100644
index 00000000..4861ac7e
--- /dev/null
+++ b/NorthstarDedicatedTest/hoststate.h
@@ -0,0 +1,45 @@
+#pragma once
+
+// use the R2 namespace for game funxcs
+namespace R2
+{
+ enum class HostState_t
+ {
+ HS_NEW_GAME = 0,
+ HS_LOAD_GAME,
+ HS_CHANGE_LEVEL_SP,
+ HS_CHANGE_LEVEL_MP,
+ HS_RUN,
+ HS_GAME_SHUTDOWN,
+ HS_SHUTDOWN,
+ HS_RESTART,
+ };
+
+ struct CHostState
+ {
+ public:
+ HostState_t m_iCurrentState;
+ HostState_t m_iNextState;
+
+ float m_vecLocation[3];
+ float m_angLocation[3];
+
+ char m_levelName[32];
+ char m_mapGroupName[32];
+ char m_landmarkName[32];
+ char m_saveName[32];
+ float m_flShortFrameTime; // run a few one-tick frames to avoid large timesteps while loading assets
+
+ bool m_activeGame;
+ bool m_bRememberLocation;
+ bool m_bBackgroundLevel;
+ bool m_bWaitingForConnection;
+ bool m_bLetToolsOverrideLoadGameEnts; // During a load game, this tells Foundry to override ents that are selected in Hammer.
+ bool m_bSplitScreenConnect;
+ bool m_bGameHasShutDownAndFlushedMemory; // This is false once we load a map into memory, and set to true once the map is unloaded
+ // and all memory flushed
+ bool m_bWorkshopMapDownloadPending;
+ };
+
+ extern CHostState* g_pHostState;
+} // namespace R2 \ No newline at end of file
diff --git a/NorthstarDedicatedTest/masterserver.cpp b/NorthstarDedicatedTest/masterserver.cpp
index a87dfb20..f8e9a6fa 100644
--- a/NorthstarDedicatedTest/masterserver.cpp
+++ b/NorthstarDedicatedTest/masterserver.cpp
@@ -7,6 +7,7 @@
#include "hookutils.h"
#include "serverauthentication.h"
#include "gameutils.h"
+#include "hoststate.h"
#include "tier0.h"
#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
@@ -17,8 +18,6 @@
#include <cstring>
#include <regex>
#include "version.h"
-// NOTE for anyone reading this: we used to use httplib for requests here, but it had issues, so we're moving to curl now for masterserver
-// requests so httplib is used exclusively for server stuff now
ConVar* Cvar_ns_masterserver_hostname;
ConVar* Cvar_ns_report_server_to_masterserver;
@@ -36,18 +35,6 @@ ConVar* Cvar_hostport;
MasterServerManager* g_MasterServerManager;
-typedef void (*CHostState__State_NewGameType)(CHostState* hostState);
-CHostState__State_NewGameType CHostState__State_NewGame;
-
-typedef void (*CHostState__State_ChangeLevelMPType)(CHostState* hostState);
-CHostState__State_ChangeLevelMPType CHostState__State_ChangeLevelMP;
-
-typedef void (*CHostState__State_ChangeLevelSPType)(CHostState* hostState);
-CHostState__State_ChangeLevelSPType CHostState__State_ChangeLevelSP;
-
-typedef void (*CHostState__State_GameShutdownType)(CHostState* hostState);
-CHostState__State_GameShutdownType CHostState__State_GameShutdown;
-
// Convert a hex digit char to integer.
inline int hctod(char c)
{
@@ -168,7 +155,7 @@ size_t CurlWriteToStringBufferCallback(char* contents, size_t size, size_t nmemb
return size * nmemb;
}
-void MasterServerManager::AuthenticateOriginWithMasterServer(char* uid, char* originToken)
+void MasterServerManager::AuthenticateOriginWithMasterServer(const char* uid, const char* originToken)
{
if (m_bOriginAuthWithMasterServerInProgress)
return;
@@ -519,7 +506,7 @@ void MasterServerManager::RequestMainMenuPromos()
requestThread.detach();
}
-void MasterServerManager::AuthenticateWithOwnServer(char* uid, char* playerToken)
+void MasterServerManager::AuthenticateWithOwnServer(const char* uid, const char* playerToken)
{
// dont wait, just stop if we're trying to do 2 auth requests at once
if (m_bAuthenticatingWithGameServer)
@@ -645,7 +632,7 @@ void MasterServerManager::AuthenticateWithOwnServer(char* uid, char* playerToken
requestThread.detach();
}
-void MasterServerManager::AuthenticateWithServer(char* uid, char* playerToken, char* serverId, char* password)
+void MasterServerManager::AuthenticateWithServer(const char* uid, const char* playerToken, const char* serverId, const char* password)
{
// dont wait, just stop if we're trying to do 2 auth requests at once
if (m_bAuthenticatingWithGameServer)
@@ -767,7 +754,14 @@ void MasterServerManager::AuthenticateWithServer(char* uid, char* playerToken, c
}
void MasterServerManager::AddSelfToServerList(
- int port, int authPort, char* name, char* description, char* map, char* playlist, int maxPlayers, char* password)
+ int port,
+ int authPort,
+ const char* name,
+ const char* description,
+ const char* map,
+ const char* playlist,
+ int maxPlayers,
+ const char* password)
{
if (!Cvar_ns_report_server_to_masterserver->GetBool())
return;
@@ -917,7 +911,7 @@ 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* escapedMapNew = curl_easy_escape(curl, R2::g_pHostState->m_levelName, NULL);
char* escapedPlaylistNew = curl_easy_escape(curl, R2::GetCurrentPlaylistName(), NULL);
char* escapedPasswordNew = curl_easy_escape(curl, Cvar_ns_server_password->GetString(), NULL);
@@ -1016,7 +1010,7 @@ void MasterServerManager::AddSelfToServerList(
requestThread.detach();
}
-void MasterServerManager::UpdateServerMapAndPlaylist(char* map, char* playlist, int maxPlayers)
+void MasterServerManager::UpdateServerMapAndPlaylist(const char* map, const char* playlist, int maxPlayers)
{
// dont call this if we don't have a server id
if (!*m_sOwnServerId)
@@ -1106,7 +1100,7 @@ void MasterServerManager::UpdateServerPlayerCount(int playerCount)
requestThread.detach();
}
-void MasterServerManager::WritePlayerPersistentData(char* playerId, char* pdata, size_t pdataSize)
+void MasterServerManager::WritePlayerPersistentData(const char* playerId, const char* pdata, size_t pdataSize)
{
// still call this if we don't have a server id, since lobbies that aren't port forwarded need to be able to call it
m_bSavingPersistentData = true;
@@ -1204,95 +1198,6 @@ void ConCommand_ns_fetchservers(const CCommand& args)
g_MasterServerManager->RequestServerList();
}
-// todo: this should be somewhere else, not masterserver code
-
-void CHostState__State_NewGameHook(CHostState* hostState)
-{
- Cbuf_AddText(Cbuf_GetCurrentPlayer(), "exec autoexec_ns_server", cmd_source_t::kCommandSrcCode);
- Cbuf_Execute();
-
- // need to do this to ensure we don't go to private match
- if (g_ServerAuthenticationManager->m_bNeedLocalAuthForNewgame)
- 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
- if (!strncmp(g_pHostState->m_levelName, "sp_", 3))
- {
- Cbuf_AddText(Cbuf_GetCurrentPlayer(), "net_data_block_enabled 1", cmd_source_t::kCommandSrcCode);
- Cbuf_Execute();
- }
-
- double dStartTime = Tier0::Plat_FloatTime();
- CHostState__State_NewGame(hostState);
- spdlog::info("loading took {}s", Tier0::Plat_FloatTime() - dStartTime);
-
- int maxPlayers = 6;
- const char* maxPlayersVar = R2::GetCurrentPlaylistVar("max_players", false);
- if (maxPlayersVar) // GetCurrentPlaylistVar can return null so protect against this
- maxPlayers = std::stoi(maxPlayersVar);
-
- // Copy new server name cvar to source
- Cvar_hostname->SetValue(Cvar_ns_server_name->GetString());
-
- g_MasterServerManager->AddSelfToServerList(
- Cvar_hostport->GetInt(),
- Cvar_ns_player_auth_port->GetInt(),
- (char*)Cvar_ns_server_name->GetString(),
- (char*)Cvar_ns_server_desc->GetString(),
- hostState->m_levelName,
- (char*)R2::GetCurrentPlaylistName(),
- maxPlayers,
- (char*)Cvar_ns_server_password->GetString());
- g_ServerAuthenticationManager->StartPlayerAuthServer();
- g_ServerAuthenticationManager->m_bNeedLocalAuthForNewgame = false;
-}
-
-void CHostState__State_ChangeLevelMPHook(CHostState* hostState)
-{
- int maxPlayers = 6;
- const char* maxPlayersVar = R2::GetCurrentPlaylistVar("max_players", false);
- if (maxPlayersVar) // GetCurrentPlaylistVar can return null so protect against this
- maxPlayers = std::stoi(maxPlayersVar);
-
- // 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
- if (!strncmp(g_pHostState->m_levelName, "sp_", 3))
- {
- Cbuf_AddText(Cbuf_GetCurrentPlayer(), "net_data_block_enabled 1", cmd_source_t::kCommandSrcCode);
- Cbuf_Execute();
- }
-
- g_MasterServerManager->UpdateServerMapAndPlaylist(hostState->m_levelName, (char*)R2::GetCurrentPlaylistName(), maxPlayers);
-
- double dStartTime = Tier0::Plat_FloatTime();
- CHostState__State_ChangeLevelMP(hostState);
- spdlog::info("loading took {}s", Tier0::Plat_FloatTime() - dStartTime);
-}
-
-void CHostState__State_ChangeLevelSPHook(CHostState* hostState)
-{
- // is this even called? genuinely i don't think so
- // from what i can tell, it's not called on mp=>sp change or sp=>sp change
- // so idk it's fucked
-
- int maxPlayers = 6;
- 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*)R2::GetCurrentPlaylistName(), maxPlayers);
- CHostState__State_ChangeLevelSP(hostState);
-}
-
-void CHostState__State_GameShutdownHook(CHostState* hostState)
-{
- g_MasterServerManager->RemoveSelfFromServerList();
- g_ServerAuthenticationManager->StopPlayerAuthServer();
-
- CHostState__State_GameShutdown(hostState);
-}
-
MasterServerManager::MasterServerManager() : m_pendingConnectionInfo {}, m_sOwnServerId {""}, m_sOwnClientAuthToken {""} {}
ON_DLL_LOAD_RELIESON("engine.dll", MasterServer, ConCommand, [](HMODULE baseAddress)
@@ -1318,23 +1223,4 @@ ON_DLL_LOAD_RELIESON("engine.dll", MasterServer, ConCommand, [](HMODULE baseAddr
Cvar_hostport = (ConVar*)((char*)baseAddress + 0x13FA6070);
RegisterConCommand("ns_fetchservers", ConCommand_ns_fetchservers, "Fetch all servers from the masterserver", FCVAR_CLIENTDLL);
-
- HookEnabler hook;
- ENABLER_CREATEHOOK(
- hook, (char*)baseAddress + 0x16E7D0, CHostState__State_NewGameHook, reinterpret_cast<LPVOID*>(&CHostState__State_NewGame));
- ENABLER_CREATEHOOK(
- hook,
- (char*)baseAddress + 0x16E520,
- CHostState__State_ChangeLevelMPHook,
- reinterpret_cast<LPVOID*>(&CHostState__State_ChangeLevelMP));
- ENABLER_CREATEHOOK(
- hook,
- (char*)baseAddress + 0x16E5D0,
- CHostState__State_ChangeLevelSPHook,
- reinterpret_cast<LPVOID*>(&CHostState__State_ChangeLevelSP));
- ENABLER_CREATEHOOK(
- hook,
- (char*)baseAddress + 0x16E640,
- CHostState__State_GameShutdownHook,
- reinterpret_cast<LPVOID*>(&CHostState__State_GameShutdown));
}) \ No newline at end of file
diff --git a/NorthstarDedicatedTest/masterserver.h b/NorthstarDedicatedTest/masterserver.h
index ff727878..dcf6fb66 100644
--- a/NorthstarDedicatedTest/masterserver.h
+++ b/NorthstarDedicatedTest/masterserver.h
@@ -3,6 +3,20 @@
#include <WinSock2.h>
#include <string>
#include <cstring>
+
+extern ConVar* Cvar_ns_masterserver_hostname;
+extern ConVar* Cvar_ns_report_server_to_masterserver;
+extern ConVar* Cvar_ns_report_sp_server_to_masterserver;
+
+extern ConVar* Cvar_ns_server_name;
+extern ConVar* Cvar_ns_server_desc;
+extern ConVar* Cvar_ns_server_password;
+
+extern ConVar* Cvar_ns_curl_log_enable;
+
+extern ConVar* Cvar_hostname;
+extern ConVar* Cvar_hostport;
+
struct RemoteModInfo
{
public:
@@ -114,14 +128,21 @@ class MasterServerManager
void ClearServerList();
void RequestServerList();
void RequestMainMenuPromos();
- void AuthenticateOriginWithMasterServer(char* uid, char* originToken);
- void AuthenticateWithOwnServer(char* uid, char* playerToken);
- void AuthenticateWithServer(char* uid, char* playerToken, char* serverId, char* password);
- void
- AddSelfToServerList(int port, int authPort, char* name, char* description, char* map, char* playlist, int maxPlayers, char* password);
- void UpdateServerMapAndPlaylist(char* map, char* playlist, int playerCount);
+ void AuthenticateOriginWithMasterServer(const char* uid, const char* originToken);
+ void AuthenticateWithOwnServer(const char* uid, const char* playerToken);
+ void AuthenticateWithServer(const char* uid, const char* playerToken, const char* serverId, const char* password);
+ void AddSelfToServerList(
+ int port,
+ int authPort,
+ const char* name,
+ const char* description,
+ const char* map,
+ const char* playlist,
+ int maxPlayers,
+ const char* password);
+ void UpdateServerMapAndPlaylist(const char* map, const char* playlist, int playerCount);
void UpdateServerPlayerCount(int playerCount);
- void WritePlayerPersistentData(char* playerId, char* pdata, size_t pdataSize);
+ void WritePlayerPersistentData(const char* playerId, const char* pdata, size_t pdataSize);
void RemoveSelfFromServerList();
};
std::string unescape_unicode(const std::string& str);
diff --git a/NorthstarDedicatedTest/misccommands.cpp b/NorthstarDedicatedTest/misccommands.cpp
index 51891a07..d74e6e5a 100644
--- a/NorthstarDedicatedTest/misccommands.cpp
+++ b/NorthstarDedicatedTest/misccommands.cpp
@@ -3,6 +3,7 @@
#include "concommand.h"
#include "gameutils.h"
#include "playlist.h"
+#include "hoststate.h"
#include "masterserver.h"
#include "serverauthentication.h"
#include "squirrel.h"
@@ -18,8 +19,8 @@ void AddMiscConCommands()
if (arg.ArgC() < 2)
return;
- g_pHostState->m_iNextState = HS_NEW_GAME;
- strncpy(g_pHostState->m_levelName, arg.Arg(1), sizeof(g_pHostState->m_levelName));
+ R2::g_pHostState->m_iNextState = R2::HostState_t::HS_NEW_GAME;
+ strncpy(R2::g_pHostState->m_levelName, arg.Arg(1), sizeof(R2::g_pHostState->m_levelName));
});
MAKE_CONCMD(
@@ -54,8 +55,8 @@ 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?
R2::SetCurrentPlaylist("tdm");
- strcpy(g_pHostState->m_levelName, "mp_lobby");
- g_pHostState->m_iNextState = HS_NEW_GAME;
+ strcpy(R2::g_pHostState->m_levelName, "mp_lobby");
+ R2::g_pHostState->m_iNextState = R2::HostState_t::HS_NEW_GAME;
}
});
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/playlist.h b/NorthstarDedicatedTest/playlist.h
index 2ca1985f..fd5949e1 100644
--- a/NorthstarDedicatedTest/playlist.h
+++ b/NorthstarDedicatedTest/playlist.h
@@ -1,4 +1,6 @@
#pragma once
+
+// use the R2 namespace for game funcs
namespace R2
{
typedef const char* (*GetCurrentPlaylistNameType)();
diff --git a/NorthstarDedicatedTest/serverauthentication.cpp b/NorthstarDedicatedTest/serverauthentication.cpp
index 3660eada..9ac20653 100644
--- a/NorthstarDedicatedTest/serverauthentication.cpp
+++ b/NorthstarDedicatedTest/serverauthentication.cpp
@@ -7,6 +7,7 @@
#include "masterserver.h"
#include "httplib.h"
#include "gameutils.h"
+#include "hoststate.h"
#include "bansystem.h"
#include "miscserverscript.h"
#include "concommand.h"
@@ -499,7 +500,7 @@ char __fastcall CNetChan___ProcessMessagesHook(void* self, void* buf)
char ret = CNetChan___ProcessMessages(self, buf);
// check processing limits, unless we're in a level transition
- if (g_pHostState->m_iCurrentState == HostState_t::HS_RUN && ThreadInServerFrameThread())
+ if (R2::g_pHostState->m_iCurrentState == R2::HostState_t::HS_RUN && ThreadInServerFrameThread())
{
// player that sent the message
void* sender = *(void**)((char*)self + 368);