From 4e9039be2d3bc0357e6bfe577c5f2add8313f8d6 Mon Sep 17 00:00:00 2001 From: timoreo Date: Fri, 14 Jan 2022 09:43:42 +0100 Subject: Start of mod downloading --- .../modplatform/modrinth/ModrinthPackIndex.cpp | 51 ++++++++++++++++++++++ launcher/modplatform/modrinth/ModrinthPackIndex.h | 46 +++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 launcher/modplatform/modrinth/ModrinthPackIndex.cpp create mode 100644 launcher/modplatform/modrinth/ModrinthPackIndex.h (limited to 'launcher/modplatform/modrinth') diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp new file mode 100644 index 00000000..fa421ab2 --- /dev/null +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -0,0 +1,51 @@ +#include +#include "ModrinthPackIndex.h" + +#include "Json.h" +#include "net/NetJob.h" + +void Modrinth::loadIndexedPack(Modrinth::IndexedPack & pack, QJsonObject & obj) +{ + pack.addonId = Json::requireString(obj, "mod_id"); + pack.name = Json::requireString(obj, "title"); + pack.websiteUrl = Json::ensureString(obj, "page_url", ""); + pack.description = Json::ensureString(obj, "description", ""); + + pack.logoUrl = Json::requireString(obj, "icon_url"); + pack.logoName = "logoName"; + + Modrinth::ModpackAuthor packAuthor; + packAuthor.name = Json::requireString(obj, "author"); + packAuthor.url = Json::requireString(obj, "author_url"); + pack.authors.append(packAuthor); //TODO delete this ? only one author ever exists +} + +void Modrinth::loadIndexedPackVersions(Modrinth::IndexedPack & pack, QJsonArray & arr, const shared_qobject_ptr& network) +{ + QVector unsortedVersions; + for(auto versionIter: arr) { + auto obj = versionIter.toObject(); + Modrinth::IndexedVersion file; + file.addonId = Json::requireString(obj,"mod_id") ; + file.fileId = Json::requireString(obj, "id"); + file.date = Json::requireString(obj, "date_published"); + auto versionArray = Json::requireArray(obj, "game_versions"); + if (versionArray.empty()) { + continue; + } + // pick the latest version supported + file.mcVersion = versionArray[0].toString(); + file.version = Json::requireString(obj, "name"); + //TODO show all the files ? + file.downloadUrl = Json::requireString(Json::requireArray(obj, "files")[0].toObject(),"url"); + unsortedVersions.append(file); + } + auto orderSortPredicate = [](const IndexedVersion & a, const IndexedVersion & b) -> bool + { + //dates are in RFC 3339 format + return a.date > b.date; + }; + std::sort(unsortedVersions.begin(), unsortedVersions.end(), orderSortPredicate); + pack.versions = unsortedVersions; + pack.versionsLoaded = true; +} diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.h b/launcher/modplatform/modrinth/ModrinthPackIndex.h new file mode 100644 index 00000000..afc31ff2 --- /dev/null +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include "net/NetJob.h" + +namespace Modrinth { + +struct ModpackAuthor { + QString name; + QString url; +}; + +struct IndexedVersion { + QString addonId; + QString fileId; + QString version; + QString mcVersion; + QString downloadUrl; + QString date; +}; + +struct IndexedPack +{ + QString addonId; + QString name; + QString description; + QList authors; + QString logoName; + QString logoUrl; + QString websiteUrl; + + bool versionsLoaded = false; + QVector versions; +}; + +void loadIndexedPack(IndexedPack & m, QJsonObject & obj); +void loadIndexedPackVersions(IndexedPack & m, QJsonArray & arr, const shared_qobject_ptr& network); +void versionJobFinished(); +} + +Q_DECLARE_METATYPE(Modrinth::IndexedPack) -- cgit From 9e6fa8f29aa8bc0f609bfcdb6460c6845b73448a Mon Sep 17 00:00:00 2001 From: timoreo Date: Fri, 14 Jan 2022 12:47:18 +0100 Subject: Added the downloading of the mods --- launcher/ModDownloadTask.cpp | 35 ++++++++++++++++++++-- launcher/ModDownloadTask.h | 15 +++++++++- .../modplatform/modrinth/ModrinthPackIndex.cpp | 4 ++- launcher/modplatform/modrinth/ModrinthPackIndex.h | 1 + launcher/ui/dialogs/ModDownloadDialog.cpp | 2 +- launcher/ui/dialogs/ModDownloadDialog.h | 1 + .../ui/pages/modplatform/modrinth/ModrinthPage.cpp | 2 +- 7 files changed, 53 insertions(+), 7 deletions(-) (limited to 'launcher/modplatform/modrinth') diff --git a/launcher/ModDownloadTask.cpp b/launcher/ModDownloadTask.cpp index 22955470..263aa5d0 100644 --- a/launcher/ModDownloadTask.cpp +++ b/launcher/ModDownloadTask.cpp @@ -14,12 +14,41 @@ */ #include "ModDownloadTask.h" +#include "Application.h" -ModDownloadTask::ModDownloadTask(const QUrl sourceUrl) { - m_sourceUrl = sourceUrl; +ModDownloadTask::ModDownloadTask(const QUrl sourceUrl,const QString filename, const std::shared_ptr mods) +: m_sourceUrl(sourceUrl), mods(mods), filename(filename) { } void ModDownloadTask::executeTask() { - //TODO actually install the mod + setStatus(tr("Downloading mod:\n%1").arg(m_sourceUrl.toString())); + + m_filesNetJob.reset(new NetJob(tr("Modpack download"), APPLICATION->network())); + m_filesNetJob->addNetAction(Net::Download::makeFile(m_sourceUrl, mods->dir().absoluteFilePath(filename))); + connect(m_filesNetJob.get(), &NetJob::succeeded, this, &ModDownloadTask::downloadSucceeded); + connect(m_filesNetJob.get(), &NetJob::progress, this, &ModDownloadTask::downloadProgressChanged); + connect(m_filesNetJob.get(), &NetJob::failed, this, &ModDownloadTask::downloadFailed); + m_filesNetJob->start(); +} + +void ModDownloadTask::downloadSucceeded() +{ emitSucceeded(); + m_filesNetJob.reset(); +} + +void ModDownloadTask::downloadFailed(QString reason) +{ + emitFailed(reason); + m_filesNetJob.reset(); } + +void ModDownloadTask::downloadProgressChanged(qint64 current, qint64 total) +{ + emit progress(current, total); +} + +bool ModDownloadTask::abort() { + return m_filesNetJob->abort(); +} + diff --git a/launcher/ModDownloadTask.h b/launcher/ModDownloadTask.h index 067bd91c..8b39917c 100644 --- a/launcher/ModDownloadTask.h +++ b/launcher/ModDownloadTask.h @@ -16,20 +16,33 @@ #pragma once #include "QObjectPtr.h" #include "tasks/Task.h" +#include "minecraft/mod/ModFolderModel.h" +#include "net/NetJob.h" #include class ModDownloadTask : public Task { Q_OBJECT public: - explicit ModDownloadTask(const QUrl sourceUrl); + explicit ModDownloadTask(const QUrl sourceUrl, const QString filename, const std::shared_ptr mods); +public slots: + bool abort() override; protected: //! Entry point for tasks. void executeTask() override; private: QUrl m_sourceUrl; + std::shared_ptr m_filesNetJob; + const std::shared_ptr mods; + const QString filename; + + void downloadProgressChanged(qint64 current, qint64 total); + + void downloadFailed(QString reason); + + void downloadSucceeded(); }; diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index fa421ab2..fbfaeac8 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -37,7 +37,9 @@ void Modrinth::loadIndexedPackVersions(Modrinth::IndexedPack & pack, QJsonArray file.mcVersion = versionArray[0].toString(); file.version = Json::requireString(obj, "name"); //TODO show all the files ? - file.downloadUrl = Json::requireString(Json::requireArray(obj, "files")[0].toObject(),"url"); + auto parent = Json::requireArray(obj, "files")[0].toObject(); + file.downloadUrl = Json::requireString(parent, "url"); + file.fileName = Json::requireString(parent, "filename"); unsortedVersions.append(file); } auto orderSortPredicate = [](const IndexedVersion & a, const IndexedVersion & b) -> bool diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.h b/launcher/modplatform/modrinth/ModrinthPackIndex.h index afc31ff2..e39b69ab 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.h +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.h @@ -22,6 +22,7 @@ struct IndexedVersion { QString mcVersion; QString downloadUrl; QString date; + QString fileName; }; struct IndexedPack diff --git a/launcher/ui/dialogs/ModDownloadDialog.cpp b/launcher/ui/dialogs/ModDownloadDialog.cpp index a40980ef..3b4e11e5 100644 --- a/launcher/ui/dialogs/ModDownloadDialog.cpp +++ b/launcher/ui/dialogs/ModDownloadDialog.cpp @@ -32,7 +32,7 @@ ModDownloadDialog::ModDownloadDialog(const std::shared_ptr& mods, QWidget *parent) - : QDialog(parent) + : QDialog(parent), mods(mods) { setObjectName(QStringLiteral("ModDownloadDialog")); resize(400, 347); diff --git a/launcher/ui/dialogs/ModDownloadDialog.h b/launcher/ui/dialogs/ModDownloadDialog.h index 6ce6ff61..ac40257d 100644 --- a/launcher/ui/dialogs/ModDownloadDialog.h +++ b/launcher/ui/dialogs/ModDownloadDialog.h @@ -46,6 +46,7 @@ public: void setSuggestedMod(const QString & name = QString(), ModDownloadTask * task = nullptr); ModDownloadTask * getTask(); + const std::shared_ptr &mods; public slots: void accept() override; diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp index ea1800d2..b68597ac 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp @@ -165,7 +165,7 @@ void ModrinthPage::suggestCurrent() return; } - dialog->setSuggestedMod(current.name, new ModDownloadTask(selectedVersion)); + dialog->setSuggestedMod(current.name, new ModDownloadTask(selectedVersion, current.versions.at(0).fileName ,dialog->mods)); } void ModrinthPage::onVersionSelectionChanged(QString data) -- cgit From 1a8c972aefae75ee91295ea5a926cca71d95140a Mon Sep 17 00:00:00 2001 From: timoreo Date: Fri, 14 Jan 2022 20:22:15 +0100 Subject: Fixed icons Also having a mod loader is now enforced --- launcher/ModDownloadTask.h | 2 +- .../modplatform/modrinth/ModrinthPackIndex.cpp | 2 +- launcher/ui/dialogs/ModDownloadDialog.cpp | 7 ++-- launcher/ui/dialogs/ModDownloadDialog.h | 3 +- launcher/ui/pages/instance/ModFolderPage.cpp | 47 +++++++++++++--------- .../pages/modplatform/modrinth/ModrinthModel.cpp | 3 +- .../ui/pages/modplatform/modrinth/ModrinthPage.cpp | 6 ++- .../ui/pages/modplatform/modrinth/ModrinthPage.h | 3 +- 8 files changed, 43 insertions(+), 30 deletions(-) (limited to 'launcher/modplatform/modrinth') diff --git a/launcher/ModDownloadTask.h b/launcher/ModDownloadTask.h index 8b39917c..950a4048 100644 --- a/launcher/ModDownloadTask.h +++ b/launcher/ModDownloadTask.h @@ -34,7 +34,7 @@ protected: private: QUrl m_sourceUrl; - std::shared_ptr m_filesNetJob; + NetJob::Ptr m_filesNetJob; const std::shared_ptr mods; const QString filename; diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index fbfaeac8..89e827b4 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -12,7 +12,7 @@ void Modrinth::loadIndexedPack(Modrinth::IndexedPack & pack, QJsonObject & obj) pack.description = Json::ensureString(obj, "description", ""); pack.logoUrl = Json::requireString(obj, "icon_url"); - pack.logoName = "logoName"; + pack.logoName = pack.addonId; Modrinth::ModpackAuthor packAuthor; packAuthor.name = Json::requireString(obj, "author"); diff --git a/launcher/ui/dialogs/ModDownloadDialog.cpp b/launcher/ui/dialogs/ModDownloadDialog.cpp index 3b4e11e5..ac5639e0 100644 --- a/launcher/ui/dialogs/ModDownloadDialog.cpp +++ b/launcher/ui/dialogs/ModDownloadDialog.cpp @@ -31,8 +31,9 @@ #include "ModDownloadTask.h" -ModDownloadDialog::ModDownloadDialog(const std::shared_ptr& mods, QWidget *parent) - : QDialog(parent), mods(mods) +ModDownloadDialog::ModDownloadDialog(const std::shared_ptr &mods, QWidget *parent, + BaseInstance *instance) + : QDialog(parent), mods(mods), m_instance(instance) { setObjectName(QStringLiteral("ModDownloadDialog")); resize(400, 347); @@ -88,7 +89,7 @@ void ModDownloadDialog::accept() QList ModDownloadDialog::getPages() { - modrinthPage = new ModrinthPage(this); + modrinthPage = new ModrinthPage(this, m_instance); return { modrinthPage diff --git a/launcher/ui/dialogs/ModDownloadDialog.h b/launcher/ui/dialogs/ModDownloadDialog.h index ac40257d..7b2d18a0 100644 --- a/launcher/ui/dialogs/ModDownloadDialog.h +++ b/launcher/ui/dialogs/ModDownloadDialog.h @@ -37,7 +37,7 @@ class ModDownloadDialog : public QDialog, public BasePageProvider Q_OBJECT public: - explicit ModDownloadDialog(const std::shared_ptr& mods, QWidget *parent = nullptr); + explicit ModDownloadDialog(const std::shared_ptr &mods, QWidget *parent, BaseInstance *instance); ~ModDownloadDialog(); QString dialogTitle() override; @@ -63,4 +63,5 @@ private: ModrinthPage *modrinthPage = nullptr; std::unique_ptr modTask; + BaseInstance *m_instance; }; diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index d2f5dead..7ebf66f6 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -349,25 +349,34 @@ void ModFolderPage::on_actionInstall_mods_triggered() if(!m_controlsEnabled) { return; } - ModDownloadDialog mdownload(m_mods, this); - mdownload.exec(); - ModDownloadTask * task = mdownload.getTask(); - if(task){ - connect(task, &Task::failed, [this](QString reason) - { - CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); - }); - connect(task, &Task::succeeded, [this, task]() - { - QStringList warnings = task->warnings(); - if(warnings.count()) - { - CustomMessageBox::selectable(this, tr("Warnings"), warnings.join('\n'), QMessageBox::Warning)->show(); - } - }); - ProgressDialog loadDialog(this); - loadDialog.setSkipButton(true, tr("Abort")); - loadDialog.execWithTask(task); + if(m_inst->typeName() != "Minecraft"){ + return; //this is a null instance or a legacy instance + } + bool hasFabric = !((MinecraftInstance *)m_inst)->getPackProfile()->getComponentVersion("net.fabricmc.fabric-loader").isEmpty(); + bool hasForge = !((MinecraftInstance *)m_inst)->getPackProfile()->getComponentVersion("net.minecraftforge").isEmpty(); + if (!hasFabric && !hasForge) { + QMessageBox::critical(this,tr("Error"),tr("Please install a mod loader first !")); + return; + } + ModDownloadDialog mdownload(m_mods, this, m_inst); + if(mdownload.exec()) { + ModDownloadTask *task = mdownload.getTask(); + if (task) { + connect(task, &Task::failed, [this](QString reason) { + CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); + }); + connect(task, &Task::succeeded, [this, task]() { + QStringList warnings = task->warnings(); + if (warnings.count()) { + CustomMessageBox::selectable(this, tr("Warnings"), warnings.join('\n'), + QMessageBox::Warning)->show(); + } + }); + ProgressDialog loadDialog(this); + loadDialog.setSkipButton(true, tr("Abort")); + loadDialog.execWithTask(task); + m_mods->update(); + } } } diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp index 3bc70e34..0242465b 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp @@ -100,7 +100,7 @@ void ListModel::requestLogo(QString logo, QString url) } MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("ModrinthPacks", QString("logos/%1").arg(logo.section(".", 0, 0))); - NetJob *job = new NetJob(QString("Modrinth Icon Download %1").arg(logo), APPLICATION->network()); + auto job = new NetJob(QString("Modrinth Icon Download %1").arg(logo), APPLICATION->network()); job->addNetAction(Net::Download::makeCached(QUrl(url), entry)); auto fullPath = entry->getFullPath(); @@ -119,7 +119,6 @@ void ListModel::requestLogo(QString logo, QString url) }); job->start(); - m_loadingLogos.append(logo); } diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp index b68597ac..e72a57f6 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp @@ -9,9 +9,11 @@ #include "InstanceImportTask.h" #include "ModrinthModel.h" #include "ModDownloadTask.h" +#include "ui/pages/instance/ModFolderPage.h" +#include "minecraft/PackProfile.h" -ModrinthPage::ModrinthPage(ModDownloadDialog* dialog, QWidget *parent) - : QWidget(parent), ui(new Ui::ModrinthPage), dialog(dialog) +ModrinthPage::ModrinthPage(ModDownloadDialog *dialog, BaseInstance *instance) + : QWidget(dialog), ui(new Ui::ModrinthPage), dialog(dialog), m_instance(instance) { ui->setupUi(this); connect(ui->searchButton, &QPushButton::clicked, this, &ModrinthPage::triggerSearch); diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h index 1f7b12af..59671d0e 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h @@ -38,7 +38,7 @@ class ModrinthPage : public QWidget, public BasePage Q_OBJECT public: - explicit ModrinthPage(ModDownloadDialog* dialog, QWidget *parent = 0); + explicit ModrinthPage(ModDownloadDialog *dialog, BaseInstance *instance); virtual ~ModrinthPage(); virtual QString displayName() const override { @@ -77,4 +77,5 @@ private: Modrinth::IndexedPack current; QString selectedVersion; + BaseInstance *m_instance; }; -- cgit From 4b37c46889cb8973d8eb8c22f0c45fe36fdb81cf Mon Sep 17 00:00:00 2001 From: timoreo Date: Sat, 15 Jan 2022 08:51:47 +0100 Subject: Filtering per mod loader & mc version --- launcher/modplatform/modrinth/ModrinthPackIndex.cpp | 9 ++++++++- launcher/modplatform/modrinth/ModrinthPackIndex.h | 3 ++- .../ui/pages/modplatform/modrinth/ModrinthModel.cpp | 19 ++++++++++++------- .../ui/pages/modplatform/modrinth/ModrinthModel.h | 6 ++++-- .../ui/pages/modplatform/modrinth/ModrinthPage.cpp | 13 +++++++++---- launcher/ui/pages/modplatform/modrinth/ModrinthPage.h | 3 ++- 6 files changed, 37 insertions(+), 16 deletions(-) (limited to 'launcher/modplatform/modrinth') diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index 89e827b4..ce408ca0 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -34,12 +34,19 @@ void Modrinth::loadIndexedPackVersions(Modrinth::IndexedPack & pack, QJsonArray continue; } // pick the latest version supported - file.mcVersion = versionArray[0].toString(); + for(auto mcVer : versionArray){ + file.mcVersion.append(mcVer.toString()); + } + auto loaders = Json::requireArray(obj,"loaders"); + for(auto loader : loaders){ + file.loaders.append(loader.toString()); + } file.version = Json::requireString(obj, "name"); //TODO show all the files ? auto parent = Json::requireArray(obj, "files")[0].toObject(); file.downloadUrl = Json::requireString(parent, "url"); file.fileName = Json::requireString(parent, "filename"); + unsortedVersions.append(file); } auto orderSortPredicate = [](const IndexedVersion & a, const IndexedVersion & b) -> bool diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.h b/launcher/modplatform/modrinth/ModrinthPackIndex.h index e39b69ab..b3cffc40 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.h +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.h @@ -19,10 +19,11 @@ struct IndexedVersion { QString addonId; QString fileId; QString version; - QString mcVersion; + QVector mcVersion; QString downloadUrl; QString date; QString fileName; + QVector loaders; }; struct IndexedPack diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp index 0242465b..e7f66768 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp @@ -1,18 +1,19 @@ #include "ModrinthModel.h" #include "Application.h" +#include "minecraft/MinecraftInstance.h" +#include "minecraft/PackProfile.h" +#include "ModrinthPage.h" #include #include #include #include -#include -#include namespace Modrinth { -ListModel::ListModel(QObject *parent) : QAbstractListModel(parent) +ListModel::ListModel(ModrinthPage *parent) : QAbstractListModel(parent) { } @@ -158,14 +159,18 @@ const char* sorts[4]{"relevance","downloads","updated","newest"}; void ListModel::performPaginatedSearch() { - NetJob *netJob = new NetJob("Modrinth::Search", APPLICATION->network()); + + 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/api/v1/mod?" "offset=%1&" "limit=25&" "query=%2&" - "index=%3" - ).arg(nextSearchOffset).arg(currentSearchTerm).arg(sorts[currentSort]); + "index=%3&" + "filters=categories=\"%4\" AND versions=\"%5\"" + ).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(); @@ -173,7 +178,7 @@ void ListModel::performPaginatedSearch() QObject::connect(netJob, &NetJob::failed, this, &ListModel::searchRequestFailed); } -void ListModel::searchWithTerm(const QString& term, int sort) +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/modrinth/ModrinthModel.h b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h index 7bd06f6a..53f1f134 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.h @@ -17,6 +17,8 @@ #include #include "modplatform/modrinth/ModrinthPackIndex.h" +#include "BaseInstance.h" +#include "ModrinthPage.h" namespace Modrinth { @@ -29,7 +31,7 @@ class ListModel : public QAbstractListModel Q_OBJECT public: - ListModel(QObject *parent); + ListModel(ModrinthPage *parent); virtual ~ListModel(); int rowCount(const QModelIndex &parent) const override; @@ -40,7 +42,7 @@ public: void fetchMore(const QModelIndex & parent) override; void getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback); - void searchWithTerm(const QString & term, const int sort); + void searchWithTerm(const QString &term, const int sort); private slots: void performPaginatedSearch(); diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp index e72a57f6..96797062 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp @@ -9,11 +9,11 @@ #include "InstanceImportTask.h" #include "ModrinthModel.h" #include "ModDownloadTask.h" -#include "ui/pages/instance/ModFolderPage.h" +#include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" ModrinthPage::ModrinthPage(ModDownloadDialog *dialog, BaseInstance *instance) - : QWidget(dialog), ui(new Ui::ModrinthPage), dialog(dialog), m_instance(instance) + : QWidget(dialog), m_instance(instance), ui(new Ui::ModrinthPage), dialog(dialog) { ui->setupUi(this); connect(ui->searchButton, &QPushButton::clicked, this, &ModrinthPage::triggerSearch); @@ -135,8 +135,13 @@ void ModrinthPage::onSelectionChanged(QModelIndex first, QModelIndex second) qDebug() << *response; qWarning() << "Error while reading Modrinth mod version: " << e.cause(); } - - for(auto version : current.versions) { + auto packProfile = ((MinecraftInstance *)m_instance)->getPackProfile(); + QString mcVersion = packProfile->getComponentVersion("net.minecraft"); + QString loaderString = (packProfile->getComponentVersion("net.minecraftforge").isEmpty()) ? "fabric" : "forge"; + for(const auto& version : current.versions) { + if(!version.mcVersion.contains(mcVersion) || !version.loaders.contains(loaderString)){ + continue; + } ui->versionSelectionBox->addItem(version.version, QVariant(version.downloadUrl)); } diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h index 8ff5cbe4..3748d836 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.h @@ -47,6 +47,8 @@ public: bool eventFilter(QObject * watched, QEvent * event) override; + BaseInstance *m_instance; + private: void suggestCurrent(); @@ -62,5 +64,4 @@ private: Modrinth::IndexedPack current; QString selectedVersion; - BaseInstance *m_instance; }; -- cgit From 621e0ba4a887ab4dfdde6a6bba2e1c7b209fb6bc Mon Sep 17 00:00:00 2001 From: timoreo Date: Sat, 15 Jan 2022 10:25:24 +0100 Subject: Added smart file selection This might fail in a few special cases --- launcher/ModDownloadTask.cpp | 2 +- .../modplatform/modrinth/ModrinthPackIndex.cpp | 41 +++++++++++++++++++--- launcher/modplatform/modrinth/ModrinthPackIndex.h | 4 +-- .../ui/pages/modplatform/modrinth/ModrinthPage.cpp | 6 ++-- 4 files changed, 43 insertions(+), 10 deletions(-) (limited to 'launcher/modplatform/modrinth') diff --git a/launcher/ModDownloadTask.cpp b/launcher/ModDownloadTask.cpp index 6e5463fc..08a02d29 100644 --- a/launcher/ModDownloadTask.cpp +++ b/launcher/ModDownloadTask.cpp @@ -8,7 +8,7 @@ ModDownloadTask::ModDownloadTask(const QUrl sourceUrl,const QString filename, co void ModDownloadTask::executeTask() { setStatus(tr("Downloading mod:\n%1").arg(m_sourceUrl.toString())); - m_filesNetJob.reset(new NetJob(tr("Modpack download"), APPLICATION->network())); + m_filesNetJob.reset(new NetJob(tr("Mod download"), APPLICATION->network())); m_filesNetJob->addNetAction(Net::Download::makeFile(m_sourceUrl, mods->dir().absoluteFilePath(filename))); connect(m_filesNetJob.get(), &NetJob::succeeded, this, &ModDownloadTask::downloadSucceeded); connect(m_filesNetJob.get(), &NetJob::progress, this, &ModDownloadTask::downloadProgressChanged); diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index ce408ca0..8d47699b 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -3,6 +3,10 @@ #include "Json.h" #include "net/NetJob.h" +#include "BaseInstance.h" +#include "minecraft/MinecraftInstance.h" +#include "minecraft/PackProfile.h" + void Modrinth::loadIndexedPack(Modrinth::IndexedPack & pack, QJsonObject & obj) { @@ -20,9 +24,12 @@ void Modrinth::loadIndexedPack(Modrinth::IndexedPack & pack, QJsonObject & obj) pack.authors.append(packAuthor); //TODO delete this ? only one author ever exists } -void Modrinth::loadIndexedPackVersions(Modrinth::IndexedPack & pack, QJsonArray & arr, const shared_qobject_ptr& network) +void Modrinth::loadIndexedPackVersions(Modrinth::IndexedPack & pack, QJsonArray & arr, const shared_qobject_ptr& network, BaseInstance * inst) { QVector unsortedVersions; + bool hasFabric = !((MinecraftInstance *)inst)->getPackProfile()->getComponentVersion("net.fabricmc.fabric-loader").isEmpty(); + QString mcVersion = ((MinecraftInstance *)inst)->getPackProfile()->getComponentVersion("net.minecraft"); + for(auto versionIter: arr) { auto obj = versionIter.toObject(); Modrinth::IndexedVersion file; @@ -33,7 +40,6 @@ void Modrinth::loadIndexedPackVersions(Modrinth::IndexedPack & pack, QJsonArray if (versionArray.empty()) { continue; } - // pick the latest version supported for(auto mcVer : versionArray){ file.mcVersion.append(mcVer.toString()); } @@ -42,8 +48,35 @@ void Modrinth::loadIndexedPackVersions(Modrinth::IndexedPack & pack, QJsonArray file.loaders.append(loader.toString()); } file.version = Json::requireString(obj, "name"); - //TODO show all the files ? - auto parent = Json::requireArray(obj, "files")[0].toObject(); + + auto files = Json::requireArray(obj, "files"); + int i = 0; + while (files.count() > 1 && i < files.count()){ + //try to resolve the correct file + auto parent = files[i].toObject(); + auto fileName = Json::requireString(parent, "filename"); + //avoid grabbing "dev" files + if(fileName.contains("javadocs",Qt::CaseInsensitive) || fileName.contains("sources",Qt::CaseInsensitive)){ + i++; + continue; + } + //grab the correct mod loader + if(fileName.contains("forge",Qt::CaseInsensitive) || fileName.contains("fabric",Qt::CaseInsensitive) ){ + if(hasFabric){ + if(fileName.contains("forge",Qt::CaseInsensitive)){ + i++; + continue; + } + }else{ + if(fileName.contains("fabric",Qt::CaseInsensitive)){ + i++; + continue; + } + } + } + break; + } + auto parent = files[i].toObject(); file.downloadUrl = Json::requireString(parent, "url"); file.fileName = Json::requireString(parent, "filename"); diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.h b/launcher/modplatform/modrinth/ModrinthPackIndex.h index b3cffc40..01ae4b44 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.h +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.h @@ -7,6 +7,7 @@ #include #include #include "net/NetJob.h" +#include "BaseInstance.h" namespace Modrinth { @@ -41,8 +42,7 @@ struct IndexedPack }; void loadIndexedPack(IndexedPack & m, QJsonObject & obj); -void loadIndexedPackVersions(IndexedPack & m, QJsonArray & arr, const shared_qobject_ptr& network); -void versionJobFinished(); +void loadIndexedPackVersions(IndexedPack &pack, QJsonArray &arr, const shared_qobject_ptr &network, BaseInstance *inst); } Q_DECLARE_METATYPE(Modrinth::IndexedPack) diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp index f58a884c..fe5766dc 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp @@ -128,7 +128,7 @@ void ModrinthPage::onSelectionChanged(QModelIndex first, QModelIndex second) QJsonArray arr = doc.array(); try { - Modrinth::loadIndexedPackVersions(current, arr, APPLICATION->network()); + Modrinth::loadIndexedPackVersions(current, arr, APPLICATION->network(), m_instance); } catch(const JSONValidationError &e) { @@ -145,7 +145,7 @@ void ModrinthPage::onSelectionChanged(QModelIndex first, QModelIndex second) ui->versionSelectionBox->addItem(version.version, QVariant(version.downloadUrl)); } if(ui->versionSelectionBox->count() == 0){ - ui->versionSelectionBox->addItem("No Valid Version found !", QVariant("")); + ui->versionSelectionBox->addItem(tr("No Valid Version found !"), QVariant("")); } suggestCurrent(); @@ -158,7 +158,7 @@ void ModrinthPage::onSelectionChanged(QModelIndex first, QModelIndex second) ui->versionSelectionBox->addItem(version.version, QVariant(version.downloadUrl)); } if(ui->versionSelectionBox->count() == 0){ - ui->versionSelectionBox->addItem("No Valid Version found !", QVariant("")); + ui->versionSelectionBox->addItem(tr("No Valid Version found !"), QVariant("")); } suggestCurrent(); } -- cgit From 1d0e6bf453bfee0d9201fabf1e979ab0aca90418 Mon Sep 17 00:00:00 2001 From: timoreo Date: Mon, 24 Jan 2022 07:23:01 +0100 Subject: Changed modrinth author data to not be a list --- launcher/modplatform/modrinth/ModrinthPackIndex.cpp | 8 ++++---- launcher/modplatform/modrinth/ModrinthPackIndex.h | 2 +- launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp | 16 +--------------- 3 files changed, 6 insertions(+), 20 deletions(-) (limited to 'launcher/modplatform/modrinth') diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index 8d47699b..a546eb7c 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -18,10 +18,10 @@ void Modrinth::loadIndexedPack(Modrinth::IndexedPack & pack, QJsonObject & obj) pack.logoUrl = Json::requireString(obj, "icon_url"); pack.logoName = pack.addonId; - Modrinth::ModpackAuthor packAuthor; - packAuthor.name = Json::requireString(obj, "author"); - packAuthor.url = Json::requireString(obj, "author_url"); - pack.authors.append(packAuthor); //TODO delete this ? only one author ever exists + Modrinth::ModpackAuthor modAuthor; + modAuthor.name = Json::requireString(obj, "author"); + modAuthor.url = Json::requireString(obj, "author_url"); + pack.author = modAuthor; } void Modrinth::loadIndexedPackVersions(Modrinth::IndexedPack & pack, QJsonArray & arr, const shared_qobject_ptr& network, BaseInstance * inst) diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.h b/launcher/modplatform/modrinth/ModrinthPackIndex.h index 01ae4b44..3a4cd270 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.h +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.h @@ -32,7 +32,7 @@ struct IndexedPack QString addonId; QString name; QString description; - QList authors; + ModpackAuthor author; QString logoName; QString logoUrl; QString websiteUrl; diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp index d0319984..61912cd7 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp @@ -90,21 +90,7 @@ void ModrinthPage::onSelectionChanged(QModelIndex first, QModelIndex second) text = name; else text = "" + name + ""; - if (!current.authors.empty()) { - auto authorToStr = [](Modrinth::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 += "

