From 5e56b8cc307211598e0771bd0875036797051ff7 Mon Sep 17 00:00:00 2001 From: 90 Date: Tue, 28 May 2024 22:01:23 +0100 Subject: [PATCH 1/2] Add NeoForge support Signed-off-by: 90 --- launcher/minecraft/PackProfile.cpp | 1 + .../minecraft/mod/tasks/LocalModParseTask.cpp | 2 +- launcher/modplatform/ModAPI.h | 11 ++++--- launcher/modplatform/flame/FlameAPI.h | 2 ++ .../flame/FlameInstanceCreationTask.cpp | 8 +++++ .../modpacksch/FTBPackInstallTask.cpp | 2 ++ launcher/modplatform/modrinth/ModrinthAPI.h | 6 ++-- .../modrinth/ModrinthCheckUpdate.cpp | 2 +- .../modrinth/ModrinthInstanceCreationTask.cpp | 4 +++ .../modrinth/ModrinthInstanceCreationTask.h | 2 +- launcher/ui/pages/instance/VersionPage.cpp | 32 +++++++++++++++++++ launcher/ui/pages/instance/VersionPage.h | 1 + launcher/ui/pages/instance/VersionPage.ui | 9 ++++++ launcher/ui/pages/modplatform/VanillaPage.cpp | 6 ++++ launcher/ui/pages/modplatform/VanillaPage.ui | 10 ++++++ 15 files changed, 88 insertions(+), 10 deletions(-) diff --git a/launcher/minecraft/PackProfile.cpp b/launcher/minecraft/PackProfile.cpp index 1618458f..2c79c66c 100644 --- a/launcher/minecraft/PackProfile.cpp +++ b/launcher/minecraft/PackProfile.cpp @@ -60,6 +60,7 @@ static const QMap modloaderMapping{ {"net.minecraftforge", ModAPI::Forge}, + {"net.neoforged.neoforge", ModAPI::NeoForge}, {"net.fabricmc.fabric-loader", ModAPI::Fabric}, {"org.quiltmc.quilt-loader", ModAPI::Quilt} }; diff --git a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp index a694e7b2..2e193dd8 100644 --- a/launcher/minecraft/mod/tasks/LocalModParseTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalModParseTask.cpp @@ -297,7 +297,7 @@ void LocalModParseTask::processAsZip() QuaZipFile file(&zip); - if (zip.setCurrentFile("META-INF/mods.toml")) { + if (zip.setCurrentFile("META-INF/neoforge.mods.toml") || zip.setCurrentFile("META-INF/mods.toml")) { if (!file.open(QIODevice::ReadOnly)) { zip.close(); return; diff --git a/launcher/modplatform/ModAPI.h b/launcher/modplatform/ModAPI.h index c7408835..d9fb7950 100644 --- a/launcher/modplatform/ModAPI.h +++ b/launcher/modplatform/ModAPI.h @@ -57,10 +57,11 @@ class ModAPI { enum ModLoaderType { Unspecified = 0, Forge = 1 << 0, - Cauldron = 1 << 1, - LiteLoader = 1 << 2, - Fabric = 1 << 3, - Quilt = 1 << 4 + NeoForge = 1 << 1, + Cauldron = 1 << 2, + LiteLoader = 1 << 3, + Fabric = 1 << 4, + Quilt = 1 << 5 }; Q_DECLARE_FLAGS(ModLoaderTypes, ModLoaderType) @@ -93,6 +94,8 @@ class ModAPI { break; case Forge: return "forge"; + case NeoForge: + return "neoforge"; case Cauldron: return "cauldron"; case LiteLoader: diff --git a/launcher/modplatform/flame/FlameAPI.h b/launcher/modplatform/flame/FlameAPI.h index 4c6ca64c..8079faf8 100644 --- a/launcher/modplatform/flame/FlameAPI.h +++ b/launcher/modplatform/flame/FlameAPI.h @@ -79,6 +79,8 @@ class FlameAPI : public NetworkModAPI { // TODO: remove this once Quilt drops official Fabric support if (loaders & Quilt) // NOTE: Most if not all Fabric mods should work *currently* return 4; // Quilt would probably be 5 + if (loaders & NeoForge) + return 6; return 0; } }; diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index 859acc40..f92b6e8e 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -257,6 +257,7 @@ bool FlameCreationTask::createInstance() QString forgeVersion; QString fabricVersion; + QString neoforgeVersion; // TODO: is Quilt relevant here? for (auto& loader : m_pack.minecraft.modLoaders) { auto id = loader.id; @@ -270,6 +271,11 @@ bool FlameCreationTask::createInstance() fabricVersion = id; continue; } + if (id.startsWith("neoforge-")) { + id.remove("neoforge-"); + neoforgeVersion = id; + continue; + } logWarning(tr("Unknown mod loader in manifest: %1").arg(id)); } @@ -300,6 +306,8 @@ bool FlameCreationTask::createInstance() } if (!fabricVersion.isEmpty()) components->setComponentVersion("net.fabricmc.fabric-loader", fabricVersion); + if (!neoforgeVersion.isEmpty()) + components->setComponentVersion("net.neoforged.neoforge", neoforgeVersion); if (m_instIcon != "default") { instance.setIconKey(m_instIcon); diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp index 3e4cc30c..45183237 100644 --- a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp +++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp @@ -313,6 +313,8 @@ void PackInstallTask::install() components->setComponentVersion("net.minecraftforge", target.version); } else if (target.name == "fabric") { components->setComponentVersion("net.fabricmc.fabric-loader", target.version); + } else if (target.name == "neoforge") { + components->setComponentVersion("net.neoforged.neoforge", target.version); } } diff --git a/launcher/modplatform/modrinth/ModrinthAPI.h b/launcher/modplatform/modrinth/ModrinthAPI.h index e1a18681..10b26f26 100644 --- a/launcher/modplatform/modrinth/ModrinthAPI.h +++ b/launcher/modplatform/modrinth/ModrinthAPI.h @@ -55,7 +55,7 @@ class ModrinthAPI : public NetworkModAPI { static auto getModLoaderStrings(const ModLoaderTypes types) -> const QStringList { QStringList l; - for (auto loader : {Forge, Fabric, Quilt}) + for (auto loader : {Forge, NeoForge, Fabric, Quilt}) { if ((types & loader) || types == Unspecified) { @@ -81,7 +81,7 @@ class ModrinthAPI : public NetworkModAPI { inline auto getModSearchURL(SearchArgs& args) const -> QString override { if (!validateModLoaders(args.loaders)) { - qWarning() << "Modrinth only have Forge and Fabric-compatible mods!"; + qWarning() << "Modrinth only have Forge, NeoForge and Fabric-compatible mods!"; return ""; } @@ -132,7 +132,7 @@ class ModrinthAPI : public NetworkModAPI { inline auto validateModLoaders(ModLoaderTypes loaders) const -> bool { - return (loaders == Unspecified) || (loaders & (Forge | Fabric | Quilt)); + return (loaders == Unspecified) || (loaders & (Forge | NeoForge | Fabric | Quilt)); } }; diff --git a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp index 856f12ac..760d9caf 100644 --- a/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp +++ b/launcher/modplatform/modrinth/ModrinthCheckUpdate.cpp @@ -108,7 +108,7 @@ void ModrinthCheckUpdate::executeTask() // Sometimes a version may have multiple files, one with "forge" and one with "fabric", // so we may want to filter it QString loader_filter; - static auto flags = { ModAPI::ModLoaderType::Forge, ModAPI::ModLoaderType::Fabric, ModAPI::ModLoaderType::Quilt }; + static auto flags = { ModAPI::ModLoaderType::Forge, ModAPI::ModLoaderType::NeoForge, ModAPI::ModLoaderType::Fabric, ModAPI::ModLoaderType::Quilt }; for (auto flag : flags) { if (m_loaders.testFlag(flag)) { loader_filter = api.getModLoaderString(flag); diff --git a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp index bd4c9461..fd3fdf0d 100644 --- a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp +++ b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.cpp @@ -215,6 +215,8 @@ bool ModrinthCreationTask::createInstance() components->setComponentVersion("org.quiltmc.quilt-loader", quiltVersion); if (!forgeVersion.isEmpty()) components->setComponentVersion("net.minecraftforge", forgeVersion); + if (!neoforgeVersion.isEmpty()) + components->setComponentVersion("net.neoforged.neoforge", neoforgeVersion); if (m_instIcon != "default") { instance.setIconKey(m_instIcon); @@ -385,6 +387,8 @@ bool ModrinthCreationTask::parseManifest(const QString& index_path, std::vector< quiltVersion = Json::requireString(*it, "Quilt Loader version"); } else if (name == "forge") { forgeVersion = Json::requireString(*it, "Forge version"); + } else if (name == "neoforge") { + neoforgeVersion = Json::requireString(*it, "NeoForge version"); } else { throw JSONValidationError("Unknown dependency type: " + name); } diff --git a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.h b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.h index e459aadf..98ee8802 100644 --- a/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.h +++ b/launcher/modplatform/modrinth/ModrinthInstanceCreationTask.h @@ -33,7 +33,7 @@ class ModrinthCreationTask final : public InstanceCreationTask { private: QWidget* m_parent = nullptr; - QString minecraftVersion, fabricVersion, quiltVersion, forgeVersion; + QString minecraftVersion, fabricVersion, quiltVersion, forgeVersion, neoforgeVersion; QString m_managed_id, m_managed_version_id, m_managed_name; QString m_source_url; diff --git a/launcher/ui/pages/instance/VersionPage.cpp b/launcher/ui/pages/instance/VersionPage.cpp index 772d6759..ed842c05 100644 --- a/launcher/ui/pages/instance/VersionPage.cpp +++ b/launcher/ui/pages/instance/VersionPage.cpp @@ -240,6 +240,9 @@ void VersionPage::updateVersionControls() ui->actionInstall_Forge->setEnabled(controlsEnabled); + bool supportsNeoForge = minecraftVersion >= Version("1.20.1"); + ui->actionInstall_NeoForge->setEnabled(controlsEnabled && supportsNeoForge); + bool supportsFabric = minecraftVersion >= Version("1.14"); ui->actionInstall_Fabric->setEnabled(controlsEnabled && supportsFabric); @@ -473,6 +476,35 @@ void VersionPage::on_actionInstall_Forge_triggered() } } +void VersionPage::on_actionInstall_NeoForge_triggered() +{ + auto vlist = APPLICATION->metadataIndex()->get("net.neoforged.neoforge"); + if(!vlist) + { + return; + } + VersionSelectDialog vselect(vlist.get(), tr("Select NeoForge version"), this); + vselect.setExactFilter(BaseVersionList::ParentVersionRole, m_profile->getComponentVersion("net.minecraft")); + vselect.setEmptyString(tr("No NeoForge versions are currently available for Minecraft ") + m_profile->getComponentVersion("net.minecraft")); + vselect.setEmptyErrorString(tr("Couldn't load or download the NeoForge version lists!")); + + auto currentVersion = m_profile->getComponentVersion("net.neoforged.neoforge"); + if(!currentVersion.isEmpty()) + { + vselect.setCurrentVersion(currentVersion); + } + + if (vselect.exec() && vselect.selectedVersion()) + { + auto vsn = vselect.selectedVersion(); + m_profile->setComponentVersion("net.neoforged.neoforge", vsn->descriptor()); + m_profile->resolve(Net::Mode::Online); + // m_profile->installVersion(); + preselect(m_profile->rowCount(QModelIndex())-1); + m_container->refreshContainer(); + } +} + void VersionPage::on_actionInstall_Fabric_triggered() { auto vlist = APPLICATION->metadataIndex()->get("net.fabricmc.fabric-loader"); diff --git a/launcher/ui/pages/instance/VersionPage.h b/launcher/ui/pages/instance/VersionPage.h index 979311fc..d6933478 100644 --- a/launcher/ui/pages/instance/VersionPage.h +++ b/launcher/ui/pages/instance/VersionPage.h @@ -72,6 +72,7 @@ public: private slots: void on_actionChange_version_triggered(); void on_actionInstall_Forge_triggered(); + void on_actionInstall_NeoForge_triggered(); void on_actionInstall_Fabric_triggered(); void on_actionInstall_Quilt_triggered(); void on_actionAdd_Empty_triggered(); diff --git a/launcher/ui/pages/instance/VersionPage.ui b/launcher/ui/pages/instance/VersionPage.ui index fcba5598..1b1d687d 100644 --- a/launcher/ui/pages/instance/VersionPage.ui +++ b/launcher/ui/pages/instance/VersionPage.ui @@ -106,6 +106,7 @@ + @@ -185,6 +186,14 @@ Install the Minecraft Forge package. + + + Install NeoForge + + + Install the NeoForge package. + + Install Fabric diff --git a/launcher/ui/pages/modplatform/VanillaPage.cpp b/launcher/ui/pages/modplatform/VanillaPage.cpp index 99190f31..18991d51 100644 --- a/launcher/ui/pages/modplatform/VanillaPage.cpp +++ b/launcher/ui/pages/modplatform/VanillaPage.cpp @@ -64,6 +64,7 @@ VanillaPage::VanillaPage(NewInstanceDialog *dialog, QWidget *parent) connect(ui->loaderVersionList, &VersionSelectWidget::selectedVersionChanged, this, &VanillaPage::setSelectedLoaderVersion); connect(ui->noneFilter, &QRadioButton::toggled, this, &VanillaPage::loaderFilterChanged); connect(ui->forgeFilter, &QRadioButton::toggled, this, &VanillaPage::loaderFilterChanged); + connect(ui->neoForgeFilter, &QRadioButton::toggled, this, &VanillaPage::loaderFilterChanged); connect(ui->fabricFilter, &QRadioButton::toggled, this, &VanillaPage::loaderFilterChanged); connect(ui->quiltFilter, &QRadioButton::toggled, this, &VanillaPage::loaderFilterChanged); connect(ui->liteLoaderFilter, &QRadioButton::toggled, this, &VanillaPage::loaderFilterChanged); @@ -142,6 +143,11 @@ void VanillaPage::loaderFilterChanged() ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, minecraftVersion); m_selectedLoader = "net.minecraftforge"; } + else if(ui->neoForgeFilter->isChecked()) + { + ui->loaderVersionList->setExactFilter(BaseVersionList::ParentVersionRole, minecraftVersion); + m_selectedLoader = "net.neoforged.neoforge"; + } else if(ui->fabricFilter->isChecked()) { // FIXME: dirty hack because the launcher is unaware of Fabric's dependencies diff --git a/launcher/ui/pages/modplatform/VanillaPage.ui b/launcher/ui/pages/modplatform/VanillaPage.ui index 43110927..f35ee4ab 100644 --- a/launcher/ui/pages/modplatform/VanillaPage.ui +++ b/launcher/ui/pages/modplatform/VanillaPage.ui @@ -204,6 +204,16 @@ + + + + NeoForge + + + loaderBtnGroup + + + From a2932ef8a8276f7b1620850ab7aa9195e6a1090b Mon Sep 17 00:00:00 2001 From: 90 Date: Mon, 24 Jun 2024 18:40:37 +0100 Subject: [PATCH 2/2] Don't offset every existing ModAPI enum entry Signed-off-by: 90 --- launcher/modplatform/ModAPI.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/launcher/modplatform/ModAPI.h b/launcher/modplatform/ModAPI.h index d9fb7950..f06a719b 100644 --- a/launcher/modplatform/ModAPI.h +++ b/launcher/modplatform/ModAPI.h @@ -57,11 +57,11 @@ class ModAPI { enum ModLoaderType { Unspecified = 0, Forge = 1 << 0, - NeoForge = 1 << 1, - Cauldron = 1 << 2, - LiteLoader = 1 << 3, - Fabric = 1 << 4, - Quilt = 1 << 5 + Cauldron = 1 << 1, + LiteLoader = 1 << 2, + Fabric = 1 << 3, + Quilt = 1 << 4, + NeoForge = 1 << 5 }; Q_DECLARE_FLAGS(ModLoaderTypes, ModLoaderType)