64 lines
4.1 KiB
Markdown
64 lines
4.1 KiB
Markdown
# 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, ¬e)
|
||
|
||
- zlib-ng в системе нет — подменять нечего, возвращает `true`, `note` пуст.
|
||
- zlib-ng есть, эталон найден — дописывает его путь в начало `LD_PRELOAD` (чужое содержимое
|
||
переменной сохраняется), возвращает `true`, в `note` пишет, что подставлено.
|
||
- zlib-ng есть, эталона нет — возвращает `false`, в `note` пишет предупреждение.
|
||
|
||
[ModLoaderInstaller](ModLoaderInstaller.md) пишет `note` в журнал установщика. Если `applyTo()`
|
||
вернула `false`, а установщик упал с ошибкой контрольных сумм, к ошибке добавляется прямая
|
||
подсказка про zlib-ng.
|
||
|
||
---
|
||
|
||
При создании этого документа использовался ИИ.
|