|
|
|
@ -1,9 +1,11 @@ |
|
|
|
// 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"
|
|
|
|
|
|
|
|
@ -11,7 +13,8 @@ namespace fs = std::filesystem; |
|
|
|
|
|
|
|
namespace QtCommon::FS { |
|
|
|
|
|
|
|
void LinkRyujinx(std::filesystem::path &from, std::filesystem::path &to) { |
|
|
|
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
|
|
|
|
@ -20,11 +23,63 @@ void LinkRyujinx(std::filesystem::path &from, std::filesystem::path &to) { |
|
|
|
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()))); |
|
|
|
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 { |
|
|
|
fs::remove_all(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) |
|
|
|
@ -53,4 +108,21 @@ u64 GetRyujinxSaveID(const u64 &program_id) |
|
|
|
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
|