Initial save file redirection implementation.

This commit is contained in:
Skyth 2024-12-30 22:01:54 +03:00
parent 38ec7865f4
commit 261907ed12
4 changed files with 52 additions and 5 deletions

View file

@ -81,8 +81,6 @@ void KiSystemStartup()
} }
} }
ModLoader::Init();
XAudioInitializeSystem(); XAudioInitializeSystem();
} }
@ -178,6 +176,8 @@ int main(int argc, char *argv[])
} }
} }
ModLoader::Init();
AchievementData::Load(); AchievementData::Load();
KiSystemStartup(); KiSystemStartup();

View file

@ -28,11 +28,29 @@ std::filesystem::path ModLoader::RedirectPath(std::string_view path)
if (g_mods.empty()) if (g_mods.empty())
return {}; return {};
thread_local xxHashMap<std::filesystem::path> s_pathCache; std::string_view root;
size_t sepIndex = path.find(":\\"); size_t sepIndex = path.find(":\\");
if (sepIndex != std::string_view::npos) if (sepIndex != std::string_view::npos)
{
root = path.substr(0, sepIndex);
path.remove_prefix(sepIndex + 2); 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<std::filesystem::path> s_pathCache;
XXH64_hash_t hash = XXH3_64bits(path.data(), path.size()); XXH64_hash_t hash = XXH3_64bits(path.data(), path.size());
auto findResult = s_pathCache.find(hash); auto findResult = s_pathCache.find(hash);
@ -75,6 +93,13 @@ void ModLoader::Init()
if (!configIni.read("cpkredir.ini")) if (!configIni.read("cpkredir.ini"))
return; 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", ""); std::string modsDbIniFilePathU8 = configIni.getString("CPKREDIR", "ModsDbIni", "");
if (modsDbIniFilePathU8.empty()) if (modsDbIniFilePathU8.empty())
return; return;
@ -83,6 +108,8 @@ void ModLoader::Init()
if (!modsDbIni.read(std::u8string_view((const char8_t*)modsDbIniFilePathU8.c_str()))) if (!modsDbIni.read(std::u8string_view((const char8_t*)modsDbIniFilePathU8.c_str())))
return; return;
bool foundModSaveFilePath = false;
size_t activeModCount = modsDbIni.get<size_t>("Main", "ActiveModCount", 0); size_t activeModCount = modsDbIni.get<size_t>("Main", "ActiveModCount", 0);
for (size_t i = 0; i < activeModCount; ++i) for (size_t i = 0; i < activeModCount; ++i)
{ {
@ -101,13 +128,14 @@ void ModLoader::Init()
continue; continue;
auto modDirectoryPath = modIniFilePath.parent_path(); auto modDirectoryPath = modIniFilePath.parent_path();
std::string modSaveFilePathU8;
Mod mod; Mod mod;
if (modIni.contains("Details") || modIni.contains("Filesystem")) // UMM if (modIni.contains("Details") || modIni.contains("Filesystem")) // UMM
{ {
mod.type = ModType::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)); 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())); 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)); mod.readOnly.emplace(readOnlySplit.substr(0, index));
readOnlySplit.remove_prefix(index + 1); readOnlySplit.remove_prefix(index + 1);
} }
if (!foundModSaveFilePath)
modSaveFilePathU8 = modIni.getString("Details", "Save", modIni.getString("Filesystem", "Save", std::string()));
} }
else // HMM else // HMM
{ {
@ -138,10 +169,19 @@ void ModLoader::Init()
if (!includeDirU8.empty()) if (!includeDirU8.empty())
mod.includeDirs.emplace_back(modDirectoryPath / std::u8string_view((const char8_t*)includeDirU8.c_str())); 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()) if (!mod.includeDirs.empty())
g_mods.emplace_back(std::move(mod)); 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;
}
} }
} }

View file

@ -2,6 +2,8 @@
struct ModLoader struct ModLoader
{ {
static inline std::filesystem::path s_saveFilePath;
static std::filesystem::path RedirectPath(std::string_view path); static std::filesystem::path RedirectPath(std::string_view path);
static std::vector<std::filesystem::path>* GetIncludeDirectories(size_t modIndex); static std::vector<std::filesystem::path>* GetIncludeDirectories(size_t modIndex);

View file

@ -1,5 +1,7 @@
#pragma once #pragma once
#include <mod/mod_loader.h>
#define USER_DIRECTORY "SWA" #define USER_DIRECTORY "SWA"
#ifndef GAME_INSTALL_DIRECTORY #ifndef GAME_INSTALL_DIRECTORY
@ -50,5 +52,8 @@ inline std::filesystem::path GetUserPath()
inline std::filesystem::path GetSavePath() inline std::filesystem::path GetSavePath()
{ {
return GetUserPath() / "save"; if (!ModLoader::s_saveFilePath.empty())
return ModLoader::s_saveFilePath.parent_path();
else
return GetUserPath() / "save";
} }