From 429cbb217823b2fbc30ccd135fde1183afb1f87e Mon Sep 17 00:00:00 2001 From: uttarayan21 Date: Tue, 26 Aug 2025 23:39:56 +0530 Subject: [PATCH] feat(nixos): add Satisfactory Dedicated Server module --- flake.lock | 4 +- modules/nixos/satisfactory.nix | 96 +++++++++++++++++++ nixos/mirai/services/default.nix | 2 +- nixos/mirai/services/games/default.nix | 6 ++ .../mirai/services/{ => games}/minecraft.nix | 0 nixos/mirai/services/games/satisfactory.nix | 9 ++ 6 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 modules/nixos/satisfactory.nix create mode 100644 nixos/mirai/services/games/default.nix rename nixos/mirai/services/{ => games}/minecraft.nix (100%) create mode 100644 nixos/mirai/services/games/satisfactory.nix diff --git a/flake.lock b/flake.lock index dd2e3d25..e39490a3 100644 --- a/flake.lock +++ b/flake.lock @@ -3125,8 +3125,8 @@ "rust-overlay": "rust-overlay_9" }, "locked": { - "lastModified": 1756059230, - "narHash": "sha256-9xvC8WYCB/JgYvYFJMxCPY98ZHzvf3/oema6HtBTRRU=", + "lastModified": 1756198947, + "narHash": "sha256-hQPFz3smC92uFvQqMbukYDIPcYpuA7Bs6TLI9V/yeH0=", "path": "/home/servius/Projects/SpotyBooty", "type": "path" }, diff --git a/modules/nixos/satisfactory.nix b/modules/nixos/satisfactory.nix new file mode 100644 index 00000000..99d64bd0 --- /dev/null +++ b/modules/nixos/satisfactory.nix @@ -0,0 +1,96 @@ +{config, pkgs, lib, ...}: +let + cfg = config.services.satisfactory; +in +{ + options.services.satisfactory = { + enable = lib.mkEnableOption "Enable Satisfactory Dedicated Server"; + + beta = lib.mkOption { + type = lib.types.enum [ "public" "experimental" ]; + default = "public"; + description = "Beta channel to follow"; + }; + + address = lib.mkOption { + type = lib.types.str; + default = "0.0.0.0"; + description = "Bind address"; + }; + + maxPlayers = lib.mkOption { + type = lib.types.number; + default = 4; + description = "Number of players"; + }; + + autoPause = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Auto pause when no players are online"; + }; + + autoSaveOnDisconnect = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Auto save on player disconnect"; + }; + + extraSteamCmdArgs = lib.mkOption { + type = lib.types.str; + default = ""; + description = "Extra arguments passed to steamcmd command"; + }; + }; + config = lib.mkIf cfg.enable { + users.users.satisfactory = { + home = "/var/lib/satisfactory"; + createHome = true; + isSystemUser = true; + group = "satisfactory"; + }; + users.groups.satisfactory = {}; + + nixpkgs.config.allowUnfree = true; + + networking = { + firewall = { + allowedUDPPorts = [ 15777 15000 7777 27015 ]; + allowedUDPPortRanges = [ { from = 27031; to = 27036; } ]; + allowedTCPPorts = [ 27015 27036 ]; + }; + }; + + systemd.services.satisfactory = { + wantedBy = [ "multi-user.target" ]; + preStart = '' + ${pkgs.steamcmd}/bin/steamcmd \ + +force_install_dir /var/lib/satisfactory/SatisfactoryDedicatedServer \ + +login anonymous \ + +app_update 1690800 \ + -beta ${cfg.beta} \ + ${cfg.extraSteamCmdArgs} \ + validate \ + +quit + ${pkgs.patchelf}/bin/patchelf --set-interpreter ${pkgs.glibc}/lib/ld-linux-x86-64.so.2 /var/lib/satisfactory/SatisfactoryDedicatedServer/Engine/Binaries/Linux/UnrealServer-Linux-Shipping + ln -sfv /var/lib/satisfactory/.steam/steam/linux64 /var/lib/satisfactory/.steam/sdk64 + mkdir -p /var/lib/satisfactory/SatisfactoryDedicatedServer/FactoryGame/Saved/Config/LinuxServer + ${pkgs.crudini}/bin/crudini --set /var/lib/satisfactory/SatisfactoryDedicatedServer/FactoryGame/Saved/Config/LinuxServer/Game.ini '/Script/Engine.GameSession' MaxPlayers ${toString cfg.maxPlayers} + ${pkgs.crudini}/bin/crudini --set /var/lib/satisfactory/SatisfactoryDedicatedServer/FactoryGame/Saved/Config/LinuxServer/ServerSettings.ini '/Script/FactoryGame.FGServerSubsystem' mAutoPause ${if cfg.autoPause then "True" else "False"} + ${pkgs.crudini}/bin/crudini --set /var/lib/satisfactory/SatisfactoryDedicatedServer/FactoryGame/Saved/Config/LinuxServer/ServerSettings.ini '/Script/FactoryGame.FGServerSubsystem' mAutoSaveOnDisconnect ${if cfg.autoSaveOnDisconnect then "True" else "False"} + ''; + script = '' + /var/lib/satisfactory/SatisfactoryDedicatedServer/Engine/Binaries/Linux/UnrealServer-Linux-Shipping FactoryGame -multihome=${cfg.address} + ''; + serviceConfig = { + Restart = "always"; + User = "satisfactory"; + Group = "satisfactory"; + WorkingDirectory = "/var/lib/satisfactory"; + }; + environment = { + LD_LIBRARY_PATH="SatisfactoryDedicatedServer/linux64:SatisfactoryDedicatedServer/Engine/Binaries/Linux:SatisfactoryDedicatedServer/Engine/Binaries/ThirdParty/PhysX3/Linux/x86_64-unknown-linux-gnu"; + }; + }; + }; +} diff --git a/nixos/mirai/services/default.nix b/nixos/mirai/services/default.nix index f35b14ff..e3913b55 100644 --- a/nixos/mirai/services/default.nix +++ b/nixos/mirai/services/default.nix @@ -11,13 +11,13 @@ ./immich.nix ./llama.nix ./lldap.nix - ./minecraft.nix ./nextcloud.nix ./prowlarr.nix ./resolved.nix ./searxng.nix ./sigmabot.nix ./tailscale.nix + ./games # ./paperless.nix ]; services = { diff --git a/nixos/mirai/services/games/default.nix b/nixos/mirai/services/games/default.nix new file mode 100644 index 00000000..ed85cd3f --- /dev/null +++ b/nixos/mirai/services/games/default.nix @@ -0,0 +1,6 @@ +{...}: { + imports = [ + ./minecraft.nix + ./satisfactory.nix + ]; +} diff --git a/nixos/mirai/services/minecraft.nix b/nixos/mirai/services/games/minecraft.nix similarity index 100% rename from nixos/mirai/services/minecraft.nix rename to nixos/mirai/services/games/minecraft.nix diff --git a/nixos/mirai/services/games/satisfactory.nix b/nixos/mirai/services/games/satisfactory.nix new file mode 100644 index 00000000..bf109e81 --- /dev/null +++ b/nixos/mirai/services/games/satisfactory.nix @@ -0,0 +1,9 @@ +{...}: { + imports = [ + ../../../../modules/nixos/satisfactory.nix + ]; + services.satisfactory = { + enable = true; + maxPlayers = 4; + }; +}