diff options
author | Sefa Eyeoglu <contact@scrumplex.net> | 2023-03-05 13:39:00 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-05 13:39:00 +0100 |
commit | f3f0652d2ba06d567c02ec2f0b85bfa97d465d98 (patch) | |
tree | 6bf189684cd1ae1db6ddac90cabdb42cbb14668a /launcher | |
parent | aae60334d1d7a9dbc26bca634d1b34257c7b9566 (diff) | |
parent | 01c4ed232e67c1b980a0c091c4c277722811d3dc (diff) | |
download | PrismLauncher-f3f0652d2ba06d567c02ec2f0b85bfa97d465d98.tar.gz PrismLauncher-f3f0652d2ba06d567c02ec2f0b85bfa97d465d98.tar.bz2 PrismLauncher-f3f0652d2ba06d567c02ec2f0b85bfa97d465d98.zip |
Merge pull request #853 from kumquat-ir/nil
NilLoader mod metadata support
Diffstat (limited to 'launcher')
-rw-r--r-- | launcher/CMakeLists.txt | 1 | ||||
-rw-r--r-- | launcher/InstancePageProvider.h | 3 | ||||
-rw-r--r-- | launcher/minecraft/MinecraftInstance.cpp | 17 | ||||
-rw-r--r-- | launcher/minecraft/MinecraftInstance.h | 3 | ||||
-rw-r--r-- | launcher/minecraft/launch/ScanModFolders.cpp | 14 | ||||
-rw-r--r-- | launcher/minecraft/launch/ScanModFolders.h | 2 | ||||
-rw-r--r-- | launcher/minecraft/mod/ModFolderModel.cpp | 2 | ||||
-rw-r--r-- | launcher/minecraft/mod/ModFolderModel.h | 2 | ||||
-rw-r--r-- | launcher/minecraft/mod/Resource.cpp | 3 | ||||
-rw-r--r-- | launcher/minecraft/mod/ResourceFolderModel.cpp | 6 | ||||
-rw-r--r-- | launcher/minecraft/mod/ResourceFolderModel.h | 2 | ||||
-rw-r--r-- | launcher/minecraft/mod/tasks/LocalModParseTask.cpp | 53 | ||||
-rw-r--r-- | launcher/ui/pages/instance/ModFolderPage.cpp | 9 | ||||
-rw-r--r-- | launcher/ui/pages/instance/ModFolderPage.h | 13 |
14 files changed, 123 insertions, 7 deletions
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 202e633c..074570e3 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -1038,6 +1038,7 @@ target_link_libraries(Launcher_logic nbt++ ${ZLIB_LIBRARIES} tomlplusplus::tomlplusplus + qdcss BuildConfig Katabasis Qt${QT_VERSION_MAJOR}::Widgets diff --git a/launcher/InstancePageProvider.h b/launcher/InstancePageProvider.h index 5d8beca9..b4b6e739 100644 --- a/launcher/InstancePageProvider.h +++ b/launcher/InstancePageProvider.h @@ -36,9 +36,10 @@ public: values.append(new VersionPage(onesix.get())); values.append(ManagedPackPage::createPage(onesix.get())); auto modsPage = new ModFolderPage(onesix.get(), onesix->loaderModList()); - modsPage->setFilter("%1 (*.zip *.jar *.litemod)"); + modsPage->setFilter("%1 (*.zip *.jar *.litemod *.nilmod)"); values.append(modsPage); values.append(new CoreModFolderPage(onesix.get(), onesix->coreModList())); + values.append(new NilModFolderPage(onesix.get(), onesix->nilModList())); values.append(new ResourcePackPage(onesix.get(), onesix->resourcePackList())); values.append(new TexturePackPage(onesix.get(), onesix->texturePackList())); values.append(new ShaderPackPage(onesix.get(), onesix->shaderPackList())); diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 4fe234c4..af4da5d0 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -290,6 +290,11 @@ QString MinecraftInstance::coreModsDir() const return FS::PathCombine(gameRoot(), "coremods"); } +QString MinecraftInstance::nilModsDir() const +{ + return FS::PathCombine(gameRoot(), "nilmods"); +} + QString MinecraftInstance::resourcePacksDir() const { return FS::PathCombine(gameRoot(), "resourcepacks"); @@ -1125,6 +1130,18 @@ std::shared_ptr<ModFolderModel> MinecraftInstance::coreModList() const return m_core_mod_list; } +std::shared_ptr<ModFolderModel> MinecraftInstance::nilModList() const +{ + if (!m_nil_mod_list) + { + bool is_indexed = !APPLICATION->settings()->get("ModMetadataDisabled").toBool(); + m_nil_mod_list.reset(new ModFolderModel(nilModsDir(), is_indexed, false)); + m_nil_mod_list->disableInteraction(isRunning()); + connect(this, &BaseInstance::runningStatusChanged, m_nil_mod_list.get(), &ModFolderModel::disableInteraction); + } + return m_nil_mod_list; +} + std::shared_ptr<ResourcePackFolderModel> MinecraftInstance::resourcePackList() const { if (!m_resource_pack_list) diff --git a/launcher/minecraft/MinecraftInstance.h b/launcher/minecraft/MinecraftInstance.h index 1bbd7b83..a75fa481 100644 --- a/launcher/minecraft/MinecraftInstance.h +++ b/launcher/minecraft/MinecraftInstance.h @@ -84,6 +84,7 @@ public: QString shaderPacksDir() const; QString modsRoot() const override; QString coreModsDir() const; + QString nilModsDir() const; QString modsCacheLocation() const; QString libDir() const; QString worldDir() const; @@ -116,6 +117,7 @@ public: ////// Mod Lists ////// std::shared_ptr<ModFolderModel> loaderModList() const; std::shared_ptr<ModFolderModel> coreModList() const; + std::shared_ptr<ModFolderModel> nilModList() const; std::shared_ptr<ResourcePackFolderModel> resourcePackList() const; std::shared_ptr<TexturePackFolderModel> texturePackList() const; std::shared_ptr<ShaderPackFolderModel> shaderPackList() const; @@ -170,6 +172,7 @@ protected: // data std::shared_ptr<PackProfile> m_components; mutable std::shared_ptr<ModFolderModel> m_loader_mod_list; mutable std::shared_ptr<ModFolderModel> m_core_mod_list; + mutable std::shared_ptr<ModFolderModel> m_nil_mod_list; mutable std::shared_ptr<ResourcePackFolderModel> m_resource_pack_list; mutable std::shared_ptr<ShaderPackFolderModel> m_shader_pack_list; mutable std::shared_ptr<TexturePackFolderModel> m_texture_pack_list; diff --git a/launcher/minecraft/launch/ScanModFolders.cpp b/launcher/minecraft/launch/ScanModFolders.cpp index bdffeadd..71e7638c 100644 --- a/launcher/minecraft/launch/ScanModFolders.cpp +++ b/launcher/minecraft/launch/ScanModFolders.cpp @@ -55,6 +55,12 @@ void ScanModFolders::executeTask() if(!cores->update()) { m_coreModsDone = true; } + + auto nils = m_inst->nilModList(); + connect(nils.get(), &ModFolderModel::updateFinished, this, &ScanModFolders::nilModsDone); + if(!nils->update()) { + m_nilModsDone = true; + } checkDone(); } @@ -70,9 +76,15 @@ void ScanModFolders::coreModsDone() checkDone(); } +void ScanModFolders::nilModsDone() +{ + m_nilModsDone = true; + checkDone(); +} + void ScanModFolders::checkDone() { - if(m_modsDone && m_coreModsDone) { + if(m_modsDone && m_coreModsDone && m_nilModsDone) { emitSucceeded(); } } diff --git a/launcher/minecraft/launch/ScanModFolders.h b/launcher/minecraft/launch/ScanModFolders.h index d5989170..111a5850 100644 --- a/launcher/minecraft/launch/ScanModFolders.h +++ b/launcher/minecraft/launch/ScanModFolders.h @@ -33,10 +33,12 @@ public: private slots: void coreModsDone(); void modsDone(); + void nilModsDone(); private: void checkDone(); private: // DATA bool m_modsDone = false; + bool m_nilModsDone = false; bool m_coreModsDone = false; }; diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index f258ad69..3f31b93c 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -50,7 +50,7 @@ #include "minecraft/mod/tasks/ModFolderLoadTask.h" #include "modplatform/ModIndex.h" -ModFolderModel::ModFolderModel(const QString &dir, bool is_indexed) : ResourceFolderModel(QDir(dir)), m_is_indexed(is_indexed) +ModFolderModel::ModFolderModel(const QString &dir, bool is_indexed, bool create_dir) : ResourceFolderModel(QDir(dir), nullptr, create_dir), m_is_indexed(is_indexed) { m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::VERSION, SortType::DATE, SortType::PROVIDER }; } diff --git a/launcher/minecraft/mod/ModFolderModel.h b/launcher/minecraft/mod/ModFolderModel.h index 6898f6eb..84e70db9 100644 --- a/launcher/minecraft/mod/ModFolderModel.h +++ b/launcher/minecraft/mod/ModFolderModel.h @@ -75,7 +75,7 @@ public: Enable, Toggle }; - ModFolderModel(const QString &dir, bool is_indexed = false); + ModFolderModel(const QString &dir, bool is_indexed = false, bool create_dir = true); QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; diff --git a/launcher/minecraft/mod/Resource.cpp b/launcher/minecraft/mod/Resource.cpp index 7c572d92..0d35d755 100644 --- a/launcher/minecraft/mod/Resource.cpp +++ b/launcher/minecraft/mod/Resource.cpp @@ -37,6 +37,9 @@ void Resource::parseFile() if (file_name.endsWith(".zip") || file_name.endsWith(".jar")) { m_type = ResourceType::ZIPFILE; file_name.chop(4); + } else if (file_name.endsWith(".nilmod")) { + m_type = ResourceType::ZIPFILE; + file_name.chop(7); } else if (file_name.endsWith(".litemod")) { m_type = ResourceType::LITEMOD; file_name.chop(8); diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index fdfb434b..f2a77c12 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -12,9 +12,11 @@ #include "tasks/Task.h" -ResourceFolderModel::ResourceFolderModel(QDir dir, QObject* parent) : QAbstractListModel(parent), m_dir(dir), m_watcher(this) +ResourceFolderModel::ResourceFolderModel(QDir dir, QObject* parent, bool create_dir) : QAbstractListModel(parent), m_dir(dir), m_watcher(this) { - FS::ensureFolderPathExists(m_dir.absolutePath()); + if (create_dir) { + FS::ensureFolderPathExists(m_dir.absolutePath()); + } m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs); m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware); diff --git a/launcher/minecraft/mod/ResourceFolderModel.h b/launcher/minecraft/mod/ResourceFolderModel.h index f1bc2dd7..3bd78870 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.h +++ b/launcher/minecraft/mod/ResourceFolderModel.h @@ -24,7 +24,7 @@ class QSortFilterProxyModel; class ResourceFolderModel : public QAbstractListModel { Q_OBJECT public: - ResourceFolderModel(QDir, QObject* parent = nullptr); + ResourceFolderModel(QDir, QObject* parent = nullptr, bool create_dir = true); ~ResourceFolderModel() override; /** Starts watching the paths for changes. diff --git a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp index 91cb747f..da27a505 100644 --- a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp @@ -3,6 +3,7 @@ #include <quazip/quazip.h> #include <quazip/quazipfile.h> #include <toml++/toml.h> +#include <qdcss.h> #include <QJsonArray> #include <QJsonDocument> #include <QJsonObject> @@ -285,6 +286,32 @@ ModDetails ReadLiteModInfo(QByteArray contents) return details; } +// https://git.sleeping.town/unascribed/NilLoader/src/commit/d7fc87b255fc31019ff90f80d45894927fac6efc/src/main/java/nilloader/api/NilMetadata.java#L64 +ModDetails ReadNilModInfo(QByteArray contents, QString fname) +{ + ModDetails details; + + QDCSS cssData = QDCSS(contents); + auto name = cssData.get("@nilmod.name"); + auto desc = cssData.get("@nilmod.description"); + auto authors = cssData.get("@nilmod.authors"); + + if (name->has_value()) { + details.name = name->value(); + } + if (desc->has_value()) { + details.description = desc->value(); + } + if (authors->has_value()) { + details.authors.append(authors->value()); + } + details.version = cssData.get("@nilmod.version")->value_or("?"); + + details.mod_id = fname.remove(".nilmod.css"); + + return details; +} + bool process(Mod& mod, ProcessingLevel level) { switch (mod.type()) { @@ -401,6 +428,32 @@ bool processZIP(Mod& mod, ProcessingLevel level) mod.setDetails(details); return true; + } else if (zip.setCurrentFile("META-INF/nil/mappings.json")) { + // nilloader uses the filename of the metadata file for the modid, so we can't know the exact filename + // thankfully, there is a good file to use as a canary so we don't look for nil meta all the time + + QString foundNilMeta; + for (auto& fname : zip.getFileNameList()) { + // nilmods can shade nilloader to be able to run as a standalone agent - which includes nilloader's own meta file + if (fname.endsWith(".nilmod.css") && fname != "nilloader.nilmod.css") { + foundNilMeta = fname; + break; + } + } + + if (zip.setCurrentFile(foundNilMeta)) { + if (!file.open(QIODevice::ReadOnly)) { + zip.close(); + return false; + } + + details = ReadNilModInfo(file.readAll(), foundNilMeta); + file.close(); + zip.close(); + + mod.setDetails(details); + return true; + } } zip.close(); diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index d9069915..4548af59 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -273,3 +273,12 @@ bool CoreModFolderPage::shouldDisplay() const } return false; } + +NilModFolderPage::NilModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel> mods, QWidget* parent) + : ModFolderPage(inst, mods, parent) +{} + +bool NilModFolderPage::shouldDisplay() const +{ + return m_model->dir().exists(); +} diff --git a/launcher/ui/pages/instance/ModFolderPage.h b/launcher/ui/pages/instance/ModFolderPage.h index ff58b38a..2fc7b574 100644 --- a/launcher/ui/pages/instance/ModFolderPage.h +++ b/launcher/ui/pages/instance/ModFolderPage.h @@ -81,3 +81,16 @@ class CoreModFolderPage : public ModFolderPage { virtual bool shouldDisplay() const override; }; + +class NilModFolderPage : public ModFolderPage { + public: + explicit NilModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel> mods, QWidget* parent = 0); + virtual ~NilModFolderPage() = default; + + virtual QString displayName() const override { return tr("Nilmods"); } + virtual QIcon icon() const override { return APPLICATION->getThemedIcon("coremods"); } + virtual QString id() const override { return "nilmods"; } + virtual QString helpPage() const override { return "Nilmods"; } + + virtual bool shouldDisplay() const override; +}; |