aboutsummaryrefslogtreecommitdiff
path: root/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp')
-rw-r--r--launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp132
1 files changed, 132 insertions, 0 deletions
diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp
new file mode 100644
index 00000000..7f184765
--- /dev/null
+++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp
@@ -0,0 +1,132 @@
+// 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/>.
+ */
+
+#include "GetModDependenciesTask.h"
+
+#include <QDebug>
+#include "QObjectPtr.h"
+#include "minecraft/mod/MetadataHandler.h"
+#include "minecraft/mod/tasks/LocalModGetAllTask.h"
+#include "modplatform/ModIndex.h"
+#include "tasks/ConcurrentTask.h"
+#include "tasks/SequentialTask.h"
+
+GetModDependenciesTask::GetModDependenciesTask(QDir index_dir, QList<ModPlatform::IndexedVersion> selected, NewDependecyVersionAPITask api)
+ : m_selected(selected), m_getDependenciesVersionAPI(api)
+{
+ m_getAllMods = makeShared<LocalModGetAllTask>(index_dir);
+ m_getNetworkDep = makeShared<SequentialTask>(this, "GetDepInfo");
+ connect(m_getNetworkDep.get(), &Task::finished, &loop, &QEventLoop::quit);
+ QObject::connect(m_getAllMods.get(), &LocalModGetAllTask::getAllMods, [this](QList<Metadata::ModStruct> mods) {
+ m_mods = mods;
+ prepareDependecies();
+ });
+}
+
+void GetModDependenciesTask::executeTask()
+{
+ setStatus(tr("Geting all mods"));
+ m_getAllMods->start();
+ loop.exec();
+ emitSucceeded();
+}
+
+auto GetModDependenciesTask::abort() -> bool
+{
+ emitAborted();
+ return true;
+}
+
+void GetModDependenciesTask::prepareDependecies()
+{
+ auto c_dependencies = getDependenciesForVersions(m_selected);
+ if (c_dependencies.length() == 0) {
+ m_getNetworkDep->start();
+ return;
+ }
+ for (auto dep : c_dependencies) {
+ auto task =
+ m_getDependenciesVersionAPI(dep, [this](const ModPlatform::IndexedVersion& new_version) { addDependecies(new_version, 20); });
+ m_getNetworkDep->addTask(task);
+ }
+ m_getNetworkDep->start();
+}
+
+void GetModDependenciesTask::addDependecies(const ModPlatform::IndexedVersion& new_version, int level)
+{
+ // some mutex?
+ m_dependencies.append(new_version);
+ auto c_dependencies = getDependenciesForVersion(new_version);
+ if (c_dependencies.length() == 0) {
+ return;
+ }
+ if (level == 0) {
+ qWarning() << "Dependency cycle exeeded";
+ return;
+ }
+ for (auto dep : c_dependencies) {
+ auto task = m_getDependenciesVersionAPI(
+ dep, [this, level](const ModPlatform::IndexedVersion& new_versions) { addDependecies(new_versions, level - 1); });
+ m_getNetworkDep->addTask(task);
+ }
+};
+
+QList<ModPlatform::Dependency> GetModDependenciesTask::getDependenciesForVersions(const QList<ModPlatform::IndexedVersion>& selected)
+{
+ auto c_dependencies = QList<ModPlatform::Dependency>();
+ for (auto version : selected) {
+ 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 auto& i) { return i.addonId == ver_dep.addonId; });
+ dep == c_dependencies.end()) { // check the current dependency list
+ if (auto dep = std::find_if(selected.begin(), selected.end(),
+ [&ver_dep](const auto& i) { return i.addonId == ver_dep.addonId; });
+ dep == selected.end()) { // check the selected versions
+ if (auto dep = std::find_if(m_mods.begin(), m_mods.end(),
+ [&ver_dep](const auto& i) { return i.project_id == ver_dep.addonId; });
+ dep == m_mods.end()) { // check the existing mods
+ c_dependencies.append(ver_dep);
+ }
+ }
+ }
+ }
+ }
+ }
+ return c_dependencies;
+};
+
+QList<ModPlatform::Dependency> GetModDependenciesTask::getDependenciesForVersion(const ModPlatform::IndexedVersion& version)
+{
+ 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 auto& i) { return i.addonId == ver_dep.addonId; });
+ dep == c_dependencies.end()) { // check the current dependency list
+ if (auto dep =
+ std::find_if(m_mods.begin(), m_mods.end(), [&ver_dep](const auto& i) { return i.project_id == ver_dep.addonId; });
+ dep == m_mods.end()) { // check the existing mods
+ c_dependencies.append(ver_dep);
+ }
+ }
+ }
+ }
+ return c_dependencies;
+}; \ No newline at end of file