diff options
Diffstat (limited to 'launcher/ui/dialogs')
-rw-r--r-- | launcher/ui/dialogs/ModUpdateDialog.cpp | 113 | ||||
-rw-r--r-- | launcher/ui/dialogs/ModUpdateDialog.h | 8 |
2 files changed, 90 insertions, 31 deletions
diff --git a/launcher/ui/dialogs/ModUpdateDialog.cpp b/launcher/ui/dialogs/ModUpdateDialog.cpp index a4d83483..7584621a 100644 --- a/launcher/ui/dialogs/ModUpdateDialog.cpp +++ b/launcher/ui/dialogs/ModUpdateDialog.cpp @@ -34,12 +34,13 @@ static ModAPI::ModLoaderTypes mcLoaders(BaseInstance* inst) ModUpdateDialog::ModUpdateDialog(QWidget* parent, BaseInstance* instance, - const std::shared_ptr<ModFolderModel>& mods, + const std::shared_ptr<ModFolderModel> mods, std::list<Mod>& search_for) : ReviewMessageBox(parent, tr("Confirm mods to update"), "") , m_parent(parent) , m_mod_model(mods) , m_candidates(search_for) + , m_second_try_metadata(new SequentialTask()) , m_instance(instance) { ReviewMessageBox::setGeometry(0, 0, 800, 600); @@ -47,15 +48,6 @@ ModUpdateDialog::ModUpdateDialog(QWidget* parent, ui->explainLabel->setText(tr("You're about to update the following mods:")); ui->onlyCheckedLabel->setText(tr("Only mods with a check will be updated!")); - connect(&m_check_task, &Task::failed, this, - [&](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->exec(); }); - - connect(&m_check_task, &Task::succeeded, this, [&]() { - QStringList warnings = m_check_task.warnings(); - if (warnings.count()) { - CustomMessageBox::selectable(this, tr("Warnings"), warnings.join('\n'), QMessageBox::Warning)->exec(); - } - }); } void ModUpdateDialog::checkCandidates() @@ -89,26 +81,39 @@ void ModUpdateDialog::checkCandidates() auto versions = mcVersions(m_instance); auto loaders = mcLoaders(m_instance); + SequentialTask check_task (m_parent, tr("Checking for updates")); + if (!m_modrinth_to_update.empty()) { m_modrinth_check_task = new ModrinthCheckUpdate(m_modrinth_to_update, versions, loaders, m_mod_model); connect(m_modrinth_check_task, &CheckUpdateTask::checkFailed, this, [this](Mod mod, QString reason, QUrl recover_url) { m_failed_check_update.emplace_back(mod, reason, recover_url); }); - m_check_task.addTask(m_modrinth_check_task); + check_task.addTask(m_modrinth_check_task); } if (!m_flame_to_update.empty()) { m_flame_check_task = new FlameCheckUpdate(m_flame_to_update, versions, loaders, m_mod_model); connect(m_flame_check_task, &CheckUpdateTask::checkFailed, this, [this](Mod mod, QString reason, QUrl recover_url) { m_failed_check_update.emplace_back(mod, reason, recover_url); }); - m_check_task.addTask(m_flame_check_task); + check_task.addTask(m_flame_check_task); } + connect(&check_task, &Task::failed, this, + [&](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->exec(); }); + + connect(&check_task, &Task::succeeded, this, [&]() { + QStringList warnings = check_task.warnings(); + if (warnings.count()) { + CustomMessageBox::selectable(this, tr("Warnings"), warnings.join('\n'), QMessageBox::Warning)->exec(); + } + }); + // Check for updates + // FIXME: SOMEHOW THIS IS NOT MODAL??????? ProgressDialog progress_dialog(m_parent); progress_dialog.setSkipButton(true, tr("Abort")); progress_dialog.setVisible(true); progress_dialog.setWindowTitle(tr("Checking for updates...")); - auto ret = progress_dialog.execWithTask(&m_check_task); + auto ret = progress_dialog.execWithTask(&check_task); // If the dialog was skipped / some download error happened if (ret == QDialog::DialogCode::Rejected) { @@ -183,13 +188,29 @@ auto ModUpdateDialog::ensureMetadata() -> bool { auto index_dir = indexDir(); - auto* seq = new SequentialTask(m_parent, tr("Looking for metadata")); + SequentialTask seq(m_parent, tr("Looking for metadata")); + + // A better use of data structures here could remove the need for this QHash + QHash<QString, bool> should_try_others; + std::list<Mod> modrinth_tmp; + std::list<Mod> flame_tmp; bool confirm_rest = false; bool try_others_rest = false; bool skip_rest = false; ModPlatform::Provider provider_rest = ModPlatform::Provider::MODRINTH; + auto addToTmp = [&](Mod& m, ModPlatform::Provider p) { + switch (p) { + case ModPlatform::Provider::MODRINTH: + modrinth_tmp.push_back(m); + break; + case ModPlatform::Provider::FLAME: + flame_tmp.push_back(m); + break; + } + }; + for (auto& candidate : m_candidates) { if (candidate.status() != ModStatus::NoMetadata) { onMetadataEnsured(candidate); @@ -200,10 +221,8 @@ auto ModUpdateDialog::ensureMetadata() -> bool continue; if (confirm_rest) { - auto* task = new EnsureMetadataTask(candidate, index_dir, try_others_rest, provider_rest); - connect(task, &EnsureMetadataTask::metadataReady, [this, &candidate] { onMetadataEnsured(candidate); }); - connect(task, &EnsureMetadataTask::metadataFailed, [this, &candidate] { onMetadataFailed(candidate); }); - seq->addTask(task); + addToTmp(candidate, provider_rest); + should_try_others.insert(candidate.internal_id(), try_others_rest); continue; } @@ -224,18 +243,36 @@ auto ModUpdateDialog::ensureMetadata() -> bool try_others_rest = response.try_others; } - if (confirmed) { - auto* task = new EnsureMetadataTask(candidate, index_dir, response.try_others, response.chosen); - connect(task, &EnsureMetadataTask::metadataReady, [this, &candidate] { onMetadataEnsured(candidate); }); - connect(task, &EnsureMetadataTask::metadataFailed, [this, &candidate] { onMetadataFailed(candidate); }); - seq->addTask(task); - } + should_try_others.insert(candidate.internal_id(), response.try_others); + + if (confirmed) + addToTmp(candidate, response.chosen); } + if (!modrinth_tmp.empty()) { + auto* modrinth_task = new EnsureMetadataTask(modrinth_tmp, index_dir, ModPlatform::Provider::MODRINTH); + connect(modrinth_task, &EnsureMetadataTask::metadataReady, [this](Mod& candidate) { onMetadataEnsured(candidate); }); + connect(modrinth_task, &EnsureMetadataTask::metadataFailed, [this, &should_try_others](Mod& candidate) { + onMetadataFailed(candidate, should_try_others.find(candidate.internal_id()).value(), ModPlatform::Provider::MODRINTH); + }); + seq.addTask(modrinth_task); + } + + if (!flame_tmp.empty()) { + auto* flame_task = new EnsureMetadataTask(flame_tmp, index_dir, ModPlatform::Provider::FLAME); + connect(flame_task, &EnsureMetadataTask::metadataReady, [this](Mod& candidate) { onMetadataEnsured(candidate); }); + connect(flame_task, &EnsureMetadataTask::metadataFailed, [this, &should_try_others](Mod& candidate) { + onMetadataFailed(candidate, should_try_others.find(candidate.internal_id()).value(), ModPlatform::Provider::FLAME); + }); + seq.addTask(flame_task); + } + + seq.addTask(m_second_try_metadata); + ProgressDialog checking_dialog(m_parent); checking_dialog.setSkipButton(true, tr("Abort")); checking_dialog.setWindowTitle(tr("Generating metadata...")); - auto ret_metadata = checking_dialog.execWithTask(seq); + auto ret_metadata = checking_dialog.execWithTask(&seq); return (ret_metadata != QDialog::DialogCode::Rejected); } @@ -256,9 +293,31 @@ void ModUpdateDialog::onMetadataEnsured(Mod& mod) } } -void ModUpdateDialog::onMetadataFailed(Mod& mod) +ModPlatform::Provider next(ModPlatform::Provider p) { - m_failed_metadata.push_back(mod); + switch (p) { + case ModPlatform::Provider::MODRINTH: + return ModPlatform::Provider::FLAME; + case ModPlatform::Provider::FLAME: + return ModPlatform::Provider::MODRINTH; + } + + return ModPlatform::Provider::FLAME; +} + +void ModUpdateDialog::onMetadataFailed(Mod& mod, bool try_others, ModPlatform::Provider first_choice) +{ + if (try_others) { + auto index_dir = indexDir(); + + auto* task = new EnsureMetadataTask(mod, index_dir, next(first_choice)); + connect(task, &EnsureMetadataTask::metadataReady, [this](Mod& candidate) { onMetadataEnsured(candidate); }); + connect(task, &EnsureMetadataTask::metadataFailed, [this](Mod& candidate) { onMetadataFailed(candidate, false); }); + + m_second_try_metadata->addTask(task); + } else { + m_failed_metadata.push_back(mod); + } } void ModUpdateDialog::appendMod(CheckUpdateTask::UpdatableMod const& info) diff --git a/launcher/ui/dialogs/ModUpdateDialog.h b/launcher/ui/dialogs/ModUpdateDialog.h index 30cd5cbd..f40fc594 100644 --- a/launcher/ui/dialogs/ModUpdateDialog.h +++ b/launcher/ui/dialogs/ModUpdateDialog.h @@ -17,7 +17,7 @@ class ModUpdateDialog final : public ReviewMessageBox { public: explicit ModUpdateDialog(QWidget* parent, BaseInstance* instance, - const std::shared_ptr<ModFolderModel>& mod_model, + const std::shared_ptr<ModFolderModel> mod_model, std::list<Mod>& search_for); void checkCandidates(); @@ -35,21 +35,21 @@ class ModUpdateDialog final : public ReviewMessageBox { private slots: void onMetadataEnsured(Mod&); - void onMetadataFailed(Mod&); + void onMetadataFailed(Mod&, bool try_others = false, ModPlatform::Provider first_choice = ModPlatform::Provider::MODRINTH); private: QWidget* m_parent; - SequentialTask m_check_task; ModrinthCheckUpdate* m_modrinth_check_task = nullptr; FlameCheckUpdate* m_flame_check_task = nullptr; - const std::shared_ptr<ModFolderModel>& m_mod_model; + const std::shared_ptr<ModFolderModel> m_mod_model; std::list<Mod>& m_candidates; std::list<Mod> m_modrinth_to_update; std::list<Mod> m_flame_to_update; + SequentialTask* m_second_try_metadata; std::list<Mod> m_failed_metadata; std::list<std::tuple<Mod, QString, QUrl>> m_failed_check_update; |