aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkumquat-ir <66188216+kumquat-ir@users.noreply.github.com>2021-04-16 13:33:56 -0700
committerkumquat-ir <66188216+kumquat-ir@users.noreply.github.com>2021-04-16 13:33:56 -0700
commit7156e086f6ba6993db87396e133b8158bed882c8 (patch)
tree7257f240bf76acacef4b211876dbe2c539425fb0
parent860706caec6cf2ab26089d6c1f1fc12166767cd9 (diff)
downloadPrismLauncher-7156e086f6ba6993db87396e133b8158bed882c8.tar.gz
PrismLauncher-7156e086f6ba6993db87396e133b8158bed882c8.tar.bz2
PrismLauncher-7156e086f6ba6993db87396e133b8158bed882c8.zip
parse META-INF/mods.toml for metadata
-rw-r--r--api/logic/CMakeLists.txt2
-rw-r--r--api/logic/minecraft/mod/LocalModParseTask.cpp74
2 files changed, 74 insertions, 2 deletions
diff --git a/api/logic/CMakeLists.txt b/api/logic/CMakeLists.txt
index beaa0c00..23bf848d 100644
--- a/api/logic/CMakeLists.txt
+++ b/api/logic/CMakeLists.txt
@@ -540,7 +540,7 @@ set_target_properties(MultiMC_logic PROPERTIES CXX_VISIBILITY_PRESET hidden VISI
generate_export_header(MultiMC_logic)
# Link
-target_link_libraries(MultiMC_logic systeminfo MultiMC_quazip MultiMC_classparser ${NBT_NAME} ${ZLIB_LIBRARIES} optional-bare BuildConfig)
+target_link_libraries(MultiMC_logic systeminfo MultiMC_quazip MultiMC_classparser ${NBT_NAME} ${ZLIB_LIBRARIES} optional-bare toml11 BuildConfig)
target_link_libraries(MultiMC_logic Qt5::Core Qt5::Xml Qt5::Network Qt5::Concurrent)
# Mark and export headers
diff --git a/api/logic/minecraft/mod/LocalModParseTask.cpp b/api/logic/minecraft/mod/LocalModParseTask.cpp
index 22ebd7d4..cb35dca6 100644
--- a/api/logic/minecraft/mod/LocalModParseTask.cpp
+++ b/api/logic/minecraft/mod/LocalModParseTask.cpp
@@ -6,6 +6,7 @@
#include <QJsonValue>
#include <quazip.h>
#include <quazipfile.h>
+#include <toml.hpp>
#include "settings/INIFile.h"
#include "FileSystem.h"
@@ -90,6 +91,64 @@ std::shared_ptr<ModDetails> ReadMCModInfo(QByteArray contents)
return nullptr;
}
+
+std::shared_ptr<ModDetails> ReadMCModTOML(QByteArray contents)
+{
+ std::shared_ptr<ModDetails> details = std::make_shared<ModDetails>();
+
+ // toml11 throws an error when something goes wrong in parsing, so we need to catch that
+ try {
+ // data under the root table
+ auto tomlData = toml::parse(contents);
+ // data under [[mods]]
+ auto tomlModsArr = toml::find<std::vector<toml::value>>(tomlData, "mods");
+
+ // these properties are required in this location by forge, and thus can be assumed to exist
+ // forge supports multiple mods in one file, details of which are accessable here from tomlModsArr[n]
+ details->mod_id = QString::fromStdString(toml::find<std::string>(tomlModsArr[0], "modId"));
+ details->version = QString::fromStdString(toml::find<std::string>(tomlModsArr[0], "version"));
+ details->name = QString::fromStdString(toml::find<std::string>(tomlModsArr[0], "displayName"));
+ // known issue: sometimes overflows the description box for some reason
+ details->description = QString::fromStdString(toml::find<std::string>(tomlModsArr[0], "description"));
+
+ // optional properties - can be stored either in the root table or in [[mods]]
+ auto authors = QString::fromStdString(toml::find_or<std::string>(tomlData, "authors", ""));
+ if(authors.isEmpty())
+ {
+ authors = QString::fromStdString(toml::find_or<std::string>(tomlModsArr[0], "authors", ""));
+ }
+ if(!authors.isEmpty())
+ {
+ // author information is stored as a string now, not a list
+ details->authors.append(authors);
+ }
+ // is credits even used anywhere? including this for completion/parity with old data version
+ auto credits = QString::fromStdString(toml::find_or<std::string>(tomlData, "credits", ""));
+ if(credits.isEmpty())
+ {
+ credits = QString::fromStdString(toml::find_or<std::string>(tomlModsArr[0], "credits", ""));
+ }
+ details->credits = credits;
+ auto homeurl = QString::fromStdString(toml::find_or<std::string>(tomlData, "displayURL", ""));
+ if(homeurl.isEmpty())
+ {
+ homeurl = QString::fromStdString(toml::find_or<std::string>(tomlModsArr[0], "displayURL", ""));
+ }
+ if(!homeurl.isEmpty())
+ {
+ // fix up url.
+ if (!homeurl.startsWith("http://") && !homeurl.startsWith("https://") && !homeurl.startsWith("ftp://"))
+ {
+ homeurl.prepend("http://");
+ }
+ }
+ details->homeurl = homeurl;
+ } catch (toml::syntax_error&) {
+ return nullptr;
+ }
+ return details;
+}
+
// https://fabricmc.net/wiki/documentation:fabric_mod_json
std::shared_ptr<ModDetails> ReadFabricModInfo(QByteArray contents)
{
@@ -198,7 +257,20 @@ void LocalModParseTask::processAsZip()
QuaZipFile file(&zip);
- if (zip.setCurrentFile("mcmod.info"))
+ if (zip.setCurrentFile("META-INF/mods.toml"))
+ {
+ if (!file.open(QIODevice::ReadOnly))
+ {
+ zip.close();
+ return;
+ }
+
+ m_result->details = ReadMCModTOML(file.readAll());
+ file.close();
+ zip.close();
+ return;
+ }
+ else if (zip.setCurrentFile("mcmod.info"))
{
if (!file.open(QIODevice::ReadOnly))
{