refactor FlameCheckUpdate to remove qEventLoop (#3046)

This commit is contained in:
TheKodeToad
2025-03-20 09:34:26 +00:00
committed by GitHub
15 changed files with 192 additions and 251 deletions

View File

@ -1,5 +1,4 @@
#include <QDebug>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>

View File

@ -1,12 +1,9 @@
#pragma once
#include <QMultiMap>
#include <QString>
#include <memory>
#include "QObjectPtr.h"
class MinecraftAccount;
class QNetworkAccessManager;
struct AuthSession {
bool MakeOffline(QString offline_playername);

View File

@ -20,7 +20,6 @@
#include <algorithm>
#include "Json.h"
#include "QObjectPtr.h"
#include "modplatform/ModIndex.h"
#include "modplatform/flame/FlameAPI.h"
#include "modplatform/flame/FlameModIndex.h"
@ -33,9 +32,7 @@
static const FlameAPI flameAPI;
static ModrinthAPI modrinthAPI;
Flame::FileResolvingTask::FileResolvingTask(const shared_qobject_ptr<QNetworkAccessManager>& network, Flame::Manifest& toProcess)
: m_network(network), m_manifest(toProcess)
{}
Flame::FileResolvingTask::FileResolvingTask(Flame::Manifest& toProcess) : m_manifest(toProcess) {}
bool Flame::FileResolvingTask::abort()
{

View File

@ -17,8 +17,6 @@
*/
#pragma once
#include <QNetworkAccessManager>
#include "PackManifest.h"
#include "tasks/Task.h"
@ -26,7 +24,7 @@ namespace Flame {
class FileResolvingTask : public Task {
Q_OBJECT
public:
explicit FileResolvingTask(const shared_qobject_ptr<QNetworkAccessManager>& network, Flame::Manifest& toProcess);
explicit FileResolvingTask(Flame::Manifest& toProcess);
virtual ~FileResolvingTask() = default;
bool canAbort() const override { return true; }
@ -44,7 +42,6 @@ class FileResolvingTask : public Task {
void getFlameProjects();
private: /* data */
shared_qobject_ptr<QNetworkAccessManager> m_network;
Flame::Manifest m_manifest;
std::shared_ptr<QByteArray> m_result;
Task::Ptr m_task;

View File

@ -102,57 +102,6 @@ QString FlameAPI::getModDescription(int modId)
return description;
}
QList<ModPlatform::IndexedVersion> FlameAPI::getLatestVersions(VersionSearchArgs&& args)
{
auto versions_url_optional = getVersionsURL(args);
if (!versions_url_optional.has_value())
return {};
auto versions_url = versions_url_optional.value();
QEventLoop loop;
auto netJob = makeShared<NetJob>(QString("Flame::GetLatestVersion(%1)").arg(args.pack.name), APPLICATION->network());
auto response = std::make_shared<QByteArray>();
QList<ModPlatform::IndexedVersion> ver;
netJob->addNetAction(Net::ApiDownload::makeByteArray(versions_url, response));
QObject::connect(netJob.get(), &NetJob::succeeded, [response, args, &ver] {
QJsonParseError parse_error{};
QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
if (parse_error.error != QJsonParseError::NoError) {
qWarning() << "Error while parsing JSON response from latest mod version at " << parse_error.offset
<< " reason: " << parse_error.errorString();
qWarning() << *response;
return;
}
try {
auto obj = Json::requireObject(doc);
auto arr = Json::requireArray(obj, "data");
for (auto file : arr) {
auto file_obj = Json::requireObject(file);
ver.append(FlameMod::loadIndexedPackVersion(file_obj));
}
} catch (Json::JsonException& e) {
qCritical() << "Failed to parse response from a version request.";
qCritical() << e.what();
qDebug() << doc;
}
});
QObject::connect(netJob.get(), &NetJob::finished, &loop, &QEventLoop::quit);
netJob->start();
loop.exec();
return ver;
}
Task::Ptr FlameAPI::getProjects(QStringList addonIds, std::shared_ptr<QByteArray> response) const
{
auto netJob = makeShared<NetJob>(QString("Flame::GetProjects"), APPLICATION->network());
@ -266,7 +215,7 @@ QList<ModPlatform::Category> FlameAPI::loadModCategories(std::shared_ptr<QByteAr
return categories;
};
std::optional<ModPlatform::IndexedVersion> FlameAPI::getLatestVersion(QList<ModPlatform::IndexedVersion> versions,
std::optional<ModPlatform::IndexedVersion> FlameAPI::getLatestVersion(QVector<ModPlatform::IndexedVersion> versions,
QList<ModPlatform::ModLoaderType> instanceLoaders,
ModPlatform::ModLoaderTypes modLoaders)
{

View File

@ -15,8 +15,7 @@ class FlameAPI : public NetworkResourceAPI {
QString getModFileChangelog(int modId, int fileId);
QString getModDescription(int modId);
QList<ModPlatform::IndexedVersion> getLatestVersions(VersionSearchArgs&& args);
std::optional<ModPlatform::IndexedVersion> getLatestVersion(QList<ModPlatform::IndexedVersion> versions,
std::optional<ModPlatform::IndexedVersion> getLatestVersion(QVector<ModPlatform::IndexedVersion> versions,
QList<ModPlatform::ModLoaderType> instanceLoaders,
ModPlatform::ModLoaderTypes fallback);
@ -108,12 +107,6 @@ class FlameAPI : public NetworkResourceAPI {
return "https://api.curseforge.com/v1/mods/search?gameId=432&" + get_arguments.join('&');
}
private:
[[nodiscard]] std::optional<QString> getInfoURL(QString const& id) const override
{
return QString("https://api.curseforge.com/v1/mods/%1").arg(id);
}
[[nodiscard]] std::optional<QString> getVersionsURL(VersionSearchArgs const& args) const override
{
auto addonId = args.pack.addonId.toString();
@ -129,6 +122,11 @@ class FlameAPI : public NetworkResourceAPI {
return url;
}
private:
[[nodiscard]] std::optional<QString> getInfoURL(QString const& id) const override
{
return QString("https://api.curseforge.com/v1/mods/%1").arg(id);
}
[[nodiscard]] std::optional<QString> getDependencyURL(DependencySearchArgs const& args) const override
{
auto addonId = args.dependency.addonId.toString();

View File

@ -3,115 +3,31 @@
#include "FlameAPI.h"
#include "FlameModIndex.h"
#include <MurmurHash2.h>
#include <QHash>
#include <memory>
#include "Json.h"
#include "QObjectPtr.h"
#include "ResourceDownloadTask.h"
#include "minecraft/mod/ModFolderModel.h"
#include "minecraft/mod/tasks/GetModDependenciesTask.h"
#include "modplatform/ModIndex.h"
#include "net/ApiDownload.h"
#include "net/NetJob.h"
#include "tasks/Task.h"
static FlameAPI api;
bool FlameCheckUpdate::abort()
{
m_was_aborted = true;
if (m_net_job)
return m_net_job->abort();
return true;
}
ModPlatform::IndexedPack FlameCheckUpdate::getProjectInfo(ModPlatform::IndexedVersion& ver_info)
{
ModPlatform::IndexedPack pack;
QEventLoop loop;
auto get_project_job = new NetJob("Flame::GetProjectJob", APPLICATION->network());
auto response = std::make_shared<QByteArray>();
auto url = QString("https://api.curseforge.com/v1/mods/%1").arg(ver_info.addonId.toString());
auto dl = Net::ApiDownload::makeByteArray(url, response);
get_project_job->addNetAction(dl);
QObject::connect(get_project_job, &NetJob::succeeded, [response, &pack]() {
QJsonParseError parse_error{};
QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
if (parse_error.error != QJsonParseError::NoError) {
qWarning() << "Error while parsing JSON response from FlameCheckUpdate at " << parse_error.offset
<< " reason: " << parse_error.errorString();
qWarning() << *response;
return;
bool result = false;
if (m_task && m_task->canAbort()) {
result = m_task->abort();
}
try {
auto doc_obj = Json::requireObject(doc);
auto data_obj = Json::requireObject(doc_obj, "data");
FlameMod::loadIndexedPack(pack, data_obj);
} catch (Json::JsonException& e) {
qWarning() << e.cause();
qDebug() << doc;
}
});
connect(get_project_job, &NetJob::failed, this, &FlameCheckUpdate::emitFailed);
QObject::connect(get_project_job, &NetJob::finished, [&loop, get_project_job] {
get_project_job->deleteLater();
loop.quit();
});
get_project_job->start();
loop.exec();
return pack;
}
ModPlatform::IndexedVersion FlameCheckUpdate::getFileInfo(int addonId, int fileId)
{
ModPlatform::IndexedVersion ver;
QEventLoop loop;
auto get_file_info_job = new NetJob("Flame::GetFileInfoJob", APPLICATION->network());
auto response = std::make_shared<QByteArray>();
auto url = QString("https://api.curseforge.com/v1/mods/%1/files/%2").arg(QString::number(addonId), QString::number(fileId));
auto dl = Net::ApiDownload::makeByteArray(url, response);
get_file_info_job->addNetAction(dl);
QObject::connect(get_file_info_job, &NetJob::succeeded, [response, &ver]() {
QJsonParseError parse_error{};
QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
if (parse_error.error != QJsonParseError::NoError) {
qWarning() << "Error while parsing JSON response from FlameCheckUpdate at " << parse_error.offset
<< " reason: " << parse_error.errorString();
qWarning() << *response;
return;
}
try {
auto doc_obj = Json::requireObject(doc);
auto data_obj = Json::requireObject(doc_obj, "data");
ver = FlameMod::loadIndexedPackVersion(data_obj);
} catch (Json::JsonException& e) {
qWarning() << e.cause();
qDebug() << doc;
}
});
connect(get_file_info_job, &NetJob::failed, this, &FlameCheckUpdate::emitFailed);
QObject::connect(get_file_info_job, &NetJob::finished, [&loop, get_file_info_job] {
get_file_info_job->deleteLater();
loop.quit();
});
get_file_info_job->start();
loop.exec();
return ver;
Task::abort();
return result;
}
/* Check for update:
@ -123,19 +39,55 @@ void FlameCheckUpdate::executeTask()
{
setStatus(tr("Preparing resources for CurseForge..."));
int i = 0;
auto netJob = new NetJob("Get latest versions", APPLICATION->network());
connect(netJob, &Task::finished, this, &FlameCheckUpdate::collectBlockedMods);
connect(netJob, &Task::progress, this, &FlameCheckUpdate::setProgress);
connect(netJob, &Task::stepProgress, this, &FlameCheckUpdate::propagateStepProgress);
connect(netJob, &Task::details, this, &FlameCheckUpdate::setDetails);
for (auto* resource : m_resources) {
setStatus(tr("Getting API response from CurseForge for '%1'...").arg(resource->name()));
setProgress(i++, m_resources.size());
auto versions_url_optional = api.getVersionsURL({ { resource->metadata()->project_id.toString() }, m_game_versions });
if (!versions_url_optional.has_value())
continue;
auto latest_vers = api.getLatestVersions({ { resource->metadata()->project_id.toString() }, m_game_versions });
auto response = std::make_shared<QByteArray>();
auto task = Net::ApiDownload::makeByteArray(versions_url_optional.value(), response);
// Check if we were aborted while getting the latest version
if (m_was_aborted) {
aborted();
connect(task.get(), &Task::succeeded, this, [this, resource, response] { getLatestVersionCallback(resource, response); });
netJob->addNetAction(task);
}
m_task.reset(netJob);
m_task->start();
}
void FlameCheckUpdate::getLatestVersionCallback(Resource* resource, std::shared_ptr<QByteArray> response)
{
QJsonParseError parse_error{};
QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
if (parse_error.error != QJsonParseError::NoError) {
qWarning() << "Error while parsing JSON response from latest mod version at " << parse_error.offset
<< " reason: " << parse_error.errorString();
qWarning() << *response;
return;
}
auto latest_ver = api.getLatestVersion(latest_vers, m_loaders_list, resource->metadata()->loaders);
// Fake pack with the necessary info to pass to the download task :)
auto pack = std::make_shared<ModPlatform::IndexedPack>();
pack->name = resource->name();
pack->slug = resource->metadata()->slug;
pack->addonId = resource->metadata()->project_id;
pack->provider = ModPlatform::ResourceProvider::FLAME;
try {
auto obj = Json::requireObject(doc);
auto arr = Json::requireArray(obj, "data");
FlameMod::loadIndexedPackVersions(*pack.get(), arr);
} catch (Json::JsonException& e) {
qCritical() << "Failed to parse response from a version request.";
qCritical() << e.what();
qDebug() << doc;
}
auto latest_ver = api.getLatestVersion(pack->versions, m_loaders_list, resource->metadata()->loaders);
setStatus(tr("Parsing the API response from CurseForge for '%1'...").arg(resource->name()));
@ -149,23 +101,14 @@ void FlameCheckUpdate::executeTask()
reason = tr("No valid version found for this resource. It's probably unavailable for the current game version.");
emit checkFailed(resource, reason);
continue;
return;
}
if (latest_ver->downloadUrl.isEmpty() && latest_ver->fileId != resource->metadata()->file_id) {
auto pack = getProjectInfo(latest_ver.value());
auto recover_url = QString("%1/download/%2").arg(pack.websiteUrl, latest_ver->fileId.toString());
emit checkFailed(resource, tr("Resource has a new update available, but is not downloadable using CurseForge."), recover_url);
continue;
m_blocked[resource] = latest_ver->fileId.toString();
return;
}
// Fake pack with the necessary info to pass to the download task :)
auto pack = std::make_shared<ModPlatform::IndexedPack>();
pack->name = resource->name();
pack->slug = resource->metadata()->slug;
pack->addonId = resource->metadata()->project_id;
pack->provider = ModPlatform::ResourceProvider::FLAME;
if (!latest_ver->hash.isEmpty() &&
(resource->metadata()->hash != latest_ver->hash || resource->status() == ResourceStatus::NOT_INSTALLED)) {
auto old_version = resource->metadata()->version_number;
@ -182,7 +125,77 @@ void FlameCheckUpdate::executeTask()
ModPlatform::ResourceProvider::FLAME, download_task, resource->enabled());
}
m_deps.append(std::make_shared<GetModDependenciesTask::PackDependency>(pack, latest_ver.value()));
}
void FlameCheckUpdate::collectBlockedMods()
{
QStringList addonIds;
QHash<QString, Resource*> quickSearch;
for (auto const& resource : m_blocked.keys()) {
auto addonId = resource->metadata()->project_id.toString();
addonIds.append(addonId);
quickSearch[addonId] = resource;
}
auto response = std::make_shared<QByteArray>();
Task::Ptr projTask;
if (addonIds.isEmpty()) {
emitSucceeded();
return;
} else if (addonIds.size() == 1) {
projTask = api.getProject(*addonIds.begin(), response);
} else {
projTask = api.getProjects(addonIds, response);
}
connect(projTask.get(), &Task::succeeded, this, [this, response, addonIds, quickSearch] {
QJsonParseError parse_error{};
auto doc = QJsonDocument::fromJson(*response, &parse_error);
if (parse_error.error != QJsonParseError::NoError) {
qWarning() << "Error while parsing JSON response from Flame projects task at " << parse_error.offset
<< " reason: " << parse_error.errorString();
qWarning() << *response;
return;
}
try {
QJsonArray entries;
if (addonIds.size() == 1)
entries = { Json::requireObject(Json::requireObject(doc), "data") };
else
entries = Json::requireArray(Json::requireObject(doc), "data");
for (auto entry : entries) {
auto entry_obj = Json::requireObject(entry);
auto id = QString::number(Json::requireInteger(entry_obj, "id"));
auto resource = quickSearch.find(id).value();
ModPlatform::IndexedPack pack;
try {
setStatus(tr("Parsing API response from CurseForge for '%1'...").arg(resource->name()));
FlameMod::loadIndexedPack(pack, entry_obj);
auto recover_url = QString("%1/download/%2").arg(pack.websiteUrl, m_blocked[resource]);
emit checkFailed(resource, tr("Resource has a new update available, but is not downloadable using CurseForge."),
recover_url);
} catch (Json::JsonException& e) {
qDebug() << e.cause();
qDebug() << entries;
}
}
} catch (Json::JsonException& e) {
qDebug() << e.cause();
qDebug() << doc;
}
});
connect(projTask.get(), &Task::finished, this, &FlameCheckUpdate::emitSucceeded); // do not care much about error
connect(projTask.get(), &Task::progress, this, &FlameCheckUpdate::setProgress);
connect(projTask.get(), &Task::stepProgress, this, &FlameCheckUpdate::propagateStepProgress);
connect(projTask.get(), &Task::details, this, &FlameCheckUpdate::setDetails);
m_task.reset(projTask);
m_task->start();
}

View File

@ -1,7 +1,6 @@
#pragma once
#include "modplatform/CheckUpdateTask.h"
#include "net/NetJob.h"
class FlameCheckUpdate : public CheckUpdateTask {
Q_OBJECT
@ -19,12 +18,12 @@ class FlameCheckUpdate : public CheckUpdateTask {
protected slots:
void executeTask() override;
private slots:
void getLatestVersionCallback(Resource* resource, std::shared_ptr<QByteArray> response);
void collectBlockedMods();
private:
ModPlatform::IndexedPack getProjectInfo(ModPlatform::IndexedVersion& ver_info);
ModPlatform::IndexedVersion getFileInfo(int addonId, int fileId);
Task::Ptr m_task = nullptr;
NetJob* m_net_job = nullptr;
bool m_was_aborted = false;
QHash<Resource*, QString> m_blocked;
};

View File

@ -442,7 +442,7 @@ bool FlameCreationTask::createInstance()
instance.setName(name());
m_modIdResolver.reset(new Flame::FileResolvingTask(APPLICATION->network(), m_pack));
m_modIdResolver.reset(new Flame::FileResolvingTask(m_pack));
connect(m_modIdResolver.get(), &Flame::FileResolvingTask::succeeded, this, [this, &loop] { idResolverSucceeded(loop); });
connect(m_modIdResolver.get(), &Flame::FileResolvingTask::failed, [this, &loop](QString reason) {
m_modIdResolver.reset();

View File

@ -76,10 +76,7 @@ static QString enumToString(int hash_algorithm)
}
}
void FlameMod::loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
QJsonArray& arr,
[[maybe_unused]] const shared_qobject_ptr<QNetworkAccessManager>& network,
const BaseInstance* inst)
void FlameMod::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, QJsonArray& arr)
{
QVector<ModPlatform::IndexedVersion> unsortedVersions;
for (auto versionIter : arr) {

View File

@ -6,7 +6,6 @@
#include "modplatform/ModIndex.h"
#include <QNetworkAccessManager>
#include "BaseInstance.h"
namespace FlameMod {
@ -14,10 +13,7 @@ namespace FlameMod {
void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj);
void loadURLs(ModPlatform::IndexedPack& m, QJsonObject& obj);
void loadBody(ModPlatform::IndexedPack& m, QJsonObject& obj);
void loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
QJsonArray& arr,
const shared_qobject_ptr<QNetworkAccessManager>& network,
const BaseInstance* inst);
auto loadIndexedPackVersion(QJsonObject& obj, bool load_changelog = false) -> ModPlatform::IndexedVersion;
auto loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr, const BaseInstance* inst) -> ModPlatform::IndexedVersion;
void loadIndexedPackVersions(ModPlatform::IndexedPack& pack, QJsonArray& arr);
ModPlatform::IndexedVersion loadIndexedPackVersion(QJsonObject& obj, bool load_changelog = false);
ModPlatform::IndexedVersion loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr, const BaseInstance* inst);
} // namespace FlameMod

View File

@ -112,7 +112,7 @@ void Modrinth::loadExtraPackData(ModPlatform::IndexedPack& pack, QJsonObject& ob
pack.extraDataLoaded = true;
}
void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, QJsonArray& arr, const BaseInstance* inst)
void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, QJsonArray& arr)
{
QVector<ModPlatform::IndexedVersion> unsortedVersions;
for (auto versionIter : arr) {

View File

@ -19,14 +19,13 @@
#include "modplatform/ModIndex.h"
#include <QNetworkAccessManager>
#include "BaseInstance.h"
namespace Modrinth {
void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj);
void loadExtraPackData(ModPlatform::IndexedPack& m, QJsonObject& obj);
void loadIndexedPackVersions(ModPlatform::IndexedPack& pack, QJsonArray& arr, const BaseInstance* inst);
void loadIndexedPackVersions(ModPlatform::IndexedPack& pack, QJsonArray& arr);
auto loadIndexedPackVersion(QJsonObject& obj, QString hash_type = "sha512", QString filename_prefer = "") -> ModPlatform::IndexedVersion;
auto loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr, const BaseInstance* inst) -> ModPlatform::IndexedVersion;

View File

@ -32,7 +32,7 @@ void FlameModModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObject&
void FlameModModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
{
FlameMod::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance);
FlameMod::loadIndexedPackVersions(m, arr);
}
auto FlameModModel::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion
@ -65,7 +65,7 @@ void FlameResourcePackModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, QJso
void FlameResourcePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
{
FlameMod::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance);
FlameMod::loadIndexedPackVersions(m, arr);
}
bool FlameResourcePackModel::optedOut(const ModPlatform::IndexedVersion& ver) const
@ -93,7 +93,7 @@ void FlameTexturePackModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, QJson
void FlameTexturePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
{
FlameMod::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance);
FlameMod::loadIndexedPackVersions(m, arr);
QVector<ModPlatform::IndexedVersion> filtered_versions(m.versions.size());
@ -157,7 +157,7 @@ void FlameShaderPackModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonO
void FlameShaderPackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
{
FlameMod::loadIndexedPackVersions(m, arr, APPLICATION->network(), &m_base_instance);
FlameMod::loadIndexedPackVersions(m, arr);
}
bool FlameShaderPackModel::optedOut(const ModPlatform::IndexedVersion& ver) const

View File

@ -39,7 +39,7 @@ void ModrinthModModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, QJsonObjec
void ModrinthModModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
{
::Modrinth::loadIndexedPackVersions(m, arr, &m_base_instance);
::Modrinth::loadIndexedPackVersions(m, arr);
}
auto ModrinthModModel::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion
@ -66,7 +66,7 @@ void ModrinthResourcePackModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, Q
void ModrinthResourcePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
{
::Modrinth::loadIndexedPackVersions(m, arr, &m_base_instance);
::Modrinth::loadIndexedPackVersions(m, arr);
}
auto ModrinthResourcePackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray
@ -88,7 +88,7 @@ void ModrinthTexturePackModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, QJ
void ModrinthTexturePackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
{
::Modrinth::loadIndexedPackVersions(m, arr, &m_base_instance);
::Modrinth::loadIndexedPackVersions(m, arr);
}
auto ModrinthTexturePackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray
@ -110,7 +110,7 @@ void ModrinthShaderPackModel::loadExtraPackInfo(ModPlatform::IndexedPack& m, QJs
void ModrinthShaderPackModel::loadIndexedPackVersions(ModPlatform::IndexedPack& m, QJsonArray& arr)
{
::Modrinth::loadIndexedPackVersions(m, arr, &m_base_instance);
::Modrinth::loadIndexedPackVersions(m, arr);
}
auto ModrinthShaderPackModel::documentToArray(QJsonDocument& obj) const -> QJsonArray