#pragma once #include #include #include #include #include class QNetworkAccessManager; // Результат авторизации — то, что подставляется в ${auth_*} аргументы запуска. struct AuthResult { bool ok = false; bool twoFactorRequired = false; // Вход в Microsoft прошёл, но копии игры на аккаунте нет: чинится только // покупкой, поэтому обрабатывается отдельно от прочих ошибок. bool licenseMissing = false; QString error; QString playerName; // ${auth_player_name} QString uuid; // ${auth_uuid}, hex без дефисов QString accessToken; // ${auth_access_token} QString clientToken; // ${clientid} QString userType; // ${user_type}: legacy / msa / ELYBY // Только для аккаунтов Microsoft. QString refreshToken; // продлевает сессию без ввода пароля QString xuid; // ${auth_xuid} QDateTime expiresAt; // UTC-время, когда протухает accessToken }; // Yggdrasil-клиент Ely.by плюс офлайн-режим. Все сетевые методы асинхронные: // колбэк вызывается один раз в потоке GUI. class AuthService : public QObject { Q_OBJECT public: using Callback = std::function; explicit AuthService(QObject *parent = nullptr); // UUID выводится из ника так же, как это делает сам Minecraft в офлайне: // UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(UTF_8)). static AuthResult offline(const QString &nickname); // Случайный clientToken лаунчера — генерируется один раз на профиль. static QString generateClientToken(); // Полный цикл: validate -> refresh -> authenticate. password можно оставить // пустым, если уже есть рабочий accessToken. void loginElyBy(const QString &login, const QString &password, const QString &clientToken, const QString &accessToken, Callback callback); // Повтор авторизации с одноразовым кодом двухфакторки (пароль:код). void loginElyByWithTotp(const QString &login, const QString &password, const QString &totp, const QString &clientToken, Callback callback); // Скачивает authlib-injector в targetDir, если его там ещё нет. // Колбэк получает путь к jar либо текст ошибки. void ensureAuthlibInjector(const QString &targetDir, std::function callback); signals: void progress(const QString &message); private: void postJson(const QString &endpoint, const QJsonObject &body, std::function handler); void authenticate(const QString &login, const QString &password, const QString &clientToken, Callback callback); QNetworkAccessManager *m_network; };