aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp29
-rw-r--r--launcher/minecraft/mod/tasks/GetModDependenciesTask.h1
-rw-r--r--launcher/modplatform/CheckUpdateTask.h3
-rw-r--r--launcher/modplatform/flame/FlameCheckUpdate.cpp23
-rw-r--r--launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp23
-rw-r--r--launcher/ui/dialogs/ModUpdateDialog.cpp65
-rw-r--r--launcher/ui/dialogs/ModUpdateDialog.h2
-rw-r--r--launcher/ui/dialogs/ResourceDownloadDialog.cpp29
8 files changed, 126 insertions, 49 deletions
diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp
index ee84b1f5..bd1fe940 100644
--- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp
+++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp
@@ -251,3 +251,32 @@ void GetModDependenciesTask::removePack(const QVariant addonId)
++it;
#endif
}
+
+QHash<QString, QStringList> GetModDependenciesTask::getRequiredBy()
+{
+ QHash<QString, QStringList> rby;
+ auto fullList = m_selected + m_pack_dependencies;
+ for (auto& mod : fullList) {
+ auto addonId = mod->pack->addonId;
+ auto provider = mod->pack->provider;
+ auto version = mod->version.fileId;
+ auto req = QStringList();
+ for (auto& smod : fullList) {
+ if (provider != smod->pack->provider)
+ continue;
+ auto deps = smod->version.dependencies;
+ if (auto dep = std::find_if(deps.begin(), deps.end(),
+ [addonId, provider, version](const ModPlatform::Dependency& d) {
+ return d.type == ModPlatform::DependencyType::REQUIRED &&
+ (provider == ModPlatform::ResourceProvider::MODRINTH && d.addonId.toString().isEmpty()
+ ? version == d.version
+ : d.addonId == addonId);
+ });
+ dep != deps.end()) {
+ req.append(smod->pack->name);
+ }
+ }
+ rby[addonId.toString()] = req;
+ }
+ return rby;
+} \ No newline at end of file
diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h
index a8b9953d..2580f807 100644
--- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h
+++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h
@@ -62,6 +62,7 @@ class GetModDependenciesTask : public SequentialTask {
QList<std::shared_ptr<PackDependency>> selected);
auto getDependecies() const -> QList<std::shared_ptr<PackDependency>> { return m_pack_dependencies; }
+ QHash<QString, QStringList> getRequiredBy();
protected slots:
Task::Ptr prepareDependencyTask(const ModPlatform::Dependency&, const ModPlatform::ResourceProvider, int);
diff --git a/launcher/modplatform/CheckUpdateTask.h b/launcher/modplatform/CheckUpdateTask.h
index d125a587..61e6a3a9 100644
--- a/launcher/modplatform/CheckUpdateTask.h
+++ b/launcher/modplatform/CheckUpdateTask.h
@@ -1,6 +1,7 @@
#pragma once
#include "minecraft/mod/Mod.h"
+#include "minecraft/mod/tasks/GetModDependenciesTask.h"
#include "modplatform/ModIndex.h"
#include "modplatform/ResourceAPI.h"
#include "tasks/Task.h"
@@ -40,6 +41,7 @@ class CheckUpdateTask : public Task {
};
auto getUpdatable() -> std::vector<UpdatableMod>&& { return std::move(m_updatable); }
+ auto getDependencies() -> QList<std::shared_ptr<GetModDependenciesTask::PackDependency>>&& { return std::move(m_deps); }
public slots:
bool abort() override = 0;
@@ -57,4 +59,5 @@ class CheckUpdateTask : public Task {
std::shared_ptr<ModFolderModel> m_mods_folder;
std::vector<UpdatableMod> m_updatable;
+ QList<std::shared_ptr<GetModDependenciesTask::PackDependency>> m_deps;
};
diff --git a/launcher/modplatform/flame/FlameCheckUpdate.cpp b/launcher/modplatform/flame/FlameCheckUpdate.cpp
index 476a4667..0501dda6 100644
--- a/launcher/modplatform/flame/FlameCheckUpdate.cpp
+++ b/launcher/modplatform/flame/FlameCheckUpdate.cpp
@@ -10,6 +10,7 @@
#include "ResourceDownloadTask.h"
#include "minecraft/mod/ModFolderModel.h"
+#include "minecraft/mod/tasks/GetModDependenciesTask.h"
#include "net/ApiDownload.h"
@@ -154,18 +155,17 @@ void FlameCheckUpdate::executeTask()
continue;
}
+ // Fake pack with the necessary info to pass to the download task :)
+ auto pack = std::make_shared<ModPlatform::IndexedPack>();
+ pack->name = mod->name();
+ pack->slug = mod->metadata()->slug;
+ pack->addonId = mod->metadata()->project_id;
+ pack->websiteUrl = mod->homeurl();
+ for (auto& author : mod->authors())
+ pack->authors.append({ author });
+ pack->description = mod->description();
+ pack->provider = ModPlatform::ResourceProvider::FLAME;
if (!latest_ver.hash.isEmpty() && (mod->metadata()->hash != latest_ver.hash || mod->status() == ModStatus::NotInstalled)) {
- // Fake pack with the necessary info to pass to the download task :)
- auto pack = std::make_shared<ModPlatform::IndexedPack>();
- pack->name = mod->name();
- pack->slug = mod->metadata()->slug;
- pack->addonId = mod->metadata()->project_id;
- pack->websiteUrl = mod->homeurl();
- for (auto& author : mod->authors())
- pack->authors.append({ author });
- pack->description = mod->description();
- pack->provider = ModPlatform::ResourceProvider::FLAME;
-
auto old_version = mod->version();
if (old_version.isEmpty() && mod->status() != ModStatus::NotInstalled) {
auto current_ver = getFileInfo(latest_ver.addonId.toInt(), mod->metadata()->file_id.toInt());
@@ -177,6 +177,7 @@ void FlameCheckUpdate::executeTask()
api.getModFileChangelog(latest_ver.addonId.toInt(), latest_ver.fileId.toInt()),
ModPlatform::ResourceProvider::FLAME, download_task);
}
+ m_deps.append(std::make_shared<GetModDependenciesTask::PackDependency>(pack, latest_ver));
}
emitSucceeded();
diff --git a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp
index 07c47f14..ab07a363 100644
--- a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp
+++ b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp
@@ -144,26 +144,27 @@ void ModrinthCheckUpdate::executeTask()
auto mod = *mod_iter;
auto key = project_ver.hash;
+
+ // Fake pack with the necessary info to pass to the download task :)
+ auto pack = std::make_shared<ModPlatform::IndexedPack>();
+ pack->name = mod->name();
+ pack->slug = mod->metadata()->slug;
+ pack->addonId = mod->metadata()->project_id;
+ pack->websiteUrl = mod->homeurl();
+ for (auto& author : mod->authors())
+ pack->authors.append({ author });
+ pack->description = mod->description();
+ pack->provider = ModPlatform::ResourceProvider::MODRINTH;
if ((key != hash && project_ver.is_preferred) || (mod->status() == ModStatus::NotInstalled)) {
if (mod->version() == project_ver.version_number)
continue;
- // Fake pack with the necessary info to pass to the download task :)
- auto pack = std::make_shared<ModPlatform::IndexedPack>();
- pack->name = mod->name();
- pack->slug = mod->metadata()->slug;
- pack->addonId = mod->metadata()->project_id;
- pack->websiteUrl = mod->homeurl();
- for (auto& author : mod->authors())
- pack->authors.append({ author });
- pack->description = mod->description();
- pack->provider = ModPlatform::ResourceProvider::MODRINTH;
-
auto download_task = makeShared<ResourceDownloadTask>(pack, project_ver, m_mods_folder);
m_updatable.emplace_back(pack->name, hash, mod->version(), project_ver.version_number, project_ver.changelog,
ModPlatform::ResourceProvider::MODRINTH, download_task);
}
+ m_deps.append(std::make_shared<GetModDependenciesTask::PackDependency>(pack, project_ver));
}
} catch (Json::JsonException& e) {
failed(e.cause() + " : " + e.what());
diff --git a/launcher/ui/dialogs/ModUpdateDialog.cpp b/launcher/ui/dialogs/ModUpdateDialog.cpp
index c95ab0ca..ee64b392 100644
--- a/launcher/ui/dialogs/ModUpdateDialog.cpp
+++ b/launcher/ui/dialogs/ModUpdateDialog.cpp
@@ -3,6 +3,9 @@
#include "CustomMessageBox.h"
#include "ProgressDialog.h"
#include "ScrollMessageBox.h"
+#include "minecraft/mod/tasks/GetModDependenciesTask.h"
+#include "modplatform/ModIndex.h"
+#include "modplatform/flame/FlameAPI.h"
#include "ui_ReviewMessageBox.h"
#include "Markdown.h"
@@ -125,6 +128,8 @@ void ModUpdateDialog::checkCandidates()
return;
}
+ QList<std::shared_ptr<GetModDependenciesTask::PackDependency>> selectedVers;
+
// Add found updates for Modrinth
if (m_modrinth_check_task) {
auto modrinth_updates = m_modrinth_check_task->getUpdatable();
@@ -134,6 +139,7 @@ void ModUpdateDialog::checkCandidates()
appendMod(updatable);
m_tasks.insert(updatable.name, updatable.download);
}
+ selectedVers.append(m_modrinth_check_task->getDependencies());
}
// Add found updated for Flame
@@ -145,6 +151,7 @@ void ModUpdateDialog::checkCandidates()
appendMod(updatable);
m_tasks.insert(updatable.name, updatable.download);
}
+ selectedVers.append(m_flame_check_task->getDependencies());
}
// Report failed update checking
@@ -179,6 +186,47 @@ void ModUpdateDialog::checkCandidates()
}
}
+ { // dependencies
+ auto depTask = makeShared<GetModDependenciesTask>(this, m_instance, m_mod_model.get(), selectedVers);
+
+ connect(depTask.get(), &Task::failed, this,
+ [&](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->exec(); });
+
+ connect(depTask.get(), &Task::succeeded, this, [&]() {
+ QStringList warnings = depTask->warnings();
+ if (warnings.count()) {
+ CustomMessageBox::selectable(this, tr("Warnings"), warnings.join('\n'), QMessageBox::Warning)->exec();
+ }
+ });
+
+ ProgressDialog progress_dialog_deps(m_parent);
+ progress_dialog_deps.setSkipButton(true, tr("Abort"));
+ progress_dialog_deps.setWindowTitle(tr("Checking for dependencies..."));
+ auto dret = progress_dialog_deps.execWithTask(depTask.get());
+
+ // If the dialog was skipped / some download error happened
+ if (dret == QDialog::DialogCode::Rejected) {
+ m_aborted = true;
+ QMetaObject::invokeMethod(this, "reject", Qt::QueuedConnection);
+ return;
+ }
+ static FlameAPI api;
+
+ auto getRequiredBy = depTask->getRequiredBy();
+
+ for (auto dep : depTask->getDependecies()) {
+ auto changelog = dep->version.changelog;
+ if (dep->pack->provider == ModPlatform::ResourceProvider::FLAME)
+ changelog = api.getModFileChangelog(dep->version.addonId.toInt(), dep->version.fileId.toInt());
+ auto download_task = makeShared<ResourceDownloadTask>(dep->pack, dep->version, m_mod_model);
+ CheckUpdateTask::UpdatableMod updatable = { dep->pack->name, dep->version.hash, "", dep->version.version,
+ changelog, dep->pack->provider, download_task };
+
+ appendMod(updatable, getRequiredBy.value(dep->version.addonId.toString()));
+ m_tasks.insert(updatable.name, updatable.download);
+ }
+ }
+
// If there's no mod to be updated
if (ui->modTreeWidget->topLevelItemCount() == 0) {
m_no_updates = true;
@@ -351,7 +399,7 @@ void ModUpdateDialog::onMetadataFailed(Mod* mod, bool try_others, ModPlatform::R
}
}
-void ModUpdateDialog::appendMod(CheckUpdateTask::UpdatableMod const& info)
+void ModUpdateDialog::appendMod(CheckUpdateTask::UpdatableMod const& info, QStringList requiredBy)
{
auto item_top = new QTreeWidgetItem(ui->modTreeWidget);
item_top->setCheckState(0, Qt::CheckState::Checked);
@@ -367,6 +415,21 @@ void ModUpdateDialog::appendMod(CheckUpdateTask::UpdatableMod const& info)
auto new_version_item = new QTreeWidgetItem(item_top);
new_version_item->setText(0, tr("New version: %1").arg(info.new_version));
+ if (!requiredBy.isEmpty()) {
+ auto requiredByItem = new QTreeWidgetItem(item_top);
+ if (requiredBy.length() == 1) {
+ requiredByItem->setText(0, tr("Required by: %1").arg(requiredBy.back()));
+ } else {
+ requiredByItem->setText(0, tr("Required by:"));
+ auto i = 0;
+ for (auto req : requiredBy) {
+ auto reqItem = new QTreeWidgetItem(requiredByItem);
+ reqItem->setText(0, req);
+ reqItem->insertChildren(i++, { reqItem });
+ }
+ }
+ }
+
auto changelog_item = new QTreeWidgetItem(item_top);
changelog_item->setText(0, tr("Changelog of the latest version"));
diff --git a/launcher/ui/dialogs/ModUpdateDialog.h b/launcher/ui/dialogs/ModUpdateDialog.h
index 12dddf5e..b79aa494 100644
--- a/launcher/ui/dialogs/ModUpdateDialog.h
+++ b/launcher/ui/dialogs/ModUpdateDialog.h
@@ -23,7 +23,7 @@ class ModUpdateDialog final : public ReviewMessageBox {
void checkCandidates();
- void appendMod(const CheckUpdateTask::UpdatableMod& info);
+ void appendMod(const CheckUpdateTask::UpdatableMod& info, QStringList requiredBy = {});
const QList<ResourceDownloadTask::Ptr> getTasks();
auto indexDir() const -> QDir { return m_mod_model->indexDir(); }
diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp
index bf76b01e..c40b1546 100644
--- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp
+++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp
@@ -127,35 +127,12 @@ void ResourceDownloadDialog::connectButtons()
static ModPlatform::ProviderCapabilities ProviderCaps;
-QStringList getRequiredBy(QList<ResourceDownloadDialog::DownloadTaskPtr> tasks, ResourceDownloadDialog::DownloadTaskPtr pack)
-{
- auto addonId = pack->getPack()->addonId;
- auto provider = pack->getPack()->provider;
- auto version = pack->getVersionID();
- auto req = QStringList();
- for (auto& task : tasks) {
- if (provider != task->getPack()->provider)
- continue;
- auto deps = task->getVersion().dependencies;
- if (auto dep = std::find_if(deps.begin(), deps.end(),
- [addonId, provider, version](const ModPlatform::Dependency& d) {
- return d.type == ModPlatform::DependencyType::REQUIRED &&
- (provider == ModPlatform::ResourceProvider::MODRINTH && d.addonId.toString().isEmpty()
- ? version == d.version
- : d.addonId == addonId);
- });
- dep != deps.end()) {
- req.append(task->getName());
- }
- }
- return req;
-}
-
void ResourceDownloadDialog::confirm()
{
auto confirm_dialog = ReviewMessageBox::create(this, tr("Confirm %1 to download").arg(resourcesString()));
confirm_dialog->retranslateUi(resourcesString());
+ QHash<QString, QStringList> getRequiredBy;
if (auto task = getModDependenciesTask(); task) {
connect(task.get(), &Task::failed, this,
[&](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->exec(); });
@@ -180,6 +157,7 @@ void ResourceDownloadDialog::confirm()
} else {
for (auto dep : task->getDependecies())
addResource(dep->pack, dep->version);
+ getRequiredBy = task->getRequiredBy();
}
}
@@ -189,7 +167,8 @@ void ResourceDownloadDialog::confirm()
});
for (auto& task : selected) {
confirm_dialog->appendResource({ task->getName(), task->getFilename(), task->getCustomPath(),
- ProviderCaps.name(task->getProvider()), getRequiredBy(selected, task) });
+ ProviderCaps.name(task->getProvider()),
+ getRequiredBy.value(task->getPack()->addonId.toString()) });
}
if (confirm_dialog->exec()) {