From bb7a4c00dea90e6d578d07618ae86a172aec58f2 Mon Sep 17 00:00:00 2001 From: Jack <66967891+ASpoonPlaysGames@users.noreply.github.com> Date: Thu, 23 Jun 2022 17:34:33 +0100 Subject: fixed custom rpaks being loaded more than once (#202) * fixed custom rpaks being loaded more than once * formatting * better things, although LoadPakSyncHook is annoying * formatting * removing unnecessary comments and stuff (whoops) * Moving to use PakLoadManager * formatting --- NorthstarDedicatedTest/rpakfilesystem.cpp | 42 +++++++++++++++++++++++++++++++ NorthstarDedicatedTest/rpakfilesystem.h | 8 ++++++ 2 files changed, 50 insertions(+) diff --git a/NorthstarDedicatedTest/rpakfilesystem.cpp b/NorthstarDedicatedTest/rpakfilesystem.cpp index d52f9ef1..b3105996 100644 --- a/NorthstarDedicatedTest/rpakfilesystem.cpp +++ b/NorthstarDedicatedTest/rpakfilesystem.cpp @@ -43,11 +43,37 @@ void PakLoadManager::LoadPakAsync(const char* path, bool bMarkForUnload) void PakLoadManager::UnloadPaks() { for (int pakHandle : m_pakHandlesToUnload) + { g_pakLoadApi->UnloadPak(pakHandle, nullptr); + // remove pak from loadedPaks and loadedPaksInv + RemoveLoadedPak(pakHandle); + } m_pakHandlesToUnload.clear(); } +bool PakLoadManager::IsPakLoaded(int32_t pakHandle) +{ + return loadedPaks.find(pakHandle) != loadedPaks.end(); +} + +bool PakLoadManager::IsPakLoaded(size_t hash) +{ + return loadedPaksInv.find(hash) != loadedPaksInv.end(); +} + +void PakLoadManager::AddLoadedPak(int32_t pakHandle, size_t hash) +{ + loadedPaks[pakHandle] = hash; + loadedPaksInv[hash] = pakHandle; +} + +void PakLoadManager::RemoveLoadedPak(int32_t pakHandle) +{ + loadedPaksInv.erase(loadedPaks[pakHandle]); + loadedPaks.erase(pakHandle); +} + void HandlePakAliases(char** map) { // convert the pak being loaded to it's aliased one, e.g. aliasing mp_hub_timeshift => sp_hub_timeshift @@ -152,6 +178,13 @@ void* LoadPakSyncHook(char* path, void* unknownSingleton, int flags) LoadPakAsyncType LoadPakAsyncOriginal; int LoadPakAsyncHook(char* path, void* unknownSingleton, int flags, void* callback0, void* callback1) { + size_t hash = STR_HASH(path); + // if the hash is already in the map, dont load the pak, it has already been loaded + if (g_PakLoadManager->IsPakLoaded(hash)) + { + return -1; + } + HandlePakAliases(&path); bool bNeedToFreePakName = false; @@ -176,6 +209,9 @@ int LoadPakAsyncHook(char* path, void* unknownSingleton, int flags, void* callba int ret = LoadPakAsyncOriginal(path, unknownSingleton, flags, callback0, callback1); spdlog::info("LoadPakAsync {} {}", path, ret); + // add the hash to the map + g_PakLoadManager->AddLoadedPak(ret, hash); + if (bNeedToFreePakName) delete[] path; @@ -185,6 +221,12 @@ int LoadPakAsyncHook(char* path, void* unknownSingleton, int flags, void* callba UnloadPakType UnloadPakOriginal; void* UnloadPakHook(int pakHandle, void* callback) { + if (g_PakLoadManager->IsPakLoaded(pakHandle)) + { + // remove the entry + g_PakLoadManager->RemoveLoadedPak(pakHandle); + } + static bool bShouldUnloadPaks = true; if (bShouldUnloadPaks) { diff --git a/NorthstarDedicatedTest/rpakfilesystem.h b/NorthstarDedicatedTest/rpakfilesystem.h index 3c104822..12ef983e 100644 --- a/NorthstarDedicatedTest/rpakfilesystem.h +++ b/NorthstarDedicatedTest/rpakfilesystem.h @@ -9,8 +9,16 @@ class PakLoadManager void LoadPakAsync(const char* path, bool bMarkForUnload); void UnloadPaks(); + bool IsPakLoaded(int32_t pakHandle); + bool IsPakLoaded(size_t hash); + void AddLoadedPak(int32_t pakHandle, size_t hash); + void RemoveLoadedPak(int32_t pakHandle); + private: std::vector m_pakHandlesToUnload; + // these size_t s are the asset path hashed with STR_HASH + std::unordered_map loadedPaks {}; + std::unordered_map loadedPaksInv {}; }; extern PakLoadManager* g_PakLoadManager; \ No newline at end of file -- cgit v1.2.3