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

64 lines
4.1 KiB
Markdown
Raw 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.
# 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/`, при
установке — в `<prefix>/lib/BiLauncher/`. Сам лаунчер с ней не линкуется. Библиотека
подкладывается через `LD_PRELOAD` только процессу установщика, системный zlib-ng не трогается.
Исходники лежат в репозитории, а не скачиваются при сборке, по двум причинам: сборка не зависит от
сети, и версия зафиксирована. От версии зависит побайтовый результат сжатия.
## Функции
На Windows и macOS все три функции ничего не делают: `systemIsZlibNg()` возвращает `false`,
`bundledPath()` пустую строку, `applyTo()` — `true`.
### systemIsZlibNg()
Открывает `libz.so.1` через `dlopen`, то есть ту же библиотеку, которую загрузчик выдаст процессу
java, и смотрит, есть ли `zlib-ng` в строке `zlibVersion()`. Результат вычисляется один раз за
запуск.
### bundledPath()
Ищет эталонную библиотеку по порядку:
1. `<applicationDirPath>/zlib/libz.so.1` — запуск из дерева сборки;
2. `<applicationDirPath>/../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, &note)
- zlib-ng в системе нет — подменять нечего, возвращает `true`, `note` пуст.
- zlib-ng есть, эталон найден — дописывает его путь в начало `LD_PRELOAD` (чужое содержимое
переменной сохраняется), возвращает `true`, в `note` пишет, что подставлено.
- zlib-ng есть, эталона нет — возвращает `false`, в `note` пишет предупреждение.
[ModLoaderInstaller](ModLoaderInstaller.md) пишет `note` в журнал установщика. Если `applyTo()`
вернула `false`, а установщик упал с ошибкой контрольных сумм, к ошибке добавляется прямая
подсказка про zlib-ng.
---
При создании этого документа использовался ИИ.