3.6 KiB
BuildArchiveWorker
buildarchiveworker.h, buildarchiveworker.cpp
Файловые операции над .minecraft: упаковать, очистить, распаковать, раскатать пак. В
.minecraft могут лежать гигабайты модов и миров, поэтому это единственная часть проекта,
которая работает не в GUI-потоке.
Объект создаёт BuildSwitcher без родителя, переносит в свой 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)
- Сначала проверяет весь архив. Небезопасный путь или файл внутри общих папок (
forbiddenTop:versions,librariesи т. д.) — отказ до любых изменений. Пак не может подменить jar игры или библиотеки. - Удаляет файлы из
removeRelative. Опасные пути и пути в общих папках молча пропускаются. После этого удаляются папки, которые стали пустыми. - Распаковывает пак, перезаписывая существующие файлы.
- Испускает
packEntries(список файлов пака), потомfinished(true).
Отмена
requestCancel() и clearCancel() выставляют атомарный флаг, его можно трогать из любого потока.
Флаг проверяется перед каждым файлом в archive, restore и applyPack.
Файлы распаковываются через QFile, а не QSaveFile. Если операцию прервать, последний файл
может остаться недописанным. Поэтому BuildSwitcher и не даёт отменить шаги после архивации.
При создании этого документа использовался ИИ.