#pragma once #include "minecraftversion.h" #include #include #include #include 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 saveProfiles(); void saveVersions(); void saveSettings(); QString defaultMinecraftDir() const; 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 m_profiles; QList m_versions; QVariantMap m_settings; QString m_dataDir; 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; };