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