From bf176fe728400b93295118e8d256c346c8c52d41 Mon Sep 17 00:00:00 2001 From: BobTheBob <32057864+BobTheBob9@users.noreply.github.com> Date: Tue, 3 Aug 2021 01:28:51 +0100 Subject: fix playlist kv building --- NorthstarDedicatedTest/dllmain.cpp | 2 ++ NorthstarDedicatedTest/keyvalues.cpp | 34 ++++++++++++++++++++++--- NorthstarDedicatedTest/keyvalues.h | 4 ++- NorthstarDedicatedTest/modmanager.cpp | 2 +- NorthstarDedicatedTest/serverauthentication.cpp | 2 +- NorthstarDedicatedTest/serverauthentication.h | 2 +- NorthstarDedicatedTest/squirrel.cpp | 3 --- 7 files changed, 39 insertions(+), 10 deletions(-) diff --git a/NorthstarDedicatedTest/dllmain.cpp b/NorthstarDedicatedTest/dllmain.cpp index 4e347d05..9fd62885 100644 --- a/NorthstarDedicatedTest/dllmain.cpp +++ b/NorthstarDedicatedTest/dllmain.cpp @@ -11,6 +11,7 @@ #include "serverauthentication.h" #include "scriptmodmenu.h" #include "scriptserverbrowser.h" +#include "keyvalues.h" bool initialised = false; @@ -64,6 +65,7 @@ void InitialiseNorthstar() AddDllLoadCallback("engine.dll", InitialiseServerAuthentication); AddDllLoadCallback("filesystem_stdio.dll", InitialiseFilesystem); + AddDllLoadCallback("engine.dll", InitialiseKeyValues); // mod manager after everything else AddDllLoadCallback("engine.dll", InitialiseModManager); diff --git a/NorthstarDedicatedTest/keyvalues.cpp b/NorthstarDedicatedTest/keyvalues.cpp index b2c278c6..6ddb9d99 100644 --- a/NorthstarDedicatedTest/keyvalues.cpp +++ b/NorthstarDedicatedTest/keyvalues.cpp @@ -2,9 +2,35 @@ #include "keyvalues.h" #include "modmanager.h" #include "filesystem.h" +#include "hookutils.h" #include +// hook forward defs +typedef char(*KeyValues__LoadFromBufferType)(void* self, const char* resourceName, const char* pBuffer, void* pFileSystem, void* a5, void* a6, int a7); +KeyValues__LoadFromBufferType KeyValues__LoadFromBuffer; +char KeyValues__LoadFromBufferHook(void* self, const char* resourceName, const char* pBuffer, void* pFileSystem, void* a5, void* a6, int a7); + +void InitialiseKeyValues(HMODULE baseAddress) +{ + HookEnabler hook; + ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x426C30, &KeyValues__LoadFromBufferHook, reinterpret_cast(&KeyValues__LoadFromBuffer)); +} + +void* savedFilesystemPtr; + +char KeyValues__LoadFromBufferHook(void* self, const char* resourceName, const char* pBuffer, void* pFileSystem, void* a5, void* a6, int a7) +{ + // this is just to allow playlists to get a valid pFileSystem ptr for kv building, other functions that call this particular overload of LoadFromBuffer seem to get called on network stuff exclusively + // not exactly sure what the address wanted here is, so just taking it from a function call that always happens before playlists is loaded + if (pFileSystem != nullptr) + savedFilesystemPtr = pFileSystem; + if (!pFileSystem && !strcmp(resourceName, "playlists")) + pFileSystem = savedFilesystemPtr; + + return KeyValues__LoadFromBuffer(self, resourceName, pBuffer, pFileSystem, a5, a6, a7); +} + void ModManager::TryBuildKeyValues(const char* filename) { spdlog::info("Building KeyValues for file {}", filename); @@ -22,7 +48,8 @@ void ModManager::TryBuildKeyValues(const char* filename) int patchNum = 0; - // copy over patch kv files, and add #includes to new file, last mods' patches should be applied first + // copy over patch kv files, and add #bases to new file, last mods' patches should be applied first + // note: #include should be identical but it's actually just broken, thanks respawn for (int i = m_loadedMods.size() - 1; i > -1; i--) { size_t fileHash = std::hash{}(normalisedPath); @@ -48,6 +75,7 @@ void ModManager::TryBuildKeyValues(const char* filename) } } + // add original #base last, #bases don't override preexisting keys, including the ones we've just done newKvs += "#base \""; newKvs += ogFilePath; newKvs += "\"\n"; @@ -57,7 +85,7 @@ void ModManager::TryBuildKeyValues(const char* 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 + // iterate until we hit an ascii char that isn't in a # command or comment to get root obj name int i = 0; while (!(originalFile[i] >= 65 && originalFile[i] <= 122)) { @@ -73,7 +101,7 @@ void ModManager::TryBuildKeyValues(const char* filename) 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 + // empty kv, all the other stuff gets #base'd newKvs += rootName; newKvs += "\n{\n}\n"; diff --git a/NorthstarDedicatedTest/keyvalues.h b/NorthstarDedicatedTest/keyvalues.h index 7b9637ef..b7de850d 100644 --- a/NorthstarDedicatedTest/keyvalues.h +++ b/NorthstarDedicatedTest/keyvalues.h @@ -1 +1,3 @@ -#pragma once \ No newline at end of file +#pragma once + +void InitialiseKeyValues(HMODULE baseAddress); \ No newline at end of file diff --git a/NorthstarDedicatedTest/modmanager.cpp b/NorthstarDedicatedTest/modmanager.cpp index faca09c4..537ea150 100644 --- a/NorthstarDedicatedTest/modmanager.cpp +++ b/NorthstarDedicatedTest/modmanager.cpp @@ -247,7 +247,7 @@ void ModManager::LoadMods() { for (fs::directory_entry file : fs::recursive_directory_iterator(mod->ModDirectory / "keyvalues")) { - if (fs::is_regular_file(file) && !file.path().extension().compare(".txt")) + if (fs::is_regular_file(file)) { std::string kvStr = file.path().lexically_relative(mod->ModDirectory / "keyvalues").lexically_normal().string(); mod->KeyValuesHash.push_back(std::hash{}(kvStr)); diff --git a/NorthstarDedicatedTest/serverauthentication.cpp b/NorthstarDedicatedTest/serverauthentication.cpp index ffc21a8b..820cb69d 100644 --- a/NorthstarDedicatedTest/serverauthentication.cpp +++ b/NorthstarDedicatedTest/serverauthentication.cpp @@ -29,7 +29,7 @@ ConVar* CVar_ns_auth_allow_insecure; ConVar* CVar_ns_auth_allow_insecure_write; ConVar* CVar_sv_quota_stringcmdspersecond; -void ServerAuthenticationManager::AddPlayerAuth(char* authToken, char* uid, char* pdata, size_t pdataSize) +void ServerAuthenticationManager::AddPlayerAuthData(char* authToken, char* uid, char* pdata, size_t pdataSize) { } diff --git a/NorthstarDedicatedTest/serverauthentication.h b/NorthstarDedicatedTest/serverauthentication.h index c28c882b..66802f31 100644 --- a/NorthstarDedicatedTest/serverauthentication.h +++ b/NorthstarDedicatedTest/serverauthentication.h @@ -17,7 +17,7 @@ public: std::unordered_map m_authData; public: - void AddPlayerAuth(char* authToken, char* uid, char* pdata, size_t pdataSize); + void AddPlayerAuthData(char* authToken, char* uid, char* pdata, size_t pdataSize); 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 46e4708a..90988eca 100644 --- a/NorthstarDedicatedTest/squirrel.cpp +++ b/NorthstarDedicatedTest/squirrel.cpp @@ -237,9 +237,6 @@ template void DestroyVMHook(void* a1, void* sqvm) template void ScriptCompileErrorHook(void* sqvm, const char* error, const char* file, int line, int column) { - // note: i think vanilla might actually show the script line that errored, might be nice to implement that if it's a thing - // look into client.dll+79540 for way better errors too - Context realContext = context; // ui and client use the same function so we use this for prints if (context == CLIENT && sqvm == g_UISquirrelManager->sqvm) realContext = UI; -- cgit v1.2.3