aboutsummaryrefslogtreecommitdiff
path: root/launcher/modplatform
diff options
context:
space:
mode:
authorRachel Powers <508861+Ryex@users.noreply.github.com>2023-05-28 11:25:58 -0700
committerRachel Powers <508861+Ryex@users.noreply.github.com>2023-07-11 21:42:29 -0700
commit9957aeb003a28f24a7d3b2bbc46d21c31506615d (patch)
tree891048851c7819f334abf384a7d99dbeec7bf0ea /launcher/modplatform
parenteb079c80605f88cbd0aaff8285dafc459c6f42eb (diff)
parent640aaa8c23d714ce17bc8e78754af6219abc6466 (diff)
downloadPrismLauncher-9957aeb003a28f24a7d3b2bbc46d21c31506615d.tar.gz
PrismLauncher-9957aeb003a28f24a7d3b2bbc46d21c31506615d.tar.bz2
PrismLauncher-9957aeb003a28f24a7d3b2bbc46d21c31506615d.zip
Merge branch 'develop' into curseforge-url-handle
Diffstat (limited to 'launcher/modplatform')
-rw-r--r--launcher/modplatform/EnsureMetadataTask.cpp25
-rw-r--r--launcher/modplatform/ModIndex.cpp8
-rw-r--r--launcher/modplatform/ModIndex.h66
-rw-r--r--launcher/modplatform/ResourceAPI.h20
-rw-r--r--launcher/modplatform/atlauncher/ATLPackInstallTask.cpp19
-rw-r--r--launcher/modplatform/atlauncher/ATLPackInstallTask.h49
-rw-r--r--launcher/modplatform/flame/FileResolvingTask.cpp130
-rw-r--r--launcher/modplatform/flame/FileResolvingTask.h36
-rw-r--r--launcher/modplatform/flame/FlameAPI.cpp51
-rw-r--r--launcher/modplatform/flame/FlameAPI.h58
-rw-r--r--launcher/modplatform/flame/FlameCheckUpdate.cpp26
-rw-r--r--launcher/modplatform/flame/FlameInstanceCreationTask.cpp9
-rw-r--r--launcher/modplatform/flame/FlameModIndex.cpp81
-rw-r--r--launcher/modplatform/flame/FlameModIndex.h6
-rw-r--r--launcher/modplatform/flame/FlamePackExportTask.cpp473
-rw-r--r--launcher/modplatform/flame/FlamePackExportTask.h90
-rw-r--r--launcher/modplatform/flame/FlamePackIndex.h10
-rw-r--r--launcher/modplatform/helpers/HashUtils.cpp16
-rw-r--r--launcher/modplatform/helpers/HashUtils.h5
-rw-r--r--launcher/modplatform/helpers/NetworkResourceAPI.cpp56
-rw-r--r--launcher/modplatform/helpers/NetworkResourceAPI.h5
-rw-r--r--launcher/modplatform/legacy_ftb/PackFetchTask.cpp68
-rw-r--r--launcher/modplatform/legacy_ftb/PackFetchTask.h26
-rw-r--r--launcher/modplatform/modrinth/ModrinthAPI.cpp22
-rw-r--r--launcher/modplatform/modrinth/ModrinthAPI.h43
-rw-r--r--launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp33
-rw-r--r--launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp2
-rw-r--r--launcher/modplatform/modrinth/ModrinthPackExportTask.cpp332
-rw-r--r--launcher/modplatform/modrinth/ModrinthPackExportTask.h77
-rw-r--r--launcher/modplatform/modrinth/ModrinthPackIndex.cpp43
-rw-r--r--launcher/modplatform/modrinth/ModrinthPackIndex.h3
-rw-r--r--launcher/modplatform/technic/SolderPackInstallTask.cpp33
-rw-r--r--launcher/modplatform/technic/SolderPackInstallTask.h73
33 files changed, 1600 insertions, 394 deletions
diff --git a/launcher/modplatform/EnsureMetadataTask.cpp b/launcher/modplatform/EnsureMetadataTask.cpp
index 34d969f0..93b5ce76 100644
--- a/launcher/modplatform/EnsureMetadataTask.cpp
+++ b/launcher/modplatform/EnsureMetadataTask.cpp
@@ -10,6 +10,7 @@
#include "modplatform/flame/FlameAPI.h"
#include "modplatform/flame/FlameModIndex.h"
+#include "modplatform/helpers/HashUtils.h"
#include "modplatform/modrinth/ModrinthAPI.h"
#include "modplatform/modrinth/ModrinthPackIndex.h"
@@ -24,8 +25,8 @@ EnsureMetadataTask::EnsureMetadataTask(Mod* mod, QDir dir, ModPlatform::Resource
auto hash_task = createNewHash(mod);
if (!hash_task)
return;
- connect(hash_task.get(), &Task::succeeded, [this, hash_task, mod] { m_mods.insert(hash_task->getResult(), mod); });
- connect(hash_task.get(), &Task::failed, [this, hash_task, mod] { emitFail(mod, "", RemoveFromList::No); });
+ connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, mod](QString hash) { m_mods.insert(hash, mod); });
+ connect(hash_task.get(), &Task::failed, [this, mod] { emitFail(mod, "", RemoveFromList::No); });
hash_task->start();
}
@@ -37,8 +38,8 @@ EnsureMetadataTask::EnsureMetadataTask(QList<Mod*>& mods, QDir dir, ModPlatform:
auto hash_task = createNewHash(mod);
if (!hash_task)
continue;
- connect(hash_task.get(), &Task::succeeded, [this, hash_task, mod] { m_mods.insert(hash_task->getResult(), mod); });
- connect(hash_task.get(), &Task::failed, [this, hash_task, mod] { emitFail(mod, "", RemoveFromList::No); });
+ connect(hash_task.get(), &Hashing::Hasher::resultsReady, [this, mod](QString hash) { m_mods.insert(hash, mod); });
+ connect(hash_task.get(), &Task::failed, [this, mod] { emitFail(mod, "", RemoveFromList::No); });
m_hashing_task->addTask(hash_task);
}
}
@@ -212,12 +213,12 @@ Task::Ptr EnsureMetadataTask::modrinthVersionsTask()
{
auto hash_type = ProviderCaps.hashType(ModPlatform::ResourceProvider::MODRINTH).first();
- auto* response = new QByteArray();
+ auto response = std::make_shared<QByteArray>();
auto ver_task = modrinth_api.currentVersions(m_mods.keys(), hash_type, response);
// Prevents unfortunate timings when aborting the task
if (!ver_task)
- return Task::Ptr{nullptr};
+ return Task::Ptr{ nullptr };
connect(ver_task.get(), &Task::succeeded, this, [this, response] {
QJsonParseError parse_error{};
@@ -264,7 +265,7 @@ Task::Ptr EnsureMetadataTask::modrinthProjectsTask()
for (auto const& data : m_temp_versions)
addonIds.insert(data.addonId.toString(), data.hash);
- auto response = new QByteArray();
+ auto response = std::make_shared<QByteArray>();
Task::Ptr proj_task;
if (addonIds.isEmpty()) {
@@ -277,7 +278,7 @@ Task::Ptr EnsureMetadataTask::modrinthProjectsTask()
// Prevents unfortunate timings when aborting the task
if (!proj_task)
- return Task::Ptr{nullptr};
+ return Task::Ptr{ nullptr };
connect(proj_task.get(), &Task::succeeded, this, [this, response, addonIds] {
QJsonParseError parse_error{};
@@ -345,7 +346,7 @@ Task::Ptr EnsureMetadataTask::modrinthProjectsTask()
// Flame
Task::Ptr EnsureMetadataTask::flameVersionsTask()
{
- auto* response = new QByteArray();
+ auto response = std::make_shared<QByteArray>();
QList<uint> fingerprints;
for (auto& murmur : m_mods.keys()) {
@@ -413,7 +414,7 @@ Task::Ptr EnsureMetadataTask::flameProjectsTask()
QHash<QString, QString> addonIds;
for (auto const& hash : m_mods.keys()) {
if (m_temp_versions.contains(hash)) {
- auto const& data = m_temp_versions.find(hash).value();
+ auto data = m_temp_versions.find(hash).value();
auto id_str = data.addonId.toString();
if (!id_str.isEmpty())
@@ -421,7 +422,7 @@ Task::Ptr EnsureMetadataTask::flameProjectsTask()
}
}
- auto response = new QByteArray();
+ auto response = std::make_shared<QByteArray>();
Task::Ptr proj_task;
if (addonIds.isEmpty()) {
@@ -434,7 +435,7 @@ Task::Ptr EnsureMetadataTask::flameProjectsTask()
// Prevents unfortunate timings when aborting the task
if (!proj_task)
- return Task::Ptr{nullptr};
+ return Task::Ptr{ nullptr };
connect(proj_task.get(), &Task::succeeded, this, [this, response, addonIds] {
QJsonParseError parse_error{};
diff --git a/launcher/modplatform/ModIndex.cpp b/launcher/modplatform/ModIndex.cpp
index 6a507caf..a1c4d891 100644
--- a/launcher/modplatform/ModIndex.cpp
+++ b/launcher/modplatform/ModIndex.cpp
@@ -70,11 +70,17 @@ auto ProviderCapabilities::hash(ResourceProvider p, QIODevice* device, QString t
}
QCryptographicHash hash(algo);
- if(!hash.addData(device))
+ if (!hash.addData(device))
qCritical() << "Failed to read JAR to create hash!";
Q_ASSERT(hash.result().length() == hash.hashLength(algo));
return { hash.result().toHex() };
}
+QString getMetaURL(ResourceProvider provider, QVariant projectID)
+{
+ return ((provider == ModPlatform::ResourceProvider::FLAME) ? "https://www.curseforge.com/projects/" : "https://modrinth.com/mod/") +
+ projectID.toString();
+}
+
} // namespace ModPlatform
diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h
index 40f1efc4..2aa91602 100644
--- a/launcher/modplatform/ModIndex.h
+++ b/launcher/modplatform/ModIndex.h
@@ -1,20 +1,21 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
-* PolyMC - Minecraft Launcher
-* Copyright (c) 2022 flowln <flowlnlnln@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/>.
-*/
+ * Prism Launcher - Minecraft Launcher
+ * Copyright (c) 2022 flowln <flowlnlnln@gmail.com>
+ * 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
@@ -23,6 +24,7 @@
#include <QString>
#include <QVariant>
#include <QVector>
+#include <memory>
class QIODevice;
@@ -32,6 +34,8 @@ enum class ResourceProvider { MODRINTH, FLAME };
enum class ResourceType { MOD, RESOURCE_PACK, SHADER_PACK };
+enum class DependencyType { REQUIRED, OPTIONAL, INCOMPATIBLE, EMBEDDED, TOOL, INCLUDE, UNKNOWN };
+
class ProviderCapabilities {
public:
auto name(ResourceProvider) -> const char*;
@@ -51,6 +55,12 @@ struct DonationData {
QString url;
};
+struct Dependency {
+ QVariant addonId;
+ DependencyType type;
+ QString version;
+};
+
struct IndexedVersion {
QVariant addonId;
QVariant fileId;
@@ -65,10 +75,10 @@ struct IndexedVersion {
QString hash;
bool is_preferred = true;
QString changelog;
+ QList<Dependency> dependencies;
// For internal use, not provided by APIs
bool is_currently_selected = false;
- QString custom_target_folder;
};
struct ExtraPackData {
@@ -83,6 +93,8 @@ struct ExtraPackData {
};
struct IndexedPack {
+ using Ptr = std::shared_ptr<IndexedPack>;
+
QVariant addonId;
ResourceProvider provider;
QString name;
@@ -113,12 +125,30 @@ struct IndexedPack {
if (!versionsLoaded)
return false;
- return std::any_of(versions.constBegin(), versions.constEnd(),
- [](auto const& v) { return v.is_currently_selected; });
+ return std::any_of(versions.constBegin(), versions.constEnd(), [](auto const& v) { return v.is_currently_selected; });
}
};
+QString getMetaURL(ResourceProvider provider, QVariant projectID);
+
+struct OverrideDep {
+ QString quilt;
+ QString fabric;
+ QString slug;
+ ModPlatform::ResourceProvider provider;
+};
+
+inline auto getOverrideDeps() -> QList<OverrideDep>
+{
+ return { { "634179", "306612", "API", ModPlatform::ResourceProvider::FLAME },
+ { "720410", "308769", "KotlinLibraries", ModPlatform::ResourceProvider::FLAME },
+
+ { "qvIfYCYJ", "P7dR8mSH", "API", ModPlatform::ResourceProvider::MODRINTH },
+ { "lwVhp9o5", "Ha28R6CL", "KotlinLibraries", ModPlatform::ResourceProvider::MODRINTH } };
+};
+QString getMetaURL(ResourceProvider provider, QVariant projectID);
} // namespace ModPlatform
Q_DECLARE_METATYPE(ModPlatform::IndexedPack)
+Q_DECLARE_METATYPE(ModPlatform::IndexedPack::Ptr)
Q_DECLARE_METATYPE(ModPlatform::ResourceProvider)
diff --git a/launcher/modplatform/ResourceAPI.h b/launcher/modplatform/ResourceAPI.h
index 34f33779..d3277761 100644
--- a/launcher/modplatform/ResourceAPI.h
+++ b/launcher/modplatform/ResourceAPI.h
@@ -111,6 +111,16 @@ class ResourceAPI {
std::function<void(QJsonDocument&, ModPlatform::IndexedPack)> on_succeed;
};
+ struct DependencySearchArgs {
+ ModPlatform::Dependency dependency;
+ Version mcVersion;
+ ModLoaderTypes loader;
+ };
+
+ struct DependencySearchCallbacks {
+ std::function<void(QJsonDocument&, const ModPlatform::Dependency&)> on_succeed;
+ };
+
public:
/** Gets a list of available sorting methods for this API. */
[[nodiscard]] virtual auto getSortingMethods() const -> QList<SortingMethod> = 0;
@@ -121,12 +131,12 @@ class ResourceAPI {
qWarning() << "TODO";
return nullptr;
}
- [[nodiscard]] virtual Task::Ptr getProject(QString addonId, QByteArray* response) const
+ [[nodiscard]] virtual Task::Ptr getProject(QString addonId, std::shared_ptr<QByteArray> response) const
{
qWarning() << "TODO";
return nullptr;
}
- [[nodiscard]] virtual Task::Ptr getProjects(QStringList addonIds, QByteArray* response) const
+ [[nodiscard]] virtual Task::Ptr getProjects(QStringList addonIds, std::shared_ptr<QByteArray> response) const
{
qWarning() << "TODO";
return nullptr;
@@ -143,6 +153,12 @@ class ResourceAPI {
return nullptr;
}
+ [[nodiscard]] virtual Task::Ptr getDependencyVersion(DependencySearchArgs&&, DependencySearchCallbacks&&) const
+ {
+ qWarning() << "TODO";
+ return nullptr;
+ }
+
static auto getModLoaderString(ModLoaderType type) -> const QString
{
switch (type) {
diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp
index 96cea7b7..22ea02da 100644
--- a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp
+++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp
@@ -82,9 +82,9 @@ void PackInstallTask::executeTask()
{
qDebug() << "PackInstallTask::executeTask: " << QThread::currentThreadId();
NetJob::Ptr netJob{ new NetJob("ATLauncher::VersionFetch", APPLICATION->network()) };
- auto searchUrl = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "packs/%1/versions/%2/Configs.json")
- .arg(m_pack_safe_name).arg(m_version_name);
- netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response));
+ auto searchUrl =
+ QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "packs/%1/versions/%2/Configs.json").arg(m_pack_safe_name).arg(m_version_name);
+ netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), response));
QObject::connect(netJob.get(), &NetJob::succeeded, this, &PackInstallTask::onDownloadSucceeded);
QObject::connect(netJob.get(), &NetJob::failed, this, &PackInstallTask::onDownloadFailed);
@@ -99,11 +99,12 @@ void PackInstallTask::onDownloadSucceeded()
qDebug() << "PackInstallTask::onDownloadSucceeded: " << QThread::currentThreadId();
jobPtr.reset();
- QJsonParseError parse_error {};
- QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error);
- if(parse_error.error != QJsonParseError::NoError) {
- qWarning() << "Error while parsing JSON response from ATLauncher at " << parse_error.offset << " reason: " << parse_error.errorString();
- qWarning() << response;
+ QJsonParseError parse_error{};
+ QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
+ if (parse_error.error != QJsonParseError::NoError) {
+ qWarning() << "Error while parsing JSON response from ATLauncher at " << parse_error.offset
+ << " reason: " << parse_error.errorString();
+ qWarning() << *response.get();
return;
}
auto obj = doc.object();
@@ -352,7 +353,7 @@ QString PackInstallTask::getVersionForLoader(QString uid)
if(m_version.loader.recommended || m_version.loader.latest) {
for (int i = 0; i < vlist->versions().size(); i++) {
auto version = vlist->versions().at(i);
- auto reqs = version->requires();
+ auto reqs = version->requiredSet();
// filter by minecraft version, if the loader depends on a certain version.
// not all mod loaders depend on a given Minecraft version, so we won't do this
diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.h b/launcher/modplatform/atlauncher/ATLPackInstallTask.h
index 90e25ae2..b82f523f 100644
--- a/launcher/modplatform/atlauncher/ATLPackInstallTask.h
+++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.h
@@ -40,12 +40,13 @@
#include "ATLPackManifest.h"
#include "InstanceTask.h"
-#include "net/NetJob.h"
-#include "settings/INISettingsObject.h"
+#include "meta/Version.h"
#include "minecraft/MinecraftInstance.h"
#include "minecraft/PackProfile.h"
-#include "meta/Version.h"
+#include "net/NetJob.h"
+#include "settings/INISettingsObject.h"
+#include <memory>
#include <optional>
namespace ATLauncher {
@@ -57,8 +58,7 @@ enum class InstallMode {
};
class UserInteractionSupport {
-
-public:
+ public:
/**
* Requests a user interaction to select which optional mods should be installed.
*/
@@ -74,23 +74,27 @@ public:
* Requests a user interaction to display a message.
*/
virtual void displayMessage(QString message) = 0;
+
+ virtual ~UserInteractionSupport() = default;
};
-class PackInstallTask : public InstanceTask
-{
-Q_OBJECT
+class PackInstallTask : public InstanceTask {
+ Q_OBJECT
-public:
- explicit PackInstallTask(UserInteractionSupport *support, QString packName, QString version, InstallMode installMode = InstallMode::Install);
- virtual ~PackInstallTask(){}
+ public:
+ explicit PackInstallTask(UserInteractionSupport* support,
+ QString packName,
+ QString version,
+ InstallMode installMode = InstallMode::Install);
+ virtual ~PackInstallTask() { delete m_support; }
bool canAbort() const override { return true; }
bool abort() override;
-protected:
+ protected:
virtual void executeTask() override;
-private slots:
+ private slots:
void onDownloadSucceeded();
void onDownloadFailed(QString reason);
void onDownloadAborted();
@@ -98,7 +102,7 @@ private slots:
void onModsDownloaded();
void onModsExtracted();
-private:
+ private:
QString getDirForModType(ModType type, QString raw);
QString getVersionForLoader(QString uid);
QString detectLibrary(VersionLibrary library);
@@ -110,20 +114,18 @@ private:
void installConfigs();
void extractConfigs();
void downloadMods();
- bool extractMods(
- const QMap<QString, VersionMod> &toExtract,
- const QMap<QString, VersionMod> &toDecomp,
- const QMap<QString, QString> &toCopy
- );
+ bool extractMods(const QMap<QString, VersionMod>& toExtract,
+ const QMap<QString, VersionMod>& toDecomp,
+ const QMap<QString, QString>& toCopy);
void install();
-private:
- UserInteractionSupport *m_support;
+ private:
+ UserInteractionSupport* m_support;
bool abortable = false;
NetJob::Ptr jobPtr;
- QByteArray response;
+ std::shared_ptr<QByteArray> response = std::make_shared<QByteArray>();
InstallMode m_install_mode;
QString m_pack_name;
@@ -145,7 +147,6 @@ private:
QFuture<bool> m_modExtractFuture;
QFutureWatcher<bool> m_modExtractFutureWatcher;
-
};
-}
+} // namespace ATLauncher
diff --git a/launcher/modplatform/flame/FileResolvingTask.cpp b/launcher/modplatform/flame/FileResolvingTask.cpp
index d3a737bb..ce7a6055 100644
--- a/launcher/modplatform/flame/FileResolvingTask.cpp
+++ b/launcher/modplatform/flame/FileResolvingTask.cpp
@@ -25,17 +25,40 @@ void Flame::FileResolvingTask::executeTask()
setProgress(0, 3);
m_dljob.reset(new NetJob("Mod id resolver", m_network));
result.reset(new QByteArray());
- //build json data to send
+ // build json data to send
QJsonObject object;
- object["fileIds"] = QJsonArray::fromVariantList(std::accumulate(m_toProcess.files.begin(), m_toProcess.files.end(), QVariantList(), [](QVariantList& l, const File& s) {
- l.push_back(s.fileId);
- return l;
- }));
+ object["fileIds"] = QJsonArray::fromVariantList(
+ std::accumulate(m_toProcess.files.begin(), m_toProcess.files.end(), QVariantList(), [](QVariantList& l, const File& s) {
+ l.push_back(s.fileId);
+ return l;
+ }));
QByteArray data = Json::toText(object);
- auto dl = Net::Upload::makeByteArray(QUrl("https://api.curseforge.com/v1/mods/files"), result.get(), data);
+ auto dl = Net::Upload::makeByteArray(QUrl("https://api.curseforge.com/v1/mods/files"), result, data);
m_dljob->addNetAction(dl);
- connect(m_dljob.get(), &NetJob::finished, this, &Flame::FileResolvingTask::netJobFinished);
+
+ auto step_progress = std::make_shared<TaskStepProgress>();
+ connect(m_dljob.get(), &NetJob::finished, this, [this, step_progress]() {
+ step_progress->state = TaskStepState::Succeeded;
+ stepProgress(*step_progress);
+ netJobFinished();
+ });
+ connect(m_dljob.get(), &NetJob::failed, this, [this, step_progress](QString reason) {
+ step_progress->state = TaskStepState::Failed;
+ stepProgress(*step_progress);
+ emitFailed(reason);
+ });
+ connect(m_dljob.get(), &NetJob::stepProgress, this, &FileResolvingTask::propogateStepProgress);
+ 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);
+ stepProgress(*step_progress);
+ });
+ connect(m_dljob.get(), &NetJob::status, this, [this, step_progress](QString status) {
+ step_progress->status = status;
+ stepProgress(*step_progress);
+ });
+
m_dljob->start();
}
@@ -44,7 +67,7 @@ void Flame::FileResolvingTask::netJobFinished()
setProgress(1, 3);
// job to check modrinth for blocked projects
m_checkJob.reset(new NetJob("Modrinth check", m_network));
- blockedProjects = QMap<File *,QByteArray *>();
+ blockedProjects = QMap<File*, std::shared_ptr<QByteArray>>();
QJsonDocument doc;
QJsonArray array;
@@ -65,24 +88,42 @@ void Flame::FileResolvingTask::netJobFinished()
auto fileid = Json::requireInteger(Json::requireObject(file)["id"]);
auto& out = m_toProcess.files[fileid];
try {
- out.parseFromObject(Json::requireObject(file));
+ out.parseFromObject(Json::requireObject(file));
} catch (const JSONValidationError& e) {
qDebug() << "Blocked mod on curseforge" << out.fileName;
auto hash = out.hash;
- if(!hash.isEmpty()) {
+ if (!hash.isEmpty()) {
auto url = QString("https://api.modrinth.com/v2/version_file/%1?algorithm=sha1").arg(hash);
- auto output = new QByteArray();
+ auto output = std::make_shared<QByteArray>();
auto dl = Net::Download::makeByteArray(QUrl(url), output);
- QObject::connect(dl.get(), &Net::Download::succeeded, [&out]() {
- out.resolved = true;
- });
+ QObject::connect(dl.get(), &Net::Download::succeeded, [&out]() { out.resolved = true; });
m_checkJob->addNetAction(dl);
blockedProjects.insert(&out, output);
}
}
}
- connect(m_checkJob.get(), &NetJob::finished, this, &Flame::FileResolvingTask::modrinthCheckFinished);
+ auto step_progress = std::make_shared<TaskStepProgress>();
+ connect(m_checkJob.get(), &NetJob::finished, this, [this, step_progress]() {
+ step_progress->state = TaskStepState::Succeeded;
+ stepProgress(*step_progress);
+ modrinthCheckFinished();
+ });
+ connect(m_checkJob.get(), &NetJob::failed, this, [this, step_progress](QString reason) {
+ step_progress->state = TaskStepState::Failed;
+ stepProgress(*step_progress);
+ emitFailed(reason);
+ });
+ connect(m_checkJob.get(), &NetJob::stepProgress, this, &FileResolvingTask::propogateStepProgress);
+ 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);
+ stepProgress(*step_progress);
+ });
+ connect(m_checkJob.get(), &NetJob::status, this, [this, step_progress](QString status) {
+ step_progress->status = status;
+ stepProgress(*step_progress);
+ });
m_checkJob->start();
}
@@ -95,7 +136,6 @@ void Flame::FileResolvingTask::modrinthCheckFinished() {
auto &out = *it;
auto bytes = blockedProjects[out];
if (!out->resolved) {
- delete bytes;
continue;
}
@@ -112,11 +152,9 @@ void Flame::FileResolvingTask::modrinthCheckFinished() {
} else {
out->resolved = false;
}
-
- delete bytes;
}
//copy to an output list and filter out projects found on modrinth
- auto block = new QList<File *>();
+ auto block = std::make_shared<QList<File*>>();
auto it = blockedProjects.keys();
std::copy_if(it.begin(), it.end(), std::back_inserter(*block), [](File *f) {
return !f->resolved;
@@ -124,32 +162,48 @@ void Flame::FileResolvingTask::modrinthCheckFinished() {
//Display not found mods early
if (!block->empty()) {
//blocked mods found, we need the slug for displaying.... we need another job :D !
- auto slugJob = new NetJob("Slug Job", m_network);
- auto slugs = QVector<QByteArray>(block->size());
- auto index = 0;
- for (auto fileInfo: *block) {
- auto projectId = fileInfo->projectId;
- slugs[index] = QByteArray();
+ m_slugJob.reset(new NetJob("Slug Job", m_network));
+ int index = 0;
+ for (auto mod : *block) {
+ auto projectId = mod->projectId;
+ auto output = std::make_shared<QByteArray>();
auto url = QString("https://api.curseforge.com/v1/mods/%1").arg(projectId);
- auto dl = Net::Download::makeByteArray(url, &slugs[index]);
- slugJob->addNetAction(dl);
- index++;
- }
- connect(slugJob, &NetJob::succeeded, this, [slugs, this, slugJob, block]() {
- slugJob->deleteLater();
- auto index = 0;
- for (const auto &slugResult: slugs) {
- auto json = QJsonDocument::fromJson(slugResult);
+ auto dl = Net::Download::makeByteArray(url, output);
+ qDebug() << "Fetching url slug for file:" << mod->fileName;
+ QObject::connect(dl.get(), &Net::Download::succeeded, [block, index, output]() {
+ auto mod = block->at(index); // use the shared_ptr so it is captured and only freed when we are done
+ auto json = QJsonDocument::fromJson(*output);
auto base = Json::requireString(Json::requireObject(Json::requireObject(Json::requireObject(json),"data"),"links"),
"websiteUrl");
- auto mod = block->at(index);
auto link = QString("%1/download/%2").arg(base, QString::number(mod->fileId));
mod->websiteUrl = link;
- index++;
- }
+ });
+ m_slugJob->addNetAction(dl);
+ index++;
+ }
+ auto step_progress = std::make_shared<TaskStepProgress>();
+ connect(m_slugJob.get(), &NetJob::succeeded, this, [this, step_progress]() {
+ step_progress->state = TaskStepState::Succeeded;
+ stepProgress(*step_progress);
emitSucceeded();
});
- slugJob->start();
+ connect(m_slugJob.get(), &NetJob::failed, this, [this, step_progress](QString reason) {
+ step_progress->state = TaskStepState::Failed;
+ stepProgress(*step_progress);
+ emitFailed(reason);
+ });
+ connect(m_slugJob.get(), &NetJob::stepProgress, this, &FileResolvingTask::propogateStepProgress);
+ connect(m_slugJob.get(), &NetJob::p