mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-01-31 07:20:14 -05:00
[Feature/fix] Save to temp file first (#3376)
* Add temp file flow to `SaveManager::SaveFileThreaded`. Add "Save finish" info log message. * Fix WiiU/Switch
This commit is contained in:
parent
fb45b66903
commit
afe032ea21
@ -47,6 +47,11 @@ std::filesystem::path SaveManager::GetFileName(int fileNum) {
|
||||
return sSavePath / ("file" + std::to_string(fileNum + 1) + ".sav");
|
||||
}
|
||||
|
||||
std::filesystem::path SaveManager::GetFileTempName(int fileNum) {
|
||||
const std::filesystem::path sSavePath(LUS::Context::GetPathRelativeToAppDirectory("Save"));
|
||||
return sSavePath / ("file" + std::to_string(fileNum + 1) + ".temp");
|
||||
}
|
||||
|
||||
SaveManager::SaveManager() {
|
||||
coreSectionIDsByName["base"] = SECTION_ID_BASE;
|
||||
coreSectionIDsByName["randomizer"] = SECTION_ID_RANDOMIZER;
|
||||
@ -874,6 +879,32 @@ void SaveManager::InitFileMaxed() {
|
||||
gSaveContext.sceneFlags[5].swch = 0x40000000;
|
||||
}
|
||||
|
||||
#if defined(__WIIU__) || defined(__SWITCH__)
|
||||
// std::filesystem::copy_file doesn't work properly with the Wii U's toolchain atm
|
||||
int copy_file(const char* src, const char* dst) {
|
||||
alignas(0x40) uint8_t buf[4096];
|
||||
FILE* r = fopen(src, "r");
|
||||
if (!r) {
|
||||
return -1;
|
||||
}
|
||||
FILE* w = fopen(dst, "w");
|
||||
if (!w) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
size_t res;
|
||||
while ((res = fread(buf, 1, sizeof(buf), r)) > 0) {
|
||||
if (fwrite(buf, 1, res, w) != res) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(r);
|
||||
fclose(w);
|
||||
return res >= 0 ? 0 : res;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Threaded SaveFile takes copy of gSaveContext for local unmodified storage
|
||||
|
||||
void SaveManager::SaveFileThreaded(int fileNum, SaveContext* saveContext, int sectionID) {
|
||||
@ -915,19 +946,42 @@ void SaveManager::SaveFileThreaded(int fileNum, SaveContext* saveContext, int se
|
||||
svi.func(saveContext, sectionID, false);
|
||||
}
|
||||
|
||||
std::filesystem::path fileName = GetFileName(fileNum);
|
||||
std::filesystem::path tempFile = GetFileTempName(fileNum);
|
||||
|
||||
if (std::filesystem::exists(tempFile)) {
|
||||
std::filesystem::remove(tempFile);
|
||||
}
|
||||
|
||||
#if defined(__SWITCH__) || defined(__WIIU__)
|
||||
FILE* w = fopen(GetFileName(fileNum).c_str(), "w");
|
||||
FILE* w = fopen(tempFile.c_str(), "w");
|
||||
std::string json_string = saveBlock.dump(4);
|
||||
fwrite(json_string.c_str(), sizeof(char), json_string.length(), w);
|
||||
fclose(w);
|
||||
#else
|
||||
std::ofstream output(GetFileName(fileNum));
|
||||
std::ofstream output(tempFile);
|
||||
output << std::setw(4) << saveBlock << std::endl;
|
||||
output.close();
|
||||
#endif
|
||||
|
||||
if (std::filesystem::exists(fileName)) {
|
||||
std::filesystem::remove(fileName);
|
||||
}
|
||||
|
||||
#if defined(__SWITCH__) || defined(__WIIU__)
|
||||
copy_file(tempFile.c_str(), fileName.c_str());
|
||||
#else
|
||||
std::filesystem::copy_file(tempFile, fileName);
|
||||
#endif
|
||||
|
||||
if (std::filesystem::exists(tempFile)) {
|
||||
std::filesystem::remove(tempFile);
|
||||
}
|
||||
|
||||
delete saveContext;
|
||||
InitMeta(fileNum);
|
||||
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSaveFile>(fileNum);
|
||||
SPDLOG_INFO("Save File Finish - fileNum: {}", fileNum);
|
||||
}
|
||||
|
||||
// SaveSection creates a copy of gSaveContext to prevent mid-save data modification, and passes its reference to SaveFileThreaded
|
||||
@ -2110,32 +2164,6 @@ void SaveManager::LoadStruct(const std::string& name, LoadStructFunc func) {
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__WIIU__) || defined(__SWITCH__)
|
||||
// std::filesystem::copy_file doesn't work properly with the Wii U's toolchain atm
|
||||
int copy_file(const char* src, const char* dst) {
|
||||
alignas(0x40) uint8_t buf[4096];
|
||||
FILE* r = fopen(src, "r");
|
||||
if (!r) {
|
||||
return -1;
|
||||
}
|
||||
FILE* w = fopen(dst, "w");
|
||||
if (!w) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
size_t res;
|
||||
while ((res = fread(buf, 1, sizeof(buf), r)) > 0) {
|
||||
if (fwrite(buf, 1, res, w) != res) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(r);
|
||||
fclose(w);
|
||||
return res >= 0 ? 0 : res;
|
||||
}
|
||||
#endif
|
||||
|
||||
void SaveManager::CopyZeldaFile(int from, int to) {
|
||||
assert(std::filesystem::exists(GetFileName(from)));
|
||||
DeleteZeldaFile(to);
|
||||
|
@ -142,6 +142,7 @@ class SaveManager {
|
||||
|
||||
private:
|
||||
std::filesystem::path GetFileName(int fileNum);
|
||||
std::filesystem::path GetFileTempName(int fileNum);
|
||||
nlohmann::json saveBlock;
|
||||
|
||||
void ConvertFromUnversioned();
|
||||
|
Loading…
Reference in New Issue
Block a user