#pragma once #include #include #include #include // Три операции над содержимым .minecraft, выполняемые в отдельном потоке: // упаковать, вычистить, распаковать. Гигабайты модов и миров нельзя гонять в // GUI-потоке — окно бы замерзало на всё время смены сборки. // // Объект живёт в своём QThread, вызывается только через очередь сигналов и // сам ничего не знает ни о сборках, ни о путях лаунчера: порядок шагов и // восстановление после сбоя — дело BuildSwitcher. class BuildArchiveWorker : public QObject { Q_OBJECT public: explicit BuildArchiveWorker(QObject *parent = nullptr); // Вызывается из GUI-потока во время работы: отмена проверяется между файлами. void requestCancel() { m_cancel.storeRelaxed(1); } void clearCancel() { m_cancel.storeRelaxed(0); } public slots: // Упаковывает всё содержимое gameDir, кроме элементов верхнего уровня из // excludeTop, во временный файл tempZipPath. void archive(const QString &gameDir, const QString &tempZipPath, const QStringList &excludeTop); // Удаляет из gameDir всё, кроме элементов верхнего уровня из keepTop. void clear(const QString &gameDir, const QStringList &keepTop); // Распаковывает архив в gameDir. void restore(const QString &zipPath, const QString &gameDir); // Докатывает пак сезонной сборки поверх уже разложенного содержимого: // сначала удаляет removeRelative (файлы, ушедшие из сборки в новой // ревизии), затем распаковывает архив с перезаписью. Того, чего нет ни в // списке, ни в архиве, операция не касается — миры и скриншоты остаются. // // forbiddenTop — элементы верхнего уровня, которые паку трогать нельзя // (общие каталоги лаунчера). Проверяется здесь, а не только у издателя: // архив приезжает из сети. void applyPack(const QString &zipPath, const QString &gameDir, const QStringList &removeRelative, const QStringList &forbiddenTop); signals: void progress(int done, int total, const QString ¤tPath); void finished(bool ok, const QString &error); // Что именно принёс пак — относительными путями. Пригодится следующему // обновлению, чтобы вычислить, какие файлы из сборки ушли. void packEntries(const QStringList &entries); private: bool canceled() const { return m_cancel.loadRelaxed() != 0; } QAtomicInt m_cancel; };