mirror of
https://github.com/PrismLauncher/PrismLauncher
synced 2026-04-23 09:05:03 +00:00
Modrith api optional changelog (#5197)
This commit is contained in:
commit
c7d43f1685
|
|
@ -297,3 +297,46 @@ auto Resource::getOriginalFileName() const -> QString
|
|||
fileName.chop(9);
|
||||
return fileName;
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug debug, ResourceType type)
|
||||
{
|
||||
switch (type) {
|
||||
case ResourceType::ZIPFILE:
|
||||
debug << "ZIPFILE";
|
||||
break;
|
||||
case ResourceType::SINGLEFILE:
|
||||
debug << "SINGLEFILE";
|
||||
break;
|
||||
case ResourceType::FOLDER:
|
||||
debug << "FOLDER";
|
||||
break;
|
||||
case ResourceType::LITEMOD:
|
||||
debug << "LITEMOD";
|
||||
break;
|
||||
case ResourceType::UNKNOWN:
|
||||
default:
|
||||
debug << "UNKNOWN";
|
||||
break;
|
||||
};
|
||||
return debug;
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug debug, ResourceStatus status)
|
||||
{
|
||||
switch (status) {
|
||||
case ResourceStatus::INSTALLED:
|
||||
debug << "INSTALLED";
|
||||
break;
|
||||
case ResourceStatus::NOT_INSTALLED:
|
||||
debug << "NOT_INSTALLED";
|
||||
break;
|
||||
case ResourceStatus::NO_METADATA:
|
||||
debug << "NO_METADATA";
|
||||
break;
|
||||
case ResourceStatus::UNKNOWN:
|
||||
default:
|
||||
debug << "UNKNOWN";
|
||||
break;
|
||||
};
|
||||
return debug;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ enum class ResourceType {
|
|||
LITEMOD, //!< The resource is a litemod
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug debug, ResourceType type);
|
||||
|
||||
enum class ResourceStatus {
|
||||
INSTALLED, // Both JAR and Metadata are present
|
||||
NOT_INSTALLED, // Only the Metadata is present
|
||||
|
|
@ -60,6 +62,8 @@ enum class ResourceStatus {
|
|||
UNKNOWN, // Default status
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug debug, ResourceStatus status);
|
||||
|
||||
enum class SortType {
|
||||
NAME,
|
||||
DATE,
|
||||
|
|
@ -134,7 +138,7 @@ class Resource : public QObject {
|
|||
* = 0: 'this' is equal to 'other'
|
||||
* < 0: 'this' comes before 'other'
|
||||
*/
|
||||
virtual int compare(Resource const& other, SortType type = SortType::NAME) const;
|
||||
virtual int compare(const Resource& other, SortType type = SortType::NAME) const;
|
||||
|
||||
/** Returns whether the given filter should filter out 'this' (false),
|
||||
* or if such filter includes the Resource (true).
|
||||
|
|
|
|||
|
|
@ -74,13 +74,13 @@ void GetModDependenciesTask::prepare()
|
|||
ModPlatform::Dependency GetModDependenciesTask::getOverride(const ModPlatform::Dependency& dep,
|
||||
const ModPlatform::ResourceProvider providerName)
|
||||
{
|
||||
if (auto isQuilt = m_loaderType & ModPlatform::Quilt; isQuilt || m_loaderType & ModPlatform::Fabric) {
|
||||
if (auto isQuilt = (m_loaderType & ModPlatform::Quilt) != 0U; isQuilt || (m_loaderType & ModPlatform::Fabric) != 0U) {
|
||||
auto overide = ModPlatform::getOverrideDeps();
|
||||
auto over = std::find_if(overide.cbegin(), overide.cend(), [dep, providerName, isQuilt](const auto& o) {
|
||||
return o.provider == providerName && dep.addonId == (isQuilt ? o.fabric : o.quilt);
|
||||
});
|
||||
if (over != overide.cend()) {
|
||||
return { isQuilt ? over->quilt : over->fabric, dep.type };
|
||||
return { .addonId = isQuilt ? over->quilt : over->fabric, .type = dep.type, .version = "" };
|
||||
}
|
||||
}
|
||||
return dep;
|
||||
|
|
@ -91,40 +91,45 @@ QList<ModPlatform::Dependency> GetModDependenciesTask::getDependenciesForVersion
|
|||
{
|
||||
QList<ModPlatform::Dependency> c_dependencies;
|
||||
for (auto ver_dep : version.dependencies) {
|
||||
if (ver_dep.type != ModPlatform::DependencyType::REQUIRED)
|
||||
if (ver_dep.type != ModPlatform::DependencyType::REQUIRED) {
|
||||
continue;
|
||||
}
|
||||
ver_dep = getOverride(ver_dep, providerName);
|
||||
auto isOnlyVersion = providerName == ModPlatform::ResourceProvider::MODRINTH && ver_dep.addonId.toString().isEmpty();
|
||||
if (auto dep = std::find_if(c_dependencies.begin(), c_dependencies.end(),
|
||||
[&ver_dep, isOnlyVersion](const ModPlatform::Dependency& i) {
|
||||
return isOnlyVersion ? i.version == ver_dep.version : i.addonId == ver_dep.addonId;
|
||||
});
|
||||
dep != c_dependencies.end())
|
||||
dep != c_dependencies.end()) {
|
||||
continue; // check the current dependency list
|
||||
}
|
||||
|
||||
if (auto dep = std::find_if(m_selected.begin(), m_selected.end(),
|
||||
[&ver_dep, providerName, isOnlyVersion](std::shared_ptr<PackDependency> i) {
|
||||
[&ver_dep, providerName, isOnlyVersion](const std::shared_ptr<PackDependency>& i) {
|
||||
return i->pack->provider == providerName && (isOnlyVersion ? i->version.version == ver_dep.version
|
||||
: i->pack->addonId == ver_dep.addonId);
|
||||
});
|
||||
dep != m_selected.end())
|
||||
dep != m_selected.end()) {
|
||||
continue; // check the selected versions
|
||||
}
|
||||
|
||||
if (auto dep = std::find_if(m_mods.begin(), m_mods.end(),
|
||||
[&ver_dep, providerName, isOnlyVersion](std::shared_ptr<Metadata::ModStruct> i) {
|
||||
[&ver_dep, providerName, isOnlyVersion](const std::shared_ptr<Metadata::ModStruct>& i) {
|
||||
return i->provider == providerName &&
|
||||
(isOnlyVersion ? i->file_id == ver_dep.version : i->project_id == ver_dep.addonId);
|
||||
});
|
||||
dep != m_mods.end())
|
||||
dep != m_mods.end()) {
|
||||
continue; // check the existing mods
|
||||
}
|
||||
|
||||
if (auto dep = std::find_if(m_pack_dependencies.begin(), m_pack_dependencies.end(),
|
||||
[&ver_dep, providerName, isOnlyVersion](std::shared_ptr<PackDependency> i) {
|
||||
[&ver_dep, providerName, isOnlyVersion](const std::shared_ptr<PackDependency>& i) {
|
||||
return i->pack->provider == providerName && (isOnlyVersion ? i->version.version == ver_dep.addonId
|
||||
: i->pack->addonId == ver_dep.addonId);
|
||||
});
|
||||
dep != m_pack_dependencies.end()) // check loaded dependencies
|
||||
dep != m_pack_dependencies.end()) { // check loaded dependencies
|
||||
continue;
|
||||
}
|
||||
|
||||
c_dependencies.append(ver_dep);
|
||||
}
|
||||
|
|
@ -180,9 +185,11 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen
|
|||
tasks->addTask(getProjectInfoTask(pDep));
|
||||
}
|
||||
|
||||
ResourceAPI::DependencySearchArgs args = { dep, m_version, m_loaderType };
|
||||
ResourceAPI::DependencySearchArgs args = {
|
||||
.dependency = dep, .mcVersion = m_version, .loader = m_loaderType, .includeChangelog = true
|
||||
};
|
||||
ResourceAPI::Callback<ModPlatform::IndexedVersion> callbacks;
|
||||
callbacks.on_fail = [](QString reason, int) {
|
||||
callbacks.on_fail = [](const QString& reason, int) {
|
||||
qCritical() << tr("A network error occurred. Could not load project dependencies:%1").arg(reason);
|
||||
};
|
||||
callbacks.on_succeed = [dep, provider, pDep, level, this](auto& pack) {
|
||||
|
|
@ -191,10 +198,10 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen
|
|||
if (m_loaderType & ModPlatform::Quilt) { // falback for quilt
|
||||
auto overide = ModPlatform::getOverrideDeps();
|
||||
auto over = std::find_if(overide.cbegin(), overide.cend(),
|
||||
[dep, provider](auto o) { return o.provider == provider && dep.addonId == o.quilt; });
|
||||
[dep, provider](const auto& o) { return o.provider == provider && dep.addonId == o.quilt; });
|
||||
if (over != overide.cend()) {
|
||||
removePack(dep.addonId);
|
||||
addTask(prepareDependencyTask({ over->fabric, dep.type }, provider, level));
|
||||
addTask(prepareDependencyTask({ .addonId = over->fabric, .type = dep.type, .version = "" }, provider, level));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -212,7 +219,7 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen
|
|||
}
|
||||
if (dep.addonId.toString().isEmpty() && !pDep->version.addonId.toString().isEmpty()) {
|
||||
pDep->pack->addonId = pDep->version.addonId;
|
||||
auto dep_ = getOverride({ pDep->version.addonId, pDep->dependency.type }, provider);
|
||||
auto dep_ = getOverride({ .addonId = pDep->version.addonId, .type = pDep->dependency.type, .version = "" }, provider);
|
||||
if (dep_.addonId != pDep->version.addonId) {
|
||||
removePack(pDep->version.addonId);
|
||||
addTask(prepareDependencyTask(dep_, provider, level));
|
||||
|
|
@ -224,7 +231,7 @@ Task::Ptr GetModDependenciesTask::prepareDependencyTask(const ModPlatform::Depen
|
|||
removePack(pDep->version.addonId);
|
||||
return;
|
||||
}
|
||||
for (auto dep_ : getDependenciesForVersion(pDep->version, provider)) {
|
||||
for (const auto& dep_ : getDependenciesForVersion(pDep->version, provider)) {
|
||||
addTask(prepareDependencyTask(dep_, provider, level - 1));
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include <QVariant>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "minecraft/mod/MetadataHandler.h"
|
||||
#include "minecraft/mod/ModFolderModel.h"
|
||||
|
|
@ -44,15 +45,11 @@ class GetModDependenciesTask : public SequentialTask {
|
|||
ModPlatform::IndexedPack::Ptr pack;
|
||||
ModPlatform::IndexedVersion version;
|
||||
PackDependency() = default;
|
||||
PackDependency(const ModPlatform::IndexedPack::Ptr p, const ModPlatform::IndexedVersion& v)
|
||||
{
|
||||
pack = p;
|
||||
version = v;
|
||||
}
|
||||
PackDependency(ModPlatform::IndexedPack::Ptr p, ModPlatform::IndexedVersion v) : pack(std::move(p)), version(std::move(v)) {}
|
||||
};
|
||||
|
||||
struct PackDependencyExtraInfo {
|
||||
bool maybe_installed;
|
||||
bool maybe_installed{};
|
||||
QStringList required_by;
|
||||
};
|
||||
|
||||
|
|
@ -62,12 +59,12 @@ class GetModDependenciesTask : public SequentialTask {
|
|||
QHash<QString, PackDependencyExtraInfo> getExtraInfo();
|
||||
|
||||
private:
|
||||
inline ResourceAPI* getAPI(ModPlatform::ResourceProvider provider)
|
||||
ResourceAPI* getAPI(ModPlatform::ResourceProvider provider)
|
||||
{
|
||||
if (provider == ModPlatform::ResourceProvider::FLAME)
|
||||
if (provider == ModPlatform::ResourceProvider::FLAME) {
|
||||
return &m_flameAPI;
|
||||
else
|
||||
return &m_modrinthAPI;
|
||||
}
|
||||
return &m_modrinthAPI;
|
||||
}
|
||||
|
||||
protected slots:
|
||||
|
|
|
|||
|
|
@ -568,7 +568,7 @@ bool process(Mod& mod, ProcessingLevel level)
|
|||
case ResourceType::LITEMOD:
|
||||
return processLitemod(mod);
|
||||
default:
|
||||
qWarning() << "Invalid type for mod parse task!";
|
||||
qWarning() << "Invalid type" << mod.type() << "for mod parse task!";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,11 @@
|
|||
|
||||
namespace ModPlatform {
|
||||
|
||||
ModLoaderType operator|(ModLoaderType lhs, ModLoaderType rhs)
|
||||
{
|
||||
return static_cast<ModLoaderType>(static_cast<std::uint16_t>(lhs) | static_cast<std::uint16_t>(rhs));
|
||||
}
|
||||
|
||||
static const QMap<QString, IndexedVersionType> s_indexed_version_type_names = { { "release", IndexedVersionType::Release },
|
||||
{ "beta", IndexedVersionType::Beta },
|
||||
{ "alpha", IndexedVersionType::Alpha } };
|
||||
|
|
|
|||
|
|
@ -24,34 +24,40 @@
|
|||
#include <QString>
|
||||
#include <QVariant>
|
||||
#include <compare>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
class QIODevice;
|
||||
|
||||
namespace ModPlatform {
|
||||
|
||||
enum ModLoaderType {
|
||||
NeoForge = 1 << 0,
|
||||
Forge = 1 << 1,
|
||||
Cauldron = 1 << 2,
|
||||
LiteLoader = 1 << 3,
|
||||
Fabric = 1 << 4,
|
||||
Quilt = 1 << 5,
|
||||
DataPack = 1 << 6,
|
||||
Babric = 1 << 7,
|
||||
BTA = 1 << 8,
|
||||
LegacyFabric = 1 << 9,
|
||||
Ornithe = 1 << 10,
|
||||
Rift = 1 << 11
|
||||
enum class ModLoaderType : std::uint16_t {
|
||||
NeoForge = 1U << 0U,
|
||||
Forge = 1U << 1U,
|
||||
Cauldron = 1U << 2U,
|
||||
LiteLoader = 1U << 3U,
|
||||
Fabric = 1U << 4U,
|
||||
Quilt = 1U << 5U,
|
||||
DataPack = 1U << 6U,
|
||||
Babric = 1U << 7U,
|
||||
BTA = 1U << 8U,
|
||||
LegacyFabric = 1U << 9U,
|
||||
Ornithe = 1U << 10U,
|
||||
Rift = 1U << 11U
|
||||
};
|
||||
|
||||
ModLoaderType operator|(ModLoaderType lhs, ModLoaderType rhs);
|
||||
|
||||
using enum ModLoaderType;
|
||||
|
||||
Q_DECLARE_FLAGS(ModLoaderTypes, ModLoaderType)
|
||||
QList<ModLoaderType> modLoaderTypesToList(ModLoaderTypes flags);
|
||||
|
||||
enum class ResourceProvider { MODRINTH, FLAME };
|
||||
enum class ResourceProvider : std::uint8_t { MODRINTH, FLAME };
|
||||
|
||||
enum class DependencyType { REQUIRED, OPTIONAL, INCOMPATIBLE, EMBEDDED, TOOL, INCLUDE, UNKNOWN };
|
||||
enum class DependencyType : std::uint8_t { REQUIRED, OPTIONAL, INCOMPATIBLE, EMBEDDED, TOOL, INCLUDE, UNKNOWN };
|
||||
|
||||
enum class Side { NoSide = 0, ClientSide = 1 << 0, ServerSide = 1 << 1, UniversalSide = ClientSide | ServerSide };
|
||||
enum class Side : std::uint8_t { NoSide = 0, ClientSide = 1U << 0U, ServerSide = 1U << 1U, UniversalSide = ClientSide | ServerSide };
|
||||
|
||||
namespace SideUtils {
|
||||
QString toString(Side side);
|
||||
|
|
@ -81,11 +87,11 @@ struct DonationData {
|
|||
};
|
||||
|
||||
struct IndexedVersionType {
|
||||
enum class Enum { Unknown, Release = 1, Beta, Alpha };
|
||||
enum class Enum : std::uint8_t { Unknown = 0, Release = 1, Beta = 2, Alpha = 3 };
|
||||
using enum Enum;
|
||||
constexpr IndexedVersionType(Enum e = Unknown) : m_type(e) {}
|
||||
constexpr IndexedVersionType(Enum e = Unknown) : m_type(e) {} // NOLINT(hicpp-explicit-conversions)
|
||||
static IndexedVersionType fromString(const QString& type);
|
||||
inline bool isValid() const { return m_type != Unknown; }
|
||||
bool isValid() const { return m_type != Unknown; }
|
||||
std::strong_ordering operator<=>(const IndexedVersionType& other) const = default;
|
||||
std::strong_ordering operator<=>(const IndexedVersionType::Enum& other) const { return m_type <=> other; }
|
||||
QString toString() const;
|
||||
|
|
@ -106,13 +112,13 @@ struct IndexedVersion {
|
|||
QVariant addonId;
|
||||
QVariant fileId;
|
||||
QString version;
|
||||
QString version_number = {};
|
||||
QString version_number;
|
||||
IndexedVersionType version_type;
|
||||
QStringList mcVersion;
|
||||
QString downloadUrl;
|
||||
QString date;
|
||||
QString fileName;
|
||||
ModLoaderTypes loaders = {};
|
||||
ModLoaderTypes loaders;
|
||||
QString hash_type;
|
||||
QString hash;
|
||||
bool is_preferred = true;
|
||||
|
|
@ -128,7 +134,7 @@ struct IndexedVersion {
|
|||
auto release_type = version_type.isValid() ? QString(" [%1]").arg(version_type.toString()) : "";
|
||||
auto versionStr = !version.contains(version_number) ? version_number : "";
|
||||
QString gameVersion = "";
|
||||
for (auto v : mcVersion) {
|
||||
for (const auto& v : mcVersion) {
|
||||
if (version.contains(v)) {
|
||||
gameVersion = "";
|
||||
break;
|
||||
|
|
@ -178,17 +184,19 @@ struct IndexedPack {
|
|||
// For internal use, not provided by APIs
|
||||
bool isVersionSelected(int index) const
|
||||
{
|
||||
if (!versionsLoaded)
|
||||
if (!versionsLoaded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return versions.at(index).is_currently_selected;
|
||||
}
|
||||
bool isAnyVersionSelected() const
|
||||
{
|
||||
if (!versionsLoaded)
|
||||
if (!versionsLoaded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return std::any_of(versions.constBegin(), versions.constEnd(), [](auto const& v) { return v.is_currently_selected; });
|
||||
return std::any_of(versions.constBegin(), versions.constEnd(), [](const auto& v) { return v.is_currently_selected; });
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -201,11 +209,13 @@ struct OverrideDep {
|
|||
|
||||
inline auto getOverrideDeps() -> QList<OverrideDep>
|
||||
{
|
||||
return { { "634179", "306612", "API", ModPlatform::ResourceProvider::FLAME },
|
||||
{ "720410", "308769", "KotlinLibraries", ModPlatform::ResourceProvider::FLAME },
|
||||
return {
|
||||
{ .quilt = "634179", .fabric = "306612", .slug = "API", .provider = ModPlatform::ResourceProvider::FLAME },
|
||||
{ .quilt = "720410", .fabric = "308769", .slug = "KotlinLibraries", .provider = ModPlatform::ResourceProvider::FLAME },
|
||||
|
||||
{ "qvIfYCYJ", "P7dR8mSH", "API", ModPlatform::ResourceProvider::MODRINTH },
|
||||
{ "lwVhp9o5", "Ha28R6CL", "KotlinLibraries", ModPlatform::ResourceProvider::MODRINTH } };
|
||||
{ .quilt = "qvIfYCYJ", .fabric = "P7dR8mSH", .slug = "API", .provider = ModPlatform::ResourceProvider::MODRINTH },
|
||||
{ .quilt = "lwVhp9o5", .fabric = "Ha28R6CL", .slug = "KotlinLibraries", .provider = ModPlatform::ResourceProvider::MODRINTH }
|
||||
};
|
||||
}
|
||||
|
||||
QString getMetaURL(ResourceProvider provider, QVariant projectID);
|
||||
|
|
@ -215,8 +225,8 @@ auto getModLoaderFromString(QString type) -> ModLoaderType;
|
|||
|
||||
constexpr bool hasSingleModLoaderSelected(ModLoaderTypes l) noexcept
|
||||
{
|
||||
auto x = static_cast<int>(l);
|
||||
return x && !(x & (x - 1));
|
||||
auto x = static_cast<std::uint16_t>(l);
|
||||
return (x != 0U) && ((x & (x - 1U)) == 0U);
|
||||
}
|
||||
|
||||
struct Category {
|
||||
|
|
|
|||
|
|
@ -106,11 +106,13 @@ Task::Ptr ResourceAPI::getProjectVersions(VersionSearchArgs&& args, Callback<QVe
|
|||
auto obj = versionIter.toObject();
|
||||
|
||||
auto file = loadIndexedPackVersion(obj, args.resourceType);
|
||||
if (!file.addonId.isValid())
|
||||
if (!file.addonId.isValid()) {
|
||||
file.addonId = args.pack->addonId;
|
||||
}
|
||||
|
||||
if (file.fileId.isValid() && !file.downloadUrl.isEmpty()) // Heuristic to check if the returned value is valid
|
||||
if (file.fileId.isValid() && !file.downloadUrl.isEmpty()) { // Heuristic to check if the returned value is valid
|
||||
unsortedVersions.append(file);
|
||||
}
|
||||
}
|
||||
|
||||
auto orderSortPredicate = [](const ModPlatform::IndexedVersion& a, const ModPlatform::IndexedVersion& b) -> bool {
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ class ResourceAPI {
|
|||
template <typename T>
|
||||
struct Callback {
|
||||
std::function<void(T&)> on_succeed;
|
||||
std::function<void(QString const& reason, int network_error_code)> on_fail;
|
||||
std::function<void(const QString& reason, int network_error_code)> on_fail;
|
||||
std::function<void()> on_abort;
|
||||
};
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ class ResourceAPI {
|
|||
std::optional<std::vector<Version>> versions;
|
||||
std::optional<ModPlatform::Side> side;
|
||||
std::optional<QStringList> categoryIds;
|
||||
bool openSource;
|
||||
bool openSource{};
|
||||
};
|
||||
|
||||
struct VersionSearchArgs {
|
||||
|
|
@ -94,6 +94,7 @@ class ResourceAPI {
|
|||
std::optional<std::vector<Version>> mcVersions;
|
||||
std::optional<ModPlatform::ModLoaderTypes> loaders;
|
||||
ModPlatform::ResourceType resourceType;
|
||||
bool includeChangelog{};
|
||||
};
|
||||
|
||||
struct ProjectInfoArgs {
|
||||
|
|
@ -104,6 +105,7 @@ class ResourceAPI {
|
|||
ModPlatform::Dependency dependency;
|
||||
Version mcVersion;
|
||||
ModPlatform::ModLoaderTypes loader;
|
||||
bool includeChangelog{};
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
@ -128,10 +130,10 @@ class ResourceAPI {
|
|||
QString getGameVersionsString(std::vector<Version> mcVersions) const;
|
||||
|
||||
public:
|
||||
virtual auto getSearchURL(SearchArgs const& args) const -> std::optional<QString> = 0;
|
||||
virtual auto getInfoURL(QString const& id) const -> std::optional<QString> = 0;
|
||||
virtual auto getVersionsURL(VersionSearchArgs const& args) const -> std::optional<QString> = 0;
|
||||
virtual auto getDependencyURL(DependencySearchArgs const& args) const -> std::optional<QString> = 0;
|
||||
virtual auto getSearchURL(const SearchArgs& args) const -> std::optional<QString> = 0;
|
||||
virtual auto getInfoURL(const QString& id) const -> std::optional<QString> = 0;
|
||||
virtual auto getVersionsURL(const VersionSearchArgs& args) const -> std::optional<QString> = 0;
|
||||
virtual auto getDependencyURL(const DependencySearchArgs& args) const -> std::optional<QString> = 0;
|
||||
|
||||
/** Functions to load data into a pack.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <QList>
|
||||
#include <cstdint>
|
||||
#include "BuildConfig.h"
|
||||
#include "Json.h"
|
||||
#include "Version.h"
|
||||
|
|
@ -97,7 +98,7 @@ class FlameAPI : public ResourceAPI {
|
|||
static const QString getModLoaderFilters(ModPlatform::ModLoaderTypes types) { return "[" + getModLoaderStrings(types).join(',') + "]"; }
|
||||
|
||||
public:
|
||||
std::optional<QString> getSearchURL(SearchArgs const& args) const override
|
||||
std::optional<QString> getSearchURL(const SearchArgs& args) const override
|
||||
{
|
||||
QStringList get_arguments;
|
||||
get_arguments.append(QString("classId=%1").arg(getClassId(args.type)));
|
||||
|
|
@ -110,7 +111,7 @@ class FlameAPI : public ResourceAPI {
|
|||
get_arguments.append("sortOrder=desc");
|
||||
if (args.loaders.has_value()) {
|
||||
ModPlatform::ModLoaderTypes loaders = args.loaders.value();
|
||||
loaders &= ~ModPlatform::ModLoaderType::DataPack;
|
||||
loaders &= ~static_cast<std::uint16_t>(ModPlatform::ModLoaderType::DataPack);
|
||||
if (loaders != 0)
|
||||
get_arguments.append(QString("modLoaderTypes=%1").arg(getModLoaderFilters(loaders)));
|
||||
}
|
||||
|
|
@ -123,7 +124,7 @@ class FlameAPI : public ResourceAPI {
|
|||
return BuildConfig.FLAME_BASE_URL + "/mods/search?gameId=432&" + get_arguments.join('&');
|
||||
}
|
||||
|
||||
std::optional<QString> getVersionsURL(VersionSearchArgs const& args) const override
|
||||
std::optional<QString> getVersionsURL(const VersionSearchArgs& args) const override
|
||||
{
|
||||
auto addonId = args.pack->addonId.toString();
|
||||
QString url = QString(BuildConfig.FLAME_BASE_URL + "/mods/%1/files?pageSize=10000").arg(addonId);
|
||||
|
|
@ -148,10 +149,10 @@ class FlameAPI : public ResourceAPI {
|
|||
return arr;
|
||||
}
|
||||
// FIXME: Client-side version filtering. This won't take into account any user-selected filtering.
|
||||
auto const& mc_versions = arr.mcVersion;
|
||||
const auto& mc_versions = arr.mcVersion;
|
||||
|
||||
if (std::any_of(mc_versions.constBegin(), mc_versions.constEnd(),
|
||||
[](auto const& mc_version) { return Version(mc_version) <= Version("1.6"); })) {
|
||||
[](const auto& mc_version) { return Version(mc_version) <= Version("1.6"); })) {
|
||||
return arr;
|
||||
}
|
||||
return {};
|
||||
|
|
@ -159,8 +160,8 @@ class FlameAPI : public ResourceAPI {
|
|||
void loadExtraPackInfo(ModPlatform::IndexedPack& m, [[maybe_unused]] QJsonObject&) const override { FlameMod::loadBody(m); }
|
||||
|
||||
private:
|
||||
std::optional<QString> getInfoURL(QString const& id) const override { return QString(BuildConfig.FLAME_BASE_URL + "/mods/%1").arg(id); }
|
||||
std::optional<QString> getDependencyURL(DependencySearchArgs const& args) const override
|
||||
std::optional<QString> getInfoURL(const QString& id) const override { return QString(BuildConfig.FLAME_BASE_URL + "/mods/%1").arg(id); }
|
||||
std::optional<QString> getDependencyURL(const DependencySearchArgs& args) const override
|
||||
{
|
||||
auto addonId = args.dependency.addonId.toString();
|
||||
auto url =
|
||||
|
|
|
|||
|
|
@ -9,9 +9,8 @@
|
|||
#include "net/ApiDownload.h"
|
||||
#include "net/ApiUpload.h"
|
||||
#include "net/NetJob.h"
|
||||
#include "net/Upload.h"
|
||||
|
||||
std::pair<Task::Ptr, QByteArray*> ModrinthAPI::currentVersion(QString hash, QString hash_format)
|
||||
std::pair<Task::Ptr, QByteArray*> ModrinthAPI::currentVersion(const QString& hash, const QString& hash_format) const
|
||||
{
|
||||
auto netJob = makeShared<NetJob>(QString("Modrinth::GetCurrentVersion"), APPLICATION->network());
|
||||
|
||||
|
|
@ -22,7 +21,7 @@ std::pair<Task::Ptr, QByteArray*> ModrinthAPI::currentVersion(QString hash, QStr
|
|||
return { netJob, response };
|
||||
}
|
||||
|
||||
std::pair<Task::Ptr, QByteArray*> ModrinthAPI::currentVersions(const QStringList& hashes, QString hash_format)
|
||||
std::pair<Task::Ptr, QByteArray*> ModrinthAPI::currentVersions(const QStringList& hashes, QString hash_format) const
|
||||
{
|
||||
auto netJob = makeShared<NetJob>(QString("Modrinth::GetCurrentVersions"), APPLICATION->network());
|
||||
|
||||
|
|
@ -40,17 +39,18 @@ std::pair<Task::Ptr, QByteArray*> ModrinthAPI::currentVersions(const QStringList
|
|||
return { netJob, response };
|
||||
}
|
||||
|
||||
std::pair<Task::Ptr, QByteArray*> ModrinthAPI::latestVersion(QString hash,
|
||||
QString hash_format,
|
||||
std::pair<Task::Ptr, QByteArray*> ModrinthAPI::latestVersion(const QString& hash,
|
||||
const QString& hash_format,
|
||||
std::optional<std::vector<Version>> mcVersions,
|
||||
std::optional<ModPlatform::ModLoaderTypes> loaders)
|
||||
std::optional<ModPlatform::ModLoaderTypes> loaders) const
|
||||
{
|
||||
auto netJob = makeShared<NetJob>(QString("Modrinth::GetLatestVersion"), APPLICATION->network());
|
||||
|
||||
QJsonObject body_obj;
|
||||
|
||||
if (loaders.has_value())
|
||||
if (loaders.has_value()) {
|
||||
Json::writeStringList(body_obj, "loaders", getModLoaderStrings(loaders.value()));
|
||||
}
|
||||
|
||||
if (mcVersions.has_value()) {
|
||||
QStringList game_versions;
|
||||
|
|
@ -71,9 +71,9 @@ std::pair<Task::Ptr, QByteArray*> ModrinthAPI::latestVersion(QString hash,
|
|||
}
|
||||
|
||||
std::pair<Task::Ptr, QByteArray*> ModrinthAPI::latestVersions(const QStringList& hashes,
|
||||
QString hash_format,
|
||||
const QString& hash_format,
|
||||
std::optional<std::vector<Version>> mcVersions,
|
||||
std::optional<ModPlatform::ModLoaderTypes> loaders)
|
||||
std::optional<ModPlatform::ModLoaderTypes> loaders) const
|
||||
{
|
||||
auto netJob = makeShared<NetJob>(QString("Modrinth::GetLatestVersions"), APPLICATION->network());
|
||||
|
||||
|
|
@ -82,8 +82,9 @@ std::pair<Task::Ptr, QByteArray*> ModrinthAPI::latestVersions(const QStringList&
|
|||
Json::writeStringList(body_obj, "hashes", hashes);
|
||||
Json::writeString(body_obj, "algorithm", hash_format);
|
||||
|
||||
if (loaders.has_value())
|
||||
if (loaders.has_value()) {
|
||||
Json::writeStringList(body_obj, "loaders", getModLoaderStrings(loaders.value()));
|
||||
}
|
||||
|
||||
if (mcVersions.has_value()) {
|
||||
QStringList game_versions;
|
||||
|
|
@ -115,11 +116,11 @@ std::pair<Task::Ptr, QByteArray*> ModrinthAPI::getProjects(QStringList addonIds)
|
|||
QList<ResourceAPI::SortingMethod> ModrinthAPI::getSortingMethods() const
|
||||
{
|
||||
// https://docs.modrinth.com/api-spec/#tag/projects/operation/searchProjects
|
||||
return { { 1, "relevance", QObject::tr("Sort by Relevance") },
|
||||
{ 2, "downloads", QObject::tr("Sort by Downloads") },
|
||||
{ 3, "follows", QObject::tr("Sort by Follows") },
|
||||
{ 4, "newest", QObject::tr("Sort by Newest") },
|
||||
{ 5, "updated", QObject::tr("Sort by Last Updated") } };
|
||||
return { { .index = 1, .name = "relevance", .readable_name = QObject::tr("Sort by Relevance") },
|
||||
{ .index = 2, .name = "downloads", .readable_name = QObject::tr("Sort by Downloads") },
|
||||
{ .index = 3, .name = "follows", .readable_name = QObject::tr("Sort by Follows") },
|
||||
{ .index = 4, .name = "newest", .readable_name = QObject::tr("Sort by Newest") },
|
||||
{ .index = 5, .name = "updated", .readable_name = QObject::tr("Sort by Last Updated") } };
|
||||
}
|
||||
|
||||
std::pair<Task::Ptr, QByteArray*> ModrinthAPI::getModCategories()
|
||||
|
|
@ -127,12 +128,12 @@ std::pair<Task::Ptr, QByteArray*> ModrinthAPI::getModCategories()
|
|||
auto netJob = makeShared<NetJob>(QString("Modrinth::GetCategories"), APPLICATION->network());
|
||||
auto [action, response] = Net::ApiDownload::makeByteArray(QUrl(BuildConfig.MODRINTH_PROD_URL + "/tag/category"));
|
||||
netJob->addNetAction(action);
|
||||
QObject::connect(netJob.get(), &Task::failed, [](QString msg) { qDebug() << "Modrinth failed to get categories:" << msg; });
|
||||
QObject::connect(netJob.get(), &Task::failed, [](const QString& msg) { qDebug() << "Modrinth failed to get categories:" << msg; });
|
||||
|
||||
return { netJob, response };
|
||||
}
|
||||
|
||||
QList<ModPlatform::Category> ModrinthAPI::loadCategories(const QByteArray& response, QString projectType)
|
||||
QList<ModPlatform::Category> ModrinthAPI::loadCategories(const QByteArray& response, const QString& projectType)
|
||||
{
|
||||
QList<ModPlatform::Category> categories;
|
||||
QJsonParseError parse_error{};
|
||||
|
|
@ -150,8 +151,9 @@ QList<ModPlatform::Category> ModrinthAPI::loadCategories(const QByteArray& respo
|
|||
for (auto val : arr) {
|
||||
auto cat = Json::requireObject(val);
|
||||
auto name = Json::requireString(cat, "name");
|
||||
if (cat["project_type"].toString() == projectType)
|
||||
categories.push_back({ name, name });
|
||||
if (cat["project_type"].toString() == projectType) {
|
||||
categories.push_back({ .name = name, .id = name });
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Json::JsonException& e) {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "BuildConfig.h"
|
||||
#include "Json.h"
|
||||
#include "modplatform/ModIndex.h"
|
||||
#include "modplatform/ResourceAPI.h"
|
||||
#include "modplatform/modrinth/ModrinthPackIndex.h"
|
||||
|
|
@ -15,57 +14,57 @@
|
|||
|
||||
class ModrinthAPI : public ResourceAPI {
|
||||
public:
|
||||
std::pair<Task::Ptr, QByteArray*> currentVersion(QString hash, QString hash_format);
|
||||
std::pair<Task::Ptr, QByteArray*> currentVersion(const QString& hash, const QString& hash_format) const;
|
||||
|
||||
std::pair<Task::Ptr, QByteArray*> currentVersions(const QStringList& hashes, QString hash_format);
|
||||
std::pair<Task::Ptr, QByteArray*> currentVersions(const QStringList& hashes, QString hash_format) const;
|
||||
|
||||
std::pair<Task::Ptr, QByteArray*> latestVersion(QString hash,
|
||||
QString hash_format,
|
||||
std::pair<Task::Ptr, QByteArray*> latestVersion(const QString& hash,
|
||||
const QString& hash_format,
|
||||
std::optional<std::vector<Version>> mcVersions,
|
||||
std::optional<ModPlatform::ModLoaderTypes> loaders);
|
||||
std::optional<ModPlatform::ModLoaderTypes> loaders) const;
|
||||
|
||||
std::pair<Task::Ptr, QByteArray*> latestVersions(const QStringList& hashes,
|
||||
QString hash_format,
|
||||
const QString& hash_format,
|
||||
std::optional<std::vector<Version>> mcVersions,
|
||||
std::optional<ModPlatform::ModLoaderTypes> loaders);
|
||||
std::optional<ModPlatform::ModLoaderTypes> loaders) const;
|
||||
|
||||
std::pair<Task::Ptr, QByteArray*> getProjects(QStringList addonIds) const override;
|
||||
|
||||
static std::pair<Task::Ptr, QByteArray*> getModCategories();
|
||||
static QList<ModPlatform::Category> loadCategories(const QByteArray& response, QString projectType);
|
||||
static QList<ModPlatform::Category> loadCategories(const QByteArray& response, const QString& projectType);
|
||||
static QList<ModPlatform::Category> loadModCategories(const QByteArray& response);
|
||||
|
||||
public:
|
||||
auto getSortingMethods() const -> QList<ResourceAPI::SortingMethod> override;
|
||||
|
||||
inline auto getAuthorURL(const QString& name) const -> QString { return "https://modrinth.com/user/" + name; };
|
||||
static auto getAuthorURL(const QString& name) -> QString { return "https://modrinth.com/user/" + name; };
|
||||
|
||||
static auto getModLoaderStrings(const ModPlatform::ModLoaderTypes types) -> const QStringList
|
||||
static auto getModLoaderStrings(const ModPlatform::ModLoaderTypes types) -> QStringList
|
||||
{
|
||||
QStringList l;
|
||||
for (auto loader : { ModPlatform::NeoForge, ModPlatform::Forge, ModPlatform::Fabric, ModPlatform::Quilt, ModPlatform::LiteLoader,
|
||||
ModPlatform::DataPack, ModPlatform::Babric, ModPlatform::BTA, ModPlatform::LegacyFabric, ModPlatform::Ornithe,
|
||||
ModPlatform::Rift }) {
|
||||
if (types & loader) {
|
||||
if ((types & loader) != 0U) {
|
||||
l << getModLoaderAsString(loader);
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
static auto getModLoaderFilters(ModPlatform::ModLoaderTypes types) -> const QString
|
||||
static auto getModLoaderFilters(ModPlatform::ModLoaderTypes types) -> QString
|
||||
{
|
||||
QStringList l;
|
||||
for (auto loader : getModLoaderStrings(types)) {
|
||||
for (const auto& loader : getModLoaderStrings(types)) {
|
||||
l << QString("\"categories:%1\"").arg(loader);
|
||||
}
|
||||
return l.join(',');
|
||||
}
|
||||
|
||||
static auto getCategoriesFilters(QStringList categories) -> const QString
|
||||
static auto getCategoriesFilters(const QStringList& categories) -> QString
|
||||
{
|
||||
QStringList l;
|
||||
for (auto cat : categories) {
|
||||
for (const auto& cat : categories) {
|
||||
l << QString("\"categories:%1\"").arg(cat);
|
||||
}
|
||||
return l.join(',');
|
||||
|
|
@ -75,11 +74,11 @@ class ModrinthAPI : public ResourceAPI {
|
|||
{
|
||||
switch (side) {
|
||||
case ModPlatform::Side::ClientSide:
|
||||
return QString("\"client_side:required\",\"client_side:optional\"],[\"server_side:optional\",\"server_side:unsupported\"");
|
||||
return { R"("client_side:required","client_side:optional"],["server_side:optional","server_side:unsupported")" };
|
||||
case ModPlatform::Side::ServerSide:
|
||||
return QString("\"server_side:required\",\"server_side:optional\"],[\"client_side:optional\",\"client_side:unsupported\"");
|
||||
return { R"("server_side:required","server_side:optional"],["client_side:optional","client_side:unsupported")" };
|
||||
case ModPlatform::Side::UniversalSide:
|
||||
return QString("\"client_side:required\"],[\"server_side:required\"");
|
||||
return { R"("client_side:required"],["server_side:required")" };
|
||||
case ModPlatform::Side::NoSide:
|
||||
// fallthrough
|
||||
default:
|
||||
|
|
@ -87,17 +86,17 @@ class ModrinthAPI : public ResourceAPI {
|
|||
}
|
||||
}
|
||||
|
||||
static inline QString mapMCVersionFromModrinth(QString v)
|
||||
static QString mapMCVersionFromModrinth(QString v)
|
||||
{
|
||||
static const QString preString = " Pre-Release ";
|
||||
static const QString s_preString = " Pre-Release ";
|
||||
bool pre = false;
|
||||
if (v.contains("-pre")) {
|
||||
pre = true;
|
||||
v.replace("-pre", preString);
|
||||
v.replace("-pre", s_preString);
|
||||
}
|
||||
v.replace("-", " ");
|
||||
if (pre) {
|
||||
v.replace(" Pre Release ", preString);
|
||||
v.replace(" Pre Release ", s_preString);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
|
@ -124,23 +123,28 @@ class ModrinthAPI : public ResourceAPI {
|
|||
return "";
|
||||
}
|
||||
|
||||
QString createFacets(SearchArgs const& args) const
|
||||
QString createFacets(const SearchArgs& args) const
|
||||
{
|
||||
QStringList facets_list;
|
||||
|
||||
if (args.loaders.has_value() && args.loaders.value() != 0)
|
||||
if (args.loaders.has_value() && args.loaders.value() != 0) {
|
||||
facets_list.append(QString("[%1]").arg(getModLoaderFilters(args.loaders.value())));
|
||||
if (args.versions.has_value() && !args.versions.value().empty())
|
||||
}
|
||||
if (args.versions.has_value() && !args.versions.value().empty()) {
|
||||
facets_list.append(QString("[%1]").arg(getGameVersionsArray(args.versions.value())));
|
||||
}
|
||||
if (args.side.has_value()) {
|
||||
auto side = getSideFilters(args.side.value());
|
||||
if (!side.isEmpty())
|
||||
if (!side.isEmpty()) {
|
||||
facets_list.append(QString("[%1]").arg(side));
|
||||
}
|
||||
}
|
||||
if (args.categoryIds.has_value() && !args.categoryIds->empty())
|
||||
if (args.categoryIds.has_value() && !args.categoryIds->empty()) {
|
||||
facets_list.append(QString("[%1]").arg(getCategoriesFilters(args.categoryIds.value())));
|
||||
if (args.openSource)
|
||||
}
|
||||
if (args.openSource) {
|
||||
facets_list.append("[\"open_source:true\"]");
|
||||
}
|
||||
|
||||
facets_list.append(QString("[\"project_type:%1\"]").arg(resourceTypeParameter(args.type)));
|
||||
|
||||
|
|
@ -148,7 +152,7 @@ class ModrinthAPI : public ResourceAPI {
|
|||
}
|
||||
|
||||
public:
|
||||
inline auto getSearchURL(SearchArgs const& args) const -> std::optional<QString> override
|
||||
auto getSearchURL(const SearchArgs& args) const -> std::optional<QString> override
|
||||
{
|
||||
if (args.loaders.has_value() && args.loaders.value() != 0) {
|
||||
if (!validateModLoaders(args.loaders.value())) {
|
||||
|
|
@ -160,67 +164,74 @@ class ModrinthAPI : public ResourceAPI {
|
|||
QStringList get_arguments;
|
||||
get_arguments.append(QString("offset=%1").arg(args.offset));
|
||||
get_arguments.append(QString("limit=25"));
|
||||
if (args.search.has_value())
|
||||
if (args.search.has_value()) {
|
||||
get_arguments.append(QString("query=%1").arg(args.search.value()));
|
||||
if (args.sorting.has_value())
|
||||
}
|
||||
if (args.sorting.has_value()) {
|
||||
get_arguments.append(QString("index=%1").arg(args.sorting.value().name));
|
||||
}
|
||||
get_arguments.append(QString("facets=%1").arg(createFacets(args)));
|
||||
|
||||
return BuildConfig.MODRINTH_PROD_URL + "/search?" + get_arguments.join('&');
|
||||
};
|
||||
|
||||
inline auto getInfoURL(QString const& id) const -> std::optional<QString> override
|
||||
auto getInfoURL(const QString& id) const -> std::optional<QString> override
|
||||
{
|
||||
return BuildConfig.MODRINTH_PROD_URL + "/project/" + id;
|
||||
};
|
||||
|
||||
inline auto getMultipleModInfoURL(QStringList ids) const -> QString
|
||||
auto getMultipleModInfoURL(const QStringList& ids) const -> QString
|
||||
{
|
||||
return BuildConfig.MODRINTH_PROD_URL + QString("/projects?ids=[\"%1\"]").arg(ids.join("\",\""));
|
||||
};
|
||||
|
||||
inline auto getVersionsURL(VersionSearchArgs const& args) const -> std::optional<QString> override
|
||||
auto getVersionsURL(const VersionSearchArgs& args) const -> std::optional<QString> override
|
||||
{
|
||||
QStringList get_arguments;
|
||||
if (args.mcVersions.has_value())
|
||||
if (args.mcVersions.has_value()) {
|
||||
get_arguments.append(QString("game_versions=[%1]").arg(getGameVersionsString(args.mcVersions.value())));
|
||||
if (args.loaders.has_value())
|
||||
}
|
||||
if (args.loaders.has_value()) {
|
||||
get_arguments.append(QString("loaders=[\"%1\"]").arg(getModLoaderStrings(args.loaders.value()).join("\",\"")));
|
||||
}
|
||||
get_arguments.append(QString("include_changelog=%1").arg(args.includeChangelog ? "true" : "false"));
|
||||
|
||||
return QString("%1/project/%2/version%3%4")
|
||||
.arg(BuildConfig.MODRINTH_PROD_URL, args.pack->addonId.toString(), get_arguments.isEmpty() ? "" : "?", get_arguments.join('&'));
|
||||
};
|
||||
|
||||
QString getGameVersionsArray(std::vector<Version> mcVersions) const
|
||||
QString getGameVersionsArray(const std::vector<Version>& mcVersions) const
|
||||
{
|
||||
QString s;
|
||||
for (auto& ver : mcVersions) {
|
||||
s += QString("\"versions:%1\",").arg(mapMCVersionToModrinth(ver));
|
||||
for (const auto& ver : mcVersions) {
|
||||
s += QString(R"("versions:%1",)").arg(mapMCVersionToModrinth(ver));
|
||||
}
|
||||
s.remove(s.length() - 1, 1); // remove last comma
|
||||
return s.isEmpty() ? QString() : s;
|
||||
}
|
||||
|
||||
static inline auto validateModLoaders(ModPlatform::ModLoaderTypes loaders) -> bool
|
||||
static auto validateModLoaders(ModPlatform::ModLoaderTypes loaders) -> bool
|
||||
{
|
||||
return loaders & (ModPlatform::NeoForge | ModPlatform::Forge | ModPlatform::Fabric | ModPlatform::Quilt | ModPlatform::LiteLoader |
|
||||
ModPlatform::DataPack | ModPlatform::Babric | ModPlatform::BTA | ModPlatform::LegacyFabric |
|
||||
ModPlatform::Ornithe | ModPlatform::Rift);
|
||||
return (loaders & (ModPlatform::NeoForge | ModPlatform::Forge | ModPlatform::Fabric | ModPlatform::Quilt | ModPlatform::LiteLoader |
|
||||
ModPlatform::DataPack | ModPlatform::Babric | ModPlatform::BTA | ModPlatform::LegacyFabric |
|
||||
ModPlatform::Ornithe | ModPlatform::Rift)) != 0;
|
||||
}
|
||||
|
||||
std::optional<QString> getDependencyURL(DependencySearchArgs const& args) const override
|
||||
std::optional<QString> getDependencyURL(const DependencySearchArgs& args) const override
|
||||
{
|
||||
return args.dependency.version.length() != 0 ? QString("%1/version/%2").arg(BuildConfig.MODRINTH_PROD_URL, args.dependency.version)
|
||||
: QString("%1/project/%2/version?game_versions=[\"%3\"]&loaders=[\"%4\"]")
|
||||
.arg(BuildConfig.MODRINTH_PROD_URL)
|
||||
.arg(args.dependency.addonId.toString())
|
||||
.arg(mapMCVersionToModrinth(args.mcVersion))
|
||||
.arg(getModLoaderStrings(args.loader).join("\",\""));
|
||||
return args.dependency.version.length() != 0
|
||||
? QString("%1/version/%2").arg(BuildConfig.MODRINTH_PROD_URL, args.dependency.version)
|
||||
: QString(R"(%1/project/%2/version?game_versions=["%3"]&loaders=["%4"]&include_changelog=%5)")
|
||||
.arg(BuildConfig.MODRINTH_PROD_URL)
|
||||
.arg(args.dependency.addonId.toString())
|
||||
.arg(mapMCVersionToModrinth(args.mcVersion))
|
||||
.arg(getModLoaderStrings(args.loader).join("\",\""))
|
||||
.arg(args.includeChangelog ? "true" : "false");
|
||||
};
|
||||
|
||||
QJsonArray documentToArray(QJsonDocument& obj) const override { return obj.object().value("hits").toArray(); }
|
||||
void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj) const override { Modrinth::loadIndexedPack(m, obj); }
|
||||
ModPlatform::IndexedVersion loadIndexedPackVersion(QJsonObject& obj, ModPlatform::ResourceType) const override
|
||||
ModPlatform::IndexedVersion loadIndexedPackVersion(QJsonObject& obj, ModPlatform::ResourceType /*unused*/) const override
|
||||
{
|
||||
return Modrinth::loadIndexedPackVersion(obj);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
#include "tasks/ConcurrentTask.h"
|
||||
|
||||
static ModrinthAPI api;
|
||||
static const ModrinthAPI g_api;
|
||||
|
||||
ModrinthCheckUpdate::ModrinthCheckUpdate(QList<Resource*>& resources,
|
||||
std::vector<Version>& mcVersions,
|
||||
|
|
@ -25,11 +25,11 @@ ModrinthCheckUpdate::ModrinthCheckUpdate(QList<Resource*>& resources,
|
|||
if (!m_loadersList.isEmpty()) { // this is for mods so append all the other posible loaders to the initial list
|
||||
m_initialSize = m_loadersList.length();
|
||||
ModPlatform::ModLoaderTypes modLoaders;
|
||||
for (auto m : resources) {
|
||||
for (auto* m : resources) {
|
||||
modLoaders |= m->metadata()->loaders;
|
||||
}
|
||||
for (auto l : m_loadersList) {
|
||||
modLoaders &= ~l;
|
||||
modLoaders &= ~static_cast<std::uint16_t>(l);
|
||||
}
|
||||
m_loadersList.append(ModPlatform::modLoaderTypesToList(modLoaders));
|
||||
}
|
||||
|
|
@ -37,8 +37,9 @@ ModrinthCheckUpdate::ModrinthCheckUpdate(QList<Resource*>& resources,
|
|||
|
||||
bool ModrinthCheckUpdate::abort()
|
||||
{
|
||||
if (m_job)
|
||||
if (m_job) {
|
||||
return m_job->abort();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -50,7 +51,7 @@ bool ModrinthCheckUpdate::abort()
|
|||
void ModrinthCheckUpdate::executeTask()
|
||||
{
|
||||
setStatus(tr("Preparing resources for Modrinth..."));
|
||||
setProgress(0, (m_loadersList.isEmpty() ? 1 : m_loadersList.length()) * 2 + 1);
|
||||
setProgress(0, ((m_loadersList.isEmpty() ? 1 : m_loadersList.length()) * 2) + 1);
|
||||
|
||||
auto hashing_task =
|
||||
makeShared<ConcurrentTask>("MakeModrinthHashesTask", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt());
|
||||
|
|
@ -90,8 +91,8 @@ void ModrinthCheckUpdate::getUpdateModsForLoader(std::optional<ModPlatform::ModL
|
|||
|
||||
QStringList hashes;
|
||||
if (forceModLoaderCheck && loader.has_value()) {
|
||||
for (auto hash : m_mappings.keys()) {
|
||||
if (m_mappings.value(hash)->metadata()->loaders & loader.value()) {
|
||||
for (const auto& hash : m_mappings.keys()) {
|
||||
if ((m_mappings.value(hash)->metadata()->loaders & loader.value()) != 0) {
|
||||
hashes.append(hash);
|
||||
}
|
||||
}
|
||||
|
|
@ -104,7 +105,7 @@ void ModrinthCheckUpdate::getUpdateModsForLoader(std::optional<ModPlatform::ModL
|
|||
return;
|
||||
}
|
||||
|
||||
auto [job, response] = api.latestVersions(hashes, m_hashType, m_gameVersions, loader);
|
||||
auto [job, response] = g_api.latestVersions(hashes, m_hashType, m_gameVersions, loader);
|
||||
|
||||
connect(job.get(), &Task::succeeded, this, [this, response, loader] { checkVersionsResponse(response, loader); });
|
||||
|
||||
|
|
|
|||
|
|
@ -25,5 +25,5 @@ class ModrinthCheckUpdate : public CheckUpdateTask {
|
|||
QHash<QString, Resource*> m_mappings;
|
||||
QString m_hashType;
|
||||
int m_loaderIdx = 0;
|
||||
int m_initialSize = 0;
|
||||
qsizetype m_initialSize = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -26,9 +26,7 @@
|
|||
#include "minecraft/PackProfile.h"
|
||||
#include "modplatform/ModIndex.h"
|
||||
|
||||
static ModrinthAPI api;
|
||||
|
||||
bool shouldDownloadOnSide(QString side)
|
||||
bool shouldDownloadOnSide(const QString& side)
|
||||
{
|
||||
return side == "required" || side == "optional";
|
||||
}
|
||||
|
|
@ -37,17 +35,19 @@ bool shouldDownloadOnSide(QString side)
|
|||
void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj)
|
||||
{
|
||||
pack.addonId = obj["project_id"].toString();
|
||||
if (pack.addonId.toString().isEmpty())
|
||||
if (pack.addonId.toString().isEmpty()) {
|
||||
pack.addonId = Json::requireString(obj, "id");
|
||||
}
|
||||
|
||||
pack.provider = ModPlatform::ResourceProvider::MODRINTH;
|
||||
pack.name = Json::requireString(obj, "title");
|
||||
|
||||
pack.slug = obj["slug"].toString("");
|
||||
if (!pack.slug.isEmpty())
|
||||
if (!pack.slug.isEmpty()) {
|
||||
pack.websiteUrl = "https://modrinth.com/mod/" + pack.slug;
|
||||
else
|
||||
} else {
|
||||
pack.websiteUrl = "";
|
||||
}
|
||||
|
||||
pack.description = obj["description"].toString("");
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj)
|
|||
if (obj.contains("author")) {
|
||||
ModPlatform::ModpackAuthor modAuthor;
|
||||
modAuthor.name = obj["author"].toString();
|
||||
modAuthor.url = api.getAuthorURL(modAuthor.name);
|
||||
modAuthor.url = ModrinthAPI::getAuthorURL(modAuthor.name);
|
||||
pack.authors = { modAuthor };
|
||||
}
|
||||
|
||||
|
|
@ -91,8 +91,9 @@ void Modrinth::loadExtraPackData(ModPlatform::IndexedPack& pack, QJsonObject& ob
|
|||
pack.extraData.wikiUrl.chop(1);
|
||||
|
||||
pack.extraData.discordUrl = obj["discord_url"].toString();
|
||||
if (pack.extraData.discordUrl.endsWith('/'))
|
||||
if (pack.extraData.discordUrl.endsWith('/')) {
|
||||
pack.extraData.discordUrl.chop(1);
|
||||
}
|
||||
|
||||
auto donate_arr = obj["donation_urls"].toArray();
|
||||
for (auto d : donate_arr) {
|
||||
|
|
@ -114,7 +115,9 @@ void Modrinth::loadExtraPackData(ModPlatform::IndexedPack& pack, QJsonObject& ob
|
|||
pack.extraDataLoaded = true;
|
||||
}
|
||||
|
||||
ModPlatform::IndexedVersion Modrinth::loadIndexedPackVersion(QJsonObject& obj, QString preferred_hash_type, QString preferred_file_name)
|
||||
ModPlatform::IndexedVersion Modrinth::loadIndexedPackVersion(QJsonObject& obj,
|
||||
const QString& preferred_hash_type,
|
||||
const QString& preferred_file_name)
|
||||
{
|
||||
ModPlatform::IndexedVersion file;
|
||||
|
||||
|
|
@ -131,24 +134,27 @@ ModPlatform::IndexedVersion Modrinth::loadIndexedPackVersion(QJsonObject& obj, Q
|
|||
}
|
||||
auto loaders = Json::requireArray(obj, "loaders");
|
||||
for (auto loader : loaders) {
|
||||
if (loader == "neoforge")
|
||||
if (loader == "neoforge") {
|
||||
file.loaders |= ModPlatform::NeoForge;
|
||||
else if (loader == "forge")
|
||||
} else if (loader == "forge") {
|
||||
file.loaders |= ModPlatform::Forge;
|
||||
else if (loader == "cauldron")
|
||||
} else if (loader == "cauldron") {
|
||||
file.loaders |= ModPlatform::Cauldron;
|
||||
else if (loader == "liteloader")
|
||||
} else if (loader == "liteloader") {
|
||||
file.loaders |= ModPlatform::LiteLoader;
|
||||
else if (loader == "fabric")
|
||||
} else if (loader == "fabric") {
|
||||
file.loaders |= ModPlatform::Fabric;
|
||||
else if (loader == "quilt")
|
||||
} else if (loader == "quilt") {
|
||||
file.loaders |= ModPlatform::Quilt;
|
||||
}
|
||||
}
|
||||
file.version = Json::requireString(obj, "name");
|
||||
file.version_number = Json::requireString(obj, "version_number");
|
||||
file.version_type = ModPlatform::IndexedVersionType::fromString(Json::requireString(obj, "version_type"));
|
||||
|
||||
file.changelog = Json::requireString(obj, "changelog");
|
||||
if (obj.contains("changelog")) {
|
||||
file.changelog = Json::requireString(obj, "changelog");
|
||||
}
|
||||
|
||||
auto dependencies = obj["dependencies"].toArray();
|
||||
for (auto d : dependencies) {
|
||||
|
|
@ -158,16 +164,17 @@ ModPlatform::IndexedVersion Modrinth::loadIndexedPackVersion(QJsonObject& obj, Q
|
|||
dependency.version = dep["version_id"].toString();
|
||||
auto depType = Json::requireString(dep, "dependency_type");
|
||||
|
||||
if (depType == "required")
|
||||
if (depType == "required") {
|
||||
dependency.type = ModPlatform::DependencyType::REQUIRED;
|
||||
else if (depType == "optional")
|
||||
} else if (depType == "optional") {
|
||||
dependency.type = ModPlatform::DependencyType::OPTIONAL;
|
||||
else if (depType == "incompatible")
|
||||
} else if (depType == "incompatible") {
|
||||
dependency.type = ModPlatform::DependencyType::INCOMPATIBLE;
|
||||
else if (depType == "embedded")
|
||||
} else if (depType == "embedded") {
|
||||
dependency.type = ModPlatform::DependencyType::EMBEDDED;
|
||||
else
|
||||
} else {
|
||||
dependency.type = ModPlatform::DependencyType::UNKNOWN;
|
||||
}
|
||||
|
||||
file.dependencies.append(dependency);
|
||||
}
|
||||
|
|
@ -195,8 +202,9 @@ ModPlatform::IndexedVersion Modrinth::loadIndexedPackVersion(QJsonObject& obj, Q
|
|||
}
|
||||
|
||||
// Grab the primary file, if available
|
||||
if (Json::requireBoolean(parent, "primary"))
|
||||
if (Json::requireBoolean(parent, "primary")) {
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,9 @@
|
|||
|
||||
namespace Modrinth {
|
||||
|
||||
void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj);
|
||||
void loadExtraPackData(ModPlatform::IndexedPack& m, QJsonObject& obj);
|
||||
auto loadIndexedPackVersion(QJsonObject& obj, QString hash_type = "sha512", QString filename_prefer = "") -> ModPlatform::IndexedVersion;
|
||||
void loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj);
|
||||
void loadExtraPackData(ModPlatform::IndexedPack& pack, QJsonObject& obj);
|
||||
auto loadIndexedPackVersion(QJsonObject& obj, const QString& preferred_hash_type = "sha512", const QString& preferred_file_name = "")
|
||||
-> ModPlatform::IndexedVersion;
|
||||
|
||||
} // namespace Modrinth
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@
|
|||
|
||||
#include <QButtonGroup>
|
||||
#include <QDialog>
|
||||
#include <cstdint>
|
||||
|
||||
namespace Ui {
|
||||
class ChooseProviderDialog;
|
||||
}
|
||||
|
||||
namespace ModPlatform {
|
||||
enum class ResourceProvider;
|
||||
enum class ResourceProvider : std::uint8_t;
|
||||
}
|
||||
|
||||
class Mod;
|
||||
|
|
|
|||
|
|
@ -5,14 +5,15 @@
|
|||
#include "ResourcePackModel.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <utility>
|
||||
|
||||
namespace ResourceDownload {
|
||||
|
||||
ResourcePackResourceModel::ResourcePackResourceModel(BaseInstance const& base_inst,
|
||||
ResourcePackResourceModel::ResourcePackResourceModel(const BaseInstance& base_inst,
|
||||
ResourceAPI* api,
|
||||
QString debugName,
|
||||
const QString& debugName,
|
||||
QString metaEntryBase)
|
||||
: ResourceModel(api), m_base_instance(base_inst), m_debugName(debugName + " (Model)"), m_metaEntryBase(metaEntryBase)
|
||||
: ResourceModel(api), m_base_instance(base_inst), m_debugName(debugName + " (Model)"), m_metaEntryBase(std::move(metaEntryBase))
|
||||
{}
|
||||
|
||||
/******** Make data requests ********/
|
||||
|
|
@ -20,19 +21,29 @@ ResourcePackResourceModel::ResourcePackResourceModel(BaseInstance const& base_in
|
|||
ResourceAPI::SearchArgs ResourcePackResourceModel::createSearchArguments()
|
||||
{
|
||||
auto sort = getCurrentSortingMethodByIndex();
|
||||
return { ModPlatform::ResourceType::ResourcePack, m_next_search_offset, m_search_term, sort };
|
||||
return {
|
||||
.type = ModPlatform::ResourceType::ResourcePack,
|
||||
.offset = m_next_search_offset,
|
||||
.search = m_search_term,
|
||||
.sorting = sort,
|
||||
.loaders = {},
|
||||
.versions = {},
|
||||
.side = {},
|
||||
.categoryIds = {},
|
||||
.openSource = {},
|
||||
};
|
||||
}
|
||||
|
||||
ResourceAPI::VersionSearchArgs ResourcePackResourceModel::createVersionsArguments(const QModelIndex& entry)
|
||||
{
|
||||
auto pack = m_packs[entry.row()];
|
||||
return { pack, {}, {}, ModPlatform::ResourceType::ResourcePack };
|
||||
return { .pack = pack, .mcVersions = {}, .loaders = {}, .resourceType = ModPlatform::ResourceType::ResourcePack };
|
||||
}
|
||||
|
||||
ResourceAPI::ProjectInfoArgs ResourcePackResourceModel::createInfoArguments(const QModelIndex& entry)
|
||||
{
|
||||
auto pack = m_packs[entry.row()];
|
||||
return { pack };
|
||||
return { .pack = pack };
|
||||
}
|
||||
|
||||
void ResourcePackResourceModel::searchWithTerm(const QString& term, unsigned int sort)
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@
|
|||
|
||||
#include "BaseInstance.h"
|
||||
|
||||
#include "modplatform/ModIndex.h"
|
||||
|
||||
#include "ui/pages/modplatform/ResourceModel.h"
|
||||
|
||||
class Version;
|
||||
|
|
@ -20,7 +18,7 @@ class ResourcePackResourceModel : public ResourceModel {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ResourcePackResourceModel(BaseInstance const&, ResourceAPI*, QString debugName, QString metaEntryBase);
|
||||
ResourcePackResourceModel(const BaseInstance&, ResourceAPI*, const QString& debugName, QString metaEntryBase);
|
||||
|
||||
/* Ask the API for more information */
|
||||
void searchWithTerm(const QString& term, unsigned int sort);
|
||||
|
|
|
|||
|
|
@ -5,11 +5,15 @@
|
|||
#include "ShaderPackModel.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <utility>
|
||||
|
||||
namespace ResourceDownload {
|
||||
|
||||
ShaderPackResourceModel::ShaderPackResourceModel(BaseInstance const& base_inst, ResourceAPI* api, QString debugName, QString metaEntryBase)
|
||||
: ResourceModel(api), m_base_instance(base_inst), m_debugName(debugName + " (Model)"), m_metaEntryBase(metaEntryBase)
|
||||
ShaderPackResourceModel::ShaderPackResourceModel(const BaseInstance& base_inst,
|
||||
ResourceAPI* api,
|
||||
const QString& debugName,
|
||||
QString metaEntryBase)
|
||||
: ResourceModel(api), m_base_instance(base_inst), m_debugName(debugName + " (Model)"), m_metaEntryBase(std::move(metaEntryBase))
|
||||
{}
|
||||
|
||||
/******** Make data requests ********/
|
||||
|
|
@ -17,19 +21,29 @@ ShaderPackResourceModel::ShaderPackResourceModel(BaseInstance const& base_inst,
|
|||
ResourceAPI::SearchArgs ShaderPackResourceModel::createSearchArguments()
|
||||
{
|
||||
auto sort = getCurrentSortingMethodByIndex();
|
||||
return { ModPlatform::ResourceType::ShaderPack, m_next_search_offset, m_search_term, sort };
|
||||
return {
|
||||
.type = ModPlatform::ResourceType::ShaderPack,
|
||||
.offset = m_next_search_offset,
|
||||
.search = m_search_term,
|
||||
.sorting = sort,
|
||||
.loaders = {},
|
||||
.versions = {},
|
||||
.side = {},
|
||||
.categoryIds = {},
|
||||
.openSource = {},
|
||||
};
|
||||
}
|
||||
|
||||
ResourceAPI::VersionSearchArgs ShaderPackResourceModel::createVersionsArguments(const QModelIndex& entry)
|
||||
{
|
||||
auto pack = m_packs[entry.row()];
|
||||
return { pack, {}, {}, ModPlatform::ResourceType::ShaderPack };
|
||||
return { .pack = pack, .mcVersions = {}, .loaders = {}, .resourceType = ModPlatform::ResourceType::ShaderPack };
|
||||
}
|
||||
|
||||
ResourceAPI::ProjectInfoArgs ShaderPackResourceModel::createInfoArguments(const QModelIndex& entry)
|
||||
{
|
||||
auto pack = m_packs[entry.row()];
|
||||
return { pack };
|
||||
return { .pack = pack };
|
||||
}
|
||||
|
||||
void ShaderPackResourceModel::searchWithTerm(const QString& term, unsigned int sort)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class ShaderPackResourceModel : public ResourceModel {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ShaderPackResourceModel(BaseInstance const&, ResourceAPI*, QString debugName, QString metaEntryBase);
|
||||
ShaderPackResourceModel(const BaseInstance&, ResourceAPI*, const QString& debugName, QString metaEntryBase);
|
||||
|
||||
/* Ask the API for more information */
|
||||
void searchWithTerm(const QString& term, unsigned int sort);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include "TexturePackModel.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "Application.h"
|
||||
|
||||
#include "meta/Index.h"
|
||||
|
|
@ -12,8 +14,12 @@
|
|||
static std::vector<Version> s_availableVersions = {};
|
||||
|
||||
namespace ResourceDownload {
|
||||
TexturePackResourceModel::TexturePackResourceModel(BaseInstance const& inst, ResourceAPI* api, QString debugName, QString metaEntryBase)
|
||||
: ResourcePackResourceModel(inst, api, debugName, metaEntryBase), m_version_list(APPLICATION->metadataIndex()->get("net.minecraft"))
|
||||
TexturePackResourceModel::TexturePackResourceModel(const BaseInstance& inst,
|
||||
ResourceAPI* api,
|
||||
const QString& debugName,
|
||||
QString metaEntryBase)
|
||||
: ResourcePackResourceModel(inst, api, debugName, std::move(metaEntryBase))
|
||||
, m_version_list(APPLICATION->metadataIndex()->get("net.minecraft"))
|
||||
{
|
||||
if (!m_version_list->isLoaded()) {
|
||||
qDebug() << "Loading version list...";
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class TexturePackResourceModel : public ResourcePackResourceModel {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TexturePackResourceModel(BaseInstance const& inst, ResourceAPI* api, QString debugName, QString metaEntryBase);
|
||||
TexturePackResourceModel(const BaseInstance& inst, ResourceAPI* api, const QString& debugName, QString metaEntryBase);
|
||||
|
||||
inline ::Version maximumTexturePackVersion() const { return { "1.6" }; }
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue