From d00c320c0041421e67d5d8ec6deb4427d0f8020c Mon Sep 17 00:00:00 2001 From: flow Date: Thu, 24 Mar 2022 18:39:53 -0300 Subject: [PATCH] optimize: Improve mod versions request to Modrinth This uses more arguments in the GET request for mod versions on the Modrinth API, filtering what versions can be returned, decreasing load on Modrinth servers and improving a little the time it takes for the versions to be available to the user. This also removes the now unneeded check on correct modloaders in ModrinthPackIndex, since it is now filtered by the Modrinth server. Lastly, this adds a couple of helper functions in ModModel. --- launcher/modplatform/ModAPI.h | 11 ++++++- launcher/modplatform/flame/FlameAPI.h | 4 +-- .../modplatform/helpers/NetworkModAPI.cpp | 10 +++--- launcher/modplatform/helpers/NetworkModAPI.h | 4 +-- launcher/modplatform/modrinth/ModrinthAPI.h | 20 +++++++++-- .../modrinth/ModrinthPackIndex.cpp | 12 ------- launcher/ui/pages/modplatform/ModModel.cpp | 33 ++++++++++++------- launcher/ui/pages/modplatform/ModModel.h | 3 ++ 8 files changed, 61 insertions(+), 36 deletions(-) diff --git a/launcher/modplatform/ModAPI.h b/launcher/modplatform/ModAPI.h index 5c7c63490..ae6ac80f1 100644 --- a/launcher/modplatform/ModAPI.h +++ b/launcher/modplatform/ModAPI.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace ModPlatform { class ListModel; @@ -25,5 +26,13 @@ class ModAPI { }; virtual void searchMods(CallerType* caller, SearchArgs&& args) const = 0; - virtual void getVersions(CallerType* caller, const QString& addonId) const = 0; + + + struct VersionSearchArgs { + QString addonId; + QList mcVersions; + ModLoaderType loader; + }; + + virtual void getVersions(CallerType* caller, VersionSearchArgs&& args) const = 0; }; diff --git a/launcher/modplatform/flame/FlameAPI.h b/launcher/modplatform/flame/FlameAPI.h index 62accfa4d..8654a693b 100644 --- a/launcher/modplatform/flame/FlameAPI.h +++ b/launcher/modplatform/flame/FlameAPI.h @@ -25,8 +25,8 @@ class FlameAPI : public NetworkModAPI { .arg(args.version); }; - inline auto getVersionsURL(const QString& addonId) const -> QString override + inline auto getVersionsURL(VersionSearchArgs& args) const -> QString override { - return QString("https://addons-ecs.forgesvc.net/api/v2/addon/%1/files").arg(addonId); + return QString("https://addons-ecs.forgesvc.net/api/v2/addon/%1/files").arg(args.addonId); }; }; diff --git a/launcher/modplatform/helpers/NetworkModAPI.cpp b/launcher/modplatform/helpers/NetworkModAPI.cpp index 25c7b9fd2..6829b837c 100644 --- a/launcher/modplatform/helpers/NetworkModAPI.cpp +++ b/launcher/modplatform/helpers/NetworkModAPI.cpp @@ -31,14 +31,14 @@ void NetworkModAPI::searchMods(CallerType* caller, SearchArgs&& args) const netJob->start(); } -void NetworkModAPI::getVersions(CallerType* caller, const QString& addonId) const +void NetworkModAPI::getVersions(CallerType* caller, VersionSearchArgs&& args) const { - auto netJob = new NetJob(QString("%1::ModVersions(%2)").arg(caller->debugName()).arg(addonId), APPLICATION->network()); + auto netJob = new NetJob(QString("%1::ModVersions(%2)").arg(caller->debugName()).arg(args.addonId), APPLICATION->network()); auto response = new QByteArray(); - netJob->addNetAction(Net::Download::makeByteArray(getVersionsURL(addonId), response)); + netJob->addNetAction(Net::Download::makeByteArray(getVersionsURL(args), response)); - QObject::connect(netJob, &NetJob::succeeded, caller, [response, caller, addonId] { + QObject::connect(netJob, &NetJob::succeeded, caller, [response, caller, args] { QJsonParseError parse_error{}; QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); if (parse_error.error != QJsonParseError::NoError) { @@ -48,7 +48,7 @@ void NetworkModAPI::getVersions(CallerType* caller, const QString& addonId) cons return; } - caller->versionRequestSucceeded(doc, addonId); + caller->versionRequestSucceeded(doc, args.addonId); }); QObject::connect(netJob, &NetJob::finished, caller, [response, netJob] { diff --git a/launcher/modplatform/helpers/NetworkModAPI.h b/launcher/modplatform/helpers/NetworkModAPI.h index 4d3f70057..000620b2f 100644 --- a/launcher/modplatform/helpers/NetworkModAPI.h +++ b/launcher/modplatform/helpers/NetworkModAPI.h @@ -5,9 +5,9 @@ class NetworkModAPI : public ModAPI { public: void searchMods(CallerType* caller, SearchArgs&& args) const override; - void getVersions(CallerType* caller, const QString& addonId) const override; + void getVersions(CallerType* caller, VersionSearchArgs&& args) const override; protected: virtual auto getModSearchURL(SearchArgs& args) const -> QString = 0; - virtual auto getVersionsURL(const QString& addonId) const -> QString = 0; + virtual auto getVersionsURL(VersionSearchArgs& args) const -> QString = 0; }; diff --git a/launcher/modplatform/modrinth/ModrinthAPI.h b/launcher/modplatform/modrinth/ModrinthAPI.h index cf4dec1a8..30952e992 100644 --- a/launcher/modplatform/modrinth/ModrinthAPI.h +++ b/launcher/modplatform/modrinth/ModrinthAPI.h @@ -30,11 +30,27 @@ class ModrinthAPI : public NetworkModAPI { .arg(args.version); }; - inline auto getVersionsURL(const QString& addonId) const -> QString override + inline auto getVersionsURL(VersionSearchArgs& args) const -> QString override { - return QString("https://api.modrinth.com/v2/project/%1/version").arg(addonId); + return QString("https://api.modrinth.com/v2/project/%1/version?" + "game_versions=[%2]" + "loaders=[%3]") + .arg(args.addonId) + .arg(getGameVersionsString(args.mcVersions)) + .arg(getModLoaderString(args.loader)); }; + inline auto getGameVersionsString(QList mcVersions) const -> QString + { + QString s; + for(int i = 0; i < mcVersions.count(); i++){ + s += mcVersions.at(i); + if(i < mcVersions.count() - 1) + s += ","; + } + return s; + } + inline auto getModLoaderString(ModLoaderType modLoader) const -> QString { switch (modLoader) { diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp index 82988cf67..a4e56d4fc 100644 --- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp @@ -30,7 +30,6 @@ void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, BaseInstance* inst) { QVector unsortedVersions; - 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) { @@ -61,17 +60,6 @@ void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, auto parent = files[i].toObject(); auto fileName = Json::requireString(parent, "filename"); - // Grab the correct mod loader - if(hasFabric){ - if(fileName.contains("forge",Qt::CaseInsensitive)){ - i++; - continue; - } - } else if(fileName.contains("fabric", Qt::CaseInsensitive)){ - i++; - continue; - } - // Grab the primary file, if available if(Json::requireBoolean(parent, "primary")) break; diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp index cc3c5326b..0a1475841 100644 --- a/launcher/ui/pages/modplatform/ModModel.cpp +++ b/launcher/ui/pages/modplatform/ModModel.cpp @@ -16,7 +16,6 @@ auto ListModel::debugName() const -> QString return m_parent->debugName(); } - /******** Make data requests ********/ void ListModel::fetchMore(const QModelIndex& parent) @@ -61,19 +60,14 @@ auto ListModel::data(const QModelIndex& index, int role) const -> QVariant void ListModel::requestModVersions(ModPlatform::IndexedPack const& current) { - m_parent->apiProvider()->getVersions(this, current.addonId.toString()); + m_parent->apiProvider()->getVersions(this, + { current.addonId.toString(), getMineVersions(), hasFabric() ? ModAPI::ModLoaderType::Fabric : ModAPI::ModLoaderType::Forge }); } void ListModel::performPaginatedSearch() { - 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(); - - m_parent->apiProvider()->searchMods( - this, { nextSearchOffset, currentSearchTerm, getSorts()[currentSort], hasFabric ? ModAPI::Fabric : ModAPI::Forge, mcVersion }); + m_parent->apiProvider()->searchMods(this, + { nextSearchOffset, currentSearchTerm, getSorts()[currentSort], hasFabric() ? ModAPI::Fabric : ModAPI::Forge, getMineVersions().at(0) }); } void ListModel::searchWithTerm(const QString& term, const int sort) @@ -131,7 +125,6 @@ void ListModel::requestLogo(QString logo, QString url) m_loadingLogos.append(logo); } - /******** Request callbacks ********/ void ListModel::logoLoaded(QString logo, QIcon out) @@ -208,7 +201,7 @@ void ListModel::versionRequestSucceeded(QJsonDocument doc, QString addonId) { auto& current = m_parent->getCurrent(); if (addonId != current.addonId) { return; } - + QJsonArray arr = doc.array(); try { loadIndexedPackVersions(current, arr); @@ -221,3 +214,19 @@ void ListModel::versionRequestSucceeded(QJsonDocument doc, QString addonId) } } // namespace ModPlatform + +/******** Helpers ********/ +auto ModPlatform::ListModel::hasFabric() const -> bool +{ + return !(dynamic_cast((dynamic_cast(parent()))->m_instance)) + ->getPackProfile() + ->getComponentVersion("net.fabricmc.fabric-loader") + .isEmpty(); +} + +auto ModPlatform::ListModel::getMineVersions() const -> QList +{ + return { (dynamic_cast((dynamic_cast(parent()))->m_instance)) + ->getPackProfile() + ->getComponentVersion("net.minecraft") }; +} diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h index 02be60491..64cfa71e2 100644 --- a/launcher/ui/pages/modplatform/ModModel.h +++ b/launcher/ui/pages/modplatform/ModModel.h @@ -62,6 +62,9 @@ class ListModel : public QAbstractListModel { void requestLogo(QString file, QString url); + inline auto hasFabric() const -> bool; + inline auto getMineVersions() const -> QList; + protected: ModPage* m_parent;