From eb56fcbe02f35ed4f418a7dc53cd9eb0ad95a504 Mon Sep 17 00:00:00 2001
From: BobTheBob <32057864+BobTheBob9@users.noreply.github.com>
Date: Mon, 2 Aug 2021 03:20:10 +0100
Subject: add dynamic keyvalue building, client serverbrowser stuff
---
.../NorthstarDedicatedTest.vcxproj | 4 +
.../NorthstarDedicatedTest.vcxproj.filters | 12 +++
NorthstarDedicatedTest/convar.cpp | 4 +-
NorthstarDedicatedTest/convar.h | 2 +-
NorthstarDedicatedTest/dllmain.cpp | 2 +
NorthstarDedicatedTest/filesystem.cpp | 16 +++-
NorthstarDedicatedTest/keyvalues.cpp | 96 +++++++++++++++++++
NorthstarDedicatedTest/keyvalues.h | 1 +
NorthstarDedicatedTest/modmanager.cpp | 54 +++++++++--
NorthstarDedicatedTest/modmanager.h | 9 +-
NorthstarDedicatedTest/scriptmodmenu.cpp | 13 ++-
NorthstarDedicatedTest/scriptserverbrowser.cpp | 103 +++++++++++++++++++++
NorthstarDedicatedTest/scriptserverbrowser.h | 4 +
NorthstarDedicatedTest/scriptsrson.cpp | 1 -
NorthstarDedicatedTest/serverauthentication.cpp | 32 ++++---
NorthstarDedicatedTest/serverauthentication.h | 2 +-
NorthstarDedicatedTest/squirrel.cpp | 5 +
NorthstarDedicatedTest/squirrel.h | 4 +
18 files changed, 330 insertions(+), 34 deletions(-)
create mode 100644 NorthstarDedicatedTest/keyvalues.cpp
create mode 100644 NorthstarDedicatedTest/keyvalues.h
create mode 100644 NorthstarDedicatedTest/scriptserverbrowser.cpp
create mode 100644 NorthstarDedicatedTest/scriptserverbrowser.h
diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj
index 203edbb3..4e3a5bc0 100644
--- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj
+++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj
@@ -303,11 +303,13 @@
+
+
@@ -325,6 +327,7 @@
+
@@ -334,6 +337,7 @@
Create
+
diff --git a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters
index 71bae5bc..cb78dff1 100644
--- a/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters
+++ b/NorthstarDedicatedTest/NorthstarDedicatedTest.vcxproj.filters
@@ -537,6 +537,12 @@
Header Files\Client
+
+ Header Files\Client
+
+
+ Header Files\Shared\Mods\Compiled
+
@@ -596,6 +602,12 @@
Source Files\Client
+
+ Source Files\Client
+
+
+ Source Files\Shared\Mods\Compiled
+
diff --git a/NorthstarDedicatedTest/convar.cpp b/NorthstarDedicatedTest/convar.cpp
index 3bb95a95..156301b6 100644
--- a/NorthstarDedicatedTest/convar.cpp
+++ b/NorthstarDedicatedTest/convar.cpp
@@ -3,7 +3,7 @@
#include
// should this be in modmanager?
-std::set g_CustomConvars; // this is used in modloading code to determine whether we've registered a mod convar already
+std::unordered_map g_CustomConvars; // this is used in modloading code to determine whether we've registered a mod convar already
typedef void(*ConVarConstructorType)(ConVar* newVar, const char* name, const char* defaultValue, int flags, const char* helpString);
ConVarConstructorType conVarConstructor;
@@ -16,7 +16,7 @@ ConVar* RegisterConVar(const char* name, const char* defaultValue, int flags, co
ConVar* newVar = new ConVar;
conVarConstructor(newVar, name, defaultValue, flags, helpString);
- g_CustomConvars.insert(name);
+ g_CustomConvars.insert(std::make_pair(name, newVar));
return newVar;
}
diff --git a/NorthstarDedicatedTest/convar.h b/NorthstarDedicatedTest/convar.h
index adfd585f..f2e35188 100644
--- a/NorthstarDedicatedTest/convar.h
+++ b/NorthstarDedicatedTest/convar.h
@@ -103,4 +103,4 @@ public:
ConVar* RegisterConVar(const char* name, const char* defaultValue, int flags, const char* helpString);
void InitialiseConVars(HMODULE baseAddress);
-extern std::set g_CustomConvars;
\ No newline at end of file
+extern std::unordered_map g_CustomConvars;
\ No newline at end of file
diff --git a/NorthstarDedicatedTest/dllmain.cpp b/NorthstarDedicatedTest/dllmain.cpp
index b0040598..4e347d05 100644
--- a/NorthstarDedicatedTest/dllmain.cpp
+++ b/NorthstarDedicatedTest/dllmain.cpp
@@ -10,6 +10,7 @@
#include "filesystem.h"
#include "serverauthentication.h"
#include "scriptmodmenu.h"
+#include "scriptserverbrowser.h"
bool initialised = false;
@@ -56,6 +57,7 @@ void InitialiseNorthstar()
AddDllLoadCallback("client.dll", InitialiseSourceConsole);
AddDllLoadCallback("client.dll", InitialiseScriptModMenu);
+ AddDllLoadCallback("client.dll", InitialiseScriptServerBrowser);
}
AddDllLoadCallback("server.dll", InitialiseServerSquirrel);
diff --git a/NorthstarDedicatedTest/filesystem.cpp b/NorthstarDedicatedTest/filesystem.cpp
index 323b8756..15b8b4dd 100644
--- a/NorthstarDedicatedTest/filesystem.cpp
+++ b/NorthstarDedicatedTest/filesystem.cpp
@@ -88,12 +88,13 @@ void SetNewModSearchPaths(Mod* mod)
}
-bool TryReplaceFile(char* path)
+bool TryReplaceFile(char* path, bool shouldCompile)
{
if (readingOriginalFile)
return false;
- (*g_ModManager).CompileAssetsForFile(path);
+ if (shouldCompile)
+ (*g_ModManager).CompileAssetsForFile(path);
// idk how efficient the lexically normal check is
// can't just set all /s in path to \, since some paths aren't in writeable memory
@@ -111,7 +112,9 @@ FileHandle_t ReadFileFromVPKHook(VPKData* vpkInfo, __int64* b, char* filename)
{
// move this to a convar at some point when we can read them in native
//spdlog::info("ReadFileFromVPKHook {} {}", filename, vpkInfo->path);
- if (TryReplaceFile(filename))
+
+ // there is literally never any reason to compile here, since we'll always compile in ReadFileFromFilesystemHook in the same codepath this is called
+ if (TryReplaceFile(filename, false))
{
*b = -1;
return b;
@@ -125,7 +128,7 @@ bool ReadFromCacheHook(IFileSystem* filesystem, char* path, void* result)
// move this to a convar at some point when we can read them in native
//spdlog::info("ReadFromCacheHook {}", path);
- if (TryReplaceFile(path))
+ if (TryReplaceFile(path, true))
return false;
return readFromCache(filesystem, path, result);
@@ -146,6 +149,9 @@ void AddSearchPathHook(IFileSystem* fileSystem, const char* pPath, const char* p
FileHandle_t ReadFileFromFilesystemHook(IFileSystem* filesystem, const char* pPath, const char* pOptions, int64_t a4, uint32_t a5)
{
// this isn't super efficient, but it's necessary, since calling addsearchpath in readfilefromvpk doesn't work, possibly refactor later
- TryReplaceFile((char*)pPath);
+ // it also might be possible to hook functions that are called later, idk look into callstack for ReadFileFromVPK
+ if (!readingOriginalFile)
+ TryReplaceFile((char*)pPath, true);
+
return readFileFromFilesystem(filesystem, pPath, pOptions, a4, a5);
}
\ No newline at end of file
diff --git a/NorthstarDedicatedTest/keyvalues.cpp b/NorthstarDedicatedTest/keyvalues.cpp
new file mode 100644
index 00000000..b2c278c6
--- /dev/null
+++ b/NorthstarDedicatedTest/keyvalues.cpp
@@ -0,0 +1,96 @@
+#include "pch.h"
+#include "keyvalues.h"
+#include "modmanager.h"
+#include "filesystem.h"
+
+#include
+
+void ModManager::TryBuildKeyValues(const char* filename)
+{
+ spdlog::info("Building KeyValues for file {}", filename);
+
+ std::string normalisedPath = fs::path(filename).lexically_normal().string();
+ fs::path compiledPath = COMPILED_ASSETS_PATH / filename;
+ fs::path compiledDir = compiledPath.parent_path();
+ fs::create_directories(compiledDir);
+
+ fs::path kvPath(filename);
+ std::string ogFilePath = "mod_original_";
+ ogFilePath += kvPath.filename().string();
+
+ std::string newKvs = "// AUTOGENERATED: MOD PATCH KV\n";
+
+ int patchNum = 0;
+
+ // copy over patch kv files, and add #includes to new file, last mods' patches should be applied first
+ for (int i = m_loadedMods.size() - 1; i > -1; i--)
+ {
+ size_t fileHash = std::hash{}(normalisedPath);
+ for (int j = 0; j < m_loadedMods[i]->KeyValuesHash.size(); j++)
+ {
+ if (fileHash == m_loadedMods[i]->KeyValuesHash[j])
+ {
+ // should result in smth along the lines of #include "mod_patch_5_mp_weapon_car.txt"
+
+ std::string patchFilePath = "mod_patch_";
+ patchFilePath += std::to_string(patchNum++);
+ patchFilePath += "_";
+ patchFilePath += kvPath.filename().string();
+
+ newKvs += "#base \"";
+ newKvs += patchFilePath;
+ newKvs += "\"\n";
+
+ fs::remove(compiledDir / patchFilePath);
+
+ fs::copy_file(m_loadedMods[i]->ModDirectory / "keyvalues" / filename, compiledDir / patchFilePath);
+ }
+ }
+ }
+
+ newKvs += "#base \"";
+ newKvs += ogFilePath;
+ newKvs += "\"\n";
+
+ // load original file, so we can parse out the name of the root obj (e.g. WeaponData for weapons)
+ std::string originalFile = ReadVPKOriginalFile(filename);
+ char rootName[64];
+ memset(rootName, 0, sizeof(rootName));
+
+ // iterate over all lines that aren't empty, and don't start with #s or //s, first one should be the name of the root obj
+ int i = 0;
+ while (!(originalFile[i] >= 65 && originalFile[i] <= 122))
+ {
+ // if we hit a comment or # thing, iterate until end of line
+ if (originalFile[i] == '/' || originalFile[i] == '#')
+ while (originalFile[i] != '\n')
+ i++;
+
+ i++;
+ }
+
+ int j = 0;
+ for (int j = 0; originalFile[i] >= 65 && originalFile[i] <= 122; j++)
+ rootName[j] = originalFile[i++];
+
+ // empty kv, all the other stuff gets #base'd or #include'd
+ newKvs += rootName;
+ newKvs += "\n{\n}\n";
+
+ std::ofstream originalFileWriteStream(compiledDir / ogFilePath);
+ originalFileWriteStream << originalFile;
+ originalFileWriteStream.close();
+
+ std::ofstream writeStream(compiledPath);
+ writeStream << newKvs;
+ writeStream.close();
+
+ ModOverrideFile* overrideFile = new ModOverrideFile;
+ overrideFile->owningMod = nullptr;
+ overrideFile->path = normalisedPath;
+
+ if (m_modFiles.find(normalisedPath) == m_modFiles.end())
+ m_modFiles.insert(std::make_pair(normalisedPath, overrideFile));
+ else
+ m_modFiles[normalisedPath] = overrideFile;
+}
\ No newline at end of file
diff --git a/NorthstarDedicatedTest/keyvalues.h b/NorthstarDedicatedTest/keyvalues.h
new file mode 100644
index 00000000..7b9637ef
--- /dev/null
+++ b/NorthstarDedicatedTest/keyvalues.h
@@ -0,0 +1 @@
+#pragma once
\ No newline at end of file
diff --git a/NorthstarDedicatedTest/modmanager.cpp b/NorthstarDedicatedTest/modmanager.cpp
index ae1ad98a..faca09c4 100644
--- a/NorthstarDedicatedTest/modmanager.cpp
+++ b/NorthstarDedicatedTest/modmanager.cpp
@@ -173,10 +173,7 @@ ModManager::ModManager()
void ModManager::LoadMods()
{
- // this needs better support for reloads
-
- // do we need to dealloc individual entries in m_loadedMods? idk, rework
- m_loadedMods.clear();
+ UnloadMods();
std::vector modDirs;
@@ -228,6 +225,11 @@ void ModManager::LoadMods()
for (Mod* mod : m_loadedMods)
{
+ mod->KeyValuesHash.clear();
+
+ if (!mod->Enabled)
+ continue;
+
// register convars
// for reloads, this is sorta barebones, when we have a good findconvar method, we could probably reset flags and stuff on preexisting convars
// potentially it might also be good to unregister convars if they get removed on a reload, but unsure if necessary
@@ -240,11 +242,27 @@ void ModManager::LoadMods()
for (fs::directory_entry file : fs::directory_iterator(mod->ModDirectory / "vpk"))
if (fs::is_regular_file(file) && file.path().extension() == "vpk")
mod->Vpks.push_back(file.path().string());
+
+ if (fs::exists(mod->ModDirectory / "keyvalues"))
+ {
+ for (fs::directory_entry file : fs::recursive_directory_iterator(mod->ModDirectory / "keyvalues"))
+ {
+ if (fs::is_regular_file(file) && !file.path().extension().compare(".txt"))
+ {
+ std::string kvStr = file.path().lexically_relative(mod->ModDirectory / "keyvalues").lexically_normal().string();
+ mod->KeyValuesHash.push_back(std::hash{}(kvStr));
+ mod->KeyValues.push_back(kvStr);
+ }
+ }
+ }
}
// in a seperate loop because we register mod files in reverse order, since mods loaded later should have their files prioritised
for (int i = m_loadedMods.size() - 1; i > -1; i--)
{
+ if (!m_loadedMods[i]->Enabled)
+ continue;
+
if (fs::exists(m_loadedMods[i]->ModDirectory / MOD_OVERRIDE_DIR))
{
for (fs::directory_entry file : fs::recursive_directory_iterator(m_loadedMods[i]->ModDirectory / MOD_OVERRIDE_DIR))
@@ -253,7 +271,6 @@ void ModManager::LoadMods()
if (file.is_regular_file() && m_modFiles.find(path.string()) == m_modFiles.end())
{
- // super temp because it relies hard on load order
ModOverrideFile* modFile = new ModOverrideFile;
modFile->owningMod = m_loadedMods[i];
modFile->path = path;
@@ -264,13 +281,38 @@ void ModManager::LoadMods()
}
}
+void ModManager::UnloadMods()
+{
+ // clean up stuff from mods before we unload
+
+ // remove all built kvs
+ for (Mod* mod : m_loadedMods)
+ for (std::string kvPaths : mod->KeyValues)
+ fs::remove(COMPILED_ASSETS_PATH / fs::path(kvPaths).lexically_relative(mod->ModDirectory));
+
+ // do we need to dealloc individual entries in m_loadedMods? idk, rework
+ m_loadedMods.clear();
+}
+
void ModManager::CompileAssetsForFile(const char* filename)
{
fs::path path(filename);
if (!path.filename().compare("scripts.rson"))
BuildScriptsRson();
-
+ else if (!strcmp((filename + strlen(filename)) - 3, "txt")) // check if it's a .txt
+ {
+ // check if we should build keyvalues, depending on whether any of our mods have patch kvs for this file
+ for (Mod* mod : m_loadedMods)
+ {
+ size_t fileHash = std::hash{}(fs::path(filename).lexically_normal().string());
+ if (std::find(mod->KeyValuesHash.begin(), mod->KeyValuesHash.end(), fileHash) != mod->KeyValuesHash.end())
+ {
+ TryBuildKeyValues(filename);
+ return;
+ }
+ }
+ }
}
void ReloadModsCommand(const CCommand& args)
diff --git a/NorthstarDedicatedTest/modmanager.h b/NorthstarDedicatedTest/modmanager.h
index 6146de0a..ad5e74ff 100644
--- a/NorthstarDedicatedTest/modmanager.h
+++ b/NorthstarDedicatedTest/modmanager.h
@@ -1,4 +1,5 @@
#pragma once
+#include "convar.h"
#include
#include
#include
@@ -45,7 +46,9 @@ public:
class Mod
{
public:
+ // runtime stuff
fs::path ModDirectory;
+ bool Enabled = true;
// mod.json stuff:
@@ -71,7 +74,8 @@ public:
// other files:
std::vector Vpks;
- //std::vector KeyValues;
+ std::vector KeyValues;
+ std::vector KeyValuesHash; // size_t because we hash these filesnames: faster than string comp
// other stuff
@@ -92,16 +96,17 @@ class ModManager
{
public:
std::vector m_loadedMods;
- //std::vector m_modFiles;
std::unordered_map m_modFiles;
public:
ModManager();
void LoadMods();
+ void UnloadMods();
void CompileAssetsForFile(const char* filename);
// compile asset type stuff, these are done in files under Mods/Compiled/
void BuildScriptsRson();
+ void TryBuildKeyValues(const char* filename);
};
void InitialiseModManager(HMODULE baseAddress);
diff --git a/NorthstarDedicatedTest/scriptmodmenu.cpp b/NorthstarDedicatedTest/scriptmodmenu.cpp
index f65b3a8c..cb19e48f 100644
--- a/NorthstarDedicatedTest/scriptmodmenu.cpp
+++ b/NorthstarDedicatedTest/scriptmodmenu.cpp
@@ -113,12 +113,21 @@ SQInteger SQ_GetModConvars(void* sqvm)
return 1; // return empty array
}
+// void NSReloadMods()
+SQInteger SQ_ReloadMods(void* sqvm)
+{
+ g_ModManager->LoadMods();
+ return 0;
+}
+
void InitialiseScriptModMenu(HMODULE baseAddress)
{
g_UISquirrelManager->AddFuncRegistration("array", "NSGetModNames", "", "Returns the names of all loaded mods", SQ_GetModNames);
- g_UISquirrelManager->AddFuncRegistration("string", "NSGetModDescriptionByModName", "asset modName", "Returns a given mod's description", SQ_GetModDescription);
+ g_UISquirrelManager->AddFuncRegistration("string", "NSGetModDescriptionByModName", "string modName", "Returns a given mod's description", SQ_GetModDescription);
g_UISquirrelManager->AddFuncRegistration("string", "NSGetModVersionByModName", "string modName", "Returns a given mod's version", SQ_GetModVersion);
- g_UISquirrelManager->AddFuncRegistration("string", "NSGetModDownloadLinkByModName", "string modName", "Returns a given mod's download link", SQ_GetModVersion);
+ g_UISquirrelManager->AddFuncRegistration("string", "NSGetModDownloadLinkByModName", "string modName", "Returns a given mod's download link", SQ_GetModDownloadLink);
g_UISquirrelManager->AddFuncRegistration("int", "NSGetModLoadPriority", "string modName", "Returns a given mod's load priority", SQ_GetModLoadPriority);
g_UISquirrelManager->AddFuncRegistration("array", "NSGetModConvarsByModName", "string modName", "Returns the names of all a given mod's cvars", SQ_GetModConvars);
+
+ g_UISquirrelManager->AddFuncRegistration("void", "NSReloadMods", "", "Reloads mods", SQ_ReloadMods);
}
\ No newline at end of file
diff --git a/NorthstarDedicatedTest/scriptserverbrowser.cpp b/NorthstarDedicatedTest/scriptserverbrowser.cpp
new file mode 100644
index 00000000..2f1c95a4
--- /dev/null
+++ b/NorthstarDedicatedTest/scriptserverbrowser.cpp
@@ -0,0 +1,103 @@
+#include "pch.h"
+#include "scriptserverbrowser.h"
+#include "squirrel.h"
+
+// functions for viewing server browser
+
+// bool function NSPollServerPage( int page )
+SQInteger SQ_PollServerPage(void* sqvm)
+{
+ SQInteger page = ClientSq_getinteger(sqvm, 1);
+
+ ClientSq_pushbool(sqvm, true);
+ return 1;
+}
+
+// int function NSGetNumServersOnPage( int page )
+SQInteger SQ_GetNumServersOnPage(void* sqvm)
+{
+ SQInteger page = ClientSq_getinteger(sqvm, 1);
+
+ ClientSq_pushinteger(sqvm, 1);
+ return 1;
+}
+
+// string function NSGetServerName( int page, int serverIndex )
+SQInteger SQ_GetServerName(void* sqvm)
+{
+ SQInteger page = ClientSq_getinteger(sqvm, 1);
+ SQInteger serverIndex = ClientSq_getinteger(sqvm, 2);
+
+ ClientSq_pushstring(sqvm, "cool", -1);
+ return 1;
+}
+
+// string function NSGetServerMap( int page, int serverIndex )
+SQInteger SQ_GetServerMap(void* sqvm)
+{
+ SQInteger page = ClientSq_getinteger(sqvm, 1);
+ SQInteger serverIndex = ClientSq_getinteger(sqvm, 2);
+
+ ClientSq_pushstring(sqvm, "mp_thaw", -1);
+ return 1;
+}
+
+// string function NSGetServerMode( int page, int serverIndex )
+SQInteger SQ_GetServerMode(void* sqvm)
+{
+ SQInteger page = ClientSq_getinteger(sqvm, 1);
+ SQInteger serverIndex = ClientSq_getinteger(sqvm, 2);
+
+ ClientSq_pushstring(sqvm, "ffa", -1);
+ return 1;
+}
+
+// string function NSGetServerID( int page, int serverIndex )
+SQInteger SQ_GetServerID(void* sqvm)
+{
+
+ return 0;
+}
+
+// void function NSResetRecievedServers()
+SQInteger SQ_ResetRecievedServers(void* sqvm)
+{
+ return 0;
+}
+
+
+// functions for authenticating with servers
+
+// void function NSTryAuthWithServer( string serverId )
+SQInteger SQ_TryAuthWithServer(void* sqvm)
+{
+ return 0;
+}
+
+// int function NSWasAuthSuccessful()
+SQInteger SQ_WasAuthSuccessful(void* sqvm)
+{
+ return 0;
+}
+
+// string function NSTryGetAuthedServerAddress()
+SQInteger SQ_TryGetAuthedServerAddress(void* sqvm)
+{
+ return 0;
+}
+
+// string function NSTryGetAuthedServerToken()
+SQInteger SQ_TryGetAuthedServerToken(void* sqvm)
+{
+ return 0;
+}
+
+void InitialiseScriptServerBrowser(HMODULE baseAddress)
+{
+ g_UISquirrelManager->AddFuncRegistration("bool", "NSPollServerPage", "int page", "", SQ_PollServerPage);
+ g_UISquirrelManager->AddFuncRegistration("int", "NSGetNumServersOnPage", "int page", "", SQ_GetNumServersOnPage);
+ g_UISquirrelManager->AddFuncRegistration("string", "NSGetServerName", "int page, int serverIndex", "", SQ_GetServerName);
+ g_UISquirrelManager->AddFuncRegistration("string", "NSGetServerMap", "int page, int serverIndex", "", SQ_GetServerMap);
+ g_UISquirrelManager->AddFuncRegistration("string", "NSGetServerMode", "int page, int serverIndex", "", SQ_GetServerMode);
+ g_UISquirrelManager->AddFuncRegistration("void", "NSResetRecievedServers", "", "", SQ_ResetRecievedServers);
+}
\ No newline at end of file
diff --git a/NorthstarDedicatedTest/scriptserverbrowser.h b/NorthstarDedicatedTest/scriptserverbrowser.h
new file mode 100644
index 00000000..55776de0
--- /dev/null
+++ b/NorthstarDedicatedTest/scriptserverbrowser.h
@@ -0,0 +1,4 @@
+#pragma once
+#include
+
+void InitialiseScriptServerBrowser(HMODULE baseAddress);
\ No newline at end of file
diff --git a/NorthstarDedicatedTest/scriptsrson.cpp b/NorthstarDedicatedTest/scriptsrson.cpp
index 9c590280..bc49ed26 100644
--- a/NorthstarDedicatedTest/scriptsrson.cpp
+++ b/NorthstarDedicatedTest/scriptsrson.cpp
@@ -4,7 +4,6 @@
#include "filesystem.h"
#include "squirrel.h"
-#include
#include
void ModManager::BuildScriptsRson()
diff --git a/NorthstarDedicatedTest/serverauthentication.cpp b/NorthstarDedicatedTest/serverauthentication.cpp
index d6f3b2b2..ffc21a8b 100644
--- a/NorthstarDedicatedTest/serverauthentication.cpp
+++ b/NorthstarDedicatedTest/serverauthentication.cpp
@@ -7,7 +7,7 @@
// hook types
-typedef void*(*CBaseServer__ConnectClientType)(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, void* a15, uint32_t a16, uint32_t a17);
+typedef void*(*CBaseServer__ConnectClientType)(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);
CBaseServer__ConnectClientType CBaseServer__ConnectClient;
typedef char(*CBaseClient__ConnectType)(void* self, char* name, __int64 netchan_ptr_arg, char b_fake_player_arg, __int64 a5, char* Buffer, int a7);
@@ -34,16 +34,19 @@ void ServerAuthenticationManager::AddPlayerAuth(char* authToken, char* uid, char
}
-bool ServerAuthenticationManager::AuthenticatePlayer(void* player, char* authToken)
+bool ServerAuthenticationManager::AuthenticatePlayer(void* player, int64_t uid, char* authToken)
{
- // straight up just given up
+ std::string strUid = std::to_string(uid);
+
if (!m_authData.empty() && m_authData.count(authToken))
{
// use stored auth data
AuthData* authData = m_authData[authToken];
-
+ if (strcmp(strUid.c_str(), authData->uid)) // connecting client's uid is different from auth's uid
+ return false;
+
// uuid
- strcpy((char*)player + 0xF500, authData->uid);
+ strcpy((char*)player + 0xF500, strUid.c_str());
// copy pdata into buffer
memcpy((char*)player + 0x4FA, authData->pdata, authData->pdataSize);
@@ -56,14 +59,13 @@ bool ServerAuthenticationManager::AuthenticatePlayer(void* player, char* authTok
if (!CVar_ns_auth_allow_insecure->m_nValue) // no auth data and insecure connections aren't allowed, so dc the client
return false;
- // insecure connections are allowed, try reading from disk, using authtoken as uid
-
+ // insecure connections are allowed, try reading from disk
// uuid
- strcpy((char*)player + 0xF500, authToken);
+ strcpy((char*)player + 0xF500, strUid.c_str());
// try reading pdata file for player
std::string pdataPath = "playerdata/playerdata_";
- pdataPath += authToken;
+ pdataPath += strUid;
pdataPath += ".pdata";
std::fstream pdataStream(pdataPath, std::ios_base::in);
@@ -120,16 +122,18 @@ void ServerAuthenticationManager::WritePersistentData(void* player)
// auth hooks
-// store this in a var so we can use it in CBaseClient::Connect
-// this is fine because serverfilter ptr won't decay by the time we use this, just don't use it outside of cbaseclient::connect
+// 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;
-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, void* a15, uint32_t a16, uint32_t a17)
+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)
{
// auth tokens are sent with serverfilter, can't be accessed from player struct to my knowledge, so have to do this here
nextPlayerToken = serverFilter;
+ nextPlayerUid = uid;
- return CBaseServer__ConnectClient(server, a2, a3, a4, a5, a6, a7, a8, serverFilter, a10, a11, a12, a13, a14, a15, a16, a17);
+ return CBaseServer__ConnectClient(server, a2, a3, a4, a5, a6, a7, a8, serverFilter, a10, a11, a12, a13, a14, uid, a16, a17);
}
char CBaseClient__ConnectHook(void* self, char* name, __int64 netchan_ptr_arg, char b_fake_player_arg, __int64 a5, char* Buffer, int a7)
@@ -139,7 +143,7 @@ char CBaseClient__ConnectHook(void* self, char* name, __int64 netchan_ptr_arg, c
char ret = CBaseClient__Connect(self, name, netchan_ptr_arg, b_fake_player_arg, a5, Buffer, a7);
if (strlen(name) >= 64) // fix for name overflow bug
CBaseClient__Disconnect(self, 1, "Invalid name");
- else if (!g_ServerAuthenticationManager->AuthenticatePlayer(self, nextPlayerToken))
+ else if (!g_ServerAuthenticationManager->AuthenticatePlayer(self, nextPlayerUid, nextPlayerToken))
CBaseClient__Disconnect(self, 1, "Authentication Failed");
return ret;
diff --git a/NorthstarDedicatedTest/serverauthentication.h b/NorthstarDedicatedTest/serverauthentication.h
index 4301b78e..c28c882b 100644
--- a/NorthstarDedicatedTest/serverauthentication.h
+++ b/NorthstarDedicatedTest/serverauthentication.h
@@ -18,7 +18,7 @@ public:
public:
void AddPlayerAuth(char* authToken, char* uid, char* pdata, size_t pdataSize);
- bool AuthenticatePlayer(void* player, char* authToken);
+ bool AuthenticatePlayer(void* player, int64_t uid, char* authToken);
bool RemovePlayerAuthData(void* player);
void WritePersistentData(void* player);
};
diff --git a/NorthstarDedicatedTest/squirrel.cpp b/NorthstarDedicatedTest/squirrel.cpp
index 17758282..46e4708a 100644
--- a/NorthstarDedicatedTest/squirrel.cpp
+++ b/NorthstarDedicatedTest/squirrel.cpp
@@ -66,6 +66,9 @@ sq_pushintegerType ServerSq_pushinteger;
sq_pushfloatType ClientSq_pushfloat;
sq_pushfloatType ServerSq_pushfloat;
+sq_pushboolType ClientSq_pushbool;
+sq_pushboolType ServerSq_pushbool;
+
// sq stack get funcs
sq_getstringType ClientSq_getstring;
@@ -118,6 +121,7 @@ void InitialiseClientSquirrel(HMODULE baseAddress)
ClientSq_pushstring = (sq_pushstringType)((char*)baseAddress + 0x3440);
ClientSq_pushinteger = (sq_pushintegerType)((char*)baseAddress + 0x36A0);
ClientSq_pushfloat = (sq_pushfloatType)((char*)baseAddress + 0x3800);
+ ClientSq_pushbool = (sq_pushboolType)((char*)baseAddress + 0x3710);
ClientSq_getstring = (sq_getstringType)((char*)baseAddress + 0x60C0);
ClientSq_getinteger = (sq_getintegerType)((char*)baseAddress + 0x60E0);
@@ -147,6 +151,7 @@ void InitialiseServerSquirrel(HMODULE baseAddress)
ServerSq_pushstring = (sq_pushstringType)((char*)baseAddress + 0x3440);
ServerSq_pushinteger = (sq_pushintegerType)((char*)baseAddress + 0x36A0);
ServerSq_pushfloat = (sq_pushfloatType)((char*)baseAddress + 0x3800);
+ ServerSq_pushbool = (sq_pushboolType)((char*)baseAddress + 0x3710);
ServerSq_getstring = (sq_getstringType)((char*)baseAddress + 0x60A0);
ServerSq_getinteger = (sq_getintegerType)((char*)baseAddress + 0x60C0);
diff --git a/NorthstarDedicatedTest/squirrel.h b/NorthstarDedicatedTest/squirrel.h
index b094dbaf..66abcd76 100644
--- a/NorthstarDedicatedTest/squirrel.h
+++ b/NorthstarDedicatedTest/squirrel.h
@@ -96,6 +96,10 @@ typedef void(*sq_pushfloatType)(void* sqvm, SQFloat f);
extern sq_pushfloatType ClientSq_pushfloat;
extern sq_pushfloatType ServerSq_pushfloat;
+typedef void(*sq_pushboolType)(void* sqvm, SQBool b);
+extern sq_pushboolType ClientSq_pushbool;
+extern sq_pushboolType ServerSq_pushbool;
+
// sq stack get funcs
typedef const SQChar*(*sq_getstringType)(void* sqvm, SQInteger stackpos);
--
cgit v1.2.3