95 lines
4.1 KiB
C++
95 lines
4.1 KiB
C++
#pragma once
|
|
|
|
#include "javaruntime.h"
|
|
|
|
#include <QDateTime>
|
|
#include <QHash>
|
|
#include <QList>
|
|
#include <QObject>
|
|
#include <QSet>
|
|
|
|
#include <functional>
|
|
|
|
class QNetworkAccessManager;
|
|
|
|
// Каталог сборок Java, которые лаунчер умеет скачать: качает, кэширует в папке
|
|
// лаунчера и отдаёт из кэша, пока тот не устарел. Устроен как
|
|
// VersionManifestService и работает в GUI-потоке.
|
|
//
|
|
// Источников два и они дополняют друг друга:
|
|
//
|
|
// * Mojang (категория «Java») — ровно тот рантайм, которым запускает игру
|
|
// официальный лаунчер. Версий немного, зато они заведомо совместимы.
|
|
//
|
|
// * Eclipse Temurin (категории JDK и JRE) — свежие сборки всех мажорных
|
|
// версий, включая те, до которых Mojang ещё не дошёл.
|
|
//
|
|
// Отдаются только сборки под текущие ОС и архитектуру: выбрать заведомо
|
|
// неработающую нечем. Исключение — macOS на Apple Silicon, где под Java 8 и 16
|
|
// сборок aarch64 нет вовсе и приходится брать x64 (работает через Rosetta).
|
|
class JavaRuntimeService : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
// ok = true и непустой warning — данные отдали из устаревшего кэша.
|
|
using Callback = std::function<void(bool ok, const QString &warning)>;
|
|
|
|
explicit JavaRuntimeService(QObject *parent = nullptr);
|
|
|
|
void ensureLoaded(Callback callback, bool forceRefresh = false);
|
|
|
|
// Новые версии сверху.
|
|
QList<JavaRuntimeEntry> entries(JavaRuntimeKind kind) const;
|
|
std::optional<JavaRuntimeEntry> find(const QString &id) const;
|
|
|
|
// Что скачать, если для версии игры нужна Java major, а подходящей в
|
|
// системе нет. Точное совпадение мажорной версии предпочтительнее более
|
|
// новой, JDK — предпочтительнее JRE: установщики Forge и NeoForge иногда
|
|
// требуют инструментов из полного комплекта. Пусто — предложить нечего.
|
|
std::optional<JavaRuntimeEntry> bestFor(int major) const;
|
|
|
|
bool isRefreshing() const { return m_outstanding > 0; }
|
|
bool hasData() const { return !m_entries.isEmpty(); }
|
|
|
|
signals:
|
|
void catalogChanged();
|
|
void refreshingChanged();
|
|
|
|
private:
|
|
void startRefresh();
|
|
void requestAdoptiumReleases();
|
|
// allowFallback — на macOS/aarch64 разрешено переспросить сборку под x64.
|
|
void requestFeatureRelease(int major, const QString &architecture, bool allowFallback);
|
|
void requestMojangRuntimes();
|
|
|
|
// Общий хвост любого запроса: считает незавершённые и, когда их не
|
|
// осталось, применяет накопленное.
|
|
void requestFinished(const QString &warning);
|
|
void finishRefresh();
|
|
|
|
static QList<JavaRuntimeEntry> parseAdoptium(const QByteArray &payload,
|
|
const QSet<int> <sVersions);
|
|
static QList<JavaRuntimeEntry> parseMojang(const QByteArray &payload);
|
|
|
|
void applyEntries(QList<JavaRuntimeEntry> list);
|
|
bool readCache();
|
|
void writeCache();
|
|
|
|
QNetworkAccessManager *m_network;
|
|
|
|
QList<JavaRuntimeEntry> m_entries;
|
|
QHash<QString, int> m_indexById;
|
|
QDateTime m_fetchedAt;
|
|
bool m_cacheRead = false;
|
|
|
|
// Накопитель одного обновления: ответы приходят вразнобой, каталог
|
|
// подменяется целиком и только когда пришли все.
|
|
QList<JavaRuntimeEntry> m_incoming;
|
|
QStringList m_warnings;
|
|
QSet<int> m_ltsVersions;
|
|
int m_outstanding = 0;
|
|
|
|
QList<Callback> m_pending;
|
|
};
|