aboutsummaryrefslogtreecommitdiff
path: root/NorthstarDedicatedTest/rpakfilesystem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'NorthstarDedicatedTest/rpakfilesystem.cpp')
-rw-r--r--NorthstarDedicatedTest/rpakfilesystem.cpp77
1 files changed, 68 insertions, 9 deletions
diff --git a/NorthstarDedicatedTest/rpakfilesystem.cpp b/NorthstarDedicatedTest/rpakfilesystem.cpp
index 4da22b56..a4c4fada 100644
--- a/NorthstarDedicatedTest/rpakfilesystem.cpp
+++ b/NorthstarDedicatedTest/rpakfilesystem.cpp
@@ -13,29 +13,88 @@ typedef void* (*LoadPakAsyncType)(const char* path, void* unknownSingleton, int
struct PakLoadFuncs
{
void* unknown[2];
- LoadPakSyncType func2;
+ LoadPakSyncType LoadPakSync;
LoadPakAsyncType LoadPakAsync;
};
PakLoadFuncs* g_pakLoadApi;
void** pUnknownPakLoadSingleton;
-void LoadPakAsync(const char* path) { g_pakLoadApi->LoadPakAsync(path, *pUnknownPakLoadSingleton, 2, nullptr, nullptr); }
+PakLoadManager* g_PakLoadManager;
+void PakLoadManager::LoadPakSync(const char* path) { g_pakLoadApi->LoadPakSync(path, *pUnknownPakLoadSingleton, 0); }
+void PakLoadManager::LoadPakAsync(const char* path) { g_pakLoadApi->LoadPakAsync(path, *pUnknownPakLoadSingleton, 2, nullptr, nullptr); }
-void LoadCommonPaksForMapHook(char* map)
+void HandlePakAliases(char** map)
{
- LoadCommonPaksForMap(map);
+ // convert the pak being loaded to it's aliased one, e.g. aliasing mp_hub_timeshift => sp_hub_timeshift
+ for (int64_t i = g_ModManager->m_loadedMods.size() - 1; i > -1; i--)
+ {
+ Mod* mod = &g_ModManager->m_loadedMods[i];
+ if (!mod->Enabled)
+ continue;
- // for sp => mp conversions, load the sp rpaks
- if (!strcmp(map, "mp_skyway_v1") || !strcmp(map, "mp_crashsite") || !strcmp(map, "mp_hub_timeshift"))
- map[0] = 's';
+ if (mod->RpakAliases.find(*map) != mod->RpakAliases.end())
+ {
+ *map = &mod->RpakAliases[*map][0];
+ return;
+ }
+ }
+}
+
+bool bShouldPreload = true;
+void LoadPreloadPaks()
+{
+ // disable preloading while we're doing this
+ bShouldPreload = false;
+
+ // note, loading from ./ is necessary otherwise paks will load from gamedir/r2/paks
+ for (Mod& mod : g_ModManager->m_loadedMods)
+ {
+ if (!mod.Enabled)
+ continue;
+
+ // need to get a relative path of mod to mod folder
+ fs::path modPakPath("./" / mod.ModDirectory / "paks");
+
+ for (ModRpakEntry& pak : mod.Rpaks)
+ if (pak.m_bAutoLoad)
+ g_PakLoadManager->LoadPakAsync((modPakPath / pak.m_sPakPath).string().c_str());
+ }
+
+ bShouldPreload = true;
+}
+
+LoadPakSyncType LoadPakSyncOriginal;
+void* LoadPakSyncHook(char* path, void* unknownSingleton, int flags)
+{
+ HandlePakAliases(&path);
+ // note: we don't handle loading any preloaded custom paks synchronously since LoadPakSync is never actually called in retail, just load them async instead
+ LoadPreloadPaks();
+
+ spdlog::info("LoadPakSync {}", path);
+ return LoadPakSyncOriginal(path, unknownSingleton, flags);
+}
+
+LoadPakAsyncType LoadPakAsyncOriginal;
+void* LoadPakAsyncHook(char* path, void* unknownSingleton, int flags, void* callback0, void* callback1)
+{
+ HandlePakAliases(&path);
+
+ if (bShouldPreload)
+ LoadPreloadPaks();
+
+ spdlog::info("LoadPakAsync {}", path);
+ return LoadPakAsyncOriginal(path, unknownSingleton, flags, callback0, callback1);
}
void InitialiseEngineRpakFilesystem(HMODULE baseAddress)
{
- g_pakLoadApi = (PakLoadFuncs*)((char*)baseAddress + 0x5BED78);
+ g_PakLoadManager = new PakLoadManager;
+
+ g_pakLoadApi = *(PakLoadFuncs**)((char*)baseAddress + 0x5BED78);
pUnknownPakLoadSingleton = (void**)((char*)baseAddress + 0x7C5E20);
HookEnabler hook;
- ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x15AD20, &LoadCommonPaksForMapHook, reinterpret_cast<LPVOID*>(&LoadCommonPaksForMap));
+ ENABLER_CREATEHOOK(hook, g_pakLoadApi->LoadPakSync, &LoadPakSyncHook, reinterpret_cast<LPVOID*>(&LoadPakSyncOriginal));
+ ENABLER_CREATEHOOK(hook, g_pakLoadApi->LoadPakAsync, &LoadPakAsyncHook, reinterpret_cast<LPVOID*>(&LoadPakAsyncOriginal));
} \ No newline at end of file