#pragma once #include "authservice.h" #include #include #include #include #include class QNetworkAccessManager; // Авторизация через аккаунт Microsoft — та же цепочка, что и в официальном // лаунчере: OAuth2 -> Xbox Live -> XSTS -> Minecraft Services -> проверка // лицензии. Результат отдаётся тем же AuthResult, что и Ely.by с офлайном, // поэтому запуск игры дальше идёт по общему пути. class MsaAuthService : public QObject { Q_OBJECT public: using Callback = std::function; explicit MsaAuthService(QObject *parent = nullptr); // Id приложения лаунчера. Игра ждёт его в ${clientid}: официальный лаунчер // подставляет туда именно id приложения, а не случайный токен сессии. static QString clientId(); // Адрес страницы входа для встроенного окна. static QUrl authorizationUrl(); // Отличает адрес, на который Microsoft возвращает управление после входа, // от остальной навигации внутри окна. Заполняет code либо error. static bool matchRedirect(const QUrl &url, QString *code, QString *error); // Полный вход по коду из окна браузера. void loginWithCode(const QString &code, Callback callback); // Продление сессии без участия пользователя. Refresh-токен Microsoft живёт // куда дольше суточного токена Minecraft, так что обычно хватает его. void loginWithRefreshToken(const QString &refreshToken, Callback callback); signals: void progress(const QString &message); private: using JsonHandler = std::function; void postForm(const QUrl &url, const QByteArray &body, JsonHandler handler); void postJson(const QUrl &url, const QJsonObject &body, const QString &bearer, JsonHandler handler); void getJson(const QUrl &url, const QString &bearer, JsonHandler handler); // Шаги цепочки. Каждый следующий вызывается из колбэка предыдущего. void exchangeToken(const QByteArray &form, Callback callback); void authenticateXbox(const QString µsoftToken, const QString &refreshToken, Callback callback); void authorizeXsts(const QString &xblToken, const QString &refreshToken, Callback callback); void loginWithXbox(const QString &userHash, const QString &xstsToken, const QString &xuid, const QString &refreshToken, Callback callback); void checkLicense(AuthResult result, Callback callback); void fetchProfile(AuthResult result, bool storeEntitlement, Callback callback); QNetworkAccessManager *m_network; };