Add Terraria server service (#16832)

Changed files
+143
nixos
modules
misc
services
games
pkgs
games
terraria-server
+2
nixos/modules/misc/ids.nix
···
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!
···
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
+1
nixos/modules/module-list.nix
···
./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
+139
nixos/modules/services/games/terraria.nix
···
+
{ 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
+
'';
+
};
+
};
+
}
+1
pkgs/games/terraria-server/default.nix
···
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