diff options
author | Trial97 <alexandru.tripon97@gmail.com> | 2023-04-12 00:45:44 +0300 |
---|---|---|
committer | Trial97 <alexandru.tripon97@gmail.com> | 2023-04-12 00:45:44 +0300 |
commit | 4fbd5abe41ac10ecd28974ff857e9bce35c7d264 (patch) | |
tree | 38be9f3454f31e6515d075573e23c061e5fb2946 | |
parent | d524935b6726c1a8d589d01abad4d262a55af149 (diff) | |
download | PrismLauncher-4fbd5abe41ac10ecd28974ff857e9bce35c7d264.tar.gz PrismLauncher-4fbd5abe41ac10ecd28974ff857e9bce35c7d264.tar.bz2 PrismLauncher-4fbd5abe41ac10ecd28974ff857e9bce35c7d264.zip |
Added task to load dependencies
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
-rw-r--r-- | launcher/minecraft/mod/MetadataHandler.h | 57 | ||||
-rw-r--r-- | launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp | 116 | ||||
-rw-r--r-- | launcher/minecraft/mod/tasks/GetModDependenciesTask.h | 63 | ||||
-rw-r--r-- | launcher/minecraft/mod/tasks/LocalModGetAllTask.cpp (renamed from launcher/minecraft/mod/tasks/LocalModGetTask.cpp) | 15 | ||||
-rw-r--r-- | launcher/minecraft/mod/tasks/LocalModGetAllTask.h (renamed from launcher/minecraft/mod/tasks/LocalModGetTask.h) | 9 | ||||
-rw-r--r-- | launcher/modplatform/packwiz/Packwiz.cpp | 11 | ||||
-rw-r--r-- | launcher/modplatform/packwiz/Packwiz.h | 57 |
7 files changed, 254 insertions, 74 deletions
diff --git a/launcher/minecraft/mod/MetadataHandler.h b/launcher/minecraft/mod/MetadataHandler.h index 39723b49..f7f08a79 100644 --- a/launcher/minecraft/mod/MetadataHandler.h +++ b/launcher/minecraft/mod/MetadataHandler.h @@ -1,20 +1,20 @@ // 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/>. -*/ + * 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/>. + */ #pragma once @@ -42,28 +42,15 @@ class Metadata { return Packwiz::V1::createModFormat(index_dir, internal_mod, mod_slug); } - static void update(QDir& index_dir, ModStruct& mod) - { - Packwiz::V1::updateModIndex(index_dir, mod); - } + static void update(QDir& index_dir, ModStruct& mod) { Packwiz::V1::updateModIndex(index_dir, mod); } - static void remove(QDir& index_dir, QString mod_slug) - { - Packwiz::V1::deleteModIndex(index_dir, mod_slug); - } + static void remove(QDir& index_dir, QString mod_slug) { Packwiz::V1::deleteModIndex(index_dir, mod_slug); } - static void remove(QDir& index_dir, QVariant& mod_id) - { - Packwiz::V1::deleteModIndex(index_dir, mod_id); - } + static void remove(QDir& index_dir, QVariant& mod_id) { Packwiz::V1::deleteModIndex(index_dir, mod_id); } - static auto get(QDir& index_dir, QString mod_slug) -> ModStruct - { - return Packwiz::V1::getIndexForMod(index_dir, mod_slug); - } + static auto get(QDir& index_dir, QString mod_slug) -> ModStruct { return Packwiz::V1::getIndexForMod(index_dir, mod_slug); } - static auto get(QDir& index_dir, QVariant& mod_id) -> ModStruct - { - return Packwiz::V1::getIndexForMod(index_dir, mod_id); - } + static auto get(QDir& index_dir, QVariant& mod_id) -> ModStruct { return Packwiz::V1::getIndexForMod(index_dir, mod_id); } + + static auto getAll(QDir& index_dir) -> QList<ModStruct> { return Packwiz::V1::getAllMods(index_dir); } }; diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp new file mode 100644 index 00000000..dcff1028 --- /dev/null +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -0,0 +1,116 @@ +// 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 "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" + +#ifdef Q_OS_WIN32 +#include <windows.h> +#endif + +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"); + QObject::connect(m_getAllMods.get(), &LocalModGetAllTask::getAllMod, [this](QList<Metadata::ModStruct> mods) { + m_mods = mods; + prepareDependecies(); + }); + +#ifdef Q_OS_WIN32 + SetFileAttributesW(index_dir.path().toStdWString().c_str(), FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED); +#endif +} + +void GetModDependenciesTask::executeTask() +{ + setStatus(tr("Geting all mods")); + m_getAllMods->start(); +} + +auto GetModDependenciesTask::abort() -> bool +{ + emitAborted(); + return true; +} + +void GetModDependenciesTask::prepareDependecies() +{ + auto c_dependencies = getDependenciesForVersions(m_selected); + if (c_dependencies.length() == 0) { + emitSucceeded(); + return; + } + for (auto dep : c_dependencies) { + auto task = m_getDependenciesVersionAPI( + dep, 20, [this](QList<ModPlatform::IndexedVersion> new_versions, int level) { addDependecies(new_versions, level - 1); }); + m_getNetworkDep->addTask(task); + } + m_getNetworkDep->start(); +} + +void GetModDependenciesTask::addDependecies(QList<ModPlatform::IndexedVersion> new_versions, int level) +{ + // some mutex? + m_dependencies.append(new_versions); + auto c_dependencies = getDependenciesForVersions(m_selected); + if (c_dependencies.length() == 0) { + return; + } + if (level == 0) { + qWarning() << "Dependency cycle exeeded"; + } + for (auto dep : c_dependencies) { + auto task = m_getDependenciesVersionAPI( + dep, 20, [this](QList<ModPlatform::IndexedVersion> new_versions, int level) { addDependecies(new_versions, level - 1); }); + m_getNetworkDep->addTask(task); + } +}; + +QList<ModPlatform::Dependency> GetModDependenciesTask::getDependenciesForVersions(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](auto i) { return i.addonId == ver_dep.addonId; }); + dep == c_dependencies.end()) { // check the current dependency list + c_dependencies.append(ver_dep); + } else if (auto dep = + std::find_if(selected.begin(), selected.end(), [ver_dep](auto i) { return i.addonId == ver_dep.addonId; }); + dep == selected.end()) { // check the selected versions + c_dependencies.append(ver_dep); + } else if (auto dep = + std::find_if(m_mods.begin(), m_mods.end(), [ver_dep](auto i) { return i.mod_id() == ver_dep.addonId; }); + dep == m_mods.end()) { // check the existing mods + c_dependencies.append(ver_dep); + } + } + } + } + return c_dependencies; +}; diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h new file mode 100644 index 00000000..28112bba --- /dev/null +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h @@ -0,0 +1,63 @@ +// 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/>. + */ + +#pragma once + +#include <QDir> +#include <functional> + +#include "minecraft/mod/MetadataHandler.h" +#include "minecraft/mod/tasks/LocalModGetAllTask.h" +#include "modplatform/ModIndex.h" +#include "tasks/SequentialTask.h" +#include "tasks/Task.h" + +class GetModDependenciesTask : public Task { + Q_OBJECT + public: + using Ptr = shared_qobject_ptr<GetModDependenciesTask>; + using LocalModGetAllTaskPtr = shared_qobject_ptr<LocalModGetAllTask>; + + using NewDependecyVersionAPITask = + std::function<Task::Ptr(ModPlatform::Dependency, int, std::function<void(QList<ModPlatform::IndexedVersion>, int)>)>; + + explicit GetModDependenciesTask(QDir index_dir, QList<ModPlatform::IndexedVersion> selected, NewDependecyVersionAPITask& api); + + auto canAbort() const -> bool override { return true; } + auto abort() -> bool override; + + protected slots: + //! Entry point for tasks. + void executeTask() override; + + void prepareDependecies(); + void addDependecies(QList<ModPlatform::IndexedVersion>, int); + QList<ModPlatform::Dependency> getDependenciesForVersions(QList<ModPlatform::IndexedVersion>); + + signals: + void getAllMod(QList<Metadata::ModStruct>); + + private: + QList<ModPlatform::IndexedVersion> m_selected; + QList<ModPlatform::IndexedVersion> m_dependencies; + QList<Metadata::ModStruct> m_mods; + + LocalModGetAllTaskPtr m_getAllMods = nullptr; + NewDependecyVersionAPITask m_getDependenciesVersionAPI; + SequentialTask::Ptr m_getNetworkDep; +}; diff --git a/launcher/minecraft/mod/tasks/LocalModGetTask.cpp b/launcher/minecraft/mod/tasks/LocalModGetAllTask.cpp index 9c056d02..9e4293ff 100644 --- a/launcher/minecraft/mod/tasks/LocalModGetTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalModGetAllTask.cpp @@ -17,7 +17,7 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include "LocalModGetTask.h" +#include "LocalModGetAllTask.h" #include "FileSystem.h" #include "minecraft/mod/MetadataHandler.h" @@ -26,11 +26,11 @@ #include <windows.h> #endif -LocalModGetTask::LocalModGetTask(QDir index_dir, QVariant addonId) : m_index_dir(index_dir), m_addonId(addonId) +LocalModGetAllTask::LocalModGetAllTask(QDir index_dir) : m_index_dir(index_dir) { // Ensure a '.index' folder exists in the mods folder, and create it if it does not if (!FS::ensureFolderPathExists(index_dir.path())) { - emitFailed(QString("Unable to create index for modId %1!").arg(m_addonId.toString())); + emitFailed(QString("Unable to create index for all mods!")); } #ifdef Q_OS_WIN32 @@ -38,13 +38,14 @@ LocalModGetTask::LocalModGetTask(QDir index_dir, QVariant addonId) : m_index_dir #endif } -void LocalModGetTask::executeTask() +void LocalModGetAllTask::executeTask() { - setStatus(tr("Updating index for modId:\n%1").arg(m_addonId.toString())); - emit getMod(Metadata::get(m_index_dir, m_addonId)); + setStatus(tr("Geting all mods")); + emit getAllMod(Metadata::getAll(m_index_dir)); + emitSucceeded(); } -auto LocalModGetTask::abort() -> bool +auto LocalModGetAllTask::abort() -> bool { emitAborted(); return true; diff --git a/launcher/minecraft/mod/tasks/LocalModGetTask.h b/launcher/minecraft/mod/tasks/LocalModGetAllTask.h index 5b741122..09e453e4 100644 --- a/launcher/minecraft/mod/tasks/LocalModGetTask.h +++ b/launcher/minecraft/mod/tasks/LocalModGetAllTask.h @@ -23,12 +23,12 @@ #include "minecraft/mod/MetadataHandler.h" #include "tasks/Task.h" -class LocalModGetTask : public Task { +class LocalModGetAllTask : public Task { Q_OBJECT public: - using Ptr = shared_qobject_ptr<LocalModGetTask>; + using Ptr = shared_qobject_ptr<LocalModGetAllTask>; - explicit LocalModGetTask(QDir index_dir, QVariant addonId); + explicit LocalModGetAllTask(QDir index_dir); auto canAbort() const -> bool override { return true; } auto abort() -> bool override; @@ -38,9 +38,8 @@ class LocalModGetTask : public Task { void executeTask() override; signals: - void getMod(Metadata::ModStruct); + void getAllMod(QList<Metadata::ModStruct>); private: QDir m_index_dir; - QVariant m_addonId; }; diff --git a/launcher/modplatform/packwiz/Packwiz.cpp b/launcher/modplatform/packwiz/Packwiz.cpp index 510c7309..a2598b97 100644 --- a/launcher/modplatform/packwiz/Packwiz.cpp +++ b/launcher/modplatform/packwiz/Packwiz.cpp @@ -21,6 +21,8 @@ #include <QDebug> #include <QDir> #include <QObject> +#include <algorithm> +#include <iterator> #include "FileSystem.h" #include "StringUtils.h" @@ -311,4 +313,13 @@ auto V1::getIndexForMod(QDir& index_dir, QVariant& mod_id) -> Mod return {}; } +auto V1::getAllMods(QDir& index_dir) -> QList<Mod> +{ + auto files = index_dir.entryList(QDir::Filter::Files); + auto mods = QList<Mod>(); + std::transform(files.begin(), files.end(), std::back_inserter(mods), + [index_dir](auto file_name) { return getIndexForMod(index_dir, file_name); }); + return mods; +} + } // namespace Packwiz diff --git a/launcher/modplatform/packwiz/Packwiz.h b/launcher/modplatform/packwiz/Packwiz.h index 4b096eec..2801f5d0 100644 --- a/launcher/modplatform/packwiz/Packwiz.h +++ b/launcher/modplatform/packwiz/Packwiz.h @@ -1,20 +1,20 @@ // 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/>. -*/ + * 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/>. + */ #pragma once @@ -36,22 +36,22 @@ auto getRealIndexName(QDir& index_dir, QString normalized_index_name, bool shoul class V1 { public: struct Mod { - QString slug {}; - QString name {}; - QString filename {}; + QString slug{}; + QString name{}; + QString filename{}; // FIXME: make side an enum - QString side {"both"}; + QString side{ "both" }; // [download] - QString mode {}; - QUrl url {}; - QString hash_format {}; - QString hash {}; + QString mode{}; + QUrl url{}; + QString hash_format{}; + QString hash{}; // [update] - ModPlatform::ResourceProvider provider {}; - QVariant file_id {}; - QVariant project_id {}; + ModPlatform::ResourceProvider provider{}; + QVariant file_id{}; + QVariant project_id{}; public: // This is a totally heuristic, but should work for now. @@ -93,6 +93,9 @@ class V1 { * If the mod doesn't have a metadata, it simply returns an empty Mod object. * */ static auto getIndexForMod(QDir& index_dir, QVariant& mod_id) -> Mod; + + /* Gets the metadata for all the mods */ + static auto getAllMods(QDir& index_dir) -> QList<Mod>; }; -} // namespace Packwiz +} // namespace Packwiz |