diff options
-rw-r--r-- | NorthstarDedicatedTest/filesystem.cpp | 29 | ||||
-rw-r--r-- | NorthstarDedicatedTest/modmanager.cpp | 8 | ||||
-rw-r--r-- | NorthstarDedicatedTest/modmanager.h | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/scriptsrson.cpp | 13 | ||||
-rw-r--r-- | NorthstarDedicatedTest/scriptsrson.h | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/serverauthentication.cpp | 36 | ||||
-rw-r--r-- | NorthstarDedicatedTest/serverauthentication.h | 1 |
7 files changed, 62 insertions, 31 deletions
diff --git a/NorthstarDedicatedTest/filesystem.cpp b/NorthstarDedicatedTest/filesystem.cpp index 04b8c98e..1a2fb993 100644 --- a/NorthstarDedicatedTest/filesystem.cpp +++ b/NorthstarDedicatedTest/filesystem.cpp @@ -9,13 +9,13 @@ #include <sstream> // hook forward declares -typedef FileHandle_t(*ReadFileFromVPKType)(VPKData* vpkInfo, __int64* b, const char* filename); +typedef FileHandle_t(*ReadFileFromVPKType)(VPKData* vpkInfo, __int64* b, char* filename); ReadFileFromVPKType readFileFromVPK; -FileHandle_t ReadFileFromVPKHook(VPKData* vpkInfo, __int64* b, const char* filename); +FileHandle_t ReadFileFromVPKHook(VPKData* vpkInfo, __int64* b, char* filename); -typedef bool(*ReadFromCacheType)(IFileSystem* filesystem, const char* path, void* result); +typedef bool(*ReadFromCacheType)(IFileSystem* filesystem, char* path, void* result); ReadFromCacheType readFromCache; -bool ReadFromCacheHook(IFileSystem* filesystem, const char* path, void* result); +bool ReadFromCacheHook(IFileSystem* filesystem, char* path, void* result); typedef void(*AddSearchPathType)(IFileSystem* fileSystem, const char* pPath, const char* pathID, SearchPathAdd_t addType); AddSearchPathType addSearchPathOriginal; @@ -78,32 +78,31 @@ void SetNewModSearchPaths(Mod* mod) currentModPath = (fs::absolute(mod->ModDirectory) / MOD_OVERRIDE_DIR).string(); } } - else if (!currentModPath.size()) // if currentModPath isn't set yet, then push compiled to head + else // push compiled to head addSearchPathOriginal(&*(*g_Filesystem), fs::absolute(COMPILED_ASSETS_PATH).string().c_str(), "GAME", PATH_ADD_TO_HEAD); } -bool TryReplaceFile(const char* path) +bool TryReplaceFile(char* path) { if (readingOriginalFile) return false; (*g_ModManager).CompileAssetsForFile(path); - // is this efficient? could probably be improved - for (ModOverrideFile* modFile : g_ModManager->m_modFiles) + // 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 + auto file = g_ModManager->m_modFiles.find(fs::path(path).lexically_normal().string()); + if (file != g_ModManager->m_modFiles.end()) { - if (!modFile->path.compare(fs::path(path).lexically_normal())) - { - SetNewModSearchPaths(modFile->owningMod); - return true; - } + SetNewModSearchPaths(file->second->owningMod); + return true; } return false; } -FileHandle_t ReadFileFromVPKHook(VPKData* vpkInfo, __int64* b, const char* filename) +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); @@ -116,7 +115,7 @@ FileHandle_t ReadFileFromVPKHook(VPKData* vpkInfo, __int64* b, const char* filen return readFileFromVPK(vpkInfo, b, filename); } -bool ReadFromCacheHook(IFileSystem* filesystem, const char* path, void* result) +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); diff --git a/NorthstarDedicatedTest/modmanager.cpp b/NorthstarDedicatedTest/modmanager.cpp index ea16f591..964d37ae 100644 --- a/NorthstarDedicatedTest/modmanager.cpp +++ b/NorthstarDedicatedTest/modmanager.cpp @@ -248,13 +248,15 @@ void ModManager::LoadMods() { for (fs::directory_entry file : fs::recursive_directory_iterator(m_loadedMods[i]->ModDirectory / MOD_OVERRIDE_DIR)) { - if (file.is_regular_file()) + fs::path path = file.path().lexically_relative(m_loadedMods[i]->ModDirectory / MOD_OVERRIDE_DIR).lexically_normal(); + + 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 = file.path().lexically_relative(m_loadedMods[i]->ModDirectory / MOD_OVERRIDE_DIR).lexically_normal(); - m_modFiles.push_back(modFile); + modFile->path = path; + m_modFiles.insert(std::make_pair(path.string(), modFile)); } } } diff --git a/NorthstarDedicatedTest/modmanager.h b/NorthstarDedicatedTest/modmanager.h index 78b3153c..6146de0a 100644 --- a/NorthstarDedicatedTest/modmanager.h +++ b/NorthstarDedicatedTest/modmanager.h @@ -92,7 +92,8 @@ class ModManager { public: std::vector<Mod*> m_loadedMods; - std::vector<ModOverrideFile*> m_modFiles; + //std::vector<ModOverrideFile*> m_modFiles; + std::unordered_map<std::string, ModOverrideFile*> m_modFiles; public: ModManager(); diff --git a/NorthstarDedicatedTest/scriptsrson.cpp b/NorthstarDedicatedTest/scriptsrson.cpp index 1f08e7f1..b5aef421 100644 --- a/NorthstarDedicatedTest/scriptsrson.cpp +++ b/NorthstarDedicatedTest/scriptsrson.cpp @@ -20,6 +20,11 @@ void ModManager::BuildScriptsRson() for (Mod* mod : m_loadedMods) { + // this isn't needed at all, just nice to have imo + scriptsRson += "// MOD: "; + scriptsRson += mod->Name; + scriptsRson += ":\n\n"; + for (ModScript* script : mod->Scripts) { /* should create something with this format for each script @@ -47,8 +52,12 @@ void ModManager::BuildScriptsRson() ModOverrideFile* overrideFile = new ModOverrideFile; overrideFile->owningMod = nullptr; - overrideFile->path = "scripts/vscripts/scripts.rson"; - m_modFiles.push_back(overrideFile); + overrideFile->path = VPK_SCRIPTS_RSON_PATH; + + if (m_modFiles.find(VPK_SCRIPTS_RSON_PATH) == m_modFiles.end()) + m_modFiles.insert(std::make_pair(VPK_SCRIPTS_RSON_PATH, overrideFile)); + else + m_modFiles[VPK_SCRIPTS_RSON_PATH] = overrideFile; // todo: for preventing dupe scripts in scripts.rson, we could actually parse when conditions with the squirrel vm, just need a way to get a result out of squirrelmanager.ExecuteCode // this would probably be the best way to do this, imo diff --git a/NorthstarDedicatedTest/scriptsrson.h b/NorthstarDedicatedTest/scriptsrson.h index f9297065..16e91fb8 100644 --- a/NorthstarDedicatedTest/scriptsrson.h +++ b/NorthstarDedicatedTest/scriptsrson.h @@ -1,3 +1,4 @@ #pragma once -const fs::path MOD_SCRIPTS_RSON_PATH = COMPILED_ASSETS_PATH / "scripts/vscripts/scripts.rson";
\ No newline at end of file +const fs::path MOD_SCRIPTS_RSON_PATH = COMPILED_ASSETS_PATH / "scripts/vscripts/scripts.rson"; +const char* VPK_SCRIPTS_RSON_PATH = "scripts\\vscripts\\scripts.rson";
\ No newline at end of file diff --git a/NorthstarDedicatedTest/serverauthentication.cpp b/NorthstarDedicatedTest/serverauthentication.cpp index da7702d2..a856c00f 100644 --- a/NorthstarDedicatedTest/serverauthentication.cpp +++ b/NorthstarDedicatedTest/serverauthentication.cpp @@ -83,6 +83,23 @@ bool ServerAuthenticationManager::AuthenticatePlayer(void* player, char* authTok return true; // auth successful, client stays on } +bool ServerAuthenticationManager::RemovePlayerAuthData(void* player) +{ + // we don't have our auth token at this point, so lookup authdata by uid + for (auto& auth : m_authData) + { + if (!strcmp((char*)player + 0xF500, auth.second->uid)) + { + // pretty sure this is fine, since we don't iterate after the erase + // i think if we iterated after it'd be undefined behaviour tho + m_authData.erase(auth.first); + return true; + } + } + + return false; +} + void ServerAuthenticationManager::WritePersistentData(void* player) { // we use 0x4 internally to mark clients as using remote persistence @@ -100,7 +117,7 @@ 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 +// this is fine because serverfilter ptr won't decay by the time we use this, just don't use it outside of cbaseclient::connect char* nextPlayerToken; 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) @@ -116,7 +133,9 @@ 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_ServerAuthenticationManager->AuthenticatePlayer(self, nextPlayerToken)) + if (strlen(name) >= 64) // fix for name overflow bug + CBaseClient__Disconnect(self, 1, "Invalid name"); + else if (!g_ServerAuthenticationManager->AuthenticatePlayer(self, nextPlayerToken)) CBaseClient__Disconnect(self, 1, "Authentication Failed"); return ret; @@ -124,13 +143,12 @@ char CBaseClient__ConnectHook(void* self, char* name, __int64 netchan_ptr_arg, c void CBaseClient__ActivatePlayerHook(void* self) { - // check whether we're authed, todo: need to only write persistence on/after second call to this per player - // todo: also need to remove authdata here - if (*((char*)self + 0x4A0) >= (char)0x3) - { - CBaseClient__ActivatePlayer(self); + // if we're authed, write our persistent data + // RemovePlayerAuthData returns true if it removed successfully, i.e. on first call only, and we only want to write on >= second call (since this func is called on map loads) + if (*((char*)self + 0x4A0) >= (char)0x3 && !g_ServerAuthenticationManager->RemovePlayerAuthData(self)) g_ServerAuthenticationManager->WritePersistentData(self); - } + + CBaseClient__ActivatePlayer(self); } void CBaseClient__DisconnectHook(void* self, uint32_t unknownButAlways1, const char* reason, ...) @@ -159,7 +177,7 @@ void InitialiseServerAuthentication(HMODULE baseAddress) HookEnabler hook; ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x114430, &CBaseServer__ConnectClientHook, reinterpret_cast<LPVOID*>(&CBaseServer__ConnectClient)); ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x101740, &CBaseClient__ConnectHook, reinterpret_cast<LPVOID*>(&CBaseClient__Connect)); - //ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x100F80, &CBaseClient__ActivatePlayerHook, reinterpret_cast<LPVOID*>(&CBaseClient__ActivatePlayer)); + ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x100F80, &CBaseClient__ActivatePlayerHook, reinterpret_cast<LPVOID*>(&CBaseClient__ActivatePlayer)); ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x1012C0, &CBaseClient__DisconnectHook, reinterpret_cast<LPVOID*>(&CBaseClient__Disconnect)); // patch to disable kicking based on incorrect serverfilter in connectclient, since we repurpose it for use as an auth token diff --git a/NorthstarDedicatedTest/serverauthentication.h b/NorthstarDedicatedTest/serverauthentication.h index 3051ea10..4301b78e 100644 --- a/NorthstarDedicatedTest/serverauthentication.h +++ b/NorthstarDedicatedTest/serverauthentication.h @@ -19,6 +19,7 @@ public: public: void AddPlayerAuth(char* authToken, char* uid, char* pdata, size_t pdataSize); bool AuthenticatePlayer(void* player, char* authToken); + bool RemovePlayerAuthData(void* player); void WritePersistentData(void* player); }; |