diff options
Diffstat (limited to 'launcher/modplatform')
15 files changed, 374 insertions, 172 deletions
diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp index 22ea02da..82a51c27 100644 --- a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp +++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp @@ -684,7 +684,7 @@ void PackInstallTask::installConfigs() abortable = true; setProgress(current, total); }); - connect(jobPtr.get(), &NetJob::stepProgress, this, &PackInstallTask::propogateStepProgress); + connect(jobPtr.get(), &NetJob::stepProgress, this, &PackInstallTask::propagateStepProgress); connect(jobPtr.get(), &NetJob::aborted, [&]{ abortable = false; jobPtr.reset(); @@ -852,7 +852,7 @@ void PackInstallTask::downloadMods() abortable = true; setProgress(current, total); }); - connect(jobPtr.get(), &NetJob::stepProgress, this, &PackInstallTask::propogateStepProgress); + connect(jobPtr.get(), &NetJob::stepProgress, this, &PackInstallTask::propagateStepProgress); connect(jobPtr.get(), &NetJob::aborted, [&] { abortable = false; diff --git a/launcher/modplatform/flame/FileResolvingTask.cpp b/launcher/modplatform/flame/FileResolvingTask.cpp index 34bd401d..ae168bbd 100644 --- a/launcher/modplatform/flame/FileResolvingTask.cpp +++ b/launcher/modplatform/flame/FileResolvingTask.cpp @@ -52,7 +52,7 @@ void Flame::FileResolvingTask::executeTask() stepProgress(*step_progress); emitFailed(reason); }); - connect(m_dljob.get(), &NetJob::stepProgress, this, &FileResolvingTask::propogateStepProgress); + connect(m_dljob.get(), &NetJob::stepProgress, this, &FileResolvingTask::propagateStepProgress); connect(m_dljob.get(), &NetJob::progress, this, [this, step_progress](qint64 current, qint64 total) { qDebug() << "Resolve slug progress" << current << total; step_progress->update(current, total); @@ -118,7 +118,7 @@ void Flame::FileResolvingTask::netJobFinished() stepProgress(*step_progress); emitFailed(reason); }); - connect(m_checkJob.get(), &NetJob::stepProgress, this, &FileResolvingTask::propogateStepProgress); + connect(m_checkJob.get(), &NetJob::stepProgress, this, &FileResolvingTask::propagateStepProgress); connect(m_checkJob.get(), &NetJob::progress, this, [this, step_progress](qint64 current, qint64 total) { qDebug() << "Resolve slug progress" << current << total; step_progress->update(current, total); @@ -195,7 +195,7 @@ void Flame::FileResolvingTask::modrinthCheckFinished() stepProgress(*step_progress); emitFailed(reason); }); - connect(m_slugJob.get(), &NetJob::stepProgress, this, &FileResolvingTask::propogateStepProgress); + connect(m_slugJob.get(), &NetJob::stepProgress, this, &FileResolvingTask::propagateStepProgress); connect(m_slugJob.get(), &NetJob::progress, this, [this, step_progress](qint64 current, qint64 total) { qDebug() << "Resolve slug progress" << current << total; step_progress->update(current, total); diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index 29145d89..e17cf1c2 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -432,7 +432,7 @@ bool FlameCreationTask::createInstance() }); connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::progress, this, &FlameCreationTask::setProgress); connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::status, this, &FlameCreationTask::setStatus); - connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::stepProgress, this, &FlameCreationTask::propogateStepProgress); + connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::stepProgress, this, &FlameCreationTask::propagateStepProgress); connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::details, this, &FlameCreationTask::setDetails); m_mod_id_resolver->start(); @@ -552,7 +552,7 @@ void FlameCreationTask::setupDownloadJob(QEventLoop& loop) setDetails(tr("%1 out of %2 complete").arg(current).arg(total)); setProgress(current, total); }); - connect(m_files_job.get(), &NetJob::stepProgress, this, &FlameCreationTask::propogateStepProgress); + connect(m_files_job.get(), &NetJob::stepProgress, this, &FlameCreationTask::propagateStepProgress); connect(m_files_job.get(), &NetJob::finished, &loop, &QEventLoop::quit); setStatus(tr("Downloading mods...")); diff --git a/launcher/modplatform/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index ac0da214..f5f3af37 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -26,6 +26,7 @@ #include <QMessageBox> #include <QtConcurrentRun> #include <algorithm> +#include <iterator> #include <memory> #include "Json.h" #include "MMCZip.h" @@ -64,20 +65,11 @@ void FlamePackExportTask::executeTask() bool FlamePackExportTask::abort() { - if (task != nullptr) { + if (task) { task->abort(); - task = nullptr; emitAborted(); return true; } - - if (buildZipFuture.isRunning()) { - buildZipFuture.cancel(); - // NOTE: Here we don't do `emitAborted()` because it will be done when `buildZipFuture` actually cancels, which may not occur - // immediately. - return true; - } - return false; } @@ -166,7 +158,7 @@ void FlamePackExportTask::collectHashes() stepProgress(*progressStep); emitFailed(reason); }); - connect(hashingTask.get(), &Task::stepProgress, this, &FlamePackExportTask::propogateStepProgress); + connect(hashingTask.get(), &Task::stepProgress, this, &FlamePackExportTask::propagateStepProgress); connect(hashingTask.get(), &Task::progress, this, [this, progressStep](qint64 current, qint64 total) { progressStep->update(current, total); @@ -336,89 +328,40 @@ void FlamePackExportTask::buildZip() setStatus(tr("Adding files...")); setProgress(4, 5); - buildZipFuture = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { - QuaZip zip(output); - if (!zip.open(QuaZip::mdCreate)) { - QFile::remove(output); - return BuildZipResult(tr("Could not create file")); - } - - if (buildZipFuture.isCanceled()) - return BuildZipResult(); + auto zipTask = makeShared<MMCZip::ExportToZipTask>(output, gameRoot, files, "overrides/", true); + zipTask->addExtraFile("manifest.json", generateIndex()); + zipTask->addExtraFile("modlist.html", generateHTML()); - QuaZipFile indexFile(&zip); - if (!indexFile.open(QIODevice::WriteOnly, QuaZipNewInfo("manifest.json"))) { - QFile::remove(output); - return BuildZipResult(tr("Could not create index")); - } - indexFile.write(generateIndex()); + QStringList exclude; + std::transform(resolvedFiles.keyBegin(), resolvedFiles.keyEnd(), std::back_insert_iterator(exclude), + [this](QString file) { return gameRoot.relativeFilePath(file); }); + zipTask->setExcludeFiles(exclude); - QuaZipFile modlist(&zip); - if (!modlist.open(QIODevice::WriteOnly, QuaZipNewInfo("modlist.html"))) { - QFile::remove(output); - return BuildZipResult(tr("Could not create index")); - } - QString content = ""; - for (auto mod : resolvedFiles) { - if (mod.isMod) { - content += QString(TEMPLATE) - .replace("{name}", mod.name.toHtmlEscaped()) - .replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.addonId).toHtmlEscaped()) - .replace("{authors}", !mod.authors.isEmpty() ? QString(" (by %1)").arg(mod.authors).toHtmlEscaped() : ""); - } - } - content = "<ul>" + content + "</ul>"; - modlist.write(content.toUtf8()); - - auto progressStep = std::make_shared<TaskStepProgress>(); - - size_t progress = 0; - for (const QFileInfo& file : files) { - if (buildZipFuture.isCanceled()) { - QFile::remove(output); - progressStep->state = TaskStepState::Failed; - stepProgress(*progressStep); - return BuildZipResult(); - } - progressStep->update(progress, files.length()); - stepProgress(*progressStep); - - const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath()); - if (!resolvedFiles.contains(file.absoluteFilePath()) && - !JlCompress::compressFile(&zip, file.absoluteFilePath(), "overrides/" + relative)) { - QFile::remove(output); - return BuildZipResult(tr("Could not read and compress %1").arg(relative)); - } - progress++; - } - - zip.close(); - - if (zip.getZipError() != 0) { - QFile::remove(output); - progressStep->state = TaskStepState::Failed; - stepProgress(*progressStep); - return BuildZipResult(tr("A zip error occurred")); - } + auto progressStep = std::make_shared<TaskStepProgress>(); + connect(zipTask.get(), &Task::finished, this, [this, progressStep] { progressStep->state = TaskStepState::Succeeded; stepProgress(*progressStep); - return BuildZipResult(); }); - connect(&buildZipWatcher, &QFutureWatcher<BuildZipResult>::finished, this, &FlamePackExportTask::finish); - buildZipWatcher.setFuture(buildZipFuture); -} -void FlamePackExportTask::finish() -{ - if (buildZipFuture.isCanceled()) - emitAborted(); - else { - const BuildZipResult result = buildZipFuture.result(); - if (result.has_value()) - emitFailed(result.value()); - else - emitSucceeded(); - } + connect(zipTask.get(), &Task::succeeded, this, &FlamePackExportTask::emitSucceeded); + connect(zipTask.get(), &Task::aborted, this, &FlamePackExportTask::emitAborted); + connect(zipTask.get(), &Task::failed, this, [this, progressStep](QString reason) { + progressStep->state = TaskStepState::Failed; + stepProgress(*progressStep); + emitFailed(reason); + }); + connect(zipTask.get(), &Task::stepProgress, this, &FlamePackExportTask::propagateStepProgress); + + connect(zipTask.get(), &Task::progress, this, [this, progressStep](qint64 current, qint64 total) { + progressStep->update(current, total); + stepProgress(*progressStep); + }); + connect(zipTask.get(), &Task::status, this, [this, progressStep](QString status) { + progressStep->status = status; + stepProgress(*progressStep); + }); + task.reset(zipTask); + zipTask->start(); } QByteArray FlamePackExportTask::generateIndex() @@ -471,3 +414,18 @@ QByteArray FlamePackExportTask::generateIndex() return QJsonDocument(obj).toJson(QJsonDocument::Compact); } + +QByteArray FlamePackExportTask::generateHTML() +{ + QString content = ""; + for (auto mod : resolvedFiles) { + if (mod.isMod) { + content += QString(TEMPLATE) + .replace("{name}", mod.name.toHtmlEscaped()) + .replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.addonId).toHtmlEscaped()) + .replace("{authors}", !mod.authors.isEmpty() ? QString(" (by %1)").arg(mod.authors).toHtmlEscaped() : ""); + } + } + content = "<ul>" + content + "</ul>"; + return content.toUtf8(); +}
\ No newline at end of file diff --git a/launcher/modplatform/flame/FlamePackExportTask.h b/launcher/modplatform/flame/FlamePackExportTask.h index 3dee0a7e..d3dc6281 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.h +++ b/launcher/modplatform/flame/FlamePackExportTask.h @@ -19,8 +19,6 @@ #pragma once -#include <QFuture> -#include <QFutureWatcher> #include "BaseInstance.h" #include "MMCZip.h" #include "minecraft/MinecraftInstance.h" @@ -52,7 +50,6 @@ class FlamePackExportTask : public Task { const QString output; const MMCZip::FilterFunction filter; - typedef std::optional<QString> BuildZipResult; struct ResolvedFile { int addonId; int version; @@ -76,15 +73,13 @@ class FlamePackExportTask : public Task { QMap<QString, HashInfo> pendingHashes{}; QMap<QString, ResolvedFile> resolvedFiles{}; Task::Ptr task; - QFuture<BuildZipResult> buildZipFuture; - QFutureWatcher<BuildZipResult> buildZipWatcher; void collectFiles(); void collectHashes(); void makeApiRequest(); void getProjectsInfo(); void buildZip(); - void finish(); QByteArray generateIndex(); + QByteArray generateHTML(); }; diff --git a/launcher/modplatform/import_ftb/PackHelpers.cpp b/launcher/modplatform/import_ftb/PackHelpers.cpp new file mode 100644 index 00000000..4a1bbef9 --- /dev/null +++ b/launcher/modplatform/import_ftb/PackHelpers.cpp @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 <alexandru.tripon97@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include "modplatform/import_ftb/PackHelpers.h" + +#include <QIcon> +#include <QString> +#include <QVariant> + +#include "FileSystem.h" +#include "Json.h" + +namespace FTBImportAPP { + +Modpack parseDirectory(QString path) +{ + Modpack modpack{ path }; + auto instanceFile = QFileInfo(FS::PathCombine(path, "instance.json")); + if (!instanceFile.exists() || !instanceFile.isFile()) + return {}; + try { + auto doc = Json::requireDocument(instanceFile.absoluteFilePath(), "FTB_APP instance JSON file"); + const auto root = doc.object(); + modpack.uuid = Json::requireString(root, "uuid", "uuid"); + modpack.id = Json::requireInteger(root, "id", "id"); + modpack.versionId = Json::requireInteger(root, "versionId", "versionId"); + modpack.name = Json::requireString(root, "name", "name"); + modpack.version = Json::requireString(root, "version", "version"); + modpack.mcVersion = Json::requireString(root, "mcVersion", "mcVersion"); + modpack.jvmArgs = Json::ensureVariant(root, "jvmArgs", {}, "jvmArgs"); + } catch (const Exception& e) { + qDebug() << "Couldn't load ftb instance json: " << e.cause(); + return {}; + } + auto versionsFile = QFileInfo(FS::PathCombine(path, "version.json")); + if (!versionsFile.exists() || !versionsFile.isFile()) + return {}; + try { + auto doc = Json::requireDocument(versionsFile.absoluteFilePath(), "FTB_APP version JSON file"); + const auto root = doc.object(); + auto targets = Json::requireArray(root, "targets", "targets"); + + for (auto target : targets) { + auto obj = Json::requireObject(target, "target"); + auto name = Json::requireString(obj, "name", "name"); + auto version = Json::requireString(obj, "version", "version"); + if (name == "forge") { + modpack.loaderType = ResourceAPI::Forge; + modpack.version = version; + break; + } else if (name == "fabric") { + modpack.loaderType = ResourceAPI::Fabric; + modpack.version = version; + break; + } else if (name == "quilt") { + modpack.loaderType = ResourceAPI::Quilt; + modpack.version = version; + break; + } + } + } catch (const Exception& e) { + qDebug() << "Couldn't load ftb version json: " << e.cause(); + return {}; + } + auto iconFile = QFileInfo(FS::PathCombine(path, "folder.jpg")); + if (iconFile.exists() && iconFile.isFile()) { + modpack.icon = QIcon(iconFile.absoluteFilePath()); + } + return modpack; +} + +} // namespace FTBImportAPP diff --git a/launcher/modplatform/import_ftb/PackHelpers.h b/launcher/modplatform/import_ftb/PackHelpers.h new file mode 100644 index 00000000..8ea4f3fa --- /dev/null +++ b/launcher/modplatform/import_ftb/PackHelpers.h @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 <alexandru.tripon97@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ +#pragma once + +#include <QIcon> +#include <QList> +#include <QMetaType> +#include <QString> +#include <QVariant> +#include "modplatform/ResourceAPI.h" + +namespace FTBImportAPP { + +struct Modpack { + QString path; + + // json data + QString uuid; + int id; + int versionId; + QString name; + QString version; + QString mcVersion; + // not needed for instance creation + QVariant jvmArgs; + + std::optional<ResourceAPI::ModLoaderType> loaderType; + QString loaderVersion; + + QIcon icon; +}; + +typedef QList<Modpack> ModpackList; + +Modpack parseDirectory(QString path); + +} // namespace FTBImportAPP + +// We need it for the proxy model +Q_DECLARE_METATYPE(FTBImportAPP::Modpack) diff --git a/launcher/modplatform/import_ftb/PackInstallTask.cpp b/launcher/modplatform/import_ftb/PackInstallTask.cpp new file mode 100644 index 00000000..b5e424d1 --- /dev/null +++ b/launcher/modplatform/import_ftb/PackInstallTask.cpp @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 <alexandru.tripon97@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include "PackInstallTask.h" + +#include <QtConcurrent> + +#include "BaseInstance.h" +#include "FileSystem.h" +#include "minecraft/MinecraftInstance.h" +#include "minecraft/PackProfile.h" +#include "modplatform/ResourceAPI.h" +#include "modplatform/import_ftb/PackHelpers.h" +#include "settings/INISettingsObject.h" + +namespace FTBImportAPP { + +void PackInstallTask::executeTask() +{ + setStatus(tr("Copying files...")); + setAbortable(false); + progress(1, 2); + + m_copyFuture = QtConcurrent::run(QThreadPool::globalInstance(), [this] { + FS::copy folderCopy(m_pack.path, FS::PathCombine(m_stagingPath, ".minecraft")); + folderCopy.followSymlinks(true); + return folderCopy(); + }); + connect(&m_copyFutureWatcher, &QFutureWatcher<bool>::finished, this, &PackInstallTask::copySettings); + connect(&m_copyFutureWatcher, &QFutureWatcher<bool>::canceled, this, &PackInstallTask::emitAborted); + m_copyFutureWatcher.setFuture(m_copyFuture); +} + +void PackInstallTask::copySettings() +{ + setStatus(tr("Copying settings...")); + progress(2, 2); + QString instanceConfigPath = FS::PathCombine(m_stagingPath, "instance.cfg"); + auto instanceSettings = std::make_shared<INISettingsObject>(instanceConfigPath); + instanceSettings->suspendSave(); + MinecraftInstance instance(m_globalSettings, instanceSettings, m_stagingPath); + instance.settings()->set("InstanceType", "OneSix"); + + if (m_pack.jvmArgs.isValid() && !m_pack.jvmArgs.toString().isEmpty()) { + instance.settings()->set("OverrideJavaArgs", true); + instance.settings()->set("JvmArgs", m_pack.jvmArgs.toString()); + } + + auto components = instance.getPackProfile(); + components->buildingFromScratch(); + components->setComponentVersion("net.minecraft", m_pack.mcVersion, true); + + auto modloader = m_pack.loaderType; + if (modloader.has_value()) + switch (modloader.value()) { + case ResourceAPI::Forge: { + components->setComponentVersion("net.minecraftforge", m_pack.version, true); + break; + } + case ResourceAPI::Fabric: { + components->setComponentVersion("net.fabricmc.fabric-loader", m_pack.version, true); + break; + } + case ResourceAPI::Quilt: { + components->setComponentVersion("org.quiltmc.quilt-loader", m_pack.version, true); + break; + } + case ResourceAPI::Cauldron: + break; + case ResourceAPI::LiteLoader: + break; + } + components->saveNow(); + + instance.setName(name()); + if (m_instIcon == "default") + m_instIcon = "ftb_logo"; + instance.setIconKey(m_instIcon); + instanceSettings->resumeSave(); + + emitSucceeded(); +} + +} // namespace FTBImportAPP diff --git a/launcher/modplatform/import_ftb/PackInstallTask.h b/launcher/modplatform/import_ftb/PackInstallTask.h new file mode 100644 index 00000000..842e4b35 --- /dev/null +++ b/launcher/modplatform/import_ftb/PackInstallTask.h @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-3.0-only +/* + * Prism Launcher - Minecraft Launcher + * Copyright (c) 2023 Trial97 <alexandru.tripon97@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#pragma once + +#include <QFuture> +#include <QFutureWatcher> + +#include "InstanceTask.h" +#include "PackHelpers.h" + +namespace FTBImportAPP { + +class PackInstallTask : public InstanceTask { + Q_OBJECT + + public: + explicit PackInstallTask(const Modpack& pack) : m_pack(pack) {} + virtual ~PackInstallTask() = default; + + protected: + virtual void executeTask() override; + + private slots: + void copySettings(); + + private: + QFuture<bool> m_copyFuture; + QFutureWatcher<bool> m_copyFutureWatcher; + + const Modpack m_pack; +}; + +} // namespace FTBImportAPP diff --git a/launcher/modplatform/legacy_ftb/PackInstallTask.cpp b/launcher/modplatform/legacy_ftb/PackInstallTask.cpp index a4c78397..1afe5783 100644 --- a/launcher/modplatform/legacy_ftb/PackInstallTask.cpp +++ b/launcher/modplatform/legacy_ftb/PackInstallTask.cpp @@ -81,7 +81,7 @@ void PackInstallTask::downloadPack() connect(netJobContainer.get(), &NetJob::succeeded, this, &PackInstallTask::unzip); connect(netJobContainer.get(), &NetJob::failed, this, &PackInstallTask::emitFailed); - connect(netJobContainer.get(), &NetJob::stepProgress, this, &PackInstallTask::propogateStepProgress); + connect(netJobContainer.get(), &NetJob::stepProgress, this, &PackInstallTask::propagateStepProgress); connect(netJobContainer.get(), &NetJob::aborted, this, &PackInstallTask::emitAborted); netJobContainer->start(); diff --git a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp index 76f07277..bd0b828c 100644 --- a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp @@ -267,7 +267,7 @@ bool ModrinthCreationTask::createInstance() setDetails(tr("%1 out of %2 complete").arg(current).arg(total)); setProgress(current, total); }); - connect(m_files_job.get(), &NetJob::stepProgress, this, &ModrinthCreationTask::propogateStepProgress); + connect(m_files_job.get(), &NetJob::stepProgress, this, &ModrinthCreationTask::propagateStepProgress); setStatus(tr("Downloading mods...")); m_files_job->start(); diff --git a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp index 30fe566d..7bf29639 100644 --- a/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackExportTask.cpp @@ -55,20 +55,11 @@ void ModrinthPackExportTask::executeTask() bool ModrinthPackExportTask::abort() { - if (task != nullptr) { + if (task) { task->abort(); - task = nullptr; emitAborted(); return true; } - - if (buildZipFuture.isRunning()) { - buildZipFuture.cancel(); - // NOTE: Here we don't do `emitAborted()` because it will be done when `buildZipFuture` actually cancels, which may not occur - // immediately. - return true; - } - return false; } @@ -205,63 +196,36 @@ void ModrinthPackExportTask::buildZip() { setStatus(tr("Adding files...")); - buildZipFuture = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { - QuaZip zip(output); - if (!zip.open(QuaZip::mdCreate)) { - QFile::remove(output); - return BuildZipResult(tr("Could not create file")); - } - - if (buildZipFuture.isCanceled()) - return BuildZipResult(); - - QuaZipFile indexFile(&zip); - if (!indexFile.open(QIODevice::WriteOnly, QuaZipNewInfo("modrinth.index.json"))) { - QFile::remove(output); - return BuildZipResult(tr("Could not create index")); - } - indexFile.write(generateIndex()); - - size_t progress = 0; - for (const QFileInfo& file : files) { - if (buildZipFuture.isCanceled()) { - QFile::remove(output); - return BuildZipResult(); - } - - setProgress(progress, files.length()); - const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath()); - if (!resolvedFiles.contains(relative) && !JlCompress::compressFile(&zip, file.absoluteFilePath(), "overrides/" + relative)) { - QFile::remove(output); - return BuildZipResult(tr("Could not read and compress %1").arg(relative)); - } - progress++; - } + auto zipTask = makeShared<MMCZip::ExportToZipTask>(output, gameRoot, files, "overrides/", true); + zipTask->addExtraFile("modrinth.index.json", generateIndex()); - zip.close(); + zipTask->setExcludeFiles(resolvedFiles.keys()); - if (zip.getZipError() != 0) { - QFile::remove(output); - return BuildZipResult(tr("A zip error occurred")); - } + auto progressStep = std::make_shared<TaskStepProgress>(); + connect(zipTask.get(), &Task::finished, this, [this, progressStep] { + progressStep->state = TaskStepState::Succeeded; + stepProgress(*progressStep); + }); - return BuildZipResult(); + connect(zipTask.get(), &Task::succeeded, this, &ModrinthPackExportTask::emitSucceeded); + connect(zipTask.get(), &Task::aborted, this, &ModrinthPackExportTask::emitAborted); + connect(zipTask.get(), &Task::failed, this, [this, progressStep](QString reason) { + progressStep->state = TaskStepState::Failed; + stepProgress(*progressStep); + emitFailed(reason); }); - connect(&buildZipWatcher, &QFutureWatcher<BuildZipResult>::finished, this, &ModrinthPackExportTask::finish); - buildZipWatcher.setFuture(buildZipFuture); -} + connect(zipTask.get(), &Task::stepProgress, this, &ModrinthPackExportTask::propagateStepProgress); -void ModrinthPackExportTask::finish() -{ - if (buildZipFuture.isCanceled()) - emitAborted(); - else { - const BuildZipResult result = buildZipFuture.result(); - if (result.has_value()) - emitFailed(result.value()); - else - emitSucceeded(); - } + connect(zipTask.get(), &Task::progress, this, [this, progressStep](qint64 current, qint64 total) { + progressStep->update(current, total); + stepProgress(*progressStep); + }); + connect(zipTask.get(), &Task::status, this, [this, progressStep](QString status) { + progressStep->status = status; + stepProgress(*progressStep); + }); + task.reset(zipTask); + zipTask->start(); } QByteArray ModrinthPackExportTask::generateIndex() diff --git a/launcher/modplatform/modrinth/ModrinthPackExportTask.h b/launcher/modplatform/modrinth/ModrinthPackExportTask.h index 96f292c1..1f9e0eb7 100644 --- a/launcher/modplatform/modrinth/ModrinthPackExportTask.h +++ b/launcher/modplatform/modrinth/ModrinthPackExportTask.h @@ -56,22 +56,17 @@ class ModrinthPackExportTask : public Task { const QString output; const MMCZip::FilterFunction filter; - typedef std::optional<QString> BuildZipResult; - ModrinthAPI api; QFileInfoList files; QMap<QString, QString> pendingHashes; QMap<QString, ResolvedFile> resolvedFiles; Task::Ptr task; - QFuture<BuildZipResult> buildZipFuture; - QFutureWatcher<BuildZipResult> buildZipWatcher; void collectFiles(); void collectHashes(); void makeApiRequest(); void parseApiResponse(const std::shared_ptr<QByteArray> response); void buildZip(); - void finish(); QByteArray generateIndex(); }; diff --git a/launcher/modplatform/technic/SingleZipPackInstallTask.cpp b/launcher/modplatform/technic/SingleZipPackInstallTask.cpp index f07ca24a..ab91c466 100644 --- a/launcher/modplatform/technic/SingleZipPackInstallTask.cpp +++ b/launcher/modplatform/technic/SingleZipPackInstallTask.cpp @@ -50,7 +50,7 @@ void Technic::SingleZipPackInstallTask::executeTask() auto job = m_filesNetJob.get(); connect(job, &NetJob::succeeded, this, &Technic::SingleZipPackInstallTask::downloadSucceeded); connect(job, &NetJob::progress, this, &Technic::SingleZipPackInstallTask::downloadProgressChanged); - connect(job, &NetJob::stepProgress, this, &Technic::SingleZipPackInstallTask::propogateStepProgress); + connect(job, &NetJob::stepProgress, this, &Technic::SingleZipPackInstallTask::propagateStepProgress); connect(job, &NetJob::failed, this, &Technic::SingleZipPackInstallTask::downloadFailed); m_filesNetJob->start(); } diff --git a/launcher/modplatform/technic/SolderPackInstallTask.cpp b/launcher/modplatform/technic/SolderPackInstallTask.cpp index 6a05d17a..cc1d261e 100644 --- a/launcher/modplatform/technic/SolderPackInstallTask.cpp +++ b/launcher/modplatform/technic/SolderPackInstallTask.cpp @@ -126,7 +126,7 @@ void Technic::SolderPackInstallTask::fileListSucceeded() connect(m_filesNetJob.get(), &NetJob::succeeded, this, &Technic::SolderPackInstallTask::downloadSucceeded); connect(m_filesNetJob.get(), &NetJob::progress, this, &Technic::SolderPackInstallTask::downloadProgressChanged); - connect(m_filesNetJob.get(), &NetJob::stepProgress, this, &Technic::SolderPackInstallTask::propogateStepProgress); + connect(m_filesNetJob.get(), &NetJob::stepProgress, this, &Technic::SolderPackInstallTask::propagateStepProgress); connect(m_filesNetJob.get(), &NetJob::failed, this, &Technic::SolderPackInstallTask::downloadFailed); connect(m_filesNetJob.get(), &NetJob::aborted, this, &Technic::SolderPackInstallTask::downloadAborted); m_filesNetJob->start(); |