Path: blob/master/src/duckstation-qt/achievementlogindialog.cpp
6247 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"78#include "common/error.h"910#include "moc_achievementlogindialog.cpp"1112AchievementLoginDialog::AchievementLoginDialog(QWidget* parent, Achievements::LoginRequestReason reason)13: QDialog(parent), m_reason(reason)14{15m_ui.setupUi(this);16m_ui.iconLabel->setPixmap(QPixmap(QtHost::GetResourceQPath("images/ra-icon.webp", true)));17QFont title_font(m_ui.titleLabel->font());18title_font.setBold(true);19title_font.setPixelSize(20);20m_ui.titleLabel->setFont(title_font);21setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);22setAttribute(Qt::WA_DeleteOnClose);2324// Adjust text if needed based on reason.25if (reason == Achievements::LoginRequestReason::TokenInvalid)26{27m_ui.instructionText->setText(tr("<strong>Your RetroAchievements login token is no longer valid.</strong> You must "28"re-enter your credentials for achievements to be tracked. Your password will not "29"be saved in DuckStation, an access token will be generated and used instead."));30}3132m_login = m_ui.buttonBox->addButton(tr("&Login"), QDialogButtonBox::AcceptRole);33m_login->setEnabled(false);34connectUi();35}3637AchievementLoginDialog::~AchievementLoginDialog() = default;3839void AchievementLoginDialog::loginClicked()40{41const QString username(m_ui.userName->text());42const QString password(m_ui.password->text());4344// TODO: Make cancellable.45m_ui.status->setText(tr("Logging in..."));46enableUI(false);4748Host::RunOnCPUThread([this, username, password]() {49Error error;50const bool result = Achievements::Login(username.toUtf8().constData(), password.toUtf8().constData(), &error);51const QString message = QString::fromStdString(error.GetDescription());52QMetaObject::invokeMethod(this, &AchievementLoginDialog::processLoginResult, Qt::QueuedConnection, result, message);53});54}5556void AchievementLoginDialog::cancelClicked()57{58// Disable hardcore mode if we cancelled reauthentication.59if (m_reason == Achievements::LoginRequestReason::TokenInvalid && QtHost::IsSystemValid())60{61Host::RunOnCPUThread([]() {62if (System::IsValid() && !Achievements::HasActiveGame())63Achievements::DisableHardcoreMode(false, false);64});65}6667reject();68}6970void AchievementLoginDialog::processLoginResult(bool result, const QString& message)71{72if (!result)73{74QtUtils::AsyncMessageBox(75this, QMessageBox::Critical, tr("Login Error"),76tr("Login failed.\nError: %1\n\nPlease check your username and password, and try again.").arg(message));77m_ui.status->setText(tr("Login failed."));78enableUI(true);79return;80}8182// don't ask to enable etc if we are just reauthenticating83if (m_reason == Achievements::LoginRequestReason::TokenInvalid)84{85accept();86return;87}8889askToEnableAchievementsAndAccept();90}9192void AchievementLoginDialog::askToEnableAchievementsAndAccept()93{94if (Host::GetBaseBoolSettingValue("Cheevos", "Enabled", false))95{96askToEnableHardcoreModeAndAccept();97return;98}99100QMessageBox* const msgbox =101QtUtils::NewMessageBox(this, QMessageBox::Question, tr("Enable Achievements"),102tr("Achievement tracking is not currently enabled. Your login will have no effect until "103"after tracking is enabled.\n\nDo you want to enable tracking now?"),104QMessageBox::Yes | QMessageBox::No, QMessageBox::NoButton);105msgbox->connect(msgbox, &QMessageBox::accepted, this, [this]() {106Host::SetBaseBoolSettingValue("Cheevos", "Enabled", true);107Host::CommitBaseSettingChanges();108g_emu_thread->applySettings();109askToEnableHardcoreModeAndAccept();110});111msgbox->connect(msgbox, &QMessageBox::rejected, this, &AchievementLoginDialog::accept);112msgbox->open();113}114115void AchievementLoginDialog::askToEnableHardcoreModeAndAccept()116{117if (Host::GetBaseBoolSettingValue("Cheevos", "ChallengeMode", false))118{119askToResetGameAndAccept();120return;121}122123QMessageBox* const msgbox = QtUtils::NewMessageBox(124this, QMessageBox::Question, tr("Enable Hardcore Mode"),125tr("Hardcore mode is not currently enabled. Enabling hardcore mode allows you to set times, scores, and "126"participate in game-specific leaderboards.\n\nHowever, hardcore mode also prevents the usage of save "127"states, cheats and slowdown functionality.\n\nDo you want to enable hardcore mode?"),128QMessageBox::Yes | QMessageBox::No, QMessageBox::NoButton);129msgbox->connect(msgbox, &QMessageBox::accepted, this, [this]() {130Host::SetBaseBoolSettingValue("Cheevos", "ChallengeMode", true);131Host::CommitBaseSettingChanges();132g_emu_thread->applySettings();133askToResetGameAndAccept();134});135msgbox->connect(msgbox, &QMessageBox::rejected, this, &AchievementLoginDialog::accept);136msgbox->open();137}138139void AchievementLoginDialog::askToResetGameAndAccept()140{141if (!QtHost::IsSystemValid())142{143accept();144return;145}146147QMessageBox* const msgbox = QtUtils::NewMessageBox(148this, QMessageBox::Question, tr("Reset System"),149tr("Hardcore mode will not be enabled until the system is reset. Do you want to reset the system now?"),150QMessageBox::Yes | QMessageBox::No, QMessageBox::NoButton);151msgbox->connect(msgbox, &QMessageBox::accepted, this, [this]() {152g_emu_thread->resetSystem(true);153accept();154});155msgbox->connect(msgbox, &QMessageBox::rejected, this, &AchievementLoginDialog::accept);156msgbox->open();157}158159void AchievementLoginDialog::connectUi()160{161connect(m_ui.buttonBox, &QDialogButtonBox::accepted, this, &AchievementLoginDialog::loginClicked);162connect(m_ui.buttonBox, &QDialogButtonBox::rejected, this, &AchievementLoginDialog::cancelClicked);163164auto enableLoginButton = [this](const QString&) { m_login->setEnabled(canEnableLoginButton()); };165connect(m_ui.userName, &QLineEdit::textChanged, enableLoginButton);166connect(m_ui.password, &QLineEdit::textChanged, enableLoginButton);167}168169void AchievementLoginDialog::enableUI(bool enabled)170{171m_ui.userName->setEnabled(enabled);172m_ui.password->setEnabled(enabled);173m_ui.buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(enabled);174m_login->setEnabled(enabled && canEnableLoginButton());175}176177bool AchievementLoginDialog::canEnableLoginButton() const178{179return !m_ui.userName->text().isEmpty() && !m_ui.password->text().isEmpty();180}181182183