···
8
+
cfg = config.services.xonotic;
10
+
serverCfg = pkgs.writeText "xonotic-server.cfg" (
11
+
toString cfg.prependConfig
13
+
+ builtins.concatStringsSep "\n" (
14
+
lib.mapAttrsToList (key: option:
16
+
escape = s: lib.escape [ "\"" ] s;
17
+
quote = s: "\"${s}\"";
19
+
toValue = x: quote (escape (toString x));
21
+
value = (if lib.isList option then
22
+
builtins.concatStringsSep
24
+
(builtins.map (x: toValue x) option)
33
+
+ toString cfg.appendConfig
38
+
options.services.xonotic = {
39
+
enable = lib.mkEnableOption (lib.mdDoc "Xonotic dedicated server");
41
+
package = lib.mkPackageOption pkgs "xonotic-dedicated" {};
43
+
openFirewall = lib.mkOption {
44
+
type = lib.types.bool;
46
+
description = lib.mdDoc ''
47
+
Open the firewall for TCP and UDP on the specified port.
51
+
dataDir = lib.mkOption {
52
+
type = lib.types.path;
54
+
default = "/var/lib/xonotic";
55
+
description = lib.mdDoc ''
60
+
settings = lib.mkOption {
61
+
description = lib.mdDoc ''
62
+
Generates the `server.cfg` file. Refer to [upstream's example][0] for
65
+
[0]: https://gitlab.com/xonotic/xonotic/-/blob/master/server/server.cfg
68
+
type = lib.types.submodule {
69
+
freeformType = with lib.types; let
70
+
scalars = oneOf [ singleLineStr int float ];
72
+
attrsOf (oneOf [ scalars (nonEmptyListOf scalars) ]);
74
+
options.sv_public = lib.mkOption {
75
+
type = lib.types.int;
77
+
example = [ (-1) 1 ];
78
+
description = lib.mdDoc ''
79
+
Controls whether the server will be publicly listed.
83
+
options.hostname = lib.mkOption {
84
+
type = lib.types.singleLineStr;
85
+
default = "Xonotic $g_xonoticversion Server";
86
+
description = lib.mdDoc ''
87
+
The name that will appear in the server list. `$g_xonoticversion`
88
+
gets replaced with the current version.
92
+
options.sv_motd = lib.mkOption {
93
+
type = lib.types.singleLineStr;
95
+
description = lib.mdDoc ''
96
+
Text displayed when players join the server.
100
+
options.sv_termsofservice_url = lib.mkOption {
101
+
type = lib.types.singleLineStr;
103
+
description = lib.mdDoc ''
104
+
URL for the Terms of Service for playing on your server.
108
+
options.maxplayers = lib.mkOption {
109
+
type = lib.types.int;
111
+
description = lib.mdDoc ''
112
+
Number of player slots on the server, including spectators.
116
+
options.net_address = lib.mkOption {
117
+
type = lib.types.singleLineStr;
118
+
default = "0.0.0.0";
119
+
description = lib.mdDoc ''
120
+
The address Xonotic will listen on.
124
+
options.port = lib.mkOption {
125
+
type = lib.types.port;
127
+
description = lib.mdDoc ''
128
+
The port Xonotic will listen on.
134
+
# Still useful even though we're using RFC 42 settings because *some* keys
136
+
appendConfig = lib.mkOption {
137
+
type = with lib.types; nullOr lines;
139
+
description = lib.mdDoc ''
140
+
Literal text to insert at the end of `server.cfg`.
144
+
# Certain changes need to happen at the beginning of the file.
145
+
prependConfig = lib.mkOption {
146
+
type = with lib.types; nullOr lines;
148
+
description = lib.mdDoc ''
149
+
Literal text to insert at the start of `server.cfg`.
154
+
config = lib.mkIf cfg.enable {
155
+
systemd.services.xonotic = {
156
+
description = "Xonotic server";
157
+
wantedBy = [ "multi-user.target" ];
160
+
# Required or else it tries to write the lock file into the nix store
161
+
HOME = cfg.dataDir;
165
+
DynamicUser = true;
167
+
StateDirectory = "xonotic";
168
+
ExecStart = "${cfg.package}/bin/xonotic-dedicated";
170
+
# Symlink the configuration from the nix store to where Xonotic actually
173
+
"${pkgs.coreutils}/bin/mkdir -p ${cfg.dataDir}/.xonotic/data"
175
+
${pkgs.coreutils}/bin/ln -sf ${serverCfg} \
176
+
${cfg.dataDir}/.xonotic/data/server.cfg
180
+
# Cargo-culted from search results about writing Xonotic systemd units
181
+
ExecReload = "${pkgs.util-linux}/bin/kill -HUP $MAINPID";
183
+
Restart = "on-failure";
185
+
StartLimitBurst = 5;
189
+
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [
192
+
networking.firewall.allowedUDPPorts = lib.mkIf cfg.openFirewall [
197
+
meta.maintainers = with lib.maintainers; [ CobaltCause ];