dotfiles/nixng/modules/minecraft-forge.nix
Magic_RB c949d4638a
Attempt to make Forge install succeed for newer MC server versions
Signed-off-by: Magic_RB <magic_rb@redalder.org>
2023-07-27 21:05:20 +02:00

187 lines
5.4 KiB
Nix

{ pkgs, config, lib, ... }:
with lib;
let
cfg = config.services.minecraft.forge;
in
{
options.services.minecraft.forge = {
enable = mkEnableOption "Enable Minecraft server service.";
modpackId = mkOption {
type = types.int;
};
versionId = mkOption {
type = types.int;
};
modpacksChHash = mkOption {
type = types.str;
};
javaPackage = mkOption {
type = types.package;
default = pkgs.jdk17;
};
serverPackage = mkOption {
type = types.package;
readOnly = true;
};
eulaAccept = mkOption {
type = with types; bool;
description = ''
By changing the setting below to true you are indicating your agreement to Mojang's EULA (https://account.mojang.com/documents/minecraft_eula).
'';
default = false;
};
extraJavaArguments = mkOption {
type = with types; listOf str;
default = [];
};
extraFixup = mkOption {
type = types.lines;
default = "";
};
};
config = mkIf cfg.enable {
services.minecraft.forge.serverPackage =
let
forgeFod =
pkgs.stdenv.mkDerivation {
pname = "minecraft";
version = "unknown";
outputHashMode = "recursive";
outputHashAlgo = "sha256";
outputHash = cfg.modpacksChHash;
buildInputs = with pkgs; [ unzip curl which cacert ];
phases = [ "fetchPhase" "installPhase" "fixupPhase "];
fetchPhase = ''
curl https://api.modpacks.ch/public/modpack/${toString cfg.modpackId}/${toString cfg.versionId}/server/linux -o modpacks.ch # fuck creeperhost
chmod +x modpacks.ch
'';
installPhase = ''
mkdir ebin $out
cat > ebin/java <<EOF
#!$(which sh)
echo "cd \$PWD && java \$@" > install-forge
EOF
chmod +x ebin/java
export PATH=$PWD/ebin:$PATH
./modpacks.ch ${toString cfg.modpackId} ${toString cfg.versionId} --nojava --path $out --verbose
'';
fixupPhase = ''
# delete useless non-reproducible data that we really don't need. A less "shotgun" cleaning is possible
rm $out/version.json
${cfg.extraFixup}
'';
};
in
pkgs.stdenv.mkDerivation {
pname = "minecraft";
version = "unknown";
phases = [ "installPhase" ];
installPhase = ''
mkdir -p $out/bin
cp ${pkgs.writeShellScript "server.sh" ''
export PATH=${makeBinPath (with pkgs; [ coreutils findutils bash cfg.javaPackage ])}:$PATH
export _path=$PWD
echo $0
echo $rw_paths
function linkFile()
{
_rw_paths=${"( " + lib.concatMapStringsSep " " (x: ''"${x}"'') [ "config" "modpack/gamemodes.json" ] + " )"}
_ignore_paths=${"( " + lib.concatMapStringsSep " " (x: ''"${x}"'') [ "start.sh" ] + " )"}
echo $1 | grep MrTJP
ignore=0
for ignore_path in ''${_ignore_paths[@]} ; do
if [ "''${1##ignore_path}" != "$1" ] || [ "$ignore_path" = "$1" ] ; then
ignore=1
break
fi
done
if [ -f "$1" ] || [ $ignore = 1 ] ; then
return
fi
mkdir -p "$_path/$(dirname "$1")"
copy=0
for rw_path in ''${_rw_paths[@]} ; do
if [ "''${1##$rw_path}" != "$1" ] || [ "$rw_path" = "$1" ] ; then
copy=1
break
fi
done
if [ "$copy" = 1 ] ; then
cp --no-preserve=mode,ownership "${forgeFod}/$1" "$_path/$1"
else
ln -s "${forgeFod}/$1" "$_path/$1"
fi
}
export -f linkFile
echo $_path
if [ "$_path" = "" ] || ! [ -d "$_path" ] ; then
echo "invalid path"
exit 1
fi
find $_path -type l -lname '/nix/store/*' -delete
find $_path -type d -empty -delete
find ${forgeFod} -type f -printf '%P\n' | tr '\n' '\0' | xargs -0 -I {} sh -c 'linkFile "$1"' sh {} # mkdir -p "$_path/$(dirname "$1")" ; ln -s "${forgeFod}/$1" "$_path/$1"
ln -s ${pkgs.writeShellScript "start.sh" ''
${lib.getExe cfg.javaPackage} $(cat ${forgeFod}/start.sh | grep -e "java" -e jar | sed 's/^"java" \(.*\) -jar .*$/\1/') "$@" -jar forge-*.jar
''} $_path/start.sh
# [ -f $_path/install-forge ] && bash install-forge
$_path/start.sh
''} $out/bin/server
'';
};
init.services.minecraft-forge = {
script = pkgs.writeShellScript "minecraft-run" ''
set -xe
mkdir -p /var/lib/minecraft/forge
cd /var/lib/minecraft/forge
echo "eula=true" > eula.txt
${pkgs.bash}/bin/bash -x ${cfg.serverPackage}/bin/server ${concatMapStringsSep " " (x: ''"${x}"'') cfg.extraJavaArguments}
'';
enabled = true;
};
assertions = [
{ assertion = cfg.eulaAccept;
message = "You must accept the EULA";
}
];
};
}