feat(nixos): add Palworld Tracion guest
This commit was merged in pull request #39.
This commit is contained in:
148
configs/nixos/modules/services/games/palworld.nix
Normal file
148
configs/nixos/modules/services/games/palworld.nix
Normal file
@@ -0,0 +1,148 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
options.modules.services.games.palworld = {
|
||||
enable = lib.mkEnableOption "Palworld dedicated server";
|
||||
|
||||
steamDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "/data/steamcmd";
|
||||
description = "Directory where SteamCMD stores metadata and cache files.";
|
||||
};
|
||||
|
||||
installDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "/data/servers/palworld/tracion";
|
||||
description = "Directory where SteamCMD installs the Palworld server files.";
|
||||
};
|
||||
|
||||
stateDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
example = "/data/state/palworld/tracion";
|
||||
description = "Directory where Palworld stores durable server state.";
|
||||
};
|
||||
|
||||
serverName = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "palworld";
|
||||
description = "Name shown for the Palworld server.";
|
||||
};
|
||||
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 8211;
|
||||
description = "UDP port for the Palworld server.";
|
||||
};
|
||||
|
||||
publicIP = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = "Public IP address advertised by the Palworld server.";
|
||||
};
|
||||
|
||||
maxPlayers = lib.mkOption {
|
||||
type = lib.types.ints.between 1 32;
|
||||
default = 32;
|
||||
description = "Maximum player count for the Palworld server.";
|
||||
};
|
||||
|
||||
publicLobby = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Advertise the server in Palworld's public lobby.";
|
||||
};
|
||||
|
||||
rcon = {
|
||||
enable = lib.mkEnableOption "Palworld RCON" // {
|
||||
default = true;
|
||||
};
|
||||
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 25575;
|
||||
description = "TCP port for Palworld RCON.";
|
||||
};
|
||||
};
|
||||
|
||||
passwordFile = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
description = "Runtime file containing the Palworld server password.";
|
||||
};
|
||||
|
||||
adminPasswordFile = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
description = "Runtime file containing the Palworld admin password.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf config.modules.services.games.palworld.enable (
|
||||
let
|
||||
service = config.modules.services.games.palworld;
|
||||
savedDir = "${service.installDir}/Pal/Saved";
|
||||
startScript = pkgs.writeShellScript "palworld-start" ''
|
||||
set -eu
|
||||
|
||||
${pkgs.coreutils}/bin/install -d \
|
||||
-m 0770 \
|
||||
${lib.escapeShellArg service.stateDir} \
|
||||
${lib.escapeShellArg (builtins.dirOf savedDir)}
|
||||
|
||||
if [ -L ${lib.escapeShellArg savedDir} ]; then
|
||||
current_target="$(${pkgs.coreutils}/bin/readlink ${lib.escapeShellArg savedDir})"
|
||||
if [ "$current_target" != ${lib.escapeShellArg service.stateDir} ]; then
|
||||
${pkgs.coreutils}/bin/rm ${lib.escapeShellArg savedDir}
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d ${lib.escapeShellArg savedDir} ] && [ ! -L ${lib.escapeShellArg savedDir} ]; then
|
||||
if ${pkgs.findutils}/bin/find ${lib.escapeShellArg service.stateDir} -mindepth 1 -maxdepth 1 | ${pkgs.gnugrep}/bin/grep -q .; then
|
||||
${pkgs.coreutils}/bin/rm -rf ${lib.escapeShellArg savedDir}
|
||||
else
|
||||
${pkgs.coreutils}/bin/cp -a ${lib.escapeShellArg savedDir}/. ${lib.escapeShellArg service.stateDir}/
|
||||
${pkgs.coreutils}/bin/rm -rf ${lib.escapeShellArg savedDir}
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -e ${lib.escapeShellArg savedDir} ]; then
|
||||
${pkgs.coreutils}/bin/ln -s ${lib.escapeShellArg service.stateDir} ${lib.escapeShellArg savedDir}
|
||||
fi
|
||||
|
||||
password="$(${pkgs.coreutils}/bin/tr -d '\n' < ${lib.escapeShellArg service.passwordFile})"
|
||||
admin_password="$(${pkgs.coreutils}/bin/tr -d '\n' < ${lib.escapeShellArg service.adminPasswordFile})"
|
||||
|
||||
exec ./PalServer.sh \
|
||||
"$@" \
|
||||
"-serverpassword=$password" \
|
||||
"-adminpassword=$admin_password"
|
||||
'';
|
||||
in
|
||||
{
|
||||
modules.services.steamcmd = {
|
||||
enable = true;
|
||||
inherit (service) steamDir installDir stateDir;
|
||||
serviceName = "palworld-${lib.toLower service.serverName}";
|
||||
appId = 2394010;
|
||||
executable = "${startScript}";
|
||||
arguments =
|
||||
[
|
||||
"-useperfthreads"
|
||||
"-NoAsyncLoadingThread"
|
||||
"-UseMultithreadForDS"
|
||||
"-port=${toString service.port}"
|
||||
"-publicport=${toString service.port}"
|
||||
"-servername=${service.serverName}"
|
||||
"-players=${toString service.maxPlayers}"
|
||||
]
|
||||
++ lib.optional service.publicLobby "-publiclobby"
|
||||
++ lib.optionals (service.publicIP != null) [ "-publicip=${service.publicIP}" ]
|
||||
++ lib.optional service.rcon.enable "-rcon";
|
||||
udpPorts = [ service.port ];
|
||||
tcpPorts = [ service.port ];
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -59,6 +59,12 @@
|
||||
default = [ ];
|
||||
description = "UDP ports opened for the game service.";
|
||||
};
|
||||
|
||||
tcpPorts = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.port;
|
||||
default = [ ];
|
||||
description = "TCP ports opened for the game service.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkMerge [
|
||||
@@ -159,6 +165,7 @@
|
||||
};
|
||||
|
||||
networking.firewall.allowedUDPPorts = service.udpPorts;
|
||||
networking.firewall.allowedTCPPorts = service.tcpPorts;
|
||||
}
|
||||
))
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user