# BuildArchiveWorker `buildarchiveworker.h`, `buildarchiveworker.cpp` Файловые операции над `.minecraft`: упаковать, очистить, распаковать, раскатать пак. В `.minecraft` могут лежать гигабайты модов и миров, поэтому это единственная часть проекта, которая работает не в GUI-потоке. Объект создаёт [BuildSwitcher](BuildSwitcher.md) без родителя, переносит в свой `QThread` и вызывает слоты через `QMetaObject::invokeMethod(..., Qt::QueuedConnection)`. Работник не знает ни про сборки, ни про журнал. Он получает пути и отвечает сигналами. ZIP читается и пишется через `QZipReader` и `QZipWriter` из `Qt6::CorePrivate`. ## Слоты Каждый слот заканчивается одним `finished(ok, error)`. По ходу работы испускается `progress(done, total, currentPath)` на каждый файл. ### archive(gameDir, tempZipPath, excludeTop) Упаковывает всё содержимое `gameDir`, кроме папок и файлов верхнего уровня из `excludeTop`. Символьные ссылки пропускаются. Сжатие `AutoCompress`: Qt сам не сжимает то, что уже сжато. При ошибке или отмене недописанный архив удаляется. ### clear(gameDir, keepTop) Удаляет всё на верхнем уровне `gameDir`, кроме `keepTop`. Символьная ссылка удаляется как файл, то, на что она указывает, не трогается. Если `gameDir` нет, это успех. Отменить нельзя. ### restore(zipPath, gameDir) Распаковывает архив в `gameDir`. Пути с `..`, абсолютные, с `\` или `:` останавливают распаковку. ### applyPack(zipPath, gameDir, removeRelative, forbiddenTop) 1. Сначала проверяет весь архив. Небезопасный путь или файл внутри общих папок (`forbiddenTop`: `versions`, `libraries` и т. д.) — отказ до любых изменений. Пак не может подменить jar игры или библиотеки. 2. Удаляет файлы из `removeRelative`. Опасные пути и пути в общих папках молча пропускаются. После этого удаляются папки, которые стали пустыми. 3. Распаковывает пак, перезаписывая существующие файлы. 4. Испускает `packEntries(список файлов пака)`, потом `finished(true)`. ## Отмена `requestCancel()` и `clearCancel()` выставляют атомарный флаг, его можно трогать из любого потока. Флаг проверяется перед каждым файлом в `archive`, `restore` и `applyPack`. Файлы распаковываются через `QFile`, а не `QSaveFile`. Если операцию прервать, последний файл может остаться недописанным. Поэтому `BuildSwitcher` и не даёт отменить шаги после архивации. --- При создании этого документа использовался ИИ.