Files
2026-09-03 09:16:56 +03:00

77 lines
4.5 KiB
Markdown

# zlibreference.h — ZlibReference
## Обзор
`Minecraft_launcher` умеет ставить модлоадеры Forge и NeoForge, а их установщики — это Java-программы,
которые собирают часть jar-файлов прямо на машине пользователя и сверяют sha1 каждого собранного
файла с эталоном из `install_profile.json`.
Эталон посчитан на обычном zlib. Дистрибутивы вроде CachyOS и Fedora подставляют вместо него
zlib-ng: сжатие корректное, но побайтово другое — поэтому установка падает на любой версии игры
сообщением «Processor failed, invalid outputs». Сменить Java не выйдет: сборки OpenJDK под Linux
берут `libz.so.1` из системы.
`ZlibReference` — обход этой проблемы. Рядом с лаунчером лежит собранный обычный zlib, и процессу
установщика он подсовывается через `LD_PRELOAD`. Системный zlib-ng при этом остаётся на месте:
подмена живёт ровно один процесс.
Пространство имён используется установщиком модлоадеров при подготовке окружения дочернего
процесса Java.
## Пространства имён
`ZlibReference` группирует три функции: проверку системной библиотеки, поиск собранного эталона и
подготовку окружения процесса. Состояния нет.
## Функции
#### bool systemIsZlibNg()
Отвечает на вопрос, окажется ли `libz.so.1`, который достанется процессу java, библиотекой zlib-ng.
От ответа зависит, нужна ли подмена вообще: на системе с обычным zlib она бессмысленна.
#### QString bundledPath()
Путь к собранному рядом эталонному `libz.so.1` или пустая строка, если его нет. Библиотека
собирается целью `launcher_zlib_reference` в `CMakeLists.txt` из исходников каталога `zlib/`,
которые лежат в репозитории, чтобы сборка не зависела от сети, а версия была зафиксирована — от
неё зависит побайтовый результат сжатия. Собирается только на Linux: на Windows и macOS проблемы
подмены системного zlib нет.
#### bool applyTo(QProcessEnvironment &env, QString *note = nullptr)
Дописывает `LD_PRELOAD` в переданное окружение, если подмена нужна. Изменяет `env` на месте.
Возвращает `true`, когда окружение готово, — в том числе в случае, когда подменять нечего:
система с обычным zlib или платформа, где вопрос не стоит. `false` означает, что подмена нужна, но
эталонной библиотеки нет на месте.
Необязательный параметр `note` заполняется строкой, пригодной и для журнала, и для текста ошибки:
она объясняет, была ли подмена применена и почему.
## Зависимости
Подключает `QString`; `QProcessEnvironment` объявлен вперёд и используется только по ссылке.
Реализация опирается на макрос `LAUNCHER_ZLIB_INSTALL_DIR`, который `CMakeLists.txt` определяет на
Linux — это путь установки библиотеки в системе, помимо каталога рядом с исполняемым файлом.
## Пример использования
```cpp
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
QString note;
if (!ZlibReference::applyTo(env, &note)) {
emit failed(note);
return;
}
QProcess installer;
installer.setProcessEnvironment(env);
installer.start(javaPath, arguments);
```
---
При создании этого документа использовался ИИ.