GH-3392 dirty initial MSA support that shares logic with Mojang flows

Both act as the first step of AuthContext.
This commit is contained in:
Petr Mrázek
2021-07-26 21:44:11 +02:00
parent fca2e9e44c
commit 3a53349e33
66 changed files with 2342 additions and 2477 deletions

View File

@ -16,7 +16,7 @@
#include "LoginDialog.h"
#include "ui_LoginDialog.h"
#include "minecraft/auth/YggdrasilTask.h"
#include "minecraft/auth/AccountTask.h"
#include <QtWidgets/QPushButton>
@ -42,11 +42,10 @@ void LoginDialog::accept()
ui->progressBar->setVisible(true);
// Setup the login task and start it
m_account = MojangAccount::createFromUsername(ui->userTextBox->text());
m_account = MinecraftAccount::createFromUsername(ui->userTextBox->text());
m_loginTask = m_account->login(nullptr, ui->passTextBox->text());
connect(m_loginTask.get(), &Task::failed, this, &LoginDialog::onTaskFailed);
connect(m_loginTask.get(), &Task::succeeded, this,
&LoginDialog::onTaskSucceeded);
connect(m_loginTask.get(), &Task::succeeded, this, &LoginDialog::onTaskSucceeded);
connect(m_loginTask.get(), &Task::status, this, &LoginDialog::onTaskStatus);
connect(m_loginTask.get(), &Task::progress, this, &LoginDialog::onTaskProgress);
m_loginTask->start();
@ -98,7 +97,7 @@ void LoginDialog::onTaskProgress(qint64 current, qint64 total)
}
// Public interface
MojangAccountPtr LoginDialog::newAccount(QWidget *parent, QString msg)
MinecraftAccountPtr LoginDialog::newAccount(QWidget *parent, QString msg)
{
LoginDialog dlg(parent);
dlg.ui->label->setText(msg);

View File

@ -18,7 +18,7 @@
#include <QtWidgets/QDialog>
#include <QtCore/QEventLoop>
#include "minecraft/auth/MojangAccount.h"
#include "minecraft/auth/MinecraftAccount.h"
namespace Ui
{
@ -32,7 +32,7 @@ class LoginDialog : public QDialog
public:
~LoginDialog();
static MojangAccountPtr newAccount(QWidget *parent, QString message);
static MinecraftAccountPtr newAccount(QWidget *parent, QString message);
private:
explicit LoginDialog(QWidget *parent = 0);
@ -53,6 +53,6 @@ slots:
private:
Ui::LoginDialog *ui;
MojangAccountPtr m_account;
MinecraftAccountPtr m_account;
std::shared_ptr<Task> m_loginTask;
};

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>421</width>
<height>238</height>
<height>198</height>
</rect>
</property>
<property name="sizePolicy">
@ -20,16 +20,6 @@
<string>Add Account</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="microsoftAccountsNoticeLabel">
<property name="text">
<string>NOTICE: MultiMC does not currently support Microsoft accounts. This means that accounts created from December 2020 onwards cannot be used.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">

View File

@ -0,0 +1,96 @@
/* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "MSALoginDialog.h"
#include "ui_MSALoginDialog.h"
#include "minecraft/auth/AccountTask.h"
#include <QtWidgets/QPushButton>
MSALoginDialog::MSALoginDialog(QWidget *parent) : QDialog(parent), ui(new Ui::MSALoginDialog)
{
ui->setupUi(this);
ui->progressBar->setVisible(false);
// ui->buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(false);
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
}
int MSALoginDialog::exec() {
setUserInputsEnabled(false);
ui->progressBar->setVisible(true);
// Setup the login task and start it
m_account = MinecraftAccount::createBlankMSA();
m_loginTask = m_account->loginMSA(nullptr);
connect(m_loginTask.get(), &Task::failed, this, &MSALoginDialog::onTaskFailed);
connect(m_loginTask.get(), &Task::succeeded, this, &MSALoginDialog::onTaskSucceeded);
connect(m_loginTask.get(), &Task::status, this, &MSALoginDialog::onTaskStatus);
connect(m_loginTask.get(), &Task::progress, this, &MSALoginDialog::onTaskProgress);
m_loginTask->start();
return QDialog::exec();
}
MSALoginDialog::~MSALoginDialog()
{
delete ui;
}
void MSALoginDialog::setUserInputsEnabled(bool enable)
{
ui->buttonBox->setEnabled(enable);
}
void MSALoginDialog::onTaskFailed(const QString &reason)
{
// Set message
ui->label->setText("<span style='color:red'>" + reason + "</span>");
// Re-enable user-interaction
setUserInputsEnabled(true);
ui->progressBar->setVisible(false);
}
void MSALoginDialog::onTaskSucceeded()
{
QDialog::accept();
}
void MSALoginDialog::onTaskStatus(const QString &status)
{
ui->label->setText(status);
}
void MSALoginDialog::onTaskProgress(qint64 current, qint64 total)
{
ui->progressBar->setMaximum(total);
ui->progressBar->setValue(current);
}
// Public interface
MinecraftAccountPtr MSALoginDialog::newAccount(QWidget *parent, QString msg)
{
MSALoginDialog dlg(parent);
dlg.ui->label->setText(msg);
if (dlg.exec() == QDialog::Accepted)
{
return dlg.m_account;
}
return 0;
}

View File

@ -0,0 +1,55 @@
/* Copyright 2013-2021 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <QtWidgets/QDialog>
#include <QtCore/QEventLoop>
#include "minecraft/auth/MinecraftAccount.h"
namespace Ui
{
class MSALoginDialog;
}
class MSALoginDialog : public QDialog
{
Q_OBJECT
public:
~MSALoginDialog();
static MinecraftAccountPtr newAccount(QWidget *parent, QString message);
int exec() override;
private:
explicit MSALoginDialog(QWidget *parent = 0);
void setUserInputsEnabled(bool enable);
protected
slots:
void onTaskFailed(const QString &reason);
void onTaskSucceeded();
void onTaskStatus(const QString &status);
void onTaskProgress(qint64 current, qint64 total);
private:
Ui::MSALoginDialog *ui;
MinecraftAccountPtr m_account;
std::shared_ptr<Task> m_loginTask;
};

View File

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MSALoginDialog</class>
<widget class="QDialog" name="MSALoginDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>421</width>
<height>114</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Add Microsoft Account</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string notr="true">Message label placeholder.</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item>
<widget class="QProgressBar" name="progressBar">
<property name="value">
<number>24</number>
</property>
<property name="textVisible">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -33,9 +33,10 @@ ProfileSelectDialog::ProfileSelectDialog(const QString &message, int flags, QWid
m_accounts = MMC->accounts();
auto view = ui->listView;
//view->setModel(m_accounts.get());
//view->hideColumn(MojangAccountList::ActiveColumn);
//view->hideColumn(AccountList::ActiveColumn);
view->setColumnCount(1);
view->setRootIsDecorated(false);
// FIXME: use a real model, not this
if(QTreeWidgetItem* header = view->headerItem())
{
header->setText(0, tr("Name"));
@ -47,20 +48,19 @@ ProfileSelectDialog::ProfileSelectDialog(const QString &message, int flags, QWid
QList <QTreeWidgetItem *> items;
for (int i = 0; i < m_accounts->count(); i++)
{
MojangAccountPtr account = m_accounts->at(i);
for (auto profile : account->profiles())
{
auto profileLabel = profile.name;
if(account->isInUse())
{
profileLabel += tr(" (in use)");
}
auto item = new QTreeWidgetItem(view);
item->setText(0, profileLabel);
item->setIcon(0, SkinUtils::getFaceFromCache(profile.id));
item->setData(0, MojangAccountList::PointerRole, QVariant::fromValue(account));
items.append(item);
MinecraftAccountPtr account = m_accounts->at(i);
QString profileLabel;
if(account->isInUse()) {
profileLabel = tr("%1 (in use)").arg(account->profileName());
}
else {
profileLabel = account->profileName();
}
auto item = new QTreeWidgetItem(view);
item->setText(0, profileLabel);
item->setIcon(0, account->getFace());
item->setData(0, AccountList::PointerRole, QVariant::fromValue(account));
items.append(item);
}
view->addTopLevelItems(items);
@ -84,7 +84,7 @@ ProfileSelectDialog::~ProfileSelectDialog()
delete ui;
}
MojangAccountPtr ProfileSelectDialog::selectedAccount() const
MinecraftAccountPtr ProfileSelectDialog::selectedAccount() const
{
return m_selected;
}
@ -105,7 +105,7 @@ void ProfileSelectDialog::on_buttonBox_accepted()
if (selection.size() > 0)
{
QModelIndex selected = selection.first();
m_selected = selected.data(MojangAccountList::PointerRole).value<MojangAccountPtr>();
m_selected = selected.data(AccountList::PointerRole).value<MinecraftAccountPtr>();
}
close();
}

View File

@ -19,7 +19,7 @@
#include <memory>
#include "minecraft/auth/MojangAccountList.h"
#include "minecraft/auth/AccountList.h"
namespace Ui
{
@ -59,7 +59,7 @@ public:
* Gets a pointer to the account that the user selected.
* This is null if the user clicked cancel or hasn't clicked OK yet.
*/
MojangAccountPtr selectedAccount() const;
MinecraftAccountPtr selectedAccount() const;
/*!
* Returns true if the user checked the "use as global default" checkbox.
@ -80,10 +80,10 @@ slots:
void on_buttonBox_rejected();
protected:
std::shared_ptr<MojangAccountList> m_accounts;
std::shared_ptr<AccountList> m_accounts;
//! The account that was selected when the user clicked OK.
MojangAccountPtr m_selected;
MinecraftAccountPtr m_selected;
private:
Ui::ProfileSelectDialog *ui;

View File

@ -107,7 +107,7 @@ void SkinUploadDialog::on_skinBrowseBtn_clicked()
ui->skinPathTextBox->setText(cooked_path);
}
SkinUploadDialog::SkinUploadDialog(MojangAccountPtr acct, QWidget *parent)
SkinUploadDialog::SkinUploadDialog(MinecraftAccountPtr acct, QWidget *parent)
:QDialog(parent), m_acct(acct), ui(new Ui::SkinUploadDialog)
{
ui->setupUi(this);

View File

@ -1,7 +1,7 @@
#pragma once
#include <QDialog>
#include <minecraft/auth/MojangAccount.h>
#include <minecraft/auth/MinecraftAccount.h>
namespace Ui
{
@ -11,7 +11,7 @@ namespace Ui
class SkinUploadDialog : public QDialog {
Q_OBJECT
public:
explicit SkinUploadDialog(MojangAccountPtr acct, QWidget *parent = 0);
explicit SkinUploadDialog(MinecraftAccountPtr acct, QWidget *parent = 0);
virtual ~SkinUploadDialog() {};
public slots:
@ -22,7 +22,7 @@ public slots:
void on_skinBrowseBtn_clicked();
protected:
MojangAccountPtr m_acct;
MinecraftAccountPtr m_acct;
private:
Ui::SkinUploadDialog *ui;