From 9fa5014d1694899c8ccb371baf0afdc2a75b3f79 Mon Sep 17 00:00:00 2001 From: Vinicius Rangel Date: Thu, 30 Jan 2025 03:59:52 -0300 Subject: [PATCH] savedata: auto-restore backup if needed --- .../libraries/save_data/save_instance.cpp | 20 ++++++++++++++----- src/core/libraries/save_data/save_instance.h | 3 ++- src/core/libraries/save_data/save_memory.cpp | 2 +- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/core/libraries/save_data/save_instance.cpp b/src/core/libraries/save_data/save_instance.cpp index 367d4871d..26708d2d6 100644 --- a/src/core/libraries/save_data/save_instance.cpp +++ b/src/core/libraries/save_data/save_instance.cpp @@ -10,6 +10,7 @@ #include "common/path_util.h" #include "common/singleton.h" #include "core/file_sys/fs.h" +#include "save_backup.h" #include "save_instance.h" constexpr auto OrbisSaveDataBlocksMin2 = 96; // 3MiB @@ -140,7 +141,8 @@ SaveInstance& SaveInstance::operator=(SaveInstance&& other) noexcept { return *this; } -void SaveInstance::SetupAndMount(bool read_only, bool copy_icon, bool ignore_corrupt) { +void SaveInstance::SetupAndMount(bool read_only, bool copy_icon, bool ignore_corrupt, + bool dont_restore_backup) { if (mounted) { UNREACHABLE_MSG("Save instance is already mounted"); } @@ -159,13 +161,21 @@ void SaveInstance::SetupAndMount(bool read_only, bool copy_icon, bool ignore_cor } exists = true; } else { + std::optional err; if (!ignore_corrupt && fs::exists(corrupt_file_path)) { - throw fs::filesystem_error("Corrupted save data", corrupt_file_path, + err = fs::filesystem_error("Corrupted save data", corrupt_file_path, + std::make_error_code(std::errc::illegal_byte_sequence)); + } else if (!param_sfo.Open(param_sfo_path)) { + err = fs::filesystem_error("Failed to read param.sfo", param_sfo_path, std::make_error_code(std::errc::illegal_byte_sequence)); } - if (!param_sfo.Open(param_sfo_path)) { - throw fs::filesystem_error("Failed to read param.sfo", param_sfo_path, - std::make_error_code(std::errc::illegal_byte_sequence)); + if (err.has_value()) { + if (dont_restore_backup) { + throw err.value(); + } + if (Backup::Restore(save_path)) { + return SetupAndMount(read_only, copy_icon, ignore_corrupt, true); + } } } diff --git a/src/core/libraries/save_data/save_instance.h b/src/core/libraries/save_data/save_instance.h index fb4f544ce..6e7ac8f66 100644 --- a/src/core/libraries/save_data/save_instance.h +++ b/src/core/libraries/save_data/save_instance.h @@ -78,7 +78,8 @@ public: SaveInstance& operator=(const SaveInstance& other) = delete; SaveInstance& operator=(SaveInstance&& other) noexcept; - void SetupAndMount(bool read_only = false, bool copy_icon = false, bool ignore_corrupt = false); + void SetupAndMount(bool read_only = false, bool copy_icon = false, bool ignore_corrupt = false, + bool dont_restore_backup = false); void Umount(); diff --git a/src/core/libraries/save_data/save_memory.cpp b/src/core/libraries/save_data/save_memory.cpp index 6f05d8926..13e122c60 100644 --- a/src/core/libraries/save_data/save_memory.cpp +++ b/src/core/libraries/save_data/save_memory.cpp @@ -126,7 +126,7 @@ size_t SetupSaveMemory(OrbisUserServiceUserId user_id, u32 slot_id, std::string_ const auto memory = save_dir / FilenameSaveDataMemory; if (fs::exists(memory)) { - return {fs::file_size(memory)}; + return fs::file_size(memory); } return 0;