aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--launcher/CMakeLists.txt2
-rw-r--r--launcher/ResourceDownloadTask.h2
-rw-r--r--launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp182
-rw-r--r--launcher/minecraft/mod/tasks/GetModDependenciesTask.h81
-rw-r--r--launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp33
-rw-r--r--launcher/modplatform/ModIndex.h12
-rw-r--r--launcher/modplatform/ResourceAPI.h24
-rw-r--r--launcher/modplatform/flame/FlameAPI.h15
-rw-r--r--launcher/modplatform/flame/FlameModIndex.cpp78
-rw-r--r--launcher/modplatform/flame/FlameModIndex.h6
-rw-r--r--launcher/modplatform/flame/FlamePackIndex.h10
-rw-r--r--launcher/modplatform/helpers/NetworkResourceAPI.cpp54
-rw-r--r--launcher/modplatform/helpers/NetworkResourceAPI.h2
-rw-r--r--launcher/modplatform/modrinth/ModrinthAPI.h35
-rw-r--r--launcher/modplatform/modrinth/ModrinthPackIndex.cpp41
-rw-r--r--launcher/modplatform/modrinth/ModrinthPackIndex.h3
-rw-r--r--launcher/ui/dialogs/ResourceDownloadDialog.cpp74
-rw-r--r--launcher/ui/dialogs/ResourceDownloadDialog.h4
-rw-r--r--launcher/ui/dialogs/ReviewMessageBox.cpp29
-rw-r--r--launcher/ui/dialogs/ReviewMessageBox.h8
-rw-r--r--launcher/ui/pages/modplatform/ModModel.h1
-rw-r--r--launcher/ui/pages/modplatform/flame/FlameResourceModels.cpp7
-rw-r--r--launcher/ui/pages/modplatform/flame/FlameResourceModels.h1
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.cpp11
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthResourceModels.h1
25 files changed, 624 insertions, 92 deletions
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index ce2771a4..9bad2a67 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -362,6 +362,8 @@ set(MINECRAFT_SOURCES
minecraft/mod/tasks/LocalWorldSaveParseTask.cpp
minecraft/mod/tasks/LocalResourceParse.h
minecraft/mod/tasks/LocalResourceParse.cpp
+ minecraft/mod/tasks/GetModDependenciesTask.h
+ minecraft/mod/tasks/GetModDependenciesTask.cpp
# Assets
minecraft/AssetsUtils.h
diff --git a/launcher/ResourceDownloadTask.h b/launcher/ResourceDownloadTask.h
index 09147c8c..2baddf8a 100644
--- a/launcher/ResourceDownloadTask.h
+++ b/launcher/ResourceDownloadTask.h
@@ -38,6 +38,8 @@ class ResourceDownloadTask : public SequentialTask {
const QString& getFilename() const { return m_pack_version.fileName; }
const QString& getCustomPath() const { return m_custom_target_folder; }
const QVariant& getVersionID() const { return m_pack_version.fileId; }
+ const ModPlatform::IndexedVersion& getVersion() const { return m_pack_version; }
+ const ModPlatform::ResourceProvider& getProvider() const { return m_pack->provider; }
const QString& getName() const { return m_pack->name; }
ModPlatform::IndexedPack::Ptr getPack() { return m_pack; }
diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp
new file mode 100644
index 00000000..bd80a661
--- /dev/null
+++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp
@@ -0,0 +1,182 @@
+// 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 "GetModDependenciesTask.h"
+
+#include <QDebug>
+#include <algorithm>
+#include <memory>
+#include "Json.h"
+#include "QObjectPtr.h"
+#include "minecraft/mod/MetadataHandler.h"
+#include "modplatform/ModIndex.h"
+#include "modplatform/flame/FlameAPI.h"
+#include "modplatform/modrinth/ModrinthAPI.h"
+#include "tasks/ConcurrentTask.h"
+#include "tasks/SequentialTask.h"
+#include "ui/pages/modplatform/ModModel.h"
+#include "ui/pages/modplatform/flame/FlameResourceModels.h"
+#include "ui/pages/modplatform/modrinth/ModrinthResourceModels.h"
+
+static Version mcVersions(BaseInstance* inst)
+{
+ return static_cast<MinecraftInstance*>(inst)->getPackProfile()->getComponent("net.minecraft")->getVersion();
+}
+
+static ResourceAPI::ModLoaderTypes mcLoaders(BaseInstance* inst)
+{
+ return static_cast<MinecraftInstance*>(inst)->getPackProfile()->getModLoaders().value();
+}
+
+GetModDependenciesTask::GetModDependenciesTask(QObject* parent,
+ BaseInstance* instance,
+ ModFolderModel* folder,
+ QList<std::shared_ptr<PackDependency>> selected)
+ : SequentialTask(parent, "Get dependencies")
+ , m_selected(selected)
+ , m_flame_provider{ ModPlatform::ResourceProvider::FLAME, std::make_shared<ResourceDownload::FlameModModel>(*instance),
+ std::make_shared<FlameAPI>() }
+ , m_modrinth_provider{ ModPlatform::ResourceProvider::MODRINTH, std::make_shared<ResourceDownload::ModrinthModModel>(*instance),
+ std::make_shared<ModrinthAPI>() }
+ , m_version(mcVersions(instance))
+ , m_loaderType(mcLoaders(instance))
+{
+ for (auto mod : folder->allMods())
+ if (auto meta = mod->metadata(); meta)
+ m_mods.append(meta);
+ prepare();
+};
+
+void GetModDependenciesTask::prepare()
+{
+ for (auto sel : m_selected) {
+ for (auto dep : getDependenciesForVersion(sel->version, sel->pack->provider)) {
+ addTask(prepareDependencyTask(dep, sel->pack->provider, 20));
+ }
+ }
+}
+
+QList<ModPlatform::Dependency> GetModDependenciesTask::getDependenciesForVersion(const ModPlatform::IndexedVersion& version,
+ const ModPlatform::ResourceProvider providerName)
+{
+ auto c_dependencies = QList<ModPlatform::Dependency>();
+ for (auto ver_dep : version.dependencies) {
+ if (ver_dep.type == ModPlatform::DependencyType::REQUIRED) {
+ if (auto dep = std::find_if(c_dependencies.begin(), c_dependencies.end(),
+ [&ver_dep](const ModPlatform::Dependency& i) { return i.addonId == ver_dep.addonId; });
+ dep == c_dependencies.end()) { // check the current dependency list
+ if (auto dep = std::find_if(m_selected.begin(), m_selected.end(),
+ [&ver_dep, providerName](std::shared_ptr<PackDependency> i) {
+ return i->pack->addonId == ver_dep.addonId && i->pack->provider == providerName;
+ });
+ dep == m_selected.end()) { // check the selected versions
+ if (auto dep = std::find_if(m_mods.begin(), m_mods.end(),
+ [&ver_dep, providerName](std::shared_ptr<Metadata::ModStruct> i) {
+ return i->project_id == ver_dep.addonId && i->provider == providerName;
+ });
+ dep == m_mods.end()) { // check the existing mods
+ if (auto dep = std::find_if(m_pack_dependencies.begin(), m_pack_dependencies.end(),
+ [&ver_dep, providerName](std::shared_ptr<PackDependency> i) {
+ return i->pack->addonId == ver_dep.addonId && i->pack->provider == providerName;
+ });
+ dep == m_pack_dependencies.end()) { // check loaded dependencies
+ c_dependencies.append(ver_dep);
+ }
+ }
+ }
+ }
+ }
+ }
+ return c_dependencies;
+};
+
+Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Dependency& dep,
+ const ModPlatform::ResourceProvider providerName,
+ int level)
+{
+ auto pDep = std::make_shared<PackDependency>();
+ pDep->dependency = dep;
+ pDep->pack = std::make_shared<ModPlatform::IndexedPack>();
+ pDep->pack->addonId = dep.addonId;
+ pDep->pack->provider = providerName;
+ m_pack_dependencies.append(pDep);
+ auto provider = providerName == m_flame_provider.name ? m_flame_provider : m_modrinth_provider;
+
+ auto tasks = makeShared<SequentialTask>(this, QString("DependencyInfo: %1").arg(dep.addonId.toString()));
+
+ auto responseInfo = new QByteArray();
+ auto info = provider.api->getProject(dep.addonId.toString(), responseInfo);
+ QObject::connect(info.get(), &NetJob::succeeded, [responseInfo, provider, pDep] {
+ QJsonParseError parse_error{};
+ QJsonDocument doc = QJsonDocument::fromJson(*responseInfo, &parse_error);
+ if (parse_error.error != QJsonParseError::NoError) {
+ qWarning() << "Error while parsing JSON response for mod info at " << parse_error.offset
+ << " reason: " << parse_error.errorString();
+ qWarning() << *responseInfo;
+ return;
+ }
+ try {
+ auto obj = provider.name == ModPlatform::ResourceProvider::FLAME ? Json::requireObject(Json::requireObject(doc), "data")
+ : Json::requireObject(doc);
+ provider.mod->loadIndexedPack(*pDep->pack, obj);
+ } catch (const JSONValidationError& e) {
+ qDebug() << doc;
+ qWarning() << "Error while reading mod info: " << e.cause();
+ }
+ });
+ tasks->addTask(info);
+
+ ResourceAPI::DependencySearchArgs args = { dep, m_version, m_loaderType };
+ ResourceAPI::DependencySearchCallbacks callbacks;
+
+ callbacks.on_succeed = [dep, provider, pDep, level, this](auto& doc, auto& pack) {
+ try {
+ QJsonArray arr;
+ if (dep.version.length() != 0 && doc.isObject()) {
+ arr.append(doc.object());
+ } else {
+ arr = doc.isObject() ? Json::ensureArray(doc.object(), "data") : doc.array();
+ }
+ pDep->version = provider.mod->loadDependencyVersions(dep, arr);
+ if (!pDep->version.addonId.isValid()) {
+ qWarning() << "Error while reading mod version empty ";
+ qDebug() << doc;
+ return;
+ }
+ pDep->version.is_currently_selected = true;
+ pDep->pack->versions = { pDep->version };
+ pDep->pack->versionsLoaded = true;
+
+ } catch (const JSONValidationError& e) {
+ qDebug() << doc;
+ qWarning() << "Error while reading mod version: " << e.cause();
+ return;
+ }
+ if (level == 0) {
+ qWarning() << "Dependency cycle exeeded";
+ return;
+ }
+ for (auto dep : getDependenciesForVersion(pDep->version, provider.name)) {
+ addTask(prepareDependencyTask(dep, provider.name, level - 1));
+ }
+ };
+
+ auto version = provider.api->getDependencyVersion(std::move(args), std::move(callbacks));
+ tasks->addTask(version);
+ return tasks;
+};
diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h
new file mode 100644
index 00000000..3824e781
--- /dev/null
+++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h
@@ -0,0 +1,81 @@
+// 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 <QDir>
+#include <QEventLoop>
+#include <QList>
+#include <QVariant>
+#include <functional>
+#include <memory>
+
+#include "minecraft/mod/MetadataHandler.h"
+#include "minecraft/mod/ModFolderModel.h"
+#include "modplatform/ModIndex.h"
+#include "modplatform/ResourceAPI.h"
+#include "tasks/SequentialTask.h"
+#include "tasks/Task.h"
+#include "ui/pages/modplatform/ModModel.h"
+
+class GetModDependenciesTask : public SequentialTask {
+ Q_OBJECT
+ public:
+ using Ptr = shared_qobject_ptr<GetModDependenciesTask>;
+
+ struct PackDependency {
+ ModPlatform::Dependency dependency;
+ ModPlatform::IndexedPack::Ptr pack;
+ ModPlatform::IndexedVersion version;
+ PackDependency(){};
+ PackDependency(const ModPlatform::IndexedPack::Ptr p, const ModPlatform::IndexedVersion& v)
+ {
+ pack = p;
+ version = v;
+ }
+ };
+
+ struct Provider {
+ ModPlatform::ResourceProvider name;
+ std::shared_ptr<ResourceDownload::ModModel> mod;
+ std::shared_ptr<ResourceAPI> api;
+ };
+
+ explicit GetModDependenciesTask(QObject* parent,
+ BaseInstance* instance,
+ ModFolderModel* folder,
+ QList<std::shared_ptr<PackDependency>> selected);
+
+ auto getDependecies() const -> QList<std::shared_ptr<PackDependency>> { return m_pack_dependencies; }
+
+ protected slots:
+ Task::Ptr prepareDependencyTask(const ModPlatform::Dependency&, const ModPlatform::ResourceProvider, int);
+ QList<ModPlatform::Dependency> getDependenciesForVersion(const ModPlatform::IndexedVersion&,
+ const ModPlatform::ResourceProvider providerName);
+ void prepare();
+
+ private:
+ QList<std::shared_ptr<PackDependency>> m_pack_dependencies;
+ QList<std::shared_ptr<Metadata::ModStruct>> m_mods;
+ QList<std::shared_ptr<PackDependency>> m_selected;
+ Provider m_flame_provider;
+ Provider m_modrinth_provider;
+
+ Version m_version;
+ ResourceAPI::ModLoaderTypes m_loaderType;
+};
diff --git a/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp b/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp
index cc4e252c..4352fad9 100644
--- a/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp
+++ b/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp
@@ -1,25 +1,24 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
-* PolyMC - Minecraft Launcher
-* Copyright (c) 2022 flowln <flowlnlnln@gmail.com>
-* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
-*
-* 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) 2022 Sefa Eyeoglu <contact@scrumplex.net>
+ *
+ * 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 "LocalModUpdateTask.h"
-#include "Application.h"
#include "FileSystem.h"
#include "minecraft/mod/MetadataHandler.h"
diff --git a/launcher/modplatform/ModIndex.h b/launcher/modplatform/ModIndex.h
index 82da2ab2..64b44055 100644
--- a/launcher/modplatform/ModIndex.h
+++ b/launcher/modplatform/ModIndex.h
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
- * PolyMC - Minecraft Launcher
+ * 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
@@ -33,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 };
+
class ProviderCapabilities {
public:
auto name(ResourceProvider) -> const char*;
@@ -52,6 +55,12 @@ struct DonationData {
QString url;
};
+struct Dependency {
+ QVariant addonId;
+ DependencyType type;
+ QString version;
+};
+
struct IndexedVersion {
QVariant addonId;
QVariant fileId;
@@ -66,6 +75,7 @@ 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;
diff --git a/launcher/modplatform/ResourceAPI.h b/launcher/modplatform/ResourceAPI.h
index 34f33779..c23444b3 100644
--- a/launcher/modplatform/ResourceAPI.h
+++ b/launcher/modplatform/ResourceAPI.h
@@ -111,6 +111,24 @@ class ResourceAPI {
std::function<void(QJsonDocument&, ModPlatform::IndexedPack)> on_succeed;
};
+ struct DependencySearchArgs {
+ ModPlatform::Dependency dependency;
+ Version mcVersion;
+ ModLoaderTypes loader;
+
+ DependencySearchArgs(DependencySearchArgs const&) = default;
+ void operator=(DependencySearchArgs other)
+ {
+ dependency = other.dependency;
+ mcVersion = other.mcVersion;
+ loader = other.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;
@@ -143,6 +161,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/flame/FlameAPI.h b/launcher/modplatform/flame/FlameAPI.h
index 5811d717..4ffc36d2 100644
--- a/launcher/modplatform/flame/FlameAPI.h
+++ b/launcher/modplatform/flame/FlameAPI.h
@@ -41,14 +41,15 @@ class FlameAPI : public NetworkResourceAPI {
return 4;
// TODO: remove this once Quilt drops official Fabric support
if (loaders & Quilt) // NOTE: Most if not all Fabric mods should work *currently*
- return 4; // Quilt would probably be 5
+ return 4; // Quilt would probably be 5
return 0;
}
private:
[[nodiscard]] std::optional<QString> getSearchURL(SearchArgs const& args) const override
{
- auto gameVersionStr = args.versions.has_value() ? QString("gameVersion=%1").arg(args.versions.value().front().toString()) : QString();
+ auto gameVersionStr =
+ args.versions.has_value() ? QString("gameVersion=%1").arg(args.versions.value().front().toString()) : QString();
QStringList get_arguments;
get_arguments.append(QString("classId=%1").arg(getClassId(args.type)));
@@ -73,7 +74,7 @@ class FlameAPI : public NetworkResourceAPI {
[[nodiscard]] std::optional<QString> getVersionsURL(VersionSearchArgs const& args) const override
{
- QString url{QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&").arg(args.pack.addonId.toString())};
+ QString url{ QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&").arg(args.pack.addonId.toString()) };
QStringList get_parameters;
if (args.mcVersions.has_value())
@@ -83,4 +84,12 @@ class FlameAPI : public NetworkResourceAPI {
return url + get_parameters.join('&');
};
+
+ [[nodiscard]] std::optional<QString> getDependencyURL(DependencySearchArgs const& args) const override
+ {
+ return QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&gameVersion=%2&modLoaderType=%3")
+ .arg(args.dependency.addonId.toString())
+ .arg(args.mcVersion.toString())
+ .arg(getMappedModLoader(args.loader));
+ };
};
diff --git a/launcher/modplatform/flame/FlameModIndex.cpp b/launcher/modplatform/flame/FlameModIndex.cpp
index 7498e830..120bfc91 100644
--- a/launcher/modplatform/flame/FlameModIndex.cpp
+++ b/launcher/modplatform/flame/FlameModIndex.cpp
@@ -39,15 +39,15 @@ void FlameMod::loadURLs(ModPlatform::IndexedPack& pack, QJsonObject& obj)
auto links_obj = Json::ensureObject(obj, "links");
pack.extraData.issuesUrl = Json::ensureString(links_obj, "issuesUrl");
- if(pack.extraData.issuesUrl.endsWith('/'))
+ if (pack.extraData.issuesUrl.endsWith('/'))
pack.extraData.issuesUrl.chop(1);
pack.extraData.sourceUrl = Json::ensureString(links_obj, "sourceUrl");
- if(pack.extraData.sourceUrl.endsWith('/'))
+ if (pack.extraData.sourceUrl.endsWith('/'))
pack.extraData.sourceUrl.chop(1);
pack.extraData.wikiUrl = Json::ensureString(links_obj, "wikiUrl");
- if(pack.extraData.wikiUrl.endsWith('/'))
+ if (pack.extraData.wikiUrl.endsWith('/'))
pack.extraData.wikiUrl.chop(1);
if (!pack.extraData.body.isEmpty())
@@ -56,7 +56,7 @@ void FlameMod::loadURLs(ModPlatform::IndexedPack& pack, QJsonObject& obj)
void FlameMod::loadBody(ModPlatform::IndexedPack& pack, QJsonObject& obj)
{
- pack.extraData.body = api.getModDescription(pack.addonId.toInt());
+ pack.extraData.body = api.getModDescription(pack.addonId.toInt());
if (!pack.extraData.issuesUrl.isEmpty() || !pack.extraData.sourceUrl.isEmpty() || !pack.extraData.wikiUrl.isEmpty())
pack.extraDataLoaded = true;
@@ -64,12 +64,12 @@ void FlameMod::loadBody(ModPlatform::IndexedPack& pack, QJsonObject& obj)
static QString enumToString(int hash_algorithm)
{
- switch(hash_algorithm){
- default:
- case 1:
- return "sha1";
- case 2:
- return "md5";
+ switch (hash_algorithm) {
+ default:
+ case 1:
+ return "sha1";
+ case 2:
+ return "md5";
}
}
@@ -84,12 +84,12 @@ void FlameMod::loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
for (auto versionIter : arr) {
auto obj = versionIter.toObject();
-
+
auto file = loadIndexedPackVersion(obj);
- if(!file.addonId.isValid())
+ if (!file.addonId.isValid())
file.addonId = pack.addonId;
- if(file.fileId.isValid()) // Heuristic to check if the returned value is valid
+ if (file.fileId.isValid()) // Heuristic to check if the returned value is valid
unsortedVersions.append(file);
}
@@ -136,8 +136,58 @@ auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool load_changelog) ->
}
}
- if(load_changelog)
+ auto dependencies = Json::ensureArray(obj, "dependencies");
+ for (auto d : dependencies) {
+ auto dep = Json::ensureObject(d);
+ ModPlatform::Dependency dependency;
+ dependency.addonId = Json::requireInteger(dep, "modId");
+ switch (Json::requireInteger(dep, "relationType")) {
+ case 1: // EmbeddedLibrary
+ dependency.type = ModPlatform::DependencyType::EMBEDDED;
+ break;
+ case 2: // OptionalDependency
+ dependency.type = ModPlatform::DependencyType::OPTIONAL;
+ break;
+ case 3: // RequiredDependency
+ dependency.type = ModPlatform::DependencyType::REQUIRED;
+ break;
+ case 4: // Tool
+ dependency.type = ModPlatform::DependencyType::TOOL;
+ break;
+ case 5: // Incompatible
+ dependency.type = ModPlatform::DependencyType::INCOMPATIBLE;
+ break;
+ case 6: // Include
+ dependency.type = ModPlatform::DependencyType::INCLUDE;
+ break;
+ }
+ file.dependencies.append(dependency);
+ }
+
+ if (load_changelog)
file.changelog = api.getModFileChangelog(file.addonId.toInt(), file.fileId.toInt());
return file;
}
+
+ModPlatform::IndexedVersion FlameMod::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr)
+{
+ QVector<ModPlatform::IndexedVersion> unsortedVersions;
+ for (auto versionIter : arr) {
+ auto obj = versionIter.toObject();
+
+ auto file = loadIndexedPackVersion(obj);
+ if (!file.addonId.isValid())
+ file.addonId = m.addonId;
+
+ if (file.fileId.isValid()) // Heuristic to check if the returned value is valid
+ unsortedVersions.append(file);
+ }
+
+ auto orderSortPredicate = [](const ModPlatform::IndexedVersion& a, const ModPlatform::IndexedVersion& b) -> bool {
+ // dates are in RFC 3339 format
+ return a.date > b.date;
+ };
+ std::sort(unsortedVersions.begin(), unsortedVersions.end(), orderSortPredicate);
+ return unsortedVersions.front();
+};
diff --git a/launcher/modplatform/flame/FlameModIndex.h b/launcher/modplatform/flame/FlameModIndex.h
index 33c4a529..aa0d6f81 100644
--- a/launcher/modplatform/flame/FlameModIndex.h
+++ b/launcher/modplatform/flame/FlameModIndex.h
@@ -6,8 +6,8 @@
#include "modplatform/ModIndex.h"
-#include "BaseInstance.h"
#include <QNetworkAccessManager>
+#include "BaseInstance.h"
namespace FlameMod {
@@ -19,5 +19,5 @@ void loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
const shared_qobject_ptr<QNetworkAccessManager>& network,
const BaseInstance* inst);
auto loadIndexedPackVersion(QJsonObject& obj, bool load_changelog = false) -> ModPlatform::IndexedVersion;
-
-} // namespace FlameMod
+auto loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion;
+} // namespace FlameMod \ No newline at end of file
diff --git a/launcher/modplatform/flame/FlamePackIndex.h b/launcher/modplatform/flame/FlamePackIndex.h
index 1ca0fc0e..b089b722 100644
--- a/launcher/modplatform/flame/FlamePackIndex.h
+++ b/launcher/modplatform/flame/FlamePackIndex.h
@@ -4,6 +4,7 @@
#include <QMetaType>
#include <QString>
#include <QVector>
+#include "modplatform/ModIndex.h"
namespace Flame {
@@ -27,8 +28,7 @@ struct ModpackExtra {
QString sourceUrl;
};
-struct IndexedPack
-{
+struct IndexedPack {
int addonId;
QString name;
QString description;
@@ -43,9 +43,9 @@ struct IndexedPack
ModpackExtra extra;
};
-void loadIndexedPack(IndexedPack & m, QJsonObject & obj);
+void loadIndexedPack(IndexedPack& m, QJsonObject& obj);
void loadIndexedInfo(IndexedPack&, QJsonObject&);
-void loadIndexedPackVersions(IndexedPack & m, QJsonArray & arr);
-}
+void loadIndexedPackVersions(IndexedPack& m, QJsonArray& arr);
+} // namespace Flame
Q_DECLARE_METATYPE(Flame::IndexedPack)
diff --git a/launcher/modplatform/helpers/NetworkResourceAPI.cpp b/launcher/modplatform/helpers/NetworkResourceAPI.cpp
index a3c592fd..eab55cfd 100644
--- a/launcher/modplatform/helpers/NetworkResourceAPI.cpp
+++ b/launcher/modplatform/helpers/NetworkResourceAPI.cpp
@@ -24,7 +24,7 @@ Task::Ptr NetworkResourceAPI::searchProjects(SearchArgs&& args, SearchCallbacks&
netJob->addNetAction(Net::Download::makeByteArray(QUrl(search_url), response));
- QObject::connect(netJob.get(), &NetJob::succeeded, [this, response, callbacks]{
+ QObject::connect(netJob.get(), &NetJob::succeeded, [this, response, callbacks] {
QJsonParseError parse_error{};
QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
if (parse_error.error != QJsonParseError::NoError) {
@@ -40,20 +40,15 @@ Task::Ptr NetworkResourceAPI::searchProjects(SearchArgs&& args, SearchCallbacks&
callbacks.on_succeed(doc);
});
- QObject::connect(netJob.get(), &NetJob::failed, [&netJob, callbacks](QString reason){
+ QObject::connect(netJob.get(), &NetJob::failed, [&netJob, callbacks](QString reason) {
int network_error_code = -1;
if (auto* failed_action = netJob->getFailedActions().at(0); failed_action && failed_action->m_reply)
network_error_code = failed_action->m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
- callbacks.on_fail(reason, network_error_code);
- });
- QObject::connect(netJob.get(), &NetJob::aborted, [callbacks]{
- callbacks.on_abort();
- });
- QObject::connect(netJob.get(), &NetJob::finished, [response] {
- delete response;
+ callbacks.on_fail(reason, network_error_code);
});
-
+ QObject::connect(netJob.get(), &NetJob::aborted, [callbacks] { callbacks.on_abort(); });
+ QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; });
return netJob;
}
@@ -105,9 +100,7 @@ Task::Ptr NetworkResourceAPI::getProjectVersions(VersionSearchArgs&& args, Versi
callbacks.on_su