From 4a1d9d31d0fa632b9f98317e69727f14e9d00a88 Mon Sep 17 00:00:00 2001 From: RedPanda4552 Date: Sun, 3 Aug 2025 17:24:01 -0400 Subject: [PATCH] Achievements: Store token to separate ini --- pcsx2-qt/QtHost.cpp | 25 +++++++++++++++++++++++++ pcsx2/Achievements.cpp | 32 +++++++++++++++++++++++++++++--- pcsx2/Host.cpp | 20 +++++++++++++++++++- pcsx2/Host.h | 8 ++++++++ pcsx2/LayeredSettingsInterface.h | 1 + 5 files changed, 82 insertions(+), 4 deletions(-) diff --git a/pcsx2-qt/QtHost.cpp b/pcsx2-qt/QtHost.cpp index 902c400597..909d1c8701 100644 --- a/pcsx2-qt/QtHost.cpp +++ b/pcsx2-qt/QtHost.cpp @@ -86,6 +86,7 @@ namespace QtHost ////////////////////////////////////////////////////////////////////////// static QTimer* s_settings_save_timer = nullptr; static std::unique_ptr s_base_settings_interface; +static std::unique_ptr s_secrets_settings_interface; static bool s_batch_mode = false; static bool s_nogui_mode = false; static bool s_start_big_picture_mode = false; @@ -1307,6 +1308,7 @@ bool QtHost::InitializeConfig() // Write crash dumps to the data directory, since that'll be accessible for certain. CrashHandler::SetWriteDirectory(EmuFolders::DataRoot); + // Load main settings ini const std::string path = Path::Combine(EmuFolders::Settings, "PCSX2.ini"); const bool settings_exists = FileSystem::FileExists(path.c_str()); Console.WriteLnFmt("Loading config from {}.", path); @@ -1347,6 +1349,29 @@ bool QtHost::InitializeConfig() SaveSettings(); } + // Layer secrets ini on top + const std::string secrets_path = Path::Combine(EmuFolders::Settings, "secrets.ini"); + const bool secrets_settings_exists = FileSystem::FileExists(secrets_path.c_str()); + Console.WriteLnFmt("Loading secrets from {}.", secrets_path); + + s_secrets_settings_interface = std::make_unique(std::move(secrets_path)); + Host::Internal::SetSecretsSettingsLayer(s_secrets_settings_interface.get()); + if (!secrets_settings_exists || !s_secrets_settings_interface->Load()) + { + if (!s_base_settings_interface->Save(&error)) + { + QMessageBox::critical( + nullptr, QStringLiteral("PCSX2"), + QStringLiteral( + "Failed to save secrets to\n\n%1\n\nThe error was: %2\n\nPlease ensure this directory is writable. You " + "can also try portable mode by creating portable.txt in the same directory you installed PCSX2 into.") + .arg(QString::fromStdString(s_secrets_settings_interface->GetFileName())) + .arg(QString::fromStdString(error.GetDescription()))); + return false; + } + + } + // Setup wizard was incomplete last time? s_run_setup_wizard = s_run_setup_wizard || s_base_settings_interface->GetBoolValue("UI", "SetupWizardIncomplete", false); diff --git a/pcsx2/Achievements.cpp b/pcsx2/Achievements.cpp index 49196ef36b..0ba5a1642a 100644 --- a/pcsx2/Achievements.cpp +++ b/pcsx2/Achievements.cpp @@ -26,6 +26,7 @@ #include "common/MD5Digest.h" #include "common/Path.h" #include "common/ScopedGuard.h" +#include "common/SettingsInterface.h" #include "common/SmallString.h" #include "common/StringUtil.h" #include "common/Timer.h" @@ -439,7 +440,25 @@ bool Achievements::Initialize() IdentifyGame(VMManager::GetDiscCRC(), VMManager::GetCurrentCRC()); const std::string username = Host::GetBaseStringSettingValue("Achievements", "Username"); - const std::string api_token = Host::GetBaseStringSettingValue("Achievements", "Token"); + + // Check the base settings file to see if the token is defined inside. Move if found. + std::string oldToken = Host::GetBaseStringSettingValue("Achievements", "Token"); + if (!oldToken.empty()) + { + auto secretsLock = Host::GetSecretsSettingsLock(); + SettingsInterface* secretsInterface = Host::Internal::GetSecretsSettingsLayer(); + secretsInterface->SetStringValue("Achievements", "Token", oldToken.c_str()); + secretsInterface->Save(); + + oldToken.clear(); + + auto baseLock = Host::GetSettingsLock(); + SettingsInterface* baseInterface = Host::Internal::GetBaseSettingsLayer(); + baseInterface->DeleteValue("Achievements", "Token"); + baseInterface->Save(); + } + + const std::string api_token = Host::GetStringSettingValue("Achievements", "Token"); if (!username.empty() && !api_token.empty()) { Console.WriteLn("Achievements: Attempting login with user '%s'...", username.c_str()); @@ -1785,9 +1804,12 @@ void Achievements::ClientLoginWithPasswordCallback(int result, const char* error // Store configuration. Host::SetBaseStringSettingValue("Achievements", "Username", params->username); - Host::SetBaseStringSettingValue("Achievements", "Token", user->token); Host::SetBaseStringSettingValue("Achievements", "LoginTimestamp", fmt::format("{}", std::time(nullptr)).c_str()); Host::CommitBaseSettingChanges(); + + SettingsInterface* secretsInterface = Host::Internal::GetSecretsSettingsLayer(); + secretsInterface->SetStringValue("Achievements", "Token", user->token); + secretsInterface->Save(); ShowLoginSuccess(client); } @@ -1887,9 +1909,13 @@ void Achievements::Logout() Console.WriteLn("Achievements: Clearing credentials..."); Host::RemoveBaseSettingValue("Achievements", "Username"); - Host::RemoveBaseSettingValue("Achievements", "Token"); Host::RemoveBaseSettingValue("Achievements", "LoginTimestamp"); Host::CommitBaseSettingChanges(); + + auto secretsLock = Host::GetSecretsSettingsLock(); + SettingsInterface* secretsInterface = Host::Internal::GetSecretsSettingsLayer(); + secretsInterface->DeleteValue("Achievements", "Token"); + secretsInterface->Save(); } diff --git a/pcsx2/Host.cpp b/pcsx2/Host.cpp index a089b3f120..575d4782c9 100644 --- a/pcsx2/Host.cpp +++ b/pcsx2/Host.cpp @@ -26,6 +26,7 @@ namespace Host const std::string_view context, const std::string_view msg); static std::mutex s_settings_mutex; + static std::mutex s_secrets_settings_mutex; static LayeredSettingsInterface s_layered_settings_interface; static constexpr u32 TRANSLATION_STRING_CACHE_SIZE = 4 * 1024 * 1024; @@ -164,6 +165,11 @@ std::unique_lock Host::GetSettingsLock() return std::unique_lock(s_settings_mutex); } +std::unique_lock Host::GetSecretsSettingsLock() +{ + return std::unique_lock(s_secrets_settings_mutex); +} + SettingsInterface* Host::GetSettingsInterface() { return &s_layered_settings_interface; @@ -352,6 +358,11 @@ SettingsInterface* Host::Internal::GetBaseSettingsLayer() return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE); } +SettingsInterface* Host::Internal::GetSecretsSettingsLayer() +{ + return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_SECRETS); +} + SettingsInterface* Host::Internal::GetGameSettingsLayer() { return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_GAME); @@ -365,10 +376,17 @@ SettingsInterface* Host::Internal::GetInputSettingsLayer() void Host::Internal::SetBaseSettingsLayer(SettingsInterface* sif) { pxAssertRel(s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE) == nullptr, - "Base layer has not been set"); + "Base layer has already been set"); s_layered_settings_interface.SetLayer(LayeredSettingsInterface::LAYER_BASE, sif); } +void Host::Internal::SetSecretsSettingsLayer(SettingsInterface* sif) +{ + pxAssertRel(s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_SECRETS) == nullptr, + "Secrets layer has already been set"); + s_layered_settings_interface.SetLayer(LayeredSettingsInterface::LAYER_SECRETS, sif); +} + void Host::Internal::SetGameSettingsLayer(SettingsInterface* sif, std::unique_lock& settings_lock) { s_layered_settings_interface.SetLayer(LayeredSettingsInterface::LAYER_GAME, sif); diff --git a/pcsx2/Host.h b/pcsx2/Host.h index 50023cc9d4..b82c5ba956 100644 --- a/pcsx2/Host.h +++ b/pcsx2/Host.h @@ -134,6 +134,8 @@ namespace Host /// Direct access to settings interface. Must hold the lock when calling GetSettingsInterface() and while using it. std::unique_lock GetSettingsLock(); + /// Ditto for secrets file. + std::unique_lock GetSecretsSettingsLock(); SettingsInterface* GetSettingsInterface(); /// Sets host-specific default settings. @@ -147,6 +149,9 @@ namespace Host /// Retrieves the base settings layer. Must call with lock held. SettingsInterface* GetBaseSettingsLayer(); + /// Retrieves the base settings layer. Must call with lock held. + SettingsInterface* GetSecretsSettingsLayer(); + /// Retrieves the game settings layer, if present. Must call with lock held. SettingsInterface* GetGameSettingsLayer(); @@ -156,6 +161,9 @@ namespace Host /// Sets the base settings layer. Should be called by the host at initialization time. void SetBaseSettingsLayer(SettingsInterface* sif); + /// Sets the secrets settings layer. Should follow call to SetBaseSettingsLayer. + void SetSecretsSettingsLayer(SettingsInterface* sif); + /// Sets the game settings layer. Called by VMManager when the game changes. void SetGameSettingsLayer(SettingsInterface* sif, std::unique_lock& settings_lock); diff --git a/pcsx2/LayeredSettingsInterface.h b/pcsx2/LayeredSettingsInterface.h index a89b94781f..ae069cf089 100644 --- a/pcsx2/LayeredSettingsInterface.h +++ b/pcsx2/LayeredSettingsInterface.h @@ -15,6 +15,7 @@ public: LAYER_CMDLINE, LAYER_GAME, LAYER_INPUT, + LAYER_SECRETS, LAYER_BASE, NUM_LAYERS };