# 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);
```

---

При создании этого документа использовался ИИ.
