mirror of
https://github.com/UltimMC/Launcher.git
synced 2025-12-24 12:32:42 +00:00
Fix conflict again
This commit is contained in:
@@ -40,7 +40,6 @@ void LaunchController::login() {
|
||||
|
||||
// Find an account to use.
|
||||
std::shared_ptr<AccountList> accounts = MMC->accounts();
|
||||
AccountPtr account = accounts->activeAccount();
|
||||
if (accounts->count() <= 0)
|
||||
{
|
||||
// Tell the user they need to log in at least one account in order to play.
|
||||
|
||||
@@ -1050,7 +1050,7 @@ void MainWindow::repopulateAccountsMenu()
|
||||
accountMenu->clear();
|
||||
|
||||
std::shared_ptr<AccountList> accounts = MMC->accounts();
|
||||
AccountPtr active_account = accounts->activeAccount();
|
||||
MinecraftAccountPtr active_account = accounts->activeAccount();
|
||||
|
||||
QString active_profileId = "";
|
||||
if (active_account != nullptr)
|
||||
@@ -1059,7 +1059,7 @@ void MainWindow::repopulateAccountsMenu()
|
||||
// this can be called before accountMenuButton exists
|
||||
if (accountMenuButton)
|
||||
{
|
||||
auto profileLabel = formatProfile(profile->name, active_account->provider()->displayName(), active_account->isInUse());
|
||||
auto profileLabel = profileInUseFilter(active_account->profileName(), active_account->isInUse());
|
||||
accountMenuButton->setText(profileLabel);
|
||||
}
|
||||
}
|
||||
@@ -1075,21 +1075,14 @@ void MainWindow::repopulateAccountsMenu()
|
||||
// TODO: Nicer way to iterate?
|
||||
for (int i = 0; i < accounts->count(); i++)
|
||||
{
|
||||
AccountPtr account = accounts->at(i);
|
||||
for (auto profile : account->profiles())
|
||||
MinecraftAccountPtr account = accounts->at(i);
|
||||
auto profileLabel = profileInUseFilter(account->profileName(), account->isInUse());
|
||||
QAction *action = new QAction(profileLabel, this);
|
||||
action->setData(account->profileId());
|
||||
action->setCheckable(true);
|
||||
if (active_profileId == account->profileId())
|
||||
{
|
||||
auto profileLabel = formatProfile(profile.name, account->provider()->displayName(), account->isInUse());
|
||||
QAction *action = new QAction(profileLabel, this);
|
||||
action->setData(account->username());
|
||||
action->setCheckable(true);
|
||||
if (active_username == account->username())
|
||||
{
|
||||
action->setChecked(true);
|
||||
}
|
||||
|
||||
action->setIcon(SkinUtils::getFaceFromCache(profile.id));
|
||||
accountMenu->addAction(action);
|
||||
connect(action, SIGNAL(triggered(bool)), SLOT(changeActiveAccount()));
|
||||
action->setChecked(true);
|
||||
}
|
||||
|
||||
action->setIcon(account->getFace());
|
||||
@@ -1151,19 +1144,15 @@ void MainWindow::activeAccountChanged()
|
||||
{
|
||||
repopulateAccountsMenu();
|
||||
|
||||
AccountPtr account = MMC->accounts()->activeAccount();
|
||||
MinecraftAccountPtr account = MMC->accounts()->activeAccount();
|
||||
|
||||
// FIXME: this needs adjustment for MSA
|
||||
if (account != nullptr && account->profileName() != "")
|
||||
{
|
||||
const AccountProfile *profile = account->currentProfile();
|
||||
if (profile != nullptr)
|
||||
{
|
||||
auto profileLabel = formatProfile(profile->name, account->provider()->displayName(), account->isInUse());
|
||||
accountMenuButton->setIcon(SkinUtils::getFaceFromCache(profile->id));
|
||||
accountMenuButton->setText(profileLabel);
|
||||
return;
|
||||
}
|
||||
auto profileLabel = profileInUseFilter(account->profileName(), account->isInUse());
|
||||
accountMenuButton->setText(profileLabel);
|
||||
accountMenuButton->setIcon(account->getFace());
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the icon to the "no account" icon.
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <QTimer>
|
||||
|
||||
#include "BaseInstance.h"
|
||||
#include "minecraft/auth/Account.h"
|
||||
#include "minecraft/auth/MinecraftAccount.h"
|
||||
#include "net/NetJob.h"
|
||||
#include "updater/GoUpdate.h"
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ void LoginDialog::onTaskProgress(qint64 current, qint64 total)
|
||||
}
|
||||
|
||||
// Public interface
|
||||
AccountPtr LoginDialog::newAccount(QWidget *parent, QString msg)
|
||||
MinecraftAccountPtr LoginDialog::newAccount(QWidget *parent, QString msg)
|
||||
{
|
||||
LoginDialog dlg(parent);
|
||||
dlg.ui->label->setText(msg);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <QtWidgets/QRadioButton>
|
||||
#include <QtCore/QEventLoop>
|
||||
|
||||
#include "minecraft/auth/Account.h"
|
||||
#include "minecraft/auth/MinecraftAccount.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
@@ -33,7 +33,7 @@ class LoginDialog : public QDialog
|
||||
public:
|
||||
~LoginDialog();
|
||||
|
||||
static AccountPtr newAccount(QWidget *parent, QString message);
|
||||
static MinecraftAccountPtr newAccount(QWidget *parent, QString message);
|
||||
|
||||
private:
|
||||
explicit LoginDialog(QWidget *parent = 0);
|
||||
@@ -54,7 +54,6 @@ slots:
|
||||
|
||||
private:
|
||||
Ui::LoginDialog *ui;
|
||||
AccountPtr m_account;
|
||||
QMap<QString, QRadioButton*> m_radioButtons;
|
||||
MinecraftAccountPtr m_account;
|
||||
std::shared_ptr<Task> m_loginTask;
|
||||
};
|
||||
|
||||
@@ -48,19 +48,10 @@ ProfileSelectDialog::ProfileSelectDialog(const QString &message, int flags, QWid
|
||||
QList <QTreeWidgetItem *> items;
|
||||
for (int i = 0; i < m_accounts->count(); i++)
|
||||
{
|
||||
AccountPtr 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, AccountList::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();
|
||||
@@ -93,7 +84,7 @@ ProfileSelectDialog::~ProfileSelectDialog()
|
||||
delete ui;
|
||||
}
|
||||
|
||||
AccountPtr ProfileSelectDialog::selectedAccount() const
|
||||
MinecraftAccountPtr ProfileSelectDialog::selectedAccount() const
|
||||
{
|
||||
return m_selected;
|
||||
}
|
||||
@@ -114,7 +105,7 @@ void ProfileSelectDialog::on_buttonBox_accepted()
|
||||
if (selection.size() > 0)
|
||||
{
|
||||
QModelIndex selected = selection.first();
|
||||
m_selected = selected.data(AccountList::PointerRole).value<AccountPtr>();
|
||||
m_selected = selected.data(AccountList::PointerRole).value<MinecraftAccountPtr>();
|
||||
}
|
||||
close();
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
AccountPtr selectedAccount() const;
|
||||
MinecraftAccountPtr selectedAccount() const;
|
||||
|
||||
/*!
|
||||
* Returns true if the user checked the "use as global default" checkbox.
|
||||
@@ -83,7 +83,7 @@ protected:
|
||||
std::shared_ptr<AccountList> m_accounts;
|
||||
|
||||
//! The account that was selected when the user clicked OK.
|
||||
AccountPtr m_selected;
|
||||
MinecraftAccountPtr m_selected;
|
||||
|
||||
private:
|
||||
Ui::ProfileSelectDialog *ui;
|
||||
|
||||
@@ -117,7 +117,7 @@ void SkinUploadDialog::on_skinBrowseBtn_clicked()
|
||||
ui->skinPathTextBox->setText(cooked_path);
|
||||
}
|
||||
|
||||
SkinUploadDialog::SkinUploadDialog(AccountPtr acct, QWidget *parent)
|
||||
SkinUploadDialog::SkinUploadDialog(MinecraftAccountPtr acct, QWidget *parent)
|
||||
:QDialog(parent), m_acct(acct), ui(new Ui::SkinUploadDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <minecraft/auth/Account.h>
|
||||
#include <minecraft/auth/MinecraftAccount.h>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
@@ -11,7 +11,7 @@ namespace Ui
|
||||
class SkinUploadDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SkinUploadDialog(AccountPtr 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:
|
||||
AccountPtr m_acct;
|
||||
MinecraftAccountPtr m_acct;
|
||||
|
||||
private:
|
||||
Ui::SkinUploadDialog *ui;
|
||||
|
||||
@@ -1,333 +0,0 @@
|
||||
#include "Account.h"
|
||||
#include "AuthProviders.h"
|
||||
#include "flows/RefreshTask.h"
|
||||
#include "flows/AuthenticateTask.h"
|
||||
|
||||
#include <QUuid>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QRegExp>
|
||||
#include <QStringList>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include <BuildConfig.h>
|
||||
|
||||
AccountPtr Account::loadFromJson(const QJsonObject &object)
|
||||
{
|
||||
// The JSON object must at least have a username for it to be valid.
|
||||
if (!object.value("username").isString())
|
||||
{
|
||||
qCritical() << "Can't load Mojang account info from JSON object. Username field is "
|
||||
"missing or of the wrong type.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QString provider = object.value("loginType").toString("dummy");
|
||||
QString username = object.value("username").toString("");
|
||||
QString clientToken = object.value("clientToken").toString("");
|
||||
QString accessToken = object.value("accessToken").toString("");
|
||||
|
||||
QJsonArray profileArray = object.value("profiles").toArray();
|
||||
if (profileArray.size() < 1)
|
||||
{
|
||||
qCritical() << "Can't load Mojang account with username \"" << username
|
||||
<< "\". No profiles found.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QList<AccountProfile> profiles;
|
||||
for (QJsonValue profileVal : profileArray)
|
||||
{
|
||||
QJsonObject profileObject = profileVal.toObject();
|
||||
QString id = profileObject.value("id").toString("");
|
||||
QString name = profileObject.value("name").toString("");
|
||||
bool legacy = profileObject.value("legacy").toBool(false);
|
||||
if (id.isEmpty() || name.isEmpty())
|
||||
{
|
||||
qWarning() << "Unable to load a profile because it was missing an ID or a name.";
|
||||
continue;
|
||||
}
|
||||
profiles.append({id, name, legacy});
|
||||
}
|
||||
|
||||
AccountPtr account(new Account());
|
||||
if (object.value("user").isObject())
|
||||
{
|
||||
User u;
|
||||
QJsonObject userStructure = object.value("user").toObject();
|
||||
u.id = userStructure.value("id").toString();
|
||||
/*
|
||||
QJsonObject propMap = userStructure.value("properties").toObject();
|
||||
for(auto key: propMap.keys())
|
||||
{
|
||||
auto values = propMap.operator[](key).toArray();
|
||||
for(auto value: values)
|
||||
u.properties.insert(key, value.toString());
|
||||
}
|
||||
*/
|
||||
account->m_user = u;
|
||||
}
|
||||
account->m_provider = AuthProviders::lookup(provider);
|
||||
account->m_username = username;
|
||||
account->m_clientToken = clientToken;
|
||||
account->m_accessToken = accessToken;
|
||||
account->m_profiles = profiles;
|
||||
|
||||
// Get the currently selected profile.
|
||||
QString currentProfile = object.value("activeProfile").toString("");
|
||||
if (!currentProfile.isEmpty())
|
||||
account->setCurrentProfile(currentProfile);
|
||||
|
||||
return account;
|
||||
}
|
||||
|
||||
AccountPtr Account::createFromUsername(const QString &username)
|
||||
{
|
||||
AccountPtr account(new Account());
|
||||
account->m_clientToken = QUuid::createUuid().toString().remove(QRegExp("[{}-]"));
|
||||
account->m_username = username;
|
||||
return account;
|
||||
}
|
||||
|
||||
QJsonObject Account::saveToJson() const
|
||||
{
|
||||
QJsonObject json;
|
||||
json.insert("loginType", m_provider->id());
|
||||
json.insert("username", m_username);
|
||||
json.insert("clientToken", m_clientToken);
|
||||
json.insert("accessToken", m_accessToken);
|
||||
|
||||
QJsonArray profileArray;
|
||||
for (AccountProfile profile : m_profiles)
|
||||
{
|
||||
QJsonObject profileObj;
|
||||
profileObj.insert("id", profile.id);
|
||||
profileObj.insert("name", profile.name);
|
||||
profileObj.insert("legacy", profile.legacy);
|
||||
profileArray.append(profileObj);
|
||||
}
|
||||
json.insert("profiles", profileArray);
|
||||
|
||||
QJsonObject userStructure;
|
||||
{
|
||||
userStructure.insert("id", m_user.id);
|
||||
/*
|
||||
QJsonObject userAttrs;
|
||||
for(auto key: m_user.properties.keys())
|
||||
{
|
||||
auto array = QJsonArray::fromStringList(m_user.properties.values(key));
|
||||
userAttrs.insert(key, array);
|
||||
}
|
||||
userStructure.insert("properties", userAttrs);
|
||||
*/
|
||||
}
|
||||
json.insert("user", userStructure);
|
||||
|
||||
if (m_currentProfile != -1)
|
||||
json.insert("activeProfile", currentProfile()->id);
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
bool Account::setProvider(AuthProviderPtr provider)
|
||||
{
|
||||
if (provider == nullptr)
|
||||
return false;
|
||||
m_provider = provider;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Account::setCurrentProfile(const QString &profileId)
|
||||
{
|
||||
for (int i = 0; i < m_profiles.length(); i++)
|
||||
{
|
||||
if (m_profiles[i].id == profileId)
|
||||
{
|
||||
m_currentProfile = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const AccountProfile *Account::currentProfile() const
|
||||
{
|
||||
if (m_currentProfile == -1)
|
||||
return nullptr;
|
||||
return &m_profiles[m_currentProfile];
|
||||
}
|
||||
|
||||
AccountStatus Account::accountStatus() const
|
||||
{
|
||||
if (m_accessToken.isEmpty())
|
||||
return NotVerified;
|
||||
else
|
||||
return Verified;
|
||||
}
|
||||
|
||||
std::shared_ptr<YggdrasilTask> Account::login(AuthSessionPtr session, QString password)
|
||||
{
|
||||
Q_ASSERT(m_currentTask.get() == nullptr);
|
||||
|
||||
// Handling alternative account types
|
||||
if (m_provider->dummyAuth())
|
||||
{
|
||||
if (session)
|
||||
{
|
||||
session->status = AuthSession::PlayableOnline;
|
||||
session->auth_server_online = false;
|
||||
fillSession(session);
|
||||
}
|
||||
if (!currentProfile())
|
||||
{
|
||||
// TODO: Proper profile support (idk how)
|
||||
auto dummyProfile = AccountProfile();
|
||||
dummyProfile.name = m_username;
|
||||
dummyProfile.id = QUuid::createUuid().toString().remove(QRegExp("[{}]"));
|
||||
m_profiles.append(dummyProfile);
|
||||
m_currentProfile = 0;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// take care of the true offline status
|
||||
if (accountStatus() == NotVerified && password.isEmpty())
|
||||
{
|
||||
if (session)
|
||||
{
|
||||
session->status = AuthSession::RequiresPassword;
|
||||
fillSession(session);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(accountStatus() == Verified && !session->wants_online)
|
||||
{
|
||||
session->status = AuthSession::PlayableOffline;
|
||||
session->auth_server_online = false;
|
||||
fillSession(session);
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (password.isEmpty())
|
||||
{
|
||||
m_currentTask.reset(new RefreshTask(this));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currentTask.reset(new AuthenticateTask(this, password));
|
||||
}
|
||||
m_currentTask->assignSession(session);
|
||||
|
||||
connect(m_currentTask.get(), SIGNAL(succeeded()), SLOT(authSucceeded()));
|
||||
connect(m_currentTask.get(), SIGNAL(failed(QString)), SLOT(authFailed(QString)));
|
||||
}
|
||||
return m_currentTask;
|
||||
}
|
||||
|
||||
void Account::authSucceeded()
|
||||
{
|
||||
auto session = m_currentTask->getAssignedSession();
|
||||
if (session)
|
||||
{
|
||||
session->status =
|
||||
session->wants_online ? AuthSession::PlayableOnline : AuthSession::PlayableOffline;
|
||||
fillSession(session);
|
||||
session->auth_server_online = true;
|
||||
}
|
||||
m_currentTask.reset();
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void Account::authFailed(QString reason)
|
||||
{
|
||||
auto session = m_currentTask->getAssignedSession();
|
||||
// This is emitted when the yggdrasil tasks time out or are cancelled.
|
||||
// -> we treat the error as no-op
|
||||
if (m_currentTask->state() == YggdrasilTask::STATE_FAILED_SOFT)
|
||||
{
|
||||
if (session)
|
||||
{
|
||||
session->status = accountStatus() == Verified ? AuthSession::PlayableOffline
|
||||
: AuthSession::RequiresPassword;
|
||||
session->auth_server_online = false;
|
||||
fillSession(session);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_accessToken = QString();
|
||||
emit changed();
|
||||
if (session)
|
||||
{
|
||||
session->status = AuthSession::RequiresPassword;
|
||||
session->auth_server_online = true;
|
||||
fillSession(session);
|
||||
}
|
||||
}
|
||||
m_currentTask.reset();
|
||||
}
|
||||
|
||||
void Account::fillSession(AuthSessionPtr session)
|
||||
{
|
||||
// the user name. you have to have an user name
|
||||
session->username = m_username;
|
||||
// volatile auth token
|
||||
session->access_token = m_accessToken;
|
||||
// the semi-permanent client token
|
||||
session->client_token = m_clientToken;
|
||||
if (currentProfile())
|
||||
{
|
||||
// profile name
|
||||
session->player_name = currentProfile()->name;
|
||||
// profile ID
|
||||
session->uuid = currentProfile()->id;
|
||||
// 'legacy' or 'mojang', depending on account type
|
||||
session->user_type = currentProfile()->legacy ? "legacy" : "mojang";
|
||||
if (!session->access_token.isEmpty())
|
||||
{
|
||||
session->session = "token:" + m_accessToken + ":" + m_profiles[m_currentProfile].id;
|
||||
}
|
||||
else
|
||||
{
|
||||
session->session = "-";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
session->player_name = m_username;
|
||||
session->session = "-";
|
||||
}
|
||||
session->u = user();
|
||||
session->m_accountPtr = shared_from_this();
|
||||
}
|
||||
|
||||
void Account::decrementUses()
|
||||
{
|
||||
Usable::decrementUses();
|
||||
if(!isInUse())
|
||||
{
|
||||
emit changed();
|
||||
qWarning() << "Account" << m_username << "is no longer in use.";
|
||||
}
|
||||
}
|
||||
|
||||
void Account::incrementUses()
|
||||
{
|
||||
bool wasInUse = isInUse();
|
||||
Usable::incrementUses();
|
||||
if(!wasInUse)
|
||||
{
|
||||
emit changed();
|
||||
qWarning() << "Account" << m_username << "is now in use.";
|
||||
}
|
||||
}
|
||||
|
||||
void Account::invalidateClientToken()
|
||||
{
|
||||
m_clientToken = QUuid::createUuid().toString().remove(QRegExp("[{}-]"));
|
||||
emit changed();
|
||||
}
|
||||
@@ -1,168 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
#include <QJsonObject>
|
||||
#include <QPair>
|
||||
#include <QMap>
|
||||
|
||||
#include <memory>
|
||||
#include "AuthSession.h"
|
||||
#include "AccountProfile.h"
|
||||
#include "Usable.h"
|
||||
#include "providers/BaseAuthProvider.h"
|
||||
|
||||
class Task;
|
||||
class YggdrasilTask;
|
||||
class Account;
|
||||
|
||||
typedef std::shared_ptr<Account> AccountPtr;
|
||||
Q_DECLARE_METATYPE(AccountPtr)
|
||||
|
||||
enum AccountStatus
|
||||
{
|
||||
NotVerified,
|
||||
Verified
|
||||
};
|
||||
|
||||
/**
|
||||
* Object that stores information about a certain Mojang account.
|
||||
*
|
||||
* Said information may include things such as that account's username, client token, and access
|
||||
* token if the user chose to stay logged in.
|
||||
*/
|
||||
class MojangAccount :
|
||||
public QObject,
|
||||
public Usable,
|
||||
public std::enable_shared_from_this<Account>
|
||||
{
|
||||
Q_OBJECT
|
||||
public: /* construction */
|
||||
//! Do not copy accounts. ever.
|
||||
explicit Account(const Account &other, QObject *parent) = delete;
|
||||
|
||||
//! Default constructor
|
||||
explicit Account(QObject *parent = 0) : QObject(parent) {};
|
||||
|
||||
//! Creates an empty account for the specified user name.
|
||||
static AccountPtr createFromUsername(const QString &username);
|
||||
|
||||
//! Loads a Account from the given JSON object.
|
||||
static AccountPtr loadFromJson(const QJsonObject &json);
|
||||
|
||||
//! Saves a Account to a JSON object and returns it.
|
||||
QJsonObject saveToJson() const;
|
||||
|
||||
public: /* manipulation */
|
||||
/**
|
||||
* Overrides the login type on the account.
|
||||
*/
|
||||
bool setProvider(AuthProviderPtr provider);
|
||||
|
||||
/**
|
||||
* Sets the currently selected profile to the profile with the given ID string.
|
||||
* If profileId is not in the list of available profiles, the function will simply return
|
||||
* false.
|
||||
*/
|
||||
bool setCurrentProfile(const QString &profileId);
|
||||
|
||||
/**
|
||||
* Attempt to login. Empty password means we use the token.
|
||||
* If the attempt fails because we already are performing some task, it returns false.
|
||||
*/
|
||||
std::shared_ptr<YggdrasilTask> login(AuthSessionPtr session, QString password = QString());
|
||||
void invalidateClientToken();
|
||||
|
||||
public: /* queries */
|
||||
const AuthProviderPtr provider() const
|
||||
{
|
||||
return m_provider;
|
||||
}
|
||||
|
||||
const QString &username() const
|
||||
{
|
||||
return m_username;
|
||||
}
|
||||
|
||||
const QString &clientToken() const
|
||||
{
|
||||
return m_clientToken;
|
||||
}
|
||||
|
||||
const QString &accessToken() const
|
||||
{
|
||||
return m_accessToken;
|
||||
}
|
||||
|
||||
const QList<AccountProfile> &profiles() const
|
||||
{
|
||||
return m_profiles;
|
||||
}
|
||||
|
||||
const User &user()
|
||||
{
|
||||
return m_user;
|
||||
}
|
||||
|
||||
//! Returns the currently selected profile (if none, returns nullptr)
|
||||
const AccountProfile *currentProfile() const;
|
||||
|
||||
//! Returns whether the account is NotVerified, Verified or Online
|
||||
AccountStatus accountStatus() const;
|
||||
|
||||
signals:
|
||||
/**
|
||||
* This signal is emitted when the account changes
|
||||
*/
|
||||
void changed();
|
||||
|
||||
// TODO: better signalling for the various possible state changes - especially errors
|
||||
|
||||
protected: /* variables */
|
||||
// Authentication system used.
|
||||
// Usable values: "mojang", "dummy", "elyby"
|
||||
AuthProviderPtr m_provider;
|
||||
|
||||
// Username taken by account.
|
||||
QString m_username;
|
||||
|
||||
// Used to identify the client - the user can have multiple clients for the same account
|
||||
// Think: different launchers, all connecting to the same account/profile
|
||||
QString m_clientToken;
|
||||
|
||||
// Blank if not logged in.
|
||||
QString m_accessToken;
|
||||
|
||||
// Index of the selected profile within the list of available
|
||||
// profiles. -1 if nothing is selected.
|
||||
int m_currentProfile = -1;
|
||||
|
||||
// List of available profiles.
|
||||
QList<AccountProfile> m_profiles;
|
||||
|
||||
// the user structure, whatever it is.
|
||||
User m_user;
|
||||
|
||||
// current task we are executing here
|
||||
std::shared_ptr<YggdrasilTask> m_currentTask;
|
||||
|
||||
protected: /* methods */
|
||||
|
||||
void incrementUses() override;
|
||||
void decrementUses() override;
|
||||
|
||||
private
|
||||
slots:
|
||||
void authSucceeded();
|
||||
void authFailed(QString reason);
|
||||
|
||||
private:
|
||||
void fillSession(AuthSessionPtr session);
|
||||
|
||||
public:
|
||||
friend class YggdrasilTask;
|
||||
friend class AuthenticateTask;
|
||||
friend class ValidateTask;
|
||||
friend class RefreshTask;
|
||||
};
|
||||
@@ -15,8 +15,6 @@
|
||||
|
||||
#include "AccountList.h"
|
||||
#include "AccountData.h"
|
||||
#include "AccountList.h"
|
||||
#include "Account.h"
|
||||
|
||||
#include <QIODevice>
|
||||
#include <QFile>
|
||||
@@ -39,15 +37,14 @@ enum AccountListVersion {
|
||||
|
||||
AccountList::AccountList(QObject *parent) : QAbstractListModel(parent) { }
|
||||
|
||||
AccountPtr AccountList::findAccount(const QString &username) const
|
||||
{
|
||||
for (int i = 0; i < count(); i++)
|
||||
{
|
||||
AccountPtr account = at(i);
|
||||
if (account->username() == username)
|
||||
return account;
|
||||
int AccountList::findAccountByProfileId(const QString& profileId) const {
|
||||
for (int i = 0; i < count(); i++) {
|
||||
MinecraftAccountPtr account = at(i);
|
||||
if (account->profileId() == profileId) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const MinecraftAccountPtr AccountList::at(int i) const
|
||||
@@ -56,12 +53,6 @@ const MinecraftAccountPtr AccountList::at(int i) const
|
||||
}
|
||||
|
||||
void AccountList::addAccount(const MinecraftAccountPtr account)
|
||||
const AccountPtr AccountList::at(int i) const
|
||||
{
|
||||
return AccountPtr(m_accounts.at(i));
|
||||
}
|
||||
|
||||
void AccountList::addAccount(const AccountPtr account)
|
||||
{
|
||||
// We only ever want accounts with valid profiles.
|
||||
// Keeping profile-less accounts is pointless and serves no purpose.
|
||||
@@ -88,23 +79,6 @@ void AccountList::addAccount(const AccountPtr account)
|
||||
onListChanged();
|
||||
}
|
||||
|
||||
void AccountList::removeAccount(const QString &username)
|
||||
{
|
||||
int idx = 0;
|
||||
for (auto account : m_accounts)
|
||||
{
|
||||
if (account->username() == username)
|
||||
{
|
||||
beginRemoveRows(QModelIndex(), idx, idx);
|
||||
m_accounts.removeOne(account);
|
||||
endRemoveRows();
|
||||
return;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
onListChanged();
|
||||
}
|
||||
|
||||
void AccountList::removeAccount(QModelIndex index)
|
||||
{
|
||||
int row = index.row();
|
||||
@@ -123,7 +97,7 @@ void AccountList::removeAccount(QModelIndex index)
|
||||
}
|
||||
}
|
||||
|
||||
AccountPtr AccountList::activeAccount() const
|
||||
MinecraftAccountPtr AccountList::activeAccount() const
|
||||
{
|
||||
return m_activeAccount;
|
||||
}
|
||||
@@ -135,7 +109,7 @@ void AccountList::setActiveAccount(const QString &profileId)
|
||||
int idx = 0;
|
||||
auto prevActiveAcc = m_activeAccount;
|
||||
m_activeAccount = nullptr;
|
||||
for (AccountPtr account : m_accounts)
|
||||
for (MinecraftAccountPtr account : m_accounts)
|
||||
{
|
||||
if (account == prevActiveAcc)
|
||||
{
|
||||
@@ -152,7 +126,7 @@ void AccountList::setActiveAccount(const QString &profileId)
|
||||
auto newActiveAccount = m_activeAccount;
|
||||
int newActiveAccountIdx = -1;
|
||||
int idx = 0;
|
||||
for (AccountPtr account : m_accounts)
|
||||
for (MinecraftAccountPtr account : m_accounts)
|
||||
{
|
||||
if (account->profileId() == profileId)
|
||||
{
|
||||
@@ -211,15 +185,7 @@ QVariant AccountList::data(const QModelIndex &index, int role) const
|
||||
if (index.row() > count())
|
||||
return QVariant();
|
||||
|
||||
AccountPtr account = at(index.row());
|
||||
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
switch (index.column())
|
||||
{
|
||||
case NameColumn:
|
||||
return account->username();
|
||||
MinecraftAccountPtr account = at(index.row());
|
||||
|
||||
switch (role)
|
||||
{
|
||||
@@ -234,28 +200,7 @@ QVariant AccountList::data(const QModelIndex &index, int role) const
|
||||
typeStr[0] = typeStr[0].toUpper();
|
||||
return typeStr;
|
||||
}
|
||||
case TypeColumn:
|
||||
return account->provider()->displayName();
|
||||
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
case Qt::ToolTipRole:
|
||||
return account->username();
|
||||
|
||||
case PointerRole:
|
||||
return qVariantFromValue(account);
|
||||
|
||||
case Qt::CheckStateRole:
|
||||
switch (index.column())
|
||||
{
|
||||
case ActiveColumn:
|
||||
return account == m_activeAccount ? Qt::Checked : Qt::Unchecked;
|
||||
}
|
||||
|
||||
default:
|
||||
return QVariant();
|
||||
case ProfileNameColumn: {
|
||||
return account->profileName();
|
||||
}
|
||||
@@ -301,9 +246,6 @@ QVariant AccountList::headerData(int section, Qt::Orientation orientation, int r
|
||||
case Qt::DisplayRole:
|
||||
switch (section)
|
||||
{
|
||||
case ActiveColumn:
|
||||
return tr("Active?");
|
||||
|
||||
case NameColumn:
|
||||
return tr("Account");
|
||||
case TypeColumn:
|
||||
@@ -312,10 +254,6 @@ QVariant AccountList::headerData(int section, Qt::Orientation orientation, int r
|
||||
return tr("Can Migrate?");
|
||||
case ProfileNameColumn:
|
||||
return tr("Profile");
|
||||
|
||||
case TypeColumn:
|
||||
return tr("Account type");
|
||||
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
@@ -372,8 +310,8 @@ bool AccountList::setData(const QModelIndex &index, const QVariant &value, int r
|
||||
{
|
||||
if(value == Qt::Checked)
|
||||
{
|
||||
AccountPtr account = this->at(index.row());
|
||||
this->setActiveAccount(account->username());
|
||||
MinecraftAccountPtr account = at(index.row());
|
||||
setActiveAccount(account->profileId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,19 +319,9 @@ bool AccountList::setData(const QModelIndex &index, const QVariant &value, int r
|
||||
return true;
|
||||
}
|
||||
|
||||
void AccountList::updateListData(QList<AccountPtr> versions)
|
||||
bool AccountList::loadList()
|
||||
{
|
||||
beginResetModel();
|
||||
m_accounts = versions;
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
bool AccountList::loadList(const QString &filePath)
|
||||
{
|
||||
QString path = filePath;
|
||||
if (path.isEmpty())
|
||||
path = m_listFilePath;
|
||||
if (path.isEmpty())
|
||||
if (m_listFilePath.isEmpty())
|
||||
{
|
||||
qCritical() << "Can't load Mojang account list. No file path given and no default set.";
|
||||
return false;
|
||||
@@ -493,11 +421,7 @@ bool AccountList::loadV3(QJsonObject& root) {
|
||||
for (QJsonValue accountVal : accounts)
|
||||
{
|
||||
QJsonObject accountObj = accountVal.toObject();
|
||||
AccountPtr account = Account::loadFromJson(accountObj);
|
||||
if (account.get() != nullptr)
|
||||
{
|
||||
connect(account.get(), SIGNAL(changed()), SLOT(accountChanged()));
|
||||
m_accounts.append(account);
|
||||
MinecraftAccountPtr account = MinecraftAccount::loadFromJsonV3(accountObj);
|
||||
if (account.get() != nullptr)
|
||||
{
|
||||
auto profileId = account->profileId();
|
||||
@@ -518,13 +442,11 @@ bool AccountList::loadV3(QJsonObject& root) {
|
||||
qWarning() << "Failed to load an account.";
|
||||
}
|
||||
}
|
||||
// Load the active account.
|
||||
m_activeAccount = findAccount(root.value("activeAccount").toString(""));
|
||||
endResetModel();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AccountList::saveList(const QString &filePath)
|
||||
bool AccountList::saveList()
|
||||
{
|
||||
if (m_listFilePath.isEmpty())
|
||||
{
|
||||
@@ -555,7 +477,7 @@ bool AccountList::saveList(const QString &filePath)
|
||||
// Build a list of accounts.
|
||||
qDebug() << "Building account array.";
|
||||
QJsonArray accounts;
|
||||
for (AccountPtr account : m_accounts)
|
||||
for (MinecraftAccountPtr account : m_accounts)
|
||||
{
|
||||
QJsonObject accountObj = account->saveToJson();
|
||||
if(m_activeAccount == account) {
|
||||
@@ -567,12 +489,6 @@ bool AccountList::saveList(const QString &filePath)
|
||||
// Insert the account list into the root object.
|
||||
root.insert("accounts", accounts);
|
||||
|
||||
if(m_activeAccount)
|
||||
{
|
||||
// Save the active account.
|
||||
root.insert("activeAccount", m_activeAccount->username());
|
||||
}
|
||||
|
||||
// Create a JSON document object to convert our JSON to bytes.
|
||||
QJsonDocument doc(root);
|
||||
|
||||
|
||||
@@ -1,212 +0,0 @@
|
||||
/* 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 "MinecraftAccount.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariant>
|
||||
#include <QAbstractListModel>
|
||||
#include <QSharedPointer>
|
||||
|
||||
/*!
|
||||
* List of available Mojang accounts.
|
||||
* This should be loaded in the background by MultiMC on startup.
|
||||
*/
|
||||
class AccountList : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum ModelRoles
|
||||
{
|
||||
PointerRole = 0x34B1CB48
|
||||
};
|
||||
|
||||
enum VListColumns
|
||||
{
|
||||
// TODO: Add icon column.
|
||||
NameColumn = 0,
|
||||
ProfileNameColumn,
|
||||
MigrationColumn,
|
||||
TypeColumn,
|
||||
|
||||
NUM_COLUMNS
|
||||
};
|
||||
|
||||
explicit AccountList(QObject *parent = 0);
|
||||
|
||||
//! Gets the account at the given index.
|
||||
virtual const AccountPtr at(int i) const;
|
||||
|
||||
//! Returns the number of accounts in the list.
|
||||
virtual int count() const;
|
||||
|
||||
//////// List Model Functions ////////
|
||||
virtual QVariant data(const QModelIndex &index, int role) const;
|
||||
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||
virtual int rowCount(const QModelIndex &parent) const;
|
||||
virtual int columnCount(const QModelIndex &parent) const;
|
||||
virtual Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
virtual bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||
|
||||
/*!
|
||||
* Adds a the given Mojang account to the account list.
|
||||
*/
|
||||
virtual void addAccount(const AccountPtr account);
|
||||
|
||||
/*!
|
||||
* Removes the mojang account with the given username from the account list.
|
||||
*/
|
||||
virtual void removeAccount(const QString &username);
|
||||
|
||||
/*!
|
||||
* Removes the account at the given QModelIndex.
|
||||
*/
|
||||
virtual void removeAccount(QModelIndex index);
|
||||
|
||||
/*!
|
||||
* \brief Finds an account by its username.
|
||||
* \param The username of the account to find.
|
||||
* \return A const pointer to the account with the given username. NULL if
|
||||
* one doesn't exist.
|
||||
*/
|
||||
virtual AccountPtr findAccount(const QString &username) const;
|
||||
|
||||
/*!
|
||||
* Sets the default path to save the list file to.
|
||||
* If autosave is true, this list will automatically save to the given path whenever it changes.
|
||||
* THIS FUNCTION DOES NOT LOAD THE LIST. If you set autosave, be sure to call loadList() immediately
|
||||
* after calling this function to ensure an autosaved change doesn't overwrite the list you intended
|
||||
* to load.
|
||||
*/
|
||||
virtual void setListFilePath(QString path, bool autosave = false);
|
||||
|
||||
/*!
|
||||
* \brief Loads the account list from the given file path.
|
||||
* If the given file is an empty string (default), will load from the default account list file.
|
||||
* \return True if successful, otherwise false.
|
||||
*/
|
||||
virtual bool loadList(const QString &file = "");
|
||||
|
||||
/*!
|
||||
* \brief Saves the account list to the given file.
|
||||
* If the given file is an empty string (default), will save from the default account list file.
|
||||
* \return True if successful, otherwise false.
|
||||
*/
|
||||
virtual bool saveList(const QString &file = "");
|
||||
|
||||
/*!
|
||||
* \brief Gets a pointer to the account that the user has selected as their "active" account.
|
||||
* Which account is active can be overridden on a per-instance basis, but this will return the one that
|
||||
* is set as active globally.
|
||||
* \return The currently active Account. If there isn't an active account, returns a null pointer.
|
||||
*/
|
||||
virtual AccountPtr activeAccount() const;
|
||||
|
||||
/*!
|
||||
* Sets the given account as the current active account.
|
||||
* If the username given is an empty string, sets the active account to nothing.
|
||||
*/
|
||||
virtual void setActiveAccount(const QString &username);
|
||||
|
||||
/*!
|
||||
* Returns true if any of the account is at least Validated
|
||||
*/
|
||||
bool anyAccountIsValid();
|
||||
|
||||
signals:
|
||||
/*!
|
||||
* Signal emitted to indicate that the account list has changed.
|
||||
* This will also fire if the value of an element in the list changes (will be implemented
|
||||
* later).
|
||||
*/
|
||||
void listChanged();
|
||||
|
||||
/*!
|
||||
* Signal emitted to indicate that the active account has changed.
|
||||
*/
|
||||
void activeAccountChanged();
|
||||
|
||||
public
|
||||
slots:
|
||||
=======
|
||||
void setListFilePath(QString path, bool autosave = false);
|
||||
|
||||
bool loadList();
|
||||
bool loadV2(QJsonObject &root);
|
||||
bool loadV3(QJsonObject &root);
|
||||
bool saveList();
|
||||
|
||||
MinecraftAccountPtr activeAccount() const;
|
||||
void setActiveAccount(const QString &profileId);
|
||||
bool anyAccountIsValid();
|
||||
|
||||
signals:
|
||||
void listChanged();
|
||||
void activeAccountChanged();
|
||||
|
||||
public slots:
|
||||
>>>>>>> e2355eb276bf355ca4acf526a0f3cc390aa88f8b
|
||||
/**
|
||||
* This is called when one of the accounts changes and the list needs to be updated
|
||||
*/
|
||||
void accountChanged();
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* Called whenever the list changes.
|
||||
* This emits the listChanged() signal and autosaves the list (if autosave is enabled).
|
||||
*/
|
||||
void onListChanged();
|
||||
|
||||
/*!
|
||||
* Called whenever the active account changes.
|
||||
* Emits the activeAccountChanged() signal and autosaves the list if enabled.
|
||||
*/
|
||||
void onActiveChanged();
|
||||
|
||||
QList<AccountPtr> m_accounts;
|
||||
|
||||
/*!
|
||||
* Account that is currently active.
|
||||
*/
|
||||
AccountPtr m_activeAccount;
|
||||
|
||||
//! Path to the account list file. Empty string if there isn't one.
|
||||
QString m_listFilePath;
|
||||
|
||||
/*!
|
||||
* If true, the account list will automatically save to the account list path when it changes.
|
||||
* Ignored if m_listFilePath is blank.
|
||||
*/
|
||||
bool m_autosave = false;
|
||||
|
||||
protected
|
||||
slots:
|
||||
/*!
|
||||
* Updates this list with the given list of accounts.
|
||||
* This is done by copying each account in the given list and inserting it
|
||||
* into this one.
|
||||
* We need to do this so that we can set the parents of the accounts are set to this
|
||||
* account list. This can't be done in the load task, because the accounts the load
|
||||
* task creates are on the load task's thread and Qt won't allow their parents
|
||||
* to be set to something created on another thread.
|
||||
* To get around that problem, we invoke this method on the GUI thread, which
|
||||
* then copies the accounts and sets their parents correctly.
|
||||
* \param accounts List of accounts whose parents should be set.
|
||||
*/
|
||||
virtual void updateListData(QList<AccountPtr> versions);
|
||||
};
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <QTimer>
|
||||
#include <qsslerror.h>
|
||||
|
||||
#include "Account.h"
|
||||
#include "MinecraftAccount.h"
|
||||
|
||||
class QNetworkReply;
|
||||
|
||||
@@ -31,8 +31,8 @@ class AccountTask : public Task
|
||||
friend class AuthContext;
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit YggdrasilTask(Account * account, QObject *parent = 0);
|
||||
virtual ~YggdrasilTask() {};
|
||||
explicit AccountTask(AccountData * data, QObject *parent = 0);
|
||||
virtual ~AccountTask() {};
|
||||
|
||||
/**
|
||||
* assign a session to this task. the session will be filled with required infomration
|
||||
@@ -102,8 +102,7 @@ protected slots:
|
||||
|
||||
protected:
|
||||
// FIXME: segfault disaster waiting to happen
|
||||
Account *m_account = nullptr;
|
||||
QNetworkReply *m_netReply = nullptr;
|
||||
AccountData *m_data = nullptr;
|
||||
std::shared_ptr<Error> m_error;
|
||||
AuthSessionPtr m_session;
|
||||
};
|
||||
|
||||
@@ -40,7 +40,7 @@ struct AuthSession
|
||||
bool auth_server_online = false;
|
||||
// Did the user request online mode?
|
||||
bool wants_online = true;
|
||||
std::shared_ptr<Account> m_accountPtr;
|
||||
std::shared_ptr<MinecraftAccount> m_accountPtr;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<AuthSession> AuthSessionPtr;
|
||||
|
||||
@@ -50,37 +50,27 @@ enum AccountStatus
|
||||
class MinecraftAccount :
|
||||
public QObject,
|
||||
public Usable,
|
||||
public std::enable_shared_from_this<Account>
|
||||
public std::enable_shared_from_this<MinecraftAccount>
|
||||
{
|
||||
Q_OBJECT
|
||||
public: /* construction */
|
||||
//! Do not copy accounts. ever.
|
||||
explicit Account(const Account &other, QObject *parent) = delete;
|
||||
explicit MinecraftAccount(const MinecraftAccount &other, QObject *parent) = delete;
|
||||
|
||||
//! Default constructor
|
||||
explicit Account(QObject *parent = 0) : QObject(parent) {};
|
||||
explicit MinecraftAccount(QObject *parent = 0) : QObject(parent) {};
|
||||
|
||||
//! Creates an empty account for the specified user name.
|
||||
static AccountPtr createFromUsername(const QString &username);
|
||||
static MinecraftAccountPtr createFromUsername(const QString &username);
|
||||
|
||||
//! Loads a Account from the given JSON object.
|
||||
static AccountPtr loadFromJson(const QJsonObject &json);
|
||||
static MinecraftAccountPtr createBlankMSA();
|
||||
|
||||
//! Saves a Account to a JSON object and returns it.
|
||||
static MinecraftAccountPtr loadFromJsonV2(const QJsonObject &json);
|
||||
static MinecraftAccountPtr loadFromJsonV3(const QJsonObject &json);
|
||||
|
||||
//! Saves a MinecraftAccount to a JSON object and returns it.
|
||||
QJsonObject saveToJson() const;
|
||||
|
||||
public: /* manipulation */
|
||||
/**
|
||||
* Overrides the login type on the account.
|
||||
*/
|
||||
bool setProvider(AuthProviderPtr provider);
|
||||
|
||||
/**
|
||||
* Sets the currently selected profile to the profile with the given ID string.
|
||||
* If profileId is not in the list of available profiles, the function will simply return
|
||||
* false.
|
||||
*/
|
||||
bool setCurrentProfile(const QString &profileId);
|
||||
|
||||
/**
|
||||
* Attempt to login. Empty password means we use the token.
|
||||
@@ -93,28 +83,26 @@ public: /* manipulation */
|
||||
std::shared_ptr<AccountTask> refresh(AuthSessionPtr session);
|
||||
|
||||
public: /* queries */
|
||||
const AuthProviderPtr provider() const
|
||||
{
|
||||
return m_provider;
|
||||
QString accountDisplayString() const {
|
||||
return data.accountDisplayString();
|
||||
}
|
||||
|
||||
const QString &username() const
|
||||
{
|
||||
return m_username;
|
||||
QString mojangUserName() const {
|
||||
return data.userName();
|
||||
}
|
||||
|
||||
QString accessToken() const {
|
||||
return data.accessToken();
|
||||
}
|
||||
|
||||
QString profileId() const {
|
||||
return data.profileId();
|
||||
}
|
||||
|
||||
QString profileName() const {
|
||||
return data.profileName();
|
||||
}
|
||||
|
||||
bool canMigrate() const {
|
||||
return data.canMigrateToMSA;
|
||||
}
|
||||
|
||||
bool isMSA() const {
|
||||
return data.type == AccountType::MSA;
|
||||
}
|
||||
|
||||
QString typeString() const {
|
||||
switch(data.type) {
|
||||
case AccountType::Mojang: {
|
||||
@@ -152,29 +140,7 @@ signals:
|
||||
// TODO: better signalling for the various possible state changes - especially errors
|
||||
|
||||
protected: /* variables */
|
||||
// Authentication system used.
|
||||
// Usable values: "mojang", "dummy", "elyby"
|
||||
AuthProviderPtr m_provider;
|
||||
|
||||
// Username taken by account.
|
||||
QString m_username;
|
||||
|
||||
// Used to identify the client - the user can have multiple clients for the same account
|
||||
// Think: different launchers, all connecting to the same account/profile
|
||||
QString m_clientToken;
|
||||
|
||||
// Blank if not logged in.
|
||||
QString m_accessToken;
|
||||
|
||||
// Index of the selected profile within the list of available
|
||||
// profiles. -1 if nothing is selected.
|
||||
int m_currentProfile = -1;
|
||||
|
||||
// List of available profiles.
|
||||
QList<AccountProfile> m_profiles;
|
||||
|
||||
// the user structure, whatever it is.
|
||||
User m_user;
|
||||
AccountData data;
|
||||
|
||||
// current task we are executing here
|
||||
std::shared_ptr<AccountTask> m_currentTask;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <launch/LaunchStep.h>
|
||||
#include <minecraft/auth/Account.h>
|
||||
#include <minecraft/auth/MinecraftAccount.h>
|
||||
|
||||
class ClaimAccount: public LaunchStep
|
||||
{
|
||||
@@ -33,5 +33,5 @@ public:
|
||||
}
|
||||
private:
|
||||
std::unique_ptr<UseLock> lock;
|
||||
AccountPtr m_account;
|
||||
MinecraftAccountPtr m_account;
|
||||
};
|
||||
|
||||
@@ -59,8 +59,6 @@ AccountListPage::AccountListPage(QWidget *parent)
|
||||
ui->listView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
|
||||
// Expand the account column
|
||||
ui->listView->header()->setSectionResizeMode(1, QHeaderView::Stretch);
|
||||
ui->listView->header()->setSectionResizeMode(2, QHeaderView::Stretch);
|
||||
|
||||
QItemSelectionModel *selectionModel = ui->listView->selectionModel();
|
||||
|
||||
@@ -188,9 +186,8 @@ void AccountListPage::on_actionSetDefault_triggered()
|
||||
if (selection.size() > 0)
|
||||
{
|
||||
QModelIndex selected = selection.first();
|
||||
AccountPtr account =
|
||||
selected.data(AccountList::PointerRole).value<AccountPtr>();
|
||||
m_accounts->setActiveAccount(account->username());
|
||||
MinecraftAccountPtr account = selected.data(AccountList::PointerRole).value<MinecraftAccountPtr>();
|
||||
m_accounts->setActiveAccount(account->profileId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,10 +207,6 @@ void AccountListPage::updateButtonStates()
|
||||
ui->actionDeleteSkin->setEnabled(selection.size() > 0);
|
||||
ui->actionRefresh->setEnabled(selection.size() > 0);
|
||||
|
||||
bool enableSkins = selection.size() > 0 && selection.first().data(AccountList::PointerRole).value<AccountPtr>()->provider()->canChangeSkin();
|
||||
ui->actionUploadSkin->setEnabled(enableSkins);
|
||||
ui->actionDeleteSkin->setEnabled(enableSkins);
|
||||
|
||||
if(m_accounts->activeAccount().get() == nullptr) {
|
||||
ui->actionNoDefault->setEnabled(false);
|
||||
ui->actionNoDefault->setChecked(true);
|
||||
@@ -225,39 +218,13 @@ void AccountListPage::updateButtonStates()
|
||||
|
||||
}
|
||||
|
||||
void AccountListPage::addAccount(const QString &errMsg)
|
||||
{
|
||||
// TODO: The login dialog isn't quite done yet
|
||||
AccountPtr account = LoginDialog::newAccount(this, errMsg);
|
||||
|
||||
if (account != nullptr)
|
||||
{
|
||||
m_accounts->addAccount(account);
|
||||
if (m_accounts->count() == 1)
|
||||
m_accounts->setActiveAccount(account->username());
|
||||
|
||||
// Grab associated player skins
|
||||
auto job = new NetJob("Player skins: " + account->username());
|
||||
|
||||
for (AccountProfile profile : account->profiles())
|
||||
{
|
||||
auto meta = Env::getInstance().metacache()->resolveEntry("skins", profile.id + ".png");
|
||||
auto action = Net::Download::makeCached(account->provider()->resolveSkinUrl(profile), meta);
|
||||
job->addNetAction(action);
|
||||
meta->setStale(true);
|
||||
}
|
||||
|
||||
job->start();
|
||||
}
|
||||
}
|
||||
|
||||
void AccountListPage::on_actionUploadSkin_triggered()
|
||||
{
|
||||
QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
|
||||
if (selection.size() > 0)
|
||||
{
|
||||
QModelIndex selected = selection.first();
|
||||
AccountPtr account = selected.data(AccountList::PointerRole).value<AccountPtr>();
|
||||
MinecraftAccountPtr account = selected.data(AccountList::PointerRole).value<MinecraftAccountPtr>();
|
||||
SkinUploadDialog dialog(account, this);
|
||||
dialog.exec();
|
||||
}
|
||||
@@ -271,8 +238,8 @@ void AccountListPage::on_actionDeleteSkin_triggered()
|
||||
|
||||
QModelIndex selected = selection.first();
|
||||
AuthSessionPtr session = std::make_shared<AuthSession>();
|
||||
AccountPtr account = selected.data(AccountList::PointerRole).value<AccountPtr>();
|
||||
auto login = account->login(session);
|
||||
MinecraftAccountPtr account = selected.data(AccountList::PointerRole).value<MinecraftAccountPtr>();
|
||||
auto login = account->refresh(session);
|
||||
ProgressDialog prog(this);
|
||||
if (prog.execWithTask((Task*)login.get()) != QDialog::Accepted) {
|
||||
CustomMessageBox::selectable(this, tr("Skin Delete"), tr("Failed to login!"), QMessageBox::Warning)->exec();
|
||||
|
||||
Reference in New Issue
Block a user