2
1
Fork 0
mirror of https://github.com/yuzu-emu/yuzu.git synced 2024-07-04 23:31:19 +01:00

Merge pull request #9082 from Morph1984/future

savedata_factory: Detect future save data paths
This commit is contained in:
liamwhite 2022-10-19 16:28:42 -04:00 committed by GitHub
commit 5ffb8b8039
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 13 deletions

View file

@ -5,6 +5,7 @@
#include "common/assert.h" #include "common/assert.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/uuid.h"
#include "core/core.h" #include "core/core.h"
#include "core/file_sys/savedata_factory.h" #include "core/file_sys/savedata_factory.h"
#include "core/file_sys/vfs.h" #include "core/file_sys/vfs.h"
@ -59,6 +60,36 @@ bool ShouldSaveDataBeAutomaticallyCreated(SaveDataSpaceId space, const SaveDataA
attr.title_id == 0 && attr.save_id == 0); attr.title_id == 0 && attr.save_id == 0);
} }
std::string GetFutureSaveDataPath(SaveDataSpaceId space_id, SaveDataType type, u64 title_id,
u128 user_id) {
// Only detect nand user saves.
const auto space_id_path = [space_id]() -> std::string_view {
switch (space_id) {
case SaveDataSpaceId::NandUser:
return "/user/save";
default:
return "";
}
}();
if (space_id_path.empty()) {
return "";
}
Common::UUID uuid;
std::memcpy(uuid.uuid.data(), user_id.data(), sizeof(Common::UUID));
// Only detect account/device saves from the future location.
switch (type) {
case SaveDataType::SaveData:
return fmt::format("{}/account/{}/{:016X}/1", space_id_path, uuid.RawString(), title_id);
case SaveDataType::DeviceSaveData:
return fmt::format("{}/device/{:016X}/1", space_id_path, title_id);
default:
return "";
}
}
} // Anonymous namespace } // Anonymous namespace
std::string SaveDataAttribute::DebugInfo() const { std::string SaveDataAttribute::DebugInfo() const {
@ -82,7 +113,7 @@ ResultVal<VirtualDir> SaveDataFactory::Create(SaveDataSpaceId space,
PrintSaveDataAttributeWarnings(meta); PrintSaveDataAttributeWarnings(meta);
const auto save_directory = const auto save_directory =
GetFullPath(system, space, meta.type, meta.title_id, meta.user_id, meta.save_id); GetFullPath(system, dir, space, meta.type, meta.title_id, meta.user_id, meta.save_id);
auto out = dir->CreateDirectoryRelative(save_directory); auto out = dir->CreateDirectoryRelative(save_directory);
@ -99,7 +130,7 @@ ResultVal<VirtualDir> SaveDataFactory::Open(SaveDataSpaceId space,
const SaveDataAttribute& meta) const { const SaveDataAttribute& meta) const {
const auto save_directory = const auto save_directory =
GetFullPath(system, space, meta.type, meta.title_id, meta.user_id, meta.save_id); GetFullPath(system, dir, space, meta.type, meta.title_id, meta.user_id, meta.save_id);
auto out = dir->GetDirectoryRelative(save_directory); auto out = dir->GetDirectoryRelative(save_directory);
@ -134,9 +165,9 @@ std::string SaveDataFactory::GetSaveDataSpaceIdPath(SaveDataSpaceId space) {
} }
} }
std::string SaveDataFactory::GetFullPath(Core::System& system, SaveDataSpaceId space, std::string SaveDataFactory::GetFullPath(Core::System& system, VirtualDir dir,
SaveDataType type, u64 title_id, u128 user_id, SaveDataSpaceId space, SaveDataType type, u64 title_id,
u64 save_id) { u128 user_id, u64 save_id) {
// According to switchbrew, if a save is of type SaveData and the title id field is 0, it should // According to switchbrew, if a save is of type SaveData and the title id field is 0, it should
// be interpreted as the title id of the current process. // be interpreted as the title id of the current process.
if (type == SaveDataType::SaveData || type == SaveDataType::DeviceSaveData) { if (type == SaveDataType::SaveData || type == SaveDataType::DeviceSaveData) {
@ -145,6 +176,17 @@ std::string SaveDataFactory::GetFullPath(Core::System& system, SaveDataSpaceId s
} }
} }
// For compat with a future impl.
if (std::string future_path =
GetFutureSaveDataPath(space, type, title_id & ~(0xFFULL), user_id);
!future_path.empty()) {
// Check if this location exists, and prefer it over the old.
if (const auto future_dir = dir->GetDirectoryRelative(future_path); future_dir != nullptr) {
LOG_INFO(Service_FS, "Using save at new location: {}", future_path);
return future_path;
}
}
std::string out = GetSaveDataSpaceIdPath(space); std::string out = GetSaveDataSpaceIdPath(space);
switch (type) { switch (type) {
@ -167,7 +209,8 @@ std::string SaveDataFactory::GetFullPath(Core::System& system, SaveDataSpaceId s
SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id, SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
u128 user_id) const { u128 user_id) const {
const auto path = GetFullPath(system, SaveDataSpaceId::NandUser, type, title_id, user_id, 0); const auto path =
GetFullPath(system, dir, SaveDataSpaceId::NandUser, type, title_id, user_id, 0);
const auto relative_dir = GetOrCreateDirectoryRelative(dir, path); const auto relative_dir = GetOrCreateDirectoryRelative(dir, path);
const auto size_file = relative_dir->GetFile(SAVE_DATA_SIZE_FILENAME); const auto size_file = relative_dir->GetFile(SAVE_DATA_SIZE_FILENAME);
@ -185,7 +228,8 @@ SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id, void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id,
SaveDataSize new_value) const { SaveDataSize new_value) const {
const auto path = GetFullPath(system, SaveDataSpaceId::NandUser, type, title_id, user_id, 0); const auto path =
GetFullPath(system, dir, SaveDataSpaceId::NandUser, type, title_id, user_id, 0);
const auto relative_dir = GetOrCreateDirectoryRelative(dir, path); const auto relative_dir = GetOrCreateDirectoryRelative(dir, path);
const auto size_file = relative_dir->CreateFile(SAVE_DATA_SIZE_FILENAME); const auto size_file = relative_dir->CreateFile(SAVE_DATA_SIZE_FILENAME);

View file

@ -95,8 +95,8 @@ public:
VirtualDir GetSaveDataSpaceDirectory(SaveDataSpaceId space) const; VirtualDir GetSaveDataSpaceDirectory(SaveDataSpaceId space) const;
static std::string GetSaveDataSpaceIdPath(SaveDataSpaceId space); static std::string GetSaveDataSpaceIdPath(SaveDataSpaceId space);
static std::string GetFullPath(Core::System& system, SaveDataSpaceId space, SaveDataType type, static std::string GetFullPath(Core::System& system, VirtualDir dir, SaveDataSpaceId space,
u64 title_id, u128 user_id, u64 save_id); SaveDataType type, u64 title_id, u128 user_id, u64 save_id);
SaveDataSize ReadSaveDataSize(SaveDataType type, u64 title_id, u128 user_id) const; SaveDataSize ReadSaveDataSize(SaveDataType type, u64 title_id, u128 user_id) const;
void WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id, void WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id,

View file

@ -1896,6 +1896,8 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
case GameListOpenTarget::SaveData: { case GameListOpenTarget::SaveData: {
open_target = tr("Save Data"); open_target = tr("Save Data");
const auto nand_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir); const auto nand_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir);
auto vfs_nand_dir =
vfs->OpenDirectory(Common::FS::PathToUTF8String(nand_dir), FileSys::Mode::Read);
if (has_user_save) { if (has_user_save) {
// User save data // User save data
@ -1922,15 +1924,15 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
ASSERT(user_id); ASSERT(user_id);
const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath( const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath(
*system, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData, *system, vfs_nand_dir, FileSys::SaveDataSpaceId::NandUser,
program_id, user_id->AsU128(), 0); FileSys::SaveDataType::SaveData, program_id, user_id->AsU128(), 0);
path = Common::FS::ConcatPathSafe(nand_dir, user_save_data_path); path = Common::FS::ConcatPathSafe(nand_dir, user_save_data_path);
} else { } else {
// Device save data // Device save data
const auto device_save_data_path = FileSys::SaveDataFactory::GetFullPath( const auto device_save_data_path = FileSys::SaveDataFactory::GetFullPath(
*system, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData, *system, vfs_nand_dir, FileSys::SaveDataSpaceId::NandUser,
program_id, {}, 0); FileSys::SaveDataType::SaveData, program_id, {}, 0);
path = Common::FS::ConcatPathSafe(nand_dir, device_save_data_path); path = Common::FS::ConcatPathSafe(nand_dir, device_save_data_path);
} }