mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-14 09:08:59 +02:00
[qt] clean up some orphaned_profiles bugs; add help (#2894)
Some weird edge cases of "phantom" profiles that are actually needed for... reasons I guess Also, fixed some of the logic w.r.t empty checking, plus added a help page Signed-off-by: crueter <crueter@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2894 Reviewed-by: Lizzie <lizzie@eden-emu.dev> Reviewed-by: Maufeat <sahyno1996@gmail.com> Reviewed-by: MaranBr <maranbr@eden-emu.dev>
This commit is contained in:
parent
d989166044
commit
e93159b047
6 changed files with 100 additions and 38 deletions
|
|
@ -10,16 +10,19 @@
|
|||
#include <iostream>
|
||||
#include <random>
|
||||
|
||||
#include <boost/algorithm/string/case_conv.hpp>
|
||||
#include <boost/algorithm/string/find.hpp>
|
||||
#include <fmt/ranges.h>
|
||||
|
||||
#include "common/fs/file.h"
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/fs_types.h"
|
||||
#include "common/fs/path_util.h"
|
||||
#include <ranges>
|
||||
#include "common/settings.h"
|
||||
#include "common/string_util.h"
|
||||
#include "core/file_sys/savedata_factory.h"
|
||||
#include "core/hle/service/acc/profile_manager.h"
|
||||
#include <ranges>
|
||||
|
||||
namespace Service::Account {
|
||||
|
||||
|
|
@ -39,6 +42,7 @@ struct ProfileDataRaw {
|
|||
INSERT_PADDING_BYTES(0x10);
|
||||
std::array<UserRaw, MAX_USERS> users{};
|
||||
};
|
||||
|
||||
static_assert(sizeof(ProfileDataRaw) == 0x650, "ProfileDataRaw has incorrect size.");
|
||||
|
||||
// TODO(ogniK): Get actual error codes
|
||||
|
|
@ -490,8 +494,22 @@ void ProfileManager::ResetUserSaveFile()
|
|||
|
||||
std::vector<std::string> ProfileManager::FindGoodProfiles()
|
||||
{
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
std::vector<std::string> good_uuids;
|
||||
|
||||
const auto path = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir)
|
||||
/ "user/save/0000000000000000";
|
||||
|
||||
// some exceptions because certain games just LOVE TO CAUSE ISSUES
|
||||
static constexpr const std::array<const char* const, 2> EXCEPTION_UUIDS
|
||||
= {"5755CC2A545A87128500000000000000", "00000000000000000000000000000000"};
|
||||
|
||||
for (const char *const uuid : EXCEPTION_UUIDS) {
|
||||
if (fs::exists(path / uuid))
|
||||
good_uuids.emplace_back(uuid);
|
||||
}
|
||||
|
||||
for (const ProfileInfo& p : profiles) {
|
||||
std::string uuid_string = [p]() -> std::string {
|
||||
auto uuid = p.user_uuid;
|
||||
|
|
@ -506,12 +524,9 @@ std::vector<std::string> ProfileManager::FindGoodProfiles()
|
|||
return fmt::format("{:016X}{:016X}", user_id[1], user_id[0]);
|
||||
}();
|
||||
|
||||
good_uuids.emplace_back(uuid_string);
|
||||
if (uuid_string != "0") good_uuids.emplace_back(uuid_string);
|
||||
}
|
||||
|
||||
// used for acnh, etc
|
||||
good_uuids.emplace_back("00000000000000000000000000000000");
|
||||
|
||||
return good_uuids;
|
||||
}
|
||||
|
||||
|
|
@ -519,6 +534,8 @@ std::vector<std::string> ProfileManager::FindOrphanedProfiles()
|
|||
{
|
||||
std::vector<std::string> good_uuids = FindGoodProfiles();
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
// TODO: fetch save_id programmatically
|
||||
const auto path = Common::FS::GetEdenPath(Common::FS::EdenPath::NANDDir)
|
||||
/ "user/save/0000000000000000";
|
||||
|
|
@ -530,32 +547,47 @@ std::vector<std::string> ProfileManager::FindOrphanedProfiles()
|
|||
[&good_uuids, &orphaned_profiles](const std::filesystem::directory_entry& entry) -> bool {
|
||||
const std::string uuid = entry.path().stem().string();
|
||||
|
||||
bool override = false;
|
||||
|
||||
// first off, we should always clear empty profiles
|
||||
// 99% of the time these are useless. If not, they are recreated anyways...
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
const auto is_empty = [&entry]() -> bool {
|
||||
const auto is_empty = [&entry, &override]() -> bool {
|
||||
try {
|
||||
for (const auto& file : fs::recursive_directory_iterator(entry.path())) {
|
||||
if (file.is_regular_file()) {
|
||||
return true;
|
||||
}
|
||||
// TODO: .yuzu_save_size is a weird file that gets created by certain games
|
||||
// I have no idea what its purpose is, but TEMPORARY SOLUTION: just mark the profile as valid if
|
||||
// this file exists (???) e.g. for SSBU
|
||||
// In short: if .yuzu_save_size is the ONLY file in a profile it's probably fine to keep
|
||||
if (file.path().filename().string() == FileSys::GetSaveDataSizeFileName())
|
||||
override = true;
|
||||
|
||||
// if there are any regular files (NOT directories) there, do NOT delete it :p
|
||||
if (file.is_regular_file())
|
||||
return false;
|
||||
}
|
||||
} catch (const fs::filesystem_error& e) {
|
||||
// if we get an error--no worries, just pretend it's not empty
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}();
|
||||
|
||||
if (!is_empty) {
|
||||
if (is_empty) {
|
||||
fs::remove_all(entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
// edge-case: some filesystems forcefully change filenames to lowercase
|
||||
// so we can just ignore any differences
|
||||
// looking at you microsoft... ;)
|
||||
std::string upper_uuid = uuid;
|
||||
boost::to_upper(upper_uuid);
|
||||
|
||||
// if profiles.dat contains the UUID--all good
|
||||
// if not--it's an orphaned profile and should be resolved by the user
|
||||
if (std::find(good_uuids.begin(), good_uuids.end(), uuid) == good_uuids.end()) {
|
||||
if (!override
|
||||
&& std::find(good_uuids.begin(), good_uuids.end(), upper_uuid) == good_uuids.end()) {
|
||||
orphaned_profiles.emplace_back(uuid);
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ enum class FatalType : u32 {
|
|||
static void GenerateErrorReport(Core::System& system, Result error_code, const FatalInfo& info) {
|
||||
const auto title_id = system.GetApplicationProcessProgramID();
|
||||
std::string crash_report = fmt::format(
|
||||
"Yuzu {}-{} crash report\n"
|
||||
"Eden {}-{} crash report\n"
|
||||
"Title ID: {:016x}\n"
|
||||
"Result: {:#X} ({:04}-{:04d})\n"
|
||||
"Set flags: 0x{:16X}\n"
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
#include <discord_rpc.h>
|
||||
#include <fmt/format.h>
|
||||
#include <qdebug.h>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "common/string_util.h"
|
||||
|
|
@ -88,8 +87,6 @@ void DiscordImpl::UpdateGameStatus(bool use_default) {
|
|||
presence.details = "Currently in game";
|
||||
presence.startTimestamp = start_time;
|
||||
Discord_UpdatePresence(&presence);
|
||||
|
||||
qDebug() << "game status updated";
|
||||
}
|
||||
|
||||
void DiscordImpl::Update() {
|
||||
|
|
|
|||
|
|
@ -340,33 +340,34 @@ void FixProfiles()
|
|||
QString qorphaned;
|
||||
|
||||
// max. of 8 orphaned profiles is fair, I think
|
||||
// 33 = 32 (UUID) + 1 (\n)
|
||||
qorphaned.reserve(8 * 33);
|
||||
// 36 = 32 (UUID) + 4 (<br>)
|
||||
qorphaned.reserve(8 * 36);
|
||||
|
||||
for (const std::string& s : orphaned) {
|
||||
qorphaned = qorphaned % QStringLiteral("\n") % QString::fromStdString(s);
|
||||
qorphaned = qorphaned % QStringLiteral("<br>") % QString::fromStdString(s);
|
||||
}
|
||||
|
||||
QString qgood;
|
||||
|
||||
// max. of 8 good profiles is fair, I think
|
||||
// 33 = 32 (UUID) + 1 (\n)
|
||||
qgood.reserve(8 * 33);
|
||||
// 36 = 32 (UUID) + 4 (<br>)
|
||||
qgood.reserve(8 * 36);
|
||||
|
||||
for (const std::string& s : good) {
|
||||
qgood = qgood % QStringLiteral("\n") % QString::fromStdString(s);
|
||||
qgood = qgood % QStringLiteral("<br>") % QString::fromStdString(s);
|
||||
}
|
||||
|
||||
QtCommon::Frontend::Critical(
|
||||
tr("Orphaned Profiles Detected!"),
|
||||
tr("UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!\n"
|
||||
"Eden has detected the following save directories with no attached profile:\n"
|
||||
"%1\n\n"
|
||||
"The following profiles are valid:\n"
|
||||
"%2\n\n"
|
||||
"Click \"OK\" to open your save folder and fix up your profiles.\n"
|
||||
tr("UNEXPECTED BAD THINGS MAY HAPPEN IF YOU DON'T READ THIS!<br>"
|
||||
"Eden has detected the following save directories with no attached profile:<br>"
|
||||
"%1<br><br>"
|
||||
"The following profiles are valid:<br>"
|
||||
"%2<br><br>"
|
||||
"Click \"OK\" to open your save folder and fix up your profiles.<br>"
|
||||
"Hint: copy the contents of the largest or last-modified folder elsewhere, "
|
||||
"delete all orphaned profiles, and move your copied contents to the good profile.")
|
||||
"delete all orphaned profiles, and move your copied contents to the good profile.<br><br>"
|
||||
"Still confused? See the <a href='https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/user/Orphaned.md'>help page</a>.<br>")
|
||||
.arg(qorphaned, qgood));
|
||||
|
||||
QtCommon::Game::OpenSaveFolder();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue