Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into feat/acknowledge_release_type
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
@ -25,17 +25,40 @@ void Flame::FileResolvingTask::executeTask()
|
||||
setProgress(0, 3);
|
||||
m_dljob.reset(new NetJob("Mod id resolver", m_network));
|
||||
result.reset(new QByteArray());
|
||||
//build json data to send
|
||||
// build json data to send
|
||||
QJsonObject object;
|
||||
|
||||
object["fileIds"] = QJsonArray::fromVariantList(std::accumulate(m_toProcess.files.begin(), m_toProcess.files.end(), QVariantList(), [](QVariantList& l, const File& s) {
|
||||
l.push_back(s.fileId);
|
||||
return l;
|
||||
}));
|
||||
object["fileIds"] = QJsonArray::fromVariantList(
|
||||
std::accumulate(m_toProcess.files.begin(), m_toProcess.files.end(), QVariantList(), [](QVariantList& l, const File& s) {
|
||||
l.push_back(s.fileId);
|
||||
return l;
|
||||
}));
|
||||
QByteArray data = Json::toText(object);
|
||||
auto dl = Net::Upload::makeByteArray(QUrl("https://api.curseforge.com/v1/mods/files"), result.get(), data);
|
||||
auto dl = Net::Upload::makeByteArray(QUrl("https://api.curseforge.com/v1/mods/files"), result, data);
|
||||
m_dljob->addNetAction(dl);
|
||||
connect(m_dljob.get(), &NetJob::finished, this, &Flame::FileResolvingTask::netJobFinished);
|
||||
|
||||
auto step_progress = std::make_shared<TaskStepProgress>();
|
||||
connect(m_dljob.get(), &NetJob::finished, this, [this, step_progress]() {
|
||||
step_progress->state = TaskStepState::Succeeded;
|
||||
stepProgress(*step_progress);
|
||||
netJobFinished();
|
||||
});
|
||||
connect(m_dljob.get(), &NetJob::failed, this, [this, step_progress](QString reason) {
|
||||
step_progress->state = TaskStepState::Failed;
|
||||
stepProgress(*step_progress);
|
||||
emitFailed(reason);
|
||||
});
|
||||
connect(m_dljob.get(), &NetJob::stepProgress, this, &FileResolvingTask::propogateStepProgress);
|
||||
connect(m_dljob.get(), &NetJob::progress, this, [this, step_progress](qint64 current, qint64 total) {
|
||||
qDebug() << "Resolve slug progress" << current << total;
|
||||
step_progress->update(current, total);
|
||||
stepProgress(*step_progress);
|
||||
});
|
||||
connect(m_dljob.get(), &NetJob::status, this, [this, step_progress](QString status) {
|
||||
step_progress->status = status;
|
||||
stepProgress(*step_progress);
|
||||
});
|
||||
|
||||
m_dljob->start();
|
||||
}
|
||||
|
||||
@ -44,7 +67,7 @@ void Flame::FileResolvingTask::netJobFinished()
|
||||
setProgress(1, 3);
|
||||
// job to check modrinth for blocked projects
|
||||
m_checkJob.reset(new NetJob("Modrinth check", m_network));
|
||||
blockedProjects = QMap<File *,QByteArray *>();
|
||||
blockedProjects = QMap<File*, std::shared_ptr<QByteArray>>();
|
||||
|
||||
QJsonDocument doc;
|
||||
QJsonArray array;
|
||||
@ -65,24 +88,42 @@ void Flame::FileResolvingTask::netJobFinished()
|
||||
auto fileid = Json::requireInteger(Json::requireObject(file)["id"]);
|
||||
auto& out = m_toProcess.files[fileid];
|
||||
try {
|
||||
out.parseFromObject(Json::requireObject(file));
|
||||
out.parseFromObject(Json::requireObject(file));
|
||||
} catch (const JSONValidationError& e) {
|
||||
qDebug() << "Blocked mod on curseforge" << out.fileName;
|
||||
auto hash = out.hash;
|
||||
if(!hash.isEmpty()) {
|
||||
if (!hash.isEmpty()) {
|
||||
auto url = QString("https://api.modrinth.com/v2/version_file/%1?algorithm=sha1").arg(hash);
|
||||
auto output = new QByteArray();
|
||||
auto output = std::make_shared<QByteArray>();
|
||||
auto dl = Net::Download::makeByteArray(QUrl(url), output);
|
||||
QObject::connect(dl.get(), &Net::Download::succeeded, [&out]() {
|
||||
out.resolved = true;
|
||||
});
|
||||
QObject::connect(dl.get(), &Net::Download::succeeded, [&out]() { out.resolved = true; });
|
||||
|
||||
m_checkJob->addNetAction(dl);
|
||||
blockedProjects.insert(&out, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
connect(m_checkJob.get(), &NetJob::finished, this, &Flame::FileResolvingTask::modrinthCheckFinished);
|
||||
auto step_progress = std::make_shared<TaskStepProgress>();
|
||||
connect(m_checkJob.get(), &NetJob::finished, this, [this, step_progress]() {
|
||||
step_progress->state = TaskStepState::Succeeded;
|
||||
stepProgress(*step_progress);
|
||||
modrinthCheckFinished();
|
||||
});
|
||||
connect(m_checkJob.get(), &NetJob::failed, this, [this, step_progress](QString reason) {
|
||||
step_progress->state = TaskStepState::Failed;
|
||||
stepProgress(*step_progress);
|
||||
emitFailed(reason);
|
||||
});
|
||||
connect(m_checkJob.get(), &NetJob::stepProgress, this, &FileResolvingTask::propogateStepProgress);
|
||||
connect(m_checkJob.get(), &NetJob::progress, this, [this, step_progress](qint64 current, qint64 total) {
|
||||
qDebug() << "Resolve slug progress" << current << total;
|
||||
step_progress->update(current, total);
|
||||
stepProgress(*step_progress);
|
||||
});
|
||||
connect(m_checkJob.get(), &NetJob::status, this, [this, step_progress](QString status) {
|
||||
step_progress->status = status;
|
||||
stepProgress(*step_progress);
|
||||
});
|
||||
|
||||
m_checkJob->start();
|
||||
}
|
||||
@ -95,7 +136,6 @@ void Flame::FileResolvingTask::modrinthCheckFinished() {
|
||||
auto &out = *it;
|
||||
auto bytes = blockedProjects[out];
|
||||
if (!out->resolved) {
|
||||
delete bytes;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -112,11 +152,9 @@ void Flame::FileResolvingTask::modrinthCheckFinished() {
|
||||
} else {
|
||||
out->resolved = false;
|
||||
}
|
||||
|
||||
delete bytes;
|
||||
}
|
||||
//copy to an output list and filter out projects found on modrinth
|
||||
auto block = new QList<File *>();
|
||||
auto block = std::make_shared<QList<File*>>();
|
||||
auto it = blockedProjects.keys();
|
||||
std::copy_if(it.begin(), it.end(), std::back_inserter(*block), [](File *f) {
|
||||
return !f->resolved;
|
||||
@ -124,32 +162,48 @@ void Flame::FileResolvingTask::modrinthCheckFinished() {
|
||||
//Display not found mods early
|
||||
if (!block->empty()) {
|
||||
//blocked mods found, we need the slug for displaying.... we need another job :D !
|
||||
auto slugJob = new NetJob("Slug Job", m_network);
|
||||
auto slugs = QVector<QByteArray>(block->size());
|
||||
auto index = 0;
|
||||
for (auto fileInfo: *block) {
|
||||
auto projectId = fileInfo->projectId;
|
||||
slugs[index] = QByteArray();
|
||||
m_slugJob.reset(new NetJob("Slug Job", m_network));
|
||||
int index = 0;
|
||||
for (auto mod : *block) {
|
||||
auto projectId = mod->projectId;
|
||||
auto output = std::make_shared<QByteArray>();
|
||||
auto url = QString("https://api.curseforge.com/v1/mods/%1").arg(projectId);
|
||||
auto dl = Net::Download::makeByteArray(url, &slugs[index]);
|
||||
slugJob->addNetAction(dl);
|
||||
index++;
|
||||
}
|
||||
connect(slugJob, &NetJob::succeeded, this, [slugs, this, slugJob, block]() {
|
||||
slugJob->deleteLater();
|
||||
auto index = 0;
|
||||
for (const auto &slugResult: slugs) {
|
||||
auto json = QJsonDocument::fromJson(slugResult);
|
||||
auto dl = Net::Download::makeByteArray(url, output);
|
||||
qDebug() << "Fetching url slug for file:" << mod->fileName;
|
||||
QObject::connect(dl.get(), &Net::Download::succeeded, [block, index, output]() {
|
||||
auto mod = block->at(index); // use the shared_ptr so it is captured and only freed when we are done
|
||||
auto json = QJsonDocument::fromJson(*output);
|
||||
auto base = Json::requireString(Json::requireObject(Json::requireObject(Json::requireObject(json),"data"),"links"),
|
||||
"websiteUrl");
|
||||
auto mod = block->at(index);
|
||||
auto link = QString("%1/download/%2").arg(base, QString::number(mod->fileId));
|
||||
mod->websiteUrl = link;
|
||||
index++;
|
||||
}
|
||||
});
|
||||
m_slugJob->addNetAction(dl);
|
||||
index++;
|
||||
}
|
||||
auto step_progress = std::make_shared<TaskStepProgress>();
|
||||
connect(m_slugJob.get(), &NetJob::succeeded, this, [this, step_progress]() {
|
||||
step_progress->state = TaskStepState::Succeeded;
|
||||
stepProgress(*step_progress);
|
||||
emitSucceeded();
|
||||
});
|
||||
slugJob->start();
|
||||
connect(m_slugJob.get(), &NetJob::failed, this, [this, step_progress](QString reason) {
|
||||
step_progress->state = TaskStepState::Failed;
|
||||
stepProgress(*step_progress);
|
||||
emitFailed(reason);
|
||||
});
|
||||
connect(m_slugJob.get(), &NetJob::stepProgress, this, &FileResolvingTask::propogateStepProgress);
|
||||
connect(m_slugJob.get(), &NetJob::progress, this, [this, step_progress](qint64 current, qint64 total) {
|
||||
qDebug() << "Resolve slug progress" << current << total;
|
||||
step_progress->update(current, total);
|
||||
stepProgress(*step_progress);
|
||||
});
|
||||
connect(m_slugJob.get(), &NetJob::status, this, [this, step_progress](QString status) {
|
||||
step_progress->status = status;
|
||||
stepProgress(*step_progress);
|
||||
});
|
||||
|
||||
m_slugJob->start();
|
||||
} else {
|
||||
emitSucceeded();
|
||||
}
|
||||
|
@ -1,41 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include "tasks/Task.h"
|
||||
#include "net/NetJob.h"
|
||||
#include "PackManifest.h"
|
||||
#include "net/NetJob.h"
|
||||
#include "tasks/Task.h"
|
||||
|
||||
namespace Flame
|
||||
{
|
||||
class FileResolvingTask : public Task
|
||||
{
|
||||
namespace Flame {
|
||||
class FileResolvingTask : public Task {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FileResolvingTask(const shared_qobject_ptr<QNetworkAccessManager>& network, Flame::Manifest &toProcess);
|
||||
virtual ~FileResolvingTask() {};
|
||||
public:
|
||||
explicit FileResolvingTask(const shared_qobject_ptr<QNetworkAccessManager>& network, Flame::Manifest& toProcess);
|
||||
virtual ~FileResolvingTask(){};
|
||||
|
||||
bool canAbort() const override { return true; }
|
||||
bool abort() override;
|
||||
|
||||
const Flame::Manifest &getResults() const
|
||||
{
|
||||
return m_toProcess;
|
||||
}
|
||||
const Flame::Manifest& getResults() const { return m_toProcess; }
|
||||
|
||||
protected:
|
||||
protected:
|
||||
virtual void executeTask() override;
|
||||
|
||||
protected slots:
|
||||
protected slots:
|
||||
void netJobFinished();
|
||||
|
||||
private: /* data */
|
||||
private: /* data */
|
||||
shared_qobject_ptr<QNetworkAccessManager> m_network;
|
||||
Flame::Manifest m_toProcess;
|
||||
std::shared_ptr<QByteArray> result;
|
||||
std::shared_ptr<QByteArray> result;
|
||||
NetJob::Ptr m_dljob;
|
||||
NetJob::Ptr m_checkJob;
|
||||
NetJob::Ptr m_checkJob;
|
||||
NetJob::Ptr m_slugJob;
|
||||
|
||||
void modrinthCheckFinished();
|
||||
|
||||
QMap<File *, QByteArray *> blockedProjects;
|
||||
QMap<File*, std::shared_ptr<QByteArray>> blockedProjects;
|
||||
};
|
||||
}
|
||||
} // namespace Flame
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "net/NetJob.h"
|
||||
#include "net/Upload.h"
|
||||
|
||||
Task::Ptr FlameAPI::matchFingerprints(const QList<uint>& fingerprints, QByteArray* response)
|
||||
Task::Ptr FlameAPI::matchFingerprints(const QList<uint>& fingerprints, std::shared_ptr<QByteArray> response)
|
||||
{
|
||||
auto netJob = makeShared<NetJob>(QString("Flame::MatchFingerprints"), APPLICATION->network());
|
||||
|
||||
@ -28,8 +28,6 @@ Task::Ptr FlameAPI::matchFingerprints(const QList<uint>& fingerprints, QByteArra
|
||||
|
||||
netJob->addNetAction(Net::Upload::makeByteArray(QString("https://api.curseforge.com/v1/fingerprints"), response, body_raw));
|
||||
|
||||
QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; });
|
||||
|
||||
return netJob;
|
||||
}
|
||||
|
||||
@ -38,14 +36,14 @@ auto FlameAPI::getModFileChangelog(int modId, int fileId) -> QString
|
||||
QEventLoop lock;
|
||||
QString changelog;
|
||||
|
||||
auto* netJob = new NetJob(QString("Flame::FileChangelog"), APPLICATION->network());
|
||||
auto* response = new QByteArray();
|
||||
auto netJob = makeShared<NetJob>(QString("Flame::FileChangelog"), APPLICATION->network());
|
||||
auto response = std::make_shared<QByteArray>();
|
||||
netJob->addNetAction(Net::Download::makeByteArray(
|
||||
QString("https://api.curseforge.com/v1/mods/%1/files/%2/changelog")
|
||||
.arg(QString::fromStdString(std::to_string(modId)), QString::fromStdString(std::to_string(fileId))),
|
||||
response));
|
||||
|
||||
QObject::connect(netJob, &NetJob::succeeded, [netJob, response, &changelog] {
|
||||
QObject::connect(netJob.get(), &NetJob::succeeded, [&netJob, response, &changelog] {
|
||||
QJsonParseError parse_error{};
|
||||
QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
|
||||
if (parse_error.error != QJsonParseError::NoError) {
|
||||
@ -60,10 +58,7 @@ auto FlameAPI::getModFileChangelog(int modId, int fileId) -> QString
|
||||
changelog = Json::ensureString(doc.object(), "data");
|
||||
});
|
||||
|
||||
QObject::connect(netJob, &NetJob::finished, [response, &lock] {
|
||||
delete response;
|
||||
lock.quit();
|
||||
});
|
||||
QObject::connect(netJob.get(), &NetJob::finished, [&lock] { lock.quit(); });
|
||||
|
||||
netJob->start();
|
||||
lock.exec();
|
||||
@ -76,13 +71,12 @@ auto FlameAPI::getModDescription(int modId) -> QString
|
||||
QEventLoop lock;
|
||||
QString description;
|
||||
|
||||
auto* netJob = new NetJob(QString("Flame::ModDescription"), APPLICATION->network());
|
||||
auto* response = new QByteArray();
|
||||
netJob->addNetAction(Net::Download::makeByteArray(
|
||||
QString("https://api.curseforge.com/v1/mods/%1/description")
|
||||
.arg(QString::number(modId)), response));
|
||||
auto netJob = makeShared<NetJob>(QString("Flame::ModDescription"), APPLICATION->network());
|
||||
auto response = std::make_shared<QByteArray>();
|
||||
netJob->addNetAction(
|
||||
Net::Download::makeByteArray(QString("https://api.curseforge.com/v1/mods/%1/description").arg(QString::number(modId)), response));
|
||||
|
||||
QObject::connect(netJob, &NetJob::succeeded, [netJob, response, &description] {
|
||||
QObject::connect(netJob.get(), &NetJob::succeeded, [&netJob, response, &description] {
|
||||
QJsonParseError parse_error{};
|
||||
QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
|
||||
if (parse_error.error != QJsonParseError::NoError) {
|
||||
@ -97,10 +91,7 @@ auto FlameAPI::getModDescription(int modId) -> QString
|
||||
description = Json::ensureString(doc.object(), "data");
|
||||
});
|
||||
|
||||
QObject::connect(netJob, &NetJob::finished, [response, &lock] {
|
||||
delete response;
|
||||
lock.quit();
|
||||
});
|
||||
QObject::connect(netJob.get(), &NetJob::finished, [&lock] { lock.quit(); });
|
||||
|
||||
netJob->start();
|
||||
lock.exec();
|
||||
@ -118,13 +109,13 @@ auto FlameAPI::getLatestVersion(VersionSearchArgs&& args) -> ModPlatform::Indexe
|
||||
|
||||
QEventLoop loop;
|
||||
|
||||
auto netJob = new NetJob(QString("Flame::GetLatestVersion(%1)").arg(args.pack.name), APPLICATION->network());
|
||||
auto response = new QByteArray();
|
||||
auto netJob = makeShared<NetJob>(QString("Flame::GetLatestVersion(%1)").arg(args.pack.name), APPLICATION->network());
|
||||
auto response = std::make_shared<QByteArray>();
|
||||
ModPlatform::IndexedVersion ver;
|
||||
|
||||
netJob->addNetAction(Net::Download::makeByteArray(versions_url, response));
|
||||
|
||||
QObject::connect(netJob, &NetJob::succeeded, [response, args, &ver] {
|
||||
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) {
|
||||
@ -145,7 +136,7 @@ auto FlameAPI::getLatestVersion(VersionSearchArgs&& args) -> ModPlatform::Indexe
|
||||
auto file_obj = Json::requireObject(file);
|
||||
auto file_tmp = FlameMod::loadIndexedPackVersion(file_obj);
|
||||
bool better_release = file_tmp.verison_type <= ver_tmp.verison_type;
|
||||
if(file_tmp.date > ver_tmp.date && better_release) {
|
||||
if (file_tmp.date > ver_tmp.date && better_release) {
|
||||
ver_tmp = file_tmp;
|
||||
latest_file_obj = file_obj;
|
||||
}
|
||||
@ -159,11 +150,7 @@ auto FlameAPI::getLatestVersion(VersionSearchArgs&& args) -> ModPlatform::Indexe
|
||||
}
|
||||
});
|
||||
|
||||
QObject::connect(netJob, &NetJob::finished, [response, netJob, &loop] {
|
||||
netJob->deleteLater();
|
||||
delete response;
|
||||
loop.quit();
|
||||
});
|
||||
QObject::connect(netJob.get(), &NetJob::finished, [&loop] { loop.quit(); });
|
||||
|
||||
netJob->start();
|
||||
|
||||
@ -172,7 +159,7 @@ auto FlameAPI::getLatestVersion(VersionSearchArgs&& args) -> ModPlatform::Indexe
|
||||
return ver;
|
||||
}
|
||||
|
||||
Task::Ptr FlameAPI::getProjects(QStringList addonIds, QByteArray* response) const
|
||||
Task::Ptr FlameAPI::getProjects(QStringList addonIds, std::shared_ptr<QByteArray> response) const
|
||||
{
|
||||
auto netJob = makeShared<NetJob>(QString("Flame::GetProjects"), APPLICATION->network());
|
||||
|
||||
@ -189,13 +176,12 @@ Task::Ptr FlameAPI::getProjects(QStringList addonIds, QByteArray* response) cons
|
||||
|
||||
netJob->addNetAction(Net::Upload::makeByteArray(QString("https://api.curseforge.com/v1/mods"), response, body_raw));
|
||||
|
||||
QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; });
|
||||
QObject::connect(netJob.get(), &NetJob::failed, [body_raw] { qDebug() << body_raw; });
|
||||
|
||||
return netJob;
|
||||
}
|
||||
|
||||
Task::Ptr FlameAPI::getFiles(const QStringList& fileIds, QByteArray* response) const
|
||||
Task::Ptr FlameAPI::getFiles(const QStringList& fileIds, std::shared_ptr<QByteArray> response) const
|
||||
{
|
||||
auto netJob = makeShared<NetJob>(QString("Flame::GetFiles"), APPLICATION->network());
|
||||
|
||||
@ -212,7 +198,6 @@ Task::Ptr FlameAPI::getFiles(const QStringList& fileIds, QByteArray* response) c
|
||||
|
||||
netJob->addNetAction(Net::Upload::makeByteArray(QString("https://api.curseforge.com/v1/mods/files"), response, body_raw));
|
||||
|
||||
QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; });
|
||||
QObject::connect(netJob.get(), &NetJob::failed, [body_raw] { qDebug() << body_raw; });
|
||||
|
||||
return netJob;
|
||||
|
@ -4,7 +4,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include "modplatform/ModIndex.h"
|
||||
#include "modplatform/ResourceAPI.h"
|
||||
#include "modplatform/helpers/NetworkResourceAPI.h"
|
||||
|
||||
class FlameAPI : public NetworkResourceAPI {
|
||||
@ -14,9 +17,9 @@ class FlameAPI : public NetworkResourceAPI {
|
||||
|
||||
auto getLatestVersion(VersionSearchArgs&& args) -> ModPlatform::IndexedVersion;
|
||||
|
||||
Task::Ptr getProjects(QStringList addonIds, QByteArray* response) const override;
|
||||
Task::Ptr matchFingerprints(const QList<uint>& fingerprints, QByteArray* response);
|
||||
Task::Ptr getFiles(const QStringList& fileIds, QByteArray* response) const;
|
||||
Task::Ptr getProjects(QStringList addonIds, std::shared_ptr<QByteArray> response) const override;
|
||||
Task::Ptr matchFingerprints(const QList<uint>& fingerprints, std::shared_ptr<QByteArray> response);
|
||||
Task::Ptr getFiles(const QStringList& fileIds, std::shared_ptr<QByteArray> response) const;
|
||||
|
||||
[[nodiscard]] auto getSortingMethods() const -> QList<ResourceAPI::SortingMethod> override;
|
||||
|
||||
@ -41,14 +44,15 @@ class FlameAPI : public NetworkResourceAPI {
|
||||
return 4;
|
||||
// TODO: remove this once Quilt drops official Fabric support
|
||||
if (loaders & Quilt) // NOTE: Most if not all Fabric mods should work *currently*
|
||||
return 4; // Quilt would probably be 5
|
||||
return 4; // Quilt would probably be 5
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
[[nodiscard]] std::optional<QString> getSearchURL(SearchArgs const& args) const override
|
||||
{
|
||||
auto gameVersionStr = args.versions.has_value() ? QString("gameVersion=%1").arg(args.versions.value().front().toString()) : QString();
|
||||
auto gameVersionStr =
|
||||
args.versions.has_value() ? QString("gameVersion=%1").arg(args.versions.value().front().toString()) : QString();
|
||||
|
||||
QStringList get_arguments;
|
||||
get_arguments.append(QString("classId=%1").arg(getClassId(args.type)));
|
||||
@ -73,14 +77,48 @@ class FlameAPI : public NetworkResourceAPI {
|
||||
|
||||
[[nodiscard]] std::optional<QString> getVersionsURL(VersionSearchArgs const& args) const override
|
||||
{
|
||||
QString url{QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&").arg(args.pack.addonId.toString())};
|
||||
auto addonId = args.pack.addonId.toString();
|
||||
QString url{ QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&").arg(addonId) };
|
||||
|
||||
QStringList get_parameters;
|
||||
if (args.mcVersions.has_value())
|
||||
get_parameters.append(QString("gameVersion=%1").arg(args.mcVersions.value().front().toString()));
|
||||
if (args.loaders.has_value())
|
||||
get_parameters.append(QString("modLoaderType=%1").arg(getMappedModLoader(args.loaders.value())));
|
||||
|
||||
if (args.loaders.has_value()) {
|
||||
int mappedModLoader = getMappedModLoader(args.loaders.value());
|
||||
|
||||
if (args.loaders.value() & Quilt) {
|
||||
auto overide = ModPlatform::getOverrideDeps();
|
||||
auto over = std::find_if(overide.cbegin(), overide.cend(), [addonId](auto dep) {
|
||||
return dep.provider == ModPlatform::ResourceProvider::FLAME && addonId == dep.quilt;
|
||||
});
|
||||
if (over != overide.cend()) {
|
||||
mappedModLoader = 5;
|
||||
}
|
||||
}
|
||||
|
||||
get_parameters.append(QString("modLoaderType=%1").arg(mappedModLoader));
|
||||
}
|
||||
|
||||
return url + get_parameters.join('&');
|
||||
};
|
||||
|
||||
[[nodiscard]] std::optional<QString> getDependencyURL(DependencySearchArgs const& args) const override
|
||||
{
|
||||
auto mappedModLoader = getMappedModLoader(args.loader);
|
||||
auto addonId = args.dependency.addonId.toString();
|
||||
if (args.loader & Quilt) {
|
||||
auto overide = ModPlatform::getOverrideDeps();
|
||||
auto over = std::find_if(overide.cbegin(), overide.cend(), [addonId](auto dep) {
|
||||
return dep.provider == ModPlatform::ResourceProvider::FLAME && addonId == dep.quilt;
|
||||
});
|
||||
if (over != overide.cend()) {
|
||||
mappedModLoader = 5;
|
||||
}
|
||||
}
|
||||
return QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&gameVersion=%2&modLoaderType=%3")
|
||||
.arg(addonId)
|
||||
.arg(args.mcVersion.toString())
|
||||
.arg(mappedModLoader);
|
||||
};
|
||||
};
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "FlameModIndex.h"
|
||||
|
||||
#include <MurmurHash2.h>
|
||||
#include <memory>
|
||||
|
||||
#include "FileSystem.h"
|
||||
#include "Json.h"
|
||||
@ -30,7 +31,7 @@ ModPlatform::IndexedPack getProjectInfo(ModPlatform::IndexedVersion& ver_info)
|
||||
|
||||
auto get_project_job = new NetJob("Flame::GetProjectJob", APPLICATION->network());
|
||||
|
||||
auto response = new QByteArray();
|
||||
auto response = std::make_shared<QByteArray>();
|
||||
auto url = QString("https://api.curseforge.com/v1/mods/%1").arg(ver_info.addonId.toString());
|
||||
auto dl = Net::Download::makeByteArray(url, response);
|
||||
get_project_job->addNetAction(dl);
|
||||
@ -74,7 +75,7 @@ ModPlatform::IndexedVersion getFileInfo(int addonId, int fileId)
|
||||
|
||||
auto get_file_info_job = new NetJob("Flame::GetFileInfoJob", APPLICATION->network());
|
||||
|
||||
auto response = new QByteArray();
|
||||
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::Download::makeByteArray(url, response);
|
||||
get_file_info_job->addNetAction(dl);
|
||||
@ -129,8 +130,7 @@ void FlameCheckUpdate::executeTask()
|
||||
setStatus(tr("Getting API response from CurseForge for '%1'...").arg(mod->name()));
|
||||
setProgress(i++, m_mods.size());
|
||||
|
||||
ModPlatform::IndexedPack pack{ mod->metadata()->project_id.toString() };
|
||||
auto latest_ver = api.getLatestVersion({ pack, m_game_versions, m_loaders });
|
||||
auto latest_ver = api.getLatestVersion({ { mod->metadata()->project_id.toString() }, m_game_versions, m_loaders });
|
||||
|
||||
// Check if we were aborted while getting the latest version
|
||||
if (m_was_aborted) {
|
||||
@ -156,15 +156,15 @@ void FlameCheckUpdate::executeTask()
|
||||
|
||||
if (!latest_ver.hash.isEmpty() && (mod->metadata()->hash != latest_ver.hash || mod->status() == ModStatus::NotInstalled)) {
|
||||
// Fake pack with the necessary info to pass to the download task :)
|
||||
ModPlatform::IndexedPack pack;
|
||||
pack.name = mod->name();
|
||||
pack.slug = mod->metadata()->slug;
|
||||
pack.addonId = mod->metadata()->project_id;
|
||||
pack.websiteUrl = mod->homeurl();
|
||||
auto pack = std::make_shared<ModPlatform::IndexedPack>();
|
||||
pack->name = mod->name();
|
||||
pack->slug = mod->metadata()->slug;
|
||||
pack->addonId = mod->metadata()->project_id;
|
||||
pack->websiteUrl = mod->homeurl();
|
||||
for (auto& author : mod->authors())
|
||||
pack.authors.append({ author });
|
||||
pack.description = mod->description();
|
||||
pack.provider = ModPlatform::ResourceProvider::FLAME;
|
||||
pack->authors.append({ author });
|
||||
pack->description = mod->description();
|
||||
pack->provider = ModPlatform::ResourceProvider::FLAME;
|
||||
|
||||
auto old_version = mod->version();
|
||||
if (old_version.isEmpty() && mod->status() != ModStatus::NotInstalled) {
|
||||
@ -173,7 +173,7 @@ void FlameCheckUpdate::executeTask()
|
||||
}
|
||||
|
||||
auto download_task = makeShared<ResourceDownloadTask>(pack, latest_ver, m_mods_folder);
|
||||
m_updatable.emplace_back(pack.name, mod->metadata()->hash, old_version, latest_ver.version, latest_ver.verison_type,
|
||||
m_updatable.emplace_back(pack->name, mod->metadata()->hash, old_version, latest_ver.version, latest_ver.verison_type,
|
||||
api.getModFileChangelog(latest_ver.addonId.toInt(), latest_ver.fileId.toInt()),
|
||||
ModPlatform::ResourceProvider::FLAME, download_task);
|
||||
}
|
||||
|
@ -153,6 +153,9 @@ bool FlameCreationTask::updateInstance()
|
||||
|
||||
old_files.remove(file.key());
|
||||
files_iterator = files.erase(files_iterator);
|
||||
|
||||
if (files_iterator != files.begin())
|
||||
files_iterator--;
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,7 +182,7 @@ bool FlameCreationTask::updateInstance()
|
||||
fileIds.append(QString::number(file.fileId));
|
||||
}
|
||||
|
||||
auto* raw_response = new QByteArray;
|
||||
auto raw_response = std::make_shared<QByteArray>();
|
||||
auto job = api.getFiles(fileIds, raw_response);
|
||||
|
||||
QEventLoop loop;
|
||||
@ -384,6 +387,7 @@ bool FlameCreationTask::createInstance()
|
||||
connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::progress, this, &FlameCreationTask::setProgress);
|
||||
connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::status, this, &FlameCreationTask::setStatus);
|
||||
connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::stepProgress, this, &FlameCreationTask::propogateStepProgress);
|
||||
connect(m_mod_id_resolver.get(), &Flame::FileResolvingTask::details, this, &FlameCreationTask::setDetails);
|
||||
m_mod_id_resolver->start();
|
||||
|
||||
loop.exec();
|
||||
|
@ -39,15 +39,15 @@ void FlameMod::loadURLs(ModPlatform::IndexedPack& pack, QJsonObject& obj)
|
||||
auto links_obj = Json::ensureObject(obj, "links");
|
||||
|
||||
pack.extraData.issuesUrl = Json::ensureString(links_obj, "issuesUrl");
|
||||
if(pack.extraData.issuesUrl.endsWith('/'))
|
||||
if (pack.extraData.issuesUrl.endsWith('/'))
|
||||
pack.extraData.issuesUrl.chop(1);
|
||||
|
||||
pack.extraData.sourceUrl = Json::ensureString(links_obj, "sourceUrl");
|
||||
if(pack.extraData.sourceUrl.endsWith('/'))
|
||||
if (pack.extraData.sourceUrl.endsWith('/'))
|
||||
pack.extraData.sourceUrl.chop(1);
|
||||
|
||||
pack.extraData.wikiUrl = Json::ensureString(links_obj, "wikiUrl");
|
||||
if(pack.extraData.wikiUrl.endsWith('/'))
|
||||
if (pack.extraData.wikiUrl.endsWith('/'))
|
||||
pack.extraData.wikiUrl.chop(1);
|
||||
|
||||
if (!pack.extraData.body.isEmpty())
|
||||
@ -56,7 +56,7 @@ void FlameMod::loadURLs(ModPlatform::IndexedPack& pack, QJsonObject& obj)
|
||||
|
||||
void FlameMod::loadBody(ModPlatform::IndexedPack& pack, QJsonObject& obj)
|
||||
{
|
||||
pack.extraData.body = api.getModDescription(pack.addonId.toInt());
|
||||
pack.extraData.body = api.getModDescription(pack.addonId.toInt());
|
||||
|
||||
if (!pack.extraData.issuesUrl.isEmpty() || !pack.extraData.sourceUrl.isEmpty() || !pack.extraData.wikiUrl.isEmpty())
|
||||
pack.extraDataLoaded = true;
|
||||
@ -64,12 +64,12 @@ void FlameMod::loadBody(ModPlatform::IndexedPack& pack, QJsonObject& obj)
|
||||
|
||||
static QString enumToString(int hash_algorithm)
|
||||
{
|
||||
switch(hash_algorithm){
|
||||
default:
|
||||
case 1:
|
||||
return "sha1";
|
||||
case 2:
|
||||
return "md5";
|
||||
switch (hash_algorithm) {
|
||||
default:
|
||||
case 1:
|
||||
return "sha1";
|
||||
case 2:
|
||||
return "md5";
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,12 +84,12 @@ void FlameMod::loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
|
||||
|
||||
for (auto versionIter : arr) {
|
||||
auto obj = versionIter.toObject();
|
||||
|
||||
|
||||
auto file = loadIndexedPackVersion(obj);
|
||||
if(!file.addonId.isValid())
|
||||
if (!file.addonId.isValid())
|
||||
file.addonId = pack.addonId;
|
||||
|
||||
if(file.fileId.isValid()) // Heuristic to check if the returned value is valid
|
||||
if (file.fileId.isValid()) // Heuristic to check if the returned value is valid
|
||||
unsortedVersions.append(file);
|
||||
}
|
||||
|
||||
@ -138,8 +138,61 @@ auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool load_changelog) ->
|
||||
}
|
||||
}
|
||||
|
||||
if(load_changelog)
|
||||
auto dependencies = Json::ensureArray(obj, "dependencies");
|
||||
for (auto d : dependencies) {
|
||||
auto dep = Json::ensureObject(d);
|
||||
ModPlatform::Dependency dependency;
|
||||
dependency.addonId = Json::requireInteger(dep, "modId");
|
||||
switch (Json::requireInteger(dep, "relationType")) {
|
||||
case 1: // EmbeddedLibrary
|
||||
dependency.type = ModPlatform::DependencyType::EMBEDDED;
|
||||
break;
|
||||
case 2: // OptionalDependency
|
||||
dependency.type = ModPlatform::DependencyType::OPTIONAL;
|
||||
break;
|
||||
case 3: // RequiredDependency
|
||||
dependency.type = ModPlatform::DependencyType::REQUIRED;
|
||||
break;
|
||||
case 4: // Tool
|
||||
dependency.type = ModPlatform::DependencyType::TOOL;
|
||||
break;
|
||||
case 5: // Incompatible
|
||||
dependency.type = ModPlatform::DependencyType::INCOMPATIBLE;
|
||||
break;
|
||||
case 6: // Include
|
||||
dependency.type = ModPlatform::DependencyType::INCLUDE;
|
||||
break;
|
||||
default:
|
||||
dependency.type = ModPlatform::DependencyType::UNKNOWN;
|
||||
break;
|
||||
}
|
||||
file.dependencies.append(dependency);
|
||||
}
|
||||
|
||||
if (load_changelog)
|
||||
file.changelog = api.getModFileChangelog(file.addonId.toInt(), file.fileId.toInt());
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
ModPlatform::IndexedVersion FlameMod::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr)
|
||||
{
|
||||
QVector<ModPlatform::IndexedVersion> versions;
|
||||
for (auto versionIter : arr) {
|
||||
auto obj = versionIter.toObject();
|
||||
|
||||
auto file = loadIndexedPackVersion(obj);
|
||||
if (!file.addonId.isValid())
|
||||
file.addonId = m.addonId;
|
||||
|
||||
if (file.fileId.isValid()) // Heuristic to check if the returned value is valid
|
||||
versions.append(file);
|
||||
}
|
||||
|
||||
auto orderSortPredicate = [](const ModPlatform::IndexedVersion& a, const ModPlatform::IndexedVersion& b) -> bool {
|
||||
// dates are in RFC 3339 format
|
||||
return a.date > b.date;
|
||||
};
|
||||
std::sort(versions.begin(), versions.end(), orderSortPredicate);
|
||||
return versions.front();
|
||||
};
|
||||
|
@ -6,8 +6,8 @@
|
||||
|
||||
#include "modplatform/ModIndex.h"
|
||||
|
||||
#include "BaseInstance.h"
|
||||
#include <QNetworkAccessManager>
|
||||
#include "BaseInstance.h"
|
||||
|
||||
namespace FlameMod {
|
||||
|
||||
@ -19,5 +19,5 @@ void loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
|
||||
const shared_qobject_ptr<QNetworkAccessManager>& network,
|
||||
const BaseInstance* inst);
|
||||
auto loadIndexedPackVersion(QJsonObject& obj, bool load_changelog = false) -> ModPlatform::IndexedVersion;
|
||||
|
||||
} // namespace FlameMod
|
||||
auto loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion;
|
||||
} // namespace FlameMod
|
@ -4,6 +4,7 @@
|
||||
#include <QMetaType>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
#include "modplatform/ModIndex.h"
|
||||
|
||||
#include "modplatform/ModIndex.h"
|
||||
|
||||
@ -30,8 +31,7 @@ struct ModpackExtra {
|
||||
QString sourceUrl;
|
||||
};
|
||||
|
||||
struct IndexedPack
|
||||
{
|
||||
struct IndexedPack {
|
||||
int addonId;
|
||||
QString name;
|
||||
QString description;
|
||||
@ -46,9 +46,9 @@ struct IndexedPack
|
||||
ModpackExtra extra;
|
||||
};
|
||||
|
||||
void loadIndexedPack(IndexedPack & m, QJsonObject & obj);
|
||||
void loadIndexedPack(IndexedPack& m, QJsonObject& obj);
|
||||
void loadIndexedInfo(IndexedPack&, QJsonObject&);
|
||||
void loadIndexedPackVersions(IndexedPack & m, QJsonArray & arr);
|
||||
}
|
||||
void loadIndexedPackVersions(IndexedPack& m, QJsonArray& arr);
|
||||
} // namespace Flame
|
||||
|
||||
Q_DECLARE_METATYPE(Flame::IndexedPack)
|
||||
|
Reference in New Issue
Block a user