# zlibreference.h `zlibreference.h`, `zlibreference.cpp` Обход одной конкретной проблемы на Linux: Forge и NeoForge не ставятся на системах, где вместо zlib стоит zlib-ng. ## В чём проблема Установщики Forge и NeoForge собирают часть jar прямо на машине пользователя и сверяют sha1 каждого собранного файла с эталоном из `install_profile.json`. Эталон посчитан на обычном zlib. CachyOS, Fedora и некоторые другие дистрибутивы ставят вместо него zlib-ng в режиме совместимости. Он сжимает корректно, но результат побайтово другой. Поэтому установка падает на любой версии игры с сообщением `Processor failed, invalid outputs`. Другая Java не помогает: сборки OpenJDK под Linux берут `libz.so.1` из системы. ## Что сделано В репозитории лежат исходники zlib 1.3.1 (каталог `zlib/`). На Linux CMake собирает из них цель `launcher_zlib_reference` (`libz.so.1`). В дереве сборки она лежит в `<папка бинарника>/zlib/`, при установке — в `/lib/BiLauncher/`. Сам лаунчер с ней не линкуется. Библиотека подкладывается через `LD_PRELOAD` только процессу установщика, системный zlib-ng не трогается. Исходники лежат в репозитории, а не скачиваются при сборке, по двум причинам: сборка не зависит от сети, и версия зафиксирована. От версии зависит побайтовый результат сжатия. ## Функции На Windows и macOS все три функции ничего не делают: `systemIsZlibNg()` возвращает `false`, `bundledPath()` пустую строку, `applyTo()` — `true`. ### systemIsZlibNg() Открывает `libz.so.1` через `dlopen`, то есть ту же библиотеку, которую загрузчик выдаст процессу java, и смотрит, есть ли `zlib-ng` в строке `zlibVersion()`. Результат вычисляется один раз за запуск. ### bundledPath() Ищет эталонную библиотеку по порядку: 1. `/zlib/libz.so.1` — запуск из дерева сборки; 2. `/../lib/BiLauncher/libz.so.1` — установленный пакет, tar.gz и AppImage; 3. `LAUNCHER_ZLIB_INSTALL_DIR/libz.so.1` — путь, заданный при конфигурации CMake. Второй вариант рассчитан на `CMAKE_INSTALL_LIBDIR=lib`. Поэтому CI на Ubuntu передаёт его явно, иначе библиотека легла бы в `lib/x86_64-linux-gnu`. ### applyTo(env, ¬e) - zlib-ng в системе нет — подменять нечего, возвращает `true`, `note` пуст. - zlib-ng есть, эталон найден — дописывает его путь в начало `LD_PRELOAD` (чужое содержимое переменной сохраняется), возвращает `true`, в `note` пишет, что подставлено. - zlib-ng есть, эталона нет — возвращает `false`, в `note` пишет предупреждение. [ModLoaderInstaller](ModLoaderInstaller.md) пишет `note` в журнал установщика. Если `applyTo()` вернула `false`, а установщик упал с ошибкой контрольных сумм, к ошибке добавляется прямая подсказка про zlib-ng. --- При создании этого документа использовался ИИ.