diff options
Diffstat (limited to 'launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp')
-rw-r--r-- | launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp | 132 |
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 |