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.
This commit is contained in:
parent
e13ca94061
commit
d00c320c00
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
namespace ModPlatform {
|
namespace ModPlatform {
|
||||||
class ListModel;
|
class ListModel;
|
||||||
@ -25,5 +26,13 @@ class ModAPI {
|
|||||||
};
|
};
|
||||||
|
|
||||||
virtual void searchMods(CallerType* caller, SearchArgs&& args) const = 0;
|
virtual void searchMods(CallerType* caller, SearchArgs&& args) const = 0;
|
||||||
virtual void getVersions(CallerType* caller, const QString& addonId) const = 0;
|
|
||||||
|
|
||||||
|
struct VersionSearchArgs {
|
||||||
|
QString addonId;
|
||||||
|
QList<QString> mcVersions;
|
||||||
|
ModLoaderType loader;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual void getVersions(CallerType* caller, VersionSearchArgs&& args) const = 0;
|
||||||
};
|
};
|
||||||
|
@ -25,8 +25,8 @@ class FlameAPI : public NetworkModAPI {
|
|||||||
.arg(args.version);
|
.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);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -31,14 +31,14 @@ void NetworkModAPI::searchMods(CallerType* caller, SearchArgs&& args) const
|
|||||||
netJob->start();
|
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();
|
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{};
|
QJsonParseError parse_error{};
|
||||||
QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
|
QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
|
||||||
if (parse_error.error != QJsonParseError::NoError) {
|
if (parse_error.error != QJsonParseError::NoError) {
|
||||||
@ -48,7 +48,7 @@ void NetworkModAPI::getVersions(CallerType* caller, const QString& addonId) cons
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
caller->versionRequestSucceeded(doc, addonId);
|
caller->versionRequestSucceeded(doc, args.addonId);
|
||||||
});
|
});
|
||||||
|
|
||||||
QObject::connect(netJob, &NetJob::finished, caller, [response, netJob] {
|
QObject::connect(netJob, &NetJob::finished, caller, [response, netJob] {
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
class NetworkModAPI : public ModAPI {
|
class NetworkModAPI : public ModAPI {
|
||||||
public:
|
public:
|
||||||
void searchMods(CallerType* caller, SearchArgs&& args) const override;
|
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:
|
protected:
|
||||||
virtual auto getModSearchURL(SearchArgs& args) const -> QString = 0;
|
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;
|
||||||
};
|
};
|
||||||
|
@ -30,11 +30,27 @@ class ModrinthAPI : public NetworkModAPI {
|
|||||||
.arg(args.version);
|
.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<QString> 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
|
inline auto getModLoaderString(ModLoaderType modLoader) const -> QString
|
||||||
{
|
{
|
||||||
switch (modLoader) {
|
switch (modLoader) {
|
||||||
|
@ -30,7 +30,6 @@ void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
|
|||||||
BaseInstance* inst)
|
BaseInstance* inst)
|
||||||
{
|
{
|
||||||
QVector<ModPlatform::IndexedVersion> unsortedVersions;
|
QVector<ModPlatform::IndexedVersion> unsortedVersions;
|
||||||
bool hasFabric = !(static_cast<MinecraftInstance*>(inst))->getPackProfile()->getComponentVersion("net.fabricmc.fabric-loader").isEmpty();
|
|
||||||
QString mcVersion = (static_cast<MinecraftInstance*>(inst))->getPackProfile()->getComponentVersion("net.minecraft");
|
QString mcVersion = (static_cast<MinecraftInstance*>(inst))->getPackProfile()->getComponentVersion("net.minecraft");
|
||||||
|
|
||||||
for (auto versionIter : arr) {
|
for (auto versionIter : arr) {
|
||||||
@ -61,17 +60,6 @@ void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
|
|||||||
auto parent = files[i].toObject();
|
auto parent = files[i].toObject();
|
||||||
auto fileName = Json::requireString(parent, "filename");
|
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
|
// Grab the primary file, if available
|
||||||
if(Json::requireBoolean(parent, "primary"))
|
if(Json::requireBoolean(parent, "primary"))
|
||||||
break;
|
break;
|
||||||
|
@ -16,7 +16,6 @@ auto ListModel::debugName() const -> QString
|
|||||||
return m_parent->debugName();
|
return m_parent->debugName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/******** Make data requests ********/
|
/******** Make data requests ********/
|
||||||
|
|
||||||
void ListModel::fetchMore(const QModelIndex& parent)
|
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)
|
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()
|
void ListModel::performPaginatedSearch()
|
||||||
{
|
{
|
||||||
QString mcVersion = (dynamic_cast<MinecraftInstance*>((dynamic_cast<ModPage*>(parent()))->m_instance))->getPackProfile()->getComponentVersion("net.minecraft");
|
m_parent->apiProvider()->searchMods(this,
|
||||||
bool hasFabric = !(dynamic_cast<MinecraftInstance*>((dynamic_cast<ModPage*>(parent()))->m_instance))
|
{ nextSearchOffset, currentSearchTerm, getSorts()[currentSort], hasFabric() ? ModAPI::Fabric : ModAPI::Forge, getMineVersions().at(0) });
|
||||||
->getPackProfile()
|
|
||||||
->getComponentVersion("net.fabricmc.fabric-loader")
|
|
||||||
.isEmpty();
|
|
||||||
|
|
||||||
m_parent->apiProvider()->searchMods(
|
|
||||||
this, { nextSearchOffset, currentSearchTerm, getSorts()[currentSort], hasFabric ? ModAPI::Fabric : ModAPI::Forge, mcVersion });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListModel::searchWithTerm(const QString& term, const int sort)
|
void ListModel::searchWithTerm(const QString& term, const int sort)
|
||||||
@ -131,7 +125,6 @@ void ListModel::requestLogo(QString logo, QString url)
|
|||||||
m_loadingLogos.append(logo);
|
m_loadingLogos.append(logo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/******** Request callbacks ********/
|
/******** Request callbacks ********/
|
||||||
|
|
||||||
void ListModel::logoLoaded(QString logo, QIcon out)
|
void ListModel::logoLoaded(QString logo, QIcon out)
|
||||||
@ -208,7 +201,7 @@ void ListModel::versionRequestSucceeded(QJsonDocument doc, QString addonId)
|
|||||||
{
|
{
|
||||||
auto& current = m_parent->getCurrent();
|
auto& current = m_parent->getCurrent();
|
||||||
if (addonId != current.addonId) { return; }
|
if (addonId != current.addonId) { return; }
|
||||||
|
|
||||||
QJsonArray arr = doc.array();
|
QJsonArray arr = doc.array();
|
||||||
try {
|
try {
|
||||||
loadIndexedPackVersions(current, arr);
|
loadIndexedPackVersions(current, arr);
|
||||||
@ -221,3 +214,19 @@ void ListModel::versionRequestSucceeded(QJsonDocument doc, QString addonId)
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ModPlatform
|
} // namespace ModPlatform
|
||||||
|
|
||||||
|
/******** Helpers ********/
|
||||||
|
auto ModPlatform::ListModel::hasFabric() const -> bool
|
||||||
|
{
|
||||||
|
return !(dynamic_cast<MinecraftInstance*>((dynamic_cast<ModPage*>(parent()))->m_instance))
|
||||||
|
->getPackProfile()
|
||||||
|
->getComponentVersion("net.fabricmc.fabric-loader")
|
||||||
|
.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ModPlatform::ListModel::getMineVersions() const -> QList<QString>
|
||||||
|
{
|
||||||
|
return { (dynamic_cast<MinecraftInstance*>((dynamic_cast<ModPage*>(parent()))->m_instance))
|
||||||
|
->getPackProfile()
|
||||||
|
->getComponentVersion("net.minecraft") };
|
||||||
|
}
|
||||||
|
@ -62,6 +62,9 @@ class ListModel : public QAbstractListModel {
|
|||||||
|
|
||||||
void requestLogo(QString file, QString url);
|
void requestLogo(QString file, QString url);
|
||||||
|
|
||||||
|
inline auto hasFabric() const -> bool;
|
||||||
|
inline auto getMineVersions() const -> QList<QString>;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ModPage* m_parent;
|
ModPage* m_parent;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user