duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

achievementlogindialog.cpp (5223B)


      1 // SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
      2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
      3 
      4 #include "achievementlogindialog.h"
      5 #include "qthost.h"
      6 
      7 #include "core/achievements.h"
      8 
      9 #include "common/error.h"
     10 
     11 #include <QtWidgets/QMessageBox>
     12 
     13 AchievementLoginDialog::AchievementLoginDialog(QWidget* parent, Achievements::LoginRequestReason reason)
     14   : QDialog(parent), m_reason(reason)
     15 {
     16   m_ui.setupUi(this);
     17   setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
     18 
     19   // Adjust text if needed based on reason.
     20   if (reason == Achievements::LoginRequestReason::TokenInvalid)
     21   {
     22     m_ui.instructionText->setText(tr("<strong>Your RetroAchievements login token is no longer valid.</strong> You must "
     23                                      "re-enter your credentials for achievements to be tracked. Your password will not "
     24                                      "be saved in DuckStation, an access token will be generated and used instead."));
     25   }
     26 
     27   m_login = m_ui.buttonBox->addButton(tr("&Login"), QDialogButtonBox::AcceptRole);
     28   m_login->setEnabled(false);
     29   connectUi();
     30 }
     31 
     32 AchievementLoginDialog::~AchievementLoginDialog() = default;
     33 
     34 void AchievementLoginDialog::loginClicked()
     35 {
     36   const QString username(m_ui.userName->text());
     37   const QString password(m_ui.password->text());
     38 
     39   // TODO: Make cancellable.
     40   m_ui.status->setText(tr("Logging in..."));
     41   enableUI(false);
     42 
     43   Host::RunOnCPUThread([this, username, password]() {
     44     Error error;
     45     const bool result = Achievements::Login(username.toUtf8().constData(), password.toUtf8().constData(), &error);
     46     const QString message = QString::fromStdString(error.GetDescription());
     47     QMetaObject::invokeMethod(this, "processLoginResult", Qt::QueuedConnection, Q_ARG(bool, result),
     48                               Q_ARG(const QString&, message));
     49   });
     50 }
     51 
     52 void AchievementLoginDialog::cancelClicked()
     53 {
     54   // Disable hardcore mode if we cancelled reauthentication.
     55   if (m_reason == Achievements::LoginRequestReason::TokenInvalid && QtHost::IsSystemValid())
     56   {
     57     Host::RunOnCPUThread([]() {
     58       if (System::IsValid() && !Achievements::HasActiveGame())
     59         Achievements::DisableHardcoreMode();
     60     });
     61   }
     62 
     63   done(1);
     64 }
     65 
     66 void AchievementLoginDialog::processLoginResult(bool result, const QString& message)
     67 {
     68   if (!result)
     69   {
     70     QMessageBox::critical(
     71       this, tr("Login Error"),
     72       tr("Login failed.\nError: %1\n\nPlease check your username and password, and try again.").arg(message));
     73     m_ui.status->setText(tr("Login failed."));
     74     enableUI(true);
     75     return;
     76   }
     77 
     78   if (!Host::GetBaseBoolSettingValue("Cheevos", "Enabled", false) &&
     79       QMessageBox::question(this, tr("Enable Achievements"),
     80                             tr("Achievement tracking is not currently enabled. Your login will have no effect until "
     81                                "after tracking is enabled.\n\nDo you want to enable tracking now?"),
     82                             QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
     83   {
     84     Host::SetBaseBoolSettingValue("Cheevos", "Enabled", true);
     85     Host::CommitBaseSettingChanges();
     86     g_emu_thread->applySettings();
     87   }
     88 
     89   if (!Host::GetBaseBoolSettingValue("Cheevos", "ChallengeMode", false) &&
     90       QMessageBox::question(
     91         this, tr("Enable Hardcore Mode"),
     92         tr("Hardcore mode is not currently enabled. Enabling hardcore mode allows you to set times, scores, and "
     93            "participate in game-specific leaderboards.\n\nHowever, hardcore mode also prevents the usage of save "
     94            "states, cheats and slowdown functionality.\n\nDo you want to enable hardcore mode?"),
     95         QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes)
     96   {
     97     Host::SetBaseBoolSettingValue("Cheevos", "ChallengeMode", true);
     98     Host::CommitBaseSettingChanges();
     99     g_emu_thread->applySettings();
    100 
    101     bool has_active_game;
    102     {
    103       auto lock = Achievements::GetLock();
    104       has_active_game = Achievements::HasActiveGame();
    105     }
    106 
    107     if (has_active_game &&
    108         QMessageBox::question(
    109           QtUtils::GetRootWidget(this), tr("Reset System"),
    110           tr("Hardcore mode will not be enabled until the system is reset. Do you want to reset the system now?")) ==
    111           QMessageBox::Yes)
    112     {
    113       g_emu_thread->resetSystem(true);
    114     }
    115   }
    116 
    117   done(0);
    118 }
    119 
    120 void AchievementLoginDialog::connectUi()
    121 {
    122   connect(m_ui.buttonBox, &QDialogButtonBox::accepted, this, &AchievementLoginDialog::loginClicked);
    123   connect(m_ui.buttonBox, &QDialogButtonBox::rejected, this, &AchievementLoginDialog::cancelClicked);
    124 
    125   auto enableLoginButton = [this](const QString&) { m_login->setEnabled(canEnableLoginButton()); };
    126   connect(m_ui.userName, &QLineEdit::textChanged, enableLoginButton);
    127   connect(m_ui.password, &QLineEdit::textChanged, enableLoginButton);
    128 }
    129 
    130 void AchievementLoginDialog::enableUI(bool enabled)
    131 {
    132   m_ui.userName->setEnabled(enabled);
    133   m_ui.password->setEnabled(enabled);
    134   m_ui.buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(enabled);
    135   m_login->setEnabled(enabled && canEnableLoginButton());
    136 }
    137 
    138 bool AchievementLoginDialog::canEnableLoginButton() const
    139 {
    140   return !m_ui.userName->text().isEmpty() && !m_ui.password->text().isEmpty();
    141 }