Files
minecraft-launcher/doc/cpp/zlibreference.md
T
2026-09-03 09:16:56 +03:00

4.5 KiB

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 — это путь установки библиотеки в системе, помимо каталога рядом с исполняемым файлом.

Пример использования

QProcessEnvironment env = QProcessEnvironment::systemEnvironment();

QString note;
if (!ZlibReference::applyTo(env, &note)) {
    emit failed(note);
    return;
}

QProcess installer;
installer.setProcessEnvironment(env);
installer.start(javaPath, arguments);

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