# ModLoaderInstaller `modloaderinstaller.h`, `modloaderinstaller.cpp` Ставит модлоадер в `.minecraft`. Fabric и Quilt ставятся иначе, чем Forge и NeoForge, но снаружи у них одинаковый интерфейс. - **Fabric и Quilt** отдают готовое описание версии. Его достаточно положить в `versions//.json`, а остальное докачает [VersionInstaller](VersionInstaller.md). - **Forge и NeoForge** при установке патчат клиентский jar, поэтому запускается их официальный `installer.jar` без окна. После него проверяется, какой профиль появился в `versions/`. Экземпляр держит [LauncherBackend](LauncherBackend.md). Геттеры прогресса устроены так же, как у `VersionInstaller` (`label`, `stage`, `currentFile`, `bytesDone`, `bytesTotal`, `fraction`), и панель загрузки читает их одинаково. ## install(gameDir, loader, gameVersion, loaderVersion, javaPreference) Если установка уже идёт или не указана версия, сразу приходит `failed`. Иначе: 1. Список версий модлоадера через [ModLoaderVersionService](ModLoaderVersionService.md). 2. **Базовая версия игры.** Если её нет или не хватает файлов, она ставится через `VersionInstaller`, и ход идёт дальше только после её `finished`. Без целой ванильной версии модлоадер ставить некуда. 3. Дальше один из двух путей. ### Fabric и Quilt Описание скачивается из `meta.fabricmc.net/v2/versions/loader/<игра>/<лоадер>/profile/json` (у Quilt `meta.quiltmc.org/v3/...`). Проверяется, что в нём есть безопасный `id` и что `inheritsFrom` совпадает с выбранной версией игры. Файл сохраняется, и `VersionInstaller` получает этот `id`. ### Forge и NeoForge 1. Ссылка на установщик берётся из записи `ModLoaderVersionService::find()`. Если записи нет, значит, эта пара версий несовместима. Установщик качается в `/cache/loaders/<ключ>-<версия>-installer.jar`. 2. Если в `.minecraft` нет `launcher_profiles.json`, создаётся заглушка. Без неё установщик отказывается работать: он считает, что официальный лаунчер не установлен. 3. Java берётся через `JavaLocator::select()` по `javaMajor` базовой версии. `javaPreference` — это та же Java, что выбрана для игры. 4. Запоминается список профилей в `versions/`. 5. Запуск: `java -jar installer.jar --installClient `. Рабочий каталог — папка загрузок модлоадеров. На Linux в окружение процесса подставляется эталонный zlib (см. [zlibreference.h](zlibreference.md)). 6. Вывод установщика построчно уходит в `log(line)`, бэкенд показывает его в журнале. Полностью он пишется в `/cache/loaders/<ключ>-<версия>-install.log`, а последние 12 строк хранятся в памяти для текста ошибки. 7. Через 15 минут процесс убивается. После успешного завершения новый профиль ищется как разница списков до и после. Угадывать имя по строке нельзя: у Forge в разные годы оно составлялось по-разному. Если новых папок нет (установщик переписал существующую), ищется профиль, который наследует базовую версию и содержит в имени версию модлоадера. Если новых папок несколько, берётся та, где есть версия модлоадера. Найденный профиль передаётся `VersionInstaller`, который докачивает библиотеки, не положенные установщиком. Когда он отчитается, приходит `finished(loaderKey, gameVersion, loaderVersion, producedVersionId)`. Бэкенд записывает `producedVersionId` в `resolvedVersionId` сборки. ### Если установщик упал Все папки, которые он успел создать в `versions/`, удаляются. В текст ошибки идут код выхода, хвост журнала и путь к полному журналу. Если подменить zlib не удалось, а в журнале есть `Processor failed` или `invalid outputs`, к сообщению добавляется прямая подсказка про zlib-ng. Почти наверняка дело в нём. ## cancel() Обрывает загрузку, убивает процесс установщика и удаляет то, что он создал. Если ход уже передан `VersionInstaller`, отменяется и он, а `canceled` придёт после его отчёта. Деструктор убивает процесс установщика, если тот ещё работает. --- При создании этого документа использовался ИИ.