6.9 KiB
minecraftversion.h
minecraftversion.h, minecraftversion.cpp
Чтение описаний версий из <gameDir>/versions/<id>/<id>.json и всё, что с ними связано: правила
Mojang, нативные библиотеки под текущую платформу, список установленного, удаление.
Профиль модлоадера обычно содержит только отличия от базовой версии и ссылается на неё через
inheritsFrom. VersionLoader::load() проходит эту цепочку и сводит её в одну структуру
MinecraftVersion, с которой уже работают GameLauncher и
VersionInstaller.
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/. Если папки нет, это не ошибка.
При создании этого документа использовался ИИ.