From e4a017fc00ceb473e803aec4db53079f700adc07 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 27 Jul 2023 19:24:55 +1000 Subject: [PATCH] Qt: Add callback for forcing achievements re-login --- pcsx2-gsrunner/Main.cpp | 7 +++++-- pcsx2-qt/MainWindow.cpp | 10 ++++++++++ pcsx2-qt/MainWindow.h | 7 +++++++ pcsx2-qt/QtHost.cpp | 6 ++++++ pcsx2-qt/QtHost.h | 9 +++++++++ pcsx2-qt/Settings/AchievementLoginDialog.cpp | 11 ++++++++++- pcsx2-qt/Settings/AchievementLoginDialog.h | 8 +++++++- pcsx2-qt/Settings/AchievementLoginDialog.ui | 2 +- pcsx2-qt/Settings/AchievementSettingsWidget.cpp | 2 +- pcsx2/Achievements.cpp | 4 +++- pcsx2/Achievements.h | 8 +++++++- tests/ctest/core/StubHost.cpp | 6 ++++-- 12 files changed, 70 insertions(+), 10 deletions(-) diff --git a/pcsx2-gsrunner/Main.cpp b/pcsx2-gsrunner/Main.cpp index 714a95455e..b1b9a218cd 100644 --- a/pcsx2-gsrunner/Main.cpp +++ b/pcsx2-gsrunner/Main.cpp @@ -385,12 +385,15 @@ void Host::RequestVMShutdown(bool allow_confirm, bool allow_save_state, bool def VMManager::SetState(VMState::Stopping); } -#ifdef ENABLE_ACHIEVEMENTS +void Host::OnAchievementsLoginRequested(Achievements::LoginRequestReason reason) +{ + // noop +} + void Host::OnAchievementsRefreshed() { // noop } -#endif std::optional InputManager::ConvertHostKeyboardStringToCode(const std::string_view& str) { diff --git a/pcsx2-qt/MainWindow.cpp b/pcsx2-qt/MainWindow.cpp index 7ec1b75a4f..4e7e75d052 100644 --- a/pcsx2-qt/MainWindow.cpp +++ b/pcsx2-qt/MainWindow.cpp @@ -25,6 +25,7 @@ #include "QtHost.h" #include "QtUtils.h" #include "SettingWidgetBinder.h" +#include "Settings/AchievementLoginDialog.h" #include "Settings/ControllerSettingsDialog.h" #include "Settings/GameListSettingsWidget.h" #include "Settings/InterfaceSettingsWidget.h" @@ -423,6 +424,7 @@ void MainWindow::connectVMThreadSignals(EmuThread* thread) connect(thread, &EmuThread::onGameChanged, this, &MainWindow::onGameChanged); connect(thread, &EmuThread::onCaptureStarted, this, &MainWindow::onCaptureStarted); connect(thread, &EmuThread::onCaptureStopped, this, &MainWindow::onCaptureStopped); + connect(thread, &EmuThread::onAchievementsLoginRequested, this, &MainWindow::onAchievementsLoginRequested); connect(m_ui.actionReset, &QAction::triggered, thread, &EmuThread::resetVM); connect(m_ui.actionPause, &QAction::toggled, thread, &EmuThread::setVMPaused); @@ -628,6 +630,14 @@ void MainWindow::onCaptureStopped() m_ui.actionToolsVideoCapture->setChecked(false); } +void MainWindow::onAchievementsLoginRequested(Achievements::LoginRequestReason reason) +{ + auto lock = pauseAndLockVM(); + + AchievementLoginDialog dlg(this, reason); + dlg.exec(); +} + void MainWindow::onSettingsTriggeredFromToolbar() { if (s_vm_valid) diff --git a/pcsx2-qt/MainWindow.h b/pcsx2-qt/MainWindow.h index acf402adfc..d7350fc573 100644 --- a/pcsx2-qt/MainWindow.h +++ b/pcsx2-qt/MainWindow.h @@ -39,6 +39,11 @@ class ControllerSettingsDialog; class EmuThread; +namespace Achievements +{ + enum class LoginRequestReason; +} + namespace GameList { struct Entry; @@ -186,6 +191,8 @@ private Q_SLOTS: void onCaptureStarted(const QString& filename); void onCaptureStopped(); + void onAchievementsLoginRequested(Achievements::LoginRequestReason reason); + protected: void showEvent(QShowEvent* event) override; void closeEvent(QCloseEvent* event) override; diff --git a/pcsx2-qt/QtHost.cpp b/pcsx2-qt/QtHost.cpp index 92ed1b81f2..35941d0486 100644 --- a/pcsx2-qt/QtHost.cpp +++ b/pcsx2-qt/QtHost.cpp @@ -1079,6 +1079,11 @@ void Host::OnSaveStateSaved(const std::string_view& filename) } #ifdef ENABLE_ACHIEVEMENTS +void Host::OnAchievementsLoginRequested(Achievements::LoginRequestReason reason) +{ + emit g_emu_thread->onAchievementsLoginRequested(reason); +} + void Host::OnAchievementsRefreshed() { u32 game_id = 0; @@ -1778,6 +1783,7 @@ void QtHost::RegisterTypes() qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); + qRegisterMetaType(); } bool QtHost::RunSetupWizard() diff --git a/pcsx2-qt/QtHost.h b/pcsx2-qt/QtHost.h index 2b2477fe51..af983faaa4 100644 --- a/pcsx2-qt/QtHost.h +++ b/pcsx2-qt/QtHost.h @@ -41,11 +41,17 @@ struct VMBootParameters; enum class CDVD_SourceType : uint8_t; +namespace Achievements +{ + enum class LoginRequestReason; +} + Q_DECLARE_METATYPE(std::shared_ptr); Q_DECLARE_METATYPE(std::optional); Q_DECLARE_METATYPE(GSRendererType); Q_DECLARE_METATYPE(InputBindingKey); Q_DECLARE_METATYPE(CDVD_SourceType); +Q_DECLARE_METATYPE(Achievements::LoginRequestReason); class EmuThread : public QThread { @@ -155,6 +161,9 @@ Q_SIGNALS: /// just signifies that the save has started, not necessarily completed. void onSaveStateSaved(const QString& path); + /// Called when achievements login is requested. + void onAchievementsLoginRequested(Achievements::LoginRequestReason reason); + /// Called when achievements are reloaded/refreshed (e.g. game change, login, option change). void onAchievementsRefreshed(quint32 id, const QString& game_info_string, quint32 total, quint32 points); diff --git a/pcsx2-qt/Settings/AchievementLoginDialog.cpp b/pcsx2-qt/Settings/AchievementLoginDialog.cpp index 85d387bd03..31542153be 100644 --- a/pcsx2-qt/Settings/AchievementLoginDialog.cpp +++ b/pcsx2-qt/Settings/AchievementLoginDialog.cpp @@ -22,13 +22,22 @@ #include -AchievementLoginDialog::AchievementLoginDialog(QWidget* parent) +AchievementLoginDialog::AchievementLoginDialog(QWidget* parent, Achievements::LoginRequestReason reason) : QDialog(parent) { m_ui.setupUi(this); m_ui.loginIcon->setPixmap(QIcon::fromTheme("login-box-line").pixmap(32)); setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + // Adjust text if needed based on reason. + if (reason == Achievements::LoginRequestReason::TokenInvalid) + { + m_ui.instructionText->setText( + tr("Your RetroAchievements login token is no longer valid. You must re-enter your " + "credentials for achievements to be tracked. Your password will not be saved in PCSX2, an access token " + "will be generated and used instead.")); + } + m_login = m_ui.buttonBox->addButton(tr("&Login"), QDialogButtonBox::AcceptRole); m_login->setEnabled(false); connectUi(); diff --git a/pcsx2-qt/Settings/AchievementLoginDialog.h b/pcsx2-qt/Settings/AchievementLoginDialog.h index 835e057eb8..ce7a512c9b 100644 --- a/pcsx2-qt/Settings/AchievementLoginDialog.h +++ b/pcsx2-qt/Settings/AchievementLoginDialog.h @@ -18,12 +18,17 @@ #include #include +namespace Achievements +{ + enum class LoginRequestReason; +} + class AchievementLoginDialog : public QDialog { Q_OBJECT public: - AchievementLoginDialog(QWidget* parent); + AchievementLoginDialog(QWidget* parent, Achievements::LoginRequestReason reason); ~AchievementLoginDialog(); private Q_SLOTS: @@ -38,4 +43,5 @@ private: Ui::AchievementLoginDialog m_ui; QPushButton* m_login; + Achievements::LoginRequestReason m_reason; }; diff --git a/pcsx2-qt/Settings/AchievementLoginDialog.ui b/pcsx2-qt/Settings/AchievementLoginDialog.ui index 5a230a3d8a..ea0b77f46b 100644 --- a/pcsx2-qt/Settings/AchievementLoginDialog.ui +++ b/pcsx2-qt/Settings/AchievementLoginDialog.ui @@ -51,7 +51,7 @@ - + Please enter user name and password for retroachievements.org below. Your password will not be saved in PCSX2, an access token will be generated and used instead. diff --git a/pcsx2-qt/Settings/AchievementSettingsWidget.cpp b/pcsx2-qt/Settings/AchievementSettingsWidget.cpp index 6e38adb868..db1b09fab1 100644 --- a/pcsx2-qt/Settings/AchievementSettingsWidget.cpp +++ b/pcsx2-qt/Settings/AchievementSettingsWidget.cpp @@ -173,7 +173,7 @@ void AchievementSettingsWidget::onLoginLogoutPressed() return; } - AchievementLoginDialog login(this); + AchievementLoginDialog login(this, Achievements::LoginRequestReason::UserInitiated); int res = login.exec(); if (res != 0) return; diff --git a/pcsx2/Achievements.cpp b/pcsx2/Achievements.cpp index 48a6d85bd7..b0715f5e1a 100644 --- a/pcsx2/Achievements.cpp +++ b/pcsx2/Achievements.cpp @@ -966,7 +966,9 @@ void Achievements::LoginWithTokenCallback(s32 status_code, const std::string& co RAPIResponse response(status_code, data); if (!response) { - FormattedError("Login failed. Please check your user name and password, and try again."); + lock.unlock(); + Logout(); + Host::OnAchievementsLoginRequested(LoginRequestReason::TokenInvalid); return; } diff --git a/pcsx2/Achievements.h b/pcsx2/Achievements.h index c404e63338..27509b57c2 100644 --- a/pcsx2/Achievements.h +++ b/pcsx2/Achievements.h @@ -31,6 +31,12 @@ namespace Achievements { + enum class LoginRequestReason + { + UserInitiated, + TokenInvalid, + }; + enum class AchievementCategory : u8 { Local = 0, @@ -255,6 +261,6 @@ namespace Achievements /// Functions implemented in the frontend. namespace Host { + void OnAchievementsLoginRequested(Achievements::LoginRequestReason reason); void OnAchievementsRefreshed(); - void OnAchievementsChallengeModeChanged(); } // namespace Host diff --git a/tests/ctest/core/StubHost.cpp b/tests/ctest/core/StubHost.cpp index e8434e215e..5cec26e89d 100644 --- a/tests/ctest/core/StubHost.cpp +++ b/tests/ctest/core/StubHost.cpp @@ -210,11 +210,13 @@ s32 Host::Internal::GetTranslatedStringImpl( return static_cast(msg.size()); } -#ifdef ENABLE_ACHIEVEMENTS +void Host::OnAchievementsLoginRequested(Achievements::LoginRequestReason reason) +{ +} + void Host::OnAchievementsRefreshed() { } -#endif std::optional InputManager::ConvertHostKeyboardStringToCode(const std::string_view& str) {