diff options
Diffstat (limited to 'nixpkgs/nixos/modules/services/games')
-rw-r--r-- | nixpkgs/nixos/modules/services/games/xonotic.nix | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/nixpkgs/nixos/modules/services/games/xonotic.nix b/nixpkgs/nixos/modules/services/games/xonotic.nix new file mode 100644 index 000000000000..c84347ddc981 --- /dev/null +++ b/nixpkgs/nixos/modules/services/games/xonotic.nix @@ -0,0 +1,198 @@ +{ 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 ]; +} |