# minecraftversion.h `minecraftversion.h`, `minecraftversion.cpp` Чтение описаний версий из `/versions//.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/`, в которых есть `.json`, по алфавиту. - `dependentsOf(gameDir, id)` — установленные профили с `inheritsFrom == id`. Без базовой версии они не запустятся, поэтому их перечисляют в предупреждении об удалении. - `installedSize(gameDir, id)` — размер папки в байтах. - `remove(gameDir, id, &error)` — удаляет `versions/`. Сначала проверяет, что id не пустой, не начинается с точки и не содержит слэшей, а итоговый путь лежит внутри `versions/`. Если папки нет, это не ошибка. --- При создании этого документа использовался ИИ.