2023-07-18 23:11:45 +02:00
|
|
|
{
|
2024-03-02 22:05:30 +01:00
|
|
|
pkgs,
|
|
|
|
config,
|
|
|
|
lib,
|
|
|
|
...
|
|
|
|
}:
|
|
|
|
with lib; let
|
|
|
|
cfg = config.services.minecraft.forge;
|
|
|
|
in {
|
2023-07-18 23:11:45 +02:00
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
2023-07-20 12:52:48 +02:00
|
|
|
javaPackage = mkOption {
|
|
|
|
type = types.package;
|
|
|
|
default = pkgs.jdk17;
|
|
|
|
};
|
|
|
|
|
2023-07-18 23:11:45 +02:00
|
|
|
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 = [];
|
|
|
|
};
|
2023-07-20 12:52:48 +02:00
|
|
|
|
|
|
|
extraFixup = mkOption {
|
|
|
|
type = types.lines;
|
|
|
|
default = "";
|
|
|
|
};
|
2023-07-18 23:11:45 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
config = mkIf cfg.enable {
|
2024-03-02 22:05:30 +01:00
|
|
|
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"] + " )"}
|
|
|
|
|
|
|
|
ignore=0
|
|
|
|
for ignore_path in ''${_ignore_paths[@]} ; do
|
|
|
|
if [ "''${1##ignore_path}" != "$1" ] || [ "$ignore_path" = "$1" ] ; then
|
|
|
|
ignore=1
|
|
|
|
break
|
2023-07-18 23:11:45 +02:00
|
|
|
fi
|
2024-03-02 22:05:30 +01:00
|
|
|
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
|
2023-07-18 23:11:45 +02:00
|
|
|
fi
|
2024-03-02 22:05:30 +01:00
|
|
|
done
|
2023-07-18 23:11:45 +02:00
|
|
|
|
2024-03-02 22:05:30 +01:00
|
|
|
if [ "$copy" = 1 ] ; then
|
|
|
|
cp --no-preserve=mode,ownership "${forgeFod}/$1" "$_path/$1"
|
|
|
|
else
|
|
|
|
ln -s "${forgeFod}/$1" "$_path/$1"
|
2023-07-18 23:11:45 +02:00
|
|
|
fi
|
2024-03-02 22:05:30 +01:00
|
|
|
}
|
|
|
|
export -f linkFile
|
|
|
|
|
|
|
|
echo $_path
|
|
|
|
if [ "$_path" = "" ] || ! [ -d "$_path" ] ; then
|
|
|
|
echo "invalid path"
|
|
|
|
exit 1
|
|
|
|
fi
|
2023-07-18 23:11:45 +02:00
|
|
|
|
2024-03-02 22:05:30 +01:00
|
|
|
find $_path -type l -lname '/nix/store/*' -delete
|
|
|
|
find $_path -type d -empty -delete
|
2023-07-18 23:11:45 +02:00
|
|
|
|
2024-03-02 22:05:30 +01:00
|
|
|
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"
|
2023-07-18 23:11:45 +02:00
|
|
|
|
2024-03-02 22:05:30 +01:00
|
|
|
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
|
2023-07-18 23:11:45 +02:00
|
|
|
|
2024-03-02 22:05:30 +01:00
|
|
|
# [ -f $_path/install-forge ] && bash install-forge
|
2023-07-20 12:52:48 +02:00
|
|
|
|
2024-03-02 22:05:30 +01:00
|
|
|
$_path/start.sh
|
|
|
|
''} $out/bin/server
|
|
|
|
'';
|
|
|
|
};
|
2023-07-18 23:11:45 +02:00
|
|
|
|
|
|
|
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
|
2023-07-20 12:52:48 +02:00
|
|
|
${pkgs.bash}/bin/bash -x ${cfg.serverPackage}/bin/server ${concatMapStringsSep " " (x: ''"${x}"'') cfg.extraJavaArguments}
|
2023-07-18 23:11:45 +02:00
|
|
|
'';
|
|
|
|
enabled = true;
|
|
|
|
};
|
|
|
|
|
|
|
|
assertions = [
|
2024-03-02 22:05:30 +01:00
|
|
|
{
|
|
|
|
assertion = cfg.eulaAccept;
|
2023-07-18 23:11:45 +02:00
|
|
|
message = "You must accept the EULA";
|
|
|
|
}
|
|
|
|
];
|
|
|
|
};
|
|
|
|
}
|