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");
|
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() {
|
SaveManager::SaveManager() {
|
||||||
coreSectionIDsByName["base"] = SECTION_ID_BASE;
|
coreSectionIDsByName["base"] = SECTION_ID_BASE;
|
||||||
coreSectionIDsByName["randomizer"] = SECTION_ID_RANDOMIZER;
|
coreSectionIDsByName["randomizer"] = SECTION_ID_RANDOMIZER;
|
||||||
@ -874,6 +879,32 @@ void SaveManager::InitFileMaxed() {
|
|||||||
gSaveContext.sceneFlags[5].swch = 0x40000000;
|
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
|
// Threaded SaveFile takes copy of gSaveContext for local unmodified storage
|
||||||
|
|
||||||
void SaveManager::SaveFileThreaded(int fileNum, SaveContext* saveContext, int sectionID) {
|
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);
|
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__)
|
#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);
|
std::string json_string = saveBlock.dump(4);
|
||||||
fwrite(json_string.c_str(), sizeof(char), json_string.length(), w);
|
fwrite(json_string.c_str(), sizeof(char), json_string.length(), w);
|
||||||
fclose(w);
|
fclose(w);
|
||||||
#else
|
#else
|
||||||
std::ofstream output(GetFileName(fileNum));
|
std::ofstream output(tempFile);
|
||||||
output << std::setw(4) << saveBlock << std::endl;
|
output << std::setw(4) << saveBlock << std::endl;
|
||||||
|
output.close();
|
||||||
#endif
|
#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;
|
delete saveContext;
|
||||||
InitMeta(fileNum);
|
InitMeta(fileNum);
|
||||||
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSaveFile>(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
|
// 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) {
|
void SaveManager::CopyZeldaFile(int from, int to) {
|
||||||
assert(std::filesystem::exists(GetFileName(from)));
|
assert(std::filesystem::exists(GetFileName(from)));
|
||||||
DeleteZeldaFile(to);
|
DeleteZeldaFile(to);
|
||||||
|
@ -142,6 +142,7 @@ class SaveManager {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::filesystem::path GetFileName(int fileNum);
|
std::filesystem::path GetFileName(int fileNum);
|
||||||
|
std::filesystem::path GetFileTempName(int fileNum);
|
||||||
nlohmann::json saveBlock;
|
nlohmann::json saveBlock;
|
||||||
|
|
||||||
void ConvertFromUnversioned();
|
void ConvertFromUnversioned();
|
||||||
|
Loading…
Reference in New Issue
Block a user