{ lib, stdenv, fetchurl, busybox, coreutils, jre_headless, runtimeShell , mods ? null, config ? null, defaultconfigs ? null }: let name = "forge-server"; version = "1.16.5-36.1.1"; mirror = "https://files.minecraftforge.net/maven/net/minecraftforge/forge"; src = fetchurl { url = "${mirror}/${version}/forge-${version}-installer.jar"; # Forge doesn't seem to like newer shas sha1 = "78e5bd0b19f05136bb25bf3c5be9b64a1d0e850e"; }; unpackCmd = "mkdir -p src; cp $curSrc src/forge-${version}-installer.jar"; # Somewhat evil pre-install step to run through the network # dependency resolution forge needs. This is also common for gradle # projects, so I think this is ok-ish here, though ideally I'd # identify all the dependencies and package them as well. deps = stdenv.mkDerivation { name = "${name}-deps"; inherit src unpackCmd; nativeBuildInputs = [ jre_headless ]; buildPhase = '' java -jar forge-${version}-installer.jar --installServer installation ''; installPhase = '' mkdir -p $out cp -r installation/forge-${version}.jar installation/libraries $out ''; outputHashAlgo = "sha256"; outputHashMode = "recursive"; outputHash = "lV4UxmSdv/I+HwvnT8CLcHpSKyDvKnldA5/Lw1GsJ/M="; }; in stdenv.mkDerivation rec { inherit name version src unpackCmd; installPhase = '' mkdir -p $out/{bin,lib/forge} cp -rv ${deps}/* $out/lib/forge/ cat > $out/bin/forge-server << EOF #!${runtimeShell} set -eu # Delete any previous mods directory so that it can be updated ${busybox}/bin/rm -fr mods ${lib.optionalString (mods != null) '' # Copy the specified mods into the directory. Note that, sadly, # forge doesn't support symlinks here. ${busybox}/bin/mkdir -p mods ${busybox}/bin/cp -r '${mods}/mods/'*.jar mods ''} # Delete any previous config directories so that they can be updated ${busybox}/bin/rm -fr config defaultconfigs ${lib.optionalString (config != null) '' # Copy the specified configs into the directory. Forge (and # mods) will try to write here, so we cannot symlink. ${busybox}/bin/mkdir -p config ${busybox}/bin/cp -r '${config}'/* config ${busybox}/bin/chmod -R u+w config ''} ${lib.optionalString (defaultconfigs != null) '' # Copy the specified configs into the directory. Forge (and # mods) will try to write here, so we cannot symlink. ${busybox}/bin/mkdir -p defaultconfigs ${busybox}/bin/cp -r '${defaultconfigs}'/* defaultconfigs ${busybox}/bin/chmod -R u+w defaultconfigs ''} exec ${jre_headless}/bin/java \$@ -jar $out'/lib/forge/forge-${version}.jar' nogui EOF chmod +x $out/bin/forge-server ''; phases = "installPhase"; meta = with lib; { description = "Forge Minecraft Server"; homepage = "https://files.minecraftforge.net/"; # Forge itself is open source, but this package pulls in # minecraft. license = licenses.unfreeRedistributable; platforms = platforms.unix; }; }