summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/file_sys/savedata_factory.cpp58
-rw-r--r--src/core/file_sys/savedata_factory.h4
-rw-r--r--src/yuzu/main.cpp10
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
63std::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
64std::string SaveDataAttribute::DebugInfo() const { 95std::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
137std::string SaveDataFactory::GetFullPath(Core::System& system, SaveDataSpaceId space, 168std::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
168SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id, 210SaveDataSize 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
186void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id, 229void 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 }