198 lines
5.3 KiB
Nix
198 lines
5.3 KiB
Nix
{ config
|
|
, pkgs
|
|
, lib
|
|
, ...
|
|
}:
|
|
|
|
let
|
|
cfg = config.services.xonotic;
|
|
|
|
serverCfg = pkgs.writeText "xonotic-server.cfg" (
|
|
toString cfg.prependConfig
|
|
+ "\n"
|
|
+ builtins.concatStringsSep "\n" (
|
|
lib.mapAttrsToList (key: option:
|
|
let
|
|
escape = s: lib.escape [ "\"" ] s;
|
|
quote = s: "\"${s}\"";
|
|
|
|
toValue = x: quote (escape (toString x));
|
|
|
|
value = (if lib.isList option then
|
|
builtins.concatStringsSep
|
|
" "
|
|
(builtins.map (x: toValue x) option)
|
|
else
|
|
toValue option
|
|
);
|
|
in
|
|
"${key} ${value}"
|
|
) cfg.settings
|
|
)
|
|
+ "\n"
|
|
+ toString cfg.appendConfig
|
|
);
|
|
in
|
|
|
|
{
|
|
options.services.xonotic = {
|
|
enable = lib.mkEnableOption (lib.mdDoc "Xonotic dedicated server");
|
|
|
|
package = lib.mkPackageOption pkgs "xonotic-dedicated" {};
|
|
|
|
openFirewall = lib.mkOption {
|
|
type = lib.types.bool;
|
|
default = false;
|
|
description = lib.mdDoc ''
|
|
Open the firewall for TCP and UDP on the specified port.
|
|
'';
|
|
};
|
|
|
|
dataDir = lib.mkOption {
|
|
type = lib.types.path;
|
|
readOnly = true;
|
|
default = "/var/lib/xonotic";
|
|
description = lib.mdDoc ''
|
|
Data directory.
|
|
'';
|
|
};
|
|
|
|
settings = lib.mkOption {
|
|
description = lib.mdDoc ''
|
|
Generates the `server.cfg` file. Refer to [upstream's example][0] for
|
|
details.
|
|
|
|
[0]: https://gitlab.com/xonotic/xonotic/-/blob/master/server/server.cfg
|
|
'';
|
|
default = {};
|
|
type = lib.types.submodule {
|
|
freeformType = with lib.types; let
|
|
scalars = oneOf [ singleLineStr int float ];
|
|
in
|
|
attrsOf (oneOf [ scalars (nonEmptyListOf scalars) ]);
|
|
|
|
options.sv_public = lib.mkOption {
|
|
type = lib.types.int;
|
|
default = 0;
|
|
example = [ (-1) 1 ];
|
|
description = lib.mdDoc ''
|
|
Controls whether the server will be publicly listed.
|
|
'';
|
|
};
|
|
|
|
options.hostname = lib.mkOption {
|
|
type = lib.types.singleLineStr;
|
|
default = "Xonotic $g_xonoticversion Server";
|
|
description = lib.mdDoc ''
|
|
The name that will appear in the server list. `$g_xonoticversion`
|
|
gets replaced with the current version.
|
|
'';
|
|
};
|
|
|
|
options.sv_motd = lib.mkOption {
|
|
type = lib.types.singleLineStr;
|
|
default = "";
|
|
description = lib.mdDoc ''
|
|
Text displayed when players join the server.
|
|
'';
|
|
};
|
|
|
|
options.sv_termsofservice_url = lib.mkOption {
|
|
type = lib.types.singleLineStr;
|
|
default = "";
|
|
description = lib.mdDoc ''
|
|
URL for the Terms of Service for playing on your server.
|
|
'';
|
|
};
|
|
|
|
options.maxplayers = lib.mkOption {
|
|
type = lib.types.int;
|
|
default = 16;
|
|
description = lib.mdDoc ''
|
|
Number of player slots on the server, including spectators.
|
|
'';
|
|
};
|
|
|
|
options.net_address = lib.mkOption {
|
|
type = lib.types.singleLineStr;
|
|
default = "0.0.0.0";
|
|
description = lib.mdDoc ''
|
|
The address Xonotic will listen on.
|
|
'';
|
|
};
|
|
|
|
options.port = lib.mkOption {
|
|
type = lib.types.port;
|
|
default = 26000;
|
|
description = lib.mdDoc ''
|
|
The port Xonotic will listen on.
|
|
'';
|
|
};
|
|
};
|
|
};
|
|
|
|
# Still useful even though we're using RFC 42 settings because *some* keys
|
|
# can be repeated.
|
|
appendConfig = lib.mkOption {
|
|
type = with lib.types; nullOr lines;
|
|
default = null;
|
|
description = lib.mdDoc ''
|
|
Literal text to insert at the end of `server.cfg`.
|
|
'';
|
|
};
|
|
|
|
# Certain changes need to happen at the beginning of the file.
|
|
prependConfig = lib.mkOption {
|
|
type = with lib.types; nullOr lines;
|
|
default = null;
|
|
description = lib.mdDoc ''
|
|
Literal text to insert at the start of `server.cfg`.
|
|
'';
|
|
};
|
|
};
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
systemd.services.xonotic = {
|
|
description = "Xonotic server";
|
|
wantedBy = [ "multi-user.target" ];
|
|
|
|
environment = {
|
|
# Required or else it tries to write the lock file into the nix store
|
|
HOME = cfg.dataDir;
|
|
};
|
|
|
|
serviceConfig = {
|
|
DynamicUser = true;
|
|
User = "xonotic";
|
|
StateDirectory = "xonotic";
|
|
ExecStart = "${cfg.package}/bin/xonotic-dedicated";
|
|
|
|
# Symlink the configuration from the nix store to where Xonotic actually
|
|
# looks for it
|
|
ExecStartPre = [
|
|
"${pkgs.coreutils}/bin/mkdir -p ${cfg.dataDir}/.xonotic/data"
|
|
''
|
|
${pkgs.coreutils}/bin/ln -sf ${serverCfg} \
|
|
${cfg.dataDir}/.xonotic/data/server.cfg
|
|
''
|
|
];
|
|
|
|
# Cargo-culted from search results about writing Xonotic systemd units
|
|
ExecReload = "${pkgs.util-linux}/bin/kill -HUP $MAINPID";
|
|
|
|
Restart = "on-failure";
|
|
RestartSec = 10;
|
|
StartLimitBurst = 5;
|
|
};
|
|
};
|
|
|
|
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [
|
|
cfg.settings.port
|
|
];
|
|
networking.firewall.allowedUDPPorts = lib.mkIf cfg.openFirewall [
|
|
cfg.settings.port
|
|
];
|
|
};
|
|
|
|
meta.maintainers = with lib.maintainers; [ CobaltCause ];
|
|
}
|