-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from scottbot95/palworld
Add Palworld dedicated server
- Loading branch information
Showing
11 changed files
with
269 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
import { parseArgs } from 'https://deno.land/[email protected]/cli/parse_args.ts'; | ||
import { LockFile, SteamObject, parseObject } from './parser.ts' | ||
|
||
const utf8Decoder = new TextDecoder(); | ||
|
||
/** | ||
* Recursively find all files matching `fileName` under `baseDir` | ||
* | ||
|
@@ -31,7 +33,7 @@ const getAppInfo = async (appId: number): Promise<SteamObject> => { | |
], | ||
}); | ||
const app_info_bytes = (await steamcmd.output()).stdout; | ||
const app_info_str = new TextDecoder().decode(app_info_bytes); | ||
const app_info_str = utf8Decoder.decode(app_info_bytes); | ||
const info_start = `"${appId}"`; | ||
const info_start_idx = app_info_str.indexOf(info_start); | ||
const app_info_obj = app_info_str.slice(info_start_idx + info_start.length); | ||
|
@@ -140,11 +142,13 @@ async function prefetch( | |
const output = await command.output(); | ||
|
||
if (!output.success) { | ||
console.error(new TextDecoder().decode(output.stdout)); | ||
console.error(utf8Decoder.decode(output.stdout)); | ||
throw new Error(`Prefetching failed with code ${output.code}`); | ||
} | ||
|
||
return new TextDecoder().decode(output.stdout); | ||
return utf8Decoder | ||
.decode(output.stdout) | ||
.trim(); | ||
} | ||
|
||
function usage(): never { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
{ | ||
config, | ||
lib, | ||
pkgs, | ||
... | ||
}: | ||
with lib; let | ||
baseCfg = config.services.steam-servers; | ||
cfg = baseCfg.palworld; | ||
enabledServers = filterAttrs (_: conf: conf.enable) cfg; | ||
# settingsFormat = pkgs.formats.ini {}; | ||
settingsFormat = { | ||
generate = name: value: let | ||
optionSettings = | ||
mapAttrsToList | ||
(optName: optVal: let | ||
optType = builtins.typeOf optVal; | ||
encodedVal = | ||
if optType == "string" | ||
then "\"${optVal}\"" | ||
else if optType == "bool" | ||
then | ||
if optVal | ||
then "True" | ||
else "False" | ||
else optVal; | ||
in "${optName}=${encodedVal}") | ||
value; | ||
in | ||
builtins.toFile name '' | ||
[/Script/Pal.PalGameWorldSettings] | ||
OptionSettings=(${concatStringsSep "," optionSettings}) | ||
''; | ||
}; | ||
in { | ||
imports = [./options.nix]; | ||
|
||
config = mkIf (enabledServers != {}) { | ||
networking.firewall = | ||
mkMerge | ||
(map | ||
(conf: | ||
mkIf conf.openFirewall { | ||
# allowedUDPPorts = [conf.config.UpdatePort conf.config.GamePort]; | ||
allowedUDPPorts = [8211]; | ||
}) | ||
(builtins.attrValues enabledServers)); | ||
|
||
services.steam-servers.servers = | ||
mapAttrs' | ||
(name: conf: let | ||
settingsFile = settingsFormat.generate "PalWorldSettings.ini" conf.worldSettings; | ||
in | ||
nameValuePair "palworld-${name}" { | ||
# inherit args; | ||
inherit (conf) enable datadir; | ||
|
||
dirs = { | ||
Pal = "${conf.package}/Pal"; | ||
Engine = "${conf.package}/Engine"; | ||
}; | ||
|
||
files = { | ||
# Copy start script since it derefernces symlinks to find the server root dir | ||
"PalServer.sh" = "${conf.package}/PalServer.sh"; | ||
|
||
"Pal/Saved/Config/LinuxServer/PalWorldSettings.ini" = settingsFile; | ||
}; | ||
|
||
executable = "chmod +x ${conf.datadir}/PalServer.sh; ${pkgs.steam-run}/bin/steam-run ${conf.datadir}/PalServer.sh"; | ||
|
||
args = | ||
[ | ||
"-port=${toString conf.port}" | ||
"-useperfthreads" | ||
"-NoAsyncLoadingThread" | ||
"-UseMultithreadForDS" | ||
] | ||
++ conf.extraArgs; | ||
}) | ||
cfg; | ||
|
||
systemd.services = | ||
mapAttrs' | ||
( | ||
name: _conf: | ||
nameValuePair "palworld-${name}" { | ||
path = with pkgs; [ | ||
xdg-user-dirs | ||
]; | ||
|
||
serviceConfig = { | ||
# Palworld needs namespaces and system calls | ||
RestrictNamespaces = false; | ||
SystemCallFilter = []; | ||
}; | ||
} | ||
) | ||
enabledServers; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{lib, ...}: | ||
with lib; { | ||
name = "palworld"; | ||
|
||
nodes = { | ||
server = { | ||
virtualisation = { | ||
cores = 8; | ||
memorySize = 16 * 1024; | ||
diskSize = 8 * 1024; | ||
}; | ||
|
||
services.steam-servers.palworld.test = { | ||
enable = true; | ||
openFirewall = true; | ||
}; | ||
}; | ||
}; | ||
|
||
testScript = '' | ||
server.wait_for_unit("palworld-test.service") | ||
''; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
{ | ||
config, | ||
lib, | ||
pkgs, | ||
... | ||
}: | ||
with lib; let | ||
baseCfg = config.services.steam-servers; | ||
moduleLib = import ../lib.nix lib; | ||
inherit (moduleLib) mkOpt; | ||
|
||
serverModule = {name, ...}: { | ||
options = { | ||
enable = mkEnableOption (mdDoc "Palworld Dedicated Server"); | ||
|
||
package = mkOption { | ||
type = types.package; | ||
default = pkgs.palworld; | ||
defaultText = literalExpression "pkgs.palworld"; | ||
description = mdDoc "Package to use for Palworld binary"; | ||
}; | ||
|
||
datadir = mkOption { | ||
type = types.path; | ||
default = "${baseCfg.datadir}/palworld/${name}"; | ||
defaultText = literalExpression "\${services.steam-servers.datadir}/palworld/\${name}"; | ||
description = mdDoc '' | ||
Directory to store save state of the game server. (eg world, saves, etc) | ||
''; | ||
}; | ||
|
||
openFirewall = mkOption { | ||
type = types.bool; | ||
default = false; | ||
description = mdDoc "Whether to open ports in the firewall."; | ||
}; | ||
|
||
port = mkOption { | ||
type = types.port; | ||
default = 8211; | ||
description = mdDoc "UDP port to listen on"; | ||
}; | ||
|
||
worldSettings = mkOption { | ||
# inherit (settingsFormat) type; | ||
type = types.attrs; | ||
default = {}; | ||
description = mdDoc "World settings used to generate PalWorldSettings.ini"; | ||
}; | ||
|
||
extraArgs = mkOpt (with types; listOf str) [] "Extra command line arguments to pass to the server"; | ||
}; | ||
}; | ||
in { | ||
options.services.steam-servers.palworld = mkOption { | ||
type = types.attrsOf (types.submodule serverModule); | ||
default = {}; | ||
description = mdDoc '' | ||
Options to configure one or more Stationers servers. | ||
''; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{ | ||
lib, | ||
mkSteamPackage, | ||
gcc-unwrapped, | ||
}: | ||
mkSteamPackage { | ||
lockFile = ./lock.json; | ||
|
||
buildInputs = [ | ||
gcc-unwrapped | ||
]; | ||
|
||
meta = with lib; { | ||
description = "Palworld Dedicated Server"; | ||
homepage = "https://steamdb.info/app/2394010/"; | ||
changelog = "https://store.steampowered.com/news/app/1623730?updates=true"; | ||
sourceProvenance = with sourceTypes; [ | ||
binaryNativeCode # Steam games are always going to contain some native binary component. | ||
]; | ||
license = licenses.unfree; | ||
platforms = ["x86_64-linux"]; | ||
}; | ||
} |
Oops, something went wrong.