summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--nixos/modules/misc/ids.nix2
-rw-r--r--nixos/modules/module-list.nix1
-rw-r--r--nixos/modules/services/games/terraria.nix139
-rw-r--r--pkgs/games/terraria-server/default.nix1
4 files changed, 143 insertions, 0 deletions
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix
index 3ba279f597d..83b47728639 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 6a6730856b1..03a191c7232 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 00000000000..57ac37bb1bd
--- /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 <literal>tmux -S /var/lib/terraria/terraria.sock attach</literal>
+          for administration by users who are a part of the <literal>terraria</literal> group (use <literal>C-b d</literal> 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 <literal>null</literal> 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 (<literal>.wld</literal>) which should be loaded.
+          If no world exists at this path, one will be created with the size
+          specified by <literal>autoCreatedWorldSize</literal>.
+        '';
+      };
+
+      autoCreatedWorldSize = mkOption {
+        type        = types.enum [ "small" "medium" "large" ];
+        default     = "medium";
+        description = ''
+          Specifies the size of the auto-created world if <literal>worldPath</literal> 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 59dabf2f9cd..5fcb5063bbc 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