diff --git a/launcher/minecraft/auth/flows/AuthContext.cpp b/launcher/minecraft/auth/flows/AuthContext.cpp index 9fb3ec48..5c4dad75 100644 --- a/launcher/minecraft/auth/flows/AuthContext.cpp +++ b/launcher/minecraft/auth/flows/AuthContext.cpp @@ -663,21 +663,10 @@ void AuthContext::checkResult() { } namespace { -bool parseMinecraftProfile(QByteArray & data, MinecraftProfile &output) { - qDebug() << "Parsing Minecraft profile..."; -#ifndef NDEBUG - qDebug() << data; -#endif - - QJsonParseError jsonError; - QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); - if(jsonError.error) { - qWarning() << "Failed to parse response from user.auth.xboxlive.com as JSON: " << jsonError.errorString(); - return false; - } - - auto obj = doc.object(); - if(!getString(obj.value("id"), output.id)) { +bool parseMinecraftProfileFromJSON(QJsonObject & obj, MinecraftProfile &output) +{ + if(!getString(obj.value("id"), output.id)) + { qWarning() << "Minecraft profile id is not a string"; return false; } @@ -740,21 +729,44 @@ bool parseMinecraftProfile(QByteArray & data, MinecraftProfile &output) { output.validity = Katabasis::Validity::Certain; return true; } + +bool parseMinecraftProfile(QByteArray & data, MinecraftProfile &output) { + qDebug() << "Parsing Minecraft profile..."; +#ifndef NDEBUG + qDebug() << data; +#endif + + QJsonParseError jsonError; + QJsonDocument doc = QJsonDocument::fromJson(data, &jsonError); + if(jsonError.error) { + qWarning() << "Failed to parse response from user.auth.xboxlive.com as JSON: " << jsonError.errorString(); + return false; + } + + auto obj = doc.object(); + return parseMinecraftProfileFromJSON(obj, output); +} } void AuthContext::doMinecraftProfile() { - setStage(AuthStage::MinecraftProfile); - changeState(STATE_WORKING, tr("Starting minecraft profile acquisition")); + + if(!m_data->provider->useYggdrasil()){ + setStage(AuthStage::MinecraftProfile); + changeState(STATE_WORKING, tr("Starting minecraft profile acquisition")); - auto url = QUrl("https://api.minecraftservices.com/minecraft/profile"); - QNetworkRequest request = QNetworkRequest(url); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - // request.setRawHeader("Accept", "application/json"); - request.setRawHeader("Authorization", QString("Bearer %1").arg(m_data->yggdrasilToken.token).toUtf8()); + auto url = QUrl("https://api.minecraftservices.com/minecraft/profile"); + QNetworkRequest request = QNetworkRequest(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + // request.setRawHeader("Accept", "application/json"); + request.setRawHeader("Authorization", QString("Bearer %1").arg(m_data->yggdrasilToken.token).toUtf8()); - AuthRequest *requestor = new AuthRequest(this); - connect(requestor, &AuthRequest::finished, this, &AuthContext::onMinecraftProfileDone); - requestor->get(request); + AuthRequest *requestor = new AuthRequest(this); + connect(requestor, &AuthRequest::finished, this, &AuthContext::onMinecraftProfileDone); + requestor->get(request); + } else { + parseMinecraftProfileFromJSON(m_yggdrasil->yggdrasilProfile, m_data->minecraftProfile); + doGetSkin(); + } } void AuthContext::onMinecraftProfileDone( @@ -850,8 +862,10 @@ void AuthContext::doGetSkin() { setStage(AuthStage::Skin); changeState(STATE_WORKING, tr("Fetching player skin")); - auto url = QUrl(m_data->minecraftProfile.skin.url); + auto url = QUrl(m_data->provider->resolveSkinUrl(m_data->profileId(), m_data->profileName())); QNetworkRequest request = QNetworkRequest(url); + request.setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy); + AuthRequest *requestor = new AuthRequest(this); connect(requestor, &AuthRequest::finished, this, &AuthContext::onSkinDone); requestor->get(request); diff --git a/launcher/minecraft/auth/flows/Yggdrasil.cpp b/launcher/minecraft/auth/flows/Yggdrasil.cpp index 20ca63d0..9f1b2b1a 100644 --- a/launcher/minecraft/auth/flows/Yggdrasil.cpp +++ b/launcher/minecraft/auth/flows/Yggdrasil.cpp @@ -85,8 +85,7 @@ void Yggdrasil::refresh() { */ req.insert("requestUser", false); QJsonDocument doc(req); - - QUrl reqUrl(BuildConfig.AUTH_BASE + "refresh"); + QUrl reqUrl(m_data->provider->authEndpoint() + "refresh"); QByteArray requestData = doc.toJson(); sendRequest(reqUrl, requestData); @@ -131,7 +130,7 @@ void Yggdrasil::login(QString password) { QJsonDocument doc(req); - QUrl reqUrl(BuildConfig.AUTH_BASE + "authenticate"); + QUrl reqUrl(m_data->provider->authEndpoint() + "authenticate"); QNetworkRequest netRequest(reqUrl); QByteArray requestData = doc.toJson(); @@ -218,6 +217,10 @@ void Yggdrasil::processResponse(QJsonObject responseData) m_data->yggdrasilToken.token = accessToken; m_data->yggdrasilToken.validity = Katabasis::Validity::Certain; + if(responseData.contains("selectedProfile")) { + yggdrasilProfile = responseData.value("selectedProfile").toObject(); + } + // We've made it through the minefield of possible errors. Return true to indicate that // we've succeeded. qDebug() << "Finished reading authentication response."; diff --git a/launcher/minecraft/auth/flows/Yggdrasil.h b/launcher/minecraft/auth/flows/Yggdrasil.h index e709cb9f..39776268 100644 --- a/launcher/minecraft/auth/flows/Yggdrasil.h +++ b/launcher/minecraft/auth/flows/Yggdrasil.h @@ -38,6 +38,9 @@ public: void refresh(); void login(QString password); + + QJsonObject yggdrasilProfile; + protected: void executeTask() override; diff --git a/launcher/minecraft/auth/providers/BaseAuthProvider.h b/launcher/minecraft/auth/providers/BaseAuthProvider.h index 5b23d3db..393402a9 100644 --- a/launcher/minecraft/auth/providers/BaseAuthProvider.h +++ b/launcher/minecraft/auth/providers/BaseAuthProvider.h @@ -7,13 +7,6 @@ #include #include -struct AccountProfile -{ - QString id; - QString name; - bool legacy; -}; - class BaseAuthProvider; typedef std::shared_ptr AuthProviderPtr; @@ -63,9 +56,9 @@ public: }; // Function to get url of skin to display in launcher - virtual QUrl resolveSkinUrl(AccountProfile profile) + virtual QUrl resolveSkinUrl(QString id, QString name) { - return QUrl(((QString) "https://crafatar.com/skins/%1.png").arg(profile.id)); + return QUrl(((QString) "https://crafatar.com/skins/%1.png").arg(id)); }; // Can change skin (currently only mojang support) @@ -73,4 +66,10 @@ public: { return false; } + + // Use legacy yggdrasil auth, (get profile from refresh and login) + virtual bool useYggdrasil() + { + return false; + } }; diff --git a/launcher/minecraft/auth/providers/ElybyAuthProvider.h b/launcher/minecraft/auth/providers/ElybyAuthProvider.h index 9a5f9030..00d66bf5 100644 --- a/launcher/minecraft/auth/providers/ElybyAuthProvider.h +++ b/launcher/minecraft/auth/providers/ElybyAuthProvider.h @@ -34,8 +34,13 @@ public: return "https://authserver.ely.by/auth/"; }; - QUrl resolveSkinUrl(AccountProfile profile) + QUrl resolveSkinUrl(QString id, QString name) { - return QUrl(((QString) "http://skinsystem.ely.by/skins/%1.png").arg(profile.name)); + return QUrl(((QString) "http://skinsystem.ely.by/skins/%1.png").arg(name)); + } + + virtual bool useYggdrasil() + { + return true; } };