From 881b2f2b385f19d9b64a149fca3c3741a803a172 Mon Sep 17 00:00:00 2001 From: flow Date: Wed, 2 Mar 2022 18:35:59 -0300 Subject: refactor: Use a single indexed pack for mods Since there's little difference between them, let's remove duplication and merge them. --- launcher/ui/pages/modplatform/flame/FlameModModel.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'launcher/ui/pages/modplatform/flame/FlameModModel.cpp') diff --git a/launcher/ui/pages/modplatform/flame/FlameModModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModModel.cpp index e8afba5a..052f30d1 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModModel.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModModel.cpp @@ -39,7 +39,7 @@ QVariant ListModel::data(const QModelIndex &index, int role) const return QString("INVALID INDEX %1").arg(pos); } - IndexedPack pack = modpacks.at(pos); + ModPlatform::IndexedPack pack = modpacks.at(pos); if(role == Qt::DisplayRole) { return pack.name; @@ -225,12 +225,12 @@ void ListModel::searchRequestFinished() return; } - QList newList; + QList newList; auto packs = doc.array(); for(auto packRaw : packs) { auto packObj = packRaw.toObject(); - FlameMod::IndexedPack pack; + ModPlatform::IndexedPack pack; try { FlameMod::loadIndexedPack(pack, packObj); -- cgit From 0dd1c26cf3cd68cd83f5d9da6cf34d4aa3f30db2 Mon Sep 17 00:00:00 2001 From: flow Date: Wed, 2 Mar 2022 21:17:10 -0300 Subject: refactor: extract common code in mod pages and model This creates a hierarchy in which ModPage and ModModel are the parents of every mod provider, providing the basic functionality common to all of them. It also imposes a unique .ui file (they were already equal before, just duplicated basically) on all mod providers. --- launcher/CMakeLists.txt | 8 +- launcher/ui/pages/modplatform/ModModel.cpp | 166 ++++++++++++++ launcher/ui/pages/modplatform/ModModel.h | 60 +++++ launcher/ui/pages/modplatform/ModPage.cpp | 152 +++++++++++++ launcher/ui/pages/modplatform/ModPage.h | 57 +++++ launcher/ui/pages/modplatform/ModPage.ui | 97 ++++++++ .../ui/pages/modplatform/flame/FlameModModel.cpp | 223 ++----------------- .../ui/pages/modplatform/flame/FlameModModel.h | 68 ++---- .../ui/pages/modplatform/flame/FlameModPage.cpp | 231 ++++--------------- launcher/ui/pages/modplatform/flame/FlameModPage.h | 72 ++---- .../ui/pages/modplatform/flame/FlameModPage.ui | 97 -------- .../pages/modplatform/modrinth/ModrinthModel.cpp | 245 +++------------------ .../ui/pages/modplatform/modrinth/ModrinthModel.h | 68 ++---- .../ui/pages/modplatform/modrinth/ModrinthPage.cpp | 217 ++++-------------- .../ui/pages/modplatform/modrinth/ModrinthPage.h | 72 ++---- .../ui/pages/modplatform/modrinth/ModrinthPage.ui | 97 -------- 16 files changed, 720 insertions(+), 1210 deletions(-) create mode 100644 launcher/ui/pages/modplatform/ModModel.cpp create mode 100644 launcher/ui/pages/modplatform/ModModel.h create mode 100644 launcher/ui/pages/modplatform/ModPage.cpp create mode 100644 launcher/ui/pages/modplatform/ModPage.h create mode 100644 launcher/ui/pages/modplatform/ModPage.ui delete mode 100644 launcher/ui/pages/modplatform/flame/FlameModPage.ui delete mode 100644 launcher/ui/pages/modplatform/modrinth/ModrinthPage.ui (limited to 'launcher/ui/pages/modplatform/flame/FlameModModel.cpp') diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 86c05651..0dcda925 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -721,6 +721,11 @@ SET(LAUNCHER_SOURCES ui/pages/modplatform/VanillaPage.cpp ui/pages/modplatform/VanillaPage.h + ui/pages/modplatform/ModPage.cpp + ui/pages/modplatform/ModPage.h + ui/pages/modplatform/ModModel.cpp + ui/pages/modplatform/ModModel.h + ui/pages/modplatform/atlauncher/AtlFilterModel.cpp ui/pages/modplatform/atlauncher/AtlFilterModel.h ui/pages/modplatform/atlauncher/AtlListModel.cpp @@ -879,13 +884,12 @@ qt5_wrap_ui(LAUNCHER_UI ui/pages/modplatform/atlauncher/AtlOptionalModDialog.ui ui/pages/modplatform/atlauncher/AtlPage.ui ui/pages/modplatform/VanillaPage.ui + ui/pages/modplatform/ModPage.ui ui/pages/modplatform/flame/FlamePage.ui - ui/pages/modplatform/flame/FlameModPage.ui ui/pages/modplatform/legacy_ftb/Page.ui ui/pages/modplatform/ImportPage.ui ui/pages/modplatform/ftb/FtbPage.ui ui/pages/modplatform/technic/TechnicPage.ui - ui/pages/modplatform/modrinth/ModrinthPage.ui ui/widgets/InstanceCardWidget.ui ui/widgets/CustomCommands.ui ui/widgets/MCModInfoFrame.ui diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp new file mode 100644 index 00000000..5bd7e33e --- /dev/null +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -0,0 +1,166 @@ +#include "ModModel.h" +#include "ModPage.h" + +#include "ui/dialogs/ModDownloadDialog.h" + +#include + +namespace ModPlatform { + +ListModel::ListModel(ModPage* parent) : QAbstractListModel(parent), m_parent(parent) {} + +ListModel::~ListModel() {} + +int ListModel::rowCount(const QModelIndex& parent) const +{ + return modpacks.size(); +} + +int ListModel::columnCount(const QModelIndex& parent) const +{ + return 1; +} + +QVariant ListModel::data(const QModelIndex& index, int role) const +{ + int pos = index.row(); + if (pos >= modpacks.size() || pos < 0 || !index.isValid()) { return QString("INVALID INDEX %1").arg(pos); } + + ModPlatform::IndexedPack pack = modpacks.at(pos); + if (role == Qt::DisplayRole) { + return pack.name; + } else if (role == Qt::ToolTipRole) { + if (pack.description.length() > 100) { + // some magic to prevent to long tooltips and replace html linebreaks + QString edit = pack.description.left(97); + edit = edit.left(edit.lastIndexOf("
")).left(edit.lastIndexOf(" ")).append("..."); + return edit; + } + return pack.description; + } else if (role == Qt::DecorationRole) { + if (m_logoMap.contains(pack.logoName)) { return (m_logoMap.value(pack.logoName)); } + QIcon icon = APPLICATION->getThemedIcon("screenshot-placeholder"); + ((ListModel*)this)->requestLogo(pack.logoName, pack.logoUrl); + return icon; + } else if (role == Qt::UserRole) { + QVariant v; + v.setValue(pack); + return v; + } + + return QVariant(); +} + +void ListModel::logoLoaded(QString logo, QIcon out) +{ + m_loadingLogos.removeAll(logo); + m_logoMap.insert(logo, out); + for (int i = 0; i < modpacks.size(); i++) { + if (modpacks[i].logoName == logo) { emit dataChanged(createIndex(i, 0), createIndex(i, 0), { Qt::DecorationRole }); } + } +} + +void ListModel::logoFailed(QString logo) +{ + m_failedLogos.append(logo); + m_loadingLogos.removeAll(logo); +} + +Qt::ItemFlags ListModel::flags(const QModelIndex& index) const +{ + return QAbstractListModel::flags(index); +} + +bool ListModel::canFetchMore(const QModelIndex& parent) const +{ + return searchState == CanPossiblyFetchMore; +} + +void ListModel::fetchMore(const QModelIndex& parent) +{ + if (parent.isValid()) return; + if (nextSearchOffset == 0) { + qWarning() << "fetchMore with 0 offset is wrong..."; + return; + } + performPaginatedSearch(); +} + +void ListModel::getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback) +{ + if (m_logoMap.contains(logo)) { + callback(APPLICATION->metacache()->resolveEntry(m_parent->metaEntryBase(), QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); + } else { + requestLogo(logo, logoUrl); + } +} + +void ListModel::searchWithTerm(const QString& term, const int sort) +{ + if (currentSearchTerm == term && currentSearchTerm.isNull() == term.isNull() && currentSort == sort) { return; } + currentSearchTerm = term; + currentSort = sort; + if (jobPtr) { + jobPtr->abort(); + searchState = ResetRequested; + return; + } else { + beginResetModel(); + modpacks.clear(); + endResetModel(); + searchState = None; + } + nextSearchOffset = 0; + performPaginatedSearch(); +} + +void ListModel::searchRequestFailed(QString reason) +{ + if (jobPtr->first()->m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 409) { + // 409 Gone, notify user to update + QMessageBox::critical(nullptr, tr("Error"), + QString("%1 %2") + .arg(m_parent->displayName()) + .arg(tr("API version too old!\nPlease update PolyMC!"))); + // self-destruct + ((ModDownloadDialog*)((ModPage*)parent())->parentWidget())->reject(); + } + jobPtr.reset(); + + if (searchState == ResetRequested) { + beginResetModel(); + modpacks.clear(); + endResetModel(); + + nextSearchOffset = 0; + performPaginatedSearch(); + } else { + searchState = Finished; + } +} + +void ListModel::requestLogo(QString logo, QString url) +{ + if (m_loadingLogos.contains(logo) || m_failedLogos.contains(logo)) { return; } + + MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry(m_parent->metaEntryBase(), QString("logos/%1").arg(logo.section(".", 0, 0))); + auto job = new NetJob(QString("%1 Icon Download %2").arg(m_parent->debugName()).arg(logo), APPLICATION->network()); + job->addNetAction(Net::Download::makeCached(QUrl(url), entry)); + + auto fullPath = entry->getFullPath(); + QObject::connect(job, &NetJob::succeeded, this, [this, logo, fullPath, job] { + job->deleteLater(); + emit logoLoaded(logo, QIcon(fullPath)); + if (waitingCallbacks.contains(logo)) { waitingCallbacks.value(logo)(fullPath); } + }); + + QObject::connect(job, &NetJob::failed, this, [this, logo, job] { + job->deleteLater(); + emit logoFailed(logo); + }); + + job->start(); + m_loadingLogos.append(logo); +} + +} // namespace ModPlatform diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h new file mode 100644 index 00000000..ae8ceb7c --- /dev/null +++ b/launcher/ui/pages/modplatform/ModModel.h @@ -0,0 +1,60 @@ +#pragma once + +#include + +#include "modplatform/ModIndex.h" +#include "net/NetJob.h" + +class ModPage; + +namespace ModPlatform { + +typedef QMap LogoMap; +typedef std::function LogoCallback; + +class ListModel : public QAbstractListModel { + Q_OBJECT + + public: + ListModel(ModPage* parent); + virtual ~ListModel(); + + int rowCount(const QModelIndex& parent) const override; + int columnCount(const QModelIndex& parent) const override; + QVariant data(const QModelIndex& index, int role) const override; + Qt::ItemFlags flags(const QModelIndex& index) const override; + bool canFetchMore(const QModelIndex& parent) const override; + void fetchMore(const QModelIndex& parent) override; + + void getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback); + void searchWithTerm(const QString& term, const int sort); + + protected slots: + virtual void performPaginatedSearch() = 0; + virtual void searchRequestFinished() = 0; + + void logoFailed(QString logo); + void logoLoaded(QString logo, QIcon out); + + void searchRequestFailed(QString reason); + + protected: + void requestLogo(QString file, QString url); + + protected: + ModPage* m_parent; + + QList modpacks; + QStringList m_failedLogos; + QStringList m_loadingLogos; + LogoMap m_logoMap; + QMap waitingCallbacks; + + QString currentSearchTerm; + int currentSort = 0; + int nextSearchOffset = 0; + enum SearchState { None, CanPossiblyFetchMore, ResetRequested, Finished } searchState = None; + NetJob::Ptr jobPtr; + QByteArray response; +}; +} // namespace ModPlatform diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp new file mode 100644 index 00000000..8af534a6 --- /dev/null +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -0,0 +1,152 @@ +#include "ModPage.h" +#include "ui_ModPage.h" + +#include + +#include "ui/dialogs/ModDownloadDialog.h" + +ModPage::ModPage(ModDownloadDialog* dialog, BaseInstance* instance) + : QWidget(dialog), m_instance(instance), ui(new Ui::ModPage), dialog(dialog) +{ + ui->setupUi(this); + connect(ui->searchButton, &QPushButton::clicked, this, &ModPage::triggerSearch); + ui->searchEdit->installEventFilter(this); + + ui->versionSelectionBox->view()->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); + ui->versionSelectionBox->view()->parentWidget()->setMaximumHeight(300); + +} + +ModPage::~ModPage() +{ + delete ui; +} + +void ModPage::openedImpl() +{ + updateSelectionButton(); + triggerSearch(); +} + +bool ModPage::eventFilter(QObject* watched, QEvent* event) +{ + if (watched == ui->searchEdit && event->type() == QEvent::KeyPress) { + QKeyEvent* keyEvent = static_cast(event); + if (keyEvent->key() == Qt::Key_Return) { + triggerSearch(); + keyEvent->accept(); + return true; + } + } + return QWidget::eventFilter(watched, event); +} + +void ModPage::updateSelectionButton() +{ + if (!isOpened || selectedVersion < 0) { + ui->modSelectionButton->setEnabled(false); + return; + } + + ui->modSelectionButton->setEnabled(true); + auto& version = current.versions[selectedVersion]; + if (!dialog->isModSelected(current.name, version.fileName)) { + ui->modSelectionButton->setText(tr("Select mod for download")); + } else { + ui->modSelectionButton->setText(tr("Deselect mod for download")); + } +} + +void ModPage::triggerSearch() +{ + listModel->searchWithTerm(ui->searchEdit->text(), ui->sortByBox->currentIndex()); +} + +void ModPage::onSelectionChanged(QModelIndex first, QModelIndex second) +{ + ui->versionSelectionBox->clear(); + + if (!first.isValid()) { return; } + + current = listModel->data(first, Qt::UserRole).value(); + QString text = ""; + QString name = current.name; + + if (current.websiteUrl.isEmpty()) + text = name; + else + text = "" + name + ""; + + if (!current.authors.empty()) { + auto authorToStr = [](ModPlatform::ModpackAuthor& author) { + if (author.url.isEmpty()) { return author.name; } + return QString("%2").arg(author.url, author.name); + }; + QStringList authorStrs; + for (auto& author : current.authors) { + authorStrs.push_back(authorToStr(author)); + } + text += "
" + tr(" by ") + authorStrs.join(", "); + } + text += "

"; + + ui->packDescription->setHtml(text + current.description); + + if (!current.versionsLoaded) { + qDebug() << QString("Loading %1 mod versions").arg(debugName()); + + ui->modSelectionButton->setText(tr("Loading versions...")); + ui->modSelectionButton->setEnabled(false); + + auto netJob = new NetJob(QString("%1::ModVersions(%2)").arg(debugName()).arg(current.name), APPLICATION->network()); + auto response = new QByteArray(); + QString addonId = current.addonId.toString(); + //FIXME + if(debugName() == "Modrinth") + netJob->addNetAction( + Net::Download::makeByteArray(QString("https://api.modrinth.com/v2/project/%1/version").arg(addonId), response)); + else + netJob->addNetAction( + Net::Download::makeByteArray(QString("https://addons-ecs.forgesvc.net/api/v2/addon/%1/files").arg(addonId), response)); + + QObject::connect(netJob, &NetJob::succeeded, this, [this, response, addonId]{ + onModVersionSucceed(this, response, addonId); + }); + + QObject::connect(netJob, &NetJob::finished, this, [response, netJob] { + netJob->deleteLater(); + delete response; + }); + + netJob->start(); + } else { + for (int i = 0; i < current.versions.size(); i++) { + ui->versionSelectionBox->addItem(current.versions[i].version, QVariant(i)); + } + if (ui->versionSelectionBox->count() == 0) { ui->versionSelectionBox->addItem(tr("No Valid Version found !"), QVariant(-1)); } + + updateSelectionButton(); + } +} + +void ModPage::onVersionSelectionChanged(QString data) +{ + if (data.isNull() || data.isEmpty()) { + selectedVersion = -1; + return; + } + selectedVersion = ui->versionSelectionBox->currentData().toInt(); + updateSelectionButton(); +} + +void ModPage::onModSelected() +{ + auto& version = current.versions[selectedVersion]; + if (dialog->isModSelected(current.name, version.fileName)) { + dialog->removeSelectedMod(current.name); + } else { + dialog->addSelectedMod(current.name, new ModDownloadTask(version.downloadUrl, version.fileName, dialog->mods)); + } + + updateSelectionButton(); +} diff --git a/launcher/ui/pages/modplatform/ModPage.h b/launcher/ui/pages/modplatform/ModPage.h new file mode 100644 index 00000000..c0102549 --- /dev/null +++ b/launcher/ui/pages/modplatform/ModPage.h @@ -0,0 +1,57 @@ +#pragma once + +#include +#include + +#include "modplatform/ModIndex.h" +#include "tasks/Task.h" +#include "ui/pages/BasePage.h" +#include "ui/pages/modplatform/ModModel.h" + +class ModDownloadDialog; + +namespace Ui { +class ModPage; +} + +class ModPage : public QWidget, public BasePage { + Q_OBJECT + + public: + explicit ModPage(ModDownloadDialog* dialog, BaseInstance* instance); + virtual ~ModPage(); + + inline virtual QString displayName() const override = 0; + inline virtual QIcon icon() const override = 0; + inline virtual QString id() const override = 0; + inline virtual QString helpPage() const override = 0; + + inline virtual QString debugName() const = 0; + inline virtual QString metaEntryBase() const = 0; + + virtual bool shouldDisplay() const override = 0; + + void openedImpl() override; + bool eventFilter(QObject* watched, QEvent* event) override; + + BaseInstance* m_instance; + + protected: + virtual void onModVersionSucceed(ModPage*, QByteArray*, QString) = 0; + + void updateSelectionButton(); + + protected slots: + void triggerSearch(); + void onSelectionChanged(QModelIndex first, QModelIndex second); + void onVersionSelectionChanged(QString data); + void onModSelected(); + + protected: + Ui::ModPage* ui = nullptr; + ModDownloadDialog* dialog = nullptr; + ModPlatform::ListModel* listModel = nullptr; + ModPlatform::IndexedPack current; + + int selectedVersion = -1; +}; diff --git a/launcher/ui/pages/modplatform/ModPage.ui b/launcher/ui/pages/modplatform/ModPage.ui new file mode 100644 index 00000000..2b52df22 --- /dev/null +++ b/launcher/ui/pages/modplatform/ModPage.ui @@ -0,0 +1,97 @@ + + + ModPage + + + + 0 + 0 + 837 + 685 + + + + + + + + + true + + + true + + + + + + + Qt::ScrollBarAlwaysOff + + + true + + + + 48 + 48 + + + + + + + + + + Search + + + + + + + Search and filter ... + + + + + + + + + + + + Version selected: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Select mod for download + + + + + + + + + searchEdit + searchButton + packView + packDescription + sortByBox + versionSelectionBox + + + + diff --git a/launcher/ui/pages/modplatform/flame/FlameModModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModModel.cpp index 052f30d1..5ab6672f 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModModel.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModModel.cpp @@ -1,169 +1,25 @@ #include "FlameModModel.h" -#include "Application.h" +#include "FlameModPage.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" -#include "FlameModPage.h" -#include - -#include -#include - -#include +#include namespace FlameMod { -ListModel::ListModel(FlameModPage *parent) : QAbstractListModel(parent) -{ -} - -ListModel::~ListModel() -{ -} - -int ListModel::rowCount(const QModelIndex &parent) const -{ - return modpacks.size(); -} - -int ListModel::columnCount(const QModelIndex &parent) const -{ - return 1; -} - -QVariant ListModel::data(const QModelIndex &index, int role) const -{ - int pos = index.row(); - if(pos >= modpacks.size() || pos < 0 || !index.isValid()) - { - return QString("INVALID INDEX %1").arg(pos); - } - - ModPlatform::IndexedPack pack = modpacks.at(pos); - if(role == Qt::DisplayRole) - { - return pack.name; - } - else if (role == Qt::ToolTipRole) - { - if(pack.description.length() > 100) - { - //some magic to prevent to long tooltips and replace html linebreaks - QString edit = pack.description.left(97); - edit = edit.left(edit.lastIndexOf("
")).left(edit.lastIndexOf(" ")).append("..."); - return edit; - - } - return pack.description; - } - else if(role == Qt::DecorationRole) - { - if(m_logoMap.contains(pack.logoName)) - { - return (m_logoMap.value(pack.logoName)); - } - QIcon icon = APPLICATION->getThemedIcon("screenshot-placeholder"); - ((ListModel *)this)->requestLogo(pack.logoName, pack.logoUrl); - return icon; - } - else if(role == Qt::UserRole) - { - QVariant v; - v.setValue(pack); - return v; - } - - return QVariant(); -} - -void ListModel::logoLoaded(QString logo, QIcon out) -{ - m_loadingLogos.removeAll(logo); - m_logoMap.insert(logo, out); - for(int i = 0; i < modpacks.size(); i++) { - if(modpacks[i].logoName == logo) { - emit dataChanged(createIndex(i, 0), createIndex(i, 0), {Qt::DecorationRole}); - } - } -} +ListModel::ListModel(FlameModPage* parent) : ModPlatform::ListModel(parent) {} -void ListModel::logoFailed(QString logo) -{ - m_failedLogos.append(logo); - m_loadingLogos.removeAll(logo); -} +ListModel::~ListModel() {} -void ListModel::requestLogo(QString logo, QString url) -{ - if(m_loadingLogos.contains(logo) || m_failedLogos.contains(logo)) - { - return; - } - - MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("FlameMods", QString("logos/%1").arg(logo.section(".", 0, 0))); - auto job = new NetJob(QString("Flame Icon Download %1").arg(logo), APPLICATION->network()); - job->addNetAction(Net::Download::makeCached(QUrl(url), entry)); - - auto fullPath = entry->getFullPath(); - QObject::connect(job, &NetJob::succeeded, this, [this, logo, fullPath, job] - { - job->deleteLater(); - emit logoLoaded(logo, QIcon(fullPath)); - if(waitingCallbacks.contains(logo)) - { - waitingCallbacks.value(logo)(fullPath); - } - }); - - QObject::connect(job, &NetJob::failed, this, [this, logo, job] - { - job->deleteLater(); - emit logoFailed(logo); - }); - - job->start(); - m_loadingLogos.append(logo); -} - -void ListModel::getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback) -{ - if(m_logoMap.contains(logo)) - { - callback(APPLICATION->metacache()->resolveEntry("FlameMods", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); - } - else - { - requestLogo(logo, logoUrl); - } -} - -Qt::ItemFlags ListModel::flags(const QModelIndex &index) const -{ - return QAbstractListModel::flags(index); -} - -bool ListModel::canFetchMore(const QModelIndex& parent) const -{ - return searchState == CanPossiblyFetchMore; -} - -void ListModel::fetchMore(const QModelIndex& parent) -{ - if (parent.isValid()) - return; - if(nextSearchOffset == 0) { - qWarning() << "fetchMore with 0 offset is wrong..."; - return; - } - performPaginatedSearch(); -} -const char* sorts[6]{"Featured","Popularity","LastUpdated","Name","Author","TotalDownloads"}; +const char* sorts[6]{ "Featured", "Popularity", "LastUpdated", "Name", "Author", "TotalDownloads" }; void ListModel::performPaginatedSearch() { - - QString mcVersion = ((MinecraftInstance *)((FlameModPage *)parent())->m_instance)->getPackProfile()->getComponentVersion("net.minecraft"); - bool hasFabric = !((MinecraftInstance *)((FlameModPage *)parent())->m_instance)->getPackProfile()->getComponentVersion("net.fabricmc.fabric-loader").isEmpty(); + QString mcVersion = ((MinecraftInstance*)((FlameModPage*)parent())->m_instance)->getPackProfile()->getComponentVersion("net.minecraft"); + bool hasFabric = !((MinecraftInstance*)((FlameModPage*)parent())->m_instance) + ->getPackProfile() + ->getComponentVersion("net.fabricmc.fabric-loader") + .isEmpty(); auto netJob = new NetJob("Flame::Search", APPLICATION->network()); auto searchUrl = QString( "https://addons-ecs.forgesvc.net/api/v2/addon/search?" @@ -176,44 +32,22 @@ void ListModel::performPaginatedSearch() "searchFilter=%2&" "sort=%3&" "modLoaderType=%4&" - "gameVersion=%5" - ) - .arg(nextSearchOffset) - .arg(currentSearchTerm) - .arg(sorts[currentSort]) - .arg(hasFabric ? 4 : 1) // Enum: https://docs.curseforge.com/?http#tocS_ModLoaderType - .arg(mcVersion); + "gameVersion=%5") + .arg(nextSearchOffset) + .arg(currentSearchTerm) + .arg(sorts[currentSort]) + .arg(hasFabric ? 4 : 1) // Enum: https://docs.curseforge.com/?http#tocS_ModLoaderType + .arg(mcVersion); netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response)); jobPtr = netJob; jobPtr->start(); - QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::searchRequestFinished); - QObject::connect(netJob, &NetJob::failed, this, &ListModel::searchRequestFailed); -} -void ListModel::searchWithTerm(const QString &term, const int sort) -{ - if(currentSearchTerm == term && currentSearchTerm.isNull() == term.isNull() && currentSort == sort) { - return; - } - currentSearchTerm = term; - currentSort = sort; - if(jobPtr) { - jobPtr->abort(); - searchState = ResetRequested; - return; - } - else { - beginResetModel(); - modpacks.clear(); - endResetModel(); - searchState = None; - } - nextSearchOffset = 0; - performPaginatedSearch(); + QObject::connect(netJob, &NetJob::succeeded, this, &FlameMod::ListModel::searchRequestFinished); + QObject::connect(netJob, &NetJob::failed, this, &ListModel::searchRequestFailed); } -void ListModel::searchRequestFinished() +void FlameMod::ListModel::searchRequestFinished() { jobPtr.reset(); @@ -253,21 +87,4 @@ void ListModel::searchRequestFinished() endInsertRows(); } -void ListModel::searchRequestFailed(QString reason) -{ - jobPtr.reset(); - - if(searchState == ResetRequested) { - beginResetModel(); - modpacks.clear(); - endResetModel(); - - nextSearchOffset = 0; - performPaginatedSearch(); - } else { - searchState = Finished; - } -} - -} - +} // namespace FlameMod diff --git a/launcher/ui/pages/modplatform/flame/FlameModModel.h b/launcher/ui/pages/modplatform/flame/FlameModModel.h index ec19ab2f..a585331d 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModModel.h +++ b/launcher/ui/pages/modplatform/flame/FlameModModel.h @@ -2,78 +2,36 @@ #include -#include -#include -#include #include -#include #include +#include +#include #include #include -#include +#include +#include -#include #include +#include -#include -#include "modplatform/flame/FlameModIndex.h" #include "BaseInstance.h" #include "FlameModPage.h" +#include "modplatform/flame/FlameModIndex.h" namespace FlameMod { - -typedef QMap LogoMap; typedef std::function LogoCallback; -class ListModel : public QAbstractListModel -{ +class ListModel : public ModPlatform::ListModel { Q_OBJECT -public: - ListModel(FlameModPage *parent); + public: + ListModel(FlameModPage* parent); virtual ~ListModel(); - int rowCount(const QModelIndex &parent) const override; - int columnCount(const QModelIndex &parent) const override; - QVariant data(const QModelIndex &index, int role) const override; - Qt::ItemFlags flags(const QModelIndex &index) const override; - bool canFetchMore(const QModelIndex & parent) const override; - void fetchMore(const QModelIndex & parent) override; - - void getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback); - void searchWithTerm(const QString &term, const int sort); - -private slots: - void performPaginatedSearch(); - - void logoFailed(QString logo); - void logoLoaded(QString logo, QIcon out); - - void searchRequestFinished(); - void searchRequestFailed(QString reason); - -private: - void requestLogo(QString file, QString url); - -private: - QList modpacks; - QStringList m_failedLogos; - QStringList m_loadingLogos; - LogoMap m_logoMap; - QMap waitingCallbacks; - - QString currentSearchTerm; - int currentSort = 0; - int nextSearchOffset = 0; - enum SearchState { - None, - CanPossiblyFetchMore, - ResetRequested, - Finished - } searchState = None; - NetJob::Ptr jobPtr; - QByteArray response; + private slots: + void performPaginatedSearch() override; + void searchRequestFinished() override; }; -} +} // namespace Modrinth diff --git a/launcher/ui/pages/modplatform/flame/FlameModPage.cpp b/launcher/ui/pages/modplatform/flame/FlameModPage.cpp index 48d38b82..ef33f972 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModPage.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModPage.cpp @@ -1,5 +1,5 @@ #include "FlameModPage.h" -#include "ui_FlameModPage.h" +#include "ui_ModPage.h" #include @@ -12,206 +12,59 @@ #include "minecraft/PackProfile.h" #include "ui/dialogs/ModDownloadDialog.h" -FlameModPage::FlameModPage(ModDownloadDialog *dialog, BaseInstance *instance) - : QWidget(dialog), m_instance(instance), ui(new Ui::FlameModPage), - dialog(dialog) { - ui->setupUi(this); - connect(ui->searchButton, &QPushButton::clicked, this, - &FlameModPage::triggerSearch); - ui->searchEdit->installEventFilter(this); - listModel = new FlameMod::ListModel(this); - ui->packView->setModel(listModel); - - ui->versionSelectionBox->view()->setVerticalScrollBarPolicy( - Qt::ScrollBarAsNeeded); - ui->versionSelectionBox->view()->parentWidget()->setMaximumHeight(300); - - // index is used to set the sorting with the flame api - ui->sortByBox->addItem(tr("Sort by Featured")); - ui->sortByBox->addItem(tr("Sort by Popularity")); - ui->sortByBox->addItem(tr("Sort by last updated")); - ui->sortByBox->addItem(tr("Sort by Name")); - ui->sortByBox->addItem(tr("Sort by Author")); - ui->sortByBox->addItem(tr("Sort by Downloads")); - - connect(ui->sortByBox, SIGNAL(currentIndexChanged(int)), this, - SLOT(triggerSearch())); - connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, - this, &FlameModPage::onSelectionChanged); - connect(ui->versionSelectionBox, &QComboBox::currentTextChanged, this, - &FlameModPage::onVersionSelectionChanged); - connect(ui->modSelectionButton, &QPushButton::clicked, this, - &FlameModPage::onModSelected); -} - -FlameModPage::~FlameModPage() { delete ui; } - -bool FlameModPage::eventFilter(QObject *watched, QEvent *event) { - if (watched == ui->searchEdit && event->type() == QEvent::KeyPress) { - QKeyEvent *keyEvent = static_cast(event); - if (keyEvent->key() == Qt::Key_Return) { - triggerSearch(); - keyEvent->accept(); - return true; - } - } - return QWidget::eventFilter(watched, event); +FlameModPage::FlameModPage(ModDownloadDialog* dialog, BaseInstance* instance) + : ModPage(dialog, instance) +{ + listModel = new FlameMod::ListModel(this); + ui->packView->setModel(listModel); + + // index is used to set the sorting with the flame api + ui->sortByBox->addItem(tr("Sort by Featured")); + ui->sortByBox->addItem(tr("Sort by Popularity")); + ui->sortByBox->addItem(tr("Sort by last updated")); + ui->sortByBox->addItem(tr("Sort by Name")); + ui->sortByBox->addItem(tr("Sort by Author")); + ui->sortByBox->addItem(tr("Sort by Downloads")); + + // sometimes Qt just ignores virtual slots and doesn't work as intended it seems, + // so it's best not to connect them in the parent's contructor... + connect(ui->sortByBox, SIGNAL(currentIndexChanged(int)), this, SLOT(triggerSearch())); + connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &FlameModPage::onSelectionChanged); + connect(ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &FlameModPage::onVersionSelectionChanged); + connect(ui->modSelectionButton, &QPushButton::clicked, this, &FlameModPage::onModSelected); } bool FlameModPage::shouldDisplay() const { return true; } -void FlameModPage::openedImpl() { - updateSelectionButton(); - triggerSearch(); -} - -void FlameModPage::triggerSearch() { - listModel->searchWithTerm(ui->searchEdit->text(), - ui->sortByBox->currentIndex()); -} - -void FlameModPage::onSelectionChanged(QModelIndex first, QModelIndex second) { - ui->versionSelectionBox->clear(); - - if (!first.isValid()) { - return; - } - - current = listModel->data(first, Qt::UserRole).value(); - QString text = ""; - QString name = current.name; - - if (current.websiteUrl.isEmpty()) - text = name; - else - text = "" + name + ""; - if (!current.authors.empty()) { - auto authorToStr = [](ModPlatform::ModpackAuthor &author) { - if (author.url.isEmpty()) { - return author.name; - } - return QString("%2").arg(author.url, author.name); - }; - QStringList authorStrs; - for (auto &author : current.authors) { - authorStrs.push_back(authorToStr(author)); +void FlameModPage::onModVersionSucceed(ModPage* instance, QByteArray* response, QString addonId) +{ + if (addonId != current.addonId) { + return; // wrong request } - text += "
" + tr(" by ") + authorStrs.join(", "); - } - text += "

"; - - ui->packDescription->setHtml(text + current.description); - - if (!current.versionsLoaded) { - qDebug() << "Loading flame mod versions"; - - ui->modSelectionButton->setText(tr("Loading versions...")); - ui->modSelectionButton->setEnabled(false); - - auto netJob = - new NetJob(QString("Flame::ModVersions(%1)").arg(current.name), - APPLICATION->network()); - auto response = new QByteArray(); - int addonId = current.addonId.toInt(); - netJob->addNetAction(Net::Download::makeByteArray( - QString("https://addons-ecs.forgesvc.net/api/v2/addon/%1/files") - .arg(addonId), - response)); - - QObject::connect(netJob, &NetJob::succeeded, this, [this, response, addonId] { - if(addonId != current.addonId){ - return; //wrong request - } - QJsonParseError parse_error; - QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from Flame at " - << parse_error.offset - << " reason: " << parse_error.errorString(); + QJsonParseError parse_error; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from Flame at " << parse_error.offset << " reason: " << parse_error.errorString(); qWarning() << *response; return; - } - QJsonArray arr = doc.array(); - try { - FlameMod::loadIndexedPackVersions(current, arr, APPLICATION->network(), - m_instance); - } catch (const JSONValidationError &e) { + } + QJsonArray arr = doc.array(); + try { + FlameMod::loadIndexedPackVersions(current, arr, APPLICATION->network(), m_instance); + } catch (const JSONValidationError& e) { qDebug() << *response; qWarning() << "Error while reading Flame mod version: " << e.cause(); - } - auto packProfile = ((MinecraftInstance *)m_instance)->getPackProfile(); - QString mcVersion = packProfile->getComponentVersion("net.minecraft"); - QString loaderString = - (packProfile->getComponentVersion("net.minecraftforge").isEmpty()) - ? "fabric" - : "forge"; - for (int i = 0; i < current.versions.size(); i++) { + } + auto packProfile = ((MinecraftInstance*)m_instance)->getPackProfile(); + QString mcVersion = packProfile->getComponentVersion("net.minecraft"); + QString loaderString = (packProfile->getComponentVersion("net.minecraftforge").isEmpty()) ? "fabric" : "forge"; + for (int i = 0; i < current.versions.size(); i++) { auto version = current.versions[i]; - if (!version.mcVersion.contains(mcVersion)) { - continue; - } + if (!version.mcVersion.contains(mcVersion)) { continue; } ui->versionSelectionBox->addItem(version.version, QVariant(i)); - } - if (ui->versionSelectionBox->count() == 0) { - ui->versionSelectionBox->addItem(tr("No Valid Version found!"), - QVariant(-1)); - } - - ui->modSelectionButton->setText(tr("Cannot select invalid version :(")); - updateSelectionButton(); - }); - QObject::connect(netJob, &NetJob::finished, this, [response, netJob] { - netJob->deleteLater(); - delete response; - }); - netJob->start(); - } else { - for (int i = 0; i < current.versions.size(); i++) { - ui->versionSelectionBox->addItem(current.versions[i].version, - QVariant(i)); - } - if (ui->versionSelectionBox->count() == 0) { - ui->versionSelectionBox->addItem(tr("No Valid Version found!"), - QVariant(-1)); } + if (ui->versionSelectionBox->count() == 0) { ui->versionSelectionBox->addItem(tr("No Valid Version found!"), QVariant(-1)); } + ui->modSelectionButton->setText(tr("Cannot select invalid version :(")); updateSelectionButton(); - } -} - -void FlameModPage::updateSelectionButton() { - if (!isOpened || selectedVersion < 0) { - ui->modSelectionButton->setEnabled(false); - return; - } - - ui->modSelectionButton->setEnabled(true); - auto &version = current.versions[selectedVersion]; - if (!dialog->isModSelected(current.name, version.fileName)) { - ui->modSelectionButton->setText(tr("Select mod for download")); - } else { - ui->modSelectionButton->setText(tr("Deselect mod for download")); - } -} - -void FlameModPage::onVersionSelectionChanged(QString data) { - if (data.isNull() || data.isEmpty()) { - selectedVersion = -1; - return; - } - selectedVersion = ui->versionSelectionBox->currentData().toInt(); - updateSelectionButton(); -} - -void FlameModPage::onModSelected() { - auto &version = current.versions[selectedVersion]; - if (dialog->isModSelected(current.name, version.fileName)) { - dialog->removeSelectedMod(current.name); - } else { - dialog->addSelectedMod(current.name, - new ModDownloadTask(version.downloadUrl, - version.fileName, dialog->mods)); - } - - updateSelectionButton(); } diff --git a/launcher/ui/pages/modplatform/flame/FlameModPage.h b/launcher/ui/pages/modplatform/flame/FlameModPage.h index 24dfcbc7..2daa155f 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModPage.h +++ b/launcher/ui/pages/modplatform/flame/FlameModPage.h @@ -1,68 +1,24 @@ #pragma once -#include +#include "ui/pages/modplatform/ModPage.h" -#include "ui/pages/BasePage.h" -#include -#include "tasks/Task.h" -#include "modplatform/flame/FlameModIndex.h" - -namespace Ui -{ -class FlameModPage; -} - -class ModDownloadDialog; - -namespace FlameMod { - class ListModel; -} - -class FlameModPage : public QWidget, public BasePage -{ +class FlameModPage : public ModPage { Q_OBJECT -public: - explicit FlameModPage(ModDownloadDialog *dialog, BaseInstance *instance); - virtual ~FlameModPage(); - virtual QString displayName() const override - { - return tr("CurseForge"); - } - virtual QIcon icon() const override - { - return APPLICATION->getThemedIcon("flame"); - } - virtual QString id() const override - { - return "curseforge"; - } - virtual QString helpPage() const override - { - return "Flame-platform"; - } - virtual bool shouldDisplay() const override; - - void openedImpl() override; - - bool eventFilter(QObject * watched, QEvent * event) override; - - BaseInstance *m_instance; + public: + explicit FlameModPage(ModDownloadDialog* dialog, BaseInstance* instance); + virtual ~FlameModPage() = default; -private: - void updateSelectionButton(); + inline QString displayName() const override { return tr("CurseForge"); } + inline QIcon icon() const override { return APPLICATION->getThemedIcon("flame"); } + inline QString id() const override { return "curseforge"; } + inline QString helpPage() const override { return "Flame-platform"; } -private slots: - void triggerSearch(); - void onSelectionChanged(QModelIndex first, QModelIndex second); - void onVersionSelectionChanged(QString data); - void onModSelected(); + inline QString debugName() const override { return tr("Flame"); } + inline QString metaEntryBase() const override { return "FlameMods"; }; -private: - Ui::FlameModPage *ui = nullptr; - ModDownloadDialog* dialog = nullptr; - FlameMod::ListModel* listModel = nullptr; - ModPlatform::IndexedPack current; + bool shouldDisplay() const override; - int selectedVersion = -1; + private: + void onModVersionSucceed(ModPage*, QByteArray*, QString) override; }; diff --git a/launcher/ui/pages/modplatform/flame/FlameModPage.ui b/launcher/ui/pages/modplatform/flame/FlameModPage.ui deleted file mode 100644 index 36df7e8a..00000000 --- a/launcher/ui/pages/modplatform/flame/FlameModPage.ui +++ /dev/null @@ -1,97 +0,0 @@ - - - FlameModPage - - - - 0 - 0 - 837 - 685 - - - - - - - - - - - - - - - Version selected: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Select mod for download - - - - - - - - - Search and filter ... - - - - - - - - - Qt::ScrollBarAlwaysOff - - - true - - - - 48 - 48 - - - - - - - - true - - - true - - - - - - - - - Search - - - - - - - searchEdit - searchButton - packView - packDescription - sortByBox - versionSelectionBox - - - - diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp index 088ca411..d2e86ef8 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp @@ -1,171 +1,25 @@ #include "ModrinthModel.h" -#include "Application.h" +#include "ModrinthPage.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" -#include "ModrinthPage.h" -#include "ui/dialogs/ModDownloadDialog.h" -#include - -#include -#include - -#include -#include +#include namespace Modrinth { -ListModel::ListModel(ModrinthPage *parent) : QAbstractListModel(parent) -{ -} - -ListModel::~ListModel() -{ -} - -int ListModel::rowCount(const QModelIndex &parent) const -{ - return modpacks.size(); -} - -int ListModel::columnCount(const QModelIndex &parent) const -{ - return 1; -} - -QVariant ListModel::data(const QModelIndex &index, int role) const -{ - int pos = index.row(); - if(pos >= modpacks.size() || pos < 0 || !index.isValid()) - { - return QString("INVALID INDEX %1").arg(pos); - } - - ModPlatform::IndexedPack pack = modpacks.at(pos); - if(role == Qt::DisplayRole) - { - return pack.name; - } - else if (role == Qt::ToolTipRole) - { - if(pack.description.length() > 100) - { - //some magic to prevent to long tooltips and replace html linebreaks - QString edit = pack.description.left(97); - edit = edit.left(edit.lastIndexOf("
")).left(edit.lastIndexOf(" ")).append("..."); - return edit; - - } - return pack.description; - } - else if(role == Qt::DecorationRole) - { - if(m_logoMap.contains(pack.logoName)) - { - return (m_logoMap.value(pack.logoName)); - } - QIcon icon = APPLICATION->getThemedIcon("screenshot-placeholder"); - ((ListModel *)this)->requestLogo(pack.logoName, pack.logoUrl); - return icon; - } - else if(role == Qt::UserRole) - { - QVariant v; - v.setValue(pack); - return v; - } - - return QVariant(); -} - -void ListModel::logoLoaded(QString logo, QIcon out) -{ - m_loadingLogos.removeAll(logo); - m_logoMap.insert(logo, out); - for(int i = 0; i < modpacks.size(); i++) { - if(modpacks[i].logoName == logo) { - emit dataChanged(createIndex(i, 0), createIndex(i, 0), {Qt::DecorationRole}); - } - } -} - -void ListModel::logoFailed(QString logo) -{ - m_failedLogos.append(logo); - m_loadingLogos.removeAll(logo); -} - -void ListModel::requestLogo(QString logo, QString url) -{ - if(m_loadingLogos.contains(logo) || m_failedLogos.contains(logo)) - { - return; - } - - MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("ModrinthPacks", QString("logos/%1").arg(logo.section(".", 0, 0))); - auto job = new NetJob(QString("Modrinth Icon Download %1").arg(logo), APPLICATION->network()); - job->addNetAction(Net::Download::makeCached(QUrl(url), entry)); +ListModel::ListModel(ModrinthPage* parent) : ModPlatform::ListModel(parent) {} - auto fullPath = entry->getFullPath(); - QObject::connect(job, &NetJob::succeeded, this, [this, logo, fullPath, job] - { - job->deleteLater(); - emit logoLoaded(logo, QIcon(fullPath)); - if(waitingCallbacks.contains(logo)) - { - waitingCallbacks.value(logo)(fullPath); - } - }); - - QObject::connect(job, &NetJob::failed, this, [this, logo, job] - { - job->deleteLater(); - emit logoFailed(logo); - }); - - job->start(); - m_loadingLogos.append(logo); -} - -void ListModel::getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback) -{ - if(m_logoMap.contains(logo)) - { - callback(APPLICATION->metacache()->resolveEntry("ModrinthPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); - } - else - { - requestLogo(logo, logoUrl); - } -} - -Qt::ItemFlags ListModel::flags(const QModelIndex &index) const -{ - return QAbstractListModel::flags(index); -} +ListModel::~ListModel() {} -bool ListModel::canFetchMore(const QModelIndex& parent) const -{ - return searchState == CanPossiblyFetchMore; -} - -void ListModel::fetchMore(const QModelIndex& parent) -{ - if (parent.isValid()) - return; - if(nextSearchOffset == 0) { - qWarning() << "fetchMore with 0 offset is wrong..."; - return; - } - performPaginatedSearch(); -} -const char* sorts[5]{"relevance","downloads","follows","updated","newest"}; +const char* sorts[5]{ "relevance", "downloads", "follows", "updated", "newest" }; void ListModel::performPaginatedSearch() { - - QString mcVersion = ((MinecraftInstance *)((ModrinthPage *)parent())->m_instance)->getPackProfile()->getComponentVersion("net.minecraft"); - bool hasFabric = !((MinecraftInstance *)((ModrinthPage *)parent())->m_instance)->getPackProfile()->getComponentVersion("net.fabricmc.fabric-loader").isEmpty(); + QString mcVersion = ((MinecraftInstance*)((ModrinthPage*)parent())->m_instance)->getPackProfile()->getComponentVersion("net.minecraft"); + bool hasFabric = !((MinecraftInstance*)((ModrinthPage*)parent())->m_instance) + ->getPackProfile() + ->getComponentVersion("net.fabricmc.fabric-loader") + .isEmpty(); auto netJob = new NetJob("Modrinth::Search", APPLICATION->network()); auto searchUrl = QString( "https://api.modrinth.com/v2/search?" @@ -173,41 +27,19 @@ void ListModel::performPaginatedSearch() "limit=25&" "query=%2&" "index=%3&" - "facets=[[\"categories:%4\"],[\"versions:%5\"],[\"project_type:mod\"]]" - ) - .arg(nextSearchOffset) - .arg(currentSearchTerm) - .arg(sorts[currentSort]) - .arg(hasFabric ? "fabric" : "forge") - .arg(mcVersion); + "facets=[[\"categories:%4\"],[\"versions:%5\"],[\"project_type:mod\"]]") + .arg(nextSearchOffset) + .arg(currentSearchTerm) + .arg(sorts[currentSort]) + .arg(hasFabric ? "fabric" : "forge") + .arg(mcVersion); netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response)); jobPtr = netJob; jobPtr->start(); - QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::searchRequestFinished); - QObject::connect(netJob, &NetJob::failed, this, &ListModel::searchRequestFailed); -} -void ListModel::searchWithTerm(const QString &term, const int sort) -{ - if(currentSearchTerm == term && currentSearchTerm.isNull() == term.isNull() && currentSort == sort) { - return; - } - currentSearchTerm = term; - currentSort = sort; - if(jobPtr) { - jobPtr->abort(); - searchState = ResetRequested; - return; - } - else { - beginResetModel(); - modpacks.clear(); - endResetModel(); - searchState = None; - } - nextSearchOffset = 0; - performPaginatedSearch(); + QObject::connect(netJob, &NetJob::succeeded, this, &Modrinth::ListModel::searchRequestFinished); + QObject::connect(netJob, &NetJob::failed, this, &ListModel::searchRequestFailed); } void Modrinth::ListModel::searchRequestFinished() @@ -216,30 +48,28 @@ void Modrinth::ListModel::searchRequestFinished() QJsonParseError parse_error; QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error); - if(parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from Modrinth at " << parse_error.offset << " reason: " << parse_error.errorString(); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from Modrinth at " << parse_error.offset + << " reason: " << parse_error.errorString(); qWarning() << response; return; } QList newList; auto packs = doc.object().value("hits").toArray(); - for(auto packRaw : packs) { + for (auto packRaw : packs) { auto packObj = packRaw.toObject(); ModPlatform::IndexedPack pack; - try - { + try { Modrinth::loadIndexedPack(pack, packObj); newList.append(pack); - } - catch(const JSONValidationError &e) - { + } catch (const JSONValidationError& e) { qWarning() << "Error while loading mod from Modrinth: " << e.cause(); continue; } } - if(packs.size() < 25) { + if (packs.size() < 25) { searchState = Finished; } else { nextSearchOffset += 25; @@ -250,27 +80,4 @@ void Modrinth::ListModel::searchRequestFinished() endInsertRows(); } -void Modrinth::ListModel::searchRequestFailed(QString reason) -{ - if(jobPtr->first()->m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 409){ - //409 Gone, notify user to update - QMessageBox::critical(nullptr, tr("Error"), tr("Modrinth API version too old!\nPlease update PolyMC!")); - //self-destruct - ((ModDownloadDialog *)((ModrinthPage *)parent())->parentWidget())->reject(); - } - jobPtr.reset(); - - if(searchState == ResetRequested) { - beginResetModel(); - modpacks.clear(); - endResetModel(); - - nextSearchOffset = 0; - performPaginatedSearch(); - } else { - searchState = Finished; - } -} - -} - +} // namespace Modrinth diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h index 20661412..73492356 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h @@ -2,78 +2,36 @@ #include -#include -#include -#include #include -#include #include +#include +#include #include #include -#include +#include +#include -#include #include +#include -#include -#include "modplatform/modrinth/ModrinthPackIndex.h" #include "BaseInstance.h" #include "ModrinthPage.h" +#include "modplatform/modrinth/ModrinthPackIndex.h" namespace Modrinth { - -typedef QMap LogoMap; typedef std::function LogoCallback; -class ListModel : public QAbstractListModel -{ +class ListModel : public ModPlatform::ListModel { Q_OBJECT -public: - ListModel(ModrinthPage *parent); + public: + ListModel(ModrinthPage* parent); virtual ~ListModel(); - int rowCount(const QModelIndex &parent) const override; - int columnCount(const QModelIndex &parent) const override; - QVariant data(const QModelIndex &index, int role) const override; - Qt::ItemFlags flags(const QModelIndex &index) const override; - bool canFetchMore(const QModelIndex & parent) const override; - void fetchMore(const QModelIndex & parent) override; - - void getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback); - void searchWithTerm(const QString &term, const int sort); - -private slots: - void performPaginatedSearch(); - - void logoFailed(QString logo); - void logoLoaded(QString logo, QIcon out); - - void searchRequestFinished(); - void searchRequestFailed(QString reason); - -private: - void requestLogo(QString file, QString url); - -private: - QList modpacks; - QStringList m_failedLogos; - QStringList m_loadingLogos; - LogoMap m_logoMap; - QMap waitingCallbacks; - - QString currentSearchTerm; - int currentSort = 0; - int nextSearchOffset = 0; - enum SearchState { - None, - CanPossiblyFetchMore, - ResetRequested, - Finished - } searchState = None; - NetJob::Ptr jobPtr; - QByteArray response; + private slots: + void performPaginatedSearch() override; + void searchRequestFinished() override; }; -} +} // namespace Modrinth diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp index 4dfc8504..aa3efe55 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp @@ -1,5 +1,5 @@ #include "ModrinthPage.h" -#include "ui_ModrinthPage.h" +#include "ui_ModPage.h" #include @@ -12,194 +12,57 @@ #include "minecraft/PackProfile.h" #include "ui/dialogs/ModDownloadDialog.h" -ModrinthPage::ModrinthPage(ModDownloadDialog *dialog, BaseInstance *instance) - : QWidget(dialog), m_instance(instance), ui(new Ui::ModrinthPage), - dialog(dialog) { - ui->setupUi(this); - connect(ui->searchButton, &QPushButton::clicked, this, - &ModrinthPage::triggerSearch); - ui->searchEdit->installEventFilter(this); - listModel = new Modrinth::ListModel(this); - ui->packView->setModel(listModel); - - ui->versionSelectionBox->view()->setVerticalScrollBarPolicy( - Qt::ScrollBarAsNeeded); - ui->versionSelectionBox->view()->parentWidget()->setMaximumHeight(300); - - // index is used to set the sorting with the modrinth api - ui->sortByBox->addItem(tr("Sort by Relevence")); - ui->sortByBox->addItem(tr("Sort by Downloads")); - ui->sortByBox->addItem(tr("Sort by Follows")); - ui->sortByBox->addItem(tr("Sort by last updated")); - ui->sortByBox->addItem(tr("Sort by newest")); - - connect(ui->sortByBox, SIGNAL(currentIndexChanged(int)), this, - SLOT(triggerSearch())); - connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, - this, &ModrinthPage::onSelectionChanged); - connect(ui->versionSelectionBox, &QComboBox::currentTextChanged, this, - &ModrinthPage::onVersionSelectionChanged); - connect(ui->modSelectionButton, &QPushButton::clicked, this, - &ModrinthPage::onModSelected); -} - -ModrinthPage::~ModrinthPage() { delete ui; } - -bool ModrinthPage::eventFilter(QObject *watched, QEvent *event) { - if (watched == ui->searchEdit && event->type() == QEvent::KeyPress) { - QKeyEvent *keyEvent = static_cast(event); - if (keyEvent->key() == Qt::Key_Return) { - triggerSearch(); - keyEvent->accept(); - return true; - } - } - return QWidget::eventFilter(watched, event); +ModrinthPage::ModrinthPage(ModDownloadDialog* dialog, BaseInstance* instance) + : ModPage(dialog, instance) +{ + listModel = new Modrinth::ListModel(this); + ui->packView->setModel(listModel); + + // index is used to set the sorting with the modrinth api + ui->sortByBox->addItem(tr("Sort by Relevence")); + ui->sortByBox->addItem(tr("Sort by Downloads")); + ui->sortByBox->addItem(tr("Sort by Follows")); + ui->sortByBox->addItem(tr("Sort by last updated")); + ui->sortByBox->addItem(tr("Sort by newest")); + + // sometimes Qt just ignores virtual slots and doesn't work as intended it seems, + // so it's best not to connect them in the parent's contructor... + connect(ui->sortByBox, SIGNAL(currentIndexChanged(int)), this, SLOT(triggerSearch())); + connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &ModrinthPage::onSelectionChanged); + connect(ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &ModrinthPage::onVersionSelectionChanged); + connect(ui->modSelectionButton, &QPushButton::clicked, this, &ModrinthPage::onModSelected); } bool ModrinthPage::shouldDisplay() const { return true; } -void ModrinthPage::openedImpl() { - updateSelectionButton(); - triggerSearch(); -} - -void ModrinthPage::triggerSearch() { - listModel->searchWithTerm(ui->searchEdit->text(), - ui->sortByBox->currentIndex()); -} - -void ModrinthPage::onSelectionChanged(QModelIndex first, QModelIndex second) { - ui->versionSelectionBox->clear(); - - if (!first.isValid()) { - return; - } - - current = listModel->data(first, Qt::UserRole).value(); - QString text = ""; - QString name = current.name; - - if (current.websiteUrl.isEmpty()) - text = name; - else - text = "" + name + ""; - text += "
" + tr(" by ") + "" + - current.authors[0].name + "

"; - ui->packDescription->setHtml(text + current.description); - - if (!current.versionsLoaded) { - qDebug() << "Loading Modrinth mod versions"; - - ui->modSelectionButton->setText(tr("Loading versions...")); - ui->modSelectionButton->setEnabled(false); - - auto netJob = - new NetJob(QString("Modrinth::ModVersions(%1)").arg(current.name), - APPLICATION->network()); - auto response = new QByteArray(); - QString addonId = current.addonId.toString(); - netJob->addNetAction(Net::Download::makeByteArray( - QString("https://api.modrinth.com/v2/project/%1/version").arg(addonId), - response)); - - QObject::connect(netJob, &NetJob::succeeded, this, [this, response, addonId] { - if(addonId != current.addonId){ - return; - } - QJsonParseError parse_error; - QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from Modrinth at " - << parse_error.offset +void ModrinthPage::onModVersionSucceed(ModPage* instance, QByteArray* response, QString addonId) +{ + if (addonId != current.addonId) { return; } + QJsonParseError parse_error; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from Modrinth at " << parse_error.offset << " reason: " << parse_error.errorString(); qWarning() << *response; return; - } - QJsonArray arr = doc.array(); - try { - Modrinth::loadIndexedPackVersions(current, arr, APPLICATION->network(), - m_instance); - } catch (const JSONValidationError &e) { + } + QJsonArray arr = doc.array(); + try { + Modrinth::loadIndexedPackVersions(current, arr, APPLICATION->network(), m_instance); + } catch (const JSONValidationError& e) { qDebug() << *response; qWarning() << "Error while reading Modrinth mod version: " << e.cause(); - } - auto packProfile = ((MinecraftInstance *)m_instance)->getPackProfile(); - QString mcVersion = packProfile->getComponentVersion("net.minecraft"); - QString loaderString = - (packProfile->getComponentVersion("net.minecraftforge").isEmpty()) - ? "fabric" - : "forge"; - for (int i = 0; i < current.versions.size(); i++) { + } + auto packProfile = ((MinecraftInstance*)m_instance)->getPackProfile(); + QString mcVersion = packProfile->getComponentVersion("net.minecraft"); + QString loaderString = (packProfile->getComponentVersion("net.minecraftforge").isEmpty()) ? "fabric" : "forge"; + for (int i = 0; i < current.versions.size(); i++) { auto version = current.versions[i]; - if (!version.mcVersion.contains(mcVersion) || - !version.loaders.contains(loaderString)) { - continue; - } + if (!version.mcVersion.contains(mcVersion) || !version.loaders.contains(loaderString)) { continue; } ui->versionSelectionBox->addItem(version.version, QVariant(i)); - } - if (ui->versionSelectionBox->count() == 0) { - ui->versionSelectionBox->addItem(tr("No Valid Version found !"), - QVariant(-1)); - } - - ui->modSelectionButton->setText(tr("Cannot select invalid version :(")); - updateSelectionButton(); - }); - - QObject::connect(netJob, &NetJob::finished, this, [response, netJob] { - netJob->deleteLater(); - delete response; - }); - - netJob->start(); - } else { - for (int i = 0; i < current.versions.size(); i++) { - ui->versionSelectionBox->addItem(current.versions[i].version, - QVariant(i)); - } - if (ui->versionSelectionBox->count() == 0) { - ui->versionSelectionBox->addItem(tr("No Valid Version found !"), - QVariant(-1)); } + if (ui->versionSelectionBox->count() == 0) { ui->versionSelectionBox->addItem(tr("No Valid Version found !"), QVariant(-1)); } + ui->modSelectionButton->setText(tr("Cannot select invalid version :(")); updateSelectionButton(); - } -} - -void ModrinthPage::updateSelectionButton() { - if (!isOpened || selectedVersion < 0) { - ui->modSelectionButton->setEnabled(false); - return; - } - - ui->modSelectionButton->setEnabled(true); - auto &version = current.versions[selectedVersion]; - if (!dialog->isModSelected(current.name, version.fileName)) { - ui->modSelectionButton->setText(tr("Select mod for download")); - } else { - ui->modSelectionButton->setText(tr("Deselect mod for download")); - } -} - -void ModrinthPage::onVersionSelectionChanged(QString data) { - if (data.isNull() || data.isEmpty()) { - selectedVersion = -1; - return; - } - selectedVersion = ui->versionSelectionBox->currentData().toInt(); - updateSelectionButton(); -} - -void ModrinthPage::onModSelected() { - auto &version = current.versions[selectedVersion]; - if (dialog->isModSelected(current.name, version.fileName)) { - dialog->removeSelectedMod(current.name); - } else { - dialog->addSelectedMod(current.name, - new ModDownloadTask(version.downloadUrl, - version.fileName, dialog->mods)); - } - - updateSelectionButton(); } diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h index 1d725d47..41c6c31d 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h @@ -1,68 +1,24 @@ #pragma once -#include +#include "ui/pages/modplatform/ModPage.h" -#include "ui/pages/BasePage.h" -#include -#include "tasks/Task.h" -#include "modplatform/modrinth/ModrinthPackIndex.h" - -namespace Ui -{ -class ModrinthPage; -} - -class ModDownloadDialog; - -namespace Modrinth { - class ListModel; -} - -class ModrinthPage : public QWidget, public BasePage -{ +class ModrinthPage : public ModPage { Q_OBJECT -public: - explicit ModrinthPage(ModDownloadDialog *dialog, BaseInstance *instance); - virtual ~ModrinthPage(); - virtual QString displayName() const override - { - return tr("Modrinth"); - } - virtual QIcon icon() const override - { - return APPLICATION->getThemedIcon("modrinth"); - } - virtual QString id() const override - { - return "modrinth"; - } - virtual QString helpPage() const override - { - return "Modrinth-platform"; - } - virtual bool shouldDisplay() const override; - - void openedImpl() override; - - bool eventFilter(QObject * watched, QEvent * event) override; - - BaseInstance *m_instance; + public: + explicit ModrinthPage(ModDownloadDialog* dialog, BaseInstance* instance); + virtual ~ModrinthPage() = default; -private: - void updateSelectionButton(); + inline QString displayName() const override { return tr("Modrinth"); } + inline QIcon icon() const override { return APPLICATION->getThemedIcon("modrinth"); } + inline QString id() const override { return "modrinth"; } + inline QString helpPage() const override { return "Modrinth-platform"; } -private slots: - void triggerSearch(); - void onSelectionChanged(QModelIndex first, QModelIndex second); - void onVersionSelectionChanged(QString data); - void onModSelected(); + inline QString debugName() const override { return tr("Modrinth"); } + inline QString metaEntryBase() const override { return "ModrinthPacks"; }; -private: - Ui::ModrinthPage *ui = nullptr; - ModDownloadDialog* dialog = nullptr; - Modrinth::ListModel* listModel = nullptr; - ModPlatform::IndexedPack current; + bool shouldDisplay() const override; - int selectedVersion = -1; + private: + void onModVersionSucceed(ModPage*, QByteArray*, QString) override; }; diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.ui b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.ui deleted file mode 100644 index d0a8b8f7..00000000 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.ui +++ /dev/null @@ -1,97 +0,0 @@ - - - ModrinthPage - - - - 0 - 0 - 837 - 685 - - - - - - - - - true - - - true - - - - - - - Qt::ScrollBarAlwaysOff - - - true - - - - 48 - 48 - - - - - - - - - - Search - - - - - - - Search and filter ... - - - - - - - - - - - - Version selected: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - Select mod for download - - - - - - - - - searchEdit - searchButton - packView - packDescription - sortByBox - versionSelectionBox - - - - -- cgit From 2d68308d4920be4c28a73d7646814765eee7b7a2 Mon Sep 17 00:00:00 2001 From: flow Date: Wed, 2 Mar 2022 23:01:23 -0300 Subject: refactor: move url creation for mods to modplatform/ Moves all things related to creating the URLs of the mod platforms that go to network tasks to a single place, so that: 1. Maintaining and fixing eventual issues is more straightforward. 2. Makes it possible to factor out more common code between the different modplatform pages --- launcher/modplatform/ModAPI.h | 12 ++++++ launcher/modplatform/flame/FlameAPI.h | 27 ++++++++++++++ launcher/modplatform/modrinth/ModrinthAPI.h | 25 +++++++++++++ .../modplatform/modrinth/ModrinthPackIndex.cpp | 5 ++- launcher/ui/pages/modplatform/ModModel.cpp | 20 ++++++++++ launcher/ui/pages/modplatform/ModModel.h | 7 +++- launcher/ui/pages/modplatform/ModPage.cpp | 9 +---- launcher/ui/pages/modplatform/ModPage.h | 2 + .../ui/pages/modplatform/flame/FlameModModel.cpp | 43 ++++------------------ .../ui/pages/modplatform/flame/FlameModModel.h | 4 +- launcher/ui/pages/modplatform/flame/FlameModPage.h | 6 +++ .../pages/modplatform/modrinth/ModrinthModel.cpp | 39 ++++---------------- .../ui/pages/modplatform/modrinth/ModrinthModel.h | 4 +- .../ui/pages/modplatform/modrinth/ModrinthPage.h | 6 +++ 14 files changed, 130 insertions(+), 79 deletions(-) create mode 100644 launcher/modplatform/ModAPI.h create mode 100644 launcher/modplatform/flame/FlameAPI.h create mode 100644 launcher/modplatform/modrinth/ModrinthAPI.h (limited to 'launcher/ui/pages/modplatform/flame/FlameModModel.cpp') diff --git a/launcher/modplatform/ModAPI.h b/launcher/modplatform/ModAPI.h new file mode 100644 index 00000000..e60fa8e0 --- /dev/null +++ b/launcher/modplatform/ModAPI.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +class ModAPI { + public: + virtual ~ModAPI() = default; + + inline virtual QString getModSearchURL(int, QString, QString, bool, QString) const { return ""; }; + inline virtual QString getVersionsURL(const QString& addonId) const { return ""; }; + inline virtual QString getAuthorURL(const QString& name) const { return ""; }; +}; diff --git a/launcher/modplatform/flame/FlameAPI.h b/launcher/modplatform/flame/FlameAPI.h new file mode 100644 index 00000000..6e2b9e25 --- /dev/null +++ b/launcher/modplatform/flame/FlameAPI.h @@ -0,0 +1,27 @@ +#pragma once + +#include "modplatform/ModAPI.h" + +class FlameAPI : public ModAPI { + public: + inline QString getModSearchURL(int index, QString searchFilter, QString sort, bool fabricCompatible, QString version) const override + { + return QString("https://addons-ecs.forgesvc.net/api/v2/addon/search?" + "gameId=432&" "categoryId=0&" "sectionId=6&" + + "index=%1&" "pageSize=25&" "searchFilter=%2&" + "sort=%3&" "modLoaderType=%4&" "gameVersion=%5") + .arg(index) + .arg(searchFilter) + .arg(sort) + .arg(fabricCompatible ? 4 : 1) // Enum: https://docs.curseforge.com/?http#tocS_ModLoaderType + .arg(version); + }; + + inline QString getVersionsURL(const QString& addonId) const override + { + return QString("https://addons-ecs.forgesvc.net/api/v2/addon/%1/files").arg(addonId); + }; + + inline QString getAuthorURL(const QString& name) const override { return ""; }; +}; diff --git a/launcher/modplatform/modrinth/ModrinthAPI.h b/launcher/modplatform/modrinth/ModrinthAPI.h new file mode 100644 index 00000000..4ae8b8f9 --- /dev/null +++ b/launcher/modplatform/modrinth/ModrinthAPI.h @@ -0,0 +1,25 @@ +#pragma once + +#include "modplatform/ModAPI.h" + +class ModrinthAPI : public ModAPI { + public: + inline QString getModSearchURL(int offset, QString query, QString sort, bool fabricCompatible, QString version) const override + { + return QString("https://api.modrinth.com/v2/search?" + "offset=%1&" "limit=25&" "query=%2&" "index=%3&" + "facets=[[\"categories:%4\"],[\"versions:%5\"],[\"project_type:mod\"]]") + .arg(offset) + .arg(query) + .arg(sort) + .arg(fabricCompatible ? "fabric" : "forge") + .arg(version); + }; + + inline QString getVersionsURL(const QString& addonId) const override + { + return QString("https://api.modrinth.com/v2/project/%1/version").arg(addonId); + }; + + inline QString getAuthorURL(const QString& name) const override { return "https://modrinth.com/user/" + name; }; +}; diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index a59186f7..02aac34d 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -1,10 +1,13 @@ #include "ModrinthPackIndex.h" +#include "ModrinthAPI.h" #include "Json.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" #include "net/NetJob.h" +static ModrinthAPI api; + void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj) { pack.addonId = Json::requireString(obj, "project_id"); @@ -17,7 +20,7 @@ void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj) ModPlatform::ModpackAuthor modAuthor; modAuthor.name = Json::requireString(obj, "author"); - modAuthor.url = "https://modrinth.com/user/" + modAuthor.name; + modAuthor.url = api.getAuthorURL(modAuthor.name); pack.authors.append(modAuthor); } diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index 5bd7e33e..481f1c56 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -1,6 +1,8 @@ #include "ModModel.h" #include "ModPage.h" +#include "minecraft/MinecraftInstance.h" +#include "minecraft/PackProfile.h" #include "ui/dialogs/ModDownloadDialog.h" #include @@ -95,6 +97,24 @@ void ListModel::getLogo(const QString& logo, const QString& logoUrl, LogoCallbac } } +void ListModel::performPaginatedSearch() +{ + QString mcVersion = ((MinecraftInstance*)((ModPage*)parent())->m_instance)->getPackProfile()->getComponentVersion("net.minecraft"); + bool hasFabric = !((MinecraftInstance*)((ModPage*)parent())->m_instance) + ->getPackProfile() + ->getComponentVersion("net.fabricmc.fabric-loader") + .isEmpty(); + auto netJob = new NetJob(QString("%1::Search").arg(m_parent->debugName()), APPLICATION->network()); + auto searchUrl = m_parent->apiProvider()->getModSearchURL(nextSearchOffset, currentSearchTerm, getSorts()[currentSort], hasFabric, mcVersion); + + netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response)); + jobPtr = netJob; + jobPtr->start(); + + QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::searchRequestFinished); + QObject::connect(netJob, &NetJob::failed, this, &ListModel::searchRequestFailed); +} + void ListModel::searchWithTerm(const QString& term, const int sort) { if (currentSearchTerm == term && currentSearchTerm.isNull() == term.isNull() && currentSort == sort) { return; } diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h index ae8ceb7c..23e544f1 100644 --- a/launcher/ui/pages/modplatform/ModModel.h +++ b/launcher/ui/pages/modplatform/ModModel.h @@ -3,6 +3,7 @@ #include #include "modplatform/ModIndex.h" +#include "modplatform/ModAPI.h" #include "net/NetJob.h" class ModPage; @@ -30,15 +31,18 @@ class ListModel : public QAbstractListModel { void searchWithTerm(const QString& term, const int sort); protected slots: - virtual void performPaginatedSearch() = 0; virtual void searchRequestFinished() = 0; + void performPaginatedSearch(); + void logoFailed(QString logo); void logoLoaded(QString logo, QIcon out); void searchRequestFailed(QString reason); protected: + virtual const char** getSorts() const = 0; + void requestLogo(QString file, QString url); protected: @@ -56,5 +60,6 @@ class ListModel : public QAbstractListModel { enum SearchState { None, CanPossiblyFetchMore, ResetRequested, Finished } searchState = None; NetJob::Ptr jobPtr; QByteArray response; + }; } // namespace ModPlatform diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index 8af534a6..2d47e31c 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -101,13 +101,8 @@ void ModPage::onSelectionChanged(QModelIndex first, QModelIndex second) auto netJob = new NetJob(QString("%1::ModVersions(%2)").arg(debugName()).arg(current.name), APPLICATION->network()); auto response = new QByteArray(); QString addonId = current.addonId.toString(); - //FIXME - if(debugName() == "Modrinth") - netJob->addNetAction( - Net::Download::makeByteArray(QString("https://api.modrinth.com/v2/project/%1/version").arg(addonId), response)); - else - netJob->addNetAction( - Net::Download::makeByteArray(QString("https://addons-ecs.forgesvc.net/api/v2/addon/%1/files").arg(addonId), response)); + + netJob->addNetAction(Net::Download::makeByteArray(apiProvider()->getVersionsURL(addonId), response)); QObject::connect(netJob, &NetJob::succeeded, this, [this, response, addonId]{ onModVersionSucceed(this, response, addonId); diff --git a/launcher/ui/pages/modplatform/ModPage.h b/launcher/ui/pages/modplatform/ModPage.h index c0102549..4657bc5e 100644 --- a/launcher/ui/pages/modplatform/ModPage.h +++ b/launcher/ui/pages/modplatform/ModPage.h @@ -3,6 +3,7 @@ #include #include +#include "modplatform/ModAPI.h" #include "modplatform/ModIndex.h" #include "tasks/Task.h" #include "ui/pages/BasePage.h" @@ -30,6 +31,7 @@ class ModPage : public QWidget, public BasePage { inline virtual QString metaEntryBase() const = 0; virtual bool shouldDisplay() const override = 0; + virtual const ModAPI* apiProvider() const = 0; void openedImpl() override; bool eventFilter(QObject* watched, QEvent* event) override; diff --git a/launcher/ui/pages/modplatform/flame/FlameModModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModModel.cpp index 5ab6672f..283f9ce7 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModModel.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModModel.cpp @@ -1,6 +1,5 @@ #include "FlameModModel.h" #include "FlameModPage.h" -#include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" #include @@ -11,41 +10,6 @@ ListModel::ListModel(FlameModPage* parent) : ModPlatform::ListModel(parent) {} ListModel::~ListModel() {} -const char* sorts[6]{ "Featured", "Popularity", "LastUpdated", "Name", "Author", "TotalDownloads" }; - -void ListModel::performPaginatedSearch() -{ - QString mcVersion = ((MinecraftInstance*)((FlameModPage*)parent())->m_instance)->getPackProfile()->getComponentVersion("net.minecraft"); - bool hasFabric = !((MinecraftInstance*)((FlameModPage*)parent())->m_instance) - ->getPackProfile() - ->getComponentVersion("net.fabricmc.fabric-loader") - .isEmpty(); - auto netJob = new NetJob("Flame::Search", APPLICATION->network()); - auto searchUrl = QString( - "https://addons-ecs.forgesvc.net/api/v2/addon/search?" - "gameId=432&" - "categoryId=0&" - "sectionId=6&" - - "index=%1&" - "pageSize=25&" - "searchFilter=%2&" - "sort=%3&" - "modLoaderType=%4&" - "gameVersion=%5") - .arg(nextSearchOffset) - .arg(currentSearchTerm) - .arg(sorts[currentSort]) - .arg(hasFabric ? 4 : 1) // Enum: https://docs.curseforge.com/?http#tocS_ModLoaderType - .arg(mcVersion); - - netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response)); - jobPtr = netJob; - jobPtr->start(); - - QObject::connect(netJob, &NetJob::succeeded, this, &FlameMod::ListModel::searchRequestFinished); - QObject::connect(netJob, &NetJob::failed, this, &ListModel::searchRequestFailed); -} void FlameMod::ListModel::searchRequestFinished() { @@ -87,4 +51,11 @@ void FlameMod::ListModel::searchRequestFinished() endInsertRows(); } +const char* sorts[6]{ "Featured", "Popularity", "LastUpdated", "Name", "Author", "TotalDownloads" }; + +const char** FlameMod::ListModel::getSorts() const +{ + return sorts; +} + } // namespace FlameMod diff --git a/launcher/ui/pages/modplatform/flame/FlameModModel.h b/launcher/ui/pages/modplatform/flame/FlameModModel.h index a585331d..ae919e63 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModModel.h +++ b/launcher/ui/pages/modplatform/flame/FlameModModel.h @@ -30,8 +30,10 @@ class ListModel : public ModPlatform::ListModel { virtual ~ListModel(); private slots: - void performPaginatedSearch() override; void searchRequestFinished() override; + + private: + const char** getSorts() const override; }; } // namespace Modrinth diff --git a/launcher/ui/pages/modplatform/flame/FlameModPage.h b/launcher/ui/pages/modplatform/flame/FlameModPage.h index 2daa155f..e7d98cb0 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModPage.h +++ b/launcher/ui/pages/modplatform/flame/FlameModPage.h @@ -2,6 +2,8 @@ #include "ui/pages/modplatform/ModPage.h" +#include "modplatform/flame/FlameAPI.h" + class FlameModPage : public ModPage { Q_OBJECT @@ -18,7 +20,11 @@ class FlameModPage : public ModPage { inline QString metaEntryBase() const override { return "FlameMods"; }; bool shouldDisplay() const override; + const ModAPI* apiProvider() const override { return &api; }; private: void onModVersionSucceed(ModPage*, QByteArray*, QString) override; + + private: + FlameAPI api; }; diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp index d2e86ef8..dc3d1469 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp @@ -1,7 +1,6 @@ #include "ModrinthModel.h" #include "ModrinthPage.h" #include "minecraft/MinecraftInstance.h" -#include "minecraft/PackProfile.h" #include @@ -11,37 +10,6 @@ ListModel::ListModel(ModrinthPage* parent) : ModPlatform::ListModel(parent) {} ListModel::~ListModel() {} -const char* sorts[5]{ "relevance", "downloads", "follows", "updated", "newest" }; - -void ListModel::performPaginatedSearch() -{ - QString mcVersion = ((MinecraftInstance*)((ModrinthPage*)parent())->m_instance)->getPackProfile()->getComponentVersion("net.minecraft"); - bool hasFabric = !((MinecraftInstance*)((ModrinthPage*)parent())->m_instance) - ->getPackProfile() - ->getComponentVersion("net.fabricmc.fabric-loader") - .isEmpty(); - auto netJob = new NetJob("Modrinth::Search", APPLICATION->network()); - auto searchUrl = QString( - "https://api.modrinth.com/v2/search?" - "offset=%1&" - "limit=25&" - "query=%2&" - "index=%3&" - "facets=[[\"categories:%4\"],[\"versions:%5\"],[\"project_type:mod\"]]") - .arg(nextSearchOffset) - .arg(currentSearchTerm) - .arg(sorts[currentSort]) - .arg(hasFabric ? "fabric" : "forge") - .arg(mcVersion); - - netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response)); - jobPtr = netJob; - jobPtr->start(); - - QObject::connect(netJob, &NetJob::succeeded, this, &Modrinth::ListModel::searchRequestFinished); - QObject::connect(netJob, &NetJob::failed, this, &ListModel::searchRequestFailed); -} - void Modrinth::ListModel::searchRequestFinished() { jobPtr.reset(); @@ -80,4 +48,11 @@ void Modrinth::ListModel::searchRequestFinished() endInsertRows(); } +const char* sorts[5]{ "relevance", "downloads", "follows", "updated", "newest" }; + +const char** Modrinth::ListModel::getSorts() const +{ + return sorts; +} + } // namespace Modrinth diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h index 73492356..b8937b50 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h @@ -30,8 +30,10 @@ class ListModel : public ModPlatform::ListModel { virtual ~ListModel(); private slots: - void performPaginatedSearch() override; void searchRequestFinished() override; + + private: + const char** getSorts() const override; }; } // namespace Modrinth diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h index 41c6c31d..504f42ad 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h @@ -2,6 +2,8 @@ #include "ui/pages/modplatform/ModPage.h" +#include "modplatform/modrinth/ModrinthAPI.h" + class ModrinthPage : public ModPage { Q_OBJECT @@ -18,7 +20,11 @@ class ModrinthPage : public ModPage { inline QString metaEntryBase() const override { return "ModrinthPacks"; }; bool shouldDisplay() const override; + const ModAPI* apiProvider() const override { return &api; }; private: void onModVersionSucceed(ModPage*, QByteArray*, QString) override; + + private: + ModrinthAPI api; }; -- cgit From f714adf6d2cc94f20ba37f2776d0d61e22267f0e Mon Sep 17 00:00:00 2001 From: flow Date: Mon, 7 Mar 2022 16:22:57 -0300 Subject: refactor: move NetJob away from ModModel to ModAPI This is done so that 1. ModAPI behaves more like an actual API instead of just a helper, and 2. Allows for more easily creating other mod providers that may or may not use network tasks (foreshadowing lol) --- launcher/modplatform/ModAPI.h | 35 +++--- launcher/modplatform/flame/FlameAPI.h | 93 +++++++++++++--- launcher/modplatform/modrinth/ModrinthAPI.h | 117 ++++++++++++++++----- launcher/ui/pages/modplatform/ModModel.cpp | 47 +++------ launcher/ui/pages/modplatform/ModModel.h | 13 ++- launcher/ui/pages/modplatform/ModPage.h | 2 +- .../ui/pages/modplatform/flame/FlameModModel.cpp | 10 +- .../ui/pages/modplatform/flame/FlameModModel.h | 2 +- .../ui/pages/modplatform/flame/FlameModPage.cpp | 12 +-- launcher/ui/pages/modplatform/flame/FlameModPage.h | 2 +- .../pages/modplatform/modrinth/ModrinthModel.cpp | 13 +-- .../ui/pages/modplatform/modrinth/ModrinthModel.h | 4 +- .../ui/pages/modplatform/modrinth/ModrinthPage.cpp | 15 +-- .../ui/pages/modplatform/modrinth/ModrinthPage.h | 2 +- 14 files changed, 231 insertions(+), 136 deletions(-) (limited to 'launcher/ui/pages/modplatform/flame/FlameModModel.cpp') diff --git a/launcher/modplatform/ModAPI.h b/launcher/modplatform/ModAPI.h index 4d22a63d..8503d7fc 100644 --- a/launcher/modplatform/ModAPI.h +++ b/launcher/modplatform/ModAPI.h @@ -1,21 +1,30 @@ #pragma once +#include #include +namespace ModPlatform { +class ListModel; +} + class ModAPI { - public: - virtual ~ModAPI() = default; + protected: + using CallerType = ModPlatform::ListModel; + + public: + virtual ~ModAPI() = default; + + // https://docs.curseforge.com/?http#tocS_ModLoaderType + enum ModLoaderType { Any = 0, Forge = 1, Cauldron = 2, LiteLoader = 3, Fabric = 4 }; - // https://docs.curseforge.com/?http#tocS_ModLoaderType - enum ModLoaderType { - Any = 0, - Forge = 1, - Cauldron = 2, - LiteLoader = 3, - Fabric = 4 - }; + struct SearchArgs { + int offset; + QString search; + QString sorting; + ModLoaderType mod_loader; + QString version; + }; - inline virtual QString getModSearchURL(int, QString, QString, ModLoaderType, QString) const { return ""; }; - inline virtual QString getVersionsURL(const QString& addonId) const { return ""; }; - inline virtual QString getAuthorURL(const QString& name) const { return ""; }; + inline virtual void searchMods(CallerType* caller, SearchArgs&& args) const {}; + inline virtual void getVersions(CallerType* caller, const QString& addonId, const QString& debugName = "") const {}; }; diff --git a/launcher/modplatform/flame/FlameAPI.h b/launcher/modplatform/flame/FlameAPI.h index b49aeb24..be88df65 100644 --- a/launcher/modplatform/flame/FlameAPI.h +++ b/launcher/modplatform/flame/FlameAPI.h @@ -1,28 +1,93 @@ #pragma once #include "modplatform/ModAPI.h" +#include "ui/pages/modplatform/ModModel.h" + +#include "Application.h" +#include "net/NetJob.h" class FlameAPI : public ModAPI { public: - - inline QString getModSearchURL(int index, QString searchFilter, QString sort, ModLoaderType modLoader, QString version) const override + inline void searchMods(CallerType* caller, SearchArgs&& args) const override { - return QString("https://addons-ecs.forgesvc.net/api/v2/addon/search?" - "gameId=432&" "categoryId=0&" "sectionId=6&" - - "index=%1&" "pageSize=25&" "searchFilter=%2&" - "sort=%3&" "modLoaderType=%4&" "gameVersion=%5") - .arg(index) - .arg(searchFilter) - .arg(sort) - .arg(modLoader) - .arg(version); + auto netJob = new NetJob(QString("Flame::Search"), APPLICATION->network()); + auto searchUrl = getModSearchURL(args); + + auto response = new QByteArray(); + netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), response)); + + QObject::connect(netJob, &NetJob::started, caller, [caller, netJob]{ caller->setActiveJob(netJob); }); + QObject::connect(netJob, &NetJob::failed, caller, &CallerType::searchRequestFailed); + QObject::connect(netJob, &NetJob::succeeded, caller, [caller, response] { + QJsonParseError parse_error; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from Modrinth at " << parse_error.offset + << " reason: " << parse_error.errorString(); + qWarning() << *response; + return; + } + + caller->searchRequestFinished(doc); + }); + + netJob->start(); + }; + + inline void getVersions(CallerType* caller, const QString& addonId, const QString& debugName = "Flame") const override + { + auto netJob = new NetJob(QString("%1::ModVersions(%2)").arg(debugName).arg(addonId), APPLICATION->network()); + auto response = new QByteArray(); + + netJob->addNetAction(Net::Download::makeByteArray(getVersionsURL(addonId), response)); + + QObject::connect(netJob, &NetJob::succeeded, caller, [response, debugName, caller, addonId] { + QJsonParseError parse_error; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from " << debugName << " at " << parse_error.offset + << " reason: " << parse_error.errorString(); + qWarning() << *response; + return; + } + + caller->versionRequestSucceeded(doc, addonId); + }); + + QObject::connect(netJob, &NetJob::finished, caller, [response, netJob] { + netJob->deleteLater(); + delete response; + }); + + netJob->start(); + }; + + private: + inline QString getModSearchURL(SearchArgs& args) const + { + return QString( + "https://addons-ecs.forgesvc.net/api/v2/addon/search?" + "gameId=432&" + "categoryId=0&" + "sectionId=6&" + + "index=%1&" + "pageSize=25&" + "searchFilter=%2&" + "sort=%3&" + "modLoaderType=%4&" + "gameVersion=%5") + .arg(args.offset) + .arg(args.search) + .arg(args.sorting) + .arg(args.mod_loader) + .arg(args.version); }; - inline QString getVersionsURL(const QString& addonId) const override + inline QString getVersionsURL(const QString& addonId) const { return QString("https://addons-ecs.forgesvc.net/api/v2/addon/%1/files").arg(addonId); }; - inline QString getAuthorURL(const QString& name) const override { return ""; }; + inline QString getAuthorURL(const QString& name) const { return ""; }; }; diff --git a/launcher/modplatform/modrinth/ModrinthAPI.h b/launcher/modplatform/modrinth/ModrinthAPI.h index 44a362c8..84cc561b 100644 --- a/launcher/modplatform/modrinth/ModrinthAPI.h +++ b/launcher/modplatform/modrinth/ModrinthAPI.h @@ -1,50 +1,111 @@ #pragma once #include "modplatform/ModAPI.h" +#include "ui/pages/modplatform/ModModel.h" + +#include "Application.h" +#include "net/NetJob.h" #include class ModrinthAPI : public ModAPI { public: - inline QString getModSearchURL(int offset, QString query, QString sort, ModLoaderType modLoader, QString version) const override - { - if(!validateModLoader(modLoader)){ + inline void searchMods(CallerType* caller, SearchArgs&& args) const override + { + auto netJob = new NetJob(QString("Modrinth::Search"), APPLICATION->network()); + auto searchUrl = getModSearchURL(args); + + auto response = new QByteArray(); + netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), response)); + + QObject::connect(netJob, &NetJob::started, caller, [caller, netJob]{ caller->setActiveJob(netJob); }); + QObject::connect(netJob, &NetJob::failed, caller, &CallerType::searchRequestFailed); + QObject::connect(netJob, &NetJob::succeeded, caller, [caller, response] { + QJsonParseError parse_error; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from Modrinth at " << parse_error.offset + << " reason: " << parse_error.errorString(); + qWarning() << *response; + return; + } + + caller->searchRequestFinished(doc); + }); + + netJob->start(); + }; + + inline void getVersions(CallerType* caller, const QString& addonId, const QString& debugName = "Modrinth") const override + { + auto netJob = new NetJob(QString("%1::ModVersions(%2)").arg(debugName).arg(addonId), APPLICATION->network()); + auto response = new QByteArray(); + + netJob->addNetAction(Net::Download::makeByteArray(getVersionsURL(addonId), response)); + + QObject::connect(netJob, &NetJob::succeeded, caller, [response, debugName, caller, addonId] { + QJsonParseError parse_error; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response from " << debugName << " at " << parse_error.offset + << " reason: " << parse_error.errorString(); + qWarning() << *response; + return; + } + + caller->versionRequestSucceeded(doc, addonId); + }); + + QObject::connect(netJob, &NetJob::finished, caller, [response, netJob] { + netJob->deleteLater(); + delete response; + }); + + netJob->start(); + }; + + inline QString getAuthorURL(const QString& name) const { return "https://modrinth.com/user/" + name; }; + + private: + inline QString getModSearchURL(SearchArgs& args) const + { + if (!validateModLoader(args.mod_loader)) { qWarning() << "Modrinth only have Forge and Fabric-compatible mods!"; return ""; } - return QString("https://api.modrinth.com/v2/search?" - "offset=%1&" "limit=25&" "query=%2&" "index=%3&" - "facets=[[\"categories:%4\"],[\"versions:%5\"],[\"project_type:mod\"]]") - .arg(offset) - .arg(query) - .arg(sort) - .arg(getModLoaderString(modLoader)) - .arg(version); + return QString( + "https://api.modrinth.com/v2/search?" + "offset=%1&" + "limit=25&" + "query=%2&" + "index=%3&" + "facets=[[\"categories:%4\"],[\"versions:%5\"],[\"project_type:mod\"]]") + .arg(args.offset) + .arg(args.search) + .arg(args.sorting) + .arg(getModLoaderString(args.mod_loader)) + .arg(args.version); }; - inline QString getVersionsURL(const QString& addonId) const override + inline QString getVersionsURL(const QString& addonId) const { return QString("https://api.modrinth.com/v2/project/%1/version").arg(addonId); }; - inline QString getAuthorURL(const QString& name) const override { return "https://modrinth.com/user/" + name; }; - - private: - inline bool validateModLoader(ModLoaderType modLoader) const{ - return modLoader == Any || modLoader == Forge || modLoader == Fabric; - } + inline bool validateModLoader(ModLoaderType modLoader) const { return modLoader == Any || modLoader == Forge || modLoader == Fabric; } - inline QString getModLoaderString(ModLoaderType modLoader) const{ - switch(modLoader){ - case Any: - return "fabric, forge"; - case Forge: - return "forge"; - case Fabric: - return "fabric"; - default: - return ""; + inline QString getModLoaderString(ModLoaderType modLoader) const + { + switch (modLoader) { + case Any: + return "fabric, forge"; + case Forge: + return "forge"; + case Fabric: + return "fabric"; + default: + return ""; } } }; diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index 5be578c1..705f384e 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -91,30 +91,16 @@ void ListModel::fetchMore(const QModelIndex& parent) void ListModel::getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback) { if (m_logoMap.contains(logo)) { - callback(APPLICATION->metacache()->resolveEntry(m_parent->metaEntryBase(), QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath()); + callback(APPLICATION->metacache() + ->resolveEntry(m_parent->metaEntryBase(), QString("logos/%1").arg(logo.section(".", 0, 0))) + ->getFullPath()); } else { requestLogo(logo, logoUrl); } } -void ListModel::requestModVersions(ModPlatform::IndexedPack const& current) -{ - auto netJob = new NetJob(QString("%1::ModVersions(%2)").arg(m_parent->debugName()).arg(current.name), APPLICATION->network()); - auto response = new QByteArray(); - QString addonId = current.addonId.toString(); - - netJob->addNetAction(Net::Download::makeByteArray(m_parent->apiProvider()->getVersionsURL(addonId), response)); - - QObject::connect(netJob, &NetJob::succeeded, this, [this, response, addonId]{ - m_parent->onRequestVersionsSucceeded(m_parent, response, addonId); - }); - - QObject::connect(netJob, &NetJob::finished, this, [response, netJob] { - netJob->deleteLater(); - delete response; - }); - - netJob->start(); +void ListModel::requestModVersions(ModPlatform::IndexedPack const& current) { + m_parent->apiProvider()->getVersions(this, current.addonId.toString(), m_parent->debugName()); } void ListModel::performPaginatedSearch() @@ -124,16 +110,9 @@ void ListModel::performPaginatedSearch() ->getPackProfile() ->getComponentVersion("net.fabricmc.fabric-loader") .isEmpty(); - auto netJob = new NetJob(QString("%1::Search").arg(m_parent->debugName()), APPLICATION->network()); - auto searchUrl = m_parent->apiProvider()->getModSearchURL( - nextSearchOffset, currentSearchTerm, getSorts()[currentSort], hasFabric ? ModAPI::Fabric : ModAPI::Forge, mcVersion); - - netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response)); - jobPtr = netJob; - jobPtr->start(); - QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::searchRequestFinished); - QObject::connect(netJob, &NetJob::failed, this, &ListModel::searchRequestFailed); + m_parent->apiProvider()->searchMods( + this, { nextSearchOffset, currentSearchTerm, getSorts()[currentSort], hasFabric ? ModAPI::Fabric : ModAPI::Forge, mcVersion }); } void ListModel::searchWithTerm(const QString& term, const int sort) @@ -160,9 +139,7 @@ void ListModel::searchRequestFailed(QString reason) if (jobPtr->first()->m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 409) { // 409 Gone, notify user to update QMessageBox::critical(nullptr, tr("Error"), - QString("%1 %2") - .arg(m_parent->displayName()) - .arg(tr("API version too old!\nPlease update PolyMC!"))); + QString("%1 %2").arg(m_parent->displayName()).arg(tr("API version too old!\nPlease update PolyMC!"))); // self-destruct ((ModDownloadDialog*)((ModPage*)parent())->parentWidget())->reject(); } @@ -180,11 +157,17 @@ void ListModel::searchRequestFailed(QString reason) } } +void ListModel::versionRequestSucceeded(QJsonDocument doc, QString addonId) +{ + m_parent->onRequestVersionsSucceeded(doc, addonId); +} + void ListModel::requestLogo(QString logo, QString url) { if (m_loadingLogos.contains(logo) || m_failedLogos.contains(logo)) { return; } - MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry(m_parent->metaEntryBase(), QString("logos/%1").arg(logo.section(".", 0, 0))); + MetaEntryPtr entry = + APPLICATION->metacache()->resolveEntry(m_parent->metaEntryBase(), QString("logos/%1").arg(logo.section(".", 0, 0))); auto job = new NetJob(QString("%1 Icon Download %2").arg(m_parent->debugName()).arg(logo), APPLICATION->network()); job->addNetAction(Net::Download::makeCached(QUrl(url), entry)); diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h index 64c17b4a..28bf05bb 100644 --- a/launcher/ui/pages/modplatform/ModModel.h +++ b/launcher/ui/pages/modplatform/ModModel.h @@ -1,9 +1,10 @@ #pragma once +#include #include -#include "modplatform/ModIndex.h" #include "modplatform/ModAPI.h" +#include "modplatform/ModIndex.h" #include "net/NetJob.h" class ModPage; @@ -26,6 +27,8 @@ class ListModel : public QAbstractListModel { QVariant data(const QModelIndex& index, int role) const override; Qt::ItemFlags flags(const QModelIndex& index) const override; + void setActiveJob(NetJob::Ptr ptr) { jobPtr = ptr; } + bool canFetchMore(const QModelIndex& parent) const override; void fetchMore(const QModelIndex& parent) override; @@ -34,10 +37,14 @@ class ListModel : public QAbstractListModel { virtual void requestModVersions(const ModPlatform::IndexedPack& current); - protected slots: - virtual void searchRequestFinished() = 0; + public slots: + virtual void searchRequestFinished(QJsonDocument& doc) = 0; void searchRequestFailed(QString reason); + void versionRequestSucceeded(QJsonDocument doc, QString addonId); + + protected slots: + void logoFailed(QString logo); void logoLoaded(QString logo, QIcon out); diff --git a/launcher/ui/pages/modplatform/ModPage.h b/launcher/ui/pages/modplatform/ModPage.h index e0d7c95c..aa0e8894 100644 --- a/launcher/ui/pages/modplatform/ModPage.h +++ b/launcher/ui/pages/modplatform/ModPage.h @@ -37,7 +37,7 @@ class ModPage : public QWidget, public BasePage { virtual bool shouldDisplay() const override = 0; const ModAPI* apiProvider() const { return api.get(); }; - virtual void onRequestVersionsSucceeded(ModPage*, QByteArray*, QString) = 0; + virtual void onRequestVersionsSucceeded(QJsonDocument&, QString) = 0; void openedImpl() override; bool eventFilter(QObject* watched, QEvent* event) override; diff --git a/launcher/ui/pages/modplatform/flame/FlameModModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModModel.cpp index 283f9ce7..cff29a79 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModModel.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModModel.cpp @@ -11,18 +11,10 @@ ListModel::ListModel(FlameModPage* parent) : ModPlatform::ListModel(parent) {} ListModel::~ListModel() {} -void FlameMod::ListModel::searchRequestFinished() +void FlameMod::ListModel::searchRequestFinished(QJsonDocument& doc) { jobPtr.reset(); - QJsonParseError parse_error; - QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error); - if(parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from Flame at " << parse_error.offset << " reason: " << parse_error.errorString(); - qWarning() << response; - return; - } - QList newList; auto packs = doc.array(); for(auto packRaw : packs) { diff --git a/launcher/ui/pages/modplatform/flame/FlameModModel.h b/launcher/ui/pages/modplatform/flame/FlameModModel.h index ae919e63..022ec32e 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModModel.h +++ b/launcher/ui/pages/modplatform/flame/FlameModModel.h @@ -30,7 +30,7 @@ class ListModel : public ModPlatform::ListModel { virtual ~ListModel(); private slots: - void searchRequestFinished() override; + void searchRequestFinished(QJsonDocument& doc) override; private: const char** getSorts() const override; diff --git a/launcher/ui/pages/modplatform/flame/FlameModPage.cpp b/launcher/ui/pages/modplatform/flame/FlameModPage.cpp index 6564265c..19f58280 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModPage.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModPage.cpp @@ -36,23 +36,17 @@ FlameModPage::FlameModPage(ModDownloadDialog* dialog, BaseInstance* instance) bool FlameModPage::shouldDisplay() const { return true; } -void FlameModPage::onRequestVersionsSucceeded(ModPage* instance, QByteArray* response, QString addonId) +void FlameModPage::onRequestVersionsSucceeded(QJsonDocument& doc, QString addonId) { if (addonId != current.addonId) { return; // wrong request } - QJsonParseError parse_error; - QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from Flame at " << parse_error.offset << " reason: " << parse_error.errorString(); - qWarning() << *response; - return; - } + QJsonArray arr = doc.array(); try { FlameMod::loadIndexedPackVersions(current, arr, APPLICATION->network(), m_instance); } catch (const JSONValidationError& e) { - qDebug() << *response; + qDebug() << doc; qWarning() << "Error while reading Flame mod version: " << e.cause(); } auto packProfile = ((MinecraftInstance*)m_instance)->getPackProfile(); diff --git a/launcher/ui/pages/modplatform/flame/FlameModPage.h b/launcher/ui/pages/modplatform/flame/FlameModPage.h index 9c6f0e6c..f15b51ec 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModPage.h +++ b/launcher/ui/pages/modplatform/flame/FlameModPage.h @@ -22,5 +22,5 @@ class FlameModPage : public ModPage { bool shouldDisplay() const override; private: - void onRequestVersionsSucceeded(ModPage*, QByteArray*, QString) override; + void onRequestVersionsSucceeded(QJsonDocument&, QString) override; }; diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp index dc3d1469..784b1128 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp @@ -10,19 +10,10 @@ ListModel::ListModel(ModrinthPage* parent) : ModPlatform::ListModel(parent) {} ListModel::~ListModel() {} -void Modrinth::ListModel::searchRequestFinished() +void Modrinth::ListModel::searchRequestFinished(QJsonDocument& doc) { jobPtr.reset(); - - QJsonParseError parse_error; - QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from Modrinth at " << parse_error.offset - << " reason: " << parse_error.errorString(); - qWarning() << response; - return; - } - + QList newList; auto packs = doc.object().value("hits").toArray(); for (auto packRaw : packs) { diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h index b8937b50..d095b18c 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h @@ -29,8 +29,8 @@ class ListModel : public ModPlatform::ListModel { ListModel(ModrinthPage* parent); virtual ~ListModel(); - private slots: - void searchRequestFinished() override; + public slots: + void searchRequestFinished(QJsonDocument& doc) override; private: const char** getSorts() const override; diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp index 944f8afb..fa703e38 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp @@ -35,22 +35,15 @@ ModrinthPage::ModrinthPage(ModDownloadDialog* dialog, BaseInstance* instance) bool ModrinthPage::shouldDisplay() const { return true; } -void ModrinthPage::onRequestVersionsSucceeded(ModPage* instance, QByteArray* response, QString addonId) +void ModrinthPage::onRequestVersionsSucceeded(QJsonDocument& response, QString addonId) { if (addonId != current.addonId) { return; } - QJsonParseError parse_error; - QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); - if (parse_error.error != QJsonParseError::NoError) { - qWarning() << "Error while parsing JSON response from Modrinth at " << parse_error.offset - << " reason: " << parse_error.errorString(); - qWarning() << *response; - return; - } - QJsonArray arr = doc.array(); + + QJsonArray arr = response.array(); try { Modrinth::loadIndexedPackVersions(current, arr, APPLICATION->network(), m_instance); } catch (const JSONValidationError& e) { - qDebug() << *response; + qDebug() << response; qWarning() << "Error while reading Modrinth mod version: " << e.cause(); } auto packProfile = ((MinecraftInstance*)m_instance)->getPackProfile(); diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h index 7b1d0a00..f6d1eef0 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h @@ -22,5 +22,5 @@ class ModrinthPage : public ModPage { bool shouldDisplay() const override; private: - void onRequestVersionsSucceeded(ModPage*, QByteArray*, QString) override; + void onRequestVersionsSucceeded(QJsonDocument&, QString) override; }; -- cgit From b131d3b2ecbe6a9be35088d8411927bcd30de896 Mon Sep 17 00:00:00 2001 From: flow Date: Mon, 7 Mar 2022 17:46:18 -0300 Subject: refactor: move more common code to base class Also removes unused imports and organize the ModModel header --- launcher/ui/pages/modplatform/ModModel.cpp | 56 +++++++++++++--------- launcher/ui/pages/modplatform/ModModel.h | 22 +++++---- .../ui/pages/modplatform/flame/FlameModModel.cpp | 48 +------------------ .../ui/pages/modplatform/flame/FlameModModel.h | 34 ++++--------- .../pages/modplatform/modrinth/ModrinthModel.cpp | 44 +---------------- .../ui/pages/modplatform/modrinth/ModrinthModel.h | 31 ++++-------- 6 files changed, 65 insertions(+), 170 deletions(-) (limited to 'launcher/ui/pages/modplatform/flame/FlameModModel.cpp') diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index 015fcf7d..b8b90f84 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -1,6 +1,6 @@ #include "ModModel.h" -#include "ModPage.h" +#include "Json.h" #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" #include "ui/dialogs/ModDownloadDialog.h" @@ -11,18 +11,6 @@ namespace ModPlatform { ListModel::ListModel(ModPage* parent) : QAbstractListModel(parent), m_parent(parent) {} -ListModel::~ListModel() {} - -int ListModel::rowCount(const QModelIndex& parent) const -{ - return modpacks.size(); -} - -int ListModel::columnCount(const QModelIndex& parent) const -{ - return 1; -} - QVariant ListModel::data(const QModelIndex& index, int role) const { int pos = index.row(); @@ -73,16 +61,6 @@ void ListModel::logoFailed(QString logo) m_loadingLogos.removeAll(logo); } -Qt::ItemFlags ListModel::flags(const QModelIndex& index) const -{ - return QAbstractListModel::flags(index); -} - -bool ListModel::canFetchMore(const QModelIndex& parent) const -{ - return searchState == CanPossiblyFetchMore; -} - void ListModel::fetchMore(const QModelIndex& parent) { if (parent.isValid()) return; @@ -140,6 +118,38 @@ void ListModel::searchWithTerm(const QString& term, const int sort) performPaginatedSearch(); } +void ListModel::searchRequestFinished(QJsonDocument& doc) +{ + jobPtr.reset(); + + QList newList; + auto packs = documentToArray(doc); + + for (auto packRaw : packs) { + auto packObj = packRaw.toObject(); + + ModPlatform::IndexedPack pack; + try { + loadIndexedPack(pack, packObj); + newList.append(pack); + } catch (const JSONValidationError& e) { + qWarning() << "Error while loading mod from " << m_parent->debugName() << ": " << e.cause(); + continue; + } + } + + if (packs.size() < 25) { + searchState = Finished; + } else { + nextSearchOffset += 25; + searchState = CanPossiblyFetchMore; + } + + beginInsertRows(QModelIndex(), modpacks.size(), modpacks.size() + newList.size() - 1); + modpacks.append(newList); + endInsertRows(); +} + void ListModel::searchRequestFailed(QString reason) { if (jobPtr->first()->m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() == 409) { diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h index e971149c..e0cc098d 100644 --- a/launcher/ui/pages/modplatform/ModModel.h +++ b/launcher/ui/pages/modplatform/ModModel.h @@ -18,29 +18,30 @@ class ListModel : public QAbstractListModel { public: ListModel(ModPage* parent); - virtual ~ListModel(); + virtual ~ListModel() = default; - int rowCount(const QModelIndex& parent) const override; - int columnCount(const QModelIndex& parent) const override; + inline int rowCount(const QModelIndex& parent) const override { return modpacks.size(); }; + inline int columnCount(const QModelIndex& parent) const override { return 1; }; + inline Qt::ItemFlags flags(const QModelIndex& index) const override { return QAbstractListModel::flags(index); }; QString debugName() const; /* Retrieve information from the model at a given index with the given role */ QVariant data(const QModelIndex& index, int role) const override; - Qt::ItemFlags flags(const QModelIndex& index) const override; - void setActiveJob(NetJob::Ptr ptr) { jobPtr = ptr; } + inline void setActiveJob(NetJob::Ptr ptr) { jobPtr = ptr; } - bool canFetchMore(const QModelIndex& parent) const override; + /* Ask the API for more information */ void fetchMore(const QModelIndex& parent) override; + void searchWithTerm(const QString& term, const int sort); + void requestModVersions(const ModPlatform::IndexedPack& current); void getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback); - void searchWithTerm(const QString& term, const int sort); - virtual void requestModVersions(const ModPlatform::IndexedPack& current); + inline bool canFetchMore(const QModelIndex& parent) const override { return searchState == CanPossiblyFetchMore; }; public slots: - virtual void searchRequestFinished(QJsonDocument& doc) = 0; + void searchRequestFinished(QJsonDocument& doc); void searchRequestFailed(QString reason); void versionRequestSucceeded(QJsonDocument doc, QString addonId); @@ -53,6 +54,8 @@ class ListModel : public QAbstractListModel { void performPaginatedSearch(); protected: + virtual void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) = 0; + virtual QJsonArray documentToArray(QJsonDocument& obj) const = 0; virtual const char** getSorts() const = 0; void requestLogo(QString file, QString url); @@ -73,6 +76,5 @@ class ListModel : public QAbstractListModel { enum SearchState { None, CanPossiblyFetchMore, ResetRequested, Finished } searchState = None; NetJob::Ptr jobPtr; - QByteArray response; }; } // namespace ModPlatform diff --git a/launcher/ui/pages/modplatform/flame/FlameModModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModModel.cpp index cff29a79..7588a714 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModModel.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModModel.cpp @@ -1,53 +1,7 @@ #include "FlameModModel.h" -#include "FlameModPage.h" -#include "minecraft/PackProfile.h" - -#include namespace FlameMod { -ListModel::ListModel(FlameModPage* parent) : ModPlatform::ListModel(parent) {} - -ListModel::~ListModel() {} - - -void FlameMod::ListModel::searchRequestFinished(QJsonDocument& doc) -{ - jobPtr.reset(); - - QList newList; - auto packs = doc.array(); - for(auto packRaw : packs) { - auto packObj = packRaw.toObject(); - - ModPlatform::IndexedPack pack; - try - { - FlameMod::loadIndexedPack(pack, packObj); - newList.append(pack); - } - catch(const JSONValidationError &e) - { - qWarning() << "Error while loading mod from Flame: " << e.cause(); - continue; - } - } - if(packs.size() < 25) { - searchState = Finished; - } else { - nextSearchOffset += 25; - searchState = CanPossiblyFetchMore; - } - beginInsertRows(QModelIndex(), modpacks.size(), modpacks.size() + newList.size() - 1); - modpacks.append(newList); - endInsertRows(); -} - -const char* sorts[6]{ "Featured", "Popularity", "LastUpdated", "Name", "Author", "TotalDownloads" }; - -const char** FlameMod::ListModel::getSorts() const -{ - return sorts; -} +const char* ListModel::sorts[6]{ "Featured", "Popularity", "LastUpdated", "Name", "Author", "TotalDownloads" }; } // namespace FlameMod diff --git a/launcher/ui/pages/modplatform/flame/FlameModModel.h b/launcher/ui/pages/modplatform/flame/FlameModModel.h index 022ec32e..204834c9 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModModel.h +++ b/launcher/ui/pages/modplatform/flame/FlameModModel.h @@ -1,39 +1,25 @@ #pragma once -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "BaseInstance.h" #include "FlameModPage.h" #include "modplatform/flame/FlameModIndex.h" namespace FlameMod { -typedef std::function LogoCallback; - class ListModel : public ModPlatform::ListModel { Q_OBJECT public: - ListModel(FlameModPage* parent); - virtual ~ListModel(); - - private slots: - void searchRequestFinished(QJsonDocument& doc) override; + ListModel(FlameModPage* parent) : ModPlatform::ListModel(parent) {} +; + virtual ~ListModel() = default; private: - const char** getSorts() const override; + void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override { FlameMod::loadIndexedPack(m, obj); }; + + QJsonArray documentToArray(QJsonDocument& obj) const override { return obj.array(); }; + + static const char* sorts[6]; + const char** getSorts() const override { return sorts; }; }; -} // namespace Modrinth +} // namespace FlameMod diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp index 784b1128..9361546e 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp @@ -1,49 +1,7 @@ #include "ModrinthModel.h" -#include "ModrinthPage.h" -#include "minecraft/MinecraftInstance.h" - -#include namespace Modrinth { -ListModel::ListModel(ModrinthPage* parent) : ModPlatform::ListModel(parent) {} - -ListModel::~ListModel() {} - -void Modrinth::ListModel::searchRequestFinished(QJsonDocument& doc) -{ - jobPtr.reset(); - - QList newList; - auto packs = doc.object().value("hits").toArray(); - for (auto packRaw : packs) { - auto packObj = packRaw.toObject(); - - ModPlatform::IndexedPack pack; - try { - Modrinth::loadIndexedPack(pack, packObj); - newList.append(pack); - } catch (const JSONValidationError& e) { - qWarning() << "Error while loading mod from Modrinth: " << e.cause(); - continue; - } - } - if (packs.size() < 25) { - searchState = Finished; - } else { - nextSearchOffset += 25; - searchState = CanPossiblyFetchMore; - } - beginInsertRows(QModelIndex(), modpacks.size(), modpacks.size() + newList.size() - 1); - modpacks.append(newList); - endInsertRows(); -} - -const char* sorts[5]{ "relevance", "downloads", "follows", "updated", "newest" }; - -const char** Modrinth::ListModel::getSorts() const -{ - return sorts; -} +const char* ListModel::sorts[5] { "relevance", "downloads", "follows", "updated", "newest" }; } // namespace Modrinth diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h index d095b18c..9137190d 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h @@ -1,39 +1,24 @@ #pragma once -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "BaseInstance.h" #include "ModrinthPage.h" #include "modplatform/modrinth/ModrinthPackIndex.h" namespace Modrinth { -typedef std::function LogoCallback; - class ListModel : public ModPlatform::ListModel { Q_OBJECT public: - ListModel(ModrinthPage* parent); - virtual ~ListModel(); - - public slots: - void searchRequestFinished(QJsonDocument& doc) override; + ListModel(ModrinthPage* parent) : ModPlatform::ListModel(parent){}; + virtual ~ListModel() = default; private: - const char** getSorts() const override; + void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override { Modrinth::loadIndexedPack(m, obj); }; + + QJsonArray documentToArray(QJsonDocument& obj) const override { return obj.object().value("hits").toArray(); }; + + static const char* sorts[5]; + const char** getSorts() const override { return sorts; }; }; } // namespace Modrinth -- cgit From 9c57b54a81a9026aa86a983a203df17c023eaa8d Mon Sep 17 00:00:00 2001 From: flow Date: Mon, 7 Mar 2022 19:29:59 -0300 Subject: refactor: move things around so that related things are close together This also adds some comments around ModModel.cpp and ModPage.cpp to add some ease of reading the code. Also move some things from headers to cpp files. --- launcher/ui/pages/modplatform/ModModel.cpp | 149 ++++++++++++--------- launcher/ui/pages/modplatform/ModModel.h | 4 +- launcher/ui/pages/modplatform/ModPage.cpp | 61 +++++++-- launcher/ui/pages/modplatform/ModPage.h | 6 +- .../ui/pages/modplatform/flame/FlameModModel.cpp | 17 +++ .../ui/pages/modplatform/flame/FlameModModel.h | 8 +- .../ui/pages/modplatform/flame/FlameModPage.cpp | 42 ++---- launcher/ui/pages/modplatform/flame/FlameModPage.h | 5 +- .../pages/modplatform/modrinth/ModrinthModel.cpp | 19 ++- .../ui/pages/modplatform/modrinth/ModrinthModel.h | 10 +- .../ui/pages/modplatform/modrinth/ModrinthPage.cpp | 39 +----- .../ui/pages/modplatform/modrinth/ModrinthPage.h | 5 +- 12 files changed, 200 insertions(+), 165 deletions(-) (limited to 'launcher/ui/pages/modplatform/flame/FlameModModel.cpp') diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index b8b90f84..6f3c6ce0 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -11,6 +11,24 @@ namespace ModPlatform { ListModel::ListModel(ModPage* parent) : QAbstractListModel(parent), m_parent(parent) {} +QString ListModel::debugName() const +{ + return m_parent->debugName(); +} + + +/******** Make data requests ********/ + +void ListModel::fetchMore(const QModelIndex& parent) +{ + if (parent.isValid()) return; + if (nextSearchOffset == 0) { + qWarning() << "fetchMore with 0 offset is wrong..."; + return; + } + performPaginatedSearch(); +} + QVariant ListModel::data(const QModelIndex& index, int role) const { int pos = index.row(); @@ -41,47 +59,6 @@ QVariant ListModel::data(const QModelIndex& index, int role) const return QVariant(); } -QString ListModel::debugName() const -{ - return m_parent->debugName(); -} - -void ListModel::logoLoaded(QString logo, QIcon out) -{ - m_loadingLogos.removeAll(logo); - m_logoMap.insert(logo, out); - for (int i = 0; i < modpacks.size(); i++) { - if (modpacks[i].logoName == logo) { emit dataChanged(createIndex(i, 0), createIndex(i, 0), { Qt::DecorationRole }); } - } -} - -void ListModel::logoFailed(QString logo) -{ - m_failedLogos.append(logo); - m_loadingLogos.removeAll(logo); -} - -void ListModel::fetchMore(const QModelIndex& parent) -{ - if (parent.isValid()) return; - if (nextSearchOffset == 0) { - qWarning() << "fetchMore with 0 offset is wrong..."; - return; - } - performPaginatedSearch(); -} - -void ListModel::getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback) -{ - if (m_logoMap.contains(logo)) { - callback(APPLICATION->metacache() - ->resolveEntry(m_parent->metaEntryBase(), QString("logos/%1").arg(logo.section(".", 0, 0))) - ->getFullPath()); - } else { - requestLogo(logo, logoUrl); - } -} - void ListModel::requestModVersions(ModPlatform::IndexedPack const& current) { m_parent->apiProvider()->getVersions(this, current.addonId.toString()); @@ -118,6 +95,60 @@ void ListModel::searchWithTerm(const QString& term, const int sort) performPaginatedSearch(); } +void ListModel::getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback) +{ + if (m_logoMap.contains(logo)) { + callback(APPLICATION->metacache() + ->resolveEntry(m_parent->metaEntryBase(), QString("logos/%1").arg(logo.section(".", 0, 0))) + ->getFullPath()); + } else { + requestLogo(logo, logoUrl); + } +} + +void ListModel::requestLogo(QString logo, QString url) +{ + if (m_loadingLogos.contains(logo) || m_failedLogos.contains(logo)) { return; } + + MetaEntryPtr entry = + APPLICATION->metacache()->resolveEntry(m_parent->metaEntryBase(), QString("logos/%1").arg(logo.section(".", 0, 0))); + auto job = new NetJob(QString("%1 Icon Download %2").arg(m_parent->debugName()).arg(logo), APPLICATION->network()); + job->addNetAction(Net::Download::makeCached(QUrl(url), entry)); + + auto fullPath = entry->getFullPath(); + QObject::connect(job, &NetJob::succeeded, this, [this, logo, fullPath, job] { + job->deleteLater(); + emit logoLoaded(logo, QIcon(fullPath)); + if (waitingCallbacks.contains(logo)) { waitingCallbacks.value(logo)(fullPath); } + }); + + QObject::connect(job, &NetJob::failed, this, [this, logo, job] { + job->deleteLater(); + emit logoFailed(logo); + }); + + job->start(); + m_loadingLogos.append(logo); +} + + +/******** Request callbacks ********/ + +void ListModel::logoLoaded(QString logo, QIcon out) +{ + m_loadingLogos.removeAll(logo); + m_logoMap.insert(logo, out); + for (int i = 0; i < modpacks.size(); i++) { + if (modpacks[i].logoName == logo) { emit dataChanged(createIndex(i, 0), createIndex(i, 0), { Qt::DecorationRole }); } + } +} + +void ListModel::logoFailed(QString logo) +{ + m_failedLogos.append(logo); + m_loadingLogos.removeAll(logo); +} + void ListModel::searchRequestFinished(QJsonDocument& doc) { jobPtr.reset(); @@ -175,32 +206,18 @@ void ListModel::searchRequestFailed(QString reason) void ListModel::versionRequestSucceeded(QJsonDocument doc, QString addonId) { - m_parent->onRequestVersionsSucceeded(doc, addonId); -} - -void ListModel::requestLogo(QString logo, QString url) -{ - if (m_loadingLogos.contains(logo) || m_failedLogos.contains(logo)) { return; } - - MetaEntryPtr entry = - APPLICATION->metacache()->resolveEntry(m_parent->metaEntryBase(), QString("logos/%1").arg(logo.section(".", 0, 0))); - auto job = new NetJob(QString("%1 Icon Download %2").arg(m_parent->debugName()).arg(logo), APPLICATION->network()); - job->addNetAction(Net::Download::makeCached(QUrl(url), entry)); - - auto fullPath = entry->getFullPath(); - QObject::connect(job, &NetJob::succeeded, this, [this, logo, fullPath, job] { - job->deleteLater(); - emit logoLoaded(logo, QIcon(fullPath)); - if (waitingCallbacks.contains(logo)) { waitingCallbacks.value(logo)(fullPath); } - }); - - QObject::connect(job, &NetJob::failed, this, [this, logo, job] { - job->deleteLater(); - emit logoFailed(logo); - }); + auto& current = m_parent->getCurrent(); + if (addonId != current.addonId) { return; } + + QJsonArray arr = doc.array(); + try { + loadIndexedPackVersions(current, arr); + } catch (const JSONValidationError& e) { + qDebug() << doc; + qWarning() << "Error while reading " << debugName() << " mod version: " << e.cause(); + } - job->start(); - m_loadingLogos.append(logo); + m_parent->updateModVersions(); } } // namespace ModPlatform diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h index e0cc098d..6c3ecc3d 100644 --- a/launcher/ui/pages/modplatform/ModModel.h +++ b/launcher/ui/pages/modplatform/ModModel.h @@ -36,6 +36,9 @@ class ListModel : public QAbstractListModel { void searchWithTerm(const QString& term, const int sort); void requestModVersions(const ModPlatform::IndexedPack& current); + virtual void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) = 0; + virtual void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) = 0; + void getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback); inline bool canFetchMore(const QModelIndex& parent) const override { return searchState == CanPossiblyFetchMore; }; @@ -54,7 +57,6 @@ class ListModel : public QAbstractListModel { void performPaginatedSearch(); protected: - virtual void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) = 0; virtual QJsonArray documentToArray(QJsonDocument& obj) const = 0; virtual const char** getSorts() const = 0; diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index a57f2903..94cf4bcf 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -3,6 +3,8 @@ #include +#include "minecraft/MinecraftInstance.h" +#include "minecraft/PackProfile.h" #include "ui/dialogs/ModDownloadDialog.h" ModPage::ModPage(ModDownloadDialog* dialog, BaseInstance* instance, ModAPI* api) @@ -22,6 +24,9 @@ ModPage::~ModPage() delete ui; } + +/******** Qt things ********/ + void ModPage::openedImpl() { updateSelectionButton(); @@ -41,21 +46,8 @@ bool ModPage::eventFilter(QObject* watched, QEvent* event) return QWidget::eventFilter(watched, event); } -void ModPage::updateSelectionButton() -{ - if (!isOpened || selectedVersion < 0) { - ui->modSelectionButton->setEnabled(false); - return; - } - ui->modSelectionButton->setEnabled(true); - auto& version = current.versions[selectedVersion]; - if (!dialog->isModSelected(current.name, version.fileName)) { - ui->modSelectionButton->setText(tr("Select mod for download")); - } else { - ui->modSelectionButton->setText(tr("Deselect mod for download")); - } -} +/******** Callbacks to events in the UI (set up in the derived classes) ********/ void ModPage::triggerSearch() { @@ -130,3 +122,44 @@ void ModPage::onModSelected() updateSelectionButton(); } + + +/******** Make changes to the UI ********/ + +void ModPage::updateModVersions() +{ + auto packProfile = (static_cast(m_instance))->getPackProfile(); + + QString mcVersion = packProfile->getComponentVersion("net.minecraft"); + QString loaderString = (packProfile->getComponentVersion("net.minecraftforge").isEmpty()) ? "fabric" : "forge"; + + for (int i = 0; i < current.versions.size(); i++) { + auto version = current.versions[i]; + //NOTE: Flame doesn't care about loaderString, so passing it changes nothing. + if (!validateVersion(version, mcVersion, loaderString)) { + continue; + } + ui->versionSelectionBox->addItem(version.version, QVariant(i)); + } + if (ui->versionSelectionBox->count() == 0) { ui->versionSelectionBox->addItem(tr("No valid version found!"), QVariant(-1)); } + + ui->modSelectionButton->setText(tr("Cannot select invalid version :(")); + updateSelectionButton(); +} + + +void ModPage::updateSelectionButton() +{ + if (!isOpened || selectedVersion < 0) { + ui->modSelectionButton->setEnabled(false); + return; + } + + ui->modSelectionButton->setEnabled(true); + auto& version = current.versions[selectedVersion]; + if (!dialog->isModSelected(current.name, version.fileName)) { + ui->modSelectionButton->setText(tr("Select mod for download")); + } else { + ui->modSelectionButton->setText(tr("Deselect mod for download")); + } +} diff --git a/launcher/ui/pages/modplatform/ModPage.h b/launcher/ui/pages/modplatform/ModPage.h index aa0e8894..de66b3b0 100644 --- a/launcher/ui/pages/modplatform/ModPage.h +++ b/launcher/ui/pages/modplatform/ModPage.h @@ -35,9 +35,12 @@ class ModPage : public QWidget, public BasePage { virtual bool shouldDisplay() const override = 0; + virtual bool validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, QString loaderVer = "") const = 0; + const ModAPI* apiProvider() const { return api.get(); }; - virtual void onRequestVersionsSucceeded(QJsonDocument&, QString) = 0; + ModPlatform::IndexedPack& getCurrent() { return current; } + void updateModVersions(); void openedImpl() override; bool eventFilter(QObject* watched, QEvent* event) override; @@ -45,7 +48,6 @@ class ModPage : public QWidget, public BasePage { BaseInstance* m_instance; protected: - void updateSelectionButton(); protected slots: diff --git a/launcher/ui/pages/modplatform/flame/FlameModModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModModel.cpp index 7588a714..ce2f74f1 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModModel.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModModel.cpp @@ -1,7 +1,24 @@ #include "FlameModModel.h" +#include "modplatform/flame/FlameModIndex.h" + namespace FlameMod { const char* ListModel::sorts[6]{ "Featured", "Popularity", "LastUpdated", "Name", "Author", "TotalDownloads" }; +void ListModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) +{ + FlameMod::loadIndexedPack(m, obj); +}; + +void ListModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) +{ + FlameMod::loadIndexedPackVersions(m, arr, APPLICATION->network(), m_parent->m_instance); +}; + +QJsonArray ListModel::documentToArray(QJsonDocument& obj) const +{ + return obj.array(); +} + } // namespace FlameMod diff --git a/launcher/ui/pages/modplatform/flame/FlameModModel.h b/launcher/ui/pages/modplatform/flame/FlameModModel.h index 204834c9..cf3042ed 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModModel.h +++ b/launcher/ui/pages/modplatform/flame/FlameModModel.h @@ -1,7 +1,6 @@ #pragma once #include "FlameModPage.h" -#include "modplatform/flame/FlameModIndex.h" namespace FlameMod { @@ -14,12 +13,13 @@ class ListModel : public ModPlatform::ListModel { virtual ~ListModel() = default; private: - void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override { FlameMod::loadIndexedPack(m, obj); }; + void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; + void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; - QJsonArray documentToArray(QJsonDocument& obj) const override { return obj.array(); }; + QJsonArray documentToArray(QJsonDocument& obj) const override; static const char* sorts[6]; - const char** getSorts() const override { return sorts; }; + inline const char** getSorts() const override { return sorts; }; }; } // namespace FlameMod diff --git a/launcher/ui/pages/modplatform/flame/FlameModPage.cpp b/launcher/ui/pages/modplatform/flame/FlameModPage.cpp index 19f58280..091e49c7 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModPage.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModPage.cpp @@ -1,15 +1,7 @@ #include "FlameModPage.h" #include "ui_ModPage.h" -#include - -#include "Application.h" #include "FlameModModel.h" -#include "InstanceImportTask.h" -#include "Json.h" -#include "ModDownloadTask.h" -#include "minecraft/MinecraftInstance.h" -#include "minecraft/PackProfile.h" #include "ui/dialogs/ModDownloadDialog.h" FlameModPage::FlameModPage(ModDownloadDialog* dialog, BaseInstance* instance) @@ -34,31 +26,13 @@ FlameModPage::FlameModPage(ModDownloadDialog* dialog, BaseInstance* instance) connect(ui->modSelectionButton, &QPushButton::clicked, this, &FlameModPage::onModSelected); } -bool FlameModPage::shouldDisplay() const { return true; } - -void FlameModPage::onRequestVersionsSucceeded(QJsonDocument& doc, QString addonId) +bool FlameModPage::validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, QString loaderVer) const { - if (addonId != current.addonId) { - return; // wrong request - } - - QJsonArray arr = doc.array(); - try { - FlameMod::loadIndexedPackVersions(current, arr, APPLICATION->network(), m_instance); - } catch (const JSONValidationError& e) { - qDebug() << doc; - qWarning() << "Error while reading Flame mod version: " << e.cause(); - } - auto packProfile = ((MinecraftInstance*)m_instance)->getPackProfile(); - QString mcVersion = packProfile->getComponentVersion("net.minecraft"); - QString loaderString = (packProfile->getComponentVersion("net.minecraftforge").isEmpty()) ? "fabric" : "forge"; - for (int i = 0; i < current.versions.size(); i++) { - auto version = current.versions[i]; - if (!version.mcVersion.contains(mcVersion)) { continue; } - ui->versionSelectionBox->addItem(version.version, QVariant(i)); - } - if (ui->versionSelectionBox->count() == 0) { ui->versionSelectionBox->addItem(tr("No Valid Version found!"), QVariant(-1)); } - - ui->modSelectionButton->setText(tr("Cannot select invalid version :(")); - updateSelectionButton(); + (void) loaderVer; + return ver.mcVersion.contains(mineVer); } + +// I don't know why, but doing this on the parent class makes it so that +// other mod providers start loading before being selected, at least with +// my Qt, so we need to implement this in every derived class... +bool FlameModPage::shouldDisplay() const { return true; } diff --git a/launcher/ui/pages/modplatform/flame/FlameModPage.h b/launcher/ui/pages/modplatform/flame/FlameModPage.h index f15b51ec..90513ca5 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModPage.h +++ b/launcher/ui/pages/modplatform/flame/FlameModPage.h @@ -19,8 +19,7 @@ class FlameModPage : public ModPage { inline QString debugName() const override { return tr("Flame"); } inline QString metaEntryBase() const override { return "FlameMods"; }; - bool shouldDisplay() const override; + bool validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, QString loaderVer = "") const override; - private: - void onRequestVersionsSucceeded(QJsonDocument&, QString) override; + bool shouldDisplay() const override; }; diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp index 9361546e..0db6aeff 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp @@ -1,7 +1,24 @@ #include "ModrinthModel.h" +#include "modplatform/modrinth/ModrinthPackIndex.h" + namespace Modrinth { -const char* ListModel::sorts[5] { "relevance", "downloads", "follows", "updated", "newest" }; +const char* ListModel::sorts[5]{ "relevance", "downloads", "follows", "updated", "newest" }; + +void ListModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) +{ + Modrinth::loadIndexedPack(m, obj); +} + +void ListModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) +{ + Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), m_parent->m_instance); +}; + +QJsonArray ListModel::documentToArray(QJsonDocument& obj) const +{ + return obj.object().value("hits").toArray(); +} } // namespace Modrinth diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h index 9137190d..de73704c 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h @@ -1,7 +1,6 @@ #pragma once #include "ModrinthPage.h" -#include "modplatform/modrinth/ModrinthPackIndex.h" namespace Modrinth { @@ -13,12 +12,13 @@ class ListModel : public ModPlatform::ListModel { virtual ~ListModel() = default; private: - void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override { Modrinth::loadIndexedPack(m, obj); }; - - QJsonArray documentToArray(QJsonDocument& obj) const override { return obj.object().value("hits").toArray(); }; + void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; + void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; + + QJsonArray documentToArray(QJsonDocument& obj) const override; static const char* sorts[5]; - const char** getSorts() const override { return sorts; }; + inline const char** getSorts() const override { return sorts; }; }; } // namespace Modrinth diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp index fa703e38..cf01506e 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp @@ -1,15 +1,7 @@ #include "ModrinthPage.h" #include "ui_ModPage.h" -#include - -#include "Application.h" -#include "InstanceImportTask.h" -#include "Json.h" -#include "ModDownloadTask.h" #include "ModrinthModel.h" -#include "minecraft/MinecraftInstance.h" -#include "minecraft/PackProfile.h" #include "ui/dialogs/ModDownloadDialog.h" ModrinthPage::ModrinthPage(ModDownloadDialog* dialog, BaseInstance* instance) @@ -33,29 +25,12 @@ ModrinthPage::ModrinthPage(ModDownloadDialog* dialog, BaseInstance* instance) connect(ui->modSelectionButton, &QPushButton::clicked, this, &ModrinthPage::onModSelected); } -bool ModrinthPage::shouldDisplay() const { return true; } - -void ModrinthPage::onRequestVersionsSucceeded(QJsonDocument& response, QString addonId) +bool ModrinthPage::validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, QString loaderVer) const { - if (addonId != current.addonId) { return; } - - QJsonArray arr = response.array(); - try { - Modrinth::loadIndexedPackVersions(current, arr, APPLICATION->network(), m_instance); - } catch (const JSONValidationError& e) { - qDebug() << response; - qWarning() << "Error while reading Modrinth mod version: " << e.cause(); - } - auto packProfile = ((MinecraftInstance*)m_instance)->getPackProfile(); - QString mcVersion = packProfile->getComponentVersion("net.minecraft"); - QString loaderString = (packProfile->getComponentVersion("net.minecraftforge").isEmpty()) ? "fabric" : "forge"; - for (int i = 0; i < current.versions.size(); i++) { - auto version = current.versions[i]; - if (!version.mcVersion.contains(mcVersion) || !version.loaders.contains(loaderString)) { continue; } - ui->versionSelectionBox->addItem(version.version, QVariant(i)); - } - if (ui->versionSelectionBox->count() == 0) { ui->versionSelectionBox->addItem(tr("No Valid Version found !"), QVariant(-1)); } - - ui->modSelectionButton->setText(tr("Cannot select invalid version :(")); - updateSelectionButton(); + return ver.mcVersion.contains(mineVer) && ver.loaders.contains(loaderVer); } + +// I don't know why, but doing this on the parent class makes it so that +// other mod providers start loading before being selected, at least with +// my Qt, so we need to implement this in every derived class... +bool ModrinthPage::shouldDisplay() const { return true; } diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h index f6d1eef0..6f387708 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h @@ -19,8 +19,7 @@ class ModrinthPage : public ModPage { inline QString debugName() const override { return tr("Modrinth"); } inline QString metaEntryBase() const override { return "ModrinthPacks"; }; - bool shouldDisplay() const override; + bool validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, QString loaderVer = "") const override; - private: - void onRequestVersionsSucceeded(QJsonDocument&, QString) override; + bool shouldDisplay() const override; }; -- cgit From b3c2a56ece925bc6fe327b8824c50f194610b5b9 Mon Sep 17 00:00:00 2001 From: flow Date: Mon, 7 Mar 2022 19:55:20 -0300 Subject: fix: delete semicolons at the end of .cpp file's functions my lsp is weird sometimes --- launcher/modplatform/helpers/NetworkModAPI.cpp | 4 ++-- launcher/ui/pages/modplatform/flame/FlameModModel.cpp | 4 ++-- launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'launcher/ui/pages/modplatform/flame/FlameModModel.cpp') diff --git a/launcher/modplatform/helpers/NetworkModAPI.cpp b/launcher/modplatform/helpers/NetworkModAPI.cpp index 4b066102..ef084535 100644 --- a/launcher/modplatform/helpers/NetworkModAPI.cpp +++ b/launcher/modplatform/helpers/NetworkModAPI.cpp @@ -29,7 +29,7 @@ void NetworkModAPI::searchMods(CallerType* caller, SearchArgs&& args) const }); netJob->start(); -}; +} void NetworkModAPI::getVersions(CallerType* caller, const QString& addonId) const { @@ -57,4 +57,4 @@ void NetworkModAPI::getVersions(CallerType* caller, const QString& addonId) cons }); netJob->start(); -}; +} diff --git a/launcher/ui/pages/modplatform/flame/FlameModModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModModel.cpp index ce2f74f1..8437f623 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModModel.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModModel.cpp @@ -9,12 +9,12 @@ const char* ListModel::sorts[6]{ "Featured", "Popularity", "LastUpdated", "Name" void ListModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) { FlameMod::loadIndexedPack(m, obj); -}; +} void ListModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) { FlameMod::loadIndexedPackVersions(m, arr, APPLICATION->network(), m_parent->m_instance); -}; +} QJsonArray ListModel::documentToArray(QJsonDocument& obj) const { diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp index 0db6aeff..ac3c14f2 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp @@ -14,7 +14,7 @@ void ListModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) void ListModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) { Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), m_parent->m_instance); -}; +} QJsonArray ListModel::documentToArray(QJsonDocument& obj) const { -- cgit From 8409aa2571d57f015a634a220107d199e88ba2fd Mon Sep 17 00:00:00 2001 From: flow Date: Tue, 8 Mar 2022 11:12:35 -0300 Subject: tidy: Fix clang-tidy issues on files changed in this PR The checks used are roughly the same as the ones proposed in the clang-tidy PR (except perhaps that I used modernize-* instead of listing them individually,though I don't think this caused any readability detriments). In ModrinthModel.cpp and FlameModModel.cpp I ignored the modernize-avoid-c-arrays one, mostly because making the sorts array an std::array would most likely increase the code complexity because of the virtual function. Aside from that, the static_cast warning from Application.h was not dealt with, since it's not in this PR's scope. --- launcher/modplatform/flame/FlameAPI.h | 4 ++-- launcher/modplatform/flame/FlameModIndex.cpp | 4 ++-- launcher/modplatform/flame/FlameModIndex.h | 2 +- launcher/modplatform/helpers/NetworkModAPI.cpp | 6 ++--- launcher/modplatform/helpers/NetworkModAPI.h | 4 ++-- launcher/modplatform/modrinth/ModrinthAPI.h | 10 ++++---- .../modplatform/modrinth/ModrinthPackIndex.cpp | 4 ++-- launcher/modplatform/modrinth/ModrinthPackIndex.h | 2 +- launcher/ui/pages/modplatform/ModModel.cpp | 12 +++++----- launcher/ui/pages/modplatform/ModModel.h | 22 +++++++++--------- launcher/ui/pages/modplatform/ModPage.cpp | 8 +++---- launcher/ui/pages/modplatform/ModPage.h | 27 +++++++++++----------- .../ui/pages/modplatform/flame/FlameModModel.cpp | 3 ++- .../ui/pages/modplatform/flame/FlameModModel.h | 8 +++---- .../ui/pages/modplatform/flame/FlameModPage.cpp | 4 ++-- launcher/ui/pages/modplatform/flame/FlameModPage.h | 18 +++++++-------- .../pages/modplatform/modrinth/ModrinthModel.cpp | 3 ++- .../ui/pages/modplatform/modrinth/ModrinthModel.h | 7 +++--- .../ui/pages/modplatform/modrinth/ModrinthPage.cpp | 4 ++-- .../ui/pages/modplatform/modrinth/ModrinthPage.h | 18 +++++++-------- 20 files changed, 86 insertions(+), 84 deletions(-) (limited to 'launcher/ui/pages/modplatform/flame/FlameModModel.cpp') diff --git a/launcher/modplatform/flame/FlameAPI.h b/launcher/modplatform/flame/FlameAPI.h index f7f993d7..62accfa4 100644 --- a/launcher/modplatform/flame/FlameAPI.h +++ b/launcher/modplatform/flame/FlameAPI.h @@ -4,7 +4,7 @@ class FlameAPI : public NetworkModAPI { private: - inline QString getModSearchURL(SearchArgs& args) const + inline auto getModSearchURL(SearchArgs& args) const -> QString override { return QString( "https://addons-ecs.forgesvc.net/api/v2/addon/search?" @@ -25,7 +25,7 @@ class FlameAPI : public NetworkModAPI { .arg(args.version); }; - inline QString getVersionsURL(const QString& addonId) const + inline auto getVersionsURL(const QString& addonId) const -> QString override { return QString("https://addons-ecs.forgesvc.net/api/v2/addon/%1/files").arg(addonId); }; diff --git a/launcher/modplatform/flame/FlameModIndex.cpp b/launcher/modplatform/flame/FlameModIndex.cpp index 61cb534c..2c3adee4 100644 --- a/launcher/modplatform/flame/FlameModIndex.cpp +++ b/launcher/modplatform/flame/FlameModIndex.cpp @@ -43,8 +43,8 @@ void FlameMod::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, BaseInstance* inst) { QVector unsortedVersions; - bool hasFabric = !((MinecraftInstance*)inst)->getPackProfile()->getComponentVersion("net.fabricmc.fabric-loader").isEmpty(); - QString mcVersion = ((MinecraftInstance*)inst)->getPackProfile()->getComponentVersion("net.minecraft"); + bool hasFabric = !(dynamic_cast(inst))->getPackProfile()->getComponentVersion("net.fabricmc.fabric-loader").isEmpty(); + QString mcVersion = (dynamic_cast(inst))->getPackProfile()->getComponentVersion("net.minecraft"); for (auto versionIter : arr) { auto obj = versionIter.toObject(); diff --git a/launcher/modplatform/flame/FlameModIndex.h b/launcher/modplatform/flame/FlameModIndex.h index 34f71498..d3171d94 100644 --- a/launcher/modplatform/flame/FlameModIndex.h +++ b/launcher/modplatform/flame/FlameModIndex.h @@ -6,8 +6,8 @@ #include "modplatform/ModIndex.h" -#include #include "BaseInstance.h" +#include namespace FlameMod { diff --git a/launcher/modplatform/helpers/NetworkModAPI.cpp b/launcher/modplatform/helpers/NetworkModAPI.cpp index ef084535..25c7b9fd 100644 --- a/launcher/modplatform/helpers/NetworkModAPI.cpp +++ b/launcher/modplatform/helpers/NetworkModAPI.cpp @@ -7,7 +7,7 @@ void NetworkModAPI::searchMods(CallerType* caller, SearchArgs&& args) const { - auto netJob = new NetJob(QString("Modrinth::Search"), APPLICATION->network()); + auto netJob = new NetJob(QString("%1::Search").arg(caller->debugName()), APPLICATION->network()); auto searchUrl = getModSearchURL(args); auto response = new QByteArray(); @@ -16,7 +16,7 @@ void NetworkModAPI::searchMods(CallerType* caller, SearchArgs&& args) const QObject::connect(netJob, &NetJob::started, caller, [caller, netJob] { caller->setActiveJob(netJob); }); QObject::connect(netJob, &NetJob::failed, caller, &CallerType::searchRequestFailed); QObject::connect(netJob, &NetJob::succeeded, caller, [caller, response] { - QJsonParseError parse_error; + QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); if (parse_error.error != QJsonParseError::NoError) { qWarning() << "Error while parsing JSON response from " << caller->debugName() << " at " << parse_error.offset @@ -39,7 +39,7 @@ void NetworkModAPI::getVersions(CallerType* caller, const QString& addonId) cons netJob->addNetAction(Net::Download::makeByteArray(getVersionsURL(addonId), response)); QObject::connect(netJob, &NetJob::succeeded, caller, [response, caller, addonId] { - QJsonParseError parse_error; + QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); if (parse_error.error != QJsonParseError::NoError) { qWarning() << "Error while parsing JSON response from " << caller->debugName() << " at " << parse_error.offset diff --git a/launcher/modplatform/helpers/NetworkModAPI.h b/launcher/modplatform/helpers/NetworkModAPI.h index 65192046..4d3f7005 100644 --- a/launcher/modplatform/helpers/NetworkModAPI.h +++ b/launcher/modplatform/helpers/NetworkModAPI.h @@ -8,6 +8,6 @@ class NetworkModAPI : public ModAPI { void getVersions(CallerType* caller, const QString& addonId) const override; protected: - virtual QString getModSearchURL(SearchArgs& args) const = 0; - virtual QString getVersionsURL(const QString& addonId) const = 0; + virtual auto getModSearchURL(SearchArgs& args) const -> QString = 0; + virtual auto getVersionsURL(const QString& addonId) const -> QString = 0; }; diff --git a/launcher/modplatform/modrinth/ModrinthAPI.h b/launcher/modplatform/modrinth/ModrinthAPI.h index 1cc51ff2..cf4dec1a 100644 --- a/launcher/modplatform/modrinth/ModrinthAPI.h +++ b/launcher/modplatform/modrinth/ModrinthAPI.h @@ -6,10 +6,10 @@ class ModrinthAPI : public NetworkModAPI { public: - inline QString getAuthorURL(const QString& name) const { return "https://modrinth.com/user/" + name; }; + inline auto getAuthorURL(const QString& name) const -> QString { return "https://modrinth.com/user/" + name; }; private: - inline QString getModSearchURL(SearchArgs& args) const override + inline auto getModSearchURL(SearchArgs& args) const -> QString override { if (!validateModLoader(args.mod_loader)) { qWarning() << "Modrinth only have Forge and Fabric-compatible mods!"; @@ -30,12 +30,12 @@ class ModrinthAPI : public NetworkModAPI { .arg(args.version); }; - inline QString getVersionsURL(const QString& addonId) const override + inline auto getVersionsURL(const QString& addonId) const -> QString override { return QString("https://api.modrinth.com/v2/project/%1/version").arg(addonId); }; - inline QString getModLoaderString(ModLoaderType modLoader) const + inline auto getModLoaderString(ModLoaderType modLoader) const -> QString { switch (modLoader) { case Any: @@ -49,7 +49,7 @@ class ModrinthAPI : public NetworkModAPI { } } - inline bool validateModLoader(ModLoaderType modLoader) const + inline auto validateModLoader(ModLoaderType modLoader) const -> bool { return modLoader == Any || modLoader == Forge || modLoader == Fabric; } diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index 02aac34d..ab6b451b 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -30,8 +30,8 @@ void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, BaseInstance* inst) { QVector unsortedVersions; - bool hasFabric = !((MinecraftInstance*)inst)->getPackProfile()->getComponentVersion("net.fabricmc.fabric-loader").isEmpty(); - QString mcVersion = ((MinecraftInstance*)inst)->getPackProfile()->getComponentVersion("net.minecraft"); + bool hasFabric = !(static_cast(inst))->getPackProfile()->getComponentVersion("net.fabricmc.fabric-loader").isEmpty(); + QString mcVersion = (static_cast(inst))->getPackProfile()->getComponentVersion("net.minecraft"); for (auto versionIter : arr) { auto obj = versionIter.toObject(); diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.h b/launcher/modplatform/modrinth/ModrinthPackIndex.h index abfdabb6..fd17847a 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.h +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.h @@ -2,8 +2,8 @@ #include "modplatform/ModIndex.h" -#include #include "BaseInstance.h" +#include namespace Modrinth { diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index 6f3c6ce0..cc3c5326 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -11,7 +11,7 @@ namespace ModPlatform { ListModel::ListModel(ModPage* parent) : QAbstractListModel(parent), m_parent(parent) {} -QString ListModel::debugName() const +auto ListModel::debugName() const -> QString { return m_parent->debugName(); } @@ -29,7 +29,7 @@ void ListModel::fetchMore(const QModelIndex& parent) performPaginatedSearch(); } -QVariant ListModel::data(const QModelIndex& index, int role) const +auto ListModel::data(const QModelIndex& index, int role) const -> QVariant { int pos = index.row(); if (pos >= modpacks.size() || pos < 0 || !index.isValid()) { return QString("INVALID INDEX %1").arg(pos); } @@ -56,7 +56,7 @@ QVariant ListModel::data(const QModelIndex& index, int role) const return v; } - return QVariant(); + return {}; } void ListModel::requestModVersions(ModPlatform::IndexedPack const& current) @@ -66,8 +66,8 @@ void ListModel::requestModVersions(ModPlatform::IndexedPack const& current) void ListModel::performPaginatedSearch() { - QString mcVersion = ((MinecraftInstance*)((ModPage*)parent())->m_instance)->getPackProfile()->getComponentVersion("net.minecraft"); - bool hasFabric = !((MinecraftInstance*)((ModPage*)parent())->m_instance) + QString mcVersion = (dynamic_cast((dynamic_cast(parent()))->m_instance))->getPackProfile()->getComponentVersion("net.minecraft"); + bool hasFabric = !(dynamic_cast((dynamic_cast(parent()))->m_instance)) ->getPackProfile() ->getComponentVersion("net.fabricmc.fabric-loader") .isEmpty(); @@ -188,7 +188,7 @@ void ListModel::searchRequestFailed(QString reason) QMessageBox::critical(nullptr, tr("Error"), QString("%1 %2").arg(m_parent->displayName()).arg(tr("API version too old!\nPlease update PolyMC!"))); // self-destruct - ((ModDownloadDialog*)((ModPage*)parent())->parentWidget())->reject(); + (dynamic_cast((dynamic_cast(parent()))->parentWidget()))->reject(); } jobPtr.reset(); diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h index 6c3ecc3d..02be6049 100644 --- a/launcher/ui/pages/modplatform/ModModel.h +++ b/launcher/ui/pages/modplatform/ModModel.h @@ -10,24 +10,24 @@ class ModPage; namespace ModPlatform { -typedef QMap LogoMap; -typedef std::function LogoCallback; +using LogoMap = QMap; +using LogoCallback = std::function; class ListModel : public QAbstractListModel { Q_OBJECT public: ListModel(ModPage* parent); - virtual ~ListModel() = default; + ~ListModel() override = default; - inline int rowCount(const QModelIndex& parent) const override { return modpacks.size(); }; - inline int columnCount(const QModelIndex& parent) const override { return 1; }; - inline Qt::ItemFlags flags(const QModelIndex& index) const override { return QAbstractListModel::flags(index); }; + inline auto rowCount(const QModelIndex& parent) const -> int override { return modpacks.size(); }; + inline auto columnCount(const QModelIndex& parent) const -> int override { return 1; }; + inline auto flags(const QModelIndex& index) const -> Qt::ItemFlags override { return QAbstractListModel::flags(index); }; - QString debugName() const; + auto debugName() const -> QString; /* Retrieve information from the model at a given index with the given role */ - QVariant data(const QModelIndex& index, int role) const override; + auto data(const QModelIndex& index, int role) const -> QVariant override; inline void setActiveJob(NetJob::Ptr ptr) { jobPtr = ptr; } @@ -41,7 +41,7 @@ class ListModel : public QAbstractListModel { void getLogo(const QString& logo, const QString& logoUrl, LogoCallback callback); - inline bool canFetchMore(const QModelIndex& parent) const override { return searchState == CanPossiblyFetchMore; }; + inline auto canFetchMore(const QModelIndex& parent) const -> bool override { return searchState == CanPossiblyFetchMore; }; public slots: void searchRequestFinished(QJsonDocument& doc); @@ -57,8 +57,8 @@ class ListModel : public QAbstractListModel { void performPaginatedSearch(); protected: - virtual QJsonArray documentToArray(QJsonDocument& obj) const = 0; - virtual const char** getSorts() const = 0; + virtual auto documentToArray(QJsonDocument& obj) const -> QJsonArray = 0; + virtual auto getSorts() const -> const char** = 0; void requestLogo(QString file, QString url); diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index 94cf4bcf..1386ba24 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -33,10 +33,10 @@ void ModPage::openedImpl() triggerSearch(); } -bool ModPage::eventFilter(QObject* watched, QEvent* event) +auto ModPage::eventFilter(QObject* watched, QEvent* event) -> bool { if (watched == ui->searchEdit && event->type() == QEvent::KeyPress) { - QKeyEvent* keyEvent = static_cast(event); + auto* keyEvent = dynamic_cast(event); if (keyEvent->key() == Qt::Key_Return) { triggerSearch(); keyEvent->accept(); @@ -70,7 +70,7 @@ void ModPage::onSelectionChanged(QModelIndex first, QModelIndex second) text = "" + name + ""; if (!current.authors.empty()) { - auto authorToStr = [](ModPlatform::ModpackAuthor& author) { + auto authorToStr = [](ModPlatform::ModpackAuthor& author) -> QString { if (author.url.isEmpty()) { return author.name; } return QString("%2").arg(author.url, author.name); }; @@ -128,7 +128,7 @@ void ModPage::onModSelected() void ModPage::updateModVersions() { - auto packProfile = (static_cast(m_instance))->getPackProfile(); + auto packProfile = (dynamic_cast(m_instance))->getPackProfile(); QString mcVersion = packProfile->getComponentVersion("net.minecraft"); QString loaderString = (packProfile->getComponentVersion("net.minecraftforge").isEmpty()) ? "fabric" : "forge"; diff --git a/launcher/ui/pages/modplatform/ModPage.h b/launcher/ui/pages/modplatform/ModPage.h index de66b3b0..58024260 100644 --- a/launcher/ui/pages/modplatform/ModPage.h +++ b/launcher/ui/pages/modplatform/ModPage.h @@ -14,36 +14,35 @@ namespace Ui { class ModPage; } -/* This page handles most logic related to browsing and selecting mods to download. - * By default, the methods provided work with net requests, to fetch data from remote APIs. */ +/* This page handles most logic related to browsing and selecting mods to download. */ class ModPage : public QWidget, public BasePage { Q_OBJECT public: explicit ModPage(ModDownloadDialog* dialog, BaseInstance* instance, ModAPI* api); - virtual ~ModPage(); + ~ModPage() override; /* Affects what the user sees */ - virtual QString displayName() const override = 0; - virtual QIcon icon() const override = 0; - virtual QString id() const override = 0; - virtual QString helpPage() const override = 0; + auto displayName() const -> QString override = 0; + auto icon() const -> QIcon override = 0; + auto id() const -> QString override = 0; + auto helpPage() const -> QString override = 0; /* Used internally */ - virtual QString metaEntryBase() const = 0; - virtual QString debugName() const = 0; + virtual auto metaEntryBase() const -> QString = 0; + virtual auto debugName() const -> QString = 0; - virtual bool shouldDisplay() const override = 0; - virtual bool validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, QString loaderVer = "") const = 0; + auto shouldDisplay() const -> bool override = 0; + virtual auto validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, QString loaderVer = "") const -> bool = 0; - const ModAPI* apiProvider() const { return api.get(); }; + auto apiProvider() const -> const ModAPI* { return api.get(); }; - ModPlatform::IndexedPack& getCurrent() { return current; } + auto getCurrent() -> ModPlatform::IndexedPack& { return current; } void updateModVersions(); void openedImpl() override; - bool eventFilter(QObject* watched, QEvent* event) override; + auto eventFilter(QObject* watched, QEvent* event) -> bool override; BaseInstance* m_instance; diff --git a/launcher/ui/pages/modplatform/flame/FlameModModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModModel.cpp index 8437f623..905fb2dd 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModModel.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModModel.cpp @@ -4,6 +4,7 @@ namespace FlameMod { +// NOLINTNEXTLINE(modernize-avoid-c-arrays) const char* ListModel::sorts[6]{ "Featured", "Popularity", "LastUpdated", "Name", "Author", "TotalDownloads" }; void ListModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) @@ -16,7 +17,7 @@ void ListModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& FlameMod::loadIndexedPackVersions(m, arr, APPLICATION->network(), m_parent->m_instance); } -QJsonArray ListModel::documentToArray(QJsonDocument& obj) const +auto ListModel::documentToArray(QJsonDocument& obj) const -> QJsonArray { return obj.array(); } diff --git a/launcher/ui/pages/modplatform/flame/FlameModModel.h b/launcher/ui/pages/modplatform/flame/FlameModModel.h index cf3042ed..707c1bb1 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModModel.h +++ b/launcher/ui/pages/modplatform/flame/FlameModModel.h @@ -9,17 +9,17 @@ class ListModel : public ModPlatform::ListModel { public: ListModel(FlameModPage* parent) : ModPlatform::ListModel(parent) {} -; - virtual ~ListModel() = default; + ~ListModel() override = default; private: void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; - QJsonArray documentToArray(QJsonDocument& obj) const override; + auto documentToArray(QJsonDocument& obj) const -> QJsonArray override; + // NOLINTNEXTLINE(modernize-avoid-c-arrays) static const char* sorts[6]; - inline const char** getSorts() const override { return sorts; }; + inline auto getSorts() const -> const char** override { return sorts; }; }; } // namespace FlameMod diff --git a/launcher/ui/pages/modplatform/flame/FlameModPage.cpp b/launcher/ui/pages/modplatform/flame/FlameModPage.cpp index 091e49c7..c409a5cb 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModPage.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModPage.cpp @@ -26,7 +26,7 @@ FlameModPage::FlameModPage(ModDownloadDialog* dialog, BaseInstance* instance) connect(ui->modSelectionButton, &QPushButton::clicked, this, &FlameModPage::onModSelected); } -bool FlameModPage::validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, QString loaderVer) const +auto FlameModPage::validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, QString loaderVer) const -> bool { (void) loaderVer; return ver.mcVersion.contains(mineVer); @@ -35,4 +35,4 @@ bool FlameModPage::validateVersion(ModPlatform::IndexedVersion& ver, QString min // I don't know why, but doing this on the parent class makes it so that // other mod providers start loading before being selected, at least with // my Qt, so we need to implement this in every derived class... -bool FlameModPage::shouldDisplay() const { return true; } +auto FlameModPage::shouldDisplay() const -> bool { return true; } diff --git a/launcher/ui/pages/modplatform/flame/FlameModPage.h b/launcher/ui/pages/modplatform/flame/FlameModPage.h index 90513ca5..b48216bb 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModPage.h +++ b/launcher/ui/pages/modplatform/flame/FlameModPage.h @@ -9,17 +9,17 @@ class FlameModPage : public ModPage { public: explicit FlameModPage(ModDownloadDialog* dialog, BaseInstance* instance); - virtual ~FlameModPage() = default; + ~FlameModPage() override = default; - inline QString displayName() const override { return tr("CurseForge"); } - inline QIcon icon() const override { return APPLICATION->getThemedIcon("flame"); } - inline QString id() const override { return "curseforge"; } - inline QString helpPage() const override { return "Flame-platform"; } + inline auto displayName() const -> QString override { return tr("CurseForge"); } + inline auto icon() const -> QIcon override { return APPLICATION->getThemedIcon("flame"); } + inline auto id() const -> QString override { return "curseforge"; } + inline auto helpPage() const -> QString override { return "Flame-platform"; } - inline QString debugName() const override { return tr("Flame"); } - inline QString metaEntryBase() const override { return "FlameMods"; }; + inline auto debugName() const -> QString override { return tr("Flame"); } + inline auto metaEntryBase() const -> QString override { return "FlameMods"; }; - bool validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, QString loaderVer = "") const override; + auto validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, QString loaderVer = "") const -> bool override; - bool shouldDisplay() const override; + auto shouldDisplay() const -> bool override; }; diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp index ac3c14f2..daa43e26 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp @@ -4,6 +4,7 @@ namespace Modrinth { +// NOLINTNEXTLINE(modernize-avoid-c-arrays) const char* ListModel::sorts[5]{ "relevance", "downloads", "follows", "updated", "newest" }; void ListModel::loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) @@ -16,7 +17,7 @@ void ListModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& Modrinth::loadIndexedPackVersions(m, arr, APPLICATION->network(), m_parent->m_instance); } -QJsonArray ListModel::documentToArray(QJsonDocument& obj) const +auto ListModel::documentToArray(QJsonDocument& obj) const -> QJsonArray { return obj.object().value("hits").toArray(); } diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h index de73704c..45a6090a 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h @@ -9,16 +9,17 @@ class ListModel : public ModPlatform::ListModel { public: ListModel(ModrinthPage* parent) : ModPlatform::ListModel(parent){}; - virtual ~ListModel() = default; + ~ListModel() override = default; private: void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) override; void loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr) override; - QJsonArray documentToArray(QJsonDocument& obj) const override; + auto documentToArray(QJsonDocument& obj) const -> QJsonArray override; + // NOLINTNEXTLINE(modernize-avoid-c-arrays) static const char* sorts[5]; - inline const char** getSorts() const override { return sorts; }; + inline auto getSorts() const -> const char** override { return sorts; }; }; } // namespace Modrinth diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp index cf01506e..aebfee74 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp @@ -25,7 +25,7 @@ ModrinthPage::ModrinthPage(ModDownloadDialog* dialog, BaseInstance* instance) connect(ui->modSelectionButton, &QPushButton::clicked, this, &ModrinthPage::onModSelected); } -bool ModrinthPage::validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, QString loaderVer) const +auto ModrinthPage::validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, QString loaderVer) const -> bool { return ver.mcVersion.contains(mineVer) && ver.loaders.contains(loaderVer); } @@ -33,4 +33,4 @@ bool ModrinthPage::validateVersion(ModPlatform::IndexedVersion& ver, QString min // I don't know why, but doing this on the parent class makes it so that // other mod providers start loading before being selected, at least with // my Qt, so we need to implement this in every derived class... -bool ModrinthPage::shouldDisplay() const { return true; } +auto ModrinthPage::shouldDisplay() const -> bool { return true; } diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h index 6f387708..6e911b83 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h @@ -9,17 +9,17 @@ class ModrinthPage : public ModPage { public: explicit ModrinthPage(ModDownloadDialog* dialog, BaseInstance* instance); - virtual ~ModrinthPage() = default; + ~ModrinthPage() override = default; - inline QString displayName() const override { return tr("Modrinth"); } - inline QIcon icon() const override { return APPLICATION->getThemedIcon("modrinth"); } - inline QString id() const override { return "modrinth"; } - inline QString helpPage() const override { return "Modrinth-platform"; } + inline auto displayName() const -> QString override { return tr("Modrinth"); } + inline auto icon() const -> QIcon override { return APPLICATION->getThemedIcon("modrinth"); } + inline auto id() const -> QString override { return "modrinth"; } + inline auto helpPage() const -> QString override { return "Modrinth-platform"; } - inline QString debugName() const override { return tr("Modrinth"); } - inline QString metaEntryBase() const override { return "ModrinthPacks"; }; + inline auto debugName() const -> QString override { return tr("Modrinth"); } + inline auto metaEntryBase() const -> QString override { return "ModrinthPacks"; }; - bool validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, QString loaderVer = "") const override; + auto validateVersion(ModPlatform::IndexedVersion& ver, QString mineVer, QString loaderVer = "") const -> bool override; - bool shouldDisplay() const override; + auto shouldDisplay() const -> bool override; }; -- cgit