# 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, папка `/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 остаётся на месте. Исходники хранятся в репозитории, чтобы сборка не зависела от сети, а версия была зафиксирована: от неё зависит побайтовый результат сжатия. --- При создании этого документа использовался ИИ.