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:
@ -14,7 +14,7 @@ class CheckUpdateTask : public Task {
|
||||
public:
|
||||
CheckUpdateTask(QList<Mod*>& mods,
|
||||
std::list<Version>& mcVersions,
|
||||
std::optional<ResourceAPI::ModLoaderTypes> loaders,
|
||||
std::optional<ModPlatform::ModLoaderTypes> loaders,
|
||||
std::shared_ptr<ModFolderModel> mods_folder)
|
||||
: Task(nullptr), m_mods(mods), m_game_versions(mcVersions), m_loaders(loaders), m_mods_folder(mods_folder){};
|
||||
|
||||
@ -62,7 +62,7 @@ class CheckUpdateTask : public Task {
|
||||
protected:
|
||||
QList<Mod*>& m_mods;
|
||||
std::list<Version>& m_game_versions;
|
||||
std::optional<ResourceAPI::ModLoaderTypes> m_loaders;
|
||||
std::optional<ModPlatform::ModLoaderTypes> m_loaders;
|
||||
std::shared_ptr<ModFolderModel> m_mods_folder;
|
||||
|
||||
std::vector<UpdatableMod> m_updatable;
|
||||
|
@ -134,4 +134,25 @@ QString getMetaURL(ResourceProvider provider, QVariant projectID)
|
||||
projectID.toString();
|
||||
}
|
||||
|
||||
auto getModLoaderString(ModLoaderType type) -> const QString
|
||||
{
|
||||
switch (type) {
|
||||
case NeoForge:
|
||||
return "neoforge";
|
||||
case Forge:
|
||||
return "forge";
|
||||
case Cauldron:
|
||||
return "cauldron";
|
||||
case LiteLoader:
|
||||
return "liteloader";
|
||||
case Fabric:
|
||||
return "fabric";
|
||||
case Quilt:
|
||||
return "quilt";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
} // namespace ModPlatform
|
||||
|
@ -31,6 +31,9 @@ class QIODevice;
|
||||
|
||||
namespace ModPlatform {
|
||||
|
||||
enum ModLoaderType { NeoForge = 1 << 0, Forge = 1 << 1, Cauldron = 1 << 2, LiteLoader = 1 << 3, Fabric = 1 << 4, Quilt = 1 << 5 };
|
||||
Q_DECLARE_FLAGS(ModLoaderTypes, ModLoaderType)
|
||||
|
||||
enum class ResourceProvider { MODRINTH, FLAME };
|
||||
|
||||
enum class ResourceType { MOD, RESOURCE_PACK, SHADER_PACK };
|
||||
@ -101,7 +104,7 @@ struct IndexedVersion {
|
||||
QString downloadUrl;
|
||||
QString date;
|
||||
QString fileName;
|
||||
QStringList loaders = {};
|
||||
ModLoaderTypes loaders = {};
|
||||
QString hash_type;
|
||||
QString hash;
|
||||
bool is_preferred = true;
|
||||
@ -144,7 +147,7 @@ struct IndexedPack {
|
||||
ExtraPackData extraData;
|
||||
|
||||
// For internal use, not provided by APIs
|
||||
[[nodiscard]] bool isVersionSelected(size_t index) const
|
||||
[[nodiscard]] bool isVersionSelected(int index) const
|
||||
{
|
||||
if (!versionsLoaded)
|
||||
return false;
|
||||
@ -174,9 +177,18 @@ inline auto getOverrideDeps() -> QList<OverrideDep>
|
||||
|
||||
{ "qvIfYCYJ", "P7dR8mSH", "API", ModPlatform::ResourceProvider::MODRINTH },
|
||||
{ "lwVhp9o5", "Ha28R6CL", "KotlinLibraries", ModPlatform::ResourceProvider::MODRINTH } };
|
||||
};
|
||||
}
|
||||
|
||||
QString getMetaURL(ResourceProvider provider, QVariant projectID);
|
||||
|
||||
auto getModLoaderString(ModLoaderType type) -> const QString;
|
||||
|
||||
constexpr bool hasSingleModLoaderSelected(ModLoaderTypes l) noexcept
|
||||
{
|
||||
auto x = static_cast<int>(l);
|
||||
return x && !(x & (x - 1));
|
||||
}
|
||||
|
||||
} // namespace ModPlatform
|
||||
|
||||
Q_DECLARE_METATYPE(ModPlatform::IndexedPack)
|
||||
|
@ -54,9 +54,6 @@ class ResourceAPI {
|
||||
public:
|
||||
virtual ~ResourceAPI() = default;
|
||||
|
||||
enum ModLoaderType { Forge = 1 << 0, Cauldron = 1 << 1, LiteLoader = 1 << 2, Fabric = 1 << 3, Quilt = 1 << 4 };
|
||||
Q_DECLARE_FLAGS(ModLoaderTypes, ModLoaderType)
|
||||
|
||||
struct SortingMethod {
|
||||
// The index of the sorting method. Used to allow for arbitrary ordering in the list of methods.
|
||||
// Used by Flame in the API request.
|
||||
@ -74,7 +71,7 @@ class ResourceAPI {
|
||||
|
||||
std::optional<QString> search;
|
||||
std::optional<SortingMethod> sorting;
|
||||
std::optional<ModLoaderTypes> loaders;
|
||||
std::optional<ModPlatform::ModLoaderTypes> loaders;
|
||||
std::optional<std::list<Version> > versions;
|
||||
};
|
||||
struct SearchCallbacks {
|
||||
@ -87,7 +84,7 @@ class ResourceAPI {
|
||||
ModPlatform::IndexedPack pack;
|
||||
|
||||
std::optional<std::list<Version> > mcVersions;
|
||||
std::optional<ModLoaderTypes> loaders;
|
||||
std::optional<ModPlatform::ModLoaderTypes> loaders;
|
||||
|
||||
VersionSearchArgs(VersionSearchArgs const&) = default;
|
||||
void operator=(VersionSearchArgs other)
|
||||
@ -108,13 +105,15 @@ class ResourceAPI {
|
||||
void operator=(ProjectInfoArgs other) { pack = other.pack; }
|
||||
};
|
||||
struct ProjectInfoCallbacks {
|
||||
std::function<void(QJsonDocument&, ModPlatform::IndexedPack)> on_succeed;
|
||||
std::function<void(QJsonDocument&, const ModPlatform::IndexedPack&)> on_succeed;
|
||||
std::function<void(QString const& reason)> on_fail;
|
||||
std::function<void()> on_abort;
|
||||
};
|
||||
|
||||
struct DependencySearchArgs {
|
||||
ModPlatform::Dependency dependency;
|
||||
Version mcVersion;
|
||||
ModLoaderTypes loader;
|
||||
ModPlatform::ModLoaderTypes loader;
|
||||
};
|
||||
|
||||
struct DependencySearchCallbacks {
|
||||
@ -128,28 +127,30 @@ class ResourceAPI {
|
||||
public slots:
|
||||
[[nodiscard]] virtual Task::Ptr searchProjects(SearchArgs&&, SearchCallbacks&&) const
|
||||
{
|
||||
qWarning() << "TODO";
|
||||
qWarning() << "TODO: ResourceAPI::searchProjects";
|
||||
return nullptr;
|
||||
}
|
||||
[[nodiscard]] virtual Task::Ptr getProject(QString addonId, std::shared_ptr<QByteArray> response) const
|
||||
[[nodiscard]] virtual Task::Ptr getProject([[maybe_unused]] QString addonId,
|
||||
[[maybe_unused]] std::shared_ptr<QByteArray> response) const
|
||||
{
|
||||
qWarning() << "TODO";
|
||||
qWarning() << "TODO: ResourceAPI::getProject";
|
||||
return nullptr;
|
||||
}
|
||||
[[nodiscard]] virtual Task::Ptr getProjects(QStringList addonIds, std::shared_ptr<QByteArray> response) const
|
||||
[[nodiscard]] virtual Task::Ptr getProjects([[maybe_unused]] QStringList addonIds,
|
||||
[[maybe_unused]] std::shared_ptr<QByteArray> response) const
|
||||
{
|
||||
qWarning() << "TODO";
|
||||
qWarning() << "TODO: ResourceAPI::getProjects";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
[[nodiscard]] virtual Task::Ptr getProjectInfo(ProjectInfoArgs&&, ProjectInfoCallbacks&&) const
|
||||
{
|
||||
qWarning() << "TODO";
|
||||
qWarning() << "TODO: ResourceAPI::getProjectInfo";
|
||||
return nullptr;
|
||||
}
|
||||
[[nodiscard]] virtual Task::Ptr getProjectVersions(VersionSearchArgs&&, VersionSearchCallbacks&&) const
|
||||
{
|
||||
qWarning() << "TODO";
|
||||
qWarning() << "TODO: ResourceAPI::getProjectVersions";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -159,25 +160,6 @@ class ResourceAPI {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static auto getModLoaderString(ModLoaderType type) -> const QString
|
||||
{
|
||||
switch (type) {
|
||||
case Forge:
|
||||
return "forge";
|
||||
case Cauldron:
|
||||
return "cauldron";
|
||||
case LiteLoader:
|
||||
return "liteloader";
|
||||
case Fabric:
|
||||
return "fabric";
|
||||
case Quilt:
|
||||
return "quilt";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
protected:
|
||||
[[nodiscard]] inline QString debugName() const { return "External resource API"; }
|
||||
|
||||
|
@ -53,6 +53,8 @@
|
||||
#include "net/ChecksumValidator.h"
|
||||
#include "settings/INISettingsObject.h"
|
||||
|
||||
#include "net/ApiDownload.h"
|
||||
|
||||
#include "Application.h"
|
||||
#include "BuildConfig.h"
|
||||
|
||||
@ -83,7 +85,7 @@ void PackInstallTask::executeTask()
|
||||
NetJob::Ptr netJob{ new NetJob("ATLauncher::VersionFetch", APPLICATION->network()) };
|
||||
auto searchUrl =
|
||||
QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "packs/%1/versions/%2/Configs.json").arg(m_pack_safe_name).arg(m_version_name);
|
||||
netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), response));
|
||||
netJob->addNetAction(Net::ApiDownload::makeByteArray(QUrl(searchUrl), response));
|
||||
|
||||
QObject::connect(netJob.get(), &NetJob::succeeded, this, &PackInstallTask::onDownloadSucceeded);
|
||||
QObject::connect(netJob.get(), &NetJob::failed, this, &PackInstallTask::onDownloadFailed);
|
||||
@ -631,7 +633,7 @@ void PackInstallTask::installConfigs()
|
||||
auto entry = APPLICATION->metacache()->resolveEntry("ATLauncherPacks", path);
|
||||
entry->setStale(true);
|
||||
|
||||
auto dl = Net::Download::makeCached(url, entry);
|
||||
auto dl = Net::ApiDownload::makeCached(url, entry);
|
||||
if (!m_version.configs.sha1.isEmpty()) {
|
||||
auto rawSha1 = QByteArray::fromHex(m_version.configs.sha1.toLatin1());
|
||||
dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawSha1));
|
||||
@ -748,7 +750,7 @@ void PackInstallTask::downloadMods()
|
||||
entry->setStale(true);
|
||||
modsToExtract.insert(entry->getFullPath(), mod);
|
||||
|
||||
auto dl = Net::Download::makeCached(url, entry);
|
||||
auto dl = Net::ApiDownload::makeCached(url, entry);
|
||||
if (!mod.md5.isEmpty()) {
|
||||
auto rawMd5 = QByteArray::fromHex(mod.md5.toLatin1());
|
||||
dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Md5, rawMd5));
|
||||
@ -759,7 +761,7 @@ void PackInstallTask::downloadMods()
|
||||
entry->setStale(true);
|
||||
modsToDecomp.insert(entry->getFullPath(), mod);
|
||||
|
||||
auto dl = Net::Download::makeCached(url, entry);
|
||||
auto dl = Net::ApiDownload::makeCached(url, entry);
|
||||
if (!mod.md5.isEmpty()) {
|
||||
auto rawMd5 = QByteArray::fromHex(mod.md5.toLatin1());
|
||||
dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Md5, rawMd5));
|
||||
@ -773,7 +775,7 @@ void PackInstallTask::downloadMods()
|
||||
auto entry = APPLICATION->metacache()->resolveEntry("ATLauncherPacks", cacheName);
|
||||
entry->setStale(true);
|
||||
|
||||
auto dl = Net::Download::makeCached(url, entry);
|
||||
auto dl = Net::ApiDownload::makeCached(url, entry);
|
||||
if (!mod.md5.isEmpty()) {
|
||||
auto rawMd5 = QByteArray::fromHex(mod.md5.toLatin1());
|
||||
dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Md5, rawMd5));
|
||||
@ -1003,15 +1005,30 @@ static Meta::Version::Ptr getComponentVersion(const QString& uid, const QString&
|
||||
if (!vlist)
|
||||
return {};
|
||||
|
||||
if (!vlist->isLoaded())
|
||||
vlist->load(Net::Mode::Online);
|
||||
if (!vlist->isLoaded()) {
|
||||
QEventLoop loadVersionLoop;
|
||||
auto task = vlist->getLoadTask();
|
||||
QObject::connect(task.get(), &Task::finished, &loadVersionLoop, &QEventLoop::quit);
|
||||
if (!task->isRunning())
|
||||
task->start();
|
||||
|
||||
loadVersionLoop.exec();
|
||||
}
|
||||
|
||||
auto ver = vlist->getVersion(version);
|
||||
if (!ver)
|
||||
return {};
|
||||
|
||||
if (!ver->isLoaded())
|
||||
if (!ver->isLoaded()) {
|
||||
QEventLoop loadVersionLoop;
|
||||
ver->load(Net::Mode::Online);
|
||||
auto task = ver->getCurrentTask();
|
||||
QObject::connect(task.get(), &Task::finished, &loadVersionLoop, &QEventLoop::quit);
|
||||
if (!task->isRunning())
|
||||
task->start();
|
||||
|
||||
loadVersionLoop.exec();
|
||||
}
|
||||
|
||||
return ver;
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
#include "FileResolvingTask.h"
|
||||
|
||||
#include "Json.h"
|
||||
#include "modplatform/ModIndex.h"
|
||||
#include "net/ApiDownload.h"
|
||||
#include "net/ApiUpload.h"
|
||||
#include "net/Upload.h"
|
||||
|
||||
#include "modplatform/modrinth/ModrinthPackIndex.h"
|
||||
@ -38,7 +41,7 @@ void Flame::FileResolvingTask::executeTask()
|
||||
return l;
|
||||
}));
|
||||
QByteArray data = Json::toText(object);
|
||||
auto dl = Net::Upload::makeByteArray(QUrl("https://api.curseforge.com/v1/mods/files"), result, data);
|
||||
auto dl = Net::ApiUpload::makeByteArray(QUrl("https://api.curseforge.com/v1/mods/files"), result, data);
|
||||
m_dljob->addNetAction(dl);
|
||||
|
||||
auto step_progress = std::make_shared<TaskStepProgress>();
|
||||
@ -93,14 +96,14 @@ void Flame::FileResolvingTask::netJobFinished()
|
||||
auto& out = m_toProcess.files[fileid];
|
||||
try {
|
||||
out.parseFromObject(Json::requireObject(file));
|
||||
} catch (const JSONValidationError& e) {
|
||||
} catch ([[maybe_unused]] const JSONValidationError& e) {
|
||||
qDebug() << "Blocked mod on curseforge" << out.fileName;
|
||||
auto hash = out.hash;
|
||||
if (!hash.isEmpty()) {
|
||||
auto url = QString("https://api.modrinth.com/v2/version_file/%1?algorithm=sha1").arg(hash);
|
||||
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; });
|
||||
auto dl = Net::ApiDownload::makeByteArray(QUrl(url), output);
|
||||
QObject::connect(dl.get(), &Net::ApiDownload::succeeded, [&out]() { out.resolved = true; });
|
||||
|
||||
m_checkJob->addNetAction(dl);
|
||||
blockedProjects.insert(&out, output);
|
||||
@ -151,7 +154,7 @@ void Flame::FileResolvingTask::modrinthCheckFinished()
|
||||
// If there's more than one mod loader for this version, we can't know for sure
|
||||
// which file is relative to each loader, so it's best to not use any one and
|
||||
// let the user download it manually.
|
||||
if (file.loaders.size() <= 1) {
|
||||
if (!file.loaders || hasSingleModLoaderSelected(file.loaders)) {
|
||||
out->url = file.downloadUrl;
|
||||
qDebug() << "Found alternative on modrinth " << out->fileName;
|
||||
} else {
|
||||
@ -171,9 +174,9 @@ void Flame::FileResolvingTask::modrinthCheckFinished()
|
||||
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, output);
|
||||
auto dl = Net::ApiDownload::makeByteArray(url, output);
|
||||
qDebug() << "Fetching url slug for file:" << mod->fileName;
|
||||
QObject::connect(dl.get(), &Net::Download::succeeded, [block, index, output]() {
|
||||
QObject::connect(dl.get(), &Net::ApiDownload::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 =
|
||||
|
@ -6,8 +6,9 @@
|
||||
#include "FlameModIndex.h"
|
||||
|
||||
#include "Application.h"
|
||||
#include "BuildConfig.h"
|
||||
#include "Json.h"
|
||||
#include "net/ApiDownload.h"
|
||||
#include "net/ApiUpload.h"
|
||||
#include "net/NetJob.h"
|
||||
#include "net/Upload.h"
|
||||
|
||||
@ -26,7 +27,7 @@ Task::Ptr FlameAPI::matchFingerprints(const QList<uint>& fingerprints, std::shar
|
||||
QJsonDocument body(body_obj);
|
||||
auto body_raw = body.toJson();
|
||||
|
||||
netJob->addNetAction(Net::Upload::makeByteArray(QString("https://api.curseforge.com/v1/fingerprints"), response, body_raw));
|
||||
netJob->addNetAction(Net::ApiUpload::makeByteArray(QString("https://api.curseforge.com/v1/fingerprints"), response, body_raw));
|
||||
|
||||
return netJob;
|
||||
}
|
||||
@ -38,7 +39,7 @@ auto FlameAPI::getModFileChangelog(int modId, int fileId) -> QString
|
||||
|
||||
auto netJob = makeShared<NetJob>(QString("Flame::FileChangelog"), APPLICATION->network());
|
||||
auto response = std::make_shared<QByteArray>();
|
||||
netJob->addNetAction(Net::Download::makeByteArray(
|
||||
netJob->addNetAction(Net::ApiDownload::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));
|
||||
@ -73,8 +74,8 @@ auto FlameAPI::getModDescription(int modId) -> QString
|
||||
|
||||
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));
|
||||
netJob->addNetAction(Net::ApiDownload::makeByteArray(
|
||||
QString("https://api.curseforge.com/v1/mods/%1/description").arg(QString::number(modId)), response));
|
||||
|
||||
QObject::connect(netJob.get(), &NetJob::succeeded, [&netJob, response, &description] {
|
||||
QJsonParseError parse_error{};
|
||||
@ -113,7 +114,7 @@ auto FlameAPI::getLatestVersion(VersionSearchArgs&& args) -> ModPlatform::Indexe
|
||||
auto response = std::make_shared<QByteArray>();
|
||||
ModPlatform::IndexedVersion ver;
|
||||
|
||||
netJob->addNetAction(Net::Download::makeByteArray(versions_url, response));
|
||||
netJob->addNetAction(Net::ApiDownload::makeByteArray(versions_url, response));
|
||||
|
||||
QObject::connect(netJob.get(), &NetJob::succeeded, [response, args, &ver] {
|
||||
QJsonParseError parse_error{};
|
||||
@ -129,20 +130,15 @@ auto FlameAPI::getLatestVersion(VersionSearchArgs&& args) -> ModPlatform::Indexe
|
||||
auto obj = Json::requireObject(doc);
|
||||
auto arr = Json::requireArray(obj, "data");
|
||||
|
||||
QJsonObject latest_file_obj;
|
||||
ModPlatform::IndexedVersion ver_tmp;
|
||||
|
||||
for (auto file : arr) {
|
||||
auto file_obj = Json::requireObject(file);
|
||||
auto file_tmp = FlameMod::loadIndexedPackVersion(file_obj);
|
||||
bool better_release = file_tmp.version_type <= ver_tmp.version_type;
|
||||
if (file_tmp.date > ver_tmp.date && better_release) {
|
||||
ver_tmp = file_tmp;
|
||||
latest_file_obj = file_obj;
|
||||
}
|
||||
if (file_tmp.date > ver.date &&
|
||||
(!args.loaders.has_value() || !file_tmp.loaders || args.loaders.value() & file_tmp.loaders) &&
|
||||
file_tmp.version_type <= ver.version_type)
|
||||
ver = file_tmp;
|
||||
}
|
||||
|
||||
ver = FlameMod::loadIndexedPackVersion(latest_file_obj);
|
||||
} catch (Json::JsonException& e) {
|
||||
qCritical() << "Failed to parse response from a version request.";
|
||||
qCritical() << e.what();
|
||||
@ -174,7 +170,7 @@ Task::Ptr FlameAPI::getProjects(QStringList addonIds, std::shared_ptr<QByteArray
|
||||
QJsonDocument body(body_obj);
|
||||
auto body_raw = body.toJson();
|
||||
|
||||
netJob->addNetAction(Net::Upload::makeByteArray(QString("https://api.curseforge.com/v1/mods"), response, body_raw));
|
||||
netJob->addNetAction(Net::ApiUpload::makeByteArray(QString("https://api.curseforge.com/v1/mods"), response, body_raw));
|
||||
|
||||
QObject::connect(netJob.get(), &NetJob::failed, [body_raw] { qDebug() << body_raw; });
|
||||
|
||||
@ -196,13 +192,24 @@ Task::Ptr FlameAPI::getFiles(const QStringList& fileIds, std::shared_ptr<QByteAr
|
||||
QJsonDocument body(body_obj);
|
||||
auto body_raw = body.toJson();
|
||||
|
||||
netJob->addNetAction(Net::Upload::makeByteArray(QString("https://api.curseforge.com/v1/mods/files"), response, body_raw));
|
||||
netJob->addNetAction(Net::ApiUpload::makeByteArray(QString("https://api.curseforge.com/v1/mods/files"), response, body_raw));
|
||||
|
||||
QObject::connect(netJob.get(), &NetJob::failed, [body_raw] { qDebug() << body_raw; });
|
||||
|
||||
return netJob;
|
||||
}
|
||||
|
||||
Task::Ptr FlameAPI::getFile(const QString& addonId, const QString& fileId, std::shared_ptr<QByteArray> response) const
|
||||
{
|
||||
auto netJob = makeShared<NetJob>(QString("Flame::GetFile"), APPLICATION->network());
|
||||
netJob->addNetAction(
|
||||
Net::ApiDownload::makeByteArray(QUrl(QString("https://api.curseforge.com/v1/mods/%1/files/%2").arg(addonId, fileId)), response));
|
||||
|
||||
QObject::connect(netJob.get(), &NetJob::failed, [addonId, fileId] { qDebug() << "Flame API file failure" << addonId << fileId; });
|
||||
|
||||
return netJob;
|
||||
}
|
||||
|
||||
// https://docs.curseforge.com/?python#tocS_ModsSearchSortField
|
||||
static QList<ResourceAPI::SortingMethod> s_sorts = { { 1, "Featured", QObject::tr("Sort by Featured") },
|
||||
{ 2, "Popularity", QObject::tr("Sort by Popularity") },
|
||||
|
@ -20,10 +20,14 @@ class FlameAPI : public NetworkResourceAPI {
|
||||
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;
|
||||
Task::Ptr getFile(const QString& addonId, const QString& fileId, std::shared_ptr<QByteArray> response) const;
|
||||
|
||||
[[nodiscard]] auto getSortingMethods() const -> QList<ResourceAPI::SortingMethod> override;
|
||||
|
||||
static inline auto validateModLoaders(ModLoaderTypes loaders) -> bool { return loaders & (Forge | Fabric | Quilt); }
|
||||
static inline auto validateModLoaders(ModPlatform::ModLoaderTypes loaders) -> bool
|
||||
{
|
||||
return loaders & (ModPlatform::NeoForge | ModPlatform::Forge | ModPlatform::Fabric | ModPlatform::Quilt);
|
||||
}
|
||||
|
||||
private:
|
||||
static int getClassId(ModPlatform::ResourceType type)
|
||||
@ -34,22 +38,47 @@ class FlameAPI : public NetworkResourceAPI {
|
||||
return 6;
|
||||
case ModPlatform::ResourceType::RESOURCE_PACK:
|
||||
return 12;
|
||||
case ModPlatform::ResourceType::SHADER_PACK:
|
||||
return 6552;
|
||||
}
|
||||
}
|
||||
|
||||
static int getMappedModLoader(ModLoaderTypes loaders)
|
||||
static int getMappedModLoader(ModPlatform::ModLoaderType loaders)
|
||||
{
|
||||
// https://docs.curseforge.com/?http#tocS_ModLoaderType
|
||||
if (loaders & Forge)
|
||||
return 1;
|
||||
if (loaders & Fabric)
|
||||
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
|
||||
switch (loaders) {
|
||||
case ModPlatform::Forge:
|
||||
return 1;
|
||||
case ModPlatform::Cauldron:
|
||||
return 2;
|
||||
case ModPlatform::LiteLoader:
|
||||
return 3;
|
||||
case ModPlatform::Fabric:
|
||||
return 4;
|
||||
case ModPlatform::Quilt:
|
||||
return 5;
|
||||
case ModPlatform::NeoForge:
|
||||
return 6;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static auto getModLoaderStrings(const ModPlatform::ModLoaderTypes types) -> const QStringList
|
||||
{
|
||||
QStringList l;
|
||||
for (auto loader : { ModPlatform::NeoForge, ModPlatform::Forge, ModPlatform::Fabric, ModPlatform::Quilt }) {
|
||||
if (types & loader) {
|
||||
l << QString::number(getMappedModLoader(loader));
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
static auto getModLoaderFilters(ModPlatform::ModLoaderTypes types) -> const QString
|
||||
{
|
||||
return "[" + getModLoaderStrings(types).join(',') + "]";
|
||||
}
|
||||
|
||||
private:
|
||||
[[nodiscard]] std::optional<QString> getSearchURL(SearchArgs const& args) const override
|
||||
{
|
||||
@ -66,7 +95,7 @@ class FlameAPI : public NetworkResourceAPI {
|
||||
get_arguments.append(QString("sortField=%1").arg(args.sorting.value().index));
|
||||
get_arguments.append("sortOrder=desc");
|
||||
if (args.loaders.has_value())
|
||||
get_arguments.append(QString("modLoaderType=%1").arg(getMappedModLoader(args.loaders.value())));
|
||||
get_arguments.append(QString("modLoaderTypes=%1").arg(getModLoaderFilters(args.loaders.value())));
|
||||
get_arguments.append(gameVersionStr);
|
||||
|
||||
return "https://api.curseforge.com/v1/mods/search?gameId=432&" + get_arguments.join('&');
|
||||
@ -80,47 +109,27 @@ class FlameAPI : public NetworkResourceAPI {
|
||||
[[nodiscard]] std::optional<QString> getVersionsURL(VersionSearchArgs const& args) const override
|
||||
{
|
||||
auto addonId = args.pack.addonId.toString();
|
||||
QString url{ QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&").arg(addonId) };
|
||||
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()));
|
||||
url += QString("&gameVersion=%1").arg(args.mcVersions.value().front().toString());
|
||||
|
||||
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));
|
||||
if (args.loaders.has_value() && ModPlatform::hasSingleModLoaderSelected(args.loaders.value())) {
|
||||
int mappedModLoader = getMappedModLoader(static_cast<ModPlatform::ModLoaderType>(static_cast<int>(args.loaders.value())));
|
||||
url += QString("&modLoaderType=%1").arg(mappedModLoader);
|
||||
}
|
||||
|
||||
return url + get_parameters.join('&');
|
||||
return url;
|
||||
};
|
||||
|
||||
[[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;
|
||||
}
|
||||
auto url =
|
||||
QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&gameVersion=%2").arg(addonId, args.mcVersion.toString());
|
||||
if (args.loader && ModPlatform::hasSingleModLoaderSelected(args.loader)) {
|
||||
int mappedModLoader = getMappedModLoader(static_cast<ModPlatform::ModLoaderType>(static_cast<int>(args.loader)));
|
||||
url += QString("&modLoaderType=%1").arg(mappedModLoader);
|
||||
}
|
||||
return QString("https://api.curseforge.com/v1/mods/%1/files?pageSize=10000&gameVersion=%2&modLoaderType=%3")
|
||||
.arg(addonId)
|
||||
.arg(args.mcVersion.toString())
|
||||
.arg(mappedModLoader);
|
||||
return url;
|
||||
};
|
||||
};
|
||||
|
@ -5,13 +5,13 @@
|
||||
#include <MurmurHash2.h>
|
||||
#include <memory>
|
||||
|
||||
#include "FileSystem.h"
|
||||
#include "Json.h"
|
||||
|
||||
#include "ResourceDownloadTask.h"
|
||||
|
||||
#include "minecraft/mod/ModFolderModel.h"
|
||||
#include "minecraft/mod/ResourceFolderModel.h"
|
||||
|
||||
#include "net/ApiDownload.h"
|
||||
|
||||
static FlameAPI api;
|
||||
|
||||
@ -33,7 +33,7 @@ ModPlatform::IndexedPack getProjectInfo(ModPlatform::IndexedVersion& ver_info)
|
||||
|
||||
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);
|
||||
auto dl = Net::ApiDownload::makeByteArray(url, response);
|
||||
get_project_job->addNetAction(dl);
|
||||
|
||||
QObject::connect(get_project_job, &NetJob::succeeded, [response, &pack]() {
|
||||
@ -77,7 +77,7 @@ ModPlatform::IndexedVersion getFileInfo(int addonId, int fileId)
|
||||
|
||||
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);
|
||||
auto dl = Net::ApiDownload::makeByteArray(url, response);
|
||||
get_file_info_job->addNetAction(dl);
|
||||
|
||||
QObject::connect(get_file_info_job, &NetJob::succeeded, [response, &ver]() {
|
||||
|
@ -10,7 +10,7 @@ class FlameCheckUpdate : public CheckUpdateTask {
|
||||
public:
|
||||
FlameCheckUpdate(QList<Mod*>& mods,
|
||||
std::list<Version>& mcVersions,
|
||||
std::optional<ResourceAPI::ModLoaderTypes> loaders,
|
||||
std::optional<ModPlatform::ModLoaderTypes> loaders,
|
||||
std::shared_ptr<ModFolderModel> mods_folder)
|
||||
: CheckUpdateTask(mods, mcVersions, loaders, mods_folder)
|
||||
{}
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "meta/VersionList.h"
|
||||
#include "minecraft/World.h"
|
||||
#include "minecraft/mod/tasks/LocalResourceParse.h"
|
||||
#include "net/ApiDownload.h"
|
||||
|
||||
static const FlameAPI api;
|
||||
|
||||
@ -283,7 +284,7 @@ QString FlameCreationTask::getVersionForLoader(QString uid, QString loaderType,
|
||||
// filter by minecraft version, if the loader depends on a certain version.
|
||||
// not all mod loaders depend on a given Minecraft version, so we won't do this
|
||||
// filtering for those loaders.
|
||||
if (loaderType == "forge") {
|
||||
if (loaderType == "forge" || loaderType == "neoforge") {
|
||||
auto iter = std::find_if(reqs.begin(), reqs.end(), [mcVersion](const Meta::Require& req) {
|
||||
return req.uid == "net.minecraft" && req.equalsVersion == mcVersion;
|
||||
});
|
||||
@ -349,7 +350,11 @@ bool FlameCreationTask::createInstance()
|
||||
|
||||
for (auto& loader : m_pack.minecraft.modLoaders) {
|
||||
auto id = loader.id;
|
||||
if (id.startsWith("forge-")) {
|
||||
if (id.startsWith("neoforge-")) {
|
||||
id.remove("neoforge-");
|
||||
loaderType = "neoforge";
|
||||
loaderUid = "net.neoforged";
|
||||
} else if (id.startsWith("forge-")) {
|
||||
id.remove("forge-");
|
||||
loaderType = "forge";
|
||||
loaderUid = "net.minecraftforge";
|
||||
@ -523,7 +528,7 @@ void FlameCreationTask::setupDownloadJob(QEventLoop& loop)
|
||||
case Flame::File::Type::Mod: {
|
||||
if (!result.url.isEmpty()) {
|
||||
qDebug() << "Will download" << result.url << "to" << path;
|
||||
auto dl = Net::Download::makeFile(result.url, path);
|
||||
auto dl = Net::ApiDownload::makeFile(result.url, path);
|
||||
m_files_job->addNetAction(dl);
|
||||
}
|
||||
break;
|
||||
|
@ -54,7 +54,7 @@ void FlameMod::loadURLs(ModPlatform::IndexedPack& pack, QJsonObject& obj)
|
||||
pack.extraDataLoaded = true;
|
||||
}
|
||||
|
||||
void FlameMod::loadBody(ModPlatform::IndexedPack& pack, QJsonObject& obj)
|
||||
void FlameMod::loadBody(ModPlatform::IndexedPack& pack, [[maybe_unused]] QJsonObject& obj)
|
||||
{
|
||||
pack.extraData.body = api.getModDescription(pack.addonId.toInt());
|
||||
|
||||
@ -75,12 +75,13 @@ static QString enumToString(int hash_algorithm)
|
||||
|
||||
void FlameMod::loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
|
||||
QJsonArray& arr,
|
||||
const shared_qobject_ptr<QNetworkAccessManager>& network,
|
||||
[[maybe_unused]] const shared_qobject_ptr<QNetworkAccessManager>& network,
|
||||
const BaseInstance* inst)
|
||||
{
|
||||
QVector<ModPlatform::IndexedVersion> unsortedVersions;
|
||||
auto profile = (dynamic_cast<const MinecraftInstance*>(inst))->getPackProfile();
|
||||
QString mcVersion = profile->getComponentVersion("net.minecraft");
|
||||
auto loaders = profile->getSupportedModLoaders();
|
||||
|
||||
for (auto versionIter : arr) {
|
||||
auto obj = versionIter.toObject();
|
||||
@ -89,7 +90,8 @@ void FlameMod::loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
|
||||
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() &&
|
||||
(!loaders.has_value() || !file.loaders || loaders.value() & file.loaders)) // Heuristic to check if the returned value is valid
|
||||
unsortedVersions.append(file);
|
||||
}
|
||||
|
||||
@ -116,6 +118,19 @@ auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool load_changelog) ->
|
||||
|
||||
if (str.contains('.'))
|
||||
file.mcVersion.append(str);
|
||||
auto loader = str.toLower();
|
||||
if (loader == "neoforge")
|
||||
file.loaders |= ModPlatform::NeoForge;
|
||||
if (loader == "forge")
|
||||
file.loaders |= ModPlatform::Forge;
|
||||
if (loader == "cauldron")
|
||||
file.loaders |= ModPlatform::Cauldron;
|
||||
if (loader == "liteloader")
|
||||
file.loaders |= ModPlatform::LiteLoader;
|
||||
if (loader == "fabric")
|
||||
file.loaders |= ModPlatform::Fabric;
|
||||
if (loader == "quilt")
|
||||
file.loaders |= ModPlatform::Quilt;
|
||||
}
|
||||
|
||||
file.addonId = Json::requireInteger(obj, "modId");
|
||||
@ -175,8 +190,11 @@ auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool load_changelog) ->
|
||||
return file;
|
||||
}
|
||||
|
||||
ModPlatform::IndexedVersion FlameMod::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr)
|
||||
ModPlatform::IndexedVersion FlameMod::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr, const BaseInstance* inst)
|
||||
{
|
||||
auto profile = (dynamic_cast<const MinecraftInstance*>(inst))->getPackProfile();
|
||||
QString mcVersion = profile->getComponentVersion("net.minecraft");
|
||||
auto loaders = profile->getSupportedModLoaders();
|
||||
QVector<ModPlatform::IndexedVersion> versions;
|
||||
for (auto versionIter : arr) {
|
||||
auto obj = versionIter.toObject();
|
||||
@ -185,7 +203,8 @@ ModPlatform::IndexedVersion FlameMod::loadDependencyVersions(const ModPlatform::
|
||||
if (!file.addonId.isValid())
|
||||
file.addonId = m.addonId;
|
||||
|
||||
if (file.fileId.isValid()) // Heuristic to check if the returned value is valid
|
||||
if (file.fileId.isValid() &&
|
||||
(!loaders.has_value() || !file.loaders || loaders.value() & file.loaders)) // Heuristic to check if the returned value is valid
|
||||
versions.append(file);
|
||||
}
|
||||
|
||||
@ -194,5 +213,7 @@ ModPlatform::IndexedVersion FlameMod::loadDependencyVersions(const ModPlatform::
|
||||
return a.date > b.date;
|
||||
};
|
||||
std::sort(versions.begin(), versions.end(), orderSortPredicate);
|
||||
return versions.front();
|
||||
};
|
||||
if (versions.size() != 0)
|
||||
return versions.front();
|
||||
return {};
|
||||
}
|
||||
|
@ -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;
|
||||
auto loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion;
|
||||
auto loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr, const BaseInstance* inst) -> ModPlatform::IndexedVersion;
|
||||
} // namespace FlameMod
|
@ -43,12 +43,14 @@ const QStringList FlamePackExportTask::FILE_EXTENSIONS({ "jar", "zip" });
|
||||
FlamePackExportTask::FlamePackExportTask(const QString& name,
|
||||
const QString& version,
|
||||
const QString& author,
|
||||
bool optionalFiles,
|
||||
InstancePtr instance,
|
||||
const QString& output,
|
||||
MMCZip::FilterFunction filter)
|
||||
: name(name)
|
||||
, version(version)
|
||||
, author(author)
|
||||
, optionalFiles(optionalFiles)
|
||||
, instance(instance)
|
||||
, mcInstance(dynamic_cast<MinecraftInstance*>(instance.get()))
|
||||
, gameRoot(instance->gameRoot())
|
||||
@ -381,6 +383,7 @@ QByteArray FlamePackExportTask::generateIndex()
|
||||
const ComponentPtr quilt = profile->getComponent("org.quiltmc.quilt-loader");
|
||||
const ComponentPtr fabric = profile->getComponent("net.fabricmc.fabric-loader");
|
||||
const ComponentPtr forge = profile->getComponent("net.minecraftforge");
|
||||
const ComponentPtr neoforge = profile->getComponent("net.neoforged");
|
||||
|
||||
// convert all available components to mrpack dependencies
|
||||
if (minecraft != nullptr)
|
||||
@ -392,6 +395,8 @@ QByteArray FlamePackExportTask::generateIndex()
|
||||
id = "fabric-" + fabric->getVersion();
|
||||
else if (forge != nullptr)
|
||||
id = "forge-" + forge->getVersion();
|
||||
else if (neoforge != nullptr)
|
||||
id = "neoforge-" + neoforge->getVersion();
|
||||
version["modLoaders"] = QJsonArray();
|
||||
if (!id.isEmpty()) {
|
||||
QJsonObject loader;
|
||||
@ -407,7 +412,7 @@ QByteArray FlamePackExportTask::generateIndex()
|
||||
QJsonObject file;
|
||||
file["projectID"] = mod.addonId;
|
||||
file["fileID"] = mod.version;
|
||||
file["required"] = mod.enabled;
|
||||
file["required"] = mod.enabled || !optionalFiles;
|
||||
files << file;
|
||||
}
|
||||
obj["files"] = files;
|
||||
|
@ -30,6 +30,7 @@ class FlamePackExportTask : public Task {
|
||||
FlamePackExportTask(const QString& name,
|
||||
const QString& version,
|
||||
const QString& author,
|
||||
bool optionalFiles,
|
||||
InstancePtr instance,
|
||||
const QString& output,
|
||||
MMCZip::FilterFunction filter);
|
||||
@ -44,6 +45,7 @@ class FlamePackExportTask : public Task {
|
||||
|
||||
// inputs
|
||||
const QString name, version, author;
|
||||
const bool optionalFiles;
|
||||
const InstancePtr instance;
|
||||
MinecraftInstance* mcInstance;
|
||||
const QDir gameRoot;
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#include "modplatform/ModIndex.h"
|
||||
|
||||
#include "net/ApiDownload.h"
|
||||
|
||||
Task::Ptr NetworkResourceAPI::searchProjects(SearchArgs&& args, SearchCallbacks&& callbacks) const
|
||||
{
|
||||
auto search_url_optional = getSearchURL(args);
|
||||
@ -23,7 +25,7 @@ Task::Ptr NetworkResourceAPI::searchProjects(SearchArgs&& args, SearchCallbacks&
|
||||
auto response = std::make_shared<QByteArray>();
|
||||
auto netJob = makeShared<NetJob>(QString("%1::Search").arg(debugName()), APPLICATION->network());
|
||||
|
||||
netJob->addNetAction(Net::Download::makeByteArray(QUrl(search_url), response));
|
||||
netJob->addNetAction(Net::ApiDownload::makeByteArray(QUrl(search_url), response));
|
||||
|
||||
QObject::connect(netJob.get(), &NetJob::succeeded, [this, response, callbacks] {
|
||||
QJsonParseError parse_error{};
|
||||
@ -70,7 +72,8 @@ Task::Ptr NetworkResourceAPI::getProjectInfo(ProjectInfoArgs&& args, ProjectInfo
|
||||
|
||||
callbacks.on_succeed(doc, args.pack);
|
||||
});
|
||||
|
||||
QObject::connect(job.get(), &NetJob::failed, [callbacks](QString reason) { callbacks.on_fail(reason); });
|
||||
QObject::connect(job.get(), &NetJob::aborted, [callbacks] { callbacks.on_abort(); });
|
||||
return job;
|
||||
}
|
||||
|
||||
@ -85,7 +88,7 @@ Task::Ptr NetworkResourceAPI::getProjectVersions(VersionSearchArgs&& args, Versi
|
||||
auto netJob = makeShared<NetJob>(QString("%1::Versions").arg(args.pack.name), APPLICATION->network());
|
||||
auto response = std::make_shared<QByteArray>();
|
||||
|
||||
netJob->addNetAction(Net::Download::makeByteArray(versions_url, response));
|
||||
netJob->addNetAction(Net::ApiDownload::makeByteArray(versions_url, response));
|
||||
|
||||
QObject::connect(netJob.get(), &NetJob::succeeded, [response, callbacks, args] {
|
||||
QJsonParseError parse_error{};
|
||||
@ -113,7 +116,7 @@ Task::Ptr NetworkResourceAPI::getProject(QString addonId, std::shared_ptr<QByteA
|
||||
|
||||
auto netJob = makeShared<NetJob>(QString("%1::GetProject").arg(addonId), APPLICATION->network());
|
||||
|
||||
netJob->addNetAction(Net::Download::makeByteArray(QUrl(project_url), response));
|
||||
netJob->addNetAction(Net::ApiDownload::makeByteArray(QUrl(project_url), response));
|
||||
|
||||
return netJob;
|
||||
}
|
||||
@ -129,7 +132,7 @@ Task::Ptr NetworkResourceAPI::getDependencyVersion(DependencySearchArgs&& args,
|
||||
auto netJob = makeShared<NetJob>(QString("%1::Dependency").arg(args.dependency.addonId.toString()), APPLICATION->network());
|
||||
auto response = std::make_shared<QByteArray>();
|
||||
|
||||
netJob->addNetAction(Net::Download::makeByteArray(versions_url, response));
|
||||
netJob->addNetAction(Net::ApiDownload::makeByteArray(versions_url, response));
|
||||
|
||||
QObject::connect(netJob.get(), &NetJob::succeeded, [=] {
|
||||
QJsonParseError parse_error{};
|
||||
@ -145,4 +148,4 @@ Task::Ptr NetworkResourceAPI::getDependencyVersion(DependencySearchArgs&& args,
|
||||
});
|
||||
|
||||
return netJob;
|
||||
};
|
||||
}
|
||||
|
@ -59,16 +59,20 @@ Modpack parseDirectory(QString path)
|
||||
auto obj = Json::requireObject(target, "target");
|
||||
auto name = Json::requireString(obj, "name", "name");
|
||||
auto version = Json::requireString(obj, "version", "version");
|
||||
if (name == "forge") {
|
||||
modpack.loaderType = ResourceAPI::Forge;
|
||||
if (name == "neoforge") {
|
||||
modpack.loaderType = ModPlatform::NeoForge;
|
||||
modpack.version = version;
|
||||
break;
|
||||
} else if (name == "forge") {
|
||||
modpack.loaderType = ModPlatform::Forge;
|
||||
modpack.version = version;
|
||||
break;
|
||||
} else if (name == "fabric") {
|
||||
modpack.loaderType = ResourceAPI::Fabric;
|
||||
modpack.loaderType = ModPlatform::Fabric;
|
||||
modpack.version = version;
|
||||
break;
|
||||
} else if (name == "quilt") {
|
||||
modpack.loaderType = ResourceAPI::Quilt;
|
||||
modpack.loaderType = ModPlatform::Quilt;
|
||||
modpack.version = version;
|
||||
break;
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ struct Modpack {
|
||||
// not needed for instance creation
|
||||
QVariant jvmArgs;
|
||||
|
||||
std::optional<ResourceAPI::ModLoaderType> loaderType;
|
||||
std::optional<ModPlatform::ModLoaderType> loaderType;
|
||||
QString loaderVersion;
|
||||
|
||||
QIcon icon;
|
||||
|
@ -68,21 +68,25 @@ void PackInstallTask::copySettings()
|
||||
auto modloader = m_pack.loaderType;
|
||||
if (modloader.has_value())
|
||||
switch (modloader.value()) {
|
||||
case ResourceAPI::Forge: {
|
||||
case ModPlatform::NeoForge: {
|
||||
components->setComponentVersion("net.neoforged", m_pack.version, true);
|
||||
break;
|
||||
}
|
||||
case ModPlatform::Forge: {
|
||||
components->setComponentVersion("net.minecraftforge", m_pack.version, true);
|
||||
break;
|
||||
}
|
||||
case ResourceAPI::Fabric: {
|
||||
case ModPlatform::Fabric: {
|
||||
components->setComponentVersion("net.fabricmc.fabric-loader", m_pack.version, true);
|
||||
break;
|
||||
}
|
||||
case ResourceAPI::Quilt: {
|
||||
case ModPlatform::Quilt: {
|
||||
components->setComponentVersion("org.quiltmc.quilt-loader", m_pack.version, true);
|
||||
break;
|
||||
}
|
||||
case ResourceAPI::Cauldron:
|
||||
case ModPlatform::Cauldron:
|
||||
break;
|
||||
case ResourceAPI::LiteLoader:
|
||||
case ModPlatform::LiteLoader:
|
||||
break;
|
||||
}
|
||||
components->saveNow();
|
||||
|
@ -40,6 +40,8 @@
|
||||
#include "Application.h"
|
||||
#include "BuildConfig.h"
|
||||
|
||||
#include "net/ApiDownload.h"
|
||||
|
||||
namespace LegacyFTB {
|
||||
|
||||
void PackFetchTask::fetch()
|
||||
@ -51,7 +53,7 @@ void PackFetchTask::fetch()
|
||||
|
||||
QUrl publicPacksUrl = QUrl(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "static/modpacks.xml");
|
||||
qDebug() << "Downloading public version info from" << publicPacksUrl.toString();
|
||||
jobPtr->addNetAction(Net::Download::makeByteArray(publicPacksUrl, publicModpacksXmlFileData));
|
||||
jobPtr->addNetAction(Net::ApiDownload::makeByteArray(publicPacksUrl, publicModpacksXmlFileData));
|
||||
|
||||
QUrl thirdPartyUrl = QUrl(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "static/thirdparty.xml");
|
||||
qDebug() << "Downloading thirdparty version info from" << thirdPartyUrl.toString();
|
||||
@ -71,7 +73,7 @@ void PackFetchTask::fetchPrivate(const QStringList& toFetch)
|
||||
for (auto& packCode : toFetch) {
|
||||
auto data = std::make_shared<QByteArray>();
|
||||
NetJob* job = new NetJob("Fetching private pack", m_network);
|
||||
job->addNetAction(Net::Download::makeByteArray(privatePackBaseUrl.arg(packCode), data));
|
||||
job->addNetAction(Net::ApiDownload::makeByteArray(privatePackBaseUrl.arg(packCode), data));
|
||||
|
||||
QObject::connect(job, &NetJob::succeeded, this, [this, job, data, packCode] {
|
||||
ModpackList packs;
|
||||
|
@ -48,6 +48,8 @@
|
||||
#include "Application.h"
|
||||
#include "BuildConfig.h"
|
||||
|
||||
#include "net/ApiDownload.h"
|
||||
|
||||
namespace LegacyFTB {
|
||||
|
||||
PackInstallTask::PackInstallTask(shared_qobject_ptr<QNetworkAccessManager> network, Modpack pack, QString version)
|
||||
@ -77,7 +79,7 @@ void PackInstallTask::downloadPack()
|
||||
} else {
|
||||
url = QString(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "modpacks/%1").arg(archivePath);
|
||||
}
|
||||
netJobContainer->addNetAction(Net::Download::makeFile(url, archivePath));
|
||||
netJobContainer->addNetAction(Net::ApiDownload::makeFile(url, archivePath));
|
||||
|
||||
connect(netJobContainer.get(), &NetJob::succeeded, this, &PackInstallTask::unzip);
|
||||
connect(netJobContainer.get(), &NetJob::failed, this, &PackInstallTask::emitFailed);
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
#include "Application.h"
|
||||
#include "Json.h"
|
||||
#include "net/ApiDownload.h"
|
||||
#include "net/ApiUpload.h"
|
||||
#include "net/NetJob.h"
|
||||
#include "net/Upload.h"
|
||||
|
||||
@ -13,7 +15,7 @@ Task::Ptr ModrinthAPI::currentVersion(QString hash, QString hash_format, std::sh
|
||||
{
|
||||
auto netJob = makeShared<NetJob>(QString("Modrinth::GetCurrentVersion"), APPLICATION->network());
|
||||
|
||||
netJob->addNetAction(Net::Download::makeByteArray(
|
||||
netJob->addNetAction(Net::ApiDownload::makeByteArray(
|
||||
QString(BuildConfig.MODRINTH_PROD_URL + "/version_file/%1?algorithm=%2").arg(hash, hash_format), response));
|
||||
|
||||
return netJob;
|
||||
@ -31,7 +33,7 @@ Task::Ptr ModrinthAPI::currentVersions(const QStringList& hashes, QString hash_f
|
||||
QJsonDocument body(body_obj);
|
||||
auto body_raw = body.toJson();
|
||||
|
||||
netJob->addNetAction(Net::Upload::makeByteArray(QString(BuildConfig.MODRINTH_PROD_URL + "/version_files"), response, body_raw));
|
||||
netJob->addNetAction(Net::ApiUpload::makeByteArray(QString(BuildConfig.MODRINTH_PROD_URL + "/version_files"), response, body_raw));
|
||||
|
||||
return netJob;
|
||||
}
|
||||
@ -39,7 +41,7 @@ Task::Ptr ModrinthAPI::currentVersions(const QStringList& hashes, QString hash_f
|
||||
Task::Ptr ModrinthAPI::latestVersion(QString hash,
|
||||
QString hash_format,
|
||||
std::optional<std::list<Version>> mcVersions,
|
||||
std::optional<ModLoaderTypes> loaders,
|
||||
std::optional<ModPlatform::ModLoaderTypes> loaders,
|
||||
std::shared_ptr<QByteArray> response)
|
||||
{
|
||||
auto netJob = makeShared<NetJob>(QString("Modrinth::GetLatestVersion"), APPLICATION->network());
|
||||
@ -60,7 +62,7 @@ Task::Ptr ModrinthAPI::latestVersion(QString hash,
|
||||
QJsonDocument body(body_obj);
|
||||
auto body_raw = body.toJson();
|
||||
|
||||
netJob->addNetAction(Net::Upload::makeByteArray(
|
||||
netJob->addNetAction(Net::ApiUpload::makeByteArray(
|
||||
QString(BuildConfig.MODRINTH_PROD_URL + "/version_file/%1/update?algorithm=%2").arg(hash, hash_format), response, body_raw));
|
||||
|
||||
return netJob;
|
||||
@ -69,7 +71,7 @@ Task::Ptr ModrinthAPI::latestVersion(QString hash,
|
||||
Task::Ptr ModrinthAPI::latestVersions(const QStringList& hashes,
|
||||
QString hash_format,
|
||||
std::optional<std::list<Version>> mcVersions,
|
||||
std::optional<ModLoaderTypes> loaders,
|
||||
std::optional<ModPlatform::ModLoaderTypes> loaders,
|
||||
std::shared_ptr<QByteArray> response)
|
||||
{
|
||||
auto netJob = makeShared<NetJob>(QString("Modrinth::GetLatestVersions"), APPLICATION->network());
|
||||
@ -93,7 +95,8 @@ Task::Ptr ModrinthAPI::latestVersions(const QStringList& hashes,
|
||||
QJsonDocument body(body_obj);
|
||||
auto body_raw = body.toJson();
|
||||
|
||||
netJob->addNetAction(Net::Upload::makeByteArray(QString(BuildConfig.MODRINTH_PROD_URL + "/version_files/update"), response, body_raw));
|
||||
netJob->addNetAction(
|
||||
Net::ApiUpload::makeByteArray(QString(BuildConfig.MODRINTH_PROD_URL + "/version_files/update"), response, body_raw));
|
||||
|
||||
return netJob;
|
||||
}
|
||||
@ -103,7 +106,7 @@ Task::Ptr ModrinthAPI::getProjects(QStringList addonIds, std::shared_ptr<QByteAr
|
||||
auto netJob = makeShared<NetJob>(QString("Modrinth::GetProjects"), APPLICATION->network());
|
||||
auto searchUrl = getMultipleModInfoURL(addonIds);
|
||||
|
||||
netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), response));
|
||||
netJob->addNetAction(Net::ApiDownload::makeByteArray(QUrl(searchUrl), response));
|
||||
|
||||
return netJob;
|
||||
}
|
||||
|
@ -19,13 +19,13 @@ class ModrinthAPI : public NetworkResourceAPI {
|
||||
auto latestVersion(QString hash,
|
||||
QString hash_format,
|
||||
std::optional<std::list<Version>> mcVersions,
|
||||
std::optional<ModLoaderTypes> loaders,
|
||||
std::optional<ModPlatform::ModLoaderTypes> loaders,
|
||||
std::shared_ptr<QByteArray> response) -> Task::Ptr;
|
||||
|
||||
auto latestVersions(const QStringList& hashes,
|
||||
QString hash_format,
|
||||
std::optional<std::list<Version>> mcVersions,
|
||||
std::optional<ModLoaderTypes> loaders,
|
||||
std::optional<ModPlatform::ModLoaderTypes> loaders,
|
||||
std::shared_ptr<QByteArray> response) -> Task::Ptr;
|
||||
|
||||
Task::Ptr getProjects(QStringList addonIds, std::shared_ptr<QByteArray> response) const override;
|
||||
@ -35,20 +35,19 @@ class ModrinthAPI : public NetworkResourceAPI {
|
||||
|
||||
inline auto getAuthorURL(const QString& name) const -> QString { return "https://modrinth.com/user/" + name; };
|
||||
|
||||
static auto getModLoaderStrings(const ModLoaderTypes types) -> const QStringList
|
||||
static auto getModLoaderStrings(const ModPlatform::ModLoaderTypes types) -> const QStringList
|
||||
{
|
||||
QStringList l;
|
||||
for (auto loader : { Forge, Fabric, Quilt, LiteLoader }) {
|
||||
for (auto loader :
|
||||
{ ModPlatform::NeoForge, ModPlatform::Forge, ModPlatform::Fabric, ModPlatform::Quilt, ModPlatform::LiteLoader }) {
|
||||
if (types & loader) {
|
||||
l << getModLoaderString(loader);
|
||||
}
|
||||
}
|
||||
if ((types & Quilt) && (~types & Fabric)) // Add Fabric if Quilt is in use, if Fabric isn't already there
|
||||
l << getModLoaderString(Fabric);
|
||||
return l;
|
||||
}
|
||||
|
||||
static auto getModLoaderFilters(ModLoaderTypes types) -> const QString
|
||||
static auto getModLoaderFilters(ModPlatform::ModLoaderTypes types) -> const QString
|
||||
{
|
||||
QStringList l;
|
||||
for (auto loader : getModLoaderStrings(types)) {
|
||||
@ -141,7 +140,10 @@ class ModrinthAPI : public NetworkResourceAPI {
|
||||
return s.isEmpty() ? QString() : s;
|
||||
}
|
||||
|
||||
static inline auto validateModLoaders(ModLoaderTypes loaders) -> bool { return loaders & (Forge | Fabric | Quilt | LiteLoader); }
|
||||
static inline auto validateModLoaders(ModPlatform::ModLoaderTypes loaders) -> bool
|
||||
{
|
||||
return loaders & (ModPlatform::NeoForge | ModPlatform::Forge | ModPlatform::Fabric | ModPlatform::Quilt | ModPlatform::LiteLoader);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::optional<QString> getDependencyURL(DependencySearchArgs const& args) const override
|
||||
{
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "tasks/ConcurrentTask.h"
|
||||
|
||||
#include "minecraft/mod/ModFolderModel.h"
|
||||
#include "minecraft/mod/ResourceFolderModel.h"
|
||||
|
||||
static ModrinthAPI api;
|
||||
static ModPlatform::ProviderCapabilities ProviderCaps;
|
||||
@ -111,11 +110,11 @@ void ModrinthCheckUpdate::executeTask()
|
||||
// so we may want to filter it
|
||||
QString loader_filter;
|
||||
if (m_loaders.has_value()) {
|
||||
static auto flags = { ResourceAPI::ModLoaderType::Forge, ResourceAPI::ModLoaderType::Fabric,
|
||||
ResourceAPI::ModLoaderType::Quilt };
|
||||
static auto flags = { ModPlatform::ModLoaderType::NeoForge, ModPlatform::ModLoaderType::Forge,
|
||||
ModPlatform::ModLoaderType::Fabric, ModPlatform::ModLoaderType::Quilt };
|
||||
for (auto flag : flags) {
|
||||
if (m_loaders.value().testFlag(flag)) {
|
||||
loader_filter = api.getModLoaderString(flag);
|
||||
loader_filter = ModPlatform::getModLoaderString(flag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ class ModrinthCheckUpdate : public CheckUpdateTask {
|
||||
public:
|
||||
ModrinthCheckUpdate(QList<Mod*>& mods,
|
||||
std::list<Version>& mcVersions,
|
||||
std::optional<ResourceAPI::ModLoaderTypes> loaders,
|
||||
std::optional<ModPlatform::ModLoaderTypes> loaders,
|
||||
std::shared_ptr<ModFolderModel> mods_folder)
|
||||
: CheckUpdateTask(mods, mcVersions, loaders, mods_folder)
|
||||
{}
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "net/ChecksumValidator.h"
|
||||
|
||||
#include "net/ApiDownload.h"
|
||||
#include "net/NetJob.h"
|
||||
#include "settings/INISettingsObject.h"
|
||||
|
||||
@ -210,6 +211,8 @@ bool ModrinthCreationTask::createInstance()
|
||||
components->setComponentVersion("org.quiltmc.quilt-loader", m_quilt_version);
|
||||
if (!m_forge_version.isEmpty())
|
||||
components->setComponentVersion("net.minecraftforge", m_forge_version);
|
||||
if (!m_neoForge_version.isEmpty())
|
||||
components->setComponentVersion("net.neoforged", m_neoForge_version);
|
||||
|
||||
if (m_instIcon != "default") {
|
||||
instance.setIconKey(m_instIcon);
|
||||
@ -238,7 +241,7 @@ bool ModrinthCreationTask::createInstance()
|
||||
}
|
||||
|
||||
qDebug() << "Will try to download" << file.downloads.front() << "to" << file_path;
|
||||
auto dl = Net::Download::makeFile(file.downloads.dequeue(), file_path);
|
||||
auto dl = Net::ApiDownload::makeFile(file.downloads.dequeue(), file_path);
|
||||
dl->addValidator(new Net::ChecksumValidator(file.hashAlgorithm, file.hash));
|
||||
m_files_job->addNetAction(dl);
|
||||
|
||||
@ -247,7 +250,7 @@ bool ModrinthCreationTask::createInstance()
|
||||
// MultipleOptionsTask's , once those exist :)
|
||||
auto param = dl.toWeakRef();
|
||||
connect(dl.get(), &NetAction::failed, [this, &file, file_path, param] {
|
||||
auto ndl = Net::Download::makeFile(file.downloads.dequeue(), file_path);
|
||||
auto ndl = Net::ApiDownload::makeFile(file.downloads.dequeue(), file_path);
|
||||
ndl->addValidator(new Net::ChecksumValidator(file.hashAlgorithm, file.hash));
|
||||
m_files_job->addNetAction(ndl);
|
||||
if (auto shared = param.lock())
|
||||
@ -397,6 +400,8 @@ bool ModrinthCreationTask::parseManifest(const QString& index_path,
|
||||
m_quilt_version = Json::requireString(*it, "Quilt Loader version");
|
||||
} else if (name == "forge") {
|
||||
m_forge_version = Json::requireString(*it, "Forge version");
|
||||
} else if (name == "neoforge") {
|
||||
m_neoForge_version = Json::requireString(*it, "NeoForge version");
|
||||
} else {
|
||||
throw JSONValidationError("Unknown dependency type: " + name);
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ class ModrinthCreationTask final : public InstanceCreationTask {
|
||||
private:
|
||||
QWidget* m_parent = nullptr;
|
||||
|
||||
QString m_minecraft_version, m_fabric_version, m_quilt_version, m_forge_version;
|
||||
QString m_minecraft_version, m_fabric_version, m_quilt_version, m_forge_version, m_neoForge_version;
|
||||
QString m_managed_id, m_managed_version_id, m_managed_name;
|
||||
|
||||
std::vector<Modrinth::File> m_files;
|
||||
|
@ -33,12 +33,14 @@ const QStringList ModrinthPackExportTask::FILE_EXTENSIONS({ "jar", "litemod", "z
|
||||
ModrinthPackExportTask::ModrinthPackExportTask(const QString& name,
|
||||
const QString& version,
|
||||
const QString& summary,
|
||||
bool optionalFiles,
|
||||
InstancePtr instance,
|
||||
const QString& output,
|
||||
MMCZip::FilterFunction filter)
|
||||
: name(name)
|
||||
, version(version)
|
||||
, summary(summary)
|
||||
, optionalFiles(optionalFiles)
|
||||
, instance(instance)
|
||||
, mcInstance(dynamic_cast<MinecraftInstance*>(instance.get()))
|
||||
, gameRoot(instance->gameRoot())
|
||||
@ -174,10 +176,10 @@ void ModrinthPackExportTask::parseApiResponse(const std::shared_ptr<QByteArray>
|
||||
if (obj.isEmpty())
|
||||
continue;
|
||||
|
||||
const QJsonArray files = obj["files"].toArray();
|
||||
if (auto fileIter = std::find_if(files.begin(), files.end(),
|
||||
const QJsonArray files_array = obj["files"].toArray();
|
||||
if (auto fileIter = std::find_if(files_array.begin(), files_array.end(),
|
||||
[&iterator](const QJsonValue& file) { return file["hashes"]["sha512"] == iterator.value(); });
|
||||
fileIter != files.end()) {
|
||||
fileIter != files_array.end()) {
|
||||
// map the file to the url
|
||||
resolvedFiles[iterator.key()] =
|
||||
ResolvedFile{ fileIter->toObject()["hashes"].toObject()["sha1"].toString(), iterator.value(),
|
||||
@ -245,6 +247,7 @@ QByteArray ModrinthPackExportTask::generateIndex()
|
||||
const ComponentPtr quilt = profile->getComponent("org.quiltmc.quilt-loader");
|
||||
const ComponentPtr fabric = profile->getComponent("net.fabricmc.fabric-loader");
|
||||
const ComponentPtr forge = profile->getComponent("net.minecraftforge");
|
||||
const ComponentPtr neoForge = profile->getComponent("net.neoforged");
|
||||
|
||||
// convert all available components to mrpack dependencies
|
||||
QJsonObject dependencies;
|
||||
@ -256,6 +259,8 @@ QByteArray ModrinthPackExportTask::generateIndex()
|
||||
dependencies["fabric-loader"] = fabric->m_version;
|
||||
if (forge != nullptr)
|
||||
dependencies["forge"] = forge->m_version;
|
||||
if (neoForge != nullptr)
|
||||
dependencies["neoforge"] = neoForge->m_version;
|
||||
|
||||
out["dependencies"] = dependencies;
|
||||
}
|
||||
@ -267,16 +272,18 @@ QByteArray ModrinthPackExportTask::generateIndex()
|
||||
QString path = iterator.key();
|
||||
const ResolvedFile& value = iterator.value();
|
||||
|
||||
// detect disabled mod
|
||||
const QFileInfo pathInfo(path);
|
||||
if (pathInfo.suffix() == "disabled") {
|
||||
// rename it
|
||||
path = pathInfo.dir().filePath(pathInfo.completeBaseName());
|
||||
// ...and make it optional
|
||||
QJsonObject env;
|
||||
env["client"] = "optional";
|
||||
env["server"] = "optional";
|
||||
fileOut["env"] = env;
|
||||
if (optionalFiles) {
|
||||
// detect disabled mod
|
||||
const QFileInfo pathInfo(path);
|
||||
if (pathInfo.suffix() == "disabled") {
|
||||
// rename it
|
||||
path = pathInfo.dir().filePath(pathInfo.completeBaseName());
|
||||
// ...and make it optional
|
||||
QJsonObject env;
|
||||
env["client"] = "optional";
|
||||
env["server"] = "optional";
|
||||
fileOut["env"] = env;
|
||||
}
|
||||
}
|
||||
|
||||
fileOut["path"] = path;
|
||||
|
@ -31,6 +31,7 @@ class ModrinthPackExportTask : public Task {
|
||||
ModrinthPackExportTask(const QString& name,
|
||||
const QString& version,
|
||||
const QString& summary,
|
||||
bool optionalFiles,
|
||||
InstancePtr instance,
|
||||
const QString& output,
|
||||
MMCZip::FilterFunction filter);
|
||||
@ -50,6 +51,7 @@ class ModrinthPackExportTask : public Task {
|
||||
|
||||
// inputs
|
||||
const QString name, version, summary;
|
||||
const bool optionalFiles;
|
||||
const InstancePtr instance;
|
||||
MinecraftInstance* mcInstance;
|
||||
const QDir gameRoot;
|
||||
|
@ -93,19 +93,19 @@ void Modrinth::loadExtraPackData(ModPlatform::IndexedPack& pack, QJsonObject& ob
|
||||
pack.extraDataLoaded = true;
|
||||
}
|
||||
|
||||
void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
|
||||
QJsonArray& arr,
|
||||
const shared_qobject_ptr<QNetworkAccessManager>& network,
|
||||
const BaseInstance* inst)
|
||||
void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, QJsonArray& arr, const BaseInstance* inst)
|
||||
{
|
||||
QVector<ModPlatform::IndexedVersion> unsortedVersions;
|
||||
QString mcVersion = (static_cast<const MinecraftInstance*>(inst))->getPackProfile()->getComponentVersion("net.minecraft");
|
||||
auto profile = (dynamic_cast<const MinecraftInstance*>(inst))->getPackProfile();
|
||||
QString mcVersion = profile->getComponentVersion("net.minecraft");
|
||||
auto loaders = profile->getSupportedModLoaders();
|
||||
|
||||
for (auto versionIter : arr) {
|
||||
auto obj = versionIter.toObject();
|
||||
auto file = loadIndexedPackVersion(obj);
|
||||
|
||||
if (file.fileId.isValid()) // Heuristic to check if the returned value is valid
|
||||
if (file.fileId.isValid() &&
|
||||
(!loaders.has_value() || !file.loaders || loaders.value() & file.loaders)) // Heuristic to check if the returned value is valid
|
||||
unsortedVersions.append(file);
|
||||
}
|
||||
auto orderSortPredicate = [](const ModPlatform::IndexedVersion& a, const ModPlatform::IndexedVersion& b) -> bool {
|
||||
@ -135,7 +135,18 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject& obj, QString preferred_hash_t
|
||||
}
|
||||
auto loaders = Json::requireArray(obj, "loaders");
|
||||
for (auto loader : loaders) {
|
||||
file.loaders.append(loader.toString());
|
||||
if (loader == "neoforge")
|
||||
file.loaders |= ModPlatform::NeoForge;
|
||||
if (loader == "forge")
|
||||
file.loaders |= ModPlatform::Forge;
|
||||
if (loader == "cauldron")
|
||||
file.loaders |= ModPlatform::Cauldron;
|
||||
if (loader == "liteloader")
|
||||
file.loaders |= ModPlatform::LiteLoader;
|
||||
if (loader == "fabric")
|
||||
file.loaders |= ModPlatform::Fabric;
|
||||
if (loader == "quilt")
|
||||
file.loaders |= ModPlatform::Quilt;
|
||||
}
|
||||
file.version = Json::requireString(obj, "name");
|
||||
file.version_number = Json::requireString(obj, "version_number");
|
||||
@ -221,15 +232,20 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject& obj, QString preferred_hash_t
|
||||
return {};
|
||||
}
|
||||
|
||||
auto Modrinth::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion
|
||||
auto Modrinth::loadDependencyVersions([[maybe_unused]] const ModPlatform::Dependency& m, QJsonArray& arr, const BaseInstance* inst)
|
||||
-> ModPlatform::IndexedVersion
|
||||
{
|
||||
QVector<ModPlatform::IndexedVersion> versions;
|
||||
auto profile = (dynamic_cast<const MinecraftInstance*>(inst))->getPackProfile();
|
||||
QString mcVersion = profile->getComponentVersion("net.minecraft");
|
||||
auto loaders = profile->getSupportedModLoaders();
|
||||
|
||||
QVector<ModPlatform::IndexedVersion> versions;
|
||||
for (auto versionIter : arr) {
|
||||
auto obj = versionIter.toObject();
|
||||
auto file = loadIndexedPackVersion(obj);
|
||||
|
||||
if (file.fileId.isValid()) // Heuristic to check if the returned value is valid
|
||||
if (file.fileId.isValid() &&
|
||||
(!loaders.has_value() || !file.loaders || loaders.value() & file.loaders)) // Heuristic to check if the returned value is valid
|
||||
versions.append(file);
|
||||
}
|
||||
auto orderSortPredicate = [](const ModPlatform::IndexedVersion& a, const ModPlatform::IndexedVersion& b) -> bool {
|
||||
@ -238,4 +254,4 @@ auto Modrinth::loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArr
|
||||
};
|
||||
std::sort(versions.begin(), versions.end(), orderSortPredicate);
|
||||
return versions.length() != 0 ? versions.front() : ModPlatform::IndexedVersion();
|
||||
}
|
||||
}
|
||||
|
@ -26,11 +26,8 @@ namespace Modrinth {
|
||||
|
||||
void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj);
|
||||
void loadExtraPackData(ModPlatform::IndexedPack& m, QJsonObject& obj);
|
||||
void loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
|
||||
QJsonArray& arr,
|
||||
const shared_qobject_ptr<QNetworkAccessManager>& network,
|
||||
const BaseInstance* inst);
|
||||
void loadIndexedPackVersions(ModPlatform::IndexedPack& pack, QJsonArray& arr, const BaseInstance* inst);
|
||||
auto loadIndexedPackVersion(QJsonObject& obj, QString hash_type = "sha512", QString filename_prefer = "") -> ModPlatform::IndexedVersion;
|
||||
auto loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) -> ModPlatform::IndexedVersion;
|
||||
auto loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr, const BaseInstance* inst) -> ModPlatform::IndexedVersion;
|
||||
|
||||
} // namespace Modrinth
|
||||
|
@ -89,7 +89,8 @@ auto intEntry(toml::table table, QString entry_name) -> int
|
||||
return node.value_or(0);
|
||||
}
|
||||
|
||||
auto V1::createModFormat(QDir& index_dir, ModPlatform::IndexedPack& mod_pack, ModPlatform::IndexedVersion& mod_version) -> Mod
|
||||
auto V1::createModFormat([[maybe_unused]] QDir& index_dir, ModPlatform::IndexedPack& mod_pack, ModPlatform::IndexedVersion& mod_version)
|
||||
-> Mod
|
||||
{
|
||||
Mod mod;
|
||||
|
||||
@ -114,7 +115,7 @@ auto V1::createModFormat(QDir& index_dir, ModPlatform::IndexedPack& mod_pack, Mo
|
||||
return mod;
|
||||
}
|
||||
|
||||
auto V1::createModFormat(QDir& index_dir, ::Mod& internal_mod, QString slug) -> Mod
|
||||
auto V1::createModFormat(QDir& index_dir, [[maybe_unused]] ::Mod& internal_mod, QString slug) -> Mod
|
||||
{
|
||||
// Try getting metadata if it exists
|
||||
Mod mod{ getIndexForMod(index_dir, slug) };
|
||||
@ -241,12 +242,13 @@ auto V1::getIndexForMod(QDir& index_dir, QString slug) -> Mod
|
||||
return {};
|
||||
}
|
||||
#else
|
||||
table = toml::parse_file(StringUtils::toStdString(index_dir.absoluteFilePath(real_fname)));
|
||||
if (!table) {
|
||||
toml::parse_result result = toml::parse_file(StringUtils::toStdString(index_dir.absoluteFilePath(real_fname)));
|
||||
if (!result) {
|
||||
qWarning() << QString("Could not open file %1!").arg(normalized_fname);
|
||||
qWarning() << "Reason: " << QString(table.error().what());
|
||||
qWarning() << "Reason: " << result.error().description();
|
||||
return {};
|
||||
}
|
||||
table = result.table();
|
||||
#endif
|
||||
|
||||
// index_file.close();
|
||||
|
@ -23,6 +23,8 @@
|
||||
|
||||
#include "Application.h"
|
||||
|
||||
#include "net/ApiDownload.h"
|
||||
|
||||
Technic::SingleZipPackInstallTask::SingleZipPackInstallTask(const QUrl& sourceUrl, const QString& minecraftVersion)
|
||||
{
|
||||
m_sourceUrl = sourceUrl;
|
||||
@ -45,7 +47,7 @@ void Technic::SingleZipPackInstallTask::executeTask()
|
||||
auto entry = APPLICATION->metacache()->resolveEntry("general", path);
|
||||
entry->setStale(true);
|
||||
m_filesNetJob.reset(new NetJob(tr("Modpack download"), APPLICATION->network()));
|
||||
m_filesNetJob->addNetAction(Net::Download::makeCached(m_sourceUrl, entry));
|
||||
m_filesNetJob->addNetAction(Net::ApiDownload::makeCached(m_sourceUrl, entry));
|
||||
m_archivePath = entry->getFullPath();
|
||||
auto job = m_filesNetJob.get();
|
||||
connect(job, &NetJob::succeeded, this, &Technic::SingleZipPackInstallTask::downloadSucceeded);
|
||||
|
@ -42,6 +42,7 @@
|
||||
|
||||
#include "SolderPackManifest.h"
|
||||
#include "TechnicPackProcessor.h"
|
||||
#include "net/ApiDownload.h"
|
||||
#include "net/ChecksumValidator.h"
|
||||
|
||||
Technic::SolderPackInstallTask::SolderPackInstallTask(shared_qobject_ptr<QNetworkAccessManager> network,
|
||||
@ -71,7 +72,7 @@ void Technic::SolderPackInstallTask::executeTask()
|
||||
|
||||
m_filesNetJob.reset(new NetJob(tr("Resolving modpack files"), m_network));
|
||||
auto sourceUrl = QString("%1/modpack/%2/%3").arg(m_solderUrl.toString(), m_pack, m_version);
|
||||
m_filesNetJob->addNetAction(Net::Download::makeByteArray(sourceUrl, m_response));
|
||||
m_filesNetJob->addNetAction(Net::ApiDownload::makeByteArray(sourceUrl, m_response));
|
||||
|
||||
auto job = m_filesNetJob.get();
|
||||
connect(job, &NetJob::succeeded, this, &Technic::SolderPackInstallTask::fileListSucceeded);
|
||||
@ -111,7 +112,7 @@ void Technic::SolderPackInstallTask::fileListSucceeded()
|
||||
for (const auto& mod : build.mods) {
|
||||
auto path = FS::PathCombine(m_outputDir.path(), QString("%1").arg(i));
|
||||
|
||||
auto dl = Net::Download::makeFile(mod.url, path);
|
||||
auto dl = Net::ApiDownload::makeFile(mod.url, path);
|
||||
if (!mod.md5.isEmpty()) {
|
||||
auto rawMd5 = QByteArray::fromHex(mod.md5.toLatin1());
|
||||
dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Md5, rawMd5));
|
||||
|
@ -31,7 +31,7 @@ void Technic::TechnicPackProcessor::run(SettingsObjectPtr globalSettings,
|
||||
const QString& instIcon,
|
||||
const QString& stagingPath,
|
||||
const QString& minecraftVersion,
|
||||
const bool isSolder)
|
||||
[[maybe_unused]] const bool isSolder)
|
||||
{
|
||||
QString minecraftPath = FS::PathCombine(stagingPath, ".minecraft");
|
||||
QString configPath = FS::PathCombine(stagingPath, "instance.cfg");
|
||||
@ -138,15 +138,15 @@ void Technic::TechnicPackProcessor::run(SettingsObjectPtr globalSettings,
|
||||
try {
|
||||
QJsonDocument doc = Json::requireDocument(data);
|
||||
QJsonObject root = Json::requireObject(doc, "version.json");
|
||||
QString minecraftVersion = Json::ensureString(root, "inheritsFrom", QString(), "");
|
||||
if (minecraftVersion.isEmpty()) {
|
||||
QString packMinecraftVersion = Json::ensureString(root, "inheritsFrom", QString(), "");
|
||||
if (packMinecraftVersion.isEmpty()) {
|
||||
if (fmlMinecraftVersion.isEmpty()) {
|
||||
emit failed(tr("Could not understand \"version.json\":\ninheritsFrom is missing"));
|
||||
return;
|
||||
}
|
||||
minecraftVersion = fmlMinecraftVersion;
|
||||
packMinecraftVersion = fmlMinecraftVersion;
|
||||
}
|
||||
components->setComponentVersion("net.minecraft", minecraftVersion, true);
|
||||
components->setComponentVersion("net.minecraft", packMinecraftVersion, true);
|
||||
for (auto library : Json::ensureArray(root, "libraries", {})) {
|
||||
if (!library.isObject()) {
|
||||
continue;
|
||||
|
Reference in New Issue
Block a user