From a600286e33601a85949b9e51bd5421a45f9998ac Mon Sep 17 00:00:00 2001 From: Sky Date: Thu, 17 Oct 2013 00:46:25 +0100 Subject: [PATCH] Use Yggdrasil error response when available, or fall back to legacy HTTP error codes --- logic/net/LoginTask.cpp | 75 +++++++++++++++++++++++++++++------------ logic/net/LoginTask.h | 4 ++- 2 files changed, 57 insertions(+), 22 deletions(-) diff --git a/logic/net/LoginTask.cpp b/logic/net/LoginTask.cpp index 70ef2ae62..4098783b9 100644 --- a/logic/net/LoginTask.cpp +++ b/logic/net/LoginTask.cpp @@ -92,15 +92,15 @@ void LoginTask::parseLegacyReply(QByteArray data) void LoginTask::processLegacyReply(QNetworkReply *reply) { - processReply(reply, &LoginTask::parseLegacyReply); + processReply(reply, &LoginTask::parseLegacyReply, &LoginTask::parseLegacyError); } void LoginTask::processYggdrasilReply(QNetworkReply *reply) { - processReply(reply, &LoginTask::parseYggdrasilReply); + processReply(reply, &LoginTask::parseYggdrasilReply, &LoginTask::parseYggdrasilError); } -void LoginTask::processReply(QNetworkReply *reply, std::function parser) +void LoginTask::processReply(QNetworkReply *reply, std::function parser, std::function errorHandler) { if (netReply != reply) return; @@ -131,27 +131,60 @@ void LoginTask::processReply(QNetworkReply *reply, std::functionattribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - - switch (responseCode) - { - case 403: - emitFailed(tr("Invalid username or password.")); - break; - - case 503: - emitFailed(tr("The login servers are currently unavailable. Check " - "http://help.mojang.com/ for more info.")); - break; - - default: - QLOG_DEBUG() << "Login failed with QNetworkReply code:" << reply->error(); - emitFailed(tr("Login failed: %1").arg(reply->errorString())); - break; - } + emitFailed(errorHandler(this, reply)); + break; } } +QString LoginTask::parseLegacyError(QNetworkReply *reply) +{ + int responseCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + switch (responseCode) + { + case 403: + return tr("Invalid username or password."); + + case 503: + return tr("The login servers are currently unavailable. Check " + "http://help.mojang.com/ for more info."); + + default: + QLOG_DEBUG() << "Login failed with QNetworkReply code:" << reply->error(); + return tr("Login failed: %1").arg(reply->errorString()); + } +} + +QString LoginTask::parseYggdrasilError(QNetworkReply *reply) +{ + QByteArray data = reply->readAll(); + QJsonParseError jsonError; + QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError); + + // If there are JSON errors fall back to using the legacy error handling using HTTP status codes + if (jsonError.error != QJsonParseError::NoError) + { + return parseLegacyError(reply); + } + + if (!jsonDoc.isObject()) + { + return parseLegacyError(reply); + } + + QJsonObject root = jsonDoc.object(); + + //QString error = root.value("error").toString(); + QString errorMessage = root.value("errorMessage").toString(); + + if(errorMessage.isEmpty()) + { + return parseLegacyError(reply); + } + + return tr("Login failed: ") + errorMessage; +} + void LoginTask::yggdrasilLogin() { setStatus(tr("Logging in...")); diff --git a/logic/net/LoginTask.h b/logic/net/LoginTask.h index fa5897cb1..aa925999f 100644 --- a/logic/net/LoginTask.h +++ b/logic/net/LoginTask.h @@ -49,12 +49,14 @@ protected slots: void legacyLogin(); void processLegacyReply(QNetworkReply *reply); void parseLegacyReply(QByteArray data); + QString parseLegacyError(QNetworkReply *reply); void yggdrasilLogin(); void processYggdrasilReply(QNetworkReply *reply); void parseYggdrasilReply(QByteArray data); + QString parseYggdrasilError(QNetworkReply *reply); - void processReply(QNetworkReply *reply, std::function); + void processReply(QNetworkReply *reply, std::function, std::function); protected: void executeTask();