diff options
Diffstat (limited to 'launcher')
24 files changed, 207 insertions, 62 deletions
| diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 66044d9a..11e42f16 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -503,6 +503,9 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)          m_settings->registerSetting("MenuBarInsteadOfToolBar", false); +        m_settings->registerSetting("NumberOfConcurrentTasks", 10); +        m_settings->registerSetting("NumberOfConcurrentDownloads", 6); +          QString defaultMonospace;          int defaultSize = 11;  #ifdef Q_OS_WIN32 diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 18e0acab..a7de0105 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -1137,6 +1137,9 @@ include(CompilerWarnings)  # Add executable  add_library(Launcher_logic STATIC ${LOGIC_SOURCES} ${LAUNCHER_SOURCES} ${LAUNCHER_UI} ${LAUNCHER_RESOURCES}) +if(BUILD_TESTING) +target_compile_definitions(Launcher_logic PUBLIC LAUNCHER_TEST) +endif()  set_project_warnings(Launcher_logic      "${Launcher_MSVC_WARNINGS}"      "${Launcher_CLANG_WARNINGS}" diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index d3237b34..0503b660 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -33,6 +33,10 @@ ResourceFolderModel::ResourceFolderModel(QDir dir, BaseInstance* instance, QObje      connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &ResourceFolderModel::directoryChanged);      connect(&m_helper_thread_task, &ConcurrentTask::finished, this, [this] { m_helper_thread_task.clear(); }); +#ifndef LAUNCHER_TEST +    // in tests the application macro doesn't work +    m_helper_thread_task.setMaxConcurrent(APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()); +#endif  }  ResourceFolderModel::~ResourceFolderModel() 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 a4c03cb7..8bd83d98 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" @@ -49,6 +50,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; @@ -66,4 +68,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/EnsureMetadataTask.cpp b/launcher/modplatform/EnsureMetadataTask.cpp index c3eadd06..a9ad2258 100644 --- a/launcher/modplatform/EnsureMetadataTask.cpp +++ b/launcher/modplatform/EnsureMetadataTask.cpp @@ -3,6 +3,7 @@  #include <MurmurHash2.h>  #include <QDebug> +#include "Application.h"  #include "Json.h"  #include "minecraft/mod/Mod.h" @@ -33,7 +34,7 @@ EnsureMetadataTask::EnsureMetadataTask(Mod* mod, QDir dir, ModPlatform::Resource  EnsureMetadataTask::EnsureMetadataTask(QList<Mod*>& mods, QDir dir, ModPlatform::ResourceProvider prov)      : Task(nullptr), m_index_dir(dir), m_provider(prov), m_current_task(nullptr)  { -    m_hashing_task.reset(new ConcurrentTask(this, "MakeHashesTask", 10)); +    m_hashing_task.reset(new ConcurrentTask(this, "MakeHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()));      for (auto* mod : mods) {          auto hash_task = createNewHash(mod);          if (!hash_task) diff --git a/launcher/modplatform/flame/FlameCheckUpdate.cpp b/launcher/modplatform/flame/FlameCheckUpdate.cpp index 023e26e4..c014863a 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/flame/FlamePackExportTask.cpp b/launcher/modplatform/flame/FlamePackExportTask.cpp index d86d34bf..b5ab7bc7 100644 --- a/launcher/modplatform/flame/FlamePackExportTask.cpp +++ b/launcher/modplatform/flame/FlamePackExportTask.cpp @@ -28,6 +28,7 @@  #include <algorithm>  #include <iterator>  #include <memory> +#include "Application.h"  #include "Json.h"  #include "MMCZip.h"  #include "minecraft/PackProfile.h" @@ -102,7 +103,8 @@ void FlamePackExportTask::collectHashes()      setStatus(tr("Finding file hashes..."));      setProgress(1, 5);      auto allMods = mcInstance->loaderModList()->allMods(); -    ConcurrentTask::Ptr hashingTask(new ConcurrentTask(this, "MakeHashesTask", 10)); +    ConcurrentTask::Ptr hashingTask( +        new ConcurrentTask(this, "MakeHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()));      task.reset(hashingTask);      for (const QFileInfo& file : files) {          const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath()); diff --git a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp index 804eb0ba..9b7c5385 100644 --- a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp +++ b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp @@ -38,7 +38,7 @@ void ModrinthCheckUpdate::executeTask()      QStringList hashes;      auto best_hash_type = ProviderCaps.hashType(ModPlatform::ResourceProvider::MODRINTH).first(); -    ConcurrentTask hashing_task(this, "MakeModrinthHashesTask", 10); +    ConcurrentTask hashing_task(this, "MakeModrinthHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt());      for (auto* mod : m_mods) {          if (!mod->enabled()) {              emit checkFailed(mod, tr("Disabled mods won't be updated, to prevent mod duplication issues!")); @@ -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.version_type,                                               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/net/NetJob.cpp b/launcher/net/NetJob.cpp index 3869316e..b99c5acb 100644 --- a/launcher/net/NetJob.cpp +++ b/launcher/net/NetJob.cpp @@ -36,6 +36,11 @@   */  #include "NetJob.h" +#include "Application.h" + +NetJob::NetJob(QString job_name, shared_qobject_ptr<QNetworkAccessManager> network) +    : ConcurrentTask(nullptr, job_name, APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt()), m_network(network) +{}  auto NetJob::addNetAction(NetAction::Ptr action) -> bool  { diff --git a/launcher/net/NetJob.h b/launcher/net/NetJob.h index cc63f449..1c4337ec 100644 --- a/launcher/net/NetJob.h +++ b/launcher/net/NetJob.h @@ -52,9 +52,7 @@ class NetJob : public ConcurrentTask {     public:      using Ptr = shared_qobject_ptr<NetJob>; -    explicit NetJob(QString job_name, shared_qobject_ptr<QNetworkAccessManager> network) -        : ConcurrentTask(nullptr, job_name), m_network(network) -    {} +    explicit NetJob(QString job_name, shared_qobject_ptr<QNetworkAccessManager> network);      ~NetJob() override = default;      void startNext() override; diff --git a/launcher/tasks/ConcurrentTask.h b/launcher/tasks/ConcurrentTask.h index 8b696bf5..00b1d48d 100644 --- a/launcher/tasks/ConcurrentTask.h +++ b/launcher/tasks/ConcurrentTask.h @@ -51,6 +51,9 @@ class ConcurrentTask : public Task {      explicit ConcurrentTask(QObject* parent = nullptr, QString task_name = "", int max_concurrent = 6);      ~ConcurrentTask() override; +    // safe to call before starting the task +    void setMaxConcurrent(int max_concurrent) { m_total_max_size = max_concurrent; } +      bool canAbort() const override { return true; }      inline auto isMultiStep() const -> bool override { return totalSize() > 1; } diff --git a/launcher/ui/dialogs/BlockedModsDialog.cpp b/launcher/ui/dialogs/BlockedModsDialog.cpp index 727c0614..5a1a2f80 100644 --- a/launcher/ui/dialogs/BlockedModsDialog.cpp +++ b/launcher/ui/dialogs/BlockedModsDialog.cpp @@ -44,7 +44,8 @@  BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, const QString& text, QList<BlockedMod>& mods)      : QDialog(parent), ui(new Ui::BlockedModsDialog), m_mods(mods)  { -    m_hashing_task = shared_qobject_ptr<ConcurrentTask>(new ConcurrentTask(this, "MakeHashesTask", 10)); +    m_hashing_task = shared_qobject_ptr<ConcurrentTask>( +        new ConcurrentTask(this, "MakeHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()));      connect(m_hashing_task.get(), &Task::finished, this, &BlockedModsDialog::hashTaskFinished);      ui->setupUi(this); diff --git a/launcher/ui/dialogs/ModUpdateDialog.cpp b/launcher/ui/dialogs/ModUpdateDialog.cpp index 0e11ff1a..43609121 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" @@ -41,7 +44,8 @@ ModUpdateDialog::ModUpdateDialog(QWidget* parent,      , m_parent(parent)      , m_mod_model(mods)      , m_candidates(search_for) -    , m_second_try_metadata(new ConcurrentTask()) +    , m_second_try_metadata( +          new ConcurrentTask(nullptr, "Second Metadata Search", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()))      , m_instance(instance)  {      ReviewMessageBox::setGeometry(0, 0, 800, 600); @@ -124,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(); @@ -133,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 @@ -144,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 @@ -178,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; @@ -350,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); @@ -371,6 +420,21 @@ void ModUpdateDialog::appendMod(CheckUpdateTask::UpdatableMod const& info)          new_version_type_itme->setText(0, tr("New Version Type: %1").arg(info.new_version_type.value().toString()));      } +    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 cfd292f4..dc7cfff0 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,7 @@ 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()),                                           task->getVersion().version_type.toString() });      } diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp index 7f22fdb5..6d8c65ec 100644 --- a/launcher/ui/pages/global/LauncherPage.cpp +++ b/launcher/ui/pages/global/LauncherPage.cpp @@ -189,6 +189,9 @@ void LauncherPage::applySettings()      s->set("MenuBarInsteadOfToolBar", ui->preferMenuBarCheckBox->isChecked()); +    s->set("NumberOfConcurrentTasks", ui->numberOfConcurrentTasksSpinBox->value()); +    s->set("NumberOfConcurrentDownloads", ui->numberOfConcurrentDownloadsSpinBox->value()); +      // Console settings      s->set("ShowConsole", ui->showConsoleCheck->isChecked());      s->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked()); @@ -236,6 +239,9 @@ void LauncherPage::loadSettings()  #endif      ui->preferMenuBarCheckBox->setChecked(s->get("MenuBarInsteadOfToolBar").toBool()); +    ui->numberOfConcurrentTasksSpinBox->setValue(s->get("NumberOfConcurrentTasks").toInt()); +    ui->numberOfConcurrentDownloadsSpinBox->setValue(s->get("NumberOfConcurrentDownloads").toInt()); +      // Console settings      ui->showConsoleCheck->setChecked(s->get("ShowConsole").toBool());      ui->autoCloseConsoleCheck->setChecked(s->get("AutoCloseConsole").toBool()); diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index bc259a9b..250a8bc8 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -190,6 +190,43 @@          </widget>         </item>         <item> +        <widget class="QGroupBox" name="miscellaneousGroupBox"> +         <property name="title"> +          <string>Miscellaneous</string> +         </property> +         <layout class="QGridLayout" name="gridLayout"> +          <item row="0" column="0"> +           <widget class="QLabel" name="numberOfConcurrentTasksLabel"> +            <property name="text"> +             <string>Number of concurrent tasks</string> +            </property> +           </widget> +          </item> +          <item row="0" column="1"> +           <widget class="QSpinBox" name="numberOfConcurrentTasksSpinBox"> +            <property name="minimum"> +             <number>1</number> +            </property> +           </widget> +          </item> +          <item row="1" column="0"> +           <widget class="QLabel" name="numberOfConcurrentDownloadsLabel"> +            <property name="text"> +             <string>Number of concurrent downloads</string> +            </property> +           </widget> +          </item> +          <item row="1" column="1"> +           <widget class="QSpinBox" name="numberOfConcurrentDownloadsSpinBox"> +            <property name="minimum"> +             <number>1</number> +            </property> +           </widget> +          </item> +         </layout> +        </widget> +       </item> +       <item>          <spacer name="verticalSpacer_2">           <property name="orientation">            <enum>Qt::Vertical</enum> diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index b42bbf46..69c34daf 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -175,7 +175,7 @@ void ModFolderPage::installMods()      ResourceDownload::ModDownloadDialog mdownload(this, m_model, m_instance);      if (mdownload.exec()) { -        ConcurrentTask* tasks = new ConcurrentTask(this); +        auto tasks = new ConcurrentTask(this, "Download Mods", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());          connect(tasks, &Task::failed, [this, tasks](QString reason) {              CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();              tasks->deleteLater(); @@ -234,7 +234,7 @@ void ModFolderPage::updateMods()      }      if (update_dialog.exec()) { -        ConcurrentTask* tasks = new ConcurrentTask(this); +        auto tasks = new ConcurrentTask(this, "Download Mods", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());          connect(tasks, &Task::failed, [this, tasks](QString reason) {              CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();              tasks->deleteLater(); diff --git a/launcher/ui/pages/instance/ResourcePackPage.cpp b/launcher/ui/pages/instance/ResourcePackPage.cpp index 26c14ca4..85be6425 100644 --- a/launcher/ui/pages/instance/ResourcePackPage.cpp +++ b/launcher/ui/pages/instance/ResourcePackPage.cpp @@ -72,7 +72,8 @@ void ResourcePackPage::downloadRPs()      ResourceDownload::ResourcePackDownloadDialog mdownload(this, std::static_pointer_cast<ResourcePackFolderModel>(m_model), m_instance);      if (mdownload.exec()) { -        auto tasks = new ConcurrentTask(this); +        auto tasks = +            new ConcurrentTask(this, "Download Resource Pack", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());          connect(tasks, &Task::failed, [this, tasks](QString reason) {              CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();              tasks->deleteLater(); diff --git a/launcher/ui/pages/instance/ShaderPackPage.cpp b/launcher/ui/pages/instance/ShaderPackPage.cpp index dc8b0a05..40366a1b 100644 --- a/launcher/ui/pages/instance/ShaderPackPage.cpp +++ b/launcher/ui/pages/instance/ShaderPackPage.cpp @@ -65,7 +65,7 @@ void ShaderPackPage::downloadShaders()      ResourceDownload::ShaderPackDownloadDialog mdownload(this, std::static_pointer_cast<ShaderPackFolderModel>(m_model), m_instance);      if (mdownload.exec()) { -        auto tasks = new ConcurrentTask(this); +        auto tasks = new ConcurrentTask(this, "Download Shaders", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());          connect(tasks, &Task::failed, [this, tasks](QString reason) {              CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();              tasks->deleteLater(); diff --git a/launcher/ui/pages/instance/TexturePackPage.cpp b/launcher/ui/pages/instance/TexturePackPage.cpp index fa478a9a..7c8d7e06 100644 --- a/launcher/ui/pages/instance/TexturePackPage.cpp +++ b/launcher/ui/pages/instance/TexturePackPage.cpp @@ -74,7 +74,8 @@ void TexturePackPage::downloadTPs()      ResourceDownload::TexturePackDownloadDialog mdownload(this, std::static_pointer_cast<TexturePackFolderModel>(m_model), m_instance);      if (mdownload.exec()) { -        auto tasks = new ConcurrentTask(this); +        auto tasks = +            new ConcurrentTask(this, "Download Texture Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());          connect(tasks, &Task::failed, [this, tasks](QString reason) {              CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();              tasks->deleteLater(); diff --git a/launcher/ui/pages/modplatform/ResourceModel.cpp b/launcher/ui/pages/modplatform/ResourceModel.cpp index cb8f1920..48e66efc 100644 --- a/launcher/ui/pages/modplatform/ResourceModel.cpp +++ b/launcher/ui/pages/modplatform/ResourceModel.cpp @@ -31,6 +31,9 @@ QHash<ResourceModel*, bool> ResourceModel::s_running_models;  ResourceModel::ResourceModel(ResourceAPI* api) : QAbstractListModel(), m_api(api)  {      s_running_models.insert(this, true); +#ifndef LAUNCHER_TEST +    m_current_info_job.setMaxConcurrent(APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt()); +#endif  }  ResourceModel::~ResourceModel() | 
