Files
minecraft-launcher/modloaderinstaller.h
T

107 lines
4.0 KiB
C++
Raw Normal View History

#pragma once
#include "modloader.h"
#include <QObject>
#include <QString>
#include <QStringList>
class QNetworkAccessManager;
class QNetworkReply;
class QProcess;
class ModLoaderVersionService;
class VersionInstaller;
// Установка модлоадера в .minecraft. Два разных пути под одним фасадом:
//
// * Fabric и Quilt отдают готовое описание версии — кладём его в
// versions/<id>/<id>.json и передаём дальше VersionInstaller, который по
// inheritsFrom сам поставит ванильную версию и библиотеки лоадера.
//
// * Forge и NeoForge так не умеют: их установка — это патч клиентского jar,
// поэтому запускаем официальный installer.jar найденной Java в headless-режиме
// и смотрим, какой профиль появился в versions.
//
// Набор геттеров повторяет VersionInstaller: панель загрузки в интерфейсе
// читает их одинаково, независимо от того, кто сейчас работает.
class ModLoaderInstaller : public QObject
{
Q_OBJECT
public:
ModLoaderInstaller(ModLoaderVersionService *meta,
VersionInstaller *versionInstaller,
QObject *parent = nullptr);
~ModLoaderInstaller() override;
bool isRunning() const { return m_running; }
QString label() const { return m_label; }
QString stage() const { return m_stage; }
QString currentFile() const { return m_currentFile; }
qint64 bytesDone() const { return m_bytesDone; }
qint64 bytesTotal() const { return m_bytesTotal; }
double fraction() const; // 0..1, либо -1 пока итог неизвестен
void install(const QString &gameDir,
ModLoader loader,
const QString &gameVersion,
const QString &loaderVersion,
const QString &javaPreference);
void cancel();
signals:
void started(const QString &label);
void progressChanged();
void finished(const QString &loaderKey,
const QString &gameVersion,
const QString &loaderVersion,
const QString &producedVersionId);
void failed(const QString &label, const QString &message);
void canceled(const QString &label);
void log(const QString &line);
private:
void beginFabricLike();
void beginInstallerJar();
void ensureBaseVersion(std::function<void()> next);
void downloadInstaller(const QUrl &url, std::function<void(const QString &)> next);
bool writeLauncherProfilesStub();
void runInstaller(const QString &installerPath);
void handleInstallerFinished(int exitCode, bool crashed);
void handOffToVersionInstaller(const QString &versionId);
void setStage(const QString &stage);
void reset();
void fail(const QString &message);
ModLoaderVersionService *m_meta;
VersionInstaller *m_versionInstaller;
QNetworkAccessManager *m_network;
QNetworkReply *m_reply = nullptr;
QProcess *m_process = nullptr;
QString m_gameDir;
ModLoader m_loader = ModLoader::Fabric;
QString m_gameVersion;
QString m_loaderVersion;
QString m_javaPreference;
QString m_label;
QString m_stage;
QString m_currentFile;
qint64 m_bytesDone = 0;
qint64 m_bytesTotal = 0;
// Профили, которые были в versions до запуска installer.jar: новый ищем
// разницей, а не угадыванием строки — id у Forge разные по эпохам.
QStringList m_versionsBefore;
QStringList m_installerLog;
// Ждём, пока VersionInstaller докачает то, что установщик не положил.
QString m_awaitingVersionId;
bool m_running = false;
bool m_canceling = false;
};