Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions primedev/Northstar.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ add_library(
"core/tier0.h"
"core/tier1.cpp"
"core/tier1.h"
"core/vanilla.h"
"core/vanilla.cpp"
"dedicated/dedicated.cpp"
"dedicated/dedicated.h"
"dedicated/dedicatedlogtoclient.cpp"
Expand Down
32 changes: 8 additions & 24 deletions primedev/client/clientauthhooks.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#include "masterserver/masterserver.h"
#include "core/convar/convar.h"
#include "client/r2client.h"
#include "core/convar/convar.h"
#include "core/vanilla.h"
#include "masterserver/masterserver.h"

AUTOHOOK_INIT()

ConVar* Cvar_ns_has_agreed_to_send_token;
char* pDummy3P = const_cast<char*>("Protocol 3: Protect the Pilot");

// mirrored in script
const int NOT_DECIDED_TO_SEND_TOKEN = 0;
Expand All @@ -17,42 +18,27 @@ AUTOHOOK(AuthWithStryder, engine.dll + 0x1843A0,
void, __fastcall, (void* a1))
// clang-format on
{
// don't attempt to do Atlas auth if we are in vanilla compatibility mode
// this prevents users from joining untrustworthy servers (unless they use a concommand or something)
if (g_pVanillaCompatibility->GetVanillaCompatibility())
{
AuthWithStryder(a1);
return;
}

// game will call this forever, until it gets a valid auth key
// so, we need to manually invalidate our key until we're authed with northstar, then we'll allow game to auth with stryder
if (!g_pMasterServerManager->m_bOriginAuthWithMasterServerDone && Cvar_ns_has_agreed_to_send_token->GetInt() != DISAGREED_TO_SEND_TOKEN)
{
// if player has agreed to send token and we aren't already authing, try to auth
if (Cvar_ns_has_agreed_to_send_token->GetInt() == AGREED_TO_SEND_TOKEN &&
!g_pMasterServerManager->m_bOriginAuthWithMasterServerInProgress)
g_pMasterServerManager->AuthenticateOriginWithMasterServer(g_pLocalPlayerUserID, g_pLocalPlayerOriginToken);

// invalidate key so auth will fail
*g_pLocalPlayerOriginToken = 0;
}

AuthWithStryder(a1);
}

char* p3PToken;

// clang-format off
AUTOHOOK(Auth3PToken, engine.dll + 0x183760,
char*, __fastcall, ())
// clang-format on
{
if (!g_pVanillaCompatibility->GetVanillaCompatibility() && g_pMasterServerManager->m_sOwnClientAuthToken[0])
{
memset(p3PToken, 0x0, 1024);
strcpy(p3PToken, "Protocol 3: Protect the Pilot");
}
// return a dummy token for northstar servers that don't need the session token stuff
// base it off serverfilter cvar since ns_is_northstar_server could be unset by an evil server
// we'll get dropped if they're faking it
if (g_pCVar->FindVar("serverfilter")->GetBool() && g_pMasterServerManager->m_sOwnClientAuthToken[0])
return pDummy3P;

return Auth3PToken();
}
Expand All @@ -61,8 +47,6 @@ ON_DLL_LOAD_CLIENT_RELIESON("engine.dll", ClientAuthHooks, ConVar, (CModule modu
{
AUTOHOOK_DISPATCH()

p3PToken = module.Offset(0x13979D80).RCast<char*>();

// this cvar will save to cfg once initially agreed with
Cvar_ns_has_agreed_to_send_token = new ConVar(
"ns_has_agreed_to_send_token",
Expand Down
29 changes: 29 additions & 0 deletions primedev/core/vanilla.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "core/vanilla.h"
#include "engine/r2engine.h"

VanillaCompatibility* g_pVanillaCompatibility;

ConVar* Cvar_ns_skip_vanilla_integrity_check;

bool VanillaCompatibility::GetVanillaCompatibility()
{
if (g_pCVar->FindVar("serverfilter")->GetBool() && !g_pCVar->FindVar("ns_is_northstar_server")->GetBool() &&
!g_pCVar->FindVar("ns_auth_allow_insecure")->GetBool())
{
// replicate old behaviour
if (Cvar_ns_skip_vanilla_integrity_check->GetBool())
return false;

Cbuf_AddText(Cbuf_GetCurrentPlayer(), "disconnect \"Server is outdated or evil\"", cmd_source_t::kCommandSrcCode);

return false;
}

return g_pCVar->FindVar("ns_is_northstar_server")->GetBool() == 0;
}

ON_DLL_LOAD_RELIESON("engine.dll", VanillaCompat, ConVar, (CModule module))
{
Cvar_ns_skip_vanilla_integrity_check =
new ConVar("ns_skip_vanilla_integrity_check", "0", FCVAR_NONE, "Skip vanilla integrity check for compatibility with older servers");
}
23 changes: 2 additions & 21 deletions primedev/core/vanilla.h
Original file line number Diff line number Diff line change
@@ -1,29 +1,10 @@
#pragma once

/// Determines if we are in vanilla-compatibility mode.
/// In this mode we shouldn't auth with Atlas, which prevents users from joining a
/// non-trusted server. This means that we can unrestrict client/server commands
/// as well as various other small changes for compatibility
class VanillaCompatibility
{
public:
void SetVanillaCompatibility(bool isVanilla)
{
static bool bInitialised = false;
if (bInitialised)
return;

bInitialised = true;
m_bIsVanillaCompatible = isVanilla;
}

bool GetVanillaCompatibility()
{
return m_bIsVanillaCompatible;
}

private:
bool m_bIsVanillaCompatible = false;
bool GetVanillaCompatibility();
};

inline VanillaCompatibility* g_pVanillaCompatibility;
extern VanillaCompatibility* g_pVanillaCompatibility;
18 changes: 8 additions & 10 deletions primedev/dllmain.cpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
#include "logging/logging.h"
#include "logging/crashhandler.h"
#include "config/profile.h"
#include "core/memalloc.h"
#include "core/vanilla.h"
#include "config/profile.h"
#include "plugins/plugins.h"
#include "logging/crashhandler.h"
#include "logging/logging.h"
#include "plugins/pluginmanager.h"
#include "plugins/plugins.h"
#include "server/serverpresence.h"
#include "squirrel/squirrel.h"
#include "util/version.h"
#include "util/wininfo.h"
#include "squirrel/squirrel.h"
#include "server/serverpresence.h"

#include "rapidjson/document.h"
#include "rapidjson/error/en.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#include "rapidjson/error/en.h"

#include <string.h>
#include <filesystem>
#include <string.h>

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
Expand Down Expand Up @@ -59,8 +59,6 @@ bool InitialiseNorthstar()

// determine if we are in vanilla-compatibility mode
g_pVanillaCompatibility = new VanillaCompatibility();
g_pVanillaCompatibility->SetVanillaCompatibility(strstr(GetCommandLineA(), "-vanilla") != NULL);

// Write launcher version to log
StartupLog();

Expand Down
13 changes: 9 additions & 4 deletions primedev/engine/hoststate.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
#include "engine/hoststate.h"
#include "core/tier0.h"
#include "engine/r2engine.h"
#include "masterserver/masterserver.h"
#include "plugins/pluginmanager.h"
#include "server/auth/serverauthentication.h"
#include "server/serverpresence.h"
#include "shared/playlist.h"
#include "core/tier0.h"
#include "engine/r2engine.h"
#include "shared/exploit_fixes/ns_limits.h"
#include "shared/playlist.h"
#include "squirrel/squirrel.h"
#include "plugins/pluginmanager.h"

AUTOHOOK_INIT()

CHostState* g_pHostState;

ConVar* Cvar_ns_is_northstar_server;

std::string sLastMode;

VAR_AT(engine.dll + 0x13FA6070, ConVar*, Cvar_hostport);
Expand All @@ -21,6 +23,7 @@ FUNCTION_AT(engine.dll + 0x1232C0, void, __fastcall, _Cmd_Exec_f, (const CComman
void ServerStartingOrChangingMap()
{
ConVar* Cvar_mp_gamemode = g_pCVar->FindVar("mp_gamemode");
Cvar_ns_is_northstar_server->SetValue(true);

// directly call _Cmd_Exec_f to avoid weirdness with ; being in mp_gamemode potentially
// if we ran exec {mp_gamemode} and mp_gamemode contained semicolons, this could be used to execute more commands
Expand Down Expand Up @@ -135,6 +138,7 @@ void, __fastcall, (CHostState* self))
g_pServerPresence->DestroyPresence();

CHostState__State_GameShutdown(self);
Cvar_ns_is_northstar_server->SetValue(false);

// run gamemode cleanup cfg now instead of when we start next map
if (sLastMode.length())
Expand Down Expand Up @@ -186,5 +190,6 @@ ON_DLL_LOAD_RELIESON("engine.dll", HostState, ConVar, (CModule module))
{
AUTOHOOK_DISPATCH()

Cvar_ns_is_northstar_server = new ConVar("ns_is_northstar_server", "0", FCVAR_REPLICATED, "Whether the server is a northstar server");
g_pHostState = module.Offset(0x7CF180).RCast<CHostState*>();
}
16 changes: 8 additions & 8 deletions primedev/masterserver/masterserver.cpp
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
#include "masterserver/masterserver.h"
#include "core/convar/concommand.h"
#include "shared/playlist.h"
#include "server/auth/serverauthentication.h"
#include "core/tier0.h"
#include "core/vanilla.h"
#include "dedicated/dedicated.h"
#include "engine/r2engine.h"
#include "mods/modmanager.h"
#include "server/auth/bansystem.h"
#include "server/auth/serverauthentication.h"
#include "shared/misccommands.h"
#include "shared/playlist.h"
#include "util/utils.h"
#include "util/version.h"
#include "server/auth/bansystem.h"
#include "dedicated/dedicated.h"

#include "rapidjson/document.h"
#include "rapidjson/error/en.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"
#include "rapidjson/error/en.h"

#include <cstring>
#include <regex>
Expand Down Expand Up @@ -90,7 +90,7 @@ size_t CurlWriteToStringBufferCallback(char* contents, size_t size, size_t nmemb

void MasterServerManager::AuthenticateOriginWithMasterServer(const char* uid, const char* originToken)
{
if (m_bOriginAuthWithMasterServerInProgress || g_pVanillaCompatibility->GetVanillaCompatibility())
if (m_bOriginAuthWithMasterServerInProgress)
return;

// do this here so it's instantly set
Expand Down Expand Up @@ -467,7 +467,7 @@ void MasterServerManager::RequestMainMenuPromos()
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 || g_pVanillaCompatibility->GetVanillaCompatibility())
if (m_bAuthenticatingWithGameServer)
return;

m_bAuthenticatingWithGameServer = true;
Expand Down Expand Up @@ -604,7 +604,7 @@ void MasterServerManager::AuthenticateWithOwnServer(const char* uid, const char*
void MasterServerManager::AuthenticateWithServer(const char* uid, const char* playerToken, RemoteServerInfo server, const char* password)
{
// dont wait, just stop if we're trying to do 2 auth requests at once
if (m_bAuthenticatingWithGameServer || g_pVanillaCompatibility->GetVanillaCompatibility())
if (m_bAuthenticatingWithGameServer)
return;

m_bAuthenticatingWithGameServer = true;
Expand Down
19 changes: 16 additions & 3 deletions primedev/scripts/client/scriptoriginauth.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#include "squirrel/squirrel.h"
#include "masterserver/masterserver.h"
#include "engine/r2engine.h"
#include "client/r2client.h"
#include "core/vanilla.h"
#include "engine/r2engine.h"
#include "masterserver/masterserver.h"
#include "squirrel/squirrel.h"

ADD_SQFUNC("bool", NSIsMasterServerAuthenticated, "", "", ScriptContext::UI)
{
Expand All @@ -18,6 +19,18 @@ global struct MasterServerAuthResult
}
*/

ADD_SQFUNC("void", NSResetToken, "", "", ScriptContext::UI)
{
g_pCVar->FindVar("serverfilter")->SetValue("");
return SQRESULT_NULL;
}

ADD_SQFUNC("bool", NSIsVanilla, "", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI)
{
g_pSquirrel<context>->pushbool(sqvm, g_pVanillaCompatibility->GetVanillaCompatibility());
return SQRESULT_NOTNULL;
}

ADD_SQFUNC("MasterServerAuthResult", NSGetMasterServerAuthResult, "", "", ScriptContext::UI)
{
g_pSquirrel<context>->pushnewstructinstance(sqvm, 3);
Expand Down
3 changes: 0 additions & 3 deletions primedev/shared/playlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,4 @@ ON_DLL_LOAD_RELIESON("engine.dll", PlaylistHooks, (ConCommand, ConVar), (CModule
// 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
module.Offset(0x18ED8D).Patch("C3");

// patch to allow setplaylistvaroverride to be called before map init on dedicated and private match launched through the game
module.Offset(0x18ED17).NOP(6);
}
17 changes: 7 additions & 10 deletions primedev/squirrel/squirrel.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
#include "squirrel.h"
#include "mods/modsavefiles.h"
#include "logging/logging.h"
#include "core/convar/concommand.h"
#include "mods/modmanager.h"
#include "core/tier0.h"
#include "core/vanilla.h"
#include "dedicated/dedicated.h"
#include "engine/r2engine.h"
#include "core/tier0.h"
#include "plugins/plugins.h"
#include "plugins/pluginmanager.h"
#include "logging/logging.h"
#include "mods/modmanager.h"
#include "mods/modsavefiles.h"
#include "ns_version.h"
#include "core/vanilla.h"
#include "plugins/pluginmanager.h"
#include "plugins/plugins.h"

#include <any>

Expand Down Expand Up @@ -202,9 +202,6 @@ template <ScriptContext context> void SquirrelManager<context>::VMCreated(CSquir
defconst(m_pSQVM, "NS_VERSION_PATCH", version[2]);
defconst(m_pSQVM, "NS_VERSION_DEV", version[3]);

// define squirrel constant for if we are in vanilla-compatibility mode
defconst(m_pSQVM, "VANILLA", g_pVanillaCompatibility->GetVanillaCompatibility());

g_pSquirrel<context>->messageBuffer = new SquirrelMessageBuffer();
g_pPluginManager->InformSqvmCreated(newSqvm);
}
Expand Down