diff options
Diffstat (limited to '')
| -rw-r--r-- | src/core/file_sys/savedata_factory.cpp | 58 | ||||
| -rw-r--r-- | src/core/file_sys/savedata_factory.h | 4 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 10 |
3 files changed, 59 insertions, 13 deletions
diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index 8c1b2523c..1567da231 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include "common/assert.h" | 5 | #include "common/assert.h" |
| 6 | #include "common/common_types.h" | 6 | #include "common/common_types.h" |
| 7 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 8 | #include "common/uuid.h" | ||
| 8 | #include "core/core.h" | 9 | #include "core/core.h" |
| 9 | #include "core/file_sys/savedata_factory.h" | 10 | #include "core/file_sys/savedata_factory.h" |
| 10 | #include "core/file_sys/vfs.h" | 11 | #include "core/file_sys/vfs.h" |
| @@ -59,6 +60,36 @@ bool ShouldSaveDataBeAutomaticallyCreated(SaveDataSpaceId space, const SaveDataA | |||
| 59 | attr.title_id == 0 && attr.save_id == 0); | 60 | attr.title_id == 0 && attr.save_id == 0); |
| 60 | } | 61 | } |
| 61 | 62 | ||
| 63 | std::string GetFutureSaveDataPath(SaveDataSpaceId space_id, SaveDataType type, u64 title_id, | ||
| 64 | u128 user_id) { | ||
| 65 | // Only detect nand user saves. | ||
| 66 | const auto space_id_path = [space_id]() -> std::string_view { | ||
| 67 | switch (space_id) { | ||
| 68 | case SaveDataSpaceId::NandUser: | ||
| 69 | return "/user/save"; | ||
| 70 | default: | ||
| 71 | return ""; | ||
| 72 | } | ||
| 73 | }(); | ||
| 74 | |||
| 75 | if (space_id_path.empty()) { | ||
| 76 | return ""; | ||
| 77 | } | ||
| 78 | |||
| 79 | Common::UUID uuid; | ||
| 80 | std::memcpy(uuid.uuid.data(), user_id.data(), sizeof(Common::UUID)); | ||
| 81 | |||
| 82 | // Only detect account/device saves from the future location. | ||
| 83 | switch (type) { | ||
| 84 | case SaveDataType::SaveData: | ||
| 85 | return fmt::format("{}/account/{}/{:016X}/1", space_id_path, uuid.RawString(), title_id); | ||
| 86 | case SaveDataType::DeviceSaveData: | ||
| 87 | return fmt::format("{}/device/{:016X}/1", space_id_path, title_id); | ||
| 88 | default: | ||
| 89 | return ""; | ||
| 90 | } | ||
| 91 | } | ||
| 92 | |||
| 62 | } // Anonymous namespace | 93 | } // Anonymous namespace |
| 63 | 94 | ||
| 64 | std::string SaveDataAttribute::DebugInfo() const { | 95 | std::string SaveDataAttribute::DebugInfo() const { |
| @@ -82,7 +113,7 @@ ResultVal<VirtualDir> SaveDataFactory::Create(SaveDataSpaceId space, | |||
| 82 | PrintSaveDataAttributeWarnings(meta); | 113 | PrintSaveDataAttributeWarnings(meta); |
| 83 | 114 | ||
| 84 | const auto save_directory = | 115 | const auto save_directory = |
| 85 | GetFullPath(system, space, meta.type, meta.title_id, meta.user_id, meta.save_id); | 116 | GetFullPath(system, dir, space, meta.type, meta.title_id, meta.user_id, meta.save_id); |
| 86 | 117 | ||
| 87 | auto out = dir->CreateDirectoryRelative(save_directory); | 118 | auto out = dir->CreateDirectoryRelative(save_directory); |
| 88 | 119 | ||
| @@ -99,7 +130,7 @@ ResultVal<VirtualDir> SaveDataFactory::Open(SaveDataSpaceId space, | |||
| 99 | const SaveDataAttribute& meta) const { | 130 | const SaveDataAttribute& meta) const { |
| 100 | 131 | ||
| 101 | const auto save_directory = | 132 | const auto save_directory = |
| 102 | GetFullPath(system, space, meta.type, meta.title_id, meta.user_id, meta.save_id); | 133 | GetFullPath(system, dir, space, meta.type, meta.title_id, meta.user_id, meta.save_id); |
| 103 | 134 | ||
| 104 | auto out = dir->GetDirectoryRelative(save_directory); | 135 | auto out = dir->GetDirectoryRelative(save_directory); |
| 105 | 136 | ||
| @@ -134,9 +165,9 @@ std::string SaveDataFactory::GetSaveDataSpaceIdPath(SaveDataSpaceId space) { | |||
| 134 | } | 165 | } |
| 135 | } | 166 | } |
| 136 | 167 | ||
| 137 | std::string SaveDataFactory::GetFullPath(Core::System& system, SaveDataSpaceId space, | 168 | std::string SaveDataFactory::GetFullPath(Core::System& system, VirtualDir dir, |
| 138 | SaveDataType type, u64 title_id, u128 user_id, | 169 | SaveDataSpaceId space, SaveDataType type, u64 title_id, |
| 139 | u64 save_id) { | 170 | u128 user_id, u64 save_id) { |
| 140 | // According to switchbrew, if a save is of type SaveData and the title id field is 0, it should | 171 | // According to switchbrew, if a save is of type SaveData and the title id field is 0, it should |
| 141 | // be interpreted as the title id of the current process. | 172 | // be interpreted as the title id of the current process. |
| 142 | if (type == SaveDataType::SaveData || type == SaveDataType::DeviceSaveData) { | 173 | if (type == SaveDataType::SaveData || type == SaveDataType::DeviceSaveData) { |
| @@ -145,6 +176,17 @@ std::string SaveDataFactory::GetFullPath(Core::System& system, SaveDataSpaceId s | |||
| 145 | } | 176 | } |
| 146 | } | 177 | } |
| 147 | 178 | ||
| 179 | // For compat with a future impl. | ||
| 180 | if (std::string future_path = | ||
| 181 | GetFutureSaveDataPath(space, type, title_id & ~(0xFFULL), user_id); | ||
| 182 | !future_path.empty()) { | ||
| 183 | // Check if this location exists, and prefer it over the old. | ||
| 184 | if (const auto future_dir = dir->GetDirectoryRelative(future_path); future_dir != nullptr) { | ||
| 185 | LOG_INFO(Service_FS, "Using save at new location: {}", future_path); | ||
| 186 | return future_path; | ||
| 187 | } | ||
| 188 | } | ||
| 189 | |||
| 148 | std::string out = GetSaveDataSpaceIdPath(space); | 190 | std::string out = GetSaveDataSpaceIdPath(space); |
| 149 | 191 | ||
| 150 | switch (type) { | 192 | switch (type) { |
| @@ -167,7 +209,8 @@ std::string SaveDataFactory::GetFullPath(Core::System& system, SaveDataSpaceId s | |||
| 167 | 209 | ||
| 168 | SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id, | 210 | SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id, |
| 169 | u128 user_id) const { | 211 | u128 user_id) const { |
| 170 | const auto path = GetFullPath(system, SaveDataSpaceId::NandUser, type, title_id, user_id, 0); | 212 | const auto path = |
| 213 | GetFullPath(system, dir, SaveDataSpaceId::NandUser, type, title_id, user_id, 0); | ||
| 171 | const auto relative_dir = GetOrCreateDirectoryRelative(dir, path); | 214 | const auto relative_dir = GetOrCreateDirectoryRelative(dir, path); |
| 172 | 215 | ||
| 173 | const auto size_file = relative_dir->GetFile(SAVE_DATA_SIZE_FILENAME); | 216 | const auto size_file = relative_dir->GetFile(SAVE_DATA_SIZE_FILENAME); |
| @@ -185,7 +228,8 @@ SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id, | |||
| 185 | 228 | ||
| 186 | void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id, | 229 | void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id, |
| 187 | SaveDataSize new_value) const { | 230 | SaveDataSize new_value) const { |
| 188 | const auto path = GetFullPath(system, SaveDataSpaceId::NandUser, type, title_id, user_id, 0); | 231 | const auto path = |
| 232 | GetFullPath(system, dir, SaveDataSpaceId::NandUser, type, title_id, user_id, 0); | ||
| 189 | const auto relative_dir = GetOrCreateDirectoryRelative(dir, path); | 233 | const auto relative_dir = GetOrCreateDirectoryRelative(dir, path); |
| 190 | 234 | ||
| 191 | const auto size_file = relative_dir->CreateFile(SAVE_DATA_SIZE_FILENAME); | 235 | const auto size_file = relative_dir->CreateFile(SAVE_DATA_SIZE_FILENAME); |
diff --git a/src/core/file_sys/savedata_factory.h b/src/core/file_sys/savedata_factory.h index a763b94c8..d3633ef03 100644 --- a/src/core/file_sys/savedata_factory.h +++ b/src/core/file_sys/savedata_factory.h | |||
| @@ -95,8 +95,8 @@ public: | |||
| 95 | VirtualDir GetSaveDataSpaceDirectory(SaveDataSpaceId space) const; | 95 | VirtualDir GetSaveDataSpaceDirectory(SaveDataSpaceId space) const; |
| 96 | 96 | ||
| 97 | static std::string GetSaveDataSpaceIdPath(SaveDataSpaceId space); | 97 | static std::string GetSaveDataSpaceIdPath(SaveDataSpaceId space); |
| 98 | static std::string GetFullPath(Core::System& system, SaveDataSpaceId space, SaveDataType type, | 98 | static std::string GetFullPath(Core::System& system, VirtualDir dir, SaveDataSpaceId space, |
| 99 | u64 title_id, u128 user_id, u64 save_id); | 99 | SaveDataType type, u64 title_id, u128 user_id, u64 save_id); |
| 100 | 100 | ||
| 101 | SaveDataSize ReadSaveDataSize(SaveDataType type, u64 title_id, u128 user_id) const; | 101 | SaveDataSize ReadSaveDataSize(SaveDataType type, u64 title_id, u128 user_id) const; |
| 102 | void WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id, | 102 | void WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id, |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index a94624be6..d05c7ece8 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -1895,6 +1895,8 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target | |||
| 1895 | case GameListOpenTarget::SaveData: { | 1895 | case GameListOpenTarget::SaveData: { |
| 1896 | open_target = tr("Save Data"); | 1896 | open_target = tr("Save Data"); |
| 1897 | const auto nand_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir); | 1897 | const auto nand_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir); |
| 1898 | auto vfs_nand_dir = | ||
| 1899 | vfs->OpenDirectory(Common::FS::PathToUTF8String(nand_dir), FileSys::Mode::Read); | ||
| 1898 | 1900 | ||
| 1899 | if (has_user_save) { | 1901 | if (has_user_save) { |
| 1900 | // User save data | 1902 | // User save data |
| @@ -1921,15 +1923,15 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target | |||
| 1921 | ASSERT(user_id); | 1923 | ASSERT(user_id); |
| 1922 | 1924 | ||
| 1923 | const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath( | 1925 | const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath( |
| 1924 | *system, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData, | 1926 | *system, vfs_nand_dir, FileSys::SaveDataSpaceId::NandUser, |
| 1925 | program_id, user_id->AsU128(), 0); | 1927 | FileSys::SaveDataType::SaveData, program_id, user_id->AsU128(), 0); |
| 1926 | 1928 | ||
| 1927 | path = Common::FS::ConcatPathSafe(nand_dir, user_save_data_path); | 1929 | path = Common::FS::ConcatPathSafe(nand_dir, user_save_data_path); |
| 1928 | } else { | 1930 | } else { |
| 1929 | // Device save data | 1931 | // Device save data |
| 1930 | const auto device_save_data_path = FileSys::SaveDataFactory::GetFullPath( | 1932 | const auto device_save_data_path = FileSys::SaveDataFactory::GetFullPath( |
| 1931 | *system, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData, | 1933 | *system, vfs_nand_dir, FileSys::SaveDataSpaceId::NandUser, |
| 1932 | program_id, {}, 0); | 1934 | FileSys::SaveDataType::SaveData, program_id, {}, 0); |
| 1933 | 1935 | ||
| 1934 | path = Common::FS::ConcatPathSafe(nand_dir, device_save_data_path); | 1936 | path = Common::FS::ConcatPathSafe(nand_dir, device_save_data_path); |
| 1935 | } | 1937 | } |