From 51fff1f02c89afd389abd77c711a4cda0c863129 Mon Sep 17 00:00:00 2001 From: Neptune Date: Mon, 11 Mar 2024 20:58:42 -0500 Subject: [PATCH] UltimMC: Use proper Ely.by profile --- launcher/CMakeLists.txt | 2 + launcher/minecraft/auth/flows/Elyby.cpp | 6 +- .../minecraft/auth/steps/ElybyProfileStep.cpp | 90 +++++++++++++++++++ .../minecraft/auth/steps/ElybyProfileStep.h | 22 +++++ 4 files changed, 117 insertions(+), 3 deletions(-) create mode 100644 launcher/minecraft/auth/steps/ElybyProfileStep.cpp create mode 100644 launcher/minecraft/auth/steps/ElybyProfileStep.h diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 42a681bf6f..b895cec040 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -248,6 +248,8 @@ set(MINECRAFT_SOURCES minecraft/auth/steps/MigrationEligibilityStep.h minecraft/auth/steps/MinecraftProfileStep.cpp minecraft/auth/steps/MinecraftProfileStep.h + minecraft/auth/steps/ElybyProfileStep.cpp + minecraft/auth/steps/ElybyProfileStep.h minecraft/auth/steps/MSAStep.cpp minecraft/auth/steps/MSAStep.h minecraft/auth/steps/LocalStep.cpp diff --git a/launcher/minecraft/auth/flows/Elyby.cpp b/launcher/minecraft/auth/flows/Elyby.cpp index 24ce24abea..e8422540ad 100644 --- a/launcher/minecraft/auth/flows/Elyby.cpp +++ b/launcher/minecraft/auth/flows/Elyby.cpp @@ -1,14 +1,14 @@ #include "Elyby.h" #include "minecraft/auth/steps/YggdrasilStep.h" -#include "minecraft/auth/steps/GetSkinStep.h" +#include "minecraft/auth/steps/ElybyProfileStep.h" ElybyRefresh::ElybyRefresh( AccountData *data, QObject *parent ) : AuthFlow(data, parent) { m_steps.append(new YggdrasilStep(m_data, QString())); - m_steps.append(new GetSkinStep(m_data)); + m_steps.append(new ElybyProfileStep(m_data)); } ElybyLogin::ElybyLogin( @@ -17,5 +17,5 @@ ElybyLogin::ElybyLogin( QObject *parent ): AuthFlow(data, parent), m_password(password) { m_steps.append(new YggdrasilStep(m_data, m_password)); - m_steps.append(new GetSkinStep(m_data)); + m_steps.append(new ElybyProfileStep(m_data)); } diff --git a/launcher/minecraft/auth/steps/ElybyProfileStep.cpp b/launcher/minecraft/auth/steps/ElybyProfileStep.cpp new file mode 100644 index 0000000000..310e71d48b --- /dev/null +++ b/launcher/minecraft/auth/steps/ElybyProfileStep.cpp @@ -0,0 +1,90 @@ +#include "ElybyProfileStep.h" + +#include + +#include "minecraft/auth/AuthRequest.h" +#include "minecraft/auth/Parsers.h" + +ElybyProfileStep::ElybyProfileStep(AccountData* data) : AuthStep(data) { + +} + +ElybyProfileStep::~ElybyProfileStep() noexcept = default; + +QString ElybyProfileStep::describe() { + return tr("Fetching the Ely.by profile."); +} + + +void ElybyProfileStep::perform() { + auto url = QUrl(QString("https://authserver.ely.by/api/users/profiles/minecraft/%1").arg(m_data->userName()).toUtf8()); + QNetworkRequest request = QNetworkRequest(url); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + + AuthRequest *requestor = new AuthRequest(this); + connect(requestor, &AuthRequest::finished, this, &ElybyProfileStep::onRequestDone); + requestor->get(request); +} + +void ElybyProfileStep::rehydrate() { + // NOOP, for now. We only save bools and there's nothing to check. +} + +void ElybyProfileStep::onRequestDone( + QNetworkReply::NetworkError error, + QByteArray data, + QList headers +) { + auto requestor = qobject_cast(QObject::sender()); + requestor->deleteLater(); + +#ifndef NDEBUG + qDebug() << data; +#endif + 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); + + emit finished( + AccountTaskState::STATE_FAILED_SOFT, + tr("Minecraft Java profile acquisition failed.") + ); + return; + } + if(!Parsers::parseMinecraftProfile(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/ElybyProfileStep.h b/launcher/minecraft/auth/steps/ElybyProfileStep.h new file mode 100644 index 0000000000..765d79e96b --- /dev/null +++ b/launcher/minecraft/auth/steps/ElybyProfileStep.h @@ -0,0 +1,22 @@ +#pragma once +#include + +#include "QObjectPtr.h" +#include "minecraft/auth/AuthStep.h" + + +class ElybyProfileStep : public AuthStep { + Q_OBJECT + +public: + explicit ElybyProfileStep(AccountData *data); + virtual ~ElybyProfileStep() noexcept; + + void perform() override; + void rehydrate() override; + + QString describe() override; + +private slots: + void onRequestDone(QNetworkReply::NetworkError, QByteArray, QList); +};