56 lines
3.6 KiB
Markdown
56 lines
3.6 KiB
Markdown
# 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` и не даёт отменить шаги после архивации.
|
||
|
||
---
|
||
|
||
При создании этого документа использовался ИИ.
|