Path: blob/master/src/duckstation-qt/achievementlogindialog.cpp
7493 views
// SPDX-FileCopyrightText: 2019-2025 Connor McLaughlin <[email protected]>1// SPDX-License-Identifier: CC-BY-NC-ND-4.023#include "achievementlogindialog.h"4#include "qthost.h"56#include "core/achievements.h"7#include "core/core.h"89#include "common/error.h"1011#include "moc_achievementlogindialog.cpp"1213AchievementLoginDialog::AchievementLoginDialog(QWidget* parent, Achievements::LoginRequestReason reason)14: QDialog(parent), m_reason(reason)15{16m_ui.setupUi(this);17m_ui.iconLabel->setPixmap(QPixmap(QtHost::GetResourceQPath("images/ra-icon.webp", true)));18QFont title_font(m_ui.titleLabel->font());19title_font.setBold(true);20title_font.setPixelSize(20);21m_ui.titleLabel->setFont(title_font);22setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);23setAttribute(Qt::WA_DeleteOnClose);2425// Adjust text if needed based on reason.26if (reason == Achievements::LoginRequestReason::TokenInvalid)27{28m_ui.instructionText->setText(tr("<strong>Your RetroAchievements login token is no longer valid.</strong> You must "29"re-enter your credentials for achievements to be tracked. Your password will not "30"be saved in DuckStation, an access token will be generated and used instead."));31}3233m_login = m_ui.buttonBox->addButton(tr("&Login"), QDialogButtonBox::AcceptRole);34m_login->setEnabled(false);35connectUi();36}3738AchievementLoginDialog::~AchievementLoginDialog() = default;3940void AchievementLoginDialog::loginClicked()41{42const QString username(m_ui.userName->text());43const QString password(m_ui.password->text());4445// TODO: Make cancellable.46m_ui.status->setText(tr("Logging in..."));47enableUI(false);4849Host::RunOnCoreThread([this, username, password]() {50Error error;51const bool result = Achievements::Login(username.toUtf8().constData(), password.toUtf8().constData(), &error);52const QString message = QString::fromStdString(error.GetDescription());53QMetaObject::invokeMethod(this, &AchievementLoginDialog::processLoginResult, Qt::QueuedConnection, result, message);54});55}5657void AchievementLoginDialog::cancelClicked()58{59// Disable hardcore mode if we cancelled reauthentication.60if (m_reason == Achievements::LoginRequestReason::TokenInvalid && QtHost::IsSystemValid())61{62Host::RunOnCoreThread([]() {63if (System::IsValid() && !Achievements::HasActiveGame())64Achievements::DisableHardcoreMode(false, false);65});66}6768reject();69}7071void AchievementLoginDialog::processLoginResult(bool result, const QString& message)72{73if (!result)74{75QtUtils::AsyncMessageBox(76this, QMessageBox::Critical, tr("Login Error"),77tr("Login failed.\nError: %1\n\nPlease check your username and password, and try again.").arg(message));78m_ui.status->setText(tr("Login failed."));79enableUI(true);80return;81}8283// don't ask to enable etc if we are just reauthenticating84if (m_reason == Achievements::LoginRequestReason::TokenInvalid)85{86accept();87return;88}8990askToEnableAchievementsAndAccept();91}9293void AchievementLoginDialog::askToEnableAchievementsAndAccept()94{95if (Core::GetBaseBoolSettingValue("Cheevos", "Enabled", false))96{97askToEnableHardcoreModeAndAccept();98return;99}100101QMessageBox* const msgbox =102QtUtils::NewMessageBox(this, QMessageBox::Question, tr("Enable Achievements"),103tr("Achievement tracking is not currently enabled. Your login will have no effect until "104"after tracking is enabled.\n\nDo you want to enable tracking now?"),105QMessageBox::Yes | QMessageBox::No, QMessageBox::NoButton);106msgbox->connect(msgbox, &QMessageBox::accepted, this, [this]() {107Core::SetBaseBoolSettingValue("Cheevos", "Enabled", true);108Host::CommitBaseSettingChanges();109g_core_thread->applySettings();110askToEnableHardcoreModeAndAccept();111});112msgbox->connect(msgbox, &QMessageBox::rejected, this, &AchievementLoginDialog::accept);113msgbox->open();114}115116void AchievementLoginDialog::askToEnableHardcoreModeAndAccept()117{118if (Core::GetBaseBoolSettingValue("Cheevos", "ChallengeMode", false))119{120askToResetGameAndAccept();121return;122}123124QMessageBox* const msgbox = QtUtils::NewMessageBox(125this, QMessageBox::Question, tr("Enable Hardcore Mode"),126tr("Hardcore mode is not currently enabled. Enabling hardcore mode allows you to set times, scores, and "127"participate in game-specific leaderboards.\n\nHowever, hardcore mode also prevents the usage of save "128"states, cheats and slowdown functionality.\n\nDo you want to enable hardcore mode?"),129QMessageBox::Yes | QMessageBox::No, QMessageBox::NoButton);130msgbox->connect(msgbox, &QMessageBox::accepted, this, [this]() {131Core::SetBaseBoolSettingValue("Cheevos", "ChallengeMode", true);132Host::CommitBaseSettingChanges();133g_core_thread->applySettings();134askToResetGameAndAccept();135});136msgbox->connect(msgbox, &QMessageBox::rejected, this, &AchievementLoginDialog::accept);137msgbox->open();138}139140void AchievementLoginDialog::askToResetGameAndAccept()141{142if (!QtHost::IsSystemValid())143{144accept();145return;146}147148QMessageBox* const msgbox = QtUtils::NewMessageBox(149this, QMessageBox::Question, tr("Restart Game"),150tr("Hardcore mode will not be enabled until the game is restarted. Do you want to restart the game now?"),151QMessageBox::Yes | QMessageBox::No, QMessageBox::NoButton);152msgbox->connect(msgbox, &QMessageBox::accepted, this, [this]() {153g_core_thread->resetSystem(true);154accept();155});156msgbox->connect(msgbox, &QMessageBox::rejected, this, &AchievementLoginDialog::accept);157msgbox->open();158}159160void AchievementLoginDialog::connectUi()161{162connect(m_ui.buttonBox, &QDialogButtonBox::accepted, this, &AchievementLoginDialog::loginClicked);163connect(m_ui.buttonBox, &QDialogButtonBox::rejected, this, &AchievementLoginDialog::cancelClicked);164165auto enableLoginButton = [this](const QString&) { m_login->setEnabled(canEnableLoginButton()); };166connect(m_ui.userName, &QLineEdit::textChanged, enableLoginButton);167connect(m_ui.password, &QLineEdit::textChanged, enableLoginButton);168}169170void AchievementLoginDialog::enableUI(bool enabled)171{172m_ui.userName->setEnabled(enabled);173m_ui.password->setEnabled(enabled);174m_ui.buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(enabled);175m_login->setEnabled(enabled && canEnableLoginButton());176}177178bool AchievementLoginDialog::canEnableLoginButton() const179{180return !m_ui.userName->text().isEmpty() && !m_ui.password->text().isEmpty();181}182183184