added side for modrinth mods

Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
Trial97 2023-09-10 16:22:57 +03:00
parent a2d44744fe
commit 47d1f23568
No known key found for this signature in database
GPG Key ID: 55EF5DA53DB36318
8 changed files with 73 additions and 12 deletions

View File

@ -31,6 +31,7 @@ class Mod;
class Metadata { class Metadata {
public: public:
using ModStruct = Packwiz::V1::Mod; using ModStruct = Packwiz::V1::Mod;
using ModSide = Packwiz::V1::Side;
static auto create(QDir& index_dir, ModPlatform::IndexedPack& mod_pack, ModPlatform::IndexedVersion& mod_version) -> ModStruct static auto create(QDir& index_dir, ModPlatform::IndexedPack& mod_pack, ModPlatform::IndexedVersion& mod_version) -> ModStruct
{ {

View File

@ -104,6 +104,7 @@ struct IndexedPack {
QString logoName; QString logoName;
QString logoUrl; QString logoUrl;
QString websiteUrl; QString websiteUrl;
QString side;
bool versionsLoaded = false; bool versionsLoaded = false;
QVector<IndexedVersion> versions; QVector<IndexedVersion> versions;
@ -128,7 +129,6 @@ struct IndexedPack {
return std::any_of(versions.constBegin(), versions.constEnd(), [](auto const& v) { return v.is_currently_selected; }); return std::any_of(versions.constBegin(), versions.constEnd(), [](auto const& v) { return v.is_currently_selected; });
} }
}; };
QString getMetaURL(ResourceProvider provider, QVariant projectID);
struct OverrideDep { struct OverrideDep {
QString quilt; QString quilt;

View File

@ -25,6 +25,7 @@
#include "Json.h" #include "Json.h"
#include "MMCZip.h" #include "MMCZip.h"
#include "minecraft/PackProfile.h" #include "minecraft/PackProfile.h"
#include "minecraft/mod/MetadataHandler.h"
#include "minecraft/mod/ModFolderModel.h" #include "minecraft/mod/ModFolderModel.h"
const QStringList ModrinthPackExportTask::PREFIXES({ "mods/", "coremods/", "resourcepacks/", "texturepacks/", "shaderpacks/" }); const QStringList ModrinthPackExportTask::PREFIXES({ "mods/", "coremods/", "resourcepacks/", "texturepacks/", "shaderpacks/" });
@ -127,7 +128,8 @@ void ModrinthPackExportTask::collectHashes()
QCryptographicHash sha1(QCryptographicHash::Algorithm::Sha1); QCryptographicHash sha1(QCryptographicHash::Algorithm::Sha1);
sha1.addData(data); sha1.addData(data);
ResolvedFile resolvedFile{ sha1.result().toHex(), sha512.result().toHex(), url.toEncoded(), openFile.size() }; ResolvedFile resolvedFile{ sha1.result().toHex(), sha512.result().toHex(), url.toEncoded(), openFile.size(),
mod->metadata()->side };
resolvedFiles[relative] = resolvedFile; resolvedFiles[relative] = resolvedFile;
// nice! we've managed to resolve based on local metadata! // nice! we've managed to resolve based on local metadata!
@ -272,18 +274,31 @@ QByteArray ModrinthPackExportTask::generateIndex()
// detect disabled mod // detect disabled mod
const QFileInfo pathInfo(path); const QFileInfo pathInfo(path);
QJsonObject env;
if (pathInfo.suffix() == "disabled") { if (pathInfo.suffix() == "disabled") {
// rename it // rename it
path = pathInfo.dir().filePath(pathInfo.completeBaseName()); path = pathInfo.dir().filePath(pathInfo.completeBaseName());
// ...and make it optional
QJsonObject env;
env["client"] = "optional"; env["client"] = "optional";
env["server"] = "optional"; env["server"] = "optional";
fileOut["env"] = env; } else {
env["client"] = "required";
env["server"] = "required";
} }
switch (iterator->side) {
case Metadata::ModSide::ClientSide:
env["server"] = "unsupported";
break;
case Metadata::ModSide::ServerSide:
env["client"] = "unsupported";
break;
case Metadata::ModSide::UniversalSide:
break;
}
fileOut["env"] = env;
fileOut["path"] = path; fileOut["path"] = path;
fileOut["downloads"] = QJsonArray{ iterator.value().url }; fileOut["downloads"] = QJsonArray{ iterator->url };
QJsonObject hashes; QJsonObject hashes;
hashes["sha1"] = value.sha1; hashes["sha1"] = value.sha1;

View File

@ -43,6 +43,7 @@ class ModrinthPackExportTask : public Task {
struct ResolvedFile { struct ResolvedFile {
QString sha1, sha512, url; QString sha1, sha512, url;
qint64 size; qint64 size;
Metadata::ModSide side;
}; };
static const QStringList PREFIXES; static const QStringList PREFIXES;

View File

@ -27,6 +27,11 @@
static ModrinthAPI api; static ModrinthAPI api;
static ModPlatform::ProviderCapabilities ProviderCaps; static ModPlatform::ProviderCapabilities ProviderCaps;
bool shouldDownloadOnSide(QString side)
{
return side == "required" || side == "optional";
}
// https://docs.modrinth.com/api-spec/#tag/projects/operation/getProject // https://docs.modrinth.com/api-spec/#tag/projects/operation/getProject
void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj) void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj)
{ {
@ -53,6 +58,17 @@ void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj)
modAuthor.url = api.getAuthorURL(modAuthor.name); modAuthor.url = api.getAuthorURL(modAuthor.name);
pack.authors.append(modAuthor); pack.authors.append(modAuthor);
auto client = shouldDownloadOnSide(Json::ensureString(obj, "client_side"));
auto server = shouldDownloadOnSide(Json::ensureString(obj, "server_side"));
if (server && client) {
pack.side = "both";
} else if (server) {
pack.side = "server";
} else if (client) {
pack.side = "client";
}
// 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 :)
pack.extraDataLoaded = false; pack.extraDataLoaded = false;
} }

View File

@ -113,6 +113,7 @@ auto V1::createModFormat([[maybe_unused]] QDir& index_dir, ModPlatform::IndexedP
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 = stringToSide(mod_pack.side);
return mod; return mod;
} }
@ -190,7 +191,7 @@ void V1::updateModIndex(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", mod.side.toStdString() }, { "side", sideToString(mod.side).toStdString() },
{ "download", { "download",
toml::table{ toml::table{
{ "mode", mod.mode.toStdString() }, { "mode", mod.mode.toStdString() },
@ -274,7 +275,7 @@ auto V1::getIndexForMod(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 = stringEntry(table, "side"); mod.side = stringToSide(stringEntry(table, "side"));
} }
{ // [download] info { // [download] info
@ -329,4 +330,28 @@ auto V1::getIndexForMod(QDir& index_dir, QVariant& mod_id) -> Mod
return {}; 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 } // namespace Packwiz

View File

@ -35,12 +35,12 @@ auto getRealIndexName(QDir& index_dir, QString normalized_index_name, bool shoul
class V1 { class V1 {
public: public:
enum class Side { ClientSide = 1 << 0, ServerSide = 1 << 1, UniversalSide = ClientSide | ServerSide };
struct Mod { struct Mod {
QString slug{}; QString slug{};
QString name{}; QString name{};
QString filename{}; QString filename{};
// FIXME: make side an enum Side side{ Side::UniversalSide };
QString side{ "both" };
// [download] // [download]
QString mode{}; QString mode{};
@ -93,6 +93,9 @@ class V1 {
* If the mod doesn't have a metadata, it simply returns an empty Mod object. * If the mod doesn't have a metadata, it simply returns an empty Mod object.
* */ * */
static auto getIndexForMod(QDir& index_dir, QVariant& mod_id) -> Mod; static auto getIndexForMod(QDir& index_dir, QVariant& mod_id) -> Mod;
static auto sideToString(Side side) -> QString;
static auto stringToSide(QString side) -> Side;
}; };
} // namespace Packwiz } // namespace Packwiz

View File

@ -42,7 +42,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, "client"); QCOMPARE(metadata.side, Packwiz::V1::Side::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");
@ -72,7 +72,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, "both"); QCOMPARE(metadata.side, Packwiz::V1::Side::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");