149 lines
5.6 KiB
C++
149 lines
5.6 KiB
C++
#pragma once
|
|
|
|
#include "minecraftversion.h"
|
|
|
|
#include <QJsonArray>
|
|
#include <QJsonDocument>
|
|
#include <QJsonObject>
|
|
#include <QObject>
|
|
#include <QQmlEngine>
|
|
#include <QStringList>
|
|
#include <QVariantMap>
|
|
|
|
struct AuthResult;
|
|
class AuthService;
|
|
class GameLauncher;
|
|
|
|
class LauncherBackend : public QObject
|
|
{
|
|
Q_OBJECT
|
|
QML_ELEMENT
|
|
|
|
Q_PROPERTY(QStringList profileNames READ profileNames NOTIFY profilesChanged)
|
|
Q_PROPERTY(QStringList versionNames READ versionNames NOTIFY versionsChanged)
|
|
Q_PROPERTY(QStringList installedVersions READ installedVersions NOTIFY installedVersionsChanged)
|
|
Q_PROPERTY(bool gameRunning READ gameRunning NOTIFY gameRunningChanged)
|
|
Q_PROPERTY(bool busy READ busy NOTIFY busyChanged)
|
|
|
|
public:
|
|
explicit LauncherBackend(QObject *parent = nullptr);
|
|
~LauncherBackend() override;
|
|
|
|
QStringList profileNames() const;
|
|
QStringList versionNames() const;
|
|
QStringList installedVersions() const;
|
|
bool gameRunning() const;
|
|
bool busy() const { return m_busy; }
|
|
|
|
Q_INVOKABLE void addProfile(const QString &name,
|
|
const QString &login,
|
|
const QString &password,
|
|
const QString &authType = QStringLiteral("offline"));
|
|
Q_INVOKABLE void addVersion(const QString &name,
|
|
const QString &serverUrl,
|
|
const QString &versionId = QString());
|
|
Q_INVOKABLE void updateProfile(int index,
|
|
const QString &name,
|
|
const QString &login,
|
|
const QString &password,
|
|
const QString &authType = QStringLiteral("offline"));
|
|
Q_INVOKABLE void updateVersion(int index,
|
|
const QString &name,
|
|
const QString &serverUrl,
|
|
const QString &versionId = QString());
|
|
Q_INVOKABLE QVariantMap profileAt(int index) const;
|
|
Q_INVOKABLE QVariantMap versionAt(int index) const;
|
|
Q_INVOKABLE void removeProfile(int index);
|
|
Q_INVOKABLE void removeVersion(int index);
|
|
|
|
// Главная кнопка. Проверяет выбор профиля и версии, комплектность .minecraft,
|
|
// при необходимости авторизуется и стартует игру.
|
|
Q_INVOKABLE void launchGame(int profileIndex, int versionIndex);
|
|
Q_INVOKABLE void submitTwoFactorCode(const QString &code);
|
|
Q_INVOKABLE void cancelPendingLaunch();
|
|
Q_INVOKABLE void stopGame();
|
|
|
|
// Проверка без запуска — для подсказки в интерфейсе.
|
|
Q_INVOKABLE QStringList checkInstallation(int versionIndex) const;
|
|
|
|
Q_INVOKABLE QVariantMap settings() const;
|
|
Q_INVOKABLE void updateSettings(const QVariantMap &values);
|
|
Q_INVOKABLE QStringList detectedJava() const;
|
|
|
|
Q_INVOKABLE void openMinecraftFolder();
|
|
Q_INVOKABLE void openGameFolder();
|
|
|
|
signals:
|
|
void profilesChanged();
|
|
void versionsChanged();
|
|
void installedVersionsChanged();
|
|
void settingsChanged();
|
|
void gameRunningChanged();
|
|
void busyChanged();
|
|
|
|
void launchProgress(const QString &message);
|
|
void launched(const QString &profileName, const QString &versionName, const QString &serverUrl);
|
|
void launchError(const QString &message);
|
|
void twoFactorRequired(const QString &profileName);
|
|
void gameOutput(const QString &line);
|
|
void gameFinished(int exitCode, bool crashed);
|
|
|
|
private:
|
|
struct Profile
|
|
{
|
|
int id = 0;
|
|
QString name, login, password;
|
|
QString authType = QStringLiteral("offline"); // offline | elyby
|
|
QString clientToken, accessToken, uuid, resolvedName, userType;
|
|
};
|
|
struct Version
|
|
{
|
|
int id = 0;
|
|
QString name, serverUrl, versionId;
|
|
};
|
|
|
|
void loadData();
|
|
void loadSettings();
|
|
void ensureDataFiles();
|
|
void saveProfiles();
|
|
void saveVersions();
|
|
void saveSettings();
|
|
|
|
// Чтение файлов лаунчера. Отсутствие файла — норма (первый запуск), а вот
|
|
// повреждённое содержимое отводится в .bak, чтобы файл создался заново.
|
|
QJsonArray readArrayFile(const QString &path);
|
|
QJsonObject readObjectFile(const QString &path);
|
|
bool moveAsideBroken(const QString &path, const QString &reason);
|
|
|
|
// Проверяет папку лаунчера и пишет документ. Об ошибке сообщает через launchError.
|
|
bool writeJsonFile(const QString &path, const QJsonDocument &document);
|
|
|
|
QString gameDir() const;
|
|
QString versionIdOf(const Version &version) const;
|
|
|
|
void setBusy(bool busy);
|
|
void failLaunch(const QString &message);
|
|
void beginAuthentication();
|
|
void continueLaunch(const AuthResult &auth);
|
|
|
|
QList<Profile> m_profiles;
|
|
QList<Version> m_versions;
|
|
QVariantMap m_settings;
|
|
// Проблемы хранилища, замеченные на старте: показываются одним сообщением,
|
|
// когда интерфейс уже подключился к сигналам.
|
|
QStringList m_storageIssues;
|
|
int m_nextProfileId = 1;
|
|
int m_nextVersionId = 1;
|
|
|
|
AuthService *m_auth;
|
|
GameLauncher *m_launcher;
|
|
|
|
bool m_busy = false;
|
|
|
|
// Состояние запуска, начатого до асинхронной авторизации.
|
|
int m_pendingProfile = -1;
|
|
int m_pendingVersion = -1;
|
|
MinecraftVersion m_pendingVersionData;
|
|
QString m_pendingInjectorPath;
|
|
};
|