From 564e394ec80fed5174a7c42edcd6801ba8c29058 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 24 Jun 2023 21:48:12 +0300 Subject: feat:Update mods now fills missing dependencies Signed-off-by: Trial97 --- launcher/ui/dialogs/ModUpdateDialog.cpp | 60 +++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 6 deletions(-) (limited to 'launcher/ui/dialogs') diff --git a/launcher/ui/dialogs/ModUpdateDialog.cpp b/launcher/ui/dialogs/ModUpdateDialog.cpp index 8618b924..6629b1f2 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 "FileSystem.h" @@ -89,15 +92,17 @@ void ModUpdateDialog::checkCandidates() if (!m_modrinth_to_update.empty()) { m_modrinth_check_task.reset(new ModrinthCheckUpdate(m_modrinth_to_update, versions, loaders, m_mod_model)); - connect(m_modrinth_check_task.get(), &CheckUpdateTask::checkFailed, this, - [this](Mod* mod, QString reason, QUrl recover_url) { m_failed_check_update.append({mod, reason, recover_url}); }); + connect(m_modrinth_check_task.get(), &CheckUpdateTask::checkFailed, this, [this](Mod* mod, QString reason, QUrl recover_url) { + m_failed_check_update.append({ mod, reason, recover_url }); + }); check_task.addTask(m_modrinth_check_task); } if (!m_flame_to_update.empty()) { m_flame_check_task.reset(new FlameCheckUpdate(m_flame_to_update, versions, loaders, m_mod_model)); - connect(m_flame_check_task.get(), &CheckUpdateTask::checkFailed, this, - [this](Mod* mod, QString reason, QUrl recover_url) { m_failed_check_update.append({mod, reason, recover_url}); }); + connect(m_flame_check_task.get(), &CheckUpdateTask::checkFailed, this, [this](Mod* mod, QString reason, QUrl recover_url) { + m_failed_check_update.append({ mod, reason, recover_url }); + }); check_task.addTask(m_flame_check_task); } @@ -124,6 +129,8 @@ void ModUpdateDialog::checkCandidates() return; } + QList> selectedVers; + // Add found updates for Modrinth if (m_modrinth_check_task) { auto modrinth_updates = m_modrinth_check_task->getUpdatable(); @@ -133,6 +140,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 @@ -144,6 +152,7 @@ void ModUpdateDialog::checkCandidates() appendMod(updatable); m_tasks.insert(updatable.name, updatable.download); } + selectedVers.append(m_flame_check_task->getDependencies()); } // Report failed update checking @@ -162,7 +171,7 @@ void ModUpdateDialog::checkCandidates() if (!recover_url.isEmpty()) //: %1 is the link to download it manually text += tr("Possible solution: Getting the latest version manually:
%1
") - .arg(QString("%1").arg(recover_url.toString())); + .arg(QString("%1").arg(recover_url.toString())); text += "
"; } @@ -178,6 +187,45 @@ void ModUpdateDialog::checkCandidates() } } + { // dependencies + auto depTask = makeShared(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; + + 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(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); + m_tasks.insert(updatable.name, updatable.download); + } + } + // If there's no mod to be updated if (ui->modTreeWidget->topLevelItemCount() == 0) { m_no_updates = true; @@ -342,7 +390,7 @@ void ModUpdateDialog::onMetadataFailed(Mod* mod, bool try_others, ModPlatform::R } else { QString reason{ tr("Couldn't find a valid version on the selected mod provider(s)") }; - m_failed_metadata.append({mod, reason}); + m_failed_metadata.append({ mod, reason }); } } -- cgit From 158b07a39e98467c10682a64fa76eb31642abc9e Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 25 Jun 2023 00:24:08 +0300 Subject: moved getRequiredBy Signed-off-by: Trial97 --- .../minecraft/mod/tasks/GetModDependenciesTask.cpp | 29 ++++++++++++++++++++++ .../minecraft/mod/tasks/GetModDependenciesTask.h | 1 + launcher/ui/dialogs/ModUpdateDialog.cpp | 24 ++++++++++++++++-- launcher/ui/dialogs/ModUpdateDialog.h | 6 +++-- launcher/ui/dialogs/ResourceDownloadDialog.cpp | 29 +++------------------- 5 files changed, 60 insertions(+), 29 deletions(-) (limited to 'launcher/ui/dialogs') diff --git a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp index f8ecdb33..43d38cfd 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.cpp @@ -250,3 +250,32 @@ void GetModDependenciesTask::removePack(const QVariant addonId) ++it; #endif } + +QHash GetModDependenciesTask::getRequiredBy() +{ + QHash 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 50eba6af..5a29b6ea 100644 --- a/launcher/minecraft/mod/tasks/GetModDependenciesTask.h +++ b/launcher/minecraft/mod/tasks/GetModDependenciesTask.h @@ -62,6 +62,7 @@ class GetModDependenciesTask : public SequentialTask { QList> selected); auto getDependecies() const -> QList> { return m_pack_dependencies; } + QHash getRequiredBy(); protected slots: Task::Ptr prepareDependencyTask(const ModPlatform::Dependency&, const ModPlatform::ResourceProvider, int); diff --git a/launcher/ui/dialogs/ModUpdateDialog.cpp b/launcher/ui/dialogs/ModUpdateDialog.cpp index 6629b1f2..33ea5a1d 100644 --- a/launcher/ui/dialogs/ModUpdateDialog.cpp +++ b/launcher/ui/dialogs/ModUpdateDialog.cpp @@ -213,6 +213,8 @@ void ModUpdateDialog::checkCandidates() } static FlameAPI api; + auto getRequiredBy = depTask->getRequiredBy(); + for (auto dep : depTask->getDependecies()) { auto changelog = dep->version.changelog; if (dep->pack->provider == ModPlatform::ResourceProvider::FLAME) @@ -221,7 +223,7 @@ void ModUpdateDialog::checkCandidates() CheckUpdateTask::UpdatableMod updatable = { dep->pack->name, dep->version.hash, "", dep->version.version, changelog, dep->pack->provider, download_task }; - appendMod(updatable); + appendMod(updatable, getRequiredBy.value(dep->version.addonId.toString())); m_tasks.insert(updatable.name, updatable.download); } } @@ -394,7 +396,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); @@ -410,6 +412,24 @@ 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 new_version_item = new QTreeWidgetItem(item_top); + new_version_item->setText(0, tr("New version: %1").arg(info.new_version)); + + 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 1a92f613..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 getTasks(); auto indexDir() const -> QDir { return m_mod_model->indexDir(); } @@ -36,7 +36,9 @@ class ModUpdateDialog final : public ReviewMessageBox { private slots: void onMetadataEnsured(Mod*); - void onMetadataFailed(Mod*, bool try_others = false, ModPlatform::ResourceProvider first_choice = ModPlatform::ResourceProvider::MODRINTH); + void onMetadataFailed(Mod*, + bool try_others = false, + ModPlatform::ResourceProvider first_choice = ModPlatform::ResourceProvider::MODRINTH); private: QWidget* m_parent; diff --git a/launcher/ui/dialogs/ResourceDownloadDialog.cpp b/launcher/ui/dialogs/ResourceDownloadDialog.cpp index 4f59f560..0e579ce6 100644 --- a/launcher/ui/dialogs/ResourceDownloadDialog.cpp +++ b/launcher/ui/dialogs/ResourceDownloadDialog.cpp @@ -125,35 +125,12 @@ void ResourceDownloadDialog::connectButtons() static ModPlatform::ProviderCapabilities ProviderCaps; -QStringList getRequiredBy(QList 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 getRequiredBy; if (auto task = getModDependenciesTask(); task) { connect(task.get(), &Task::failed, this, [&](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->exec(); }); @@ -178,6 +155,7 @@ void ResourceDownloadDialog::confirm() } else { for (auto dep : task->getDependecies()) addResource(dep->pack, dep->version); + getRequiredBy = task->getRequiredBy(); } } @@ -187,7 +165,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()) { -- cgit From 6f7d901a1f5c02e0629e4bae9172c04bb81ce0d9 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sun, 25 Jun 2023 09:17:28 +0300 Subject: removed extra variable Signed-off-by: Trial97 --- launcher/ui/dialogs/ModUpdateDialog.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'launcher/ui/dialogs') diff --git a/launcher/ui/dialogs/ModUpdateDialog.cpp b/launcher/ui/dialogs/ModUpdateDialog.cpp index 33ea5a1d..66d7e3af 100644 --- a/launcher/ui/dialogs/ModUpdateDialog.cpp +++ b/launcher/ui/dialogs/ModUpdateDialog.cpp @@ -413,9 +413,6 @@ void ModUpdateDialog::appendMod(CheckUpdateTask::UpdatableMod const& info, QStri new_version_item->setText(0, tr("New version: %1").arg(info.new_version)); if (!requiredBy.isEmpty()) { - auto new_version_item = new QTreeWidgetItem(item_top); - new_version_item->setText(0, tr("New version: %1").arg(info.new_version)); - auto requiredByItem = new QTreeWidgetItem(item_top); if (requiredBy.length() == 1) { requiredByItem->setText(0, tr("Required by: %1").arg(requiredBy.back())); -- cgit