From 4fda35b466e4e3f242955cf8cb692a10e8820f0b Mon Sep 17 00:00:00 2001 From: flow Date: Sat, 14 May 2022 20:17:05 -0300 Subject: feat: add modrinth pack downloading Things that don't work / work poorly (there's more for sure but those are the evident ones): - Icons are broken in the import dialog - No way to search for private packs - Icons are not downloaded when downloading a mod - No support for multiple download URLs - Probably a lot more... --- .../modplatform/modrinth/ModrinthPackManifest.cpp | 84 ++++++++++++++++++++++ 1 file changed, 84 insertions(+) (limited to 'launcher/modplatform/modrinth/ModrinthPackManifest.cpp') diff --git a/launcher/modplatform/modrinth/ModrinthPackManifest.cpp b/launcher/modplatform/modrinth/ModrinthPackManifest.cpp index 2100aaf9..4dcd2fd4 100644 --- a/launcher/modplatform/modrinth/ModrinthPackManifest.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackManifest.cpp @@ -14,3 +14,87 @@ */ #include "ModrinthPackManifest.h" +#include "Json.h" + +#include "minecraft/MinecraftInstance.h" +#include "minecraft/PackProfile.h" + +namespace Modrinth { + +void loadIndexedPack(Modpack& pack, QJsonObject& obj) +{ + pack.id = Json::ensureString(obj, "project_id"); + + pack.name = Json::ensureString(obj, "title"); + pack.description = Json::ensureString(obj, "description"); + pack.authors << Json::ensureString(obj, "author"); + pack.iconName = QString("modrinth_%1").arg(Json::ensureString(obj, "slug")); + pack.iconUrl = Json::ensureString(obj, "icon_url"); +} + +void loadIndexedInfo(Modpack& pack, QJsonObject& obj) +{ + pack.extra.body = Json::ensureString(obj, "body"); + pack.extra.sourceUrl = Json::ensureString(obj, "source_url"); + pack.extra.wikiUrl = Json::ensureString(obj, "wiki_url"); + + pack.extraInfoLoaded = true; +} + +void loadIndexedVersions(Modpack& pack, QJsonDocument& doc) +{ + QVector unsortedVersions; + + auto arr = Json::requireArray(doc); + + for (auto versionIter : arr) { + auto obj = Json::requireObject(versionIter); + auto file = loadIndexedVersion(obj); + + if(!file.id.isEmpty()) // Heuristic to check if the returned value is valid + unsortedVersions.append(file); + } + auto orderSortPredicate = [](const ModpackVersion& a, const ModpackVersion& b) -> bool { + // dates are in RFC 3339 format + return a.date > b.date; + }; + + std::sort(unsortedVersions.begin(), unsortedVersions.end(), orderSortPredicate); + + pack.versions.swap(unsortedVersions); + + pack.versionsLoaded = true; +} + +auto loadIndexedVersion(QJsonObject &obj) -> ModpackVersion +{ + ModpackVersion file; + + file.name = Json::requireString(obj, "name"); + file.version = Json::requireString(obj, "version_number"); + + file.id = Json::requireString(obj, "id"); + file.project_id = Json::requireString(obj, "project_id"); + + file.date = Json::requireString(obj, "date_published"); + + auto files = Json::requireArray(obj, "files"); + + for (auto file_iter : files) { + File indexed_file; + auto parent = Json::requireObject(file_iter); + if (!Json::ensureBoolean(parent, "primary", false)) { + continue; + } + + file.download_url = Json::requireString(parent, "url"); + break; + } + + if(file.download_url.isEmpty()) + return {}; + + return file; +} + +} // namespace Modrinth -- cgit From 9899a0e098e5cfb76a754fa9da2f73be46cc880a Mon Sep 17 00:00:00 2001 From: flow Date: Sat, 14 May 2022 21:47:35 -0300 Subject: fix: Have the URL be the project URL itself (I think, doesn't seem to work for the waffle though, probably because of the staging API :/) --- launcher/modplatform/modrinth/ModrinthPackManifest.cpp | 1 + launcher/modplatform/modrinth/ModrinthPackManifest.h | 1 + launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) (limited to 'launcher/modplatform/modrinth/ModrinthPackManifest.cpp') diff --git a/launcher/modplatform/modrinth/ModrinthPackManifest.cpp b/launcher/modplatform/modrinth/ModrinthPackManifest.cpp index 4dcd2fd4..4b8a9a9b 100644 --- a/launcher/modplatform/modrinth/ModrinthPackManifest.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackManifest.cpp @@ -35,6 +35,7 @@ void loadIndexedPack(Modpack& pack, QJsonObject& obj) void loadIndexedInfo(Modpack& pack, QJsonObject& obj) { pack.extra.body = Json::ensureString(obj, "body"); + pack.extra.projectUrl = QString("https://modrinth.com/modpack/%1").arg(Json::ensureString(obj, "slug")); pack.extra.sourceUrl = Json::ensureString(obj, "source_url"); pack.extra.wikiUrl = Json::ensureString(obj, "wiki_url"); diff --git a/launcher/modplatform/modrinth/ModrinthPackManifest.h b/launcher/modplatform/modrinth/ModrinthPackManifest.h index 7dab893c..aaaacf2c 100644 --- a/launcher/modplatform/modrinth/ModrinthPackManifest.h +++ b/launcher/modplatform/modrinth/ModrinthPackManifest.h @@ -39,6 +39,7 @@ struct File struct ModpackExtra { QString body; + QString projectUrl; QString sourceUrl; QString wikiUrl; }; diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp index b21fdf4a..cf519b8c 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp @@ -219,7 +219,7 @@ void ModrinthPage::updateUI() if (current.extra.sourceUrl.isEmpty()) text = current.name; else - text = "" + current.name + ""; + text = "" + current.name + ""; if (!current.authors.empty()) { // TODO: Implement multiple authors with links -- cgit From 4745ed28186f46de60de155826c8f2bfb54f45cb Mon Sep 17 00:00:00 2001 From: flow Date: Sat, 14 May 2022 22:12:51 -0300 Subject: fix: choose valid download url even if it's not the primary one It seems to be possible to have modpack versions that have to primary file. In those cases, we pick a valid one "at random". --- launcher/modplatform/modrinth/ModrinthPackManifest.cpp | 14 +++++++++++--- launcher/modplatform/modrinth/ModrinthPackManifest.h | 4 ++-- 2 files changed, 13 insertions(+), 5 deletions(-) (limited to 'launcher/modplatform/modrinth/ModrinthPackManifest.cpp') diff --git a/launcher/modplatform/modrinth/ModrinthPackManifest.cpp b/launcher/modplatform/modrinth/ModrinthPackManifest.cpp index 4b8a9a9b..88ca808a 100644 --- a/launcher/modplatform/modrinth/ModrinthPackManifest.cpp +++ b/launcher/modplatform/modrinth/ModrinthPackManifest.cpp @@ -81,15 +81,23 @@ auto loadIndexedVersion(QJsonObject &obj) -> ModpackVersion auto files = Json::requireArray(obj, "files"); + qWarning() << files; + for (auto file_iter : files) { File indexed_file; auto parent = Json::requireObject(file_iter); - if (!Json::ensureBoolean(parent, "primary", false)) { - continue; + auto is_primary = Json::ensureBoolean(parent, "primary", false); + if (!is_primary) { + auto filename = Json::ensureString(parent, "filename"); + // Checking suffix here is fine because it's the response from Modrinth, + // so one would assume it will always be in English. + if(!filename.endsWith("mrpack") && !filename.endsWith("zip")) + continue; } file.download_url = Json::requireString(parent, "url"); - break; + if(is_primary) + break; } if(file.download_url.isEmpty()) diff --git a/launcher/modplatform/modrinth/ModrinthPackManifest.h b/launcher/modplatform/modrinth/ModrinthPackManifest.h index aaaacf2c..585f692a 100644 --- a/launcher/modplatform/modrinth/ModrinthPackManifest.h +++ b/launcher/modplatform/modrinth/ModrinthPackManifest.h @@ -79,5 +79,5 @@ auto loadIndexedVersion(QJsonObject&) -> ModpackVersion; } -Q_DECLARE_METATYPE(Modrinth::Modpack); -Q_DECLARE_METATYPE(Modrinth::ModpackVersion); +Q_DECLARE_METATYPE(Modrinth::Modpack) +Q_DECLARE_METATYPE(Modrinth::ModpackVersion) -- cgit