aboutsummaryrefslogtreecommitdiff
path: root/launcher/modplatform
diff options
context:
space:
mode:
Diffstat (limited to 'launcher/modplatform')
-rw-r--r--launcher/modplatform/atlauncher/ATLPackInstallTask.cpp4
-rw-r--r--launcher/modplatform/flame/FileResolvingTask.cpp6
-rw-r--r--launcher/modplatform/flame/FlameInstanceCreationTask.cpp4
-rw-r--r--launcher/modplatform/flame/FlamePackExportTask.cpp134
-rw-r--r--launcher/modplatform/flame/FlamePackExportTask.h7
-rw-r--r--launcher/modplatform/import_ftb/PackHelpers.cpp87
-rw-r--r--launcher/modplatform/import_ftb/PackHelpers.h55
-rw-r--r--launcher/modplatform/import_ftb/PackInstallTask.cpp99
-rw-r--r--launcher/modplatform/import_ftb/PackInstallTask.h49
-rw-r--r--launcher/modplatform/legacy_ftb/PackInstallTask.cpp2
-rw-r--r--launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp2
-rw-r--r--launcher/modplatform/modrinth/ModrinthPackExportTask.cpp88
-rw-r--r--launcher/modplatform/modrinth/ModrinthPackExportTask.h5
-rw-r--r--launcher/modplatform/technic/SingleZipPackInstallTask.cpp2
-rw-r--r--launcher/modplatform/technic/SolderPackInstallTask.cpp2
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();