diff --git a/nix/hosts.nix b/nix/hosts.nix index 5c9d851e..b245074d 100644 --- a/nix/hosts.nix +++ b/nix/hosts.nix @@ -61,6 +61,8 @@ in cfg.modules.nixos.steam cfg.modules.nixos.prismlauncher cfg.modules.nixos.daily-midnight-poweroff + cfg.modules.nixos.gtnh-server + cfg.modules.nixos.gtnh-backups ( { config, diff --git a/nix/modules/gtnh-backups.nix b/nix/modules/gtnh-backups.nix new file mode 100644 index 00000000..d18946d3 --- /dev/null +++ b/nix/modules/gtnh-backups.nix @@ -0,0 +1,50 @@ +{ + config.flake.modules.nixos.gtnh-backups = + { pkgs, ... }: + let + backupDir = "/srv/gtnh-backups"; + in + { + systemd = { + tmpfiles.rules = [ "d ${backupDir} 0750 root root -" ]; + services.gtnh-backup = { + description = "Backup GTNH server"; + serviceConfig = { + Type = "oneshot"; + ExecStart = pkgs.writeShellScript "gtnh-backup" '' + set -euo pipefail + + ts="$(${pkgs.coreutils}/bin/date +%Y%m%d-%H%M%S)" + dest="${backupDir}/gtnh-$ts.tar.zst" + + echo "say Starting server backup" > /run/gtnh-server.stdin || true + echo "save-all" > /run/gtnh-server.stdin || true + ${pkgs.coreutils}/bin/sleep 10 + + ${pkgs.gnutar}/bin/tar \ + --exclude='/srv/gtnh/backups' \ + -C /srv \ + -I '${pkgs.zstd}/bin/zstd -T0 -10' \ + -cf "$dest" \ + gtnh + + ${pkgs.findutils}/bin/find ${backupDir} \ + -name 'gtnh-*.tar.zst' \ + -type f \ + -mtime +14 \ + -delete + + echo "say Server backup complete" > /run/gtnh-server.stdin || true + ''; + }; + }; + timers.gtnh-backup = { + wantedBy = [ "timers.target" ]; + timerConfig = { + OnCalendar = "03:30"; + Persistent = true; + }; + }; + }; + }; +} diff --git a/nix/modules/gtnh-server.nix b/nix/modules/gtnh-server.nix new file mode 100644 index 00000000..b53f7372 --- /dev/null +++ b/nix/modules/gtnh-server.nix @@ -0,0 +1,102 @@ +{ + config.flake.modules.nixos.gtnh-server = + { pkgs, ... }: + let + gtnhDir = "/srv/gtnh"; + java = pkgs.jdk25_headless; + stopScript = pkgs.writeShellScript "gtnh-stop" '' + set -euo pipefail + + if [ -p /run/gtnh-server.stdin ]; then + echo "stop" > /run/gtnh-server.stdin || true + fi + + timeout=120 + while kill -0 "$1" 2>/dev/null && [ "$timeout" -gt 0 ]; do + sleep 1 + timeout=$((timeout - 1)) + done + + if kill -0 "$1" 2>/dev/null; then + kill -TERM "$1" + fi + ''; + in + { + users = { + users.gtnh = { + description = "GT New Horizons server user"; + isSystemUser = true; + group = "gtnh"; + home = gtnhDir; + createHome = true; + }; + groups.gtnh = { }; + }; + systemd = { + tmpfiles.rules = [ "d ${gtnhDir} 0750 gtnh gtnh -" ]; + sockets.gtnh-server = { + bindsTo = [ "gtnh-server.service" ]; + socketConfig = { + ListenFIFO = "/run/gtnh-server.stdin"; + SocketMode = "0660"; + SocketUser = "gtnh"; + SocketGroup = "gtnh"; + RemoveOnStop = true; + FlushPending = true; + }; + }; + services.gtnh-server = { + description = "GT New Horizons 2.8.4 Server"; + wantedBy = [ "multi-user.target" ]; + requires = [ "gtnh-server.socket" ]; + after = [ + "network-online.target" + "gtnh-server.socket" + ]; + wants = [ "network-online.target" ]; + unitConfig.ConditionPathExists = [ + "${gtnhDir}/java9args.txt" + "${gtnhDir}/lwjgl3ify-forgePatches.jar" + ]; + path = [ + java + pkgs.bash + pkgs.coreutils + ]; + serviceConfig = { + User = "gtnh"; + Group = "gtnh"; + WorkingDirectory = gtnhDir; + Restart = "on-failure"; + RestartSec = "30s"; + SuccessExitStatus = "0 143"; + StandardInput = "socket"; + StandardOutput = "journal"; + StandardError = "journal"; + ExecStart = '' + ${java}/bin/java \ + -Xms6G \ + -Xmx10G \ + -XX:+UseZGC \ + -Dfml.readTimeout=180 \ + @java9args.txt \ + -jar lwjgl3ify-forgePatches.jar \ + nogui + ''; + ExecStop = "${stopScript} $MAINPID"; + UMask = "0027"; + NoNewPrivileges = true; + PrivateTmp = true; + ProtectSystem = "strict"; + ReadWritePaths = [ gtnhDir ]; + ProtectHome = true; + }; + }; + }; + networking.firewall = { + allowedTCPPorts = [ 25565 ]; + allowedUDPPorts = [ 25565 ]; + }; + }; +} diff --git a/nix/modules/prismlauncher.nix b/nix/modules/prismlauncher.nix index c2b0faee..88c01688 100644 --- a/nix/modules/prismlauncher.nix +++ b/nix/modules/prismlauncher.nix @@ -10,8 +10,13 @@ in darwin.prismlauncher = osModule; nixos.prismlauncher = osModule; homeManager.prismlauncher = - { pkgs, ... }: + { config, pkgs, ... }: { + xdg.desktopEntries.gtnh = { + name = "GregTech New Horizons"; + icon = "${config.home.homeDirectory}/.local/share/PrismLauncher/instances/GT_New_Horizons_2.8.4_Java_17-25/icon.png"; + exec = "prismlauncher --launch GT_New_Horizons_2.8.4_Java_17-25"; + }; home.packages = [ (pkgs.prismlauncher.override { jdks = [ pkgs.jdk25 ];