aboutsummaryrefslogtreecommitdiff
path: root/launcher
diff options
context:
space:
mode:
authorTrial97 <alexandru.tripon97@gmail.com>2023-09-25 17:44:04 +0300
committerTrial97 <alexandru.tripon97@gmail.com>2023-09-25 17:44:04 +0300
commit7c636d46080443357d10471b00406c549687ee11 (patch)
tree10366421bc325d5073e882a9899d108ef5f0d8a8 /launcher
parentad9fb7349f8724651e109f95b2ce1d44ba274aa9 (diff)
downloadPrismLauncher-7c636d46080443357d10471b00406c549687ee11.tar.gz
PrismLauncher-7c636d46080443357d10471b00406c549687ee11.tar.bz2
PrismLauncher-7c636d46080443357d10471b00406c549687ee11.zip
Removed mojang
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
Diffstat (limited to 'launcher')
-rw-r--r--launcher/CMakeLists.txt13
-rw-r--r--launcher/minecraft/MinecraftInstance.cpp3
-rw-r--r--launcher/minecraft/auth/AccountData.cpp121
-rw-r--r--launcher/minecraft/auth/AccountData.h14
-rw-r--r--launcher/minecraft/auth/AccountList.cpp50
-rw-r--r--launcher/minecraft/auth/AccountList.h2
-rw-r--r--launcher/minecraft/auth/AuthSession.h4
-rw-r--r--launcher/minecraft/auth/MinecraftAccount.cpp40
-rw-r--r--launcher/minecraft/auth/MinecraftAccount.h19
-rw-r--r--launcher/minecraft/auth/Yggdrasil.cpp342
-rw-r--r--launcher/minecraft/auth/Yggdrasil.h92
-rw-r--r--launcher/minecraft/auth/flows/AuthFlow.h1
-rw-r--r--launcher/minecraft/auth/flows/Mojang.cpp22
-rw-r--r--launcher/minecraft/auth/flows/Mojang.h17
-rw-r--r--launcher/minecraft/auth/steps/MigrationEligibilityStep.cpp45
-rw-r--r--launcher/minecraft/auth/steps/MigrationEligibilityStep.h21
-rw-r--r--launcher/minecraft/auth/steps/MinecraftProfileStep.cpp9
-rw-r--r--launcher/minecraft/auth/steps/MinecraftProfileStepMojang.cpp87
-rw-r--r--launcher/minecraft/auth/steps/MinecraftProfileStepMojang.h21
-rw-r--r--launcher/minecraft/auth/steps/YggdrasilStep.cpp57
-rw-r--r--launcher/minecraft/auth/steps/YggdrasilStep.h28
-rw-r--r--launcher/ui/dialogs/LoginDialog.cpp115
-rw-r--r--launcher/ui/dialogs/LoginDialog.h56
-rw-r--r--launcher/ui/dialogs/LoginDialog.ui77
-rw-r--r--launcher/ui/pages/global/AccountListPage.cpp18
-rw-r--r--launcher/ui/pages/global/AccountListPage.h1
-rw-r--r--launcher/ui/pages/global/AccountListPage.ui6
27 files changed, 5 insertions, 1276 deletions
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index 18e0acab..de750afd 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -216,13 +216,9 @@ set(MINECRAFT_SOURCES
minecraft/auth/MinecraftAccount.h
minecraft/auth/Parsers.cpp
minecraft/auth/Parsers.h
- minecraft/auth/Yggdrasil.cpp
- minecraft/auth/Yggdrasil.h
minecraft/auth/flows/AuthFlow.cpp
minecraft/auth/flows/AuthFlow.h
- minecraft/auth/flows/Mojang.cpp
- minecraft/auth/flows/Mojang.h
minecraft/auth/flows/MSA.cpp
minecraft/auth/flows/MSA.h
minecraft/auth/flows/Offline.cpp
@@ -236,12 +232,8 @@ set(MINECRAFT_SOURCES
minecraft/auth/steps/GetSkinStep.h
minecraft/auth/steps/LauncherLoginStep.cpp
minecraft/auth/steps/LauncherLoginStep.h
- minecraft/auth/steps/MigrationEligibilityStep.cpp
- minecraft/auth/steps/MigrationEligibilityStep.h
minecraft/auth/steps/MinecraftProfileStep.cpp
minecraft/auth/steps/MinecraftProfileStep.h
- minecraft/auth/steps/MinecraftProfileStepMojang.cpp
- minecraft/auth/steps/MinecraftProfileStepMojang.h
minecraft/auth/steps/MSAStep.cpp
minecraft/auth/steps/MSAStep.h
minecraft/auth/steps/XboxAuthorizationStep.cpp
@@ -250,8 +242,6 @@ set(MINECRAFT_SOURCES
minecraft/auth/steps/XboxProfileStep.h
minecraft/auth/steps/XboxUserStep.cpp
minecraft/auth/steps/XboxUserStep.h
- minecraft/auth/steps/YggdrasilStep.cpp
- minecraft/auth/steps/YggdrasilStep.h
minecraft/gameoptions/GameOptions.h
minecraft/gameoptions/GameOptions.cpp
@@ -944,8 +934,6 @@ SET(LAUNCHER_SOURCES
ui/dialogs/IconPickerDialog.h
ui/dialogs/ImportResourceDialog.cpp
ui/dialogs/ImportResourceDialog.h
- ui/dialogs/LoginDialog.cpp
- ui/dialogs/LoginDialog.h
ui/dialogs/MSALoginDialog.cpp
ui/dialogs/MSALoginDialog.h
ui/dialogs/OfflineLoginDialog.cpp
@@ -1104,7 +1092,6 @@ qt_wrap_ui(LAUNCHER_UI
ui/dialogs/MSALoginDialog.ui
ui/dialogs/OfflineLoginDialog.ui
ui/dialogs/AboutDialog.ui
- ui/dialogs/LoginDialog.ui
ui/dialogs/EditAccountDialog.ui
ui/dialogs/ReviewMessageBox.ui
ui/dialogs/ScrollMessageBox.ui
diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp
index 0e64c46d..57bbcd40 100644
--- a/launcher/minecraft/MinecraftInstance.cpp
+++ b/launcher/minecraft/MinecraftInstance.cpp
@@ -856,9 +856,6 @@ QMap<QString, QString> MinecraftInstance::createCensorFilterFromSession(AuthSess
if (sessionRef.access_token != "0") {
addToFilter(sessionRef.access_token, tr("<ACCESS TOKEN>"));
}
- if (sessionRef.client_token.size()) {
- addToFilter(sessionRef.client_token, tr("<CLIENT TOKEN>"));
- }
addToFilter(sessionRef.uuid, tr("<PROFILE ID>"));
return filter;
diff --git a/launcher/minecraft/auth/AccountData.cpp b/launcher/minecraft/auth/AccountData.cpp
index 474bf7c6..e1f1e9b1 100644
--- a/launcher/minecraft/auth/AccountData.cpp
+++ b/launcher/minecraft/auth/AccountData.cpp
@@ -278,67 +278,6 @@ bool entitlementFromJSONV3(const QJsonObject& parent, MinecraftEntitlement& out)
} // namespace
-bool AccountData::resumeStateFromV2(QJsonObject data)
-{
- // The JSON object must at least have a username for it to be valid.
- if (!data.value("username").isString()) {
- qCritical() << "Can't load Mojang account info from JSON object. Username field is missing or of the wrong type.";
- return false;
- }
-
- QString userName = data.value("username").toString("");
- QString clientToken = data.value("clientToken").toString("");
- QString accessToken = data.value("accessToken").toString("");
-
- QJsonArray profileArray = data.value("profiles").toArray();
- if (profileArray.size() < 1) {
- qCritical() << "Can't load Mojang account with username \"" << userName << "\". No profiles found.";
- return false;
- }
-
- struct AccountProfile {
- QString id;
- QString name;
- bool legacy;
- };
-
- QList<AccountProfile> profiles;
- int currentProfileIndex = 0;
- int index = -1;
- QString currentProfile = data.value("activeProfile").toString("");
- for (QJsonValue profileVal : profileArray) {
- index++;
- 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" << name << "because it was missing an ID or a name.";
- continue;
- }
- if (id == currentProfile) {
- currentProfileIndex = index;
- }
- profiles.append({ id, name, legacy_ });
- }
- auto& profile = profiles[currentProfileIndex];
-
- type = AccountType::Mojang;
- legacy = profile.legacy;
-
- minecraftProfile.id = profile.id;
- minecraftProfile.name = profile.name;
- minecraftProfile.validity = Katabasis::Validity::Assumed;
-
- yggdrasilToken.token = accessToken;
- yggdrasilToken.extra["clientToken"] = clientToken;
- yggdrasilToken.extra["userName"] = userName;
- yggdrasilToken.validity = Katabasis::Validity::Assumed;
-
- validity_ = minecraftProfile.validity;
- return true;
-}
-
bool AccountData::resumeStateFromV3(QJsonObject data)
{
auto typeV = data.value("type");
@@ -349,8 +288,6 @@ bool AccountData::resumeStateFromV3(QJsonObject data)
auto typeS = typeV.toString();
if (typeS == "MSA") {
type = AccountType::MSA;
- } else if (typeS == "Mojang") {
- type = AccountType::Mojang;
} else if (typeS == "Offline") {
type = AccountType::Offline;
} else {
@@ -358,11 +295,6 @@ bool AccountData::resumeStateFromV3(QJsonObject data)
return false;
}
- if (type == AccountType::Mojang) {
- legacy = data.value("legacy").toBool(false);
- canMigrateToMSA = data.value("canMigrateToMSA").toBool(false);
- }
-
if (type == AccountType::MSA) {
auto clientIDV = data.value("msa-client-id");
if (clientIDV.isString()) {
@@ -395,15 +327,7 @@ bool AccountData::resumeStateFromV3(QJsonObject data)
QJsonObject AccountData::saveState() const
{
QJsonObject output;
- if (type == AccountType::Mojang) {
- output["type"] = "Mojang";
- if (legacy) {
- output["legacy"] = true;
- }
- if (canMigrateToMSA) {
- output["canMigrateToMSA"] = true;
- }
- } else if (type == AccountType::MSA) {
+ if (type == AccountType::MSA) {
output["type"] = "MSA";
output["msa-client-id"] = msaClientID;
tokenToJSONV3(output, msaToken, "msa");
@@ -420,51 +344,11 @@ QJsonObject AccountData::saveState() const
return output;
}
-QString AccountData::userName() const
-{
- if (type == AccountType::MSA) {
- return QString();
- }
- return yggdrasilToken.extra["userName"].toString();
-}
-
QString AccountData::accessToken() const
{
return yggdrasilToken.token;
}
-QString AccountData::clientToken() const
-{
- if (type != AccountType::Mojang) {
- return QString();
- }
- return yggdrasilToken.extra["clientToken"].toString();
-}
-
-void AccountData::setClientToken(QString clientToken)
-{
- if (type != AccountType::Mojang) {
- return;
- }
- yggdrasilToken.extra["clientToken"] = clientToken;
-}
-
-void AccountData::generateClientTokenIfMissing()
-{
- if (yggdrasilToken.extra.contains("clientToken")) {
- return;
- }
- invalidateClientToken();
-}
-
-void AccountData::invalidateClientToken()
-{
- if (type != AccountType::Mojang) {
- return;
- }
- yggdrasilToken.extra["clientToken"] = QUuid::createUuid().toString().remove(QRegularExpression("[{-}]"));
-}
-
QString AccountData::profileId() const
{
return minecraftProfile.id;
@@ -482,9 +366,6 @@ QString AccountData::profileName() const
QString AccountData::accountDisplayString() const
{
switch (type) {
- case AccountType::Mojang: {
- return userName();
- }
case AccountType::Offline: {
return QObject::tr("<Offline>");
}
diff --git a/launcher/minecraft/auth/AccountData.h b/launcher/minecraft/auth/AccountData.h
index 9b626c34..bac77e17 100644
--- a/launcher/minecraft/auth/AccountData.h
+++ b/launcher/minecraft/auth/AccountData.h
@@ -71,27 +71,17 @@ struct MinecraftProfile {
Katabasis::Validity validity = Katabasis::Validity::None;
};
-enum class AccountType { MSA, Mojang, Offline };
+enum class AccountType { MSA, Offline };
enum class AccountState { Unchecked, Offline, Working, Online, Disabled, Errored, Expired, Gone };
struct AccountData {
QJsonObject saveState() const;
- bool resumeStateFromV2(QJsonObject data);
bool resumeStateFromV3(QJsonObject data);
//! userName for Mojang accounts, gamertag for MSA
QString accountDisplayString() const;
- //! Only valid for Mojang accounts. MSA does not preserve this information
- QString userName() const;
-
- //! Only valid for Mojang accounts.
- QString clientToken() const;
- void setClientToken(QString clientToken);
- void invalidateClientToken();
- void generateClientTokenIfMissing();
-
//! Yggdrasil access token, as passed to the game.
QString accessToken() const;
@@ -101,8 +91,6 @@ struct AccountData {
QString lastError() const;
AccountType type = AccountType::MSA;
- bool legacy = false;
- bool canMigrateToMSA = false;
QString msaClientID;
Katabasis::Token msaToken;
diff --git a/launcher/minecraft/auth/AccountList.cpp b/launcher/minecraft/auth/AccountList.cpp
index 84dbd841..a29de4ec 100644
--- a/launcher/minecraft/auth/AccountList.cpp
+++ b/launcher/minecraft/auth/AccountList.cpp
@@ -54,7 +54,7 @@
#include <chrono>
-enum AccountListVersion { MojangOnly = 2, MojangMSA = 3 };
+enum AccountListVersion { MojangMSA = 3 };
AccountList::AccountList(QObject* parent) : QAbstractListModel(parent)
{
@@ -320,17 +320,6 @@ QVariant AccountList::data(const QModelIndex& index, int role) const
}
}
- case MigrationColumn: {
- if (account->isMSA() || account->isOffline()) {
- return tr("N/A", "Can Migrate");
- }
- if (account->canMigrate()) {
- return tr("Yes", "Can Migrate");
- } else {
- return tr("No", "Can Migrate");
- }
- }
-
default:
return QVariant();
}
@@ -366,8 +355,6 @@ QVariant AccountList::headerData(int section, [[maybe_unused]] Qt::Orientation o
return tr("Type");
case StatusColumn:
return tr("Status");
- case MigrationColumn:
- return tr("Can Migrate?");
default:
return QVariant();
}
@@ -382,8 +369,6 @@ QVariant AccountList::headerData(int section, [[maybe_unused]] Qt::Orientation o
return tr("Type of the account - Mojang or MSA.");
case StatusColumn:
return tr("Current status of the account.");
- case MigrationColumn:
- return tr("Can this account migrate to a Microsoft account?");
default:
return QVariant();
}
@@ -473,9 +458,6 @@ bool AccountList::loadList()
// Make sure the format version matches.
auto listVersion = root.value("formatVersion").toVariant().toInt();
switch (listVersion) {
- case AccountListVersion::MojangOnly: {
- return loadV2(root);
- } break;
case AccountListVersion::MojangMSA: {
return loadV3(root);
} break;
@@ -489,36 +471,6 @@ bool AccountList::loadList()
}
}
-bool AccountList::loadV2(QJsonObject& root)
-{
- beginResetModel();
- auto defaultUserName = root.value("activeAccount").toString("");
- QJsonArray accounts = root.value("accounts").toArray();
- for (QJsonValue accountVal : accounts) {
- QJsonObject accountObj = accountVal.toObject();
- MinecraftAccountPtr account = MinecraftAccount::loadFromJsonV2(accountObj);
- if (account.get() != nullptr) {
- auto profileId = account->profileId();
- if (!profileId.size()) {
- continue;
- }
- if (findAccountByProfileId(profileId) != -1) {
- continue;
- }
- connect(account.get(), &MinecraftAccount::changed, this, &AccountList::accountChanged);
- connect(account.get(), &MinecraftAccount::activityChanged, this, &AccountList::accountActivityChanged);
- m_accounts.append(account);
- if (defaultUserName.size() && account->mojangUserName() == defaultUserName) {
- m_defaultAccount = account;
- }
- } else {
- qWarning() << "Failed to load an account.";
- }
- }
- endResetModel();
- return true;
-}
-
bool AccountList::loadV3(QJsonObject& root)
{
beginResetModel();
diff --git a/launcher/minecraft/auth/AccountList.h b/launcher/minecraft/auth/AccountList.h
index 6a0b0191..051d8f95 100644
--- a/launcher/minecraft/auth/AccountList.h
+++ b/launcher/minecraft/auth/AccountList.h
@@ -55,7 +55,6 @@ class AccountList : public QAbstractListModel {
// TODO: Add icon column.
ProfileNameColumn = 0,
NameColumn,
- MigrationColumn,
TypeColumn,
StatusColumn,
@@ -97,7 +96,6 @@ class AccountList : public QAbstractListModel {
void setListFilePath(QString path, bool autosave = false);
bool loadList();
- bool loadV2(QJsonObject& root);
bool loadV3(QJsonObject& root);
bool saveList();
diff --git a/launcher/minecraft/auth/AuthSession.h b/launcher/minecraft/auth/AuthSession.h
index 40519476..074b2d6e 100644
--- a/launcher/minecraft/auth/AuthSession.h
+++ b/launcher/minecraft/auth/AuthSession.h
@@ -24,10 +24,6 @@ struct AuthSession {
GoneOrMigrated
} status = Undetermined;
- // client token
- QString client_token;
- // account user name
- QString username;
// combined session ID
QString session;
// volatile auth token
diff --git a/launcher/minecraft/auth/MinecraftAccount.cpp b/launcher/minecraft/auth/MinecraftAccount.cpp
index 6c2f0805..545d06ae 100644
--- a/launcher/minecraft/auth/MinecraftAccount.cpp
+++ b/launcher/minecraft/auth/MinecraftAccount.cpp
@@ -51,7 +51,6 @@
#include <QPainter>
#include "flows/MSA.h"
-#include "flows/Mojang.h"
#include "flows/Offline.h"
MinecraftAccount::MinecraftAccount(QObject* parent) : QObject(parent)
@@ -59,15 +58,6 @@ MinecraftAccount::MinecraftAccount(QObject* parent) : QObject(parent)
data.internalId = QUuid::createUuid().toString().remove(QRegularExpression("[{}-]"));
}
-MinecraftAccountPtr MinecraftAccount::loadFromJsonV2(const QJsonObject& json)
-{
- MinecraftAccountPtr account(new MinecraftAccount());
- if (account->data.resumeStateFromV2(json)) {
- return account;
- }
- return nullptr;
-}
-
MinecraftAccountPtr MinecraftAccount::loadFromJsonV3(const QJsonObject& json)
{
MinecraftAccountPtr account(new MinecraftAccount());
@@ -77,15 +67,6 @@ MinecraftAccountPtr MinecraftAccount::loadFromJsonV3(const QJsonObject& json)
return nullptr;
}
-MinecraftAccountPtr MinecraftAccount::createFromUsername(const QString& username)
-{
- auto account = makeShared<MinecraftAccount>();
- account->data.type = AccountType::Mojang;
- account->data.yggdrasilToken.extra["userName"] = username;
- account->data.yggdrasilToken.extra["clientToken"] = QUuid::createUuid().toString().remove(QRegularExpression("[{}-]"));
- return account;
-}
-
MinecraftAccountPtr MinecraftAccount::createBlankMSA()
{
MinecraftAccountPtr account(new MinecraftAccount());
@@ -138,18 +119,6 @@ QPixmap MinecraftAccount::getFace() const
return skin.scaled(64, 64, Qt::KeepAspectRatio);
}
-shared_qobject_ptr<AccountTask> MinecraftAccount::login(QString password)
-{
- Q_ASSERT(m_currentTask.get() == nullptr);
-
- m_currentTask.reset(new MojangLogin(&data, password));
- connect(m_currentTask.get(), &Task::succeeded, this, &MinecraftAccount::authSucceeded);
- connect(m_currentTask.get(), &Task::failed, this, &MinecraftAccount::authFailed);
- connect(m_currentTask.get(), &Task::aborted, this, [this] { authFailed(tr("Aborted")); });
- emit activityChanged(true);
- return m_currentTask;
-}
-
shared_qobject_ptr<AccountTask> MinecraftAccount::loginMSA()
{
Q_ASSERT(m_currentTask.get() == nullptr);
@@ -182,10 +151,8 @@ shared_qobject_ptr<AccountTask> MinecraftAccount::refresh()
if (data.type == AccountType::MSA) {
m_currentTask.reset(new MSASilent(&data));
- } else if (data.type == AccountType::Offline) {
- m_currentTask.reset(new OfflineRefresh(&data));
} else {
- m_currentTask.reset(new MojangRefresh(&data));
+ m_currentTask.reset(new OfflineRefresh(&data));
}
connect(m_currentTask.get(), &Task::succeeded, this, &MinecraftAccount::authSucceeded);
@@ -296,13 +263,8 @@ void MinecraftAccount::fillSession(AuthSessionPtr session)
}
}
- // the user name. you have to have an user name
- // FIXME: not with MSA
- session->username = data.userName();
// volatile auth token
session->access_token = data.accessToken();
- // the semi-permanent client token
- session->client_token = data.clientToken();
// profile name
session->player_name = data.profileName();
// profile ID
diff --git a/launcher/minecraft/auth/MinecraftAccount.h b/launcher/minecraft/auth/MinecraftAccount.h
index f04f947f..910f4a28 100644
--- a/launcher/minecraft/auth/MinecraftAccount.h
+++ b/launcher/minecraft/auth/MinecraftAccount.h
@@ -85,13 +85,10 @@ class MinecraftAccount : public QObject, public Usable {
//! Default constructor
explicit MinecraftAccount(QObject* parent = 0);
- static MinecraftAccountPtr createFromUsername(const QString& username);
-
static MinecraftAccountPtr createBlankMSA();
static MinecraftAccountPtr createOffline(const QString& username);
- static MinecraftAccountPtr loadFromJsonV2(const QJsonObject& json);
static MinecraftAccountPtr loadFromJsonV3(const QJsonObject& json);
static QUuid uuidFromUsername(QString username);
@@ -100,12 +97,6 @@ class MinecraftAccount : public QObject, public Usable {
QJsonObject saveToJson() const;
public: /* manipulation */
- /**
- * Attempt to login. Empty password means we use the token.
- * If the attempt fails because we already are performing some task, it returns false.
- */
- shared_qobject_ptr<AccountTask> login(QString password);
-
shared_qobject_ptr<AccountTask> loginMSA();
shared_qobject_ptr<AccountTask> loginOffline();
@@ -119,8 +110,6 @@ class MinecraftAccount : public QObject, public Usable {
QString accountDisplayString() const { return data.accountDisplayString(); }
- QString mojangUserName() const { return data.userName(); }
-
QString accessToken() const { return data.accessToken(); }
QString profileId() const { return data.profileId(); }
@@ -129,8 +118,6 @@ class MinecraftAccount : public QObject, public Usable {
bool isActive() const;
- bool canMigrate() const { return data.canMigrateToMSA; }
-
bool isMSA() const { return data.type == AccountType::MSA; }
bool isOffline() const { return data.type == AccountType::Offline; }
@@ -142,12 +129,6 @@ class MinecraftAccount : public QObject, public Usable {
QString typeString() const
{
switch (data.type) {
- case AccountType::Mojang: {
- if (data.legacy) {
- return "legacy";
- }
- return "mojang";
- } break;
case AccountType::MSA: {
return "msa";
} break;
diff --git a/launcher/minecraft/auth/Yggdrasil.cpp b/launcher/minecraft/auth/Yggdrasil.cpp
deleted file mode 100644
index 97f2a78d..00000000
--- a/launcher/minecraft/auth/Yggdrasil.cpp
+++ /dev/null
@@ -1,342 +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.
- */
-
-#include "Yggdrasil.h"
-#include "AccountData.h"
-
-#include <QByteArray>
-#include <QJsonDocument>
-#include <QJsonObject>
-#include <QNetworkReply>
-#include <QObject>
-#include <QString>
-
-#include <QDebug>
-
-#include "Application.h"
-
-Yggdrasil::Yggdrasil(AccountData* data, QObject* parent) : AccountTask(data, parent)
-{
- changeState(AccountTaskState::STATE_CREATED);
-}
-
-void Yggdrasil::sendRequest(QUrl endpoint, QByteArray content)
-{
- changeState(AccountTaskState::STATE_WORKING);
-
- QNetworkRequest netRequest(endpoint);
- netRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
- m_netReply = APPLICATION->network()->post(netRequest, content);
- connect(m_netReply, &QNetworkReply::finished, this, &Yggdrasil::processReply);
- connect(m_netReply, &QNetworkReply::uploadProgress, this, &Yggdrasil::refreshTimers);
- connect(m_netReply, &QNetworkReply::downloadProgress, this, &Yggdrasil::refreshTimers);
- connect(m_netReply, &QNetworkReply::sslErrors, this, &Yggdrasil::sslErrors);
- timeout_keeper.setSingleShot(true);
- timeout_keeper.start(timeout_max);
- counter.setSingleShot(false);
- counter.start(time_step);
- progress(0, timeout_max);
- connect(&timeout_keeper, &QTimer::timeout, this, &Yggdrasil::abortByTimeout);
- connect(&counter, &QTimer::timeout, this, &Yggdrasil::heartbeat);
-}
-
-void Yggdrasil::executeTask() {}
-
-void Yggdrasil::refresh()
-{
- start();
- /*
- * {
- * "clientToken": "client identifier"
- * "accessToken": "current access token to be refreshed"
- * "selectedProfile": // specifying this causes errors
- * {
- * "id": "profile ID"
- * "name": "profile name"
- * }
- * "requestUser": true/false // request the user structure
- * }
- */
- QJsonObject req;
- req.insert("clientToken", m_data->clientToken());
- req.insert("accessToken", m_data->accessToken());
- /*
- {
- auto currentProfile = m_account->currentProfile();
- QJsonObject profile;
- profile.insert("id", currentProfile->id());
- profile.insert("name", currentProfile->name());
- req.insert("selectedProfile", profile);
- }
- */
- req.insert("requestUser", false);
- QJsonDocument doc(req);
-
- QUrl reqUrl("https://authserver.mojang.com/refresh");
- QByteArray requestData = doc.toJson();
-
- sendRequest(reqUrl, requestData);
-}
-
-void Yggdrasil::login(QString password)
-{
- start();
- /*
- * {
- * "agent": { // optional
- * "name": "Minecraft", // So far this is the only encountered value
- * "version": 1 // This number might be increased
- * // by the vanilla client in the future
- * },
- * "username": "mojang account name", // Can be an email address or player name for
- * // unmigrated accounts
- * "password": "mojang account password",
- * "clientToken": "client identifier", // optional
- * "requestUser": true/false // request the user structure
- * }
- */
- QJsonObject req;
-
- {
- QJsonObject agent;
- // C++ makes string literals void* for some stupid reason, so we have to tell it
- // QString... Thanks Obama.
- agent.insert("name", QString("Minecraft"));
- agent.insert("version", 1);
- req.insert("agent", agent);
- }
-
- req.insert("username", m_data->userName());
- req.insert("password", password);
- req.insert("requestUser", false);
-
- // If we already have a client token, give it to the server.
- // Otherwise, let the server give us one.
-
- m_data->generateClientTokenIfMissing();
- req.insert("clientToken", m_data->clientToken());
-
- QJsonDocument doc(req);
-
- QUrl reqUrl("https://authserver.mojang.com/authenticate");
- QNetworkRequest netRequest(reqUrl);
- QByteArray requestData = doc.toJson();
-
- sendRequest(reqUrl, requestData);
-}
-
-void Yggdrasil::refreshTimers(qint64, qint64)
-{
- timeout_keeper.stop();
- timeout_keeper.start(timeout_max);
- progress(count = 0, timeout_max);
-}
-
-void Yggdrasil::heartbeat()
-{
- count += time_step;
- progress(count, timeout_max);
-}
-
-bool Yggdrasil::abort()
-{
- progress(timeout_max, timeout_max);
- // TODO: actually use this in a meaningful way
- m_aborted = Yggdrasil::BY_USER;
- m_netReply->abort();
- return true;
-}
-
-void Yggdrasil::abortByTimeout()
-{
- progress(timeout_max, timeout_max);
- // TODO: actually use this in a meaningful way
- m_aborted = Yggdrasil::BY_TIMEOUT;
- m_netReply->abort();
-}
-
-void Yggdrasil::sslErrors(QList<QSslError> errors)
-{
- int i = 1;
- for (auto error : errors) {
- qCritical() << "LOGIN SSL Error #" << i << " : " << error.errorString();
- auto cert = error.certificate();
- qCritical() << "Certificate in question:\n" << cert.toText();
- i++;
- }
-}
-
-void Yggdrasil::processResponse(QJsonObject responseData)
-{
- // Read the response data. We need to get the client token, access token, and the selected
- // profile.
- qDebug() << "Processing authentication response.";
-
- // qDebug() << responseData;
- // If we already have a client token, make sure the one the server gave us matches our
- // existing one.
- QString clientToken = responseData.value("clientToken").toString("");
- if (clientToken.isEmpty()) {
- // Fail if the server gave us an empty client token
- changeState(AccountTaskState::STATE_FAILED_HARD, tr("Authentication server didn't send a client token."));
- return;
- }
- if (m_data->clientToken().isEmpty()) {
- m_data->setClientToken(clientToken);
- } else if (clientToken != m_data->clientToken()) {
- changeState(AccountTaskState::STATE_FAILED_HARD,
- tr("Authentication server attempted to change the client token. This isn't supported."));
- return;
- }
-
- // Now, we set the access token.
- qDebug() << "Getting access token.";
- QString accessToken = responseData.value("accessToken").toString("");
- if (accessToken.isEmpty()) {
- // Fail if the server didn't give us an access token.
- changeState(AccountTaskState::STATE_FAILED_HARD, tr("Authentication server didn't send an access token."));
- return;
- }
- // Set the access token.
- m_data->yggdrasilToken.token = accessToken;
- m_data->yggdrasilToken.validity = Katabasis::Validity::Certain;
- m_data->yggdrasilToken.issueInstant = QDateTime::currentDateTimeUtc();
-
- // Get UUID here since we need it for later
- auto profile = responseData.value("selectedProfile");
- if (!profile.isObject()) {
- changeState(AccountTaskState::STATE_FAILED_HARD, tr("Authentication server didn't send a selected profile."));
- return;
- }
-
- auto profileObj = profile.toObject();
- for (auto i = profileObj.constBegin(); i != profileObj.constEnd(); ++i) {
- if (i.key() == "name" && i.value().isString()) {
- m_data->minecraftProfile.name = i->toString();
- } else if (i.key() == "id" && i.value().isString()) {
- m_data->minecraftProfile.id = i->toString();
- }
- }
-
- if (m_data->minecraftProfile.id.isEmpty()) {
- changeState(AccountTaskState::STATE_FAILED_HARD, tr("Authentication server didn't send a UUID in selected profile."));
- return;
- }
-
- // We've made it through the minefield of possible errors. Return true to indicate that
- // we've succeeded.
- qDebug() << "Finished reading authentication response.";
- changeState(AccountTaskState::STATE_SUCCEEDED);
-}
-
-void Yggdrasil::processReply()
-{
- changeState(AccountTaskState::STATE_WORKING);
-
- switch (m_netReply->error()) {
- case QNetworkReply::NoError:
- break;
- case QNetworkReply::TimeoutError:
- changeState(AccountTaskState::STATE_FAILED_SOFT, tr("Authentication operation timed out."));
- return;
- case QNetworkReply::OperationCanceledError:
- changeState(AccountTaskState::STATE_FAILED_SOFT, tr("Authentication operation cancelled."));
- return;
- case QNetworkReply::SslHandshakeFailedError:
- changeState(AccountTaskState::STATE_FAILED_SOFT,
- tr("<b>SSL Handshake failed.</b><br/>There might be a few causes for it:<br/>"
- "<ul>"
- "<li>You use Windows and need to update your root certificates, please install any outstanding updates.</li>"
- "<li>Some device on your network is interfering with SSL traffic. In that case, "
- "you have bigger worries than Minecraft not starting.</li>"
- "<li>Possibly something else. Check the log file for details</li>"
- "</ul>"));
- return;
- // used for invalid credentials and similar errors. Fall through.
- case QNetworkReply::ContentAccessDenied:
- case QNetworkReply::ContentOperationNotPermittedError:
- break;
- case QNetworkReply::ContentGoneError: {
- changeState(AccountTaskState::STATE_FAILED_GONE,
- tr("The Mojang account no longer exists. It may have been migrated to a Microsoft account."));
- return;
- }
- default:
- changeState(AccountTaskState::STATE_FAILED_SOFT, tr("Authentication operation failed due to a network error: %1 (%2)")
- .arg(m_netReply->errorString())
- .arg(m_netReply->error()));
- return;
- }
-
- // Try to parse the response regardless of the response code.
- // Sometimes the auth server will give more information and an error code.
- QJsonParseError jsonError;
- QByteArray replyData = m_netReply->readAll();
- QJsonDocument doc = QJsonDocument::fromJson(replyData, &jsonError);
- // Check the response code.
- int responseCode = m_netReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
-
- if (responseCode == 200) {
- // If the response code was 200, then there shouldn't be an error. Make sure
- // anyways.
- // Also, sometimes an empty reply indicates success. If there was no data received,
- // pass an empty json object to the processResponse function.
- if (jsonError.error == QJsonParseError::NoError || replyData.size() == 0) {
- processResponse(replyData.size() > 0 ? doc.object() : QJsonObject());
- return;
- } else {
- changeState(AccountTaskState::STATE_FAILED_SOFT,
- tr("Failed to parse authentication server response JSON response: %1 at offset %2.")
- .arg(jsonError.errorString())
- .arg(jsonError.offset));
- qCritical() << replyData;
- }
- return;
- }
-
- // If the response code was not 200, then Yggdrasil may have given us information
- // about the error.
- // If we can parse the response, then get information from it. Otherwise just say
- // there was an unknown error.
- if (jsonError.error == QJsonParseError::NoError) {
- // We were able to parse the server's response. Woo!
- // Call processError. If a subclass has overridden it then they'll handle their
- // stuff there.
- qDebug() << "The request failed, but the server gave us an error message. Processing error.";
- processError(doc.object());
- } else {
- // The server didn't say anything regarding the error. Give the user an unknown
- // error.
- qDebug() << "The request failed and the server gave no error message. Unknown error.";
- changeState(
- AccountTaskState::STATE_FAILED_SOFT,
- tr("An unknown error occurred when trying to communicate with the authentication server: %1").arg(m_netReply->errorString()));
- }
-}
-
-void Yggdrasil::processError(QJsonObject responseData)
-{
- QJsonValue errorVal = responseData.value("error");
- QJsonValue errorMessageValue = responseData.value("errorMessage");
- QJsonValue causeVal = responseData.value("cause");
-
- if (errorVal.isString() && errorMessageValue.isString()) {
- m_error = std::shared_ptr<Error>(new Error{ errorVal.toString(""), errorMessageValue.toString(""), causeVal.toString("") });
- changeState(AccountTaskState::STATE_FAILED_HARD, m_error->m_errorMessageVerbose);
- } else {
- // Error is not in standard format. Don't set m_error and return unknown error.
- changeState(AccountTaskState::STATE_FAILED_HARD, tr("An unknown Yggdrasil error occurred."));
- }
-}
diff --git a/launcher/minecraft/auth/Yggdrasil.h b/launcher/minecraft/auth/Yggdrasil.h
deleted file mode 100644
index 560d7fb8..00000000
--- a/launcher/minecraft/auth/Yggdrasil.h
+++ /dev/null
@@ -1,92 +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 "AccountTask.h"
-
-#include <qsslerror.h>
-#include <QJsonObject>
-#include <QString>
-#include <QTimer>
-
-#include "MinecraftAccount.h"
-
-class QNetworkAccessManager;
-class QNetworkReply;
-
-/**
- * A Yggdrasil task is a task that performs an operation on a given mojang account.
- */
-class Yggdrasil : public AccountTask {
- Q_OBJECT
- public:
- explicit Yggdrasil(AccountData* data, QObject* parent = 0);
- virtual ~Yggdrasil() = default;
-
- void refresh();
- void login(QString password);
-
- struct Error {
- QString m_errorMessageShort;
- QString m_errorMessageVerbose;
- QString m_cause;
- };
- std::shared_ptr<Error> m_error;
-
- enum AbortedBy { BY_NOTHING, BY_USER, BY_TIMEOUT } m_aborted = BY_NOTHING;
-
- protected:
- void executeTask() override;
-
- /**
- * Processes the response received from the server.
- * If an error occurred, this should emit a failed signal.
- * If Yggdrasil gave an error response, it should call setError() first, and then return false.
- * Otherwise, it should return true.
- * Note: If the response from the server was blank, and the HTTP code was 200, this function is called with
- * an empty QJsonObject.
- */
- void processResponse(QJsonObject responseData);
-
- /**
- * Processes an error response received from the server.
- * The default implementation will read data from Yggdrasil's standard error response format and set it as this task's Error.
- * \returns a QString error message that will be passed to emitFailed.
- */
- virtual void processError(QJsonObject responseData);
-
- protected slots:
- void processReply();
- void refreshTimers(qint64, qint64);
- void heartbeat();
- void sslErrors(QList<QSslError>);
- void abortByTimeout();
-
- public slots:
- virtual bool abort() override;
-
- private:
- void sendRequest(QUrl endpoint, QByteArray content);
-
- protected:
- QNetworkReply* m_netReply = nullptr;
- QTimer timeout_keeper;
- QTimer counter;
- int count = 0; // num msec since time reset
-
- const int timeout_max = 30000;
- const int time_step = 50;
-};
diff --git a/launcher/minecraft/auth/flows/AuthFlow.h b/launcher/minecraft/auth/flows/AuthFlow.h
index c2c412ab..e39e926d 100644
--- a/launcher/minecraft/auth/flows/AuthFlow.h
+++ b/launcher/minecraft/auth/flows/AuthFlow.h
@@ -12,7 +12,6 @@
#include "minecraft/auth/AccountData.h"
#include "minecraft/auth/AccountTask.h"
#include "minecraft/auth/AuthStep.h"
-#include "minecraft/auth/Yggdrasil.h"
class AuthFlow : public AccountTask {
Q_OBJECT
diff --git a/launcher/minecraft/auth/flows/Mojang.cpp b/launcher/minecraft/auth/flows/Mojang.cpp
deleted file mode 100644
index 7e2db16f..00000000
--- a/launcher/minecraft/auth/flows/Mojang.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-#include "Mojang.h"
-
-#include "minecraft/auth/steps/GetSkinStep.h"
-#include "minecraft/auth/steps/MigrationEligibilityStep.h"
-#include "minecraft/auth/steps/MinecraftProfileStepMojang.h"
-#include "minecraft/auth/steps/YggdrasilStep.h"
-
-MojangRefresh::MojangRefresh(AccountData* data, QObject* parent) : AuthFlow(data, parent)
-{
- m_steps.append(makeShared<YggdrasilStep>(m_data, QString()));
- m_steps.append(makeShared<MinecraftProfileStepMojang>(m_data));
- m_steps.append(makeShared<MigrationEligibilityStep>(m_data));
- m_steps.append(makeShared<GetSkinStep>(m_data));
-}
-
-MojangLogin::MojangLogin(AccountData* data, QString password, QObject* parent) : AuthFlow(data, parent), m_password(password)
-{
- m_steps.append(makeShared<YggdrasilStep>(m_data, m_password));
- m_steps.append(makeShared<MinecraftProfileStepMojang>(m_data));
- m_steps.append(makeShared<MigrationEligibilityStep>(m_data));
- m_steps.append(makeShared<GetSkinStep>(m_data));
-}
diff --git a/launcher/minecraft/auth/flows/Mojang.h b/launcher/minecraft/auth/flows/Mojang.h
deleted file mode 100644
index 779ca7e3..00000000
--- a/launcher/minecraft/auth/flows/Mojang.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma once
-#include "AuthFlow.h"
-
-class MojangRefresh : public AuthFlow {
- Q_OBJECT
- public:
- explicit MojangRefresh(AccountData* data, QObject* parent = 0);
-};
-
-class MojangLogin : public AuthFlow {
- Q_OBJECT
- public:
- explicit MojangLogin(AccountData* data, QString password, QObject* parent = 0);
-
- private:
- QString m_password;
-};
diff --git a/launcher/minecraft/auth/steps/MigrationEligibilityStep.cpp b/launcher/minecraft/auth/steps/MigrationEligibilityStep.cpp
deleted file mode 100644
index 5ce953df..00000000
--- a/launcher/minecraft/auth/steps/MigrationEligibilityStep.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-#include "MigrationEligibilityStep.h"
-
-#include <QNetworkRequest>
-
-#include "minecraft/auth/AuthRequest.h"
-#include "minecraft/auth/Parsers.h"
-
-MigrationEligibilityStep::MigrationEligibilityStep(AccountData* data) : AuthStep(data) {}
-
-MigrationEligibilityStep::~MigrationEligibilityStep() noexcept = default;
-
-QString MigrationEligibilityStep::describe()
-{
- return tr("Checking for migration eligibility.");
-}
-
-void MigrationEligibilityStep::perform()
-{
- auto url = QUrl("https://api.minecraftservices.com/rollout/v1/msamigration");
- QNetworkRequest request = QNetworkRequest(url);
- request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
- request.setRawHeader("Authorization", QString("Bearer %1").arg(m_data->yggdrasilToken.token).toUtf8());
-
- AuthRequest* requestor = new AuthRequest(this);
- connect(requestor, &AuthRequest::finished, this, &MigrationEligibilityStep::onRequestDone);
- requestor->get(request);
-}
-
-void MigrationEligibilityStep::rehydrate()
-{
- // NOOP, for now. We only save bools and there's nothing to check.
-}
-
-void MigrationEligibilityStep::onRequestDone(QNetworkReply::NetworkError error,
- QByteArray data,
- QList<QNetworkReply::RawHeaderPair> headers)
-{
- auto requestor = qobject_cast<AuthRequest*>(QObject::sender());
- requestor->deleteLater();
-
- if (error == QNetworkReply::NoError) {
- Parsers::parseRolloutResponse(data, m_data->canMigrateToMSA);
- }
- emit finished(AccountTaskState::STATE_WORKING, tr("Got migration flags"));
-}
diff --git a/launcher/minecraft/auth/steps/MigrationEligibilityStep.h b/launcher/minecraft/auth/steps/MigrationEligibilityStep.h
deleted file mode 100644
index 8638975d..00000000
--- a/launcher/minecraft/auth/steps/MigrationEligibilityStep.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-#include <QObject>
-
-#include "QObjectPtr.h"
-#include "minecraft/auth/AuthStep.h"
-
-class MigrationEligibilityStep : public AuthStep {
- Q_OBJECT
-
- public:
- explicit MigrationEligibilityStep(AccountData* data);
- virtual ~MigrationEligibilityStep() noexcept;
-
- void perform() override;
- void rehydrate() override;
-
- QString describe() override;
-
- private slots:
- void onRequestDone(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
-};
diff --git a/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp b/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp
index 7cdce23f..a854342b 100644
--- a/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp
+++ b/launcher/minecraft/auth/steps/MinecraftProfileStep.cpp
@@ -41,10 +41,6 @@ void MinecraftProfileStep::onRequestDone(QNetworkReply::NetworkError error, QByt
qCDebug(authCredentials()) << data;
if (error == QNetworkReply::ContentNotFoundError) {
// NOTE: Succeed even if we do not have a profile. This is a valid account state.
- if (m_data->type == AccountType::Mojang) {
- m_data->minecraftEntitlement.canPlayMinecraft = false;
- m_data->minecraftEntitlement.ownsMinecraft = false;
- }
m_data->minecraftProfile = MinecraftProfile();
emit finished(AccountTaskState::STATE_SUCCEEDED, tr("Account has no Minecraft profile."));
return;
@@ -73,10 +69,5 @@ void MinecraftProfileStep::onRequestDone(QNetworkReply::NetworkError error, QByt
return;
}
- if (m_data->type == AccountType::Mojang) {
- auto validProfile = m_data->minecraftProfile.validity == Katabasis::Validity::Certain;
- m_data->minecraftEntitlement.canPlayMinecraft = validProfile;
- m_data->minecraftEntitlement.ownsMinecraft = validProfile;
- }
emit finished(AccountTaskState::STATE_WORKING, tr("Minecraft Java profile acquisition succeeded."));
}
diff --git a/launcher/minecraft/auth/steps/MinecraftProfileStepMojang.cpp b/launcher/minecraft/auth/steps/MinecraftProfileStepMojang.cpp
deleted file mode 100644
index d035e39a..00000000
--- a/launcher/minecraft/auth/steps/MinecraftProfileStepMojang.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-#include "MinecraftProfileStepMojang.h"
-
-#include <QNetworkRequest>
-
-#include "Logging.h"
-#include "minecraft/auth/AuthRequest.h"
-#include "minecraft/auth/Parsers.h"
-#include "net/NetUtils.h"
-
-MinecraftProfileStepMojang::MinecraftProfileStepMojang(AccountData* data) : AuthStep(data) {}
-
-MinecraftProfileStepMojang::~MinecraftProfileStepMojang() noexcept = default;
-
-QString MinecraftProfileStepMojang::describe()
-{
- return tr("Fetching the Minecraft profile.");
-}
-
-void MinecraftProfileStepMojang::perform()
-{
- if (m_data->minecraftProfile.id.isEmpty()) {
- emit finished(AccountTaskState::STATE_FAILED_HARD, tr("A UUID is required to get the profile."));
- return;
- }
-
- // use session server instead of profile due to profile endpoint being locked for locked Mojang accounts
- QUrl url = QUrl("https://sessionserver.mojang.com/session/minecraft/profile/" + m_data->minecraftProfile.id);
- QNetworkRequest req = QNetworkRequest(url);
- AuthRequest* request = new AuthRequest(this);
- connect(request, &AuthRequest::finished, this, &MinecraftProfileStepMojang::onRequestDone);
- request->get(req);
-}
-
-void MinecraftProfileStepMojang::rehydrate()
-{
- // NOOP, for now. We only save bools and there's nothing to check.
-}
-
-void MinecraftProfileStepMojang::onRequestDone(QNetworkReply::NetworkError error,
- QByteArray data,
- QList<QNetworkReply::RawHeaderPair> headers)
-{
- auto requestor = qobject_cast<AuthRequest*>(QObject::sender());
- requestor->deleteLater();
-
- qCDebug(authCredentials()) << data;
- if (error == QNetworkReply::ContentNotFoundError) {
- // NOTE: Succeed even if we do not have a profile. This is a valid account state.
- if (m_data->type == AccountType::Mojang) {
- m_data->minecraftEntitlement.canPlayMinecraft = false;
- m_data->minecraftEntitlement.ownsMinecraft = false;
- }
- m_data->minecraftProfile = MinecraftProfile();
- emit finished(AccountTaskState::STATE_SUCCEEDED, tr("Account has no Minecraft profile."));
- return;
- }
- if (error != QNetworkReply::NoError) {
- qWarning() << "Error getting profile:";
- qWarning() << " HTTP Status: " << requestor->httpStatus_;
- qWarning() << " Internal error no.: " << error;
- qWarning() << " Error string: " << requestor->errorString_;
-
- qWarning() << " Response:";
- qWarning() << QString::fromUtf8(data);
-
- if (Net::isApplicationError(error)) {
- emit finished(AccountTaskState::STATE_FAILED_SOFT,
- tr("Minecraft Java profile acquisition failed: %1").arg(requestor->errorString_));
- } else {
- emit finished(AccountTaskState::STATE_OFFLINE,
- tr("Minecraft Java profile acquisition failed: %1").arg(requestor->errorString_));
- }
- return;
- }
- if (!Parsers::parseMinecraftProfileMojang(data, m_data->minecraftProfile)) {
- m_data->minecraftProfile = MinecraftProfile();
- emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("Minecraft Java profile response could not be parsed"));
- return;
- }
-
- if (m_data->type == AccountType::Mojang) {
- auto validProfile = m_data->minecraftProfile.validity == Katabasis::Validity::Certain;
- m_data->minecraftEntitlement.canPlayMinecraft = validProfile;
- m_data->minecraftEntitlement.ownsMinecraft = validProfile;
- }
- emit finished(AccountTaskState::STATE_WORKING, tr("Minecraft Java profile acquisition succeeded."));
-}
diff --git a/launcher/minecraft/auth/steps/MinecraftProfileStepMojang.h b/launcher/minecraft/auth/steps/MinecraftProfileStepMojang.h
deleted file mode 100644
index 730ec3f6..00000000
--- a/launcher/minecraft/auth/steps/MinecraftProfileStepMojang.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-#include <QObject>
-
-#include "QObjectPtr.h"
-#include "minecraft/auth/AuthStep.h"
-
-class MinecraftProfileStepMojang : public AuthStep {
- Q_OBJECT
-
- public:
- explicit MinecraftProfileStepMojang(AccountData* data);
- virtual ~MinecraftProfileStepMojang() noexcept;
-
- void perform() override;
- void rehydrate() override;
-
- QString describe() override;
-
- private slots:
- void onRequestDone(QNetworkReply::NetworkError, QByteArray, QList<QNetworkReply::RawHeaderPair>);
-};
diff --git a/launcher/minecraft/auth/steps/YggdrasilStep.cpp b/launcher/minecraft/auth/steps/YggdrasilStep.cpp
deleted file mode 100644
index fdcaa0d6..00000000
--- a/launcher/minecraft/auth/steps/YggdrasilStep.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-#include "YggdrasilStep.h"
-
-#include "minecraft/auth/AuthRequest.h"
-#include "minecraft/auth/Parsers.h"
-#include "minecraft/auth/Yggdrasil.h"
-
-YggdrasilStep::YggdrasilStep(AccountData* data, QString password) : AuthStep(data), m_password(password)
-{
- m_yggdrasil = new Yggdrasil(m_data, this);
-
- connect(m_yggdrasil, &Task::failed, this, &YggdrasilStep::onAuthFailed);
- connect(m_yggdrasil, &Task::succeeded, this, &YggdrasilStep::onAuthSucceeded);
- connect(m_yggdrasil, &Task::aborted, this, &YggdrasilStep::onAuthFailed);
-}
-
-YggdrasilStep::~YggdrasilStep() noexcept = default;
-
-QString YggdrasilStep::describe()
-{
- return tr("Logging in with Mojang account.");
-}
-
-void YggdrasilStep::rehydrate()
-{
- // NOOP, for now.
-}
-
-void YggdrasilStep::perform()
-{
- if (m_password.size()) {
- m_yggdrasil->login(m_password);
- } else {
- m_yggdrasil->refresh();
- }
-}
-
-void YggdrasilStep::onAuthSucceeded()
-{
- emit finished(AccountTaskState::STATE_WORKING, tr("Logged in with Mojang"));
-}
-
-void YggdrasilStep::onAuthFailed()
-{
- // TODO: hook these in again, expand to MSA
- // m_error = m_yggdrasil->m_error;
- // m_aborted = m_yggdrasil->m_aborted;
-
- auto state = m_yggdrasil->taskState();
- QString errorMessage = tr("Mojang user authentication failed.");
-
- // NOTE: soft error in the first step means 'offline'
- if (state == AccountTaskState::STATE_FAILED_SOFT) {
- state = AccountTaskState::STATE_OFFLINE;
- errorMessage = tr("Mojang user authentication ended with a network error.");
- }
- emit finished(state, errorMessage);
-}
diff --git a/launcher/minecraft/auth/steps/YggdrasilStep.h b/launcher/minecraft/auth/steps/YggdrasilStep.h
deleted file mode 100644
index ef31f34d..00000000
--- a/launcher/minecraft/auth/steps/YggdrasilStep.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#pragma once
-#include <QObject>
-
-#include "QObjectPtr.h"
-#include "minecraft/auth/AuthStep.h"
-
-class Yggdrasil;
-
-class YggdrasilStep : public AuthStep {
- Q_OBJECT
-
- public:
- explicit YggdrasilStep(AccountData* data, QString password);
- virtual ~YggdrasilStep() noexcept;
-
- void perform() override;
- void rehydrate() override;
-
- QString describe() override;
-
- private slots:
- void onAuthSucceeded();
- void onAuthFailed();
-
- private:
- Yggdrasil* m_yggdrasil = nullptr;
- QString m_password;
-};
diff --git a/launcher/ui/dialogs/LoginDialog.cpp b/launcher/ui/dialogs/LoginDialog.cpp
deleted file mode 100644
index 7296a13e..00000000
--- a/launcher/ui/dialogs/LoginDialog.cpp
+++ /dev/null
@@ -1,115 +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.
- */
-
-#include "LoginDialog.h"
-#include "ui_LoginDialog.h"
-
-#include "minecraft/auth/AccountTask.h"
-
-#include <QtWidgets/QPushButton>
-
-LoginDialog::LoginDialog(QWidget* parent) : QDialog(parent), ui(new Ui::LoginDialog)
-{
- ui->setupUi(this);
- ui->progressBar->setVisible(false);
- ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
-
- connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
- connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
-}
-
-LoginDialog::~LoginDialog()
-{
- delete ui;
-}
-
-// Stage 1: User interaction
-void LoginDialog::accept()
-{
- setUserInputsEnabled(false);
- ui->progressBar->setVisible(true);
-
- // Setup the login task and start it
- m_account = MinecraftAccount::createFromUsername(ui->userTextBox->text());
- m_loginTask = m_account->login(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::status, this, &LoginDialog::onTaskStatus);
- connect(m_loginTask.get(), &Task::progress, this, &LoginDialog::onTaskProgress);
- m_loginTask->start();
-}
-
-void LoginDialog::setUserInputsEnabled(bool enable)
-{
- ui->userTextBox->setEnabled(enable);
- ui->passTextBox->setEnabled(enable);
- ui->buttonBox->setEnabled(enable);
-}
-
-// Enable the OK button only when both textboxes contain something.
-void LoginDialog::on_userTextBox_textEdited(const QString& newText)
-{
- ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!newText.isEmpty() && !ui->passTextBox->text().isEmpty());
-}
-void LoginDialog::on_passTextBox_textEdited(const QString& newText)
-{
- ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!newText.isEmpty() && !ui->userTextBox->text().isEmpty());
-}
-
-void LoginDialog::onTaskFailed(const QString& reason)
-{
- // Set message
- auto lines = reason.split('\n');
- QString processed;
- for (auto line : lines) {
- if (line.size()) {
- processed += "<font color='red'>" + line + "</font><br />";
- } else {
- processed += "<br />";
- }
- }
- ui->label->setText(processed);
-
- // Re-enable user-interaction
- setUserInputsEnabled(true);
- ui->progressBar->setVisible(false);
-}
-
-void LoginDialog::onTaskSucceeded()
-{
- QDialog::accept();
-}
-
-void LoginDialog::onTaskStatus(const QString& status)
-{
- ui->label->setText(status);
-}
-
-void LoginDialog::onTaskProgress(qint64 current, qint64 total)
-{
- ui->progressBar->setMaximum(total);
- ui->progressBar->setValue(current);
-}
-
-// Public interface
-MinecraftAccountPtr LoginDialog::newAccount(QWidget* parent, QString msg)
-{
- LoginDialog dlg(parent);
- dlg.ui->label->setText(msg);
- if (dlg.exec() == QDialog::Accepted) {
- return dlg.m_account;
- }
- return nullptr;
-}
diff --git a/launcher/ui/dialogs/LoginDialog.h b/launcher/ui/dialogs/LoginDialog.h
deleted file mode 100644
index 601b5fa7..00000000
--- a/launcher/ui/dialogs/LoginDialog.h
+++ /dev/null
@@ -1,56 +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 <QtCore/QEventLoop>
-#include <QtWidgets/QDialog>
-
-#include "minecraft/auth/MinecraftAccount.h"
-#include "tasks/Task.h"
-
-namespace Ui {
-class LoginDialog;
-}
-
-class LoginDialog : public QDialog {
- Q_OBJECT
-
- public:
- ~LoginDialog();
-
- static MinecraftAccountPtr newAccount(QWidget* parent, QString message);
-
- private:
- explicit LoginDialog(QWidget* parent = 0);
-
- void setUserInputsEnabled(bool enable);
-
- protected slots:
- void accept();
-
- void onTaskFailed(const QString& reason);
- void onTaskSucceeded();
- void onTaskStatus(const QString& status);
- void onTaskProgress(qint64 current, qint64 total);
-
- void on_userTextBox_textEdited(const QString& newText);
- void on_passTextBox_textEdited(const QString& newText);
-
- private:
- Ui::LoginDialog* ui;
- MinecraftAccountPtr m_account;
- Task::Ptr m_loginTask;
-};
diff --git a/launcher/ui/dialogs/LoginDialog.ui b/launcher/ui/dialogs/LoginDialog.ui
deleted file mode 100644
index 8fa4a45d..00000000
--- a/launcher/ui/dialogs/LoginDialog.ui
+++ /dev/null
@@ -1,77 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>LoginDialog</class>
- <widget class="QDialog" name="LoginDialog">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>421</width>
- <height>198</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="windowTitle">
- <string>Add 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="QLineEdit" name="userTextBox">
- <property name="placeholderText">
- <string>Email</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="passTextBox">
- <property name="echoMode">
- <enum>QLineEdit::Password</enum>
- </property>
- <property name="placeholderText">
- <string>Password</string>
- </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|QDialogButtonBox::Ok</set>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/launcher/ui/pages/global/AccountListPage.cpp b/launcher/ui/pages/global/AccountListPage.cpp
index c95bfabd..90591c7f 100644
--- a/launcher/ui/pages/global/AccountListPage.cpp
+++ b/launcher/ui/pages/global/AccountListPage.cpp
@@ -45,7 +45,6 @@
#include "net/NetJob.h"
#include "ui/dialogs/CustomMessageBox.h"
-#include "ui/dialogs/LoginDialog.h"
#include "ui/dialogs/MSALoginDialog.h"
#include "ui/dialogs/OfflineLoginDialog.h"
#include "ui/dialogs/ProgressDialog.h"
@@ -64,8 +63,7 @@ AccountListPage::AccountListPage(QWidget* parent) : QMainWindow(parent), ui(new
ui->setupUi(this);
ui->listView->setEmptyString(
tr("Welcome!\n"
- "If you're new here, you can select the \"Add Microsoft\" or \"Add Mojang\" buttons to link your Microsoft and/or Mojang "
- "accounts."));
+ "If you're new here, you can select the \"Add Microsoft\" button to link your Microsoft account."));
ui->listView->setEmptyMode(VersionListView::String);
ui->listView->setContextMenuPolicy(Qt::CustomContextMenu);
@@ -74,7 +72,6 @@ AccountListPage::AccountListPage(QWidget* parent) : QMainWindow(parent), ui(new
ui->listView->setModel(m_accounts.get());
ui->listView->header()->setSectionResizeMode(AccountList::VListColumns::ProfileNameColumn, QHeaderView::Stretch);
ui->listView->header()->setSectionResizeMode(AccountList::VListColumns::NameColumn, QHeaderView::Stretch);
- ui->listView->header()->setSectionResizeMode(AccountList::VListColumns::MigrationColumn, QHeaderView::ResizeToContents);
ui->listView->header()->setSectionResizeMode(AccountList::VListColumns::TypeColumn, QHeaderView::ResizeToContents);
ui->listView->header()->setSectionResizeMode(AccountList::VListColumns::StatusColumn, QHeaderView::ResizeToContents);
ui->listView->setSelectionMode(QAbstractItemView::SingleSelection);
@@ -139,19 +136,6 @@ void AccountListPage::listChanged()
updateButtonStates();
}
-void AccountListPage::on_actionAddMojang_triggered()
-{
- MinecraftAccountPtr account =
- LoginDialog::newAccount(this, tr("Please enter your Mojang account email and password to add your account."));
-
- if (account) {
- m_accounts->addAccount(account);
- if (m_accounts->count() == 1) {
- m_accounts->setDefaultAccount(account);
- }
- }
-}
-
void AccountListPage::on_actionAddMicrosoft_triggered()
{
MinecraftAccountPtr account =
diff --git a/launcher/ui/pages/global/AccountListPage.h b/launcher/ui/pages/global/AccountListPage.h
index add0f4aa..f3b80191 100644
--- a/launcher/ui/pages/global/AccountListPage.h
+++ b/launcher/ui/pages/global/AccountListPage.h
@@ -70,7 +70,6 @@ class AccountListPage : public QMainWindow, public BasePage {
void retranslate() override;
public slots:
- void on_actionAddMojang_triggered();
void on_actionAddMicrosoft_triggered();
void on_actionAddOffline_triggered();
void on_actionRemove_triggered();
diff --git a/launcher/ui/pages/global/AccountListPage.ui b/launcher/ui/pages/global/AccountListPage.ui
index 469955b5..d8cf3ac0 100644
--- a/launcher/ui/pages/global/AccountListPage.ui
+++ b/launcher/ui/pages/global/AccountListPage.ui
@@ -53,7 +53,6 @@
<bool>false</bool>
</attribute>
<addaction name="actionAddMicrosoft"/>
- <addaction name="actionAddMojang"/>
<addaction name="actionAddOffline"/>
<addaction name="actionRefresh"/>
<addaction name="actionRemove"/>
@@ -63,11 +62,6 @@
<addaction name="actionUploadSkin"/>
<addaction name="actionDeleteSkin"/>
</widget>
- <action name="actionAddMojang">
- <property name="text">
- <string>Add &amp;Mojang</string>
- </property>
- </action>
<action name="actionRemove">
<property name="text">
<string>Remo&amp;ve</string>