diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix index 3ba279f597da..83b47728639c 100644 --- a/nixos/modules/misc/ids.nix +++ b/nixos/modules/misc/ids.nix @@ -273,6 +273,7 @@ smokeping = 250; gocd-agent = 251; gocd-server = 252; + terraria = 253; # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! @@ -516,6 +517,7 @@ smokeping = 250; gocd-agent = 251; gocd-server = 252; + terraria = 253; # When adding a gid, make sure it doesn't match an existing # uid. Users and groups with the same name should have equal diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 6a6730856b15..03a191c72321 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -174,6 +174,7 @@ ./services/games/ghost-one.nix ./services/games/minecraft-server.nix ./services/games/minetest-server.nix + ./services/games/terraria.nix ./services/hardware/acpid.nix ./services/hardware/actkbd.nix ./services/hardware/amd-hybrid-graphics.nix diff --git a/nixos/modules/services/games/terraria.nix b/nixos/modules/services/games/terraria.nix new file mode 100644 index 000000000000..57ac37bb1bd3 --- /dev/null +++ b/nixos/modules/services/games/terraria.nix @@ -0,0 +1,139 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.terraria; + worldSizeMap = { "small" = 1; "medium" = 2; "large" = 3; }; + valFlag = name: val: optionalString (val != null) "-${name} \"${escape ["\\" "\""] (toString val)}\""; + boolFlag = name: val: optionalString val "-${name}"; + flags = [ + (valFlag "port" cfg.port) + (valFlag "maxPlayers" cfg.maxPlayers) + (valFlag "password" cfg.password) + (valFlag "motd" cfg.messageOfTheDay) + (valFlag "world" cfg.worldPath) + (valFlag "autocreate" (builtins.getAttr cfg.autoCreatedWorldSize worldSizeMap)) + (valFlag "banlist" cfg.banListPath) + (boolFlag "secure" cfg.secure) + (boolFlag "noupnp" cfg.noUPnP) + ]; +in +{ + options = { + services.terraria = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + If enabled, starts a Terraria server. The server can be connected to via tmux -S /var/lib/terraria/terraria.sock attach + for administration by users who are a part of the terraria group (use C-b d shortcut to detach again). + ''; + }; + + port = mkOption { + type = types.int; + default = 7777; + description = '' + Specifies the port to listen on. + ''; + }; + + maxPlayers = mkOption { + type = types.int; + default = 255; + description = '' + Sets the max number of players (between 1 and 255). + ''; + }; + + password = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Sets the server password. Leave null for no password. + ''; + }; + + messageOfTheDay = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Set the server message of the day text. + ''; + }; + + worldPath = mkOption { + type = types.path; + default = null; + description = '' + The path to the world file (.wld) which should be loaded. + If no world exists at this path, one will be created with the size + specified by autoCreatedWorldSize. + ''; + }; + + autoCreatedWorldSize = mkOption { + type = types.enum [ "small" "medium" "large" ]; + default = "medium"; + description = '' + Specifies the size of the auto-created world if worldPath does not + point to an existing world. + ''; + }; + + banListPath = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + The path to the ban list. + ''; + }; + + secure = mkOption { + type = types.bool; + default = false; + description = "Adds additional cheat protection to the server."; + }; + + noUPnP = mkOption { + type = types.bool; + default = false; + description = "Disables automatic Universal Plug and Play."; + }; + }; + }; + + config = mkIf cfg.enable { + users.extraUsers.terraria = { + description = "Terraria server service user"; + home = "/var/lib/terraria"; + createHome = true; + uid = config.ids.uids.terraria; + }; + + users.extraGroups.terraria = { + gid = config.ids.gids.terraria; + members = [ "terraria" ]; + }; + + systemd.services.terraria = { + description = "Terraria Server Service"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + serviceConfig = { + User = "terraria"; + Type = "oneshot"; + RemainAfterExit = true; + ExecStart = "${pkgs.tmux.bin}/bin/tmux -S /var/lib/terraria/terraria.sock new -d ${pkgs.terraria-server}/bin/TerrariaServer ${concatStringsSep " " flags}"; + ExecStop = "${pkgs.tmux.bin}/bin/tmux -S /var/lib/terraria/terraria.sock send-keys Enter \"exit\" Enter"; + }; + + postStart = '' + ${pkgs.coreutils}/bin/chmod 660 /var/lib/terraria/terraria.sock + ${pkgs.coreutils}/bin/chgrp terraria /var/lib/terraria/terraria.sock + ''; + }; + }; +} diff --git a/pkgs/games/terraria-server/default.nix b/pkgs/games/terraria-server/default.nix index 59dabf2f9cde..5fcb5063bbc8 100644 --- a/pkgs/games/terraria-server/default.nix +++ b/pkgs/games/terraria-server/default.nix @@ -16,6 +16,7 @@ stdenv.mkDerivation rec { installPhase = '' mkdir -p $out/bin cp -r Linux $out/ + chmod +x "$out/Linux/TerrariaServer.bin.x86_64" ln -s "$out/Linux/TerrariaServer.bin.x86_64" $out/bin/TerrariaServer # Fix "/lib64/ld-linux-x86-64.so.2" like references in ELF executables. find "$out" | while read filepath; do