aboutsummaryrefslogtreecommitdiff
path: root/launcher/minecraft/auth
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2021-08-29 19:58:35 +0200
committerPetr Mrázek <peterix@gmail.com>2021-08-29 19:59:18 +0200
commit7239502675fb68b1a2050c68f483e5d5371114e1 (patch)
tree80f39a62be153e525aeab5e1349960067173bb5f /launcher/minecraft/auth
parent1e1655bc4b2d6fef3bb14736c7f9506fca246876 (diff)
downloadPrismLauncher-7239502675fb68b1a2050c68f483e5d5371114e1.tar.gz
PrismLauncher-7239502675fb68b1a2050c68f483e5d5371114e1.tar.bz2
PrismLauncher-7239502675fb68b1a2050c68f483e5d5371114e1.zip
GH-3392 Add recognition of already migrated Mojang accounts
Diffstat (limited to 'launcher/minecraft/auth')
-rw-r--r--launcher/minecraft/auth/AccountTask.cpp4
-rw-r--r--launcher/minecraft/auth/AccountTask.h1
-rw-r--r--launcher/minecraft/auth/AuthSession.h3
-rw-r--r--launcher/minecraft/auth/MinecraftAccount.cpp74
-rw-r--r--launcher/minecraft/auth/flows/Yggdrasil.cpp43
5 files changed, 84 insertions, 41 deletions
diff --git a/launcher/minecraft/auth/AccountTask.cpp b/launcher/minecraft/auth/AccountTask.cpp
index c06be42b..d400ce8d 100644
--- a/launcher/minecraft/auth/AccountTask.cpp
+++ b/launcher/minecraft/auth/AccountTask.cpp
@@ -49,6 +49,8 @@ QString AccountTask::getStateMessage() const
return tr("Failed to contact the authentication server.");
case STATE_FAILED_HARD:
return tr("Failed to authenticate.");
+ case STATE_FAILED_GONE:
+ return tr("Failed to authenticate. The account no longer exists.");
default:
return tr("...");
}
@@ -62,7 +64,7 @@ void AccountTask::changeState(AccountTask::State newState, QString reason)
{
emitSucceeded();
}
- else if (newState == STATE_FAILED_HARD || newState == STATE_FAILED_SOFT)
+ else if (newState == STATE_FAILED_HARD || newState == STATE_FAILED_SOFT || newState == STATE_FAILED_GONE)
{
emitFailed(reason);
}
diff --git a/launcher/minecraft/auth/AccountTask.h b/launcher/minecraft/auth/AccountTask.h
index fc3488eb..4f3bd52a 100644
--- a/launcher/minecraft/auth/AccountTask.h
+++ b/launcher/minecraft/auth/AccountTask.h
@@ -76,6 +76,7 @@ public:
STATE_WORKING,
STATE_FAILED_SOFT, //!< soft failure. this generally means the user auth details haven't been invalidated
STATE_FAILED_HARD, //!< hard failure. auth is invalid
+ STATE_FAILED_GONE, //!< hard failure. auth is invalid, and the account no longer exists
STATE_SUCCEEDED
} m_accountState = STATE_CREATED;
diff --git a/launcher/minecraft/auth/AuthSession.h b/launcher/minecraft/auth/AuthSession.h
index d77435b8..f609d5d3 100644
--- a/launcher/minecraft/auth/AuthSession.h
+++ b/launcher/minecraft/auth/AuthSession.h
@@ -18,7 +18,8 @@ struct AuthSession
RequiresOAuth,
RequiresPassword,
PlayableOffline,
- PlayableOnline
+ PlayableOnline,
+ GoneOrMigrated
} status = Undetermined;
// client token
diff --git a/launcher/minecraft/auth/MinecraftAccount.cpp b/launcher/minecraft/auth/MinecraftAccount.cpp
index 4231d6b0..2d76f9ac 100644
--- a/launcher/minecraft/auth/MinecraftAccount.cpp
+++ b/launcher/minecraft/auth/MinecraftAccount.cpp
@@ -227,32 +227,60 @@ void MinecraftAccount::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->accountState() == AccountTask::STATE_FAILED_SOFT)
- {
- if (session)
- {
- session->status = accountStatus() == Verified ? AuthSession::PlayableOffline : AuthSession::RequiresPassword;
- session->auth_server_online = false;
- fillSession(session);
+ switch (m_currentTask->accountState()) {
+ case AccountTask::STATE_FAILED_SOFT: {
+ if (session)
+ {
+ if(accountStatus() == Verified) {
+ session->status = AuthSession::PlayableOffline;
+ }
+ else {
+ if(data.type == AccountType::MSA) {
+ session->status = AuthSession::RequiresOAuth;
+ }
+ else {
+ session->status = AuthSession::RequiresPassword;
+ }
+ }
+ session->auth_server_online = false;
+ fillSession(session);
+ }
}
- }
- else
- {
- // FIXME: MSA ...
- data.yggdrasilToken.token = QString();
- data.yggdrasilToken.validity = Katabasis::Validity::None;
- data.validity_ = Katabasis::Validity::None;
- emit changed();
- if (session)
- {
- if(data.type == AccountType::MSA) {
- session->status = AuthSession::RequiresOAuth;
+ break;
+ case AccountTask::STATE_FAILED_HARD: {
+ // FIXME: MSA data clearing
+ data.yggdrasilToken.token = QString();
+ data.yggdrasilToken.validity = Katabasis::Validity::None;
+ data.validity_ = Katabasis::Validity::None;
+ emit changed();
+ if (session)
+ {
+ if(data.type == AccountType::MSA) {
+ session->status = AuthSession::RequiresOAuth;
+ }
+ else {
+ session->status = AuthSession::RequiresPassword;
+ }
+ session->auth_server_online = true;
+ fillSession(session);
}
- else {
- session->status = AuthSession::RequiresPassword;
+ }
+ break;
+ case AccountTask::STATE_FAILED_GONE: {
+ data.validity_ = Katabasis::Validity::None;
+ emit changed();
+ if (session)
+ {
+ session->status = AuthSession::GoneOrMigrated;
+ session->auth_server_online = true;
+ fillSession(session);
}
- session->auth_server_online = true;
- fillSession(session);
+ }
+ break;
+ case AccountTask::STATE_CREATED:
+ case AccountTask::STATE_WORKING:
+ case AccountTask::STATE_SUCCEEDED: {
+ // Not reachable here, as they are not failures.
}
}
m_currentTask.reset();
diff --git a/launcher/minecraft/auth/flows/Yggdrasil.cpp b/launcher/minecraft/auth/flows/Yggdrasil.cpp
index 7cea059c..c2935d05 100644
--- a/launcher/minecraft/auth/flows/Yggdrasil.cpp
+++ b/launcher/minecraft/auth/flows/Yggdrasil.cpp
@@ -255,10 +255,17 @@ void Yggdrasil::processReply()
case QNetworkReply::ContentAccessDenied:
case QNetworkReply::ContentOperationNotPermittedError:
break;
+ case QNetworkReply::ContentGoneError: {
+ changeState(
+ STATE_FAILED_GONE,
+ tr("The Mojang account no longer exists. It may have been migrated to a Microsoft account.")
+ );
+ }
default:
- changeState(STATE_FAILED_SOFT,
- tr("Authentication operation failed due to a network error: %1 (%2)")
- .arg(m_netReply->errorString()).arg(m_netReply->error()));
+ changeState(
+ STATE_FAILED_SOFT,
+ tr("Authentication operation failed due to a network error: %1 (%2)").arg(m_netReply->errorString()).arg(m_netReply->error())
+ );
return;
}
@@ -283,10 +290,10 @@ void Yggdrasil::processReply()
}
else
{
- changeState(STATE_FAILED_SOFT, tr("Failed to parse authentication server response "
- "JSON response: %1 at offset %2.")
- .arg(jsonError.errorString())
- .arg(jsonError.offset));
+ changeState(
+ 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;
@@ -301,19 +308,18 @@ void Yggdrasil::processReply()
// 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.";
+ 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(STATE_FAILED_SOFT,
- tr("An unknown error occurred when trying to communicate with the "
- "authentication server: %1").arg(m_netReply->errorString()));
+ qDebug() << "The request failed and the server gave no error message. Unknown error.";
+ changeState(
+ STATE_FAILED_SOFT,
+ tr("An unknown error occurred when trying to communicate with the authentication server: %1").arg(m_netReply->errorString())
+ );
}
}
@@ -325,8 +331,13 @@ void Yggdrasil::processError(QJsonObject responseData)
if (errorVal.isString() && errorMessageValue.isString())
{
- m_error = std::shared_ptr<Error>(new Error{
- errorVal.toString(""), errorMessageValue.toString(""), causeVal.toString("")});
+ m_error = std::shared_ptr<Error>(
+ new Error {
+ errorVal.toString(""),
+ errorMessageValue.toString(""),
+ causeVal.toString("")
+ }
+ );
changeState(STATE_FAILED_HARD, m_error->m_errorMessageVerbose);
}
else