Implement save file redirection fallback.

This commit is contained in:
Skyth 2024-12-30 23:31:27 +03:00
parent cb7b8a0d2d
commit 34f8315c01
5 changed files with 41 additions and 13 deletions

View file

@ -308,7 +308,7 @@ SWA_API uint32_t XamContentCreateEx(uint32_t dwUserIndex, const char* szRootName
if (pContentData->dwContentType == XCONTENTTYPE_SAVEDATA)
{
std::u8string savePathU8 = GetSavePath().u8string();
std::u8string savePathU8 = GetSavePath(true).u8string();
root = (const char *)(savePathU8.c_str());
}
else if (pContentData->dwContentType == XCONTENTTYPE_DLC)

View file

@ -54,13 +54,26 @@ void KiSystemStartup()
XamRegisterContent(gameContent, GAME_INSTALL_DIRECTORY "/game");
XamRegisterContent(updateContent, GAME_INSTALL_DIRECTORY "/update");
const auto savePath = GetSavePath();
const auto saveName = "SYS-DATA";
const auto saveFilePath = GetSaveFilePath(true);
bool saveFileExists = std::filesystem::exists(saveFilePath);
if (std::filesystem::exists(savePath / saveName))
if (!saveFileExists)
{
std::u8string savePathU8 = savePath.u8string();
XamRegisterContent(XamMakeContent(XCONTENTTYPE_SAVEDATA, saveName), (const char *)(savePathU8.c_str()));
// Copy base save data to modded save as fallback.
std::error_code ec;
std::filesystem::create_directories(saveFilePath.parent_path(), ec);
if (!ec)
{
std::filesystem::copy_file(GetSaveFilePath(false), saveFilePath, ec);
saveFileExists = !ec;
}
}
if (saveFileExists)
{
std::u8string savePathU8 = saveFilePath.parent_path().u8string();
XamRegisterContent(XamMakeContent(XCONTENTTYPE_SAVEDATA, "SYS-DATA"), (const char*)(savePathU8.c_str()));
}
// Mount game

View file

@ -104,10 +104,15 @@ bool AchievementData::VerifyChecksum()
void AchievementData::Load()
{
auto dataPath = GetDataPath();
auto dataPath = GetDataPath(true);
if (!std::filesystem::exists(dataPath))
return;
{
// Try loading base achievement data as fallback.
dataPath = GetDataPath(false);
if (!std::filesystem::exists(dataPath))
return;
}
std::ifstream file(dataPath, std::ios::binary);
@ -160,7 +165,7 @@ void AchievementData::Load()
void AchievementData::Save()
{
std::ofstream file(GetDataPath(), std::ios::binary);
std::ofstream file(GetDataPath(true), std::ios::binary);
if (!file)
{

View file

@ -45,9 +45,9 @@ public:
static inline Data Data{ ACH_SIGNATURE, ACH_VERSION };
static std::filesystem::path GetDataPath()
static std::filesystem::path GetDataPath(bool checkForMods)
{
return GetSavePath() / "ACH-DATA";
return GetSavePath(checkForMods) / "ACH-DATA";
}
static time_t GetTimestamp(uint16_t id);

View file

@ -50,10 +50,20 @@ inline std::filesystem::path GetUserPath()
return userPath;
}
inline std::filesystem::path GetSavePath()
inline std::filesystem::path GetSavePath(bool checkForMods)
{
if (!ModLoader::s_saveFilePath.empty())
if (checkForMods && !ModLoader::s_saveFilePath.empty())
return ModLoader::s_saveFilePath.parent_path();
else
return GetUserPath() / "save";
}
// Returned file name may not necessarily be
// equal to SYS-DATA as mods can assign anything.
inline std::filesystem::path GetSaveFilePath(bool checkForMods)
{
if (checkForMods && !ModLoader::s_saveFilePath.empty())
return ModLoader::s_saveFilePath;
else
return GetSavePath(false) / "SYS-DATA";
}