Files
BiLauncher/doc/cpp/minecraftversion.md
2026-10-11 22:32:13 +03:00

104 lines
6.9 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.
# minecraftversion.h
`minecraftversion.h`, `minecraftversion.cpp`
Чтение описаний версий из `<gameDir>/versions/<id>/<id>.json` и всё, что с ними связано: правила
Mojang, нативные библиотеки под текущую платформу, список установленного, удаление.
Профиль модлоадера обычно содержит только отличия от базовой версии и ссылается на неё через
`inheritsFrom`. `VersionLoader::load()` проходит эту цепочку и сводит её в одну структуру
`MinecraftVersion`, с которой уже работают [GameLauncher](GameLauncher.md) и
[VersionInstaller](VersionInstaller.md).
## MinecraftLibrary
Одна библиотека, к которой уже применены правила.
| Поле | Что это |
|------|---------|
| `name` | Maven-координаты, например `org.lwjgl:lwjgl:3.3.1:natives-windows` |
| `path` | путь относительно `libraries/` |
| `url` | откуда качать; может быть пустым |
| `sha1`, `size` | для проверки; могут отсутствовать |
| `native` | распаковывается в `natives`, в classpath не идёт |
| `extractExclude` | префиксы путей внутри jar, которые не распаковываются |
## MinecraftVersion
| Поле | Что это |
|------|---------|
| `id` | имя папки в `versions/` |
| `mainClass` | |
| `type` | `release`, `snapshot` и т. д.; по умолчанию `release` |
| `assetIndexId` | id индекса ресурсов |
| `assetsKind` | поле `assets`: `legacy`, `pre-1.6` или тот же id |
| `clientJarPath` | абсолютный путь к клиентскому jar; часто это jar родителя |
| `javaMajor` | из `javaVersion.majorVersion`; по умолчанию 8 |
| `jvmArgs`, `gameArgs` | с ещё не подставленными `${...}` |
| `libraries` | |
| `loggingArgument`, `loggingConfigPath` | аргумент log4j и путь к его xml в `assets/log_configs` |
| `supportsQuickPlay` | среди аргументов игры есть `quickPlayMultiplayer` (1.20+) |
| `hasCustomResolutionArgs` | описание само передаёт `resolution_width` |
`isValid()` возвращает `true`, если заданы `id` и `mainClass`.
## Как сводится цепочка
`load(gameDir, versionId, features, &error)` идёт от запрошенной версии к родителям по
`inheritsFrom`. Ограничения: не больше 10 звеньев, без циклов. Если файл отсутствует или не
разбирается, это ошибка, и возвращается невалидный объект.
Дальше поля применяются от корня к потомку:
- `mainClass`, `type`, `assets`, `assetIndex`, `javaVersion`, `logging` — потомок перекрывает
родителя;
- `minecraftArguments` (старый формат, одна строка) **заменяет** `gameArgs` целиком;
- `arguments.jvm` и `arguments.game` (новый формат) **дописываются** к тому, что дал родитель.
Библиотеки собираются в обратном порядке, от потомка к корню. Повторы убираются по ключу
`группа:артефакт[:классификатор]`, без версии. Поэтому если Forge приносит свою версию библиотеки,
она вытесняет ванильную.
Если среди JVM-аргументов нет `-cp`, значит это старая версия без блока `arguments.jvm`. Тогда
добавляются аргументы, которые официальный лаунчер подставляет сам: `-Djava.library.path`, бренд и
версия лаунчера, `-cp ${classpath}`.
Клиентский jar берётся первый найденный по цепочке, от потомка к корню. Если его нет нигде,
указывается путь у корня. `GameLauncher::missingFiles()` потом скажет, что его не хватает.
`features` нужен для правил вида `"features": {"has_custom_resolution": true}`. Бэкенд передаёт
`has_custom_resolution`, если в настройках задан размер окна.
## Правила и натив
`rulesAllow(rules, features)` реализует алгоритм Mojang: правила проверяются по порядку,
действует последнее совпавшее; пустой список означает «разрешено». Правило совпадает, если подошли
`features`, `os.name`, `os.arch` и регулярное выражение `os.version` (сверяется с
`QSysInfo::productVersion()`).
Нативные библиотеки встречаются в двух форматах:
- старый: блок `natives` с классификатором под ОС, `${arch}` заменяется на `32` или `64`;
- новый (LWJGL 3.3+): отдельные библиотеки с классификатором `natives-<ос>[-<арх>]`.
`pickNativesForCurrentArch()` оставляет для каждого артефакта один классификатор. Лучше всего
точный (`nativeClassifier()`, например `natives-macos-arm64`), потом общий для ОС
(`natives-macos`), потом какой попадётся.
`osName()` возвращает `windows`, `osx` или `linux`. `osArch()` возвращает архитектуру из
`QSysInfo`, причём `i386` и `i686` сводятся к `x86`.
## Установленные версии
- `installedVersions(gameDir)` — подпапки `versions/`, в которых есть `<id>.json`, по алфавиту.
- `dependentsOf(gameDir, id)` — установленные профили с `inheritsFrom == id`. Без базовой версии они
не запустятся, поэтому их перечисляют в предупреждении об удалении.
- `installedSize(gameDir, id)` — размер папки в байтах.
- `remove(gameDir, id, &error)` — удаляет `versions/<id>`. Сначала проверяет, что id не пустой,
не начинается с точки и не содержит слэшей, а итоговый путь лежит внутри `versions/`. Если папки
нет, это не ошибка.
---
При создании этого документа использовался ИИ.