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

13 KiB
Raw Permalink Blame History

Minecraft Launcher — справочник по исходному коду

Десктопный лаунчер Minecraft на Qt 6. Интерфейс написан на QML, вся работа — авторизация, скачивание версий, установка модлоадеров и Java, запуск игры — лежит в C++.

Документация разделена на две части: QML-компоненты и C++-классы.

Как устроено приложение

Слоёв четыре, и каждый общается только с соседними:

  1. QML. Main — единственное настоящее окно и точка входа. Оно держит единственный экземпляр LauncherBackend и раздаёт его вложенным диалогам через свойство backend. Ни один QML-файл не обращается к сервисам напрямую.

  2. Фасад. LauncherBackend — главный класс, видимый из QML. Хранит профили, сборки и настройки, владеет двенадцатью сервисами и сводит их состояние к свойствам, которые читает интерфейс. Каталоги он отдаёт уже сведёнными с локальным состоянием, поэтому окна показывают статус, не считая ничего сами.

  3. Сервисы. Каталоги (версий, модлоадеров, Java, сезонных сборок), установщики, службы авторизации, переключатель сборок и запуск игры. Каждый занят одним делом и ничего не знает об интерфейсе. Особняком стоит Localization — второй и последний тип, видимый из QML. Это синглтон Loc, через который проходят все тексты интерфейса: Loc.t.домен.вид.имя в QML и Loc::text("домен.вид.имя") в C++. Он ни от чего не зависит и доступен всем слоям сразу.

  4. Внешний мир. Сеть (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 остаётся на месте. Исходники хранятся в репозитории, чтобы сборка не зависела от сети, а версия была зафиксирована: от неё зависит побайтовый результат сжатия.


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