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, ¬e)) {
emit failed(note);
return;
}
QProcess installer;
installer.setProcessEnvironment(env);
installer.start(javaPath, arguments);
При создании этого документа использовался ИИ.