Files
2026-09-03 09:16:56 +03:00

166 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Minecraft Launcher — справочник по исходному коду
Десктопный лаунчер Minecraft на Qt 6. Интерфейс написан на QML, вся работа — авторизация,
скачивание версий, установка модлоадеров и Java, запуск игры — лежит в C++.
Документация разделена на две части: [QML-компоненты](#qml-компоненты) и
[C++-классы](#c-классы).
## Как устроено приложение
Слоёв четыре, и каждый общается только с соседними:
1. **QML.** [Main](qml/Main.md) — единственное настоящее окно и точка входа. Оно держит
единственный экземпляр `LauncherBackend` и раздаёт его вложенным диалогам через свойство
`backend`. Ни один QML-файл не обращается к сервисам напрямую.
2. **Фасад.** [LauncherBackend](cpp/LauncherBackend.md) — главный класс, видимый из QML.
Хранит профили, сборки и настройки, владеет двенадцатью сервисами и сводит их состояние к
свойствам, которые читает интерфейс. Каталоги он отдаёт уже сведёнными с локальным состоянием,
поэтому окна показывают статус, не считая ничего сами.
3. **Сервисы.** Каталоги (версий, модлоадеров, Java, сезонных сборок), установщики, службы
авторизации, переключатель сборок и запуск игры. Каждый занят одним делом и ничего не знает об
интерфейсе.
Особняком стоит [Localization](cpp/Localization.md) — второй и последний тип, видимый из QML.
Это синглтон `Loc`, через который проходят все тексты интерфейса: `Loc.t.домен.вид.имя` в QML и
`Loc::text("домен.вид.имя")` в C++. Он ни от чего не зависит и доступен всем слоям сразу.
4. **Внешний мир.** Сеть (Mojang, Ely.by, Microsoft, Adoptium, файловый сервер сборок), файловая
система (`.minecraft` и папка лаунчера) и дочерние процессы (java, установщики модлоадеров,
`tar`).
Почти весь код работает в потоке GUI: параллелизм даёт асинхронная сеть, а не потоки. Единственное
исключение — операции над содержимым `.minecraft` (гигабайты модов и миров), вынесенные в
отдельный поток к [BuildArchiveWorker](cpp/BuildArchiveWorker.md).
## QML-компоненты
| Компонент | Описание |
|-----------|----------|
| [Main](qml/Main.md) | Главное окно и точка входа: экран запуска, профили, плашка сообщений, панели прогресса и внутренние диалоги |
| [BuildsDialog](qml/BuildsDialog.md) | Пользовательские сборки: список слева, карточка редактирования справа |
| [VersionPickerDialog](qml/VersionPickerDialog.md) | Выбор версии Minecraft: категории, поиск, удаление скачанных версий |
| [JavaPickerDialog](qml/JavaPickerDialog.md) | Выбор сборки Java; подтверждение при необходимости сразу начинает загрузку |
| [SeasonalBuildsDialog](qml/SeasonalBuildsDialog.md) | Каталог готовых сезонных сборок таблицей и установка одной кнопкой |
| [MicrosoftLoginDialog](qml/MicrosoftLoginDialog.md) | Окно входа в аккаунт Microsoft; собирается только с Qt WebEngine |
| [LoaderRow](qml/LoaderRow.md) | Одна строка модлоадера в карточке сборки: чекбокс и список версий |
| [ProgressPanel](qml/ProgressPanel.md) | Плашка хода долгой операции в левом нижнем углу |
| [DarkCombo](qml/DarkCombo.md) | Выпадающий список в тёмном стиле окна |
| [LabelledField](qml/LabelledField.md) | Подпись и поле ввода одной колонкой |
## C++-классы
### Точка входа
| Файл | Описание |
|------|----------|
| [main.cpp](cpp/main.md) | Инициализация WebEngine, объект приложения, каталог переводов, стиль `Basic`, загрузка QML-модуля |
### Фасад
| Класс | Описание |
|-------|----------|
| [Localization](cpp/Localization.md) | Синглтон `Loc`: все тексты интерфейса в одном файле `i18n/translations.json`, переключение языка на лету |
| [LauncherBackend](cpp/LauncherBackend.md) | Единственный тип, видимый из QML: 26 свойств, 42 вызываемых метода, состояние лаунчера и порядок работы всех сервисов |
### Авторизация и запуск
| Класс | Описание |
|-------|----------|
| [AuthService](cpp/AuthService.md) | Вход через Ely.by и офлайн-режим; структура `AuthResult` |
| [MsaAuthService](cpp/MsaAuthService.md) | Вход через аккаунт Microsoft: OAuth2 → Xbox Live → XSTS → Minecraft Services |
| [GameLauncher](cpp/GameLauncher.md) | Сборка командной строки, распаковка нативных библиотек и запуск JVM |
### Версии игры
| Класс | Описание |
|-------|----------|
| [VersionManifestService](cpp/VersionManifestService.md) | Каталог версий Mojang с кэшем в папке лаунчера |
| [VersionInstaller](cpp/VersionInstaller.md) | Фоновая установка версии: jar, библиотеки, индекс ресурсов и сами ресурсы |
### Модлоадеры
| Класс | Описание |
|-------|----------|
| [ModLoaderVersionService](cpp/ModLoaderVersionService.md) | Списки версий Forge, Fabric, NeoForge и Quilt; совместимость заложена в структуру данных |
| [ModLoaderInstaller](cpp/ModLoaderInstaller.md) | Два пути установки под одним фасадом: готовое описание версии либо запуск `installer.jar` |
### Java
| Класс | Описание |
|-------|----------|
| [JavaRuntimeService](cpp/JavaRuntimeService.md) | Каталог сборок Mojang и Eclipse Temurin под текущую платформу |
| [JavaInstaller](cpp/JavaInstaller.md) | Установка сборки Java: архив Temurin либо дерево файлов Mojang |
### Сборки и их содержимое
| Класс | Описание |
|-------|----------|
| [BuildSwitcher](cpp/BuildSwitcher.md) | Порядок шагов смены активной сборки и восстановление после прерванной операции |
| [BuildArchiveWorker](cpp/BuildArchiveWorker.md) | Упаковка, очистка, распаковка и раскатка пака в отдельном потоке |
### Сезонные сборки
| Класс | Описание |
|-------|----------|
| [SeasonalBuildService](cpp/SeasonalBuildService.md) | Каталог готовых сборок с файлового сервера |
| [SeasonalPackDownloader](cpp/SeasonalPackDownloader.md) | Загрузка архива сборки потоком с проверкой sha256 |
### Общие типы и утилиты
| Файл | Описание |
|------|----------|
| [minecraftversion.h](cpp/minecraftversion.md) | Структуры версии и библиотеки, чтение и разворачивание цепочки `inheritsFrom` |
| [javaruntime.h](cpp/javaruntime.md) | Виды сборок Java, папка `<root>/java` и таблица требований версий игры |
| [modloader.h](cpp/modloader.md) | Перечисление модлоадеров, запись версии и перевод ключей |
| [launcherpaths.h](cpp/launcherpaths.md) | Все пути к данным лаунчера в одном месте |
| [javalocator.h](cpp/javalocator.md) | Поиск установленной в системе Java и выбор подходящей версии |
| [zlibreference.h](cpp/zlibreference.md) | Подмена zlib-ng эталонным zlib для установщиков Forge и NeoForge |
## Сборка
Требуется Qt 6.8 или новее. Обязательные модули: `Quick`, `QuickControls2`, `Core`, `CorePrivate`,
`Gui`, `Network`. `CorePrivate` нужен ради `QZipReader` и `QZipWriter` — ими распаковываются
нативные библиотеки LWJGL и архивы сборок; привязка к версии Qt из-за приватного модуля —
осознанный выбор, и предупреждение о ней в `CMakeLists.txt` отключено.
`Qt6::WebEngineQuick` необязателен, и это принципиально: модуль ставится отдельной галочкой в
установщике Qt и тянет за собой WebChannel с Positioning, которых в типовой установке нет. Если
сделать его обязательным, у любого, кто их не поставил, проект перестанет конфигурироваться
целиком — вместе с офлайном и Ely.by. Когда модуль найден, определяется макрос
`LAUNCHER_HAS_WEBENGINE`, а [MicrosoftLoginDialog.qml](qml/MicrosoftLoginDialog.md) добавляется в
QML-модуль; без модуля лаунчер собирается и работает как обычно, только вход через Microsoft
сообщает, что эта сборка его не умеет. В QML различие видно через свойство
`backend.microsoftAvailable`.
QML-модуль объявлен как `qt_add_qml_module` с URI `Minecraft_launcher`; точка входа —
`engine.loadFromModule("Minecraft_launcher", "Main")`. Туда же, в список `RESOURCES`, попадает
каталог переводов `i18n/translations.json`.
### Тексты интерфейса
Все подписи, сообщения и ошибки лежат в одном файле `i18n/translations.json` и достаются через
синглтон `Loc` — подробности, правила именования ключей и порядок добавления языка описаны в
[Localization](cpp/Localization.md). Штатные `.ts`/`.qm` не используются, `lupdate` и `lrelease`
в сборке не участвуют. Целостность каталога проверяет `python3 tools/check_translations.py`.
### Каталог `zlib/`
В репозитории лежат исходники обычного zlib версии 1.3.1 — это чужой upstream-код, и
документацией он не покрыт. Он нужен вот зачем.
Установщики Forge и NeoForge сверяют sha1 каждого jar, который сами же и собирают, с эталоном из
`install_profile.json`. Эталон посчитан на обычном zlib, а дистрибутивы вроде CachyOS и Fedora
подставляют вместо него zlib-ng: сжатие корректное, но побайтово другое, поэтому установка падает
на любой версии игры сообщением «Processor failed, invalid outputs». Сменить Java не выйдет —
сборки OpenJDK под Linux берут `libz.so.1` из системы.
Поэтому на Linux собирается цель `launcher_zlib_reference` из этих исходников, и готовая
библиотека подсовывается через `LD_PRELOAD` только процессу установщика — см.
[zlibreference.h](cpp/zlibreference.md). Сам лаунчер с ней не линкуется, системный zlib-ng
остаётся на месте. Исходники хранятся в репозитории, чтобы сборка не зависела от сети, а версия
была зафиксирована: от неё зависит побайтовый результат сжатия.
---
При создании этого документа использовался ИИ.