diff options
Diffstat (limited to 'src/qt_common/util')
| -rw-r--r-- | src/qt_common/util/content.cpp | 6 | ||||
| -rw-r--r-- | src/qt_common/util/content.h | 6 | ||||
| -rw-r--r-- | src/qt_common/util/fs.cpp | 130 | ||||
| -rw-r--r-- | src/qt_common/util/fs.h | 22 | ||||
| -rw-r--r-- | src/qt_common/util/game.cpp | 2 | ||||
| -rw-r--r-- | src/qt_common/util/path.cpp | 2 |
6 files changed, 161 insertions, 7 deletions
diff --git a/src/qt_common/util/content.cpp b/src/qt_common/util/content.cpp index 4360efeef0..df4435f567 100644 --- a/src/qt_common/util/content.cpp +++ b/src/qt_common/util/content.cpp @@ -11,7 +11,7 @@ #include "frontend_common/firmware_manager.h" #include "compress.h" -#include "qt_common/abstract/qt_frontend_util.h" +#include "qt_common/abstract/frontend.h" #include "qt_common/abstract/qt_progress_dialog.h" #include "qt_common/qt_common.h" @@ -404,7 +404,7 @@ void ExportDataDir(FrontendCommon::DataManager::DataDir data_dir, std::function<void()> callback) { using namespace QtCommon::Frontend; - const std::string dir = FrontendCommon::DataManager::GetDataDir(data_dir, user_id); + const std::string dir = FrontendCommon::DataManager::GetDataDirString(data_dir, user_id); const QString zip_dump_location = GetSaveFileName(tr("Select Export Location"), tr("%1.zip").arg(name), @@ -468,7 +468,7 @@ void ImportDataDir(FrontendCommon::DataManager::DataDir data_dir, const std::string& user_id, std::function<void()> callback) { - const std::string dir = FrontendCommon::DataManager::GetDataDir(data_dir, user_id); + const std::string dir = FrontendCommon::DataManager::GetDataDirString(data_dir, user_id); using namespace QtCommon::Frontend; diff --git a/src/qt_common/util/content.h b/src/qt_common/util/content.h index d1384546e1..4102737fb1 100644 --- a/src/qt_common/util/content.h +++ b/src/qt_common/util/content.h @@ -25,7 +25,8 @@ enum class FirmwareInstallResult { inline const QString GetFirmwareInstallResultString(FirmwareInstallResult result) { - return QtCommon::StringLookup::Lookup(static_cast<StringLookup::StringKey>((int) result + (int) QtCommon::StringLookup::FwInstallSuccess)); + return QtCommon::StringLookup::Lookup(static_cast<StringLookup::StringKey>( + (int) result + (int) QtCommon::StringLookup::FwInstallSuccess)); } /** @@ -36,7 +37,8 @@ inline const QString GetFirmwareInstallResultString(FirmwareInstallResult result inline const QString GetKeyInstallResultString(FirmwareManager::KeyInstallResult result) { // this can probably be made into a common function of sorts - return QtCommon::StringLookup::Lookup(static_cast<StringLookup::StringKey>((int) result + (int) QtCommon::StringLookup::KeyInstallSuccess)); + return QtCommon::StringLookup::Lookup(static_cast<StringLookup::StringKey>( + (int) result + (int) QtCommon::StringLookup::KeyInstallSuccess)); } void InstallFirmware(const QString &location, bool recursive); diff --git a/src/qt_common/util/fs.cpp b/src/qt_common/util/fs.cpp new file mode 100644 index 0000000000..da59a4e675 --- /dev/null +++ b/src/qt_common/util/fs.cpp @@ -0,0 +1,130 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include <filesystem> +#include "fs.h" +#include "common/fs/ryujinx_compat.h" +#include "common/fs/symlink.h" +#include "frontend_common/data_manager.h" +#include "qt_common/abstract/frontend.h" +#include "qt_common/qt_string_lookup.h" + +namespace fs = std::filesystem; + +namespace QtCommon::FS { + +void LinkRyujinx(std::filesystem::path &from, std::filesystem::path &to) +{ + std::error_code ec; + + // "ignore" errors--if the dir fails to be deleted, error handling later will handle it + fs::remove_all(to, ec); + + if (Common::FS::CreateSymlink(from, to)) { + QtCommon::Frontend::Information(tr("Linked Save Data"), tr("Save data has been linked.")); + } else { + QtCommon::Frontend::Critical( + tr("Failed to link save data"), + tr("Could not link directory:\n\t%1\nTo:\n\t%2").arg(QString::fromStdString(from.string()), QString::fromStdString(to.string()))); + } +} + +bool CheckUnlink(const fs::path &eden_dir, const fs::path &ryu_dir) +{ + bool eden_link = Common::FS::IsSymlink(eden_dir); + bool ryu_link = Common::FS::IsSymlink(ryu_dir); + + if (!(eden_link || ryu_link)) + return false; + + auto result = QtCommon::Frontend::Warning( + tr("Already Linked"), + tr("This title is already linked to Ryujinx. Would you like to unlink it?"), + QtCommon::Frontend::StandardButton::Yes | QtCommon::Frontend::StandardButton::No); + + if (result != QtCommon::Frontend::StandardButton::Yes) + return true; + + fs::path linked; + fs::path orig; + + if (eden_link) { + linked = eden_dir; + orig = ryu_dir; + } else { + linked = ryu_dir; + orig = eden_dir; + } + + // first cleanup the symlink/junction, + try { + // NB: do NOT use remove_all, as Windows treats this as a remove_all to the target, + // NOT the junction + fs::remove(linked); + } catch (std::exception &e) { + QtCommon::Frontend::Critical( + tr("Failed to unlink old directory"), + tr("OS returned error: %1").arg(QString::fromStdString(e.what()))); + return true; + } + + // then COPY the other dir + try { + fs::copy(orig, linked, fs::copy_options::recursive); + } catch (std::exception &e) { + QtCommon::Frontend::Critical( + tr("Failed to copy save data"), + tr("OS returned error: %1").arg(QString::fromStdString(e.what()))); + } + + QtCommon::Frontend::Information( + tr("Unlink Successful"), + tr("Successfully unlinked Ryujinx save data. Save data has been kept intact.")); + + return true; +} + +u64 GetRyujinxSaveID(const u64 &program_id) +{ + auto path = Common::FS::GetKvdbPath(); + std::vector<Common::FS::IMEN> imens; + Common::FS::IMENReadResult res = Common::FS::ReadKvdb(path, imens); + + if (res == Common::FS::IMENReadResult::Success) { + // TODO: this can probably be done with std::find_if but I'm lazy + for (const Common::FS::IMEN &imen : imens) { + if (imen.title_id == program_id) + return imen.save_id; + } + + QtCommon::Frontend::Critical( + tr("Could not find Ryujinx save data"), + StringLookup::Lookup(StringLookup::RyujinxNoSaveId).arg(program_id, 0, 16)); + } else { + // TODO: make this long thing a function or something + QString caption = StringLookup::Lookup( + static_cast<StringLookup::StringKey>((int) res + (int) StringLookup::KvdbNonexistent)); + QtCommon::Frontend::Critical(tr("Could not find Ryujinx save data"), caption); + } + + return -1; +} + +std::optional<std::pair<fs::path, fs::path> > GetEmuPaths( + const u64 program_id, const u64 save_id, const std::string &user_id) +{ + fs::path ryu_dir = Common::FS::GetRyuSavePath(save_id); + + if (user_id.empty()) + return std::nullopt; + + std::string hex_program = fmt::format("{:016X}", program_id); + fs::path eden_dir + = FrontendCommon::DataManager::GetDataDir(FrontendCommon::DataManager::DataDir::Saves, + user_id) + / hex_program; + + return std::make_pair(eden_dir, ryu_dir); +} + +} // namespace QtCommon::FS diff --git a/src/qt_common/util/fs.h b/src/qt_common/util/fs.h new file mode 100644 index 0000000000..ee8859a2e5 --- /dev/null +++ b/src/qt_common/util/fs.h @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "common/common_types.h" +#include <filesystem> +#include <optional> + +#pragma once + +namespace QtCommon::FS { + +void LinkRyujinx(std::filesystem::path &from, std::filesystem::path &to); +u64 GetRyujinxSaveID(const u64 &program_id); + +/// @brief {eden, ryu} +std::optional<std::pair<std::filesystem::path, std::filesystem::path>> GetEmuPaths( + const u64 program_id, const u64 save_id, const std::string &user_id); + +/// returns FALSE if the dirs are NOT linked +bool CheckUnlink(const std::filesystem::path &eden_dir, const std::filesystem::path &ryu_dir); + +} // namespace QtCommon::FS diff --git a/src/qt_common/util/game.cpp b/src/qt_common/util/game.cpp index e5018d24cb..e34a388993 100644 --- a/src/qt_common/util/game.cpp +++ b/src/qt_common/util/game.cpp @@ -8,7 +8,7 @@ #include "core/file_sys/savedata_factory.h" #include "core/hle/service/am/am_types.h" #include "frontend_common/content_manager.h" -#include "qt_common/abstract/qt_frontend_util.h" +#include "qt_common/abstract/frontend.h" #include "qt_common/config/uisettings.h" #include "qt_common/qt_common.h" #include "yuzu/util/util.h" diff --git a/src/qt_common/util/path.cpp b/src/qt_common/util/path.cpp index 93e8007eb9..73689058c6 100644 --- a/src/qt_common/util/path.cpp +++ b/src/qt_common/util/path.cpp @@ -7,7 +7,7 @@ #include <QUrl> #include "common/fs/fs.h" #include "common/fs/path_util.h" -#include "qt_common/abstract/qt_frontend_util.h" +#include "qt_common/abstract/frontend.h" #include <fmt/format.h> namespace QtCommon::Path { |
