Files
minecraft-launcher/authservice.h
T

77 lines
3.0 KiB
C++

#pragma once
#include <QJsonObject>
#include <QObject>
#include <QString>
#include <functional>
class QNetworkAccessManager;
// Результат авторизации — то, что подставляется в ${auth_*} аргументы запуска.
struct AuthResult
{
bool ok = false;
bool twoFactorRequired = 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
};
// Yggdrasil-клиент Ely.by плюс офлайн-режим. Все сетевые методы асинхронные:
// колбэк вызывается один раз в потоке GUI.
class AuthService : public QObject
{
Q_OBJECT
public:
using Callback = std::function<void(const AuthResult &)>;
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<void(const QString &path, const QString &error)> callback);
signals:
void progress(const QString &message);
private:
void postJson(const QString &endpoint,
const QJsonObject &body,
std::function<void(int status, const QJsonObject &response, const QString &transportError)> handler);
void authenticate(const QString &login,
const QString &password,
const QString &clientToken,
Callback callback);
QNetworkAccessManager *m_network;
};