13 KiB
Minecraft Launcher — справочник по исходному коду
Десктопный лаунчер Minecraft на Qt 6. Интерфейс написан на QML, вся работа — авторизация, скачивание версий, установка модлоадеров и Java, запуск игры — лежит в C++.
Документация разделена на две части: QML-компоненты и C++-классы.
Как устроено приложение
Слоёв четыре, и каждый общается только с соседними:
-
QML. Main — единственное настоящее окно и точка входа. Оно держит единственный экземпляр
LauncherBackendи раздаёт его вложенным диалогам через свойствоbackend. Ни один QML-файл не обращается к сервисам напрямую. -
Фасад. LauncherBackend — главный класс, видимый из QML. Хранит профили, сборки и настройки, владеет двенадцатью сервисами и сводит их состояние к свойствам, которые читает интерфейс. Каталоги он отдаёт уже сведёнными с локальным состоянием, поэтому окна показывают статус, не считая ничего сами.
-
Сервисы. Каталоги (версий, модлоадеров, Java, сезонных сборок), установщики, службы авторизации, переключатель сборок и запуск игры. Каждый занят одним делом и ничего не знает об интерфейсе. Особняком стоит Localization — второй и последний тип, видимый из QML. Это синглтон
Loc, через который проходят все тексты интерфейса:Loc.t.домен.вид.имяв QML иLoc::text("домен.вид.имя")в C++. Он ни от чего не зависит и доступен всем слоям сразу. -
Внешний мир. Сеть (Mojang, Ely.by, Microsoft, Adoptium, файловый сервер сборок), файловая система (
.minecraftи папка лаунчера) и дочерние процессы (java, установщики модлоадеров,tar).
Почти весь код работает в потоке GUI: параллелизм даёт асинхронная сеть, а не потоки. Единственное
исключение — операции над содержимым .minecraft (гигабайты модов и миров), вынесенные в
отдельный поток к BuildArchiveWorker.
QML-компоненты
| Компонент | Описание |
|---|---|
| Main | Главное окно и точка входа: экран запуска, профили, плашка сообщений, панели прогресса и внутренние диалоги |
| BuildsDialog | Пользовательские сборки: список слева, карточка редактирования справа |
| VersionPickerDialog | Выбор версии Minecraft: категории, поиск, удаление скачанных версий |
| JavaPickerDialog | Выбор сборки Java; подтверждение при необходимости сразу начинает загрузку |
| SeasonalBuildsDialog | Каталог готовых сезонных сборок таблицей и установка одной кнопкой |
| MicrosoftLoginDialog | Окно входа в аккаунт Microsoft; собирается только с Qt WebEngine |
| LoaderRow | Одна строка модлоадера в карточке сборки: чекбокс и список версий |
| ProgressPanel | Плашка хода долгой операции в левом нижнем углу |
| DarkCombo | Выпадающий список в тёмном стиле окна |
| LabelledField | Подпись и поле ввода одной колонкой |
C++-классы
Точка входа
| Файл | Описание |
|---|---|
| main.cpp | Инициализация WebEngine, объект приложения, каталог переводов, стиль Basic, загрузка QML-модуля |
Фасад
| Класс | Описание |
|---|---|
| Localization | Синглтон Loc: все тексты интерфейса в одном файле i18n/translations.json, переключение языка на лету |
| LauncherBackend | Единственный тип, видимый из QML: 26 свойств, 42 вызываемых метода, состояние лаунчера и порядок работы всех сервисов |
Авторизация и запуск
| Класс | Описание |
|---|---|
| AuthService | Вход через Ely.by и офлайн-режим; структура AuthResult |
| MsaAuthService | Вход через аккаунт Microsoft: OAuth2 → Xbox Live → XSTS → Minecraft Services |
| GameLauncher | Сборка командной строки, распаковка нативных библиотек и запуск JVM |
Версии игры
| Класс | Описание |
|---|---|
| VersionManifestService | Каталог версий Mojang с кэшем в папке лаунчера |
| VersionInstaller | Фоновая установка версии: jar, библиотеки, индекс ресурсов и сами ресурсы |
Модлоадеры
| Класс | Описание |
|---|---|
| ModLoaderVersionService | Списки версий Forge, Fabric, NeoForge и Quilt; совместимость заложена в структуру данных |
| ModLoaderInstaller | Два пути установки под одним фасадом: готовое описание версии либо запуск installer.jar |
Java
| Класс | Описание |
|---|---|
| JavaRuntimeService | Каталог сборок Mojang и Eclipse Temurin под текущую платформу |
| JavaInstaller | Установка сборки Java: архив Temurin либо дерево файлов Mojang |
Сборки и их содержимое
| Класс | Описание |
|---|---|
| BuildSwitcher | Порядок шагов смены активной сборки и восстановление после прерванной операции |
| BuildArchiveWorker | Упаковка, очистка, распаковка и раскатка пака в отдельном потоке |
Сезонные сборки
| Класс | Описание |
|---|---|
| SeasonalBuildService | Каталог готовых сборок с файлового сервера |
| SeasonalPackDownloader | Загрузка архива сборки потоком с проверкой sha256 |
Общие типы и утилиты
| Файл | Описание |
|---|---|
| minecraftversion.h | Структуры версии и библиотеки, чтение и разворачивание цепочки inheritsFrom |
| javaruntime.h | Виды сборок Java, папка <root>/java и таблица требований версий игры |
| modloader.h | Перечисление модлоадеров, запись версии и перевод ключей |
| launcherpaths.h | Все пути к данным лаунчера в одном месте |
| javalocator.h | Поиск установленной в системе Java и выбор подходящей версии |
| zlibreference.h | Подмена 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-модуль; без модуля лаунчер собирается и работает как обычно, только вход через 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. Штатные .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. Сам лаунчер с ней не линкуется, системный zlib-ng
остаётся на месте. Исходники хранятся в репозитории, чтобы сборка не зависела от сети, а версия
была зафиксирована: от неё зависит побайтовый результат сжатия.
При создании этого документа использовался ИИ.