diff --git a/UnleashedRecomp/main.cpp b/UnleashedRecomp/main.cpp index a78559cb..8b255632 100644 --- a/UnleashedRecomp/main.cpp +++ b/UnleashedRecomp/main.cpp @@ -81,8 +81,6 @@ void KiSystemStartup() } } - ModLoader::Init(); - XAudioInitializeSystem(); } @@ -178,6 +176,8 @@ int main(int argc, char *argv[]) } } + ModLoader::Init(); + AchievementData::Load(); KiSystemStartup(); diff --git a/UnleashedRecomp/mod/mod_loader.cpp b/UnleashedRecomp/mod/mod_loader.cpp index fbe62504..5da26730 100644 --- a/UnleashedRecomp/mod/mod_loader.cpp +++ b/UnleashedRecomp/mod/mod_loader.cpp @@ -28,11 +28,29 @@ std::filesystem::path ModLoader::RedirectPath(std::string_view path) if (g_mods.empty()) return {}; - thread_local xxHashMap s_pathCache; + std::string_view root; size_t sepIndex = path.find(":\\"); if (sepIndex != std::string_view::npos) + { + root = path.substr(0, sepIndex); path.remove_prefix(sepIndex + 2); + } + + if (root == "save") + { + if (!ModLoader::s_saveFilePath.empty()) + { + if (path == "SYS-DATA") + return ModLoader::s_saveFilePath; + else + return ModLoader::s_saveFilePath.parent_path() / path; + } + + return {}; + } + + thread_local xxHashMap s_pathCache; XXH64_hash_t hash = XXH3_64bits(path.data(), path.size()); auto findResult = s_pathCache.find(hash); @@ -75,6 +93,13 @@ void ModLoader::Init() if (!configIni.read("cpkredir.ini")) return; + if (configIni.getBool("CPKREDIR", "EnableSaveFileRedirection", false)) + { + std::string saveFilePathU8 = configIni.getString("CPKREDIR", "SaveFileFallback", std::string()); + if (!saveFilePathU8.empty()) + ModLoader::s_saveFilePath = std::u8string_view((const char8_t*)saveFilePathU8.c_str()); + } + std::string modsDbIniFilePathU8 = configIni.getString("CPKREDIR", "ModsDbIni", ""); if (modsDbIniFilePathU8.empty()) return; @@ -83,6 +108,8 @@ void ModLoader::Init() if (!modsDbIni.read(std::u8string_view((const char8_t*)modsDbIniFilePathU8.c_str()))) return; + bool foundModSaveFilePath = false; + size_t activeModCount = modsDbIni.get("Main", "ActiveModCount", 0); for (size_t i = 0; i < activeModCount; ++i) { @@ -101,13 +128,14 @@ void ModLoader::Init() continue; auto modDirectoryPath = modIniFilePath.parent_path(); + std::string modSaveFilePathU8; Mod mod; if (modIni.contains("Details") || modIni.contains("Filesystem")) // UMM { mod.type = ModType::UMM; - mod.includeDirs.emplace_back(std::move(modDirectoryPath)); + mod.includeDirs.emplace_back(modDirectoryPath); mod.merge = modIni.getBool("Details", "Merge", modIni.getBool("Filesystem", "Merge", false)); std::string readOnly = modIni.getString("Details", "Read-only", modIni.getString("Filesystem", "Read-only", std::string())); @@ -126,6 +154,9 @@ void ModLoader::Init() mod.readOnly.emplace(readOnlySplit.substr(0, index)); readOnlySplit.remove_prefix(index + 1); } + + if (!foundModSaveFilePath) + modSaveFilePathU8 = modIni.getString("Details", "Save", modIni.getString("Filesystem", "Save", std::string())); } else // HMM { @@ -138,10 +169,19 @@ void ModLoader::Init() if (!includeDirU8.empty()) mod.includeDirs.emplace_back(modDirectoryPath / std::u8string_view((const char8_t*)includeDirU8.c_str())); } + + if (!foundModSaveFilePath) + modSaveFilePathU8 = modIni.getString("Main", "SaveFile", std::string()); } if (!mod.includeDirs.empty()) g_mods.emplace_back(std::move(mod)); + + if (!modSaveFilePathU8.empty()) + { + ModLoader::s_saveFilePath = modDirectoryPath / std::u8string_view((const char8_t*)modSaveFilePathU8.c_str()); + foundModSaveFilePath = true; + } } } diff --git a/UnleashedRecomp/mod/mod_loader.h b/UnleashedRecomp/mod/mod_loader.h index adcdb6dd..73f4961a 100644 --- a/UnleashedRecomp/mod/mod_loader.h +++ b/UnleashedRecomp/mod/mod_loader.h @@ -2,6 +2,8 @@ struct ModLoader { + static inline std::filesystem::path s_saveFilePath; + static std::filesystem::path RedirectPath(std::string_view path); static std::vector* GetIncludeDirectories(size_t modIndex); diff --git a/UnleashedRecomp/user/paths.h b/UnleashedRecomp/user/paths.h index 53a40e8b..d067ca9f 100644 --- a/UnleashedRecomp/user/paths.h +++ b/UnleashedRecomp/user/paths.h @@ -1,5 +1,7 @@ #pragma once +#include + #define USER_DIRECTORY "SWA" #ifndef GAME_INSTALL_DIRECTORY @@ -50,5 +52,8 @@ inline std::filesystem::path GetUserPath() inline std::filesystem::path GetSavePath() { - return GetUserPath() / "save"; + if (!ModLoader::s_saveFilePath.empty()) + return ModLoader::s_saveFilePath.parent_path(); + else + return GetUserPath() / "save"; }