mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-15 13:18:56 +02:00
[desktop, fs] main_window separation; fix Ryujinx save data link issues (#2929)
Some genius decided to put the entire MainWindow class into main.h and main.cpp, which is not only horrific practice but also completely destroys clangd beyond repair. Please, just don't do this. (this will probably merge conflict to hell and back) Also, fixes a bunch of issues with Ryujinx save data link: - Paths with spaces would cause mklink to fail - Add support for portable directories - Symlink detection was incorrect sometimes(????) - Some other stuff I'm forgetting Furthermore, when selecting "From Eden" and attempting to save in Ryujinx, Ryujinx would destroy the link for... some reason? So to get around this we just copy the Eden data to Ryujinx then treat it like a "From Ryujinx" op Signed-off-by: crueter <crueter@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2929 Reviewed-by: Lizzie <lizzie@eden-emu.dev> Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
This commit is contained in:
parent
e13c7ef3f8
commit
08f3639c80
51 changed files with 5386 additions and 5283 deletions
|
|
@ -1,11 +1,11 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include <algorithm>
|
||||
#include <filesystem>
|
||||
#include "fs.h"
|
||||
#include "common/fs/ryujinx_compat.h"
|
||||
#include "common/fs/symlink.h"
|
||||
#include "frontend_common/data_manager.h"
|
||||
#include "fs.h"
|
||||
#include "qt_common/abstract/frontend.h"
|
||||
#include "qt_common/qt_string_lookup.h"
|
||||
|
||||
|
|
@ -56,6 +56,9 @@ bool CheckUnlink(const fs::path &eden_dir, const fs::path &ryu_dir)
|
|||
orig = eden_dir;
|
||||
}
|
||||
|
||||
linked.make_preferred();
|
||||
orig.make_preferred();
|
||||
|
||||
// first cleanup the symlink/junction,
|
||||
try {
|
||||
// NB: do NOT use remove_all, as Windows treats this as a remove_all to the target,
|
||||
|
|
@ -84,47 +87,64 @@ bool CheckUnlink(const fs::path &eden_dir, const fs::path &ryu_dir)
|
|||
return true;
|
||||
}
|
||||
|
||||
u64 GetRyujinxSaveID(const u64 &program_id)
|
||||
const fs::path GetRyujinxSavePath(const fs::path &path_hint, const u64 &program_id)
|
||||
{
|
||||
auto path = Common::FS::GetKvdbPath();
|
||||
auto ryu_path = path_hint;
|
||||
|
||||
auto kvdb_path = Common::FS::GetKvdbPath(ryu_path);
|
||||
|
||||
if (!fs::exists(kvdb_path)) {
|
||||
using namespace QtCommon::Frontend;
|
||||
auto res = Warning(
|
||||
tr("Could not find Ryujinx installation"),
|
||||
tr("Could not find a valid Ryujinx installation. This may typically occur if you are "
|
||||
"using Ryujinx in portable mode.\n\nWould you like to manually select a portable "
|
||||
"folder to use?"), StandardButton::Yes | StandardButton::No);
|
||||
|
||||
if (res == StandardButton::Yes) {
|
||||
auto selected_path = GetExistingDirectory(tr("Ryujinx Portable Location"), QDir::homePath()).toStdString();
|
||||
if (selected_path.empty())
|
||||
return fs::path{};
|
||||
|
||||
ryu_path = selected_path;
|
||||
|
||||
// In case the user selects the actual ryujinx installation dir INSTEAD OF
|
||||
// the portable dir
|
||||
if (fs::exists(ryu_path / "portable")) {
|
||||
ryu_path = ryu_path / "portable";
|
||||
}
|
||||
|
||||
kvdb_path = Common::FS::GetKvdbPath(ryu_path);
|
||||
|
||||
if (!fs::exists(kvdb_path)) {
|
||||
QtCommon::Frontend::Critical(
|
||||
tr("Not a valid Ryujinx directory"),
|
||||
tr("The specified directory does not contain valid Ryujinx data."));
|
||||
return fs::path{};
|
||||
}
|
||||
} else {
|
||||
return fs::path{};
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Common::FS::IMEN> imens;
|
||||
Common::FS::IMENReadResult res = Common::FS::ReadKvdb(path, imens);
|
||||
Common::FS::IMENReadResult res = Common::FS::ReadKvdb(kvdb_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;
|
||||
return Common::FS::GetRyuSavePath(ryu_path, 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));
|
||||
QString caption = LOOKUP_ENUM(res, 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);
|
||||
return fs::path{};
|
||||
}
|
||||
|
||||
} // namespace QtCommon::FS
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue