From 5e56b8cc307211598e0771bd0875036797051ff7 Mon Sep 17 00:00:00 2001 From: 90 Date: Tue, 28 May 2024 22:01:23 +0100 Subject: [PATCH 1/3] 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/3] 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) From 3f4de323b491454340804b30bec2ae9350a1062b Mon Sep 17 00:00:00 2001 From: LordMZTE Date: Tue, 30 Jul 2024 21:24:28 +0200 Subject: [PATCH 3/3] Update Nix package - Updated Nix flake. This fixes theming, which was broken on newer systems due to a version mismatch. - Added xrandr to the path inside the wrapped binary. Xrandr is required by older LWJGL versions. This allows launching old MC versions without a system Xrandr installation. - Added options to the wrapped package that allow for the user to add additonal libraries or binaries. - Added support for libgamemode - Set BUILD_PLATFORM to nix to make nix builds identifiable --- flake.lock | 12 ++++++------ nix/default.nix | 20 +++++++++++++++++--- nix/unwrapped.nix | 9 +++++++-- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/flake.lock b/flake.lock index 5a12e61a..858135d8 100644 --- a/flake.lock +++ b/flake.lock @@ -34,11 +34,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1712129508, - "narHash": "sha256-FBVpEX0eLiqX3jnSL3rmJHqHhbuCikJZyDyV3Cl3qAY=", + "lastModified": 1722141560, + "narHash": "sha256-Ul3rIdesWaiW56PS/Ak3UlJdkwBrD4UcagCmXZR9Z7Y=", "owner": "nixos", "repo": "nixpkgs", - "rev": "d03a4482228d4d6dbd2d4b425b6dfcd49ebe765f", + "rev": "038fb464fcfa79b4f08131b07f2d8c9a6bcc4160", "type": "github" }, "original": { @@ -59,11 +59,11 @@ "tomlplusplus": { "flake": false, "locked": { - "lastModified": 1710824845, - "narHash": "sha256-A9XuCfVcLle/tMNaH7aqb1leM+t3wwC9ER5RIbMMovo=", + "lastModified": 1720775063, + "narHash": "sha256-9j8qNCITFPvKECY5Sjb2Ri5KcPzRrF0e7G2CUemIhBw=", "owner": "marzer", "repo": "tomlplusplus", - "rev": "1f7884e59165e517462f922e7b6de131bd9844f3", + "rev": "e2bae9d559b4956a831fcef10ac8f01c88cb0d13", "type": "github" }, "original": { diff --git a/nix/default.nix b/nix/default.nix index 94a156ed..9209145c 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -8,6 +8,8 @@ , jdk17 , jdk21 , xorg +, gamemode +, glxinfo , libpulseaudio , qtbase , libGL @@ -19,13 +21,16 @@ , msaClientID ? "" , jdks ? [ jdk21 jdk17 jdk8 ] , enableLTO ? false +, gamemodeSupport ? stdenv.isLinux +, additionalLibs ? [ ] +, additionalBins ? [ ] , self , version # flake }: let - polymcInner = polymc-unwrapped.override { inherit msaClientID enableLTO; }; + polymcInner = polymc-unwrapped.override { inherit msaClientID enableLTO gamemodeSupport; }; in symlinkJoin { @@ -59,12 +64,21 @@ symlinkJoin { stdenv.cc.cc.lib udev # OSHI wayland - ]; + ] + ++ lib.optional gamemodeSupport gamemode.lib + ++ additionalLibs; + + runtimeBins = [ + # Required by old LWJGL versions + xorg.xrandr + glxinfo + ] ++ additionalBins; in [ "--prefix POLYMC_JAVA_PATHS : ${lib.makeSearchPath "bin/java" jdks}" "--set LD_LIBRARY_PATH ${addOpenGLRunpath.driverLink}/lib:${lib.makeLibraryPath runtimeLibs}" + "--prefix PATH : ${lib.makeBinPath runtimeBins}" ]; - inherit (polymcInner) meta; + inherit (polymcInner) meta; } diff --git a/nix/unwrapped.nix b/nix/unwrapped.nix index b46f550c..15fd78f9 100644 --- a/nix/unwrapped.nix +++ b/nix/unwrapped.nix @@ -3,12 +3,12 @@ , cmake , ninja , jdk8 +, gamemode , ghc_filesystem , zlib , file , qtbase , quazip -, msaClientID ? "" , extra-cmake-modules , qtcharts , qtwayland @@ -17,6 +17,8 @@ , version , libnbtplusplus , tomlplusplus +, msaClientID ? "" +, gamemodeSupport ? stdenv.isLinux , enableLTO ? false }: @@ -27,7 +29,9 @@ stdenv.mkDerivation { src = lib.cleanSource self; nativeBuildInputs = [ cmake extra-cmake-modules ninja jdk8 ghc_filesystem file ]; - buildInputs = [ qtbase quazip zlib qtcharts ] ++ lib.optional (lib.versionAtLeast qtbase.version "6") qtwayland; + buildInputs = [ qtbase quazip zlib qtcharts ] + ++ lib.optional (lib.versionAtLeast qtbase.version "6") qtwayland + ++ lib.optional gamemodeSupport gamemode; postUnpack = '' # Copy libnbtplusplus @@ -47,6 +51,7 @@ stdenv.mkDerivation { cmakeFlags = [ "-GNinja" "-DLauncher_QT_VERSION_MAJOR=${lib.versions.major qtbase.version}" + "-DLauncher_BUILD_PLATFORM=nix" ] ++ lib.optionals enableLTO [ "-DENABLE_LTO=on" ] ++ lib.optionals (msaClientID != "") [ "-DLauncher_MSA_CLIENT_ID=${msaClientID}" ];