2026-10-11 22:32:13 +03:00
|
|
|
|
# BiLauncher: устройство проекта
|
|
|
|
|
|
|
|
|
|
|
|
Лаунчер Minecraft на Qt 6. Интерфейс на QML. Всё остальное, то есть вход в аккаунт, загрузка
|
|
|
|
|
|
версий, установка модлоадеров и Java, смена сборок и запуск игры, написано на C++.
|
|
|
|
|
|
|
|
|
|
|
|
Здесь описано, как устроен код. Как собрать проект и выпустить релиз, рассказано в
|
|
|
|
|
|
[build-and-release.md](build-and-release.md).
|
|
|
|
|
|
|
|
|
|
|
|
## Общая схема
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
QML (Main.qml и диалоги)
|
|
|
|
|
|
│ свойства, вызовы, сигналы
|
|
|
|
|
|
▼
|
|
|
|
|
|
LauncherBackend ──────────────── Loc (Localization)
|
|
|
|
|
|
│ владеет
|
|
|
|
|
|
▼
|
|
|
|
|
|
сервисы: каталоги, установщики, авторизация, BuildSwitcher, GameLauncher
|
|
|
|
|
|
│
|
|
|
|
|
|
▼
|
|
|
|
|
|
сеть, файлы, дочерние процессы
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
1. **QML.** [Main.qml](qml/Main.md) — единственное окно приложения. Остальные окна — `Dialog` внутри
|
|
|
|
|
|
него. Main создаёт один `LauncherBackend` и передаёт его диалогам через `required property var
|
|
|
|
|
|
backend`. К сервисам QML не обращается.
|
|
|
|
|
|
2. **[LauncherBackend](cpp/LauncherBackend.md)** хранит профили, сборки и настройки, владеет
|
|
|
|
|
|
двенадцатью сервисами и следит, чтобы их операции не пересекались. Каталоги он отдаёт в QML
|
|
|
|
|
|
уже сведёнными с тем, что лежит на диске, поэтому окна сами ничего не считают.
|
|
|
|
|
|
3. **Сервисы.** Каждый занят одним делом и про интерфейс не знает.
|
|
|
|
|
|
4. **Внешний мир.** Серверы Mojang, Ely.by, Microsoft/Xbox, Adoptium, Fabric/Quilt/Forge/NeoForge и
|
|
|
|
|
|
свой сервер сезонных сборок. Файлы: `.minecraft` и папка лаунчера. Процессы: java с игрой,
|
|
|
|
|
|
установщики Forge/NeoForge, `tar`.
|
|
|
|
|
|
|
|
|
|
|
|
Отдельно стоит [Localization](cpp/Localization.md), синглтон `Loc`. Через него идут все тексты
|
|
|
|
|
|
интерфейса: `Loc.t.домен.вид.имя` в QML и `Loc::text("домен.вид.имя")` в C++. Он ни от чего не
|
|
|
|
|
|
зависит, и обращаться к нему можно из любого слоя.
|
|
|
|
|
|
|
|
|
|
|
|
Почти всё работает в GUI-потоке. Параллельность даёт асинхронная сеть, а не потоки. Исключение —
|
|
|
|
|
|
файловые операции над `.minecraft` (это могут быть гигабайты модов и миров). Они вынесены в
|
|
|
|
|
|
отдельный поток в [BuildArchiveWorker](cpp/BuildArchiveWorker.md).
|
|
|
|
|
|
|
|
|
|
|
|
## Основные понятия
|
|
|
|
|
|
|
|
|
|
|
|
**Профиль** — игрок и способ входа: офлайн, Ely.by или Microsoft.
|
|
|
|
|
|
|
|
|
|
|
|
**Сборка** — версия игры, модлоадер (или без него), адрес сервера и собственное содержимое
|
|
|
|
|
|
`.minecraft`: моды, конфиги, миры. Активная сборка одна, её файлы разложены в `.minecraft`, у
|
|
|
|
|
|
остальных файлы лежат в архивах в папке лаунчера. Папки `versions`, `libraries`, `assets`,
|
|
|
|
|
|
`runtime` общие для всех сборок. См. [BuildSwitcher](cpp/BuildSwitcher.md).
|
|
|
|
|
|
|
|
|
|
|
|
**Сезонная сборка** — готовая сборка, которую публикует команда на своём сервере. Ставится одной
|
|
|
|
|
|
кнопкой вместе с версией, модлоадером и Java, обновляется по номеру ревизии. Формат каталога
|
|
|
|
|
|
описан в [SeasonalBuildService](cpp/SeasonalBuildService.md).
|
|
|
|
|
|
|
|
|
|
|
|
**Папка лаунчера** — `BiLauncher` рядом с `.minecraft`. Что в ней лежит, расписано в
|
|
|
|
|
|
[launcherpaths.h](cpp/launcherpaths.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 во встроенном браузере; только с WebEngine |
|
|
|
|
|
|
| [LoaderRow](qml/LoaderRow.md) | строка модлоадера в карточке сборки |
|
|
|
|
|
|
| [ProgressPanel](qml/ProgressPanel.md) | плашка прогресса |
|
|
|
|
|
|
| [DarkCombo](qml/DarkCombo.md) | выпадающий список в стиле окна |
|
|
|
|
|
|
| [LabelledField](qml/LabelledField.md) | подпись и поле ввода |
|
|
|
|
|
|
|
|
|
|
|
|
## C++
|
|
|
|
|
|
|
|
|
|
|
|
### Вход и фасад
|
|
|
|
|
|
|
|
|
|
|
|
| | |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| [main.cpp](cpp/main.md) | запуск приложения |
|
|
|
|
|
|
| [LauncherBackend](cpp/LauncherBackend.md) | всё, что видит QML |
|
|
|
|
|
|
| [Localization](cpp/Localization.md) | тексты интерфейса, `i18n/translations.json` |
|
|
|
|
|
|
|
|
|
|
|
|
### Вход в аккаунт и запуск
|
|
|
|
|
|
|
|
|
|
|
|
| | |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| [AuthService](cpp/AuthService.md) | Ely.by, офлайн, authlib-injector; структура `AuthResult` |
|
|
|
|
|
|
| [MsaAuthService](cpp/MsaAuthService.md) | Microsoft: OAuth2 → Xbox Live → XSTS → Minecraft Services |
|
|
|
|
|
|
| [GameLauncher](cpp/GameLauncher.md) | командная строка, нативные библиотеки, процесс игры |
|
2026-09-03 09:16:56 +03:00
|
|
|
|
|
|
|
|
|
|
### Версии игры
|
|
|
|
|
|
|
2026-10-11 22:32:13 +03:00
|
|
|
|
| | |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| [VersionManifestService](cpp/VersionManifestService.md) | каталог версий Mojang |
|
|
|
|
|
|
| [VersionInstaller](cpp/VersionInstaller.md) | установка версии: jar, библиотеки, ресурсы |
|
|
|
|
|
|
| [minecraftversion.h](cpp/minecraftversion.md) | чтение описаний версий, цепочка `inheritsFrom`, правила Mojang |
|
2026-09-03 09:16:56 +03:00
|
|
|
|
|
|
|
|
|
|
### Модлоадеры
|
|
|
|
|
|
|
2026-10-11 22:32:13 +03:00
|
|
|
|
| | |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| [modloader.h](cpp/modloader.md) | перечисление модлоадеров и ключи |
|
|
|
|
|
|
| [ModLoaderVersionService](cpp/ModLoaderVersionService.md) | версии Forge, Fabric, NeoForge, Quilt |
|
|
|
|
|
|
| [ModLoaderInstaller](cpp/ModLoaderInstaller.md) | установка: готовый профиль или `installer.jar` |
|
|
|
|
|
|
| [zlibreference.h](cpp/zlibreference.md) | обход zlib-ng для установщиков Forge/NeoForge на Linux |
|
2026-09-03 09:16:56 +03:00
|
|
|
|
|
|
|
|
|
|
### Java
|
|
|
|
|
|
|
2026-10-11 22:32:13 +03:00
|
|
|
|
| | |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| [javaruntime.h](cpp/javaruntime.md) | типы, папка `<root>/java`, какая Java нужна какой версии игры |
|
|
|
|
|
|
| [JavaRuntimeService](cpp/JavaRuntimeService.md) | каталог Mojang и Temurin |
|
|
|
|
|
|
| [JavaInstaller](cpp/JavaInstaller.md) | установка: архив Temurin или дерево файлов Mojang |
|
|
|
|
|
|
| [javalocator.h](cpp/javalocator.md) | поиск java в системе |
|
|
|
|
|
|
|
|
|
|
|
|
### Сборки
|
|
|
|
|
|
|
|
|
|
|
|
| | |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| [BuildSwitcher](cpp/BuildSwitcher.md) | смена активной сборки, раскатка пака, продолжение после падения |
|
|
|
|
|
|
| [BuildArchiveWorker](cpp/BuildArchiveWorker.md) | файловые операции в отдельном потоке |
|
|
|
|
|
|
| [SeasonalBuildService](cpp/SeasonalBuildService.md) | каталог сезонных сборок и его формат |
|
|
|
|
|
|
| [SeasonalPackDownloader](cpp/SeasonalPackDownloader.md) | загрузка архива сезонной сборки |
|
|
|
|
|
|
| [launcherpaths.h](cpp/launcherpaths.md) | все пути к данным лаунчера |
|
|
|
|
|
|
|
|
|
|
|
|
## Прочее в репозитории
|
|
|
|
|
|
|
|
|
|
|
|
| Путь | Что это |
|
|
|
|
|
|
|------|---------|
|
|
|
|
|
|
| `i18n/translations.json` | все тексты интерфейса |
|
|
|
|
|
|
| `tools/check_translations.py` | проверка каталога переводов |
|
|
|
|
|
|
| `icons/` | иконки и скрипт, который их генерирует |
|
|
|
|
|
|
| `images/` | картинки интерфейса |
|
|
|
|
|
|
| `zlib/` | исходники zlib 1.3.1 (чужой код) |
|
|
|
|
|
|
| `packaging/` | установщик Windows, лицензии сторонних компонентов |
|
|
|
|
|
|
| `ci/` | скрипты подготовки раннеров |
|
|
|
|
|
|
| `.gitea/workflows/release.yml` | сборка релизов |
|
|
|
|
|
|
| `Screenshots/` | картинки для README |
|
2026-09-03 09:16:56 +03:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
При создании этого документа использовался ИИ.
|