From a026fabd20b0fa56ced59c93c404cc305d126702 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Tue, 17 Dec 2024 03:40:09 +0100 Subject: [PATCH] GH-5166 refine offline account handling on launch to allow going online Added a button to the offline name selection dialog that allows switching the intent from offline launch to online launch. This lets you launch online with a currently offline account when you regain network connectivity. --- launcher/CMakeLists.txt | 2 + launcher/LaunchController.cpp | 48 +++++++------- launcher/LaunchController.h | 4 +- launcher/minecraft/auth/AccountList.cpp | 4 +- launcher/ui/dialogs/MSALoginDialog.cpp | 5 +- launcher/ui/dialogs/MSALoginDialog.h | 2 +- launcher/ui/dialogs/OfflineNameDialog.cpp | 66 ++++++++++++++++++++ launcher/ui/dialogs/OfflineNameDialog.h | 40 ++++++++++++ launcher/ui/pages/global/AccountListPage.cpp | 6 +- 9 files changed, 139 insertions(+), 38 deletions(-) create mode 100644 launcher/ui/dialogs/OfflineNameDialog.cpp create mode 100644 launcher/ui/dialogs/OfflineNameDialog.h diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 6aa8dc13..cb929bd4 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -768,6 +768,8 @@ SET(LAUNCHER_SOURCES ui/dialogs/NewInstanceDialog.h ui/dialogs/NotificationDialog.cpp ui/dialogs/NotificationDialog.h + ui/dialogs/OfflineNameDialog.cpp + ui/dialogs/OfflineNameDialog.h ui/pagedialog/PageDialog.cpp ui/pagedialog/PageDialog.h ui/dialogs/ProgressDialog.cpp diff --git a/launcher/LaunchController.cpp b/launcher/LaunchController.cpp index e813163e..5420c3ad 100644 --- a/launcher/LaunchController.cpp +++ b/launcher/LaunchController.cpp @@ -11,6 +11,7 @@ #include "ui/dialogs/EditAccountDialog.h" #include "ui/dialogs/ProfileSetupDialog.h" #include "ui/dialogs/MSALoginDialog.h" +#include "ui/dialogs/OfflineNameDialog.h" #include #include @@ -107,20 +108,14 @@ void LaunchController::login() { return; } - // we try empty password first :) - QString password; // we loop until the user succeeds in logging in or gives up bool tryagain = true; - // the failure. the default failure. - const QString needLoginAgain = tr("Your account is currently not logged in. Please enter your password to log in again.

This could be caused by a password change."); - QString failReason = needLoginAgain; while (tryagain) { m_session = std::make_shared(); - m_session->wants_online = m_online; + m_session->wants_online = m_userWantsOnline; m_accountToUse->fillSession(m_session); - switch(m_accountToUse->accountState()) { case AccountState::Offline: { m_session->wants_online = false; @@ -131,26 +126,32 @@ void LaunchController::login() { QString usedname; if(m_offlineName.isEmpty()) { // we ask the user for a player name - bool ok = false; QString lastOfflinePlayerName = APPLICATION->settings()->get("LastOfflinePlayerName").toString(); usedname = lastOfflinePlayerName.isEmpty() ? m_session->player_name : lastOfflinePlayerName; - QString name = QInputDialog::getText( - m_parentWidget, - tr("Player name"), - tr("Choose your offline mode player name."), - QLineEdit::Normal, - usedname, - &ok - ); - if (!ok) + OfflineNameDialog dialog(usedname, m_parentWidget); + int result = dialog.exec(); + if(result == OfflineNameDialog::Accepted) + { + usedname = dialog.textValue(); + APPLICATION->settings()->set("LastOfflinePlayerName", usedname); + } + else if (result == OfflineNameDialog::Rejected) { tryagain = false; break; } - if (name.length()) + else if(result == OfflineNameDialog::OnlineRequested) { - usedname = name; - APPLICATION->settings()->set("LastOfflinePlayerName", usedname); + m_userWantsOnline = true; + if(m_accountToUse->accountState() == AccountState::Offline) + { + auto task = m_accountToUse->refresh(); + if(task) + { + task->start(); + } + } + break; } } else { @@ -210,7 +211,7 @@ void LaunchController::login() { case AccountState::Working: { // refresh is in progress, we need to wait for it to finish to proceed. ProgressDialog progDialog(m_parentWidget); - if (m_online) + if (m_userWantsOnline) { progDialog.setSkipButton(true, tr("Play Offline")); } @@ -238,10 +239,7 @@ void LaunchController::login() { bool isDefault = accounts->defaultAccount() == m_accountToUse; accounts->removeAccount(accounts->index(accounts->findAccountByProfileId(m_accountToUse->profileId()))); MinecraftAccountPtr newAccount = nullptr; - newAccount = MSALoginDialog::newAccount( - m_parentWidget, - tr("Please enter your Mojang account email and password to add your account.") - ); + newAccount = MSALoginDialog::newAccount(m_parentWidget); if (newAccount) { accounts->addAccount(newAccount); if (isDefault) { diff --git a/launcher/LaunchController.h b/launcher/LaunchController.h index cb99dc27..8b43071d 100644 --- a/launcher/LaunchController.h +++ b/launcher/LaunchController.h @@ -25,7 +25,7 @@ public: } void setOnline(bool online) { - m_online = online; + m_userWantsOnline = online; } void setOfflineName(const QString &offlineName) { @@ -69,7 +69,7 @@ private slots: private: BaseProfilerFactory *m_profiler = nullptr; - bool m_online = true; + bool m_userWantsOnline = true; QString m_offlineName; InstancePtr m_instance; QWidget * m_parentWidget = nullptr; diff --git a/launcher/minecraft/auth/AccountList.cpp b/launcher/minecraft/auth/AccountList.cpp index 74982adf..140a47e5 100644 --- a/launcher/minecraft/auth/AccountList.cpp +++ b/launcher/minecraft/auth/AccountList.cpp @@ -400,7 +400,7 @@ bool AccountList::loadList() { if (m_listFilePath.isEmpty()) { - qCritical() << "Can't load Mojang account list. No file path given and no default set."; + qCritical() << "Can't load account list. No file path given and no default set."; return false; } @@ -492,7 +492,7 @@ bool AccountList::saveList() { if (m_listFilePath.isEmpty()) { - qCritical() << "Can't save Mojang account list. No file path given and no default set."; + qCritical() << "Can't save account list. No file path given and no default set."; return false; } diff --git a/launcher/ui/dialogs/MSALoginDialog.cpp b/launcher/ui/dialogs/MSALoginDialog.cpp index 84155b49..7fe6bd2d 100644 --- a/launcher/ui/dialogs/MSALoginDialog.cpp +++ b/launcher/ui/dialogs/MSALoginDialog.cpp @@ -143,10 +143,9 @@ void MSALoginDialog::onTaskProgress(qint64 current, qint64 total) } // Public interface -MinecraftAccountPtr MSALoginDialog::newAccount(QWidget *parent, QString msg) +MinecraftAccountPtr MSALoginDialog::newAccount(QWidget *parent) { MSALoginDialog dlg(parent); - dlg.ui->label->setText(msg); if (dlg.exec() == QDialog::Accepted) { return dlg.m_account; @@ -157,4 +156,4 @@ MinecraftAccountPtr MSALoginDialog::newAccount(QWidget *parent, QString msg) void MSALoginDialog::on_copyCodeButton_clicked() { QApplication::clipboard()->setText(m_code); -} \ No newline at end of file +} diff --git a/launcher/ui/dialogs/MSALoginDialog.h b/launcher/ui/dialogs/MSALoginDialog.h index 963f550b..c2553eb7 100644 --- a/launcher/ui/dialogs/MSALoginDialog.h +++ b/launcher/ui/dialogs/MSALoginDialog.h @@ -33,7 +33,7 @@ class MSALoginDialog : public QDialog public: ~MSALoginDialog(); - static MinecraftAccountPtr newAccount(QWidget *parent, QString message); + static MinecraftAccountPtr newAccount(QWidget *parent); int exec() override; private: diff --git a/launcher/ui/dialogs/OfflineNameDialog.cpp b/launcher/ui/dialogs/OfflineNameDialog.cpp new file mode 100644 index 00000000..64b62dbd --- /dev/null +++ b/launcher/ui/dialogs/OfflineNameDialog.cpp @@ -0,0 +1,66 @@ +/* + * Copyright 2024 Petr Mrázek + * + * This source is subject to the Microsoft Permissive License (MS-PL). + * Please see the COPYING.md file for more information. + */ + +#include +#include +#include +#include +#include + +#include "OfflineNameDialog.h" + +OfflineNameDialog::OfflineNameDialog(QString current_name, QWidget* parent) +{ + setWindowTitle(tr("Player name")); + + m_lineEdit = new QLineEdit(this); + m_lineEdit->setText(current_name); + connect(m_lineEdit, &QLineEdit::textChanged, this, &OfflineNameDialog::textChanged); + + QLabel *label = new QLabel(tr("Choose your offline mode player name."), this); + label->setBuddy(m_lineEdit); + label->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); + + m_buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this); + QPushButton * retryButton = m_buttonBox->addButton(tr("Retry Online"), QDialogButtonBox::ActionRole); + connect(m_buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); + connect(retryButton, &QPushButton::clicked, this, &OfflineNameDialog::retryOnline); + + QVBoxLayout *mainLayout = new QVBoxLayout(this); + mainLayout->setSizeConstraint(QLayout::SetMinAndMaxSize); + mainLayout->addWidget(label); + mainLayout->addWidget(m_lineEdit); + mainLayout->addWidget(m_buttonBox); + + textChanged(current_name); +} + +void OfflineNameDialog::accept() +{ + if(!m_acceptEnabled) + { + return; + } + QDialog::accept(); +} + +QString OfflineNameDialog::textValue() const +{ + return m_lineEdit->text(); +} + +void OfflineNameDialog::textChanged(const QString& text) +{ + m_acceptEnabled = !text.isEmpty(); + m_buttonBox->button(QDialogButtonBox::Ok)->setEnabled(m_acceptEnabled); +} + +void OfflineNameDialog::retryOnline() +{ + done(OnlineRequested); +} diff --git a/launcher/ui/dialogs/OfflineNameDialog.h b/launcher/ui/dialogs/OfflineNameDialog.h new file mode 100644 index 00000000..0b97a78c --- /dev/null +++ b/launcher/ui/dialogs/OfflineNameDialog.h @@ -0,0 +1,40 @@ +#pragma once +/* + * Copyright 2024 Petr Mrázek + * + * This source is subject to the Microsoft Permissive License (MS-PL). + * Please see the COPYING.md file for more information. + */ + +#include +#include + + +class OfflineNameDialog : public QDialog +{ + Q_OBJECT + +public: + enum OfflineNameDialogCode { + Rejected = QDialog::Rejected, + Accepted = QDialog::Accepted, + OnlineRequested, + }; + + OfflineNameDialog(QString current_name, QWidget * parent = nullptr); + virtual ~OfflineNameDialog() = default; + + QString textValue() const; + +public slots: + void accept() override; + +private slots: + void textChanged(const QString& text); + void retryOnline(); + +private: + class QDialogButtonBox * m_buttonBox; + class QLineEdit* m_lineEdit; + bool m_acceptEnabled = false; +}; diff --git a/launcher/ui/pages/global/AccountListPage.cpp b/launcher/ui/pages/global/AccountListPage.cpp index f5ce69be..4bf9d33e 100644 --- a/launcher/ui/pages/global/AccountListPage.cpp +++ b/launcher/ui/pages/global/AccountListPage.cpp @@ -110,11 +110,7 @@ void AccountListPage::listChanged() void AccountListPage::on_actionAddMicrosoft_triggered() { - MinecraftAccountPtr account = MSALoginDialog::newAccount( - this, - tr("Please enter your Mojang account email and password to add your account.") - ); - + MinecraftAccountPtr account = MSALoginDialog::newAccount(this); if (account) { m_accounts->addAccount(account);