# javaruntime.h — JavaRuntime, JavaRuntimeStore и JavaRequirement

## Обзор

`Minecraft_launcher` умеет скачивать Java сам: официальные сборки Mojang — те же, которыми игру
запускает официальный лаунчер, — и сборки Eclipse Temurin в вариантах JDK и JRE. Скачанные сборки
живут в папке лаунчера, по одной подпапке на сборку.

Заголовок `javaruntime.h` — словарь этой части проекта. Он даёт перечисление видов сборок, две
структуры (строка каталога и уже установленная сборка), пространство имён для работы с папкой
`<root>/java` и таблицу требований версий игры к Java.

Заголовок подключают [JavaRuntimeService](JavaRuntimeService.md) (каталог),
[JavaInstaller](JavaInstaller.md) (скачивание и распаковка) и
[LauncherBackend](LauncherBackend.md) (отдача каталога в QML).

## Типы

| Имя | Вид | Описание |
|-----|-----|----------|
| `JavaRuntimeKind` | `enum class` | Откуда взялась сборка и что именно в ней лежит |
| `JavaRuntimeEntry` | `struct` | Строка каталога — то, что можно скачать |
| `InstalledJavaRuntime` | `struct` | Сборка, уже распакованная в папке лаунчера |

### JavaRuntimeKind

| Значение | Ключ | Описание |
|----------|------|----------|
| `Mojang` | `java` | Тот же рантайм, которым игру запускает официальный лаунчер |
| `Jdk` | `jdk` | Eclipse Temurin JDK: компилятор и инструменты в комплекте |
| `Jre` | `jre` | Eclipse Temurin JRE: только то, что нужно для запуска |

Эти же ключи служат именами категорий в окне выбора Java.

### JavaRuntimeEntry

| Поле | Тип | Описание |
|------|-----|----------|
| `id` | `QString` | Идентификатор сборки, например `temurin-jdk-21.0.12.1_1` или `mojang-java-runtime-delta` |
| `kind` | `JavaRuntimeKind` | Вид сборки; по умолчанию `Jdk` |
| `major` | `int` | Мажорная версия: 8, 17, 21… |
| `version` | `QString` | Полная версия, например `21.0.12.1+1` или `21.0.7` |
| `component` | `QString` | Имя компонента вида `java-runtime-delta`; только у сборок Mojang |
| `released` | `QDateTime` | Дата выпуска; по ней каталог сортируется новыми вперёд |
| `url` | `QUrl` | Архив Temurin либо `manifest.json` компонента Mojang |
| `checksum` | `QString` | sha256 архива Temurin или sha1 манифеста Mojang |
| `size` | `qint64` | Размер загрузки в байтах; `0` — неизвестен |
| `archive` | `QString` | Формат: `zip`, `tar.gz` или `mojang` — последний означает не архив, а манифест с пофайловой загрузкой |
| `architecture` | `QString` | `x64` или `aarch64`; на macOS бывает и не родная архитектура |
| `lts` | `bool` | Версия с длительной поддержкой; помечается в списке |

Метод `isValid()` возвращает `true`, когда заполнен `id`, `major` больше нуля и `url` корректен.

### InstalledJavaRuntime

| Поле | Тип | Описание |
|------|-----|----------|
| `id` | `QString` | Идентификатор сборки, он же имя подпапки |
| `kind` | `QString` | Вид сборки строкой: `java`, `jdk` или `jre` |
| `major` | `int` | Мажорная версия |
| `version` | `QString` | Полная версия |
| `javaPath` | `QString` | Абсолютный путь к исполняемому файлу `java` или `java.exe` |
| `size` | `qint64` | Сколько сборка заняла на диске по итогам установки |

## Функции

### Перевод видов сборок

#### QString javaKindKey(JavaRuntimeKind kind)

Строковый ключ вида сборки: `java`, `jdk` или `jre`.

#### std::optional&lt;JavaRuntimeKind&gt; javaKindFromKey(const QString &key)

Обратный перевод; `std::nullopt` для неизвестного ключа.

#### QString javaKindTitle(JavaRuntimeKind kind)

Человекочитаемое название вида сборки для интерфейса.

### JavaRuntimeStore — папка `<root>/java`

Устройство папки: одна подпапка на сборку плюс её описание внутри. Отдельного индекса нет
намеренно — удалённую вручную папку не пришлось бы вычищать ещё и из общего файла.

#### QString dirFor(const QString &id)

Папка конкретной сборки внутри `<root>/java`.

#### QList&lt;InstalledJavaRuntime&gt; installed()

Всё, что лежит в `<root>/java` и на что нашлась java. Новые версии идут первыми.

#### std::optional&lt;InstalledJavaRuntime&gt; find(const QString &id)

Описание одной установленной сборки; `std::nullopt`, если такой нет.

#### QString locateBinary(const QString &rootDir)

Ищет `bin/java` в распакованном дереве. Раскладка отличается между поставщиками: у Temurin на macOS
это `Contents/Home/bin`, у Mojang — `jre.bundle/Contents/Home/bin`.

#### bool writeMeta(const InstalledJavaRuntime &runtime, QString \*error)

Записывает описание сборки в её папку. Вызывается по завершении установки. При неудаче возвращает
`false` и заполняет `error`.

#### bool remove(const QString &id, QString \*error)

Удаляет папку сборки целиком. При неудаче возвращает `false` и заполняет `error`.

#### QString sanitizeId(const QString &id)

Превращает идентификатор каталога в безопасное имя папки: всё, кроме букв, цифр, точки, дефиса и
подчёркивания, заменяется. Идентификатор приходит из сети, поэтому подставлять его в путь как есть
нельзя.

### JavaRequirement — какая Java нужна какой версии игры

Точный ответ лежит в `client.json` версии (поле `javaVersion.majorVersion`) и берётся оттуда при
запуске. Эта таблица нужна раньше — когда версия ещё не скачана, а подсказку в каталоге показать
надо.

#### int minimumFor(const QString &minecraftVersionId)

Минимальная мажорная версия Java для версии игры; `0`, если разобрать идентификатор версии не
удалось.

#### QString coverage(int javaMajor)

Подпись к строке каталога вида «Minecraft 1.20.5 и новее» — какие версии игры покрывает эта версия
Java.

## Зависимости

Подключает `QDateTime`, `QList`, `QString`, `QUrl` и `<optional>` — только Qt Core. От классов
проекта не зависит.

## Пример использования

```cpp
const auto runtime = JavaRuntimeStore::find(settings.javaRuntime);
if (runtime && QFileInfo::exists(runtime->javaPath)) {
    javaPath = runtime->javaPath;
} else {
    // сборка удалена вручную — возвращаемся к поиску в системе
    javaPath = JavaLocator::select(gameDir, version.javaMajor, settings.javaPath, &error);
}
```

---

При создании этого документа использовался ИИ.