"; - + text += "
"+ tr(" by ") + ""+current.author.name+"

"; ui->packDescription->setHtml(text + current.description); if (!current.versionsLoaded) -- cgit From aa2c27bf6984f9ea2d67411c0f28d802d40834af Mon Sep 17 00:00:00 2001 From: timoreo Date: Mon, 31 Jan 2022 17:18:11 +0100 Subject: Update to Modrinth API V2 --- launcher/modplatform/modrinth/ModrinthPackIndex.cpp | 6 +++--- launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp | 6 +++--- launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'launcher/modplatform/modrinth') diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index a546eb7c..1a31e940 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -10,7 +10,7 @@ void Modrinth::loadIndexedPack(Modrinth::IndexedPack & pack, QJsonObject & obj) { - pack.addonId = Json::requireString(obj, "mod_id"); + pack.addonId = Json::requireString(obj, "project_id"); pack.name = Json::requireString(obj, "title"); pack.websiteUrl = Json::ensureString(obj, "page_url", ""); pack.description = Json::ensureString(obj, "description", ""); @@ -20,7 +20,7 @@ void Modrinth::loadIndexedPack(Modrinth::IndexedPack & pack, QJsonObject & obj) Modrinth::ModpackAuthor modAuthor; modAuthor.name = Json::requireString(obj, "author"); - modAuthor.url = Json::requireString(obj, "author_url"); + modAuthor.url = "https://modrinth.com/user/"+modAuthor.name; pack.author = modAuthor; } @@ -33,7 +33,7 @@ void Modrinth::loadIndexedPackVersions(Modrinth::IndexedPack & pack, QJsonArray for(auto versionIter: arr) { auto obj = versionIter.toObject(); Modrinth::IndexedVersion file; - file.addonId = Json::requireString(obj,"mod_id") ; + file.addonId = Json::requireString(obj,"project_id") ; file.fileId = Json::requireString(obj, "id"); file.date = Json::requireString(obj, "date_published"); auto versionArray = Json::requireArray(obj, "game_versions"); diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp index 4f6a491e..71574156 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp @@ -157,7 +157,7 @@ void ListModel::fetchMore(const QModelIndex& parent) } performPaginatedSearch(); } -const char* sorts[4]{"relevance","downloads","updated","newest"}; +const char* sorts[5]{"relevance","downloads","follows","updated","newest"}; void ListModel::performPaginatedSearch() { @@ -166,12 +166,12 @@ void ListModel::performPaginatedSearch() 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/api/v1/mod?" + "https://api.modrinth.com/v2/search?" "offset=%1&" "limit=25&" "query=%2&" "index=%3&" - "filters=categories=\"%4\" AND versions=\"%5\"" + "facets=[[\"categories:%4\"],[\"versions:%5\"],[\"project_type:mod\"]]" ) .arg(nextSearchOffset) .arg(currentSearchTerm) diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp index 61912cd7..ee3c9e76 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp @@ -27,6 +27,7 @@ ModrinthPage::ModrinthPage(ModDownloadDialog *dialog, BaseInstance *instance) // 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")); @@ -99,8 +100,7 @@ void ModrinthPage::onSelectionChanged(QModelIndex first, QModelIndex second) auto netJob = new NetJob(QString("Modrinth::ModVersions(%1)").arg(current.name), APPLICATION->network()); std::shared_ptr response = std::make_shared(); QString addonId = current.addonId; - addonId.remove(0,6); - netJob->addNetAction(Net::Download::makeByteArray(QString("https://api.modrinth.com/api/v1/mod/%1/version").arg(addonId), response.get())); + netJob->addNetAction(Net::Download::makeByteArray(QString("https://api.modrinth.com/v2/project/%1/version").arg(addonId), response.get())); QObject::connect(netJob, &NetJob::succeeded, this, [this, response, netJob] { -- cgit From 71b1ac9f349c0831f9d5242e88e7eabd38984e28 Mon Sep 17 00:00:00 2001 From: timoreo Date: Tue, 1 Feb 2022 21:56:52 +0100 Subject: Fix braindead moments --- launcher/modplatform/flame/FlameModIndex.cpp | 2 +- launcher/modplatform/modrinth/ModrinthPackIndex.cpp | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'launcher/modplatform/modrinth') diff --git a/launcher/modplatform/flame/FlameModIndex.cpp b/launcher/modplatform/flame/FlameModIndex.cpp index ca8f7fd7..4b81fd7c 100644 --- a/launcher/modplatform/flame/FlameModIndex.cpp +++ b/launcher/modplatform/flame/FlameModIndex.cpp @@ -83,7 +83,7 @@ void FlameMod::loadIndexedPackVersions(FlameMod::IndexedPack & pack, QJsonArray } } } - if(!valid || !hasFabric){ + if(!valid && !hasFabric){ continue; } diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index 1a31e940..9017eb67 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -77,10 +77,12 @@ void Modrinth::loadIndexedPackVersions(Modrinth::IndexedPack & pack, QJsonArray break; } auto parent = files[i].toObject(); - file.downloadUrl = Json::requireString(parent, "url"); - file.fileName = Json::requireString(parent, "filename"); + if(parent.contains("url")) { + file.downloadUrl = Json::requireString(parent, "url"); + file.fileName = Json::requireString(parent, "filename"); - unsortedVersions.append(file); + unsortedVersions.append(file); + } } auto orderSortPredicate = [](const IndexedVersion & a, const IndexedVersion & b) -> bool { -- cgit