propagate side as enum instead of Qstring (#3544)

This commit is contained in:
timoreo
2025-07-09 10:01:51 +02:00
committed by GitHub
18 changed files with 89 additions and 131 deletions

View File

@@ -152,4 +152,29 @@ auto getModLoaderFromString(QString type) -> ModLoaderType
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;
}
} // namespace ModPlatform

View File

@@ -47,6 +47,13 @@ enum class ResourceType { MOD, RESOURCE_PACK, SHADER_PACK, MODPACK, DATA_PACK };
enum class DependencyType { REQUIRED, OPTIONAL, INCOMPATIBLE, EMBEDDED, TOOL, INCLUDE, UNKNOWN };
enum class Side { NoSide = 0, ClientSide = 1 << 0, ServerSide = 1 << 1, UniversalSide = ClientSide | ServerSide };
namespace SideUtils {
QString toString(Side side);
Side fromString(QString side);
} // namespace SideUtils
namespace ProviderCapabilities {
const char* name(ResourceProvider);
QString readableName(ResourceProvider);
@@ -114,7 +121,7 @@ struct IndexedVersion {
bool is_preferred = true;
QString changelog;
QList<Dependency> dependencies;
QString side; // this is for flame API
Side side; // this is for flame API
// For internal use, not provided by APIs
bool is_currently_selected = false;
@@ -145,7 +152,7 @@ struct IndexedPack {
QString logoName;
QString logoUrl;
QString websiteUrl;
QString side;
Side side;
bool versionsLoaded = false;
QList<IndexedVersion> versions;

View File

@@ -74,7 +74,7 @@ class ResourceAPI {
std::optional<SortingMethod> sorting;
std::optional<ModPlatform::ModLoaderTypes> loaders;
std::optional<std::list<Version>> versions;
std::optional<QString> side;
std::optional<ModPlatform::Side> side;
std::optional<QStringList> categoryIds;
bool openSource;
};

View File

@@ -4,6 +4,7 @@
#include "Json.h"
#include "minecraft/MinecraftInstance.h"
#include "minecraft/PackProfile.h"
#include "modplatform/ModIndex.h"
#include "modplatform/flame/FlameAPI.h"
static FlameAPI api;
@@ -110,6 +111,7 @@ auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool load_changelog) ->
if (str.contains('.'))
file.mcVersion.append(str);
file.side = ModPlatform::Side::NoSide;
if (auto loader = str.toLower(); loader == "neoforge")
file.loaders |= ModPlatform::NeoForge;
else if (loader == "forge")
@@ -123,10 +125,10 @@ auto FlameMod::loadIndexedPackVersion(QJsonObject& obj, bool load_changelog) ->
else if (loader == "quilt")
file.loaders |= ModPlatform::Quilt;
else if (loader == "server" || loader == "client") {
if (file.side.isEmpty())
file.side = loader;
else if (file.side != loader)
file.side = "both";
if (file.side == ModPlatform::Side::NoSide)
file.side = ModPlatform::SideUtils::fromString(loader);
else if (file.side != ModPlatform::SideUtils::fromString(loader))
file.side = ModPlatform::Side::UniversalSide;
}
}

View File

@@ -69,18 +69,20 @@ class ModrinthAPI : public NetworkResourceAPI {
return l.join(',');
}
static auto getSideFilters(QString side) -> const QString
static QString getSideFilters(ModPlatform::Side side)
{
if (side.isEmpty()) {
return {};
switch (side) {
case ModPlatform::Side::ClientSide:
return QString("\"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\"");
case ModPlatform::Side::UniversalSide:
return QString("\"client_side:required\"],[\"server_side:required\"");
case ModPlatform::Side::NoSide:
// fallthrough
default:
return {};
}
if (side == "both")
return QString("\"client_side:required\"],[\"server_side:required\"");
if (side == "client")
return QString("\"client_side:required\",\"client_side:optional\"],[\"server_side:optional\",\"server_side:unsupported\"");
if (side == "server")
return QString("\"server_side:required\",\"server_side:optional\"],[\"client_side:optional\",\"client_side:unsupported\"");
return {};
}
[[nodiscard]] static inline QString mapMCVersionFromModrinth(QString v)

View File

@@ -28,6 +28,7 @@
#include "minecraft/PackProfile.h"
#include "minecraft/mod/MetadataHandler.h"
#include "minecraft/mod/ModFolderModel.h"
#include "modplatform/ModIndex.h"
#include "modplatform/helpers/HashUtils.h"
#include "tasks/Task.h"
@@ -289,7 +290,7 @@ QByteArray ModrinthPackExportTask::generateIndex()
// 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
if (iterator->side == Metadata::ModSide::ClientSide)
if (iterator->side == ModPlatform::Side::ClientSide)
env["server"] = "unsupported";
fileOut["env"] = env;

View File

@@ -23,6 +23,7 @@
#include "BaseInstance.h"
#include "MMCZip.h"
#include "minecraft/MinecraftInstance.h"
#include "modplatform/ModIndex.h"
#include "modplatform/modrinth/ModrinthAPI.h"
#include "tasks/Task.h"
@@ -45,7 +46,7 @@ class ModrinthPackExportTask : public Task {
struct ResolvedFile {
QString sha1, sha512, url;
qint64 size;
Metadata::ModSide side;
ModPlatform::Side side;
};
static const QStringList PREFIXES;

View File

@@ -63,11 +63,11 @@ void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj)
auto server = shouldDownloadOnSide(Json::ensureString(obj, "server_side"));
if (server && client) {
pack.side = "both";
pack.side = ModPlatform::Side::UniversalSide;
} else if (server) {
pack.side = "server";
pack.side = ModPlatform::Side::ServerSide;
} else if (client) {
pack.side = "client";
pack.side = ModPlatform::Side::ClientSide;
}
// Modrinth can have more data than what's provided by the basic search :)

View File

@@ -28,7 +28,6 @@
#include "FileSystem.h"
#include "StringUtils.h"
#include "minecraft/mod/Mod.h"
#include "modplatform/ModIndex.h"
#include <toml++/toml.h>
@@ -113,7 +112,7 @@ auto V1::createModFormat([[maybe_unused]] const QDir& index_dir,
mod.provider = mod_pack.provider;
mod.file_id = mod_version.fileId;
mod.project_id = mod_pack.addonId;
mod.side = stringToSide(mod_version.side.isEmpty() ? mod_pack.side : mod_version.side);
mod.side = mod_version.side == ModPlatform::Side::NoSide ? mod_pack.side : mod_version.side;
mod.loaders = mod_version.loaders;
mod.mcVersions = mod_version.mcVersion;
mod.mcVersions.sort();
@@ -126,18 +125,6 @@ auto V1::createModFormat([[maybe_unused]] const QDir& index_dir,
return mod;
}
auto V1::createModFormat(const QDir& index_dir, [[maybe_unused]] ::Mod& internal_mod, QString slug) -> Mod
{
// Try getting metadata if it exists
Mod mod{ getIndexForMod(index_dir, slug) };
if (mod.isValid())
return mod;
qWarning() << QString("Tried to create mod metadata with a Mod without metadata!");
return {};
}
void V1::updateModIndex(const QDir& index_dir, Mod& mod)
{
if (!mod.isValid()) {
@@ -208,7 +195,7 @@ void V1::updateModIndex(const QDir& index_dir, Mod& mod)
{
auto tbl = toml::table{ { "name", mod.name.toStdString() },
{ "filename", mod.filename.toStdString() },
{ "side", sideToString(mod.side).toStdString() },
{ "side", ModPlatform::SideUtils::toString(mod.side).toStdString() },
{ "x-prismlauncher-loaders", loaders },
{ "x-prismlauncher-mc-versions", mcVersions },
{ "x-prismlauncher-release-type", mod.releaseType.toString().toStdString() },
@@ -249,18 +236,6 @@ void V1::deleteModIndex(const QDir& index_dir, QString& mod_slug)
}
}
void V1::deleteModIndex(const QDir& index_dir, QVariant& mod_id)
{
for (auto& file_name : index_dir.entryList(QDir::Filter::Files)) {
auto mod = getIndexForMod(index_dir, file_name);
if (mod.mod_id() == mod_id) {
deleteModIndex(index_dir, mod.name);
break;
}
}
}
auto V1::getIndexForMod(const QDir& index_dir, QString slug) -> Mod
{
Mod mod;
@@ -296,7 +271,7 @@ auto V1::getIndexForMod(const QDir& index_dir, QString slug) -> Mod
{ // Basic info
mod.name = stringEntry(table, "name");
mod.filename = stringEntry(table, "filename");
mod.side = stringToSide(stringEntry(table, "side"));
mod.side = ModPlatform::SideUtils::fromString(stringEntry(table, "side"));
mod.releaseType = ModPlatform::IndexedVersionType(table["x-prismlauncher-release-type"].value_or(""));
if (auto loaders = table["x-prismlauncher-loaders"]; loaders && loaders.is_array()) {
for (auto&& loader : *loaders.as_array()) {
@@ -371,28 +346,4 @@ auto V1::getIndexForMod(const QDir& index_dir, QVariant& mod_id) -> Mod
return {};
}
auto V1::sideToString(Side side) -> QString
{
switch (side) {
case Side::ClientSide:
return "client";
case Side::ServerSide:
return "server";
case Side::UniversalSide:
return "both";
}
return {};
}
auto V1::stringToSide(QString side) -> Side
{
if (side == "client")
return Side::ClientSide;
if (side == "server")
return Side::ServerSide;
if (side == "both")
return Side::UniversalSide;
return Side::UniversalSide;
}
} // namespace Packwiz

View File

@@ -27,23 +27,18 @@
class QDir;
// Mod from launcher/minecraft/mod/Mod.h
class Mod;
namespace Packwiz {
auto getRealIndexName(const QDir& index_dir, QString normalized_index_name, bool should_match = false) -> QString;
class V1 {
public:
enum class Side { ClientSide = 1 << 0, ServerSide = 1 << 1, UniversalSide = ClientSide | ServerSide };
// can also represent other resources beside loader mods - but this is what packwiz calls it
struct Mod {
QString slug{};
QString name{};
QString filename{};
Side side{ Side::UniversalSide };
ModPlatform::Side side{ ModPlatform::Side::UniversalSide };
ModPlatform::ModLoaderTypes loaders;
QStringList mcVersions;
ModPlatform::IndexedVersionType releaseType;
@@ -74,10 +69,6 @@ class V1 {
* its common representation in the launcher, when downloading mods.
* */
static auto createModFormat(const QDir& index_dir, ModPlatform::IndexedPack& mod_pack, ModPlatform::IndexedVersion& mod_version) -> Mod;
/* Generates the object representing the information in a mod.pw.toml file via
* its common representation in the launcher, plus a necessary slug.
* */
static auto createModFormat(const QDir& index_dir, ::Mod& internal_mod, QString slug) -> Mod;
/* Updates the mod index for the provided mod.
* This creates a new index if one does not exist already
@@ -88,9 +79,6 @@ class V1 {
/* Deletes the metadata for the mod with the given slug. If the metadata doesn't exist, it does nothing. */
static void deleteModIndex(const QDir& index_dir, QString& mod_slug);
/* Deletes the metadata for the mod with the given id. If the metadata doesn't exist, it does nothing. */
static void deleteModIndex(const QDir& index_dir, QVariant& mod_id);
/* Gets the metadata for a mod with a particular file name.
* If the mod doesn't have a metadata, it simply returns an empty Mod object.
* */
@@ -100,9 +88,6 @@ class V1 {
* If the mod doesn't have a metadata, it simply returns an empty Mod object.
* */
static auto getIndexForMod(const QDir& index_dir, QVariant& mod_id) -> Mod;
static auto sideToString(Side side) -> QString;
static auto stringToSide(QString side) -> Side;
};
} // namespace Packwiz