mirror of
https://github.com/PrismLauncher/PrismLauncher.git
synced 2026-06-29 01:54:20 +03:00
Merge 148b97ef94 into 9c2c641531
This commit is contained in:
commit
2b7fc2b17f
24 changed files with 333 additions and 276 deletions
|
|
@ -39,6 +39,7 @@ set(CORE_SOURCES
|
||||||
QVariantUtils.h
|
QVariantUtils.h
|
||||||
RuntimeContext.h
|
RuntimeContext.h
|
||||||
PSaveFile.h
|
PSaveFile.h
|
||||||
|
EnumWrapper.h
|
||||||
|
|
||||||
# Basic instance manipulation tasks (derived from InstanceTask)
|
# Basic instance manipulation tasks (derived from InstanceTask)
|
||||||
InstanceCreationTask.h
|
InstanceCreationTask.h
|
||||||
|
|
|
||||||
71
launcher/EnumWrapper.h
Normal file
71
launcher/EnumWrapper.h
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
/*
|
||||||
|
* Prism Launcher - Minecraft Launcher
|
||||||
|
* Copyright (C) 2026 Rachel Powers <508861+Ryex@users.noreply.github.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QtGlobal>
|
||||||
|
#include <compare>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
template <typename Derived, typename EnumV>
|
||||||
|
struct EnumWrapper {
|
||||||
|
using Enum = EnumV;
|
||||||
|
using EnumBase = std::underlying_type_t<Enum>;
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(hicpp-explicit-conversions)
|
||||||
|
constexpr EnumWrapper(Enum e = Derived::invalid()) : m_value(e) {}
|
||||||
|
|
||||||
|
constexpr bool isValid() const { return m_value != Derived::invalid(); }
|
||||||
|
|
||||||
|
bool operator==(const EnumWrapper&) const = default;
|
||||||
|
|
||||||
|
std::strong_ordering operator<=>(const EnumWrapper& other) const { return m_value <=> other.m_value; };
|
||||||
|
|
||||||
|
std::strong_ordering operator<=>(Enum other) const { return m_value <=> other; }
|
||||||
|
|
||||||
|
QString toString() const
|
||||||
|
{
|
||||||
|
for (auto&& [e, name] : Derived::mapping()) {
|
||||||
|
if (e == m_value) {
|
||||||
|
return QString(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Q_ASSERT_X(false, "EnumWrapper::toString()", "No string mapping found for current enum value");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr Derived fromString(const QString& str)
|
||||||
|
{
|
||||||
|
for (auto&& [e, name] : Derived::mapping()) {
|
||||||
|
if (str == name) {
|
||||||
|
return Derived(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Derived(Derived::invalid());
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit operator EnumBase() const { return static_cast<EnumBase>(m_value); }
|
||||||
|
|
||||||
|
explicit operator Enum() const { return m_value; }
|
||||||
|
|
||||||
|
Enum value() const { return m_value; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Enum m_value;
|
||||||
|
};
|
||||||
|
|
@ -1,30 +1,5 @@
|
||||||
#include "MessageLevel.h"
|
#include "MessageLevel.h"
|
||||||
|
|
||||||
MessageLevel MessageLevel::fromName(const QString& levelName)
|
|
||||||
{
|
|
||||||
QString name = levelName.toUpper();
|
|
||||||
if (name == "LAUNCHER")
|
|
||||||
return MessageLevel::Launcher;
|
|
||||||
else if (name == "TRACE")
|
|
||||||
return MessageLevel::Trace;
|
|
||||||
else if (name == "DEBUG")
|
|
||||||
return MessageLevel::Debug;
|
|
||||||
else if (name == "INFO")
|
|
||||||
return MessageLevel::Info;
|
|
||||||
else if (name == "MESSAGE")
|
|
||||||
return MessageLevel::Message;
|
|
||||||
else if (name == "WARNING" || name == "WARN")
|
|
||||||
return MessageLevel::Warning;
|
|
||||||
else if (name == "ERROR" || name == "CRITICAL")
|
|
||||||
return MessageLevel::Error;
|
|
||||||
else if (name == "FATAL")
|
|
||||||
return MessageLevel::Fatal;
|
|
||||||
// Skip PrePost, it's not exposed to !![]!
|
|
||||||
// Also skip StdErr and StdOut
|
|
||||||
else
|
|
||||||
return MessageLevel::Unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageLevel MessageLevel::fromQtMsgType(const QtMsgType& type)
|
MessageLevel MessageLevel::fromQtMsgType(const QtMsgType& type)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,51 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <compare>
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <utility>
|
||||||
|
#include "EnumWrapper.h"
|
||||||
|
|
||||||
|
enum class MessageLevelValue : std::uint8_t {
|
||||||
|
Unknown, /**< No idea what this is or where it came from */
|
||||||
|
StdOut, /**< Undetermined stderr messages */
|
||||||
|
StdErr, /**< Undetermined stdout messages */
|
||||||
|
Launcher, /**< Launcher Messages */
|
||||||
|
Trace, /**< Trace Messages */
|
||||||
|
Debug, /**< Debug Messages */
|
||||||
|
Info, /**< Info Messages */
|
||||||
|
Message, /**< Standard Messages */
|
||||||
|
Warning, /**< Warnings */
|
||||||
|
Error, /**< Errors */
|
||||||
|
Fatal, /**< Fatal Errors */
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief the MessageLevel Enum
|
* @brief the MessageLevel Enum
|
||||||
* defines what level a log message is
|
* defines what level a log message is
|
||||||
*/
|
*/
|
||||||
struct MessageLevel {
|
struct MessageLevel : EnumWrapper<MessageLevel, MessageLevelValue> {
|
||||||
enum class Enum {
|
static constexpr auto invalid() { return Unknown; };
|
||||||
Unknown, /**< No idea what this is or where it came from */
|
static constexpr auto mapping()
|
||||||
StdOut, /**< Undetermined stderr messages */
|
{
|
||||||
StdErr, /**< Undetermined stdout messages */
|
return std::array{
|
||||||
Launcher, /**< Launcher Messages */
|
std::pair{ Unknown, "UNKNOWN" }, std::pair{ Launcher, "LAUNCHER" }, std::pair{ Trace, "TRACE" },
|
||||||
Trace, /**< Trace Messages */
|
std::pair{ Debug, "DEBUG" }, std::pair{ Info, "INFO" }, std::pair{ Message, "MESSAGE" },
|
||||||
Debug, /**< Debug Messages */
|
std::pair{ Warning, "WARNING" }, std::pair{ Warning, "WARN" }, std::pair{ Error, "ERROR" },
|
||||||
Info, /**< Info Messages */
|
std::pair{ Error, "CRITICAL" }, std::pair{ Fatal, "FATAL" },
|
||||||
Message, /**< Standard Messages */
|
};
|
||||||
Warning, /**< Warnings */
|
|
||||||
Error, /**< Errors */
|
|
||||||
Fatal, /**< Fatal Errors */
|
|
||||||
};
|
};
|
||||||
using enum Enum;
|
using enum MessageLevelValue;
|
||||||
constexpr MessageLevel(Enum e = Unknown) : m_type(e) {}
|
using Base = EnumWrapper<MessageLevel, MessageLevelValue>;
|
||||||
static MessageLevel fromName(const QString& type);
|
using Base::Base; /* inherit ctor */
|
||||||
|
|
||||||
|
static MessageLevel fromName(const QString& type) { return fromString(type.toUpper()); };
|
||||||
static MessageLevel fromQtMsgType(const QtMsgType& type);
|
static MessageLevel fromQtMsgType(const QtMsgType& type);
|
||||||
static MessageLevel fromLine(const QString& line);
|
static MessageLevel fromLine(const QString& line);
|
||||||
inline bool isValid() const { return m_type != Unknown; }
|
|
||||||
std::strong_ordering operator<=>(const MessageLevel& other) const = default;
|
|
||||||
std::strong_ordering operator<=>(const MessageLevel::Enum& other) const { return m_type <=> other; }
|
|
||||||
explicit operator int() const { return static_cast<int>(m_type); }
|
|
||||||
explicit operator MessageLevel::Enum() { return m_type; }
|
|
||||||
|
|
||||||
/* Get message level from a line. Line is modified if it was successful. */
|
/* Get message level from a line. Line is modified if it was successful. */
|
||||||
static MessageLevel takeFromLine(QString& line);
|
static MessageLevel takeFromLine(QString& line);
|
||||||
|
|
||||||
/* Get message level from a line from the launcher log. Line is modified if it was successful. */
|
/* Get message level from a line from the launcher log. Line is modified if it was successful. */
|
||||||
static MessageLevel takeFromLauncherLine(QString& line);
|
static MessageLevel takeFromLauncherLine(QString& line);
|
||||||
|
|
||||||
private:
|
|
||||||
Enum m_type;
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ QVariant LogModel::data(const QModelIndex& index, int role) const
|
||||||
return m_content[realRow].line;
|
return m_content[realRow].line;
|
||||||
}
|
}
|
||||||
if (role == LevelRole) {
|
if (role == LevelRole) {
|
||||||
return static_cast<int>(m_content[realRow].level);
|
return static_cast<int>(m_content[realRow].level.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
|
||||||
|
|
@ -192,9 +192,9 @@ auto Mod::loaders() const -> QString
|
||||||
auto Mod::side() const -> QString
|
auto Mod::side() const -> QString
|
||||||
{
|
{
|
||||||
if (metadata())
|
if (metadata())
|
||||||
return ModPlatform::SideUtils::toString(metadata()->side);
|
return metadata()->side.toString();
|
||||||
|
|
||||||
return ModPlatform::SideUtils::toString(ModPlatform::Side::UniversalSide);
|
return ModPlatform::SideType(ModPlatform::SideType::UniversalSide).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Mod::mcVersions() const -> QString
|
auto Mod::mcVersions() const -> QString
|
||||||
|
|
|
||||||
|
|
@ -30,10 +30,6 @@ ModLoaderType operator|(ModLoaderType lhs, ModLoaderType rhs)
|
||||||
return static_cast<ModLoaderType>(static_cast<std::uint16_t>(lhs) | static_cast<std::uint16_t>(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 } };
|
|
||||||
|
|
||||||
static const QList<ModLoaderType> loaderList = { NeoForge, Forge, Cauldron, LiteLoader, Quilt, Fabric,
|
static const QList<ModLoaderType> loaderList = { NeoForge, Forge, Cauldron, LiteLoader, Quilt, Fabric,
|
||||||
Babric, BTA, LegacyFabric, Ornithe, Rift };
|
Babric, BTA, LegacyFabric, Ornithe, Rift };
|
||||||
|
|
||||||
|
|
@ -48,16 +44,6 @@ QList<ModLoaderType> modLoaderTypesToList(ModLoaderTypes flags)
|
||||||
return flagList;
|
return flagList;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString IndexedVersionType::toString() const
|
|
||||||
{
|
|
||||||
return s_indexed_version_type_names.key(m_type, "unknown");
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexedVersionType IndexedVersionType::fromString(const QString& type)
|
|
||||||
{
|
|
||||||
return s_indexed_version_type_names.value(type, IndexedVersionType::Unknown);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* ProviderCapabilities::name(ResourceProvider p)
|
const char* ProviderCapabilities::name(ResourceProvider p)
|
||||||
{
|
{
|
||||||
switch (p) {
|
switch (p) {
|
||||||
|
|
@ -158,65 +144,4 @@ auto getModLoaderFromString(QString type) -> ModLoaderType
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SideUtils::toString(Side side)
|
|
||||||
{
|
|
||||||
switch (side) {
|
|
||||||
case Side::ClientSide:
|
|
||||||
return "client";
|
|
||||||
case Side::ServerSide:
|
|
||||||
return "server";
|
|
||||||
case Side::UniversalSide:
|
|
||||||
return "both";
|
|
||||||
case Side::NoSide:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Side SideUtils::fromString(QString side)
|
|
||||||
{
|
|
||||||
if (side == "client")
|
|
||||||
return Side::ClientSide;
|
|
||||||
if (side == "server")
|
|
||||||
return Side::ServerSide;
|
|
||||||
if (side == "both")
|
|
||||||
return Side::UniversalSide;
|
|
||||||
return Side::UniversalSide;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString DependencyTypeUtils::toString(DependencyType type)
|
|
||||||
{
|
|
||||||
switch (type) {
|
|
||||||
case DependencyType::REQUIRED:
|
|
||||||
return "REQUIRED";
|
|
||||||
case DependencyType::OPTIONAL:
|
|
||||||
return "OPTIONAL";
|
|
||||||
case DependencyType::INCOMPATIBLE:
|
|
||||||
return "INCOMPATIBLE";
|
|
||||||
case DependencyType::EMBEDDED:
|
|
||||||
return "EMBEDDED";
|
|
||||||
case DependencyType::TOOL:
|
|
||||||
return "TOOL";
|
|
||||||
case DependencyType::INCLUDE:
|
|
||||||
return "INCLUDE";
|
|
||||||
case DependencyType::UNKNOWN:
|
|
||||||
return "UNKNOWN";
|
|
||||||
}
|
|
||||||
return "UNKNOWN";
|
|
||||||
}
|
|
||||||
|
|
||||||
DependencyType DependencyTypeUtils::fromString(const QString& str)
|
|
||||||
{
|
|
||||||
static const QHash<QString, DependencyType> map = {
|
|
||||||
{ "REQUIRED", DependencyType::REQUIRED },
|
|
||||||
{ "OPTIONAL", DependencyType::OPTIONAL },
|
|
||||||
{ "INCOMPATIBLE", DependencyType::INCOMPATIBLE },
|
|
||||||
{ "EMBEDDED", DependencyType::EMBEDDED },
|
|
||||||
{ "TOOL", DependencyType::TOOL },
|
|
||||||
{ "INCLUDE", DependencyType::INCLUDE },
|
|
||||||
{ "UNKNOWN", DependencyType::UNKNOWN },
|
|
||||||
};
|
|
||||||
|
|
||||||
return map.value(str.toUpper(), DependencyType::UNKNOWN);
|
|
||||||
}
|
|
||||||
} // namespace ModPlatform
|
} // namespace ModPlatform
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,11 @@
|
||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <compare>
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
#include "EnumWrapper.h"
|
||||||
|
|
||||||
class QIODevice;
|
class QIODevice;
|
||||||
|
|
||||||
|
|
@ -56,19 +58,48 @@ QList<ModLoaderType> modLoaderTypesToList(ModLoaderTypes flags);
|
||||||
|
|
||||||
enum class ResourceProvider : std::uint8_t { MODRINTH, FLAME };
|
enum class ResourceProvider : std::uint8_t { MODRINTH, FLAME };
|
||||||
|
|
||||||
enum class DependencyType : std::uint8_t { REQUIRED, OPTIONAL, INCOMPATIBLE, EMBEDDED, TOOL, INCLUDE, UNKNOWN };
|
enum class DependencyTypeValue : std::uint8_t { REQUIRED, OPTIONAL, INCOMPATIBLE, EMBEDDED, TOOL, INCLUDE, UNKNOWN };
|
||||||
|
struct DependencyType : EnumWrapper<DependencyType, DependencyTypeValue> {
|
||||||
|
static constexpr auto invalid() { return UNKNOWN; };
|
||||||
|
|
||||||
enum class Side : std::uint8_t { NoSide = 0, ClientSide = 1U << 0U, ServerSide = 1U << 1U, UniversalSide = ClientSide | ServerSide };
|
static constexpr auto mapping()
|
||||||
|
{
|
||||||
|
return std::array{
|
||||||
|
std::pair{ REQUIRED, "REQUIRED" }, std::pair{ OPTIONAL, "OPTIONAL" }, std::pair{ INCOMPATIBLE, "INCOMPATIBLE" },
|
||||||
|
std::pair{ EMBEDDED, "EMBEDDED" }, std::pair{ TOOL, "TOOL" }, std::pair{ INCLUDE, "INCLUDE" },
|
||||||
|
std::pair{ UNKNOWN, "UNKNOWN" },
|
||||||
|
};
|
||||||
|
};
|
||||||
|
static DependencyType fromString(const QString& str)
|
||||||
|
{
|
||||||
|
return EnumWrapper<DependencyType, DependencyTypeValue>::fromString(str.toUpper());
|
||||||
|
}
|
||||||
|
|
||||||
namespace SideUtils {
|
using enum DependencyTypeValue;
|
||||||
QString toString(Side side);
|
using Base = EnumWrapper<DependencyType, DependencyTypeValue>;
|
||||||
Side fromString(QString side);
|
using Base::Base; /* inherit ctor */
|
||||||
} // namespace SideUtils
|
};
|
||||||
|
|
||||||
namespace DependencyTypeUtils {
|
enum class SideTypeValue : std::uint8_t {
|
||||||
QString toString(DependencyType type);
|
NoSide = 0,
|
||||||
DependencyType fromString(const QString& str);
|
ClientSide = 1U << 0U,
|
||||||
} // namespace DependencyTypeUtils
|
ServerSide = 1U << 1U,
|
||||||
|
UniversalSide = ClientSide | ServerSide
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SideType : EnumWrapper<SideType, SideTypeValue> {
|
||||||
|
static constexpr auto invalid() { return NoSide; };
|
||||||
|
|
||||||
|
static constexpr auto mapping()
|
||||||
|
{
|
||||||
|
return std::array{ std::pair{ ClientSide, "client" }, std::pair{ ServerSide, "server" }, std::pair{ UniversalSide, "both" },
|
||||||
|
std::pair{ NoSide, "" } };
|
||||||
|
};
|
||||||
|
|
||||||
|
using enum SideTypeValue;
|
||||||
|
using Base = EnumWrapper<SideType, SideTypeValue>;
|
||||||
|
using Base::Base; /* inherit ctor */
|
||||||
|
};
|
||||||
|
|
||||||
namespace ProviderCapabilities {
|
namespace ProviderCapabilities {
|
||||||
const char* name(ResourceProvider);
|
const char* name(ResourceProvider);
|
||||||
|
|
@ -87,20 +118,19 @@ struct DonationData {
|
||||||
QString url;
|
QString url;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IndexedVersionType {
|
enum class IndexedVersionTypeValue : std::uint8_t { Unknown = 0, Release = 1, Beta = 2, Alpha = 3 };
|
||||||
enum class Enum : std::uint8_t { Unknown = 0, Release = 1, Beta = 2, Alpha = 3 };
|
struct IndexedVersionType : EnumWrapper<IndexedVersionType, IndexedVersionTypeValue> {
|
||||||
using enum Enum;
|
static constexpr auto invalid() { return Unknown; };
|
||||||
constexpr IndexedVersionType(Enum e = Unknown) : m_type(e) {} // NOLINT(hicpp-explicit-conversions)
|
|
||||||
static IndexedVersionType fromString(const QString& type);
|
|
||||||
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;
|
|
||||||
explicit operator int() const { return static_cast<int>(m_type); }
|
|
||||||
explicit operator IndexedVersionType::Enum() { return m_type; }
|
|
||||||
|
|
||||||
private:
|
static constexpr auto mapping()
|
||||||
Enum m_type;
|
{
|
||||||
|
return std::array{ std::pair{ Unknown, "Unknown" }, std::pair{ Release, "Release" }, std::pair{ Beta, "Beta" },
|
||||||
|
std::pair{ Alpha, "Alpha" } };
|
||||||
|
};
|
||||||
|
|
||||||
|
using enum IndexedVersionTypeValue;
|
||||||
|
using Base = EnumWrapper<IndexedVersionType, IndexedVersionTypeValue>;
|
||||||
|
using Base::Base; /* inherit ctor */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Dependency {
|
struct Dependency {
|
||||||
|
|
@ -125,7 +155,7 @@ struct IndexedVersion {
|
||||||
bool is_preferred = true;
|
bool is_preferred = true;
|
||||||
QString changelog;
|
QString changelog;
|
||||||
QList<Dependency> dependencies;
|
QList<Dependency> dependencies;
|
||||||
Side side = Side::NoSide; // this is for flame API
|
SideType side = SideType::NoSide; // this is for flame API
|
||||||
|
|
||||||
// For internal use, not provided by APIs
|
// For internal use, not provided by APIs
|
||||||
bool is_currently_selected = false;
|
bool is_currently_selected = false;
|
||||||
|
|
@ -173,7 +203,7 @@ struct IndexedPack {
|
||||||
QString logoName;
|
QString logoName;
|
||||||
QString logoUrl;
|
QString logoUrl;
|
||||||
QString websiteUrl;
|
QString websiteUrl;
|
||||||
Side side = Side::NoSide;
|
SideType side = SideType::NoSide;
|
||||||
|
|
||||||
bool versionsLoaded = false;
|
bool versionsLoaded = false;
|
||||||
QList<IndexedVersion> versions;
|
QList<IndexedVersion> versions;
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ class ResourceAPI {
|
||||||
std::optional<SortingMethod> sorting;
|
std::optional<SortingMethod> sorting;
|
||||||
std::optional<ModPlatform::ModLoaderTypes> loaders;
|
std::optional<ModPlatform::ModLoaderTypes> loaders;
|
||||||
std::optional<std::vector<Version>> versions;
|
std::optional<std::vector<Version>> versions;
|
||||||
std::optional<ModPlatform::Side> side;
|
std::optional<ModPlatform::SideType> side;
|
||||||
std::optional<QStringList> categoryIds;
|
std::optional<QStringList> categoryIds;
|
||||||
bool openSource{};
|
bool openSource{};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,9 @@
|
||||||
|
|
||||||
#include "FileSystem.h"
|
#include "FileSystem.h"
|
||||||
#include "Json.h"
|
#include "Json.h"
|
||||||
#include "minecraft/MinecraftInstance.h"
|
|
||||||
#include "minecraft/PackProfile.h"
|
|
||||||
#include "modplatform/ModIndex.h"
|
#include "modplatform/ModIndex.h"
|
||||||
#include "modplatform/flame/FlameAPI.h"
|
#include "modplatform/flame/FlameAPI.h"
|
||||||
|
|
||||||
static FlameAPI api;
|
|
||||||
|
|
||||||
void FlameMod::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj)
|
void FlameMod::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj)
|
||||||
{
|
{
|
||||||
pack.addonId = Json::requireInteger(obj, "id");
|
pack.addonId = Json::requireInteger(obj, "id");
|
||||||
|
|
@ -46,30 +42,36 @@ void FlameMod::loadURLs(ModPlatform::IndexedPack& pack, QJsonObject& obj)
|
||||||
auto links_obj = obj["links"].toObject();
|
auto links_obj = obj["links"].toObject();
|
||||||
|
|
||||||
pack.extraData.issuesUrl = links_obj["issuesUrl"].toString();
|
pack.extraData.issuesUrl = links_obj["issuesUrl"].toString();
|
||||||
if (pack.extraData.issuesUrl.endsWith('/'))
|
if (pack.extraData.issuesUrl.endsWith('/')) {
|
||||||
pack.extraData.issuesUrl.chop(1);
|
pack.extraData.issuesUrl.chop(1);
|
||||||
|
}
|
||||||
|
|
||||||
pack.extraData.sourceUrl = links_obj["sourceUrl"].toString();
|
pack.extraData.sourceUrl = links_obj["sourceUrl"].toString();
|
||||||
if (pack.extraData.sourceUrl.endsWith('/'))
|
if (pack.extraData.sourceUrl.endsWith('/')) {
|
||||||
pack.extraData.sourceUrl.chop(1);
|
pack.extraData.sourceUrl.chop(1);
|
||||||
|
}
|
||||||
|
|
||||||
pack.extraData.wikiUrl = links_obj["wikiUrl"].toString();
|
pack.extraData.wikiUrl = links_obj["wikiUrl"].toString();
|
||||||
if (pack.extraData.wikiUrl.endsWith('/'))
|
if (pack.extraData.wikiUrl.endsWith('/')) {
|
||||||
pack.extraData.wikiUrl.chop(1);
|
pack.extraData.wikiUrl.chop(1);
|
||||||
|
}
|
||||||
|
|
||||||
if (!pack.extraData.body.isEmpty())
|
if (!pack.extraData.body.isEmpty()) {
|
||||||
pack.extraDataLoaded = true;
|
pack.extraDataLoaded = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlameMod::loadBody(ModPlatform::IndexedPack& pack)
|
void FlameMod::loadBody(ModPlatform::IndexedPack& pack)
|
||||||
{
|
{
|
||||||
pack.extraData.body = api.getModDescription(pack.addonId.toInt());
|
pack.extraData.body = FlameAPI().getModDescription(pack.addonId.toInt());
|
||||||
|
|
||||||
if (!pack.extraData.issuesUrl.isEmpty() || !pack.extraData.sourceUrl.isEmpty() || !pack.extraData.wikiUrl.isEmpty())
|
if (!pack.extraData.issuesUrl.isEmpty() || !pack.extraData.sourceUrl.isEmpty() || !pack.extraData.wikiUrl.isEmpty()) {
|
||||||
pack.extraDataLoaded = true;
|
pack.extraDataLoaded = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString enumToString(int hash_algorithm)
|
namespace {
|
||||||
|
QString enumToString(int hash_algorithm)
|
||||||
{
|
{
|
||||||
switch (hash_algorithm) {
|
switch (hash_algorithm) {
|
||||||
default:
|
default:
|
||||||
|
|
@ -79,6 +81,7 @@ static QString enumToString(int hash_algorithm)
|
||||||
return "md5";
|
return "md5";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
void FlameMod::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, QJsonArray& arr)
|
void FlameMod::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, QJsonArray& arr)
|
||||||
{
|
{
|
||||||
|
|
@ -87,11 +90,13 @@ void FlameMod::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, QJsonArra
|
||||||
auto obj = versionIter.toObject();
|
auto obj = versionIter.toObject();
|
||||||
|
|
||||||
auto file = loadIndexedPackVersion(obj);
|
auto file = loadIndexedPackVersion(obj);
|
||||||
if (!file.addonId.isValid())
|
if (!file.addonId.isValid()) {
|
||||||
file.addonId = pack.addonId;
|
file.addonId = pack.addonId;
|
||||||
|
}
|
||||||
|
|
||||||
if (file.fileId.isValid()) // Heuristic to check if the returned value is valid
|
if (file.fileId.isValid()) { // Heuristic to check if the returned value is valid
|
||||||
unsortedVersions.append(file);
|
unsortedVersions.append(file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto orderSortPredicate = [](const ModPlatform::IndexedVersion& a, const ModPlatform::IndexedVersion& b) -> bool {
|
auto orderSortPredicate = [](const ModPlatform::IndexedVersion& a, const ModPlatform::IndexedVersion& b) -> bool {
|
||||||
|
|
@ -111,27 +116,29 @@ auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool load_changelog) ->
|
||||||
for (auto mcVer : versionArray) {
|
for (auto mcVer : versionArray) {
|
||||||
auto str = mcVer.toString();
|
auto str = mcVer.toString();
|
||||||
|
|
||||||
if (str.contains('.'))
|
if (str.contains('.')) {
|
||||||
file.mcVersion.append(str);
|
file.mcVersion.append(str);
|
||||||
|
}
|
||||||
|
|
||||||
file.side = ModPlatform::Side::NoSide;
|
file.side = ModPlatform::SideType::NoSide;
|
||||||
if (auto loader = str.toLower(); loader == "neoforge")
|
if (auto loader = str.toLower(); loader == "neoforge") {
|
||||||
file.loaders |= ModPlatform::NeoForge;
|
file.loaders |= ModPlatform::NeoForge;
|
||||||
else if (loader == "forge")
|
} else if (loader == "forge") {
|
||||||
file.loaders |= ModPlatform::Forge;
|
file.loaders |= ModPlatform::Forge;
|
||||||
else if (loader == "cauldron")
|
} else if (loader == "cauldron") {
|
||||||
file.loaders |= ModPlatform::Cauldron;
|
file.loaders |= ModPlatform::Cauldron;
|
||||||
else if (loader == "liteloader")
|
} else if (loader == "liteloader") {
|
||||||
file.loaders |= ModPlatform::LiteLoader;
|
file.loaders |= ModPlatform::LiteLoader;
|
||||||
else if (loader == "fabric")
|
} else if (loader == "fabric") {
|
||||||
file.loaders |= ModPlatform::Fabric;
|
file.loaders |= ModPlatform::Fabric;
|
||||||
else if (loader == "quilt")
|
} else if (loader == "quilt") {
|
||||||
file.loaders |= ModPlatform::Quilt;
|
file.loaders |= ModPlatform::Quilt;
|
||||||
else if (loader == "server" || loader == "client") {
|
} else if (loader == "server" || loader == "client") {
|
||||||
if (file.side == ModPlatform::Side::NoSide)
|
if (!file.side.isValid()) {
|
||||||
file.side = ModPlatform::SideUtils::fromString(loader);
|
file.side = ModPlatform::SideType::fromString(loader);
|
||||||
else if (file.side != ModPlatform::SideUtils::fromString(loader))
|
} else if (file.side != ModPlatform::SideType::fromString(loader)) {
|
||||||
file.side = ModPlatform::Side::UniversalSide;
|
file.side = ModPlatform::SideType::UniversalSide;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -203,8 +210,9 @@ auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool load_changelog) ->
|
||||||
file.dependencies.append(dependency);
|
file.dependencies.append(dependency);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (load_changelog)
|
if (load_changelog) {
|
||||||
file.changelog = api.getModFileChangelog(file.addonId.toInt(), file.fileId.toInt());
|
file.changelog = FlameAPI().getModFileChangelog(file.addonId.toInt(), file.fileId.toInt());
|
||||||
|
}
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,11 @@
|
||||||
|
|
||||||
#include "modplatform/ModIndex.h"
|
#include "modplatform/ModIndex.h"
|
||||||
|
|
||||||
#include "BaseInstance.h"
|
|
||||||
|
|
||||||
namespace FlameMod {
|
namespace FlameMod {
|
||||||
|
|
||||||
void loadIndexedPack(ModPlatform::IndexedPack& m, QJsonObject& obj);
|
void loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj);
|
||||||
void loadURLs(ModPlatform::IndexedPack& m, QJsonObject& obj);
|
void loadURLs(ModPlatform::IndexedPack& pack, QJsonObject& obj);
|
||||||
void loadBody(ModPlatform::IndexedPack& m);
|
void loadBody(ModPlatform::IndexedPack& pack);
|
||||||
void loadIndexedPackVersions(ModPlatform::IndexedPack& pack, QJsonArray& arr);
|
void loadIndexedPackVersions(ModPlatform::IndexedPack& pack, QJsonArray& arr);
|
||||||
ModPlatform::IndexedVersion loadIndexedPackVersion(QJsonObject& obj, bool load_changelog = false);
|
ModPlatform::IndexedVersion loadIndexedPackVersion(QJsonObject& obj, bool load_changelog = false);
|
||||||
} // namespace FlameMod
|
} // namespace FlameMod
|
||||||
|
|
|
||||||
|
|
@ -70,16 +70,16 @@ class ModrinthAPI : public ResourceAPI {
|
||||||
return l.join(',');
|
return l.join(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString getSideFilters(ModPlatform::Side side)
|
static QString getSideFilters(ModPlatform::SideType side)
|
||||||
{
|
{
|
||||||
switch (side) {
|
switch (side.value()) {
|
||||||
case ModPlatform::Side::ClientSide:
|
case ModPlatform::SideType::ClientSide:
|
||||||
return { R"("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:
|
case ModPlatform::SideTypeValue::ServerSide:
|
||||||
return { R"("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:
|
case ModPlatform::SideTypeValue::UniversalSide:
|
||||||
return { R"("client_side:required"],["server_side:required")" };
|
return { R"("client_side:required"],["server_side:required")" };
|
||||||
case ModPlatform::Side::NoSide:
|
case ModPlatform::SideTypeValue::NoSide:
|
||||||
// fallthrough
|
// fallthrough
|
||||||
default:
|
default:
|
||||||
return {};
|
return {};
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,12 @@
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QtConcurrentRun>
|
#include <QtConcurrentRun>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <utility>
|
||||||
#include "Json.h"
|
#include "Json.h"
|
||||||
#include "MMCZip.h"
|
#include "MMCZip.h"
|
||||||
#include "archive/ExportToZipTask.h"
|
#include "archive/ExportToZipTask.h"
|
||||||
#include "minecraft/PackProfile.h"
|
#include "minecraft/PackProfile.h"
|
||||||
#include "minecraft/mod/MetadataHandler.h"
|
|
||||||
#include "minecraft/mod/ModFolderModel.h"
|
#include "minecraft/mod/ModFolderModel.h"
|
||||||
#include "modplatform/ModIndex.h"
|
#include "modplatform/ModIndex.h"
|
||||||
#include "modplatform/helpers/HashUtils.h"
|
#include "modplatform/helpers/HashUtils.h"
|
||||||
|
|
@ -51,7 +52,7 @@ ModrinthPackExportTask::ModrinthPackExportTask(const QString& name,
|
||||||
, mcInstance(dynamic_cast<MinecraftInstance*>(instance))
|
, mcInstance(dynamic_cast<MinecraftInstance*>(instance))
|
||||||
, gameRoot(instance->gameRoot())
|
, gameRoot(instance->gameRoot())
|
||||||
, output(output)
|
, output(output)
|
||||||
, filter(filter)
|
, filter(std::move(filter))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void ModrinthPackExportTask::executeTask()
|
void ModrinthPackExportTask::executeTask()
|
||||||
|
|
@ -87,8 +88,9 @@ void ModrinthPackExportTask::collectFiles()
|
||||||
if (mcInstance) {
|
if (mcInstance) {
|
||||||
mcInstance->loaderModList()->update();
|
mcInstance->loaderModList()->update();
|
||||||
connect(mcInstance->loaderModList(), &ModFolderModel::updateFinished, this, &ModrinthPackExportTask::collectHashes);
|
connect(mcInstance->loaderModList(), &ModFolderModel::updateFinished, this, &ModrinthPackExportTask::collectHashes);
|
||||||
} else
|
} else {
|
||||||
collectHashes();
|
collectHashes();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModrinthPackExportTask::collectHashes()
|
void ModrinthPackExportTask::collectHashes()
|
||||||
|
|
@ -99,12 +101,14 @@ void ModrinthPackExportTask::collectHashes()
|
||||||
|
|
||||||
const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath());
|
const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath());
|
||||||
// require sensible file types
|
// require sensible file types
|
||||||
if (!std::any_of(PREFIXES.begin(), PREFIXES.end(), [&relative](const QString& prefix) { return relative.startsWith(prefix); }))
|
if (!std::ranges::any_of(PREFIXES, [&relative](const QString& prefix) { return relative.startsWith(prefix); })) {
|
||||||
continue;
|
continue;
|
||||||
if (!std::any_of(FILE_EXTENSIONS.begin(), FILE_EXTENSIONS.end(), [&relative](const QString& extension) {
|
}
|
||||||
|
if (!std::ranges::any_of(FILE_EXTENSIONS, [&relative](const QString& extension) {
|
||||||
return relative.endsWith('.' + extension) || relative.endsWith('.' + extension + ".disabled");
|
return relative.endsWith('.' + extension) || relative.endsWith('.' + extension + ".disabled");
|
||||||
}))
|
})) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
QFile openFile(file.absoluteFilePath());
|
QFile openFile(file.absoluteFilePath());
|
||||||
if (!openFile.open(QFile::ReadOnly)) {
|
if (!openFile.open(QFile::ReadOnly)) {
|
||||||
|
|
@ -151,9 +155,9 @@ void ModrinthPackExportTask::collectHashes()
|
||||||
|
|
||||||
void ModrinthPackExportTask::makeApiRequest()
|
void ModrinthPackExportTask::makeApiRequest()
|
||||||
{
|
{
|
||||||
if (pendingHashes.isEmpty())
|
if (pendingHashes.isEmpty()) {
|
||||||
buildZip();
|
buildZip();
|
||||||
else {
|
} else {
|
||||||
setStatus(tr("Finding versions for hashes..."));
|
setStatus(tr("Finding versions for hashes..."));
|
||||||
auto [versionsTask, response] = api.currentVersions(pendingHashes.values(), "sha512");
|
auto [versionsTask, response] = api.currentVersions(pendingHashes.values(), "sha512");
|
||||||
task = versionsTask;
|
task = versionsTask;
|
||||||
|
|
@ -176,17 +180,19 @@ void ModrinthPackExportTask::parseApiResponse(QByteArray* response)
|
||||||
iterator.next();
|
iterator.next();
|
||||||
|
|
||||||
const QJsonObject obj = doc[iterator.value()].toObject();
|
const QJsonObject obj = doc[iterator.value()].toObject();
|
||||||
if (obj.isEmpty())
|
if (obj.isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const QJsonArray files_array = obj["files"].toArray();
|
const QJsonArray files_array = obj["files"].toArray();
|
||||||
if (auto fileIter = std::find_if(files_array.begin(), files_array.end(),
|
if (auto fileIter = std::find_if(files_array.begin(), files_array.end(),
|
||||||
[&iterator](const QJsonValue& file) { return file["hashes"]["sha512"] == iterator.value(); });
|
[&iterator](const QJsonValue& file) { return file["hashes"]["sha512"] == iterator.value(); });
|
||||||
fileIter != files_array.end()) {
|
fileIter != files_array.end()) {
|
||||||
// map the file to the url
|
// map the file to the url
|
||||||
resolvedFiles[iterator.key()] =
|
resolvedFiles[iterator.key()] = ResolvedFile{ .sha1 = fileIter->toObject()["hashes"].toObject()["sha1"].toString(),
|
||||||
ResolvedFile{ fileIter->toObject()["hashes"].toObject()["sha1"].toString(), iterator.value(),
|
.sha512 = iterator.value(),
|
||||||
fileIter->toObject()["url"].toString(), fileIter->toObject()["size"].toInt() };
|
.url = fileIter->toObject()["url"].toString(),
|
||||||
|
.size = fileIter->toObject()["size"].toInt() };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (const Json::JsonException& e) {
|
} catch (const Json::JsonException& e) {
|
||||||
|
|
@ -217,7 +223,7 @@ void ModrinthPackExportTask::buildZip()
|
||||||
connect(zipTask.get(), &Task::failed, this, [this, progressStep](QString reason) {
|
connect(zipTask.get(), &Task::failed, this, [this, progressStep](QString reason) {
|
||||||
progressStep->state = TaskStepState::Failed;
|
progressStep->state = TaskStepState::Failed;
|
||||||
stepProgress(*progressStep);
|
stepProgress(*progressStep);
|
||||||
emitFailed(reason);
|
emitFailed(std::move(reason));
|
||||||
});
|
});
|
||||||
connect(zipTask.get(), &Task::stepProgress, this, &ModrinthPackExportTask::propagateStepProgress);
|
connect(zipTask.get(), &Task::stepProgress, this, &ModrinthPackExportTask::propagateStepProgress);
|
||||||
|
|
||||||
|
|
@ -226,7 +232,7 @@ void ModrinthPackExportTask::buildZip()
|
||||||
stepProgress(*progressStep);
|
stepProgress(*progressStep);
|
||||||
});
|
});
|
||||||
connect(zipTask.get(), &Task::status, this, [this, progressStep](QString status) {
|
connect(zipTask.get(), &Task::status, this, [this, progressStep](QString status) {
|
||||||
progressStep->status = status;
|
progressStep->status = std::move(status);
|
||||||
stepProgress(*progressStep);
|
stepProgress(*progressStep);
|
||||||
});
|
});
|
||||||
task.reset(zipTask);
|
task.reset(zipTask);
|
||||||
|
|
@ -240,11 +246,12 @@ QByteArray ModrinthPackExportTask::generateIndex()
|
||||||
out["game"] = "minecraft";
|
out["game"] = "minecraft";
|
||||||
out["name"] = name;
|
out["name"] = name;
|
||||||
out["versionId"] = version;
|
out["versionId"] = version;
|
||||||
if (!summary.isEmpty())
|
if (!summary.isEmpty()) {
|
||||||
out["summary"] = summary;
|
out["summary"] = summary;
|
||||||
|
}
|
||||||
|
|
||||||
if (mcInstance) {
|
if (mcInstance) {
|
||||||
auto profile = mcInstance->getPackProfile();
|
auto* profile = mcInstance->getPackProfile();
|
||||||
// collect all supported components
|
// collect all supported components
|
||||||
const ComponentPtr minecraft = profile->getComponent("net.minecraft");
|
const ComponentPtr minecraft = profile->getComponent("net.minecraft");
|
||||||
const ComponentPtr quilt = profile->getComponent("org.quiltmc.quilt-loader");
|
const ComponentPtr quilt = profile->getComponent("org.quiltmc.quilt-loader");
|
||||||
|
|
@ -254,16 +261,21 @@ QByteArray ModrinthPackExportTask::generateIndex()
|
||||||
|
|
||||||
// convert all available components to mrpack dependencies
|
// convert all available components to mrpack dependencies
|
||||||
QJsonObject dependencies;
|
QJsonObject dependencies;
|
||||||
if (minecraft != nullptr)
|
if (minecraft != nullptr) {
|
||||||
dependencies["minecraft"] = minecraft->m_version;
|
dependencies["minecraft"] = minecraft->m_version;
|
||||||
if (quilt != nullptr)
|
}
|
||||||
|
if (quilt != nullptr) {
|
||||||
dependencies["quilt-loader"] = quilt->m_version;
|
dependencies["quilt-loader"] = quilt->m_version;
|
||||||
if (fabric != nullptr)
|
}
|
||||||
|
if (fabric != nullptr) {
|
||||||
dependencies["fabric-loader"] = fabric->m_version;
|
dependencies["fabric-loader"] = fabric->m_version;
|
||||||
if (forge != nullptr)
|
}
|
||||||
|
if (forge != nullptr) {
|
||||||
dependencies["forge"] = forge->m_version;
|
dependencies["forge"] = forge->m_version;
|
||||||
if (neoForge != nullptr)
|
}
|
||||||
|
if (neoForge != nullptr) {
|
||||||
dependencies["neoforge"] = neoForge->m_version;
|
dependencies["neoforge"] = neoForge->m_version;
|
||||||
|
}
|
||||||
|
|
||||||
out["dependencies"] = dependencies;
|
out["dependencies"] = dependencies;
|
||||||
}
|
}
|
||||||
|
|
@ -291,8 +303,9 @@ QByteArray ModrinthPackExportTask::generateIndex()
|
||||||
|
|
||||||
// a server side mod does not imply that the mod does not work on the client
|
// a server side mod does not imply that the mod does not work on the client
|
||||||
// however, if a mrpack mod is marked as server-only it will not install on the client
|
// however, if a mrpack mod is marked as server-only it will not install on the client
|
||||||
if (iterator->side == ModPlatform::Side::ClientSide)
|
if (iterator->side == ModPlatform::SideType::ClientSide) {
|
||||||
env["server"] = "unsupported";
|
env["server"] = "unsupported";
|
||||||
|
}
|
||||||
|
|
||||||
fileOut["env"] = env;
|
fileOut["env"] = env;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ class ModrinthPackExportTask : public Task {
|
||||||
struct ResolvedFile {
|
struct ResolvedFile {
|
||||||
QString sha1, sha512, url;
|
QString sha1, sha512, url;
|
||||||
qint64 size;
|
qint64 size;
|
||||||
ModPlatform::Side side;
|
ModPlatform::SideType side;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const QStringList PREFIXES;
|
static const QStringList PREFIXES;
|
||||||
|
|
|
||||||
|
|
@ -65,11 +65,11 @@ void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj)
|
||||||
auto server = shouldDownloadOnSide(obj["server_side"].toString());
|
auto server = shouldDownloadOnSide(obj["server_side"].toString());
|
||||||
|
|
||||||
if (server && client) {
|
if (server && client) {
|
||||||
pack.side = ModPlatform::Side::UniversalSide;
|
pack.side = ModPlatform::SideType::UniversalSide;
|
||||||
} else if (server) {
|
} else if (server) {
|
||||||
pack.side = ModPlatform::Side::ServerSide;
|
pack.side = ModPlatform::SideType::ServerSide;
|
||||||
} else if (client) {
|
} else if (client) {
|
||||||
pack.side = ModPlatform::Side::ClientSide;
|
pack.side = ModPlatform::SideType::ClientSide;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modrinth can have more data than what's provided by the basic search :)
|
// Modrinth can have more data than what's provided by the basic search :)
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,7 @@ auto V1::createModFormat([[maybe_unused]] const QDir& index_dir,
|
||||||
mod.provider = mod_pack.provider;
|
mod.provider = mod_pack.provider;
|
||||||
mod.file_id = mod_version.fileId;
|
mod.file_id = mod_version.fileId;
|
||||||
mod.project_id = mod_pack.addonId;
|
mod.project_id = mod_pack.addonId;
|
||||||
mod.side = mod_version.side == ModPlatform::Side::NoSide ? mod_pack.side : mod_version.side;
|
mod.side = !mod_version.side.isValid() ? mod_pack.side : mod_version.side;
|
||||||
mod.loaders = mod_version.loaders;
|
mod.loaders = mod_version.loaders;
|
||||||
mod.mcVersions = mod_version.mcVersion;
|
mod.mcVersions = mod_version.mcVersion;
|
||||||
mod.mcVersions.removeDuplicates();
|
mod.mcVersions.removeDuplicates();
|
||||||
|
|
@ -210,8 +210,7 @@ void V1::updateModIndex(const QDir& index_dir, Mod& mod)
|
||||||
|
|
||||||
toml::array deps;
|
toml::array deps;
|
||||||
for (auto dep : mod.dependencies) {
|
for (auto dep : mod.dependencies) {
|
||||||
auto tbl = toml::table{ { "addonId", dep.addonId.toString().toStdString() },
|
auto tbl = toml::table{ { "addonId", dep.addonId.toString().toStdString() }, { "type", dep.type.toString().toStdString() } };
|
||||||
{ "type", ModPlatform::DependencyTypeUtils::toString(dep.type).toStdString() } };
|
|
||||||
if (!dep.version.isEmpty()) {
|
if (!dep.version.isEmpty()) {
|
||||||
tbl.emplace("version", dep.version.toStdString());
|
tbl.emplace("version", dep.version.toStdString());
|
||||||
}
|
}
|
||||||
|
|
@ -223,7 +222,7 @@ void V1::updateModIndex(const QDir& index_dir, Mod& mod)
|
||||||
{
|
{
|
||||||
auto tbl = toml::table{ { "name", mod.name.toStdString() },
|
auto tbl = toml::table{ { "name", mod.name.toStdString() },
|
||||||
{ "filename", mod.filename.toStdString() },
|
{ "filename", mod.filename.toStdString() },
|
||||||
{ "side", ModPlatform::SideUtils::toString(mod.side).toStdString() },
|
{ "side", mod.side.toString().toStdString() },
|
||||||
{ "x-prismlauncher-loaders", loaders },
|
{ "x-prismlauncher-loaders", loaders },
|
||||||
{ "x-prismlauncher-mc-versions", mcVersions },
|
{ "x-prismlauncher-mc-versions", mcVersions },
|
||||||
{ "x-prismlauncher-release-type", mod.releaseType.toString().toStdString() },
|
{ "x-prismlauncher-release-type", mod.releaseType.toString().toStdString() },
|
||||||
|
|
@ -300,7 +299,7 @@ auto V1::getIndexForMod(const QDir& index_dir, QString slug) -> Mod
|
||||||
{ // Basic info
|
{ // Basic info
|
||||||
mod.name = stringEntry(table, "name");
|
mod.name = stringEntry(table, "name");
|
||||||
mod.filename = stringEntry(table, "filename");
|
mod.filename = stringEntry(table, "filename");
|
||||||
mod.side = ModPlatform::SideUtils::fromString(stringEntry(table, "side"));
|
mod.side = ModPlatform::SideType::fromString(stringEntry(table, "side"));
|
||||||
mod.releaseType = ModPlatform::IndexedVersionType::fromString(table["x-prismlauncher-release-type"].value_or(""));
|
mod.releaseType = ModPlatform::IndexedVersionType::fromString(table["x-prismlauncher-release-type"].value_or(""));
|
||||||
if (auto loaders = table["x-prismlauncher-loaders"]; loaders && loaders.is_array()) {
|
if (auto loaders = table["x-prismlauncher-loaders"]; loaders && loaders.is_array()) {
|
||||||
for (auto&& loader : *loaders.as_array()) {
|
for (auto&& loader : *loaders.as_array()) {
|
||||||
|
|
@ -371,7 +370,7 @@ auto V1::getIndexForMod(const QDir& index_dir, QString slug) -> Mod
|
||||||
if (dep->contains("version")) {
|
if (dep->contains("version")) {
|
||||||
d.version = stringEntry(*dep, "version");
|
d.version = stringEntry(*dep, "version");
|
||||||
}
|
}
|
||||||
d.type = ModPlatform::DependencyTypeUtils::fromString(stringEntry(*dep, "type"));
|
d.type = ModPlatform::DependencyType::fromString(stringEntry(*dep, "type"));
|
||||||
mod.dependencies << d;
|
mod.dependencies << d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ class V1 {
|
||||||
QString slug{};
|
QString slug{};
|
||||||
QString name{};
|
QString name{};
|
||||||
QString filename{};
|
QString filename{};
|
||||||
ModPlatform::Side side{ ModPlatform::Side::UniversalSide };
|
ModPlatform::SideType side{ ModPlatform::SideType::UniversalSide };
|
||||||
ModPlatform::ModLoaderTypes loaders;
|
ModPlatform::ModLoaderTypes loaders;
|
||||||
QStringList mcVersions;
|
QStringList mcVersions;
|
||||||
ModPlatform::IndexedVersionType releaseType;
|
ModPlatform::IndexedVersionType releaseType;
|
||||||
|
|
|
||||||
|
|
@ -6,23 +6,30 @@
|
||||||
|
|
||||||
#include "minecraft/MinecraftInstance.h"
|
#include "minecraft/MinecraftInstance.h"
|
||||||
#include "minecraft/PackProfile.h"
|
#include "minecraft/PackProfile.h"
|
||||||
|
#include "minecraft/mod/Mod.h"
|
||||||
#include "minecraft/mod/ModFolderModel.h"
|
#include "minecraft/mod/ModFolderModel.h"
|
||||||
#include "modplatform/ModIndex.h"
|
#include "modplatform/ModIndex.h"
|
||||||
|
#include "modplatform/ResourceAPI.h"
|
||||||
|
#include "modplatform/ResourceType.h"
|
||||||
|
#include "ui/pages/modplatform/ResourceModel.h"
|
||||||
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QModelIndex>
|
||||||
|
#include <QString>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace ResourceDownload {
|
namespace ResourceDownload {
|
||||||
|
|
||||||
ModModel::ModModel(BaseInstance& base_inst, ResourceAPI* api, QString debugName, QString metaEntryBase)
|
ModModel::ModModel(BaseInstance& base_inst, ResourceAPI* api, 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 ********/
|
/******** Make data requests ********/
|
||||||
|
|
||||||
ResourceAPI::SearchArgs ModModel::createSearchArguments()
|
ResourceAPI::SearchArgs ModModel::createSearchArguments()
|
||||||
{
|
{
|
||||||
auto profile = static_cast<MinecraftInstance const&>(m_base_instance).getPackProfile();
|
auto* profile = static_cast<const MinecraftInstance&>(m_base_instance).getPackProfile();
|
||||||
|
|
||||||
Q_ASSERT(profile);
|
Q_ASSERT(profile);
|
||||||
Q_ASSERT(m_filter);
|
Q_ASSERT(m_filter);
|
||||||
|
|
@ -32,42 +39,53 @@ ResourceAPI::SearchArgs ModModel::createSearchArguments()
|
||||||
auto loaders = profile->getSupportedModLoaders();
|
auto loaders = profile->getSupportedModLoaders();
|
||||||
|
|
||||||
// Version filter
|
// Version filter
|
||||||
if (!m_filter->versions.empty())
|
if (!m_filter->versions.empty()) {
|
||||||
versions = m_filter->versions;
|
versions = m_filter->versions;
|
||||||
if (m_filter->loaders)
|
}
|
||||||
|
if (m_filter->loaders != 0U) {
|
||||||
loaders = m_filter->loaders;
|
loaders = m_filter->loaders;
|
||||||
if (!m_filter->categoryIds.empty())
|
}
|
||||||
|
if (!m_filter->categoryIds.empty()) {
|
||||||
categories = m_filter->categoryIds;
|
categories = m_filter->categoryIds;
|
||||||
|
}
|
||||||
auto side = m_filter->side;
|
auto side = m_filter->side;
|
||||||
|
|
||||||
auto sort = getCurrentSortingMethodByIndex();
|
auto sort = getCurrentSortingMethodByIndex();
|
||||||
|
|
||||||
return {
|
return { .type = ModPlatform::ResourceType::Mod,
|
||||||
ModPlatform::ResourceType::Mod, m_next_search_offset, m_search_term, sort, loaders, versions, side, categories, m_filter->openSource
|
.offset = m_next_search_offset,
|
||||||
};
|
.search = m_search_term,
|
||||||
|
.sorting = sort,
|
||||||
|
.loaders = loaders,
|
||||||
|
.versions = versions,
|
||||||
|
.side = side,
|
||||||
|
.categoryIds = categories,
|
||||||
|
.openSource = m_filter->openSource };
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceAPI::VersionSearchArgs ModModel::createVersionsArguments(const QModelIndex& entry)
|
ResourceAPI::VersionSearchArgs ModModel::createVersionsArguments(const QModelIndex& index)
|
||||||
{
|
{
|
||||||
auto pack = m_packs[entry.row()];
|
auto pack = m_packs[index.row()];
|
||||||
auto profile = static_cast<MinecraftInstance const&>(m_base_instance).getPackProfile();
|
auto* profile = static_cast<const MinecraftInstance&>(m_base_instance).getPackProfile();
|
||||||
|
|
||||||
Q_ASSERT(profile);
|
Q_ASSERT(profile);
|
||||||
Q_ASSERT(m_filter);
|
Q_ASSERT(m_filter);
|
||||||
|
|
||||||
std::optional<std::vector<Version>> versions{};
|
std::optional<std::vector<Version>> versions{};
|
||||||
auto loaders = profile->getSupportedModLoaders();
|
auto loaders = profile->getSupportedModLoaders();
|
||||||
if (!m_filter->versions.empty())
|
if (!m_filter->versions.empty()) {
|
||||||
versions = m_filter->versions;
|
versions = m_filter->versions;
|
||||||
if (m_filter->loaders)
|
}
|
||||||
|
if (m_filter->loaders != 0U) {
|
||||||
loaders = m_filter->loaders;
|
loaders = m_filter->loaders;
|
||||||
|
}
|
||||||
|
|
||||||
return { pack, versions, loaders, ModPlatform::ResourceType::Mod };
|
return { .pack = pack, .mcVersions = versions, .loaders = loaders, .resourceType = ModPlatform::ResourceType::Mod };
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceAPI::ProjectInfoArgs ModModel::createInfoArguments(const QModelIndex& entry)
|
ResourceAPI::ProjectInfoArgs ModModel::createInfoArguments(const QModelIndex& index)
|
||||||
{
|
{
|
||||||
auto pack = m_packs[entry.row()];
|
auto pack = m_packs[index.row()];
|
||||||
return { pack };
|
return { pack };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -86,9 +104,10 @@ void ModModel::searchWithTerm(const QString& term, unsigned int sort, bool filte
|
||||||
bool ModModel::isPackInstalled(ModPlatform::IndexedPack::Ptr pack) const
|
bool ModModel::isPackInstalled(ModPlatform::IndexedPack::Ptr pack) const
|
||||||
{
|
{
|
||||||
auto allMods = static_cast<MinecraftInstance&>(m_base_instance).loaderModList()->allMods();
|
auto allMods = static_cast<MinecraftInstance&>(m_base_instance).loaderModList()->allMods();
|
||||||
return std::any_of(allMods.cbegin(), allMods.cend(), [pack](Mod* mod) {
|
return std::ranges::any_of(allMods, [pack](Mod* mod) {
|
||||||
if (auto meta = mod->metadata(); meta)
|
if (auto meta = mod->metadata(); meta) {
|
||||||
return meta->provider == pack->provider && meta->project_id == pack->addonId;
|
return meta->provider == pack->provider && meta->project_id == pack->addonId;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -96,7 +115,7 @@ bool ModModel::isPackInstalled(ModPlatform::IndexedPack::Ptr pack) const
|
||||||
QVariant ModModel::getInstalledPackVersion(ModPlatform::IndexedPack::Ptr pack) const
|
QVariant ModModel::getInstalledPackVersion(ModPlatform::IndexedPack::Ptr pack) const
|
||||||
{
|
{
|
||||||
auto allMods = static_cast<MinecraftInstance&>(m_base_instance).loaderModList()->allMods();
|
auto allMods = static_cast<MinecraftInstance&>(m_base_instance).loaderModList()->allMods();
|
||||||
for (auto mod : allMods) {
|
for (auto* mod : allMods) {
|
||||||
if (auto meta = mod->metadata(); meta && meta->provider == pack->provider && meta->project_id == pack->addonId) {
|
if (auto meta = mod->metadata(); meta && meta->provider == pack->provider && meta->project_id == pack->addonId) {
|
||||||
return meta->version();
|
return meta->version();
|
||||||
}
|
}
|
||||||
|
|
@ -104,30 +123,36 @@ QVariant ModModel::getInstalledPackVersion(ModPlatform::IndexedPack::Ptr pack) c
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkSide(ModPlatform::Side filter, ModPlatform::Side value)
|
namespace {
|
||||||
|
|
||||||
|
bool checkSide(ModPlatform::SideType filter, ModPlatform::SideType value)
|
||||||
{
|
{
|
||||||
return (filter != ModPlatform::Side::ClientSide && filter != ModPlatform::Side::ServerSide) ||
|
return (filter != ModPlatform::SideType::ClientSide && filter != ModPlatform::SideType::ServerSide) ||
|
||||||
(value != ModPlatform::Side::ClientSide && value != ModPlatform::Side::ServerSide) || filter == value;
|
(value != ModPlatform::SideType::ClientSide && value != ModPlatform::SideType::ServerSide) || filter == value;
|
||||||
}
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
bool ModModel::checkFilters(ModPlatform::IndexedPack::Ptr pack)
|
bool ModModel::checkFilters(ModPlatform::IndexedPack::Ptr pack)
|
||||||
{
|
{
|
||||||
if (!m_filter)
|
if (!m_filter) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
return !(m_filter->hideInstalled && isPackInstalled(pack)) && checkSide(m_filter->side, pack->side);
|
return !(m_filter->hideInstalled && isPackInstalled(pack)) && checkSide(m_filter->side, pack->side);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModModel::checkVersionFilters(const ModPlatform::IndexedVersion& v)
|
bool ModModel::checkVersionFilters(const ModPlatform::IndexedVersion& v)
|
||||||
{
|
{
|
||||||
if (!m_filter)
|
if (!m_filter) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
auto loaders = static_cast<MinecraftInstance&>(m_base_instance).getPackProfile()->getSupportedModLoaders();
|
auto loaders = static_cast<MinecraftInstance&>(m_base_instance).getPackProfile()->getSupportedModLoaders();
|
||||||
if (m_filter->loaders)
|
if (m_filter->loaders != 0U) {
|
||||||
loaders = m_filter->loaders;
|
loaders = m_filter->loaders;
|
||||||
return (!optedOut(v) && // is opted out(aka curseforge download link)
|
}
|
||||||
(!loaders.has_value() || !v.loaders || loaders.value() & v.loaders) && // loaders
|
return (!optedOut(v) && // is opted out(aka curseforge download link)
|
||||||
checkSide(m_filter->side, v.side) && // side
|
(!loaders.has_value() || !v.loaders || ((loaders.value() & v.loaders) != 0U)) && // loaders
|
||||||
(m_filter->releases.empty() || // releases
|
checkSide(m_filter->side, v.side) && // side
|
||||||
|
(m_filter->releases.empty() || // releases
|
||||||
std::find(m_filter->releases.cbegin(), m_filter->releases.cend(), v.version_type) != m_filter->releases.cend()) &&
|
std::find(m_filter->releases.cbegin(), m_filter->releases.cend(), v.version_type) != m_filter->releases.cend()) &&
|
||||||
m_filter->checkMcVersions(v.mcVersion)); // mcVersions
|
m_filter->checkMcVersions(v.mcVersion)); // mcVersions
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QAbstractListModel>
|
#include <QAbstractListModel>
|
||||||
|
#include <QString>
|
||||||
|
#include <QVariant>
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include "BaseInstance.h"
|
#include "BaseInstance.h"
|
||||||
|
|
||||||
|
|
@ -24,27 +28,27 @@ class ModModel : public ResourceModel {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ModModel(BaseInstance&, ResourceAPI* api, QString debugName, QString metaEntryBase);
|
ModModel(BaseInstance&, ResourceAPI* api, const QString& debugName, QString metaEntryBase);
|
||||||
|
|
||||||
/* Ask the API for more information */
|
/* Ask the API for more information */
|
||||||
void searchWithTerm(const QString& term, unsigned int sort, bool filter_changed);
|
void searchWithTerm(const QString& term, unsigned int sort, bool filter_changed);
|
||||||
|
|
||||||
void setFilter(std::shared_ptr<ModFilterWidget::Filter> filter) { m_filter = filter; }
|
void setFilter(std::shared_ptr<ModFilterWidget::Filter> filter) { m_filter = std::move(filter); }
|
||||||
virtual QVariant getInstalledPackVersion(ModPlatform::IndexedPack::Ptr) const override;
|
QVariant getInstalledPackVersion(ModPlatform::IndexedPack::Ptr pack) const override;
|
||||||
|
|
||||||
[[nodiscard]] QString debugName() const override { return m_debugName; }
|
[[nodiscard]] QString debugName() const override { return m_debugName; }
|
||||||
[[nodiscard]] QString metaEntryBase() const override { return m_metaEntryBase; }
|
[[nodiscard]] QString metaEntryBase() const override { return m_metaEntryBase; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
ResourceAPI::SearchArgs createSearchArguments() override;
|
ResourceAPI::SearchArgs createSearchArguments() override;
|
||||||
ResourceAPI::VersionSearchArgs createVersionsArguments(const QModelIndex&) override;
|
ResourceAPI::VersionSearchArgs createVersionsArguments(const QModelIndex& index) override;
|
||||||
ResourceAPI::ProjectInfoArgs createInfoArguments(const QModelIndex&) override;
|
ResourceAPI::ProjectInfoArgs createInfoArguments(const QModelIndex& index) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool isPackInstalled(ModPlatform::IndexedPack::Ptr) const override;
|
bool isPackInstalled(ModPlatform::IndexedPack::Ptr pack) const override;
|
||||||
|
|
||||||
virtual bool checkFilters(ModPlatform::IndexedPack::Ptr) override;
|
bool checkFilters(ModPlatform::IndexedPack::Ptr pack) override;
|
||||||
virtual bool checkVersionFilters(const ModPlatform::IndexedVersion&) override;
|
bool checkVersionFilters(const ModPlatform::IndexedVersion& version) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BaseInstance& m_base_instance;
|
BaseInstance& m_base_instance;
|
||||||
|
|
|
||||||
|
|
@ -206,7 +206,7 @@ void ListModel::performPaginatedSearch()
|
||||||
};
|
};
|
||||||
|
|
||||||
auto netJob = api.searchProjects({ ModPlatform::ResourceType::Modpack, m_nextSearchOffset, m_currentSearchTerm, sort, m_filter->loaders,
|
auto netJob = api.searchProjects({ ModPlatform::ResourceType::Modpack, m_nextSearchOffset, m_currentSearchTerm, sort, m_filter->loaders,
|
||||||
m_filter->versions, ModPlatform::Side::NoSide, m_filter->categoryIds, m_filter->openSource },
|
m_filter->versions, ModPlatform::SideType::NoSide, m_filter->categoryIds, m_filter->openSource },
|
||||||
std::move(callbacks));
|
std::move(callbacks));
|
||||||
|
|
||||||
m_jobPtr = netJob;
|
m_jobPtr = netJob;
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,7 @@ void ModpackListModel::performPaginatedSearch()
|
||||||
};
|
};
|
||||||
|
|
||||||
auto netJob = api.searchProjects({ ModPlatform::ResourceType::Modpack, m_nextSearchOffset, m_currentSearchTerm, sort, m_filter->loaders,
|
auto netJob = api.searchProjects({ ModPlatform::ResourceType::Modpack, m_nextSearchOffset, m_currentSearchTerm, sort, m_filter->loaders,
|
||||||
m_filter->versions, ModPlatform::Side::NoSide, m_filter->categoryIds, m_filter->openSource },
|
m_filter->versions, ModPlatform::SideType::NoSide, m_filter->categoryIds, m_filter->openSource },
|
||||||
std::move(callbacks));
|
std::move(callbacks));
|
||||||
|
|
||||||
m_jobPtr = netJob;
|
m_jobPtr = netJob;
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,7 @@ void ModFilterWidget::prepareBasicFilter()
|
||||||
m_filter->openSource = false;
|
m_filter->openSource = false;
|
||||||
if (m_instance) {
|
if (m_instance) {
|
||||||
m_filter->hideInstalled = false;
|
m_filter->hideInstalled = false;
|
||||||
m_filter->side = ModPlatform::Side::NoSide; // or "both"
|
m_filter->side = ModPlatform::SideType::NoSide; // or "both"
|
||||||
ModPlatform::ModLoaderTypes loaders;
|
ModPlatform::ModLoaderTypes loaders;
|
||||||
if (m_instance->settings()->get("OverrideModDownloadLoaders").toBool()) {
|
if (m_instance->settings()->get("OverrideModDownloadLoaders").toBool()) {
|
||||||
for (auto loader : Json::toStringList(m_instance->settings()->get("ModDownloadLoaders").toString())) {
|
for (auto loader : Json::toStringList(m_instance->settings()->get("ModDownloadLoaders").toString())) {
|
||||||
|
|
@ -311,16 +311,16 @@ void ModFilterWidget::onLoadersFilterChanged()
|
||||||
|
|
||||||
void ModFilterWidget::onSideFilterChanged()
|
void ModFilterWidget::onSideFilterChanged()
|
||||||
{
|
{
|
||||||
ModPlatform::Side side;
|
ModPlatform::SideType side;
|
||||||
|
|
||||||
if (ui->clientSide->isChecked() && !ui->serverSide->isChecked()) {
|
if (ui->clientSide->isChecked() && !ui->serverSide->isChecked()) {
|
||||||
side = ModPlatform::Side::ClientSide;
|
side = ModPlatform::SideType::ClientSide;
|
||||||
} else if (!ui->clientSide->isChecked() && ui->serverSide->isChecked()) {
|
} else if (!ui->clientSide->isChecked() && ui->serverSide->isChecked()) {
|
||||||
side = ModPlatform::Side::ServerSide;
|
side = ModPlatform::SideType::ServerSide;
|
||||||
} else if (ui->clientSide->isChecked() && ui->serverSide->isChecked()) {
|
} else if (ui->clientSide->isChecked() && ui->serverSide->isChecked()) {
|
||||||
side = ModPlatform::Side::UniversalSide;
|
side = ModPlatform::SideType::UniversalSide;
|
||||||
} else {
|
} else {
|
||||||
side = ModPlatform::Side::NoSide;
|
side = ModPlatform::SideType::NoSide;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_filter_changed = side != m_filter->side;
|
m_filter_changed = side != m_filter->side;
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ class ModFilterWidget : public QTabWidget {
|
||||||
std::vector<Version> versions;
|
std::vector<Version> versions;
|
||||||
std::vector<ModPlatform::IndexedVersionType> releases;
|
std::vector<ModPlatform::IndexedVersionType> releases;
|
||||||
ModPlatform::ModLoaderTypes loaders;
|
ModPlatform::ModLoaderTypes loaders;
|
||||||
ModPlatform::Side side;
|
ModPlatform::SideType side;
|
||||||
bool hideInstalled;
|
bool hideInstalled;
|
||||||
QStringList categoryIds;
|
QStringList categoryIds;
|
||||||
bool openSource;
|
bool openSource;
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ class PackwizTest : public QObject {
|
||||||
|
|
||||||
QCOMPARE(metadata.name, "Borderless Mining");
|
QCOMPARE(metadata.name, "Borderless Mining");
|
||||||
QCOMPARE(metadata.filename, "borderless-mining-1.1.1+1.18.jar");
|
QCOMPARE(metadata.filename, "borderless-mining-1.1.1+1.18.jar");
|
||||||
QCOMPARE(metadata.side, ModPlatform::Side::ClientSide);
|
QCOMPARE(metadata.side, ModPlatform::SideType::ClientSide);
|
||||||
|
|
||||||
QCOMPARE(metadata.url, QUrl("https://cdn.modrinth.com/data/kYq5qkSL/versions/1.1.1+1.18/borderless-mining-1.1.1+1.18.jar"));
|
QCOMPARE(metadata.url, QUrl("https://cdn.modrinth.com/data/kYq5qkSL/versions/1.1.1+1.18/borderless-mining-1.1.1+1.18.jar"));
|
||||||
QCOMPARE(metadata.hash_format, "sha512");
|
QCOMPARE(metadata.hash_format, "sha512");
|
||||||
|
|
@ -73,7 +73,7 @@ class PackwizTest : public QObject {
|
||||||
|
|
||||||
QCOMPARE(metadata.name, "Screenshot to Clipboard (Fabric)");
|
QCOMPARE(metadata.name, "Screenshot to Clipboard (Fabric)");
|
||||||
QCOMPARE(metadata.filename, "screenshot-to-clipboard-1.0.7-fabric.jar");
|
QCOMPARE(metadata.filename, "screenshot-to-clipboard-1.0.7-fabric.jar");
|
||||||
QCOMPARE(metadata.side, ModPlatform::Side::UniversalSide);
|
QCOMPARE(metadata.side, ModPlatform::SideType::UniversalSide);
|
||||||
|
|
||||||
QCOMPARE(metadata.url, QUrl("https://edge.forgecdn.net/files/3509/43/screenshot-to-clipboard-1.0.7-fabric.jar"));
|
QCOMPARE(metadata.url, QUrl("https://edge.forgecdn.net/files/3509/43/screenshot-to-clipboard-1.0.7-fabric.jar"));
|
||||||
QCOMPARE(metadata.hash_format, "murmur2");
|
QCOMPARE(metadata.hash_format, "murmur2");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue