Loading pkgs/by-name/hm/hmcl/0002-nix-use-terracotta-from-nix.patch 0 → 100644 +43 −0 Original line number Diff line number Diff line From 541d055bf55703aa9e2c5a5e04a397f1d25efe28 Mon Sep 17 00:00:00 2001 From: Moraxyc <i@qaq.li> Date: Wed, 29 Oct 2025 00:09:56 +0800 Subject: [PATCH 2/3] nix: use terracotta from nix --- .../org/jackhuang/hmcl/terracotta/TerracottaNative.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/terracotta/TerracottaNative.java b/HMCL/src/main/java/org/jackhuang/hmcl/terracotta/TerracottaNative.java index 079537978..68954b09e 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/terracotta/TerracottaNative.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/terracotta/TerracottaNative.java @@ -47,7 +47,7 @@ public final class TerracottaNative { public TerracottaNative(List<URI> links, Path path, FileDownloadTask.IntegrityCheck checking) { this.links = links; - this.path = path; + this.path = Path.of("@TERRACOTTA_BIN@"); this.checking = checking; } @@ -130,9 +130,7 @@ public final class TerracottaNative { public ITerracottaProvider.Status status() throws IOException { if (Files.exists(path)) { - if (DigestUtils.digestToString(checking.getAlgorithm(), path).equalsIgnoreCase(checking.getChecksum())) { - return ITerracottaProvider.Status.READY; - } + return ITerracottaProvider.Status.READY; } try { @@ -144,4 +142,4 @@ public final class TerracottaNative { } return ITerracottaProvider.Status.NOT_EXIST; } -} +} \ No newline at end of file -- 2.51.0 pkgs/by-name/hm/hmcl/0003-nix-skip-terracotta-existence-check-on-darwin.patch 0 → 100644 +27 −0 Original line number Diff line number Diff line From bcf95a23380424f2ca82649d93e9e0bdf8274b74 Mon Sep 17 00:00:00 2001 From: Moraxyc <i@qaq.li> Date: Fri, 31 Oct 2025 14:23:54 +0800 Subject: [PATCH 3/3] nix: skip terracotta existence check on darwin --- .../org/jackhuang/hmcl/terracotta/provider/MacOSProvider.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/terracotta/provider/MacOSProvider.java b/HMCL/src/main/java/org/jackhuang/hmcl/terracotta/provider/MacOSProvider.java index 00626f8b6..59125962d 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/terracotta/provider/MacOSProvider.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/terracotta/provider/MacOSProvider.java @@ -45,10 +45,6 @@ public final class MacOSProvider implements ITerracottaProvider { public Status status() throws IOException { assert binary != null; - if (!Files.exists(Path.of("/Applications/terracotta.app"))) { - return Status.NOT_EXIST; - } - return binary.status(); } -- 2.51.0 pkgs/by-name/hm/hmcl/package.nix +74 −13 Original line number Diff line number Diff line Loading @@ -2,18 +2,25 @@ lib, stdenv, fetchurl, replaceVars, terracotta, makeDesktopItem, wrapGAppsHook3, copyDesktopItems, imagemagick, jdk, jdk17, jdk21, hmclJdk ? jdk, hmclJdk ? jdk.override { # Required by jar file enableJavaFX = true; }, buildPackages, hmclJdkBuild ? buildPackages.jdk.override { enableJavaFX = true; }, minecraftJdks ? [ jdk hmclJdk jdk17 jdk21 ], xorg, glib, Loading Loading @@ -45,8 +52,63 @@ stdenv.mkDerivation (finalAttrs: { hash = "sha256-1OVq4ujA2ZHboB7zEk7004kYgl9YcoM4qLq154MZMGo="; }; # - HMCL prompts users to download prebuilt Terracotta binary for # multi-user functionality, which is messy and doesn’t work on NixOS. # - Building from source isn’t feasible because HMCL’s code relies on # Microsoft OAuth, CurseForge, and other API keys that upstream doesn’t # allow in custom builds, causing features to break. # - Our workaround is to compile only the Java files that handle # Terracotta downloads, package them into a patch jar that overrides # the original classes, and have it load the original jar. This preserves # the original jar’s integrity check and avoids modifying the upstream jar. terracottaNativeJava = fetchurl { name = "hmcl-terracotta-native-java-${finalAttrs.version}"; url = "https://raw.githubusercontent.com/HMCL-dev/HMCL/v${finalAttrs.version}/${finalAttrs.terracottaNativeJavaPath}"; hash = "sha256-sg8gBOMNdITmHeYByYriYp05ja1vtWPF/wuqdGmkgiA="; }; macOSProviderJava = fetchurl { name = "hmcl-macos-provider-java-${finalAttrs.version}"; url = "https://raw.githubusercontent.com/HMCL-dev/HMCL/v${finalAttrs.version}/${finalAttrs.macOSProviderJavaPath}"; hash = "sha256-V8FNPPkq6/P3/HKcqKkAy6Ya1kUI3oEMfjEc8XdExgo="; }; terracottaNativeJavaPath = "HMCL/src/main/java/org/jackhuang/hmcl/terracotta/TerracottaNative.java"; macOSProviderJavaPath = "HMCL/src/main/java/org/jackhuang/hmcl/terracotta/provider/MacOSProvider.java"; dontUnpack = true; prePatch = '' install -Dm644 $terracottaNativeJava $terracottaNativeJavaPath install -Dm644 $macOSProviderJava $macOSProviderJavaPath ''; patches = [ (replaceVars ./0002-nix-use-terracotta-from-nix.patch { TERRACOTTA_BIN = lib.getExe terracotta; }) ./0003-nix-skip-terracotta-existence-check-on-darwin.patch ]; buildPhase = '' runHook preBuild # Build only classes we modified javac -cp $src -d out $terracottaNativeJavaPath $macOSProviderJavaPath # Extract MANIFEST.MF from original jar # We need Main-Class, Add-Opens, etc jar xf $src META-INF/MANIFEST.MF # Remove last empty line; otherwise file is invalid sed -i '/^[[:space:]]*$/d' META-INF/MANIFEST.MF # Let our patch jar be the entrace and load hmcl.jar echo "Class-Path: $out/lib/hmcl/hmcl.jar" >> META-INF/MANIFEST.MF # Package our patch jar # Reserve link to terracotta by not applying zip; nix cannot detect path from zipped jar jar cvf0m patch.jar META-INF/MANIFEST.MF -C out . runHook postBuild ''; dontWrapGApps = true; desktopItems = [ Loading @@ -65,6 +127,7 @@ stdenv.mkDerivation (finalAttrs: { wrapGAppsHook3 copyDesktopItems imagemagick hmclJdkBuild ]; installPhase = '' Loading @@ -72,6 +135,7 @@ stdenv.mkDerivation (finalAttrs: { mkdir -p $out/{bin,lib/hmcl} cp $src $out/lib/hmcl/hmcl.jar cp patch.jar $out/lib/hmcl/hmcl-terracotta-patch.jar for n in 16 32 48 64 96 128 256 do Loading Loading @@ -106,15 +170,12 @@ stdenv.mkDerivation (finalAttrs: { alsa-lib ] ); hmclJdk' = hmclJdk.override { enableJavaFX = true; # Necessary for hardware acceleration. }; in '' runHook preFixup makeBinaryWrapper ${hmclJdk'}/bin/java $out/bin/hmcl \ --add-flags "-jar $out/lib/hmcl/hmcl.jar" \ makeBinaryWrapper ${hmclJdk}/bin/java $out/bin/hmcl \ --add-flags "-jar $out/lib/hmcl/hmcl-terracotta-patch.jar" \ --set LD_LIBRARY_PATH ${libpath} \ --prefix PATH : "${lib.makeBinPath minecraftJdks}"\ ''${gappsWrapperArgs[@]} Loading @@ -129,15 +190,15 @@ stdenv.mkDerivation (finalAttrs: { description = "Minecraft Launcher which is multi-functional, cross-platform and popular"; changelog = "https://docs.hmcl.net/changelog/stable.html"; mainProgram = "hmcl"; sourceProvenance = with lib.sourceTypes; [ binaryBytecode ]; sourceProvenance = with lib.sourceTypes; [ fromSource # Our patch jar is built from source binaryBytecode ]; license = lib.licenses.gpl3Only; longDescription = '' Hello Minecraft! Launcher (HMCL) is a free, open-source, and cross-platform Minecraft launcher. It provides comprehensive support for managing multiple game versions and mod loaders, including Forge, NeoForge, Fabric, Quilt, LiteLoader, and OptiFine. Note: HMCL manages the Terracotta binary internally. On NixOS, Terracotta-related features require `programs.nix-ld` to be enabled, as the runtime-downloaded binary is not patched. ''; maintainers = with lib.maintainers; [ daru-san Loading pkgs/by-name/hm/hmcl/update.nix +2 −0 Original line number Diff line number Diff line Loading @@ -36,5 +36,7 @@ writeShellApplication { nix-update hmcl --version="$version" update-source-version hmcl --source-key=icon --ignore-same-version update-source-version hmcl --source-key=terracottaNativeJava --ignore-same-version update-source-version hmcl --source-key=macOSProviderJava --ignore-same-version ''; } Loading
pkgs/by-name/hm/hmcl/0002-nix-use-terracotta-from-nix.patch 0 → 100644 +43 −0 Original line number Diff line number Diff line From 541d055bf55703aa9e2c5a5e04a397f1d25efe28 Mon Sep 17 00:00:00 2001 From: Moraxyc <i@qaq.li> Date: Wed, 29 Oct 2025 00:09:56 +0800 Subject: [PATCH 2/3] nix: use terracotta from nix --- .../org/jackhuang/hmcl/terracotta/TerracottaNative.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/terracotta/TerracottaNative.java b/HMCL/src/main/java/org/jackhuang/hmcl/terracotta/TerracottaNative.java index 079537978..68954b09e 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/terracotta/TerracottaNative.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/terracotta/TerracottaNative.java @@ -47,7 +47,7 @@ public final class TerracottaNative { public TerracottaNative(List<URI> links, Path path, FileDownloadTask.IntegrityCheck checking) { this.links = links; - this.path = path; + this.path = Path.of("@TERRACOTTA_BIN@"); this.checking = checking; } @@ -130,9 +130,7 @@ public final class TerracottaNative { public ITerracottaProvider.Status status() throws IOException { if (Files.exists(path)) { - if (DigestUtils.digestToString(checking.getAlgorithm(), path).equalsIgnoreCase(checking.getChecksum())) { - return ITerracottaProvider.Status.READY; - } + return ITerracottaProvider.Status.READY; } try { @@ -144,4 +142,4 @@ public final class TerracottaNative { } return ITerracottaProvider.Status.NOT_EXIST; } -} +} \ No newline at end of file -- 2.51.0
pkgs/by-name/hm/hmcl/0003-nix-skip-terracotta-existence-check-on-darwin.patch 0 → 100644 +27 −0 Original line number Diff line number Diff line From bcf95a23380424f2ca82649d93e9e0bdf8274b74 Mon Sep 17 00:00:00 2001 From: Moraxyc <i@qaq.li> Date: Fri, 31 Oct 2025 14:23:54 +0800 Subject: [PATCH 3/3] nix: skip terracotta existence check on darwin --- .../org/jackhuang/hmcl/terracotta/provider/MacOSProvider.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/terracotta/provider/MacOSProvider.java b/HMCL/src/main/java/org/jackhuang/hmcl/terracotta/provider/MacOSProvider.java index 00626f8b6..59125962d 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/terracotta/provider/MacOSProvider.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/terracotta/provider/MacOSProvider.java @@ -45,10 +45,6 @@ public final class MacOSProvider implements ITerracottaProvider { public Status status() throws IOException { assert binary != null; - if (!Files.exists(Path.of("/Applications/terracotta.app"))) { - return Status.NOT_EXIST; - } - return binary.status(); } -- 2.51.0
pkgs/by-name/hm/hmcl/package.nix +74 −13 Original line number Diff line number Diff line Loading @@ -2,18 +2,25 @@ lib, stdenv, fetchurl, replaceVars, terracotta, makeDesktopItem, wrapGAppsHook3, copyDesktopItems, imagemagick, jdk, jdk17, jdk21, hmclJdk ? jdk, hmclJdk ? jdk.override { # Required by jar file enableJavaFX = true; }, buildPackages, hmclJdkBuild ? buildPackages.jdk.override { enableJavaFX = true; }, minecraftJdks ? [ jdk hmclJdk jdk17 jdk21 ], xorg, glib, Loading Loading @@ -45,8 +52,63 @@ stdenv.mkDerivation (finalAttrs: { hash = "sha256-1OVq4ujA2ZHboB7zEk7004kYgl9YcoM4qLq154MZMGo="; }; # - HMCL prompts users to download prebuilt Terracotta binary for # multi-user functionality, which is messy and doesn’t work on NixOS. # - Building from source isn’t feasible because HMCL’s code relies on # Microsoft OAuth, CurseForge, and other API keys that upstream doesn’t # allow in custom builds, causing features to break. # - Our workaround is to compile only the Java files that handle # Terracotta downloads, package them into a patch jar that overrides # the original classes, and have it load the original jar. This preserves # the original jar’s integrity check and avoids modifying the upstream jar. terracottaNativeJava = fetchurl { name = "hmcl-terracotta-native-java-${finalAttrs.version}"; url = "https://raw.githubusercontent.com/HMCL-dev/HMCL/v${finalAttrs.version}/${finalAttrs.terracottaNativeJavaPath}"; hash = "sha256-sg8gBOMNdITmHeYByYriYp05ja1vtWPF/wuqdGmkgiA="; }; macOSProviderJava = fetchurl { name = "hmcl-macos-provider-java-${finalAttrs.version}"; url = "https://raw.githubusercontent.com/HMCL-dev/HMCL/v${finalAttrs.version}/${finalAttrs.macOSProviderJavaPath}"; hash = "sha256-V8FNPPkq6/P3/HKcqKkAy6Ya1kUI3oEMfjEc8XdExgo="; }; terracottaNativeJavaPath = "HMCL/src/main/java/org/jackhuang/hmcl/terracotta/TerracottaNative.java"; macOSProviderJavaPath = "HMCL/src/main/java/org/jackhuang/hmcl/terracotta/provider/MacOSProvider.java"; dontUnpack = true; prePatch = '' install -Dm644 $terracottaNativeJava $terracottaNativeJavaPath install -Dm644 $macOSProviderJava $macOSProviderJavaPath ''; patches = [ (replaceVars ./0002-nix-use-terracotta-from-nix.patch { TERRACOTTA_BIN = lib.getExe terracotta; }) ./0003-nix-skip-terracotta-existence-check-on-darwin.patch ]; buildPhase = '' runHook preBuild # Build only classes we modified javac -cp $src -d out $terracottaNativeJavaPath $macOSProviderJavaPath # Extract MANIFEST.MF from original jar # We need Main-Class, Add-Opens, etc jar xf $src META-INF/MANIFEST.MF # Remove last empty line; otherwise file is invalid sed -i '/^[[:space:]]*$/d' META-INF/MANIFEST.MF # Let our patch jar be the entrace and load hmcl.jar echo "Class-Path: $out/lib/hmcl/hmcl.jar" >> META-INF/MANIFEST.MF # Package our patch jar # Reserve link to terracotta by not applying zip; nix cannot detect path from zipped jar jar cvf0m patch.jar META-INF/MANIFEST.MF -C out . runHook postBuild ''; dontWrapGApps = true; desktopItems = [ Loading @@ -65,6 +127,7 @@ stdenv.mkDerivation (finalAttrs: { wrapGAppsHook3 copyDesktopItems imagemagick hmclJdkBuild ]; installPhase = '' Loading @@ -72,6 +135,7 @@ stdenv.mkDerivation (finalAttrs: { mkdir -p $out/{bin,lib/hmcl} cp $src $out/lib/hmcl/hmcl.jar cp patch.jar $out/lib/hmcl/hmcl-terracotta-patch.jar for n in 16 32 48 64 96 128 256 do Loading Loading @@ -106,15 +170,12 @@ stdenv.mkDerivation (finalAttrs: { alsa-lib ] ); hmclJdk' = hmclJdk.override { enableJavaFX = true; # Necessary for hardware acceleration. }; in '' runHook preFixup makeBinaryWrapper ${hmclJdk'}/bin/java $out/bin/hmcl \ --add-flags "-jar $out/lib/hmcl/hmcl.jar" \ makeBinaryWrapper ${hmclJdk}/bin/java $out/bin/hmcl \ --add-flags "-jar $out/lib/hmcl/hmcl-terracotta-patch.jar" \ --set LD_LIBRARY_PATH ${libpath} \ --prefix PATH : "${lib.makeBinPath minecraftJdks}"\ ''${gappsWrapperArgs[@]} Loading @@ -129,15 +190,15 @@ stdenv.mkDerivation (finalAttrs: { description = "Minecraft Launcher which is multi-functional, cross-platform and popular"; changelog = "https://docs.hmcl.net/changelog/stable.html"; mainProgram = "hmcl"; sourceProvenance = with lib.sourceTypes; [ binaryBytecode ]; sourceProvenance = with lib.sourceTypes; [ fromSource # Our patch jar is built from source binaryBytecode ]; license = lib.licenses.gpl3Only; longDescription = '' Hello Minecraft! Launcher (HMCL) is a free, open-source, and cross-platform Minecraft launcher. It provides comprehensive support for managing multiple game versions and mod loaders, including Forge, NeoForge, Fabric, Quilt, LiteLoader, and OptiFine. Note: HMCL manages the Terracotta binary internally. On NixOS, Terracotta-related features require `programs.nix-ld` to be enabled, as the runtime-downloaded binary is not patched. ''; maintainers = with lib.maintainers; [ daru-san Loading
pkgs/by-name/hm/hmcl/update.nix +2 −0 Original line number Diff line number Diff line Loading @@ -36,5 +36,7 @@ writeShellApplication { nix-update hmcl --version="$version" update-source-version hmcl --source-key=icon --ignore-same-version update-source-version hmcl --source-key=terracottaNativeJava --ignore-same-version update-source-version hmcl --source-key=macOSProviderJava --ignore-same-version ''; }