Personal Nix setup
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge remote-tracking branch 'origin/palworld'

+796 -9
+19 -4
flake.nix
··· 92 92 }; 93 93 }; 94 94 95 - outputs = inputs: let 95 + outputs = inputs @ { self, ... }: let 96 96 inherit (inputs.nixpkgs) lib; 97 97 inherit (import ./lib/system.nix inputs) mkSystem; 98 98 eachSystem = lib.genAttrs ["aarch64-darwin" "aarch64-linux" "x86_64-darwin" "x86_64-linux"]; 99 99 overlays = [ 100 + self.overlays.default 100 101 inputs.lix-module.overlays.default 101 102 inputs.nvim-plugins.overlays.default 102 103 inputs.android-sdk.overlays.default ··· 104 105 inputs.system-shell.overlays.default 105 106 (self: super: { 106 107 zen-browser = inputs.zen-browser.packages.${self.system}.beta; 107 - } // (import ./lib/pkgs self)) 108 + }) 108 109 ]; 109 110 in { 110 111 darwinConfigurations."sprite" = mkSystem { ··· 143 144 hostname = "sodacream"; 144 145 }; 145 146 146 - packages = eachSystem (system: { 147 + overlays = { 148 + default = import ./lib/pkgs; 149 + }; 150 + 151 + packages = eachSystem (system: let 152 + pkgs = import inputs.nixpkgs { 153 + inherit system; 154 + overlays = [ self.overlays.default ]; 155 + }; 156 + in { 147 157 inherit (inputs.agenix.packages.${system}) agenix; 148 158 inherit (inputs.darwin.packages.${system}) darwin-rebuild; 149 - } // (import ./lib/pkgs inputs.nixpkgs.legacyPackages.${system})); 159 + } // { 160 + inherit (pkgs) 161 + steamworks-sdk-redist 162 + systemd-transparent-udp-forwarderd 163 + force-bind; 164 + }); 150 165 151 166 apps = eachSystem (system: import ./lib/apps { 152 167 inherit lib;
+12 -4
lib/pkgs/default.nix
··· 1 - pkgs: { 2 - sf-pro = import ./sf-pro.nix pkgs; 3 - sf-mono = import ./sf-mono.nix pkgs; 4 - new-york = import ./new-york.nix pkgs; 1 + self: super: { 2 + sf-pro = import ./sf-pro.nix super; 3 + sf-mono = import ./sf-mono.nix super; 4 + new-york = import ./new-york.nix super; 5 + 6 + fetchSteam = import ./fetch-steam.nix self super; 7 + mkSteamPackage = import ./mk-steam-package.nix self super; 8 + mkSteamWrapper = import ./mk-steam-wrapper.nix self super; 9 + systemd-transparent-udp-forwarderd = import ./systemd-transparent-udp-forwarderd.nix self super; 10 + force-bind = import ./force-bind-seccomp.nix self super; 11 + steamworks-sdk-redist = import ./steamworks-sdk-redist.nix self super; 12 + palworld-server = import ./palworld-server.nix self super; 5 13 }
+60
lib/pkgs/fetch-steam.nix
··· 1 + self: pkgs @ { 2 + lib, 3 + runCommand, 4 + depotdownloader, 5 + cacert, 6 + ... 7 + }: 8 + 9 + with lib; 10 + makeOverridable ( 11 + { 12 + name ? "steamapp-${appId}-${depotId}-${manifestId}", 13 + appId, 14 + depotId, 15 + manifestId, 16 + hash ? "", 17 + branch ? null, 18 + fileList ? null, 19 + debug ? false, 20 + passthru ? { }, 21 + meta ? { }, 22 + } @ args: 23 + let 24 + fileListArg = 25 + if isList fileList then 26 + builtins.toFile "steam-files-list.txt" (concatLines fileList) 27 + else 28 + fileList; 29 + 30 + downloadArgs = 31 + [ 32 + "-app" appId 33 + "-depot" depotId 34 + "-manifest" manifestId 35 + ] 36 + ++ optionals (branch != null) [ "-beta" branch ] 37 + ++ optionals (fileList != null) [ "-filelist" fileListArg ] 38 + ++ optionals debug [ "-debug" ]; 39 + 40 + drvArgs = { 41 + depsBuildBuild = [ depotdownloader ]; 42 + 43 + strictDeps = true; 44 + 45 + outputHashAlgo = "sha256"; 46 + outputHashMode = "recursive"; 47 + outputHash = if hash != "" then hash else fakeHash; 48 + 49 + env.SSL_CERT_FILE = "${cacert}/etc/ssl/certs/ca-bundle.crt"; 50 + 51 + pos = builtins.unsafeGetAttrPos "manifestId" args; 52 + 53 + inherit passthru; 54 + } // optionalAttrs (args ? meta) { inherit meta; }; 55 + in 56 + runCommand name drvArgs '' 57 + HOME=$PWD DepotDownloader -dir "$out" ${escapeShellArgs downloadArgs} 58 + rm -r "$out"/.DepotDownloader 59 + '' 60 + )
+55
lib/pkgs/force-bind-seccomp.nix
··· 1 + self: pkgs @ { 2 + stdenv, 3 + autoPatchelfHook, 4 + fetchFromGitHub, 5 + writeText, 6 + ... 7 + }: 8 + 9 + let 10 + makefile = writeText "Makefile" '' 11 + TARGETS = force-bind target-mkdir target-bind parent-socket-activate 12 + 13 + all: $(TARGETS) 14 + 15 + force-bind: main.c scm_functions.c 16 + $(CC) $(CFLAGS) -o $@ $^ 17 + 18 + parent-socket-activate: parent_soocket_activate.c 19 + $(CC) $(CFLAGS) -o $@ $^ 20 + 21 + target-mkdir: target_mkdir.c 22 + $(CC) $(CFLAGS) -o $@ $^ 23 + 24 + target-bind: target_bind.c 25 + $(CC) $(CFLAGS) -o $@ $^ 26 + 27 + .PHONY: all 28 + ''; 29 + in stdenv.mkDerivation rec { 30 + pname = "force-bind"; 31 + version = "0.0.1-4867c53"; 32 + 33 + nativeBuildInputs = [ autoPatchelfHook ]; 34 + buildInputs = with self; [ stdenv.cc.cc.lib stdenv.cc.libc.linuxHeaders ]; 35 + buildPhase = "make"; 36 + 37 + src = fetchFromGitHub { 38 + owner = "kitten"; 39 + repo = "force-bind-seccomp"; 40 + rev = "0df29fbbe20f5c191c3b76951af090ab60d533e8"; 41 + sha256 = "sha256-SWdPacxJ2WmB+8b8uVpxrnlLuH3wAvFIDyfBclh0a/4="; 42 + }; 43 + postPatch = '' 44 + cp ${makefile} Makefile; 45 + ''; 46 + installPhase = '' 47 + runHook preInstall 48 + install -Dm755 force-bind "$out/bin/$pname" 49 + install -Dm755 target-bind "$out/bin/$pname-test-target-bind" 50 + install -Dm755 parent-socket-activate "$out/bin/$pname-test-socket-activate" 51 + runHook postInstall 52 + ''; 53 + 54 + meta.mainProgram = pname; 55 + }
+56
lib/pkgs/mk-steam-package.nix
··· 1 + self: pkgs @ { 2 + lib, 3 + stdenv, 4 + autoPatchelfHook, 5 + ... 6 + }: 7 + 8 + with lib; 9 + let 10 + inherit (stdenv.hostPlatform) isAarch64; 11 + in 12 + { 13 + name, 14 + hash ? "", 15 + version, 16 + appId, 17 + depotId, 18 + manifestId, 19 + ... 20 + } @ args: let 21 + derivationArgs = builtins.removeAttrs args [ "name" "appId" "depotId" "manifestId" "hash" ]; 22 + in 23 + stdenv.mkDerivation (rec { 24 + pname = name; 25 + src = self.fetchSteam { 26 + inherit name appId depotId manifestId hash; 27 + }; 28 + 29 + dontBuild = true; 30 + dontConfigure = true; 31 + dontFixup = isAarch64; 32 + 33 + nativeBuildInputs = optionals (!isAarch64) [ autoPatchelfHook ]; 34 + appendRunpaths = with self; makeLibraryPath [ 35 + steamworks-sdk-redist 36 + glibc 37 + libxcrypt 38 + libGL 39 + libdrm 40 + mesa # for libgbm 41 + udev 42 + libudev0-shim 43 + libva 44 + vulkan-loader 45 + ]; 46 + 47 + installPhase = '' 48 + runHook preInstall 49 + 50 + mkdir -p $out 51 + mv ./* $out 52 + chmod 755 -R $out 53 + 54 + runHook postInstall 55 + ''; 56 + } // derivationArgs)
+69
lib/pkgs/mk-steam-wrapper.nix
··· 1 + self: pkgs @ { 2 + lib, 3 + box64, 4 + makeWrapper, 5 + pkgsCross, 6 + stdenv, 7 + ... 8 + }: 9 + 10 + with lib; 11 + let 12 + useBox64 = stdenv.hostPlatform.isAarch64; 13 + 14 + defaultLibs = with self; [ 15 + steamworks-sdk-redist 16 + glibc 17 + libxcrypt 18 + libGL 19 + libdrm 20 + mesa # for libgbm 21 + udev 22 + libudev0-shim 23 + libva 24 + vulkan-loader 25 + ]; 26 + 27 + defaultNativeLibs = optionals useBox64 [ pkgsCross.gnu64.libgcc ]; 28 + 29 + mkSteamWrapper = makeOverridable ( 30 + { 31 + logLevel ? 0, 32 + env ? {}, 33 + libs ? defaultLibs, 34 + nativeLibs ? defaultNativeLibs, 35 + extraWrapperArgs ? [], 36 + }: let 37 + runpaths = libs ++ optionals useBox64 nativeLibs; 38 + combinedEnv = optionalAttrs useBox64 { 39 + BOX64_LOG = logLevel; 40 + BOX64_DYNAREC_STRONGMEM = 0; 41 + } // env; 42 + in bin: 43 + stdenv.mkDerivation rec { 44 + name = "box64-wrapper"; 45 + meta.mainProgram = name; 46 + 47 + dontUnpack = true; 48 + dontConfigure = true; 49 + dontBuild = true; 50 + 51 + nativeBuildInputs = [ makeWrapper ]; 52 + buildInputs = runpaths; 53 + 54 + installPhase = let 55 + outBin = if useBox64 then "${box64}/bin/box64" else bin; 56 + targetBinFlag = if useBox64 then "--add-flags ${escapeShellArg bin}" else ""; 57 + in '' 58 + runHook preInstall 59 + makeWrapper "${outBin}" "$out/bin/${name}" \ 60 + ${concatStrings (mapAttrsToList (name: value: "--set ${name} '${toString value}' ") combinedEnv)} \ 61 + --prefix LD_LIBRARY_PATH : ${makeLibraryPath runpaths} \ 62 + ${targetBinFlag} \ 63 + ${lib.strings.concatStringsSep " " extraWrapperArgs} 64 + runHook postInstall 65 + ''; 66 + } 67 + ); 68 + in 69 + mkSteamWrapper { }
+20
lib/pkgs/palworld-server.nix
··· 1 + self: { 2 + lib, 3 + ... 4 + }: 5 + 6 + with lib; 7 + self.mkSteamPackage { 8 + name = "palworld-server"; 9 + version = "17403768"; 10 + appId = "2394010"; 11 + depotId = "2394012"; 12 + manifestId = "1367771460964183113"; 13 + hash = "sha256-L/lRfVmc3tkMiPSPJSg6uum0/DJB97dkuPzOA3LtDEw="; 14 + meta = { 15 + description = "Palworld Dedicated Server"; 16 + homepage = "https://steamdb.info/app/2394010/"; 17 + changelog = "https://store.steampowered.com/news/app/1623730?updates=true"; 18 + sourceProvenance = with sourceTypes; [ sourceTypes.binaryNativeCode ]; 19 + }; 20 + }
+42
lib/pkgs/steamworks-sdk-redist.nix
··· 1 + self: pkgs @ { 2 + lib, 3 + stdenv, 4 + ... 5 + }: 6 + 7 + with lib; 8 + stdenv.mkDerivation { 9 + pname = "steamworks-sdk-redist"; 10 + version = "unstable-2024-05-30"; 11 + 12 + # Steamworks SDK Redist with steamclient.so. 13 + # https://steamdb.info/app/1007/depots 14 + src = self.fetchSteam { 15 + appId = "1007"; 16 + depotId = "1006"; 17 + manifestId = "7138471031118904166"; 18 + hash = "sha256-OtPI1kAx6+9G09IEr2kYchyvxlPl3rzx/ai/xEVG4oM="; 19 + }; 20 + 21 + dontConfigure = true; 22 + dontBuild = true; 23 + 24 + installPhase = '' 25 + runHook preInstall 26 + 27 + mkdir -p $out/lib 28 + cp linux64/steamclient.so $out/lib 29 + chmod +x $out/lib/steamclient.so 30 + 31 + runHook postInstall 32 + ''; 33 + 34 + meta = { 35 + description = "Steamworks SDK Redist"; 36 + sourceProvenance = [ sourceTypes.binaryNativeCode ]; 37 + license = licenses.unfree; 38 + badPlatforms = [ 39 + { hasSharedLibraries = false; } 40 + ]; 41 + }; 42 + }
+29
lib/pkgs/systemd-transparent-udp-forwarderd.nix
··· 1 + self: pkgs @ { 2 + stdenv, 3 + cmake, 4 + pkg-config, 5 + fetchFromGitHub, 6 + systemdLibs, 7 + ... 8 + }: 9 + 10 + stdenv.mkDerivation rec { 11 + pname = "systemd-transparent-udp-forwarderd"; 12 + version = "0.0.1-add-activity-timeout-shutdown"; 13 + nativeBuildInputs = [ cmake pkg-config ]; 14 + buildInputs = [ systemdLibs ]; 15 + src = fetchFromGitHub { 16 + owner = "cecton"; 17 + repo = "systemd-transparent-udp-forwarderd"; 18 + rev = "69072ef1271f013cefa91c239455d197f68d3f8e"; 19 + sha256 = "sha256-c4pui1aHw35Jw1pjCBgLQTHrjt5nYI2IUD4FqkyEd/M="; 20 + }; 21 + 22 + installPhase = '' 23 + runHook preInstall 24 + install -Dm755 systemd-transparent-udp-forwarderd "$out/bin/$pname" 25 + runHook postInstall 26 + ''; 27 + 28 + meta.mainProgram = pname; 29 + }
+17
machines/ramune/configuration.nix
··· 51 51 caddy.enable = true; 52 52 vaultwarden.enable = true; 53 53 }; 54 + games = { 55 + enable = true; 56 + palworld = { 57 + enable = true; 58 + public = true; 59 + ip = "51.38.68.193"; 60 + settings = { 61 + ServerName = "London Boroughs"; 62 + AllowConnectPlatform = "Xbox"; 63 + PalEggDefaultHatchingTime = 1; 64 + GuildPlayerMaxNum = 10; 65 + bShowPlayerList = true; 66 + bEnableNonLoginPenalty = false; 67 + bUseAuth = false; 68 + }; 69 + }; 70 + }; 54 71 }; 55 72 56 73 system.stateVersion = "24.11";
+1
modules/default.nix
··· 5 5 ./base 6 6 ./apps 7 7 ./desktop 8 + ./games 8 9 ./nvim 9 10 ./router 10 11 ./server
+54
modules/games/default.nix
··· 1 + { lib, helpers, config, ... }: 2 + 3 + with lib; let 4 + cfg = config.modules.games; 5 + in { 6 + options.modules.games = { 7 + enable = mkOption { 8 + default = false; 9 + example = true; 10 + description = "Whether to enable game server options."; 11 + type = types.bool; 12 + }; 13 + 14 + datadir = mkOption { 15 + type = types.path; 16 + default = "/var/lib/games"; 17 + description = "Base directory for all game servers created with this module."; 18 + example = "/mnt/nfs/steam"; 19 + }; 20 + 21 + user = mkOption { 22 + type = types.str; 23 + default = "games"; 24 + description = "User to use when running game servers and creating top-level resources"; 25 + }; 26 + 27 + group = mkOption { 28 + type = types.str; 29 + default = cfg.user; 30 + defaultText = literalExpression "\${cfg.user}"; 31 + description = "Group to use when running game servers"; 32 + }; 33 + }; 34 + } // helpers.linuxAttrs { 35 + config = mkIf cfg.enable { 36 + users.users."${cfg.user}" = { 37 + home = "${cfg.datadir}"; 38 + group = cfg.group; 39 + isSystemUser = true; 40 + createHome = true; 41 + homeMode = "750"; 42 + }; 43 + 44 + users.groups."${cfg.group}" = {}; 45 + 46 + systemd.tmpfiles.rules = [ 47 + "d ${cfg.datadir}/.steam 0755 ${cfg.user} ${cfg.group} - -" 48 + ]; 49 + }; 50 + 51 + imports = [ 52 + ./palworld 53 + ]; 54 + }
+73
modules/games/lib/scripts.nix
··· 1 + { lib, pkgs, ... }: 2 + 3 + with lib; 4 + { 5 + mkSymlinks = name: symlinks: 6 + pkgs.writeShellScript "${name}-symlinks" 7 + (concatStringsSep "\n" 8 + (mapAttrsToList 9 + (n: v: '' 10 + if [[ -L "${n}" ]]; then 11 + unlink "${n}" 12 + elif [[ -e "${n}" ]]; then 13 + echo "${n} already exists, moving" 14 + mv "${n}" "${n}.bak" 15 + fi 16 + mkdir -p "$(dirname "${n}")" 17 + ln -sf "${v}" "${n}" 18 + '') 19 + symlinks)); 20 + 21 + mkFiles = name: files: 22 + pkgs.writeShellScript "${name}-files" 23 + (concatStringsSep "\n" 24 + (mapAttrsToList 25 + (n: v: '' 26 + if [[ -L "${n}" ]]; then 27 + unlink "${n}" 28 + elif ${pkgs.diffutils}/bin/cmp -s "${n}" "${v}"; then 29 + rm "${n}" 30 + elif [[ -e "${n}" ]]; then 31 + echo "${n} already exists, moving" 32 + mv "${n}" "${n}.bak" 33 + fi 34 + mkdir -p $(dirname "${n}") 35 + ${pkgs.gawk}/bin/awk '{ 36 + for(varname in ENVIRON) 37 + gsub("@"varname"@", ENVIRON[varname]) 38 + print 39 + }' "${v}" > "${n}" 40 + chmod --reference="${v}" "${n}" 41 + '') 42 + files)); 43 + 44 + mkDirs = name: dirs: 45 + pkgs.writeShellScript "${name}-dirs" 46 + (concatStringsSep "\n" 47 + (mapAttrsToList 48 + (n: v: '' 49 + if [[ -L "${n}" ]]; then 50 + unlink "${n}" 51 + elif [[ ! -d "${n}" ]]; then 52 + echo "${n} already exists and isn't a directory, moving" 53 + mv "${n}" "${n}.bak" 54 + fi 55 + ${pkgs.rsync}/bin/rsync -avu "${v}/" "${n}" 56 + chmod -R u+w "${n}" 57 + '') 58 + dirs)); 59 + 60 + rmSymlinks = name: symlinks: 61 + pkgs.writeShellScript "${name}-rm-symlinks" 62 + ( 63 + concatStringsSep "\n" 64 + (mapAttrsToList (n: _v: "unlink \"${n}\"") symlinks) 65 + ); 66 + 67 + rmFiles = name: files: 68 + pkgs.writeShellScript "${name}-rm-symlinks" 69 + ( 70 + concatStringsSep "\n" 71 + (mapAttrsToList (n: _v: "rm \"${n}\"") files) 72 + ); 73 + }
+86
modules/games/palworld/Engine.ini
··· 1 + [Core.System] 2 + Paths=../../../Engine/Content 3 + Paths=%GAMEDIR%Content 4 + Paths=../../../Engine/Plugins/2D/Paper2D/Content 5 + Paths=../../../Engine/Plugins/Animation/ControlRigSpline/Content 6 + Paths=../../../Engine/Plugins/Animation/ControlRig/Content 7 + Paths=../../../Engine/Plugins/Animation/IKRig/Content 8 + Paths=../../../Engine/Plugins/Animation/MotionWarping/Content 9 + Paths=../../../Engine/Plugins/Bridge/Content 10 + Paths=../../../Engine/Plugins/Compositing/Composure/Content 11 + Paths=../../../Engine/Plugins/Compositing/OpenColorIO/Content 12 + Paths=../../../Engine/Plugins/Developer/AnimationSharing/Content 13 + Paths=../../../Engine/Plugins/Developer/Concert/ConcertSync/ConcertSyncClient/Content 14 + Paths=../../../Engine/Plugins/Editor/BlueprintHeaderView/Content 15 + Paths=../../../Engine/Plugins/Editor/GeometryMode/Content 16 + Paths=../../../Engine/Plugins/Editor/ModelingToolsEditorMode/Content 17 + Paths=../../../Engine/Plugins/Editor/ObjectMixer/LightMixer/Content 18 + Paths=../../../Engine/Plugins/Editor/ObjectMixer/ObjectMixer/Content 19 + Paths=../../../Engine/Plugins/Editor/SpeedTreeImporter/Content 20 + Paths=../../../Engine/Plugins/Enterprise/DatasmithContent/Content 21 + Paths=../../../Engine/Plugins/Enterprise/GLTFExporter/Content 22 + Paths=../../../Engine/Plugins/Experimental/ChaosCaching/Content 23 + Paths=../../../Engine/Plugins/Experimental/ChaosClothEditor/Content 24 + Paths=../../../Engine/Plugins/Experimental/ChaosNiagara/Content 25 + Paths=../../../Engine/Plugins/Experimental/ChaosSolverPlugin/Content 26 + Paths=../../../Engine/Plugins/Experimental/CommonUI/Content 27 + Paths=../../../Engine/Plugins/Experimental/Dataflow/Content 28 + Paths=../../../Engine/Plugins/Experimental/FullBodyIK/Content 29 + Paths=../../../Engine/Plugins/Experimental/GeometryCollectionPlugin/Content 30 + Paths=../../../Engine/Plugins/Experimental/GeometryFlow/Content 31 + Paths=../../../Engine/Plugins/Experimental/ImpostorBaker/Content 32 + Paths=../../../Engine/Plugins/Experimental/Landmass/Content 33 + Paths=../../../Engine/Plugins/Experimental/MeshLODToolset/Content 34 + Paths=../../../Engine/Plugins/Experimental/PythonScriptPlugin/Content 35 + Paths=../../../Engine/Plugins/Experimental/StaticMeshEditorModeling/Content 36 + Paths=../../../Engine/Plugins/Experimental/UVEditor/Content 37 + Paths=../../../Engine/Plugins/Experimental/Volumetrics/Content 38 + Paths=../../../Engine/Plugins/Experimental/Water/Content 39 + Paths=../../../Engine/Plugins/FX/Niagara/Content 40 + Paths=../../../Engine/Plugins/JsonBlueprintUtilities/Content 41 + Paths=../../../Engine/Plugins/Media/MediaCompositing/Content 42 + Paths=../../../Engine/Plugins/Media/MediaPlate/Content 43 + Paths=../../../Engine/Plugins/MovieScene/SequencerScripting/Content 44 + Paths=../../../Engine/Plugins/PivotTool/Content 45 + Paths=../../../Engine/Plugins/PlacementTools/Content 46 + Paths=../../../Engine/Plugins/Runtime/AudioSynesthesia/Content 47 + Paths=../../../Engine/Plugins/Runtime/AudioWidgets/Content 48 + Paths=../../../Engine/Plugins/Runtime/GeometryProcessing/Content 49 + Paths=../../../Engine/Plugins/Runtime/Metasound/Content 50 + Paths=../../../Engine/Plugins/Runtime/ResonanceAudio/Content 51 + Paths=../../../Engine/Plugins/Runtime/SunPosition/Content 52 + Paths=../../../Engine/Plugins/Runtime/Synthesis/Content 53 + Paths=../../../Engine/Plugins/Runtime/WaveTable/Content 54 + Paths=../../../Engine/Plugins/Runtime/WebBrowserWidget/Content 55 + Paths=../../../Engine/Plugins/SkyCreatorPlugin/Content 56 + Paths=../../../Engine/Plugins/VirtualProduction/CameraCalibrationCore/Content 57 + Paths=../../../Engine/Plugins/VirtualProduction/LiveLinkCamera/Content 58 + Paths=../../../Engine/Plugins/VirtualProduction/Takes/Content 59 + Paths=../../../Engine/Plugins/Web/HttpBlueprint/Content 60 + Paths=../../../Pal/Plugins/DLSS/Content 61 + Paths=../../../Pal/Plugins/EffectsChecker/Content 62 + Paths=../../../Pal/Plugins/HoudiniEngine/Content 63 + Paths=../../../Pal/Plugins/PPSkyCreatorPlugin/Content 64 + Paths=../../../Pal/Plugins/PocketpairUser/Content 65 + Paths=../../../Pal/Plugins/SpreadSheetToCsv/Content 66 + Paths=../../../Pal/Plugins/Wwise/Content 67 + 68 + [/script/onlinesubsystemutils.ipnetdriver] 69 + LanServerMaxTickRate=60 70 + NetServerMaxTickRate=60 71 + 72 + [/script/engine.player] 73 + ConfiguredInternetSpeed=104857600 74 + ConfiguredLanSpeed=104857600 75 + 76 + [/script/socketsubsystemepic.epicnetdriver] 77 + MaxClientRate=104857600 78 + MaxInternetClientRate=104857600 79 + 80 + [/script/engine.engine] 81 + bSmoothFrameRate=true 82 + SmoothedFrameRateRange=(LowerBound=(Type=Inclusive,Value=30.000000),UpperBound=(Type=Exclusive,Value=60.000000)) 83 + bUseFixedFrameRate=false 84 + FixedFrameRate=60 85 + MinDesiredFrameRate=30 86 + NetClientTicksPerSecond=60
+196
modules/games/palworld/default.nix
··· 1 + { lib, config, pkgs, ... } @ args: 2 + 3 + with lib; 4 + let 5 + isEnabled = config.modules.games.enable && config.modules.games.palworld.enable; 6 + baseCfg = config.modules.games; 7 + cfg = config.modules.games.palworld; 8 + port = toString cfg.port; 9 + 10 + name = "palworld-server"; 11 + scripts = (import ../lib/scripts.nix) args; 12 + 13 + generateSettings = name: value: let 14 + optionSettings = 15 + mapAttrsToList 16 + (optName: optVal: let 17 + optType = builtins.typeOf optVal; 18 + encodedVal = 19 + if optType == "string" 20 + then "\"${optVal}\"" 21 + else if optType == "bool" 22 + then 23 + if optVal 24 + then "True" 25 + else "False" 26 + else toString optVal; 27 + in "${optName}=${encodedVal}") 28 + value; 29 + in 30 + builtins.toFile name '' 31 + [/Script/Pal.PalGameWorldSettings] 32 + OptionSettings=(${concatStringsSep "," optionSettings}) 33 + ''; 34 + 35 + baseSettings = { 36 + ServerName = "Unnamed Server"; 37 + AllowConnectPlatform = "Steam"; 38 + CoopPlayerMaxNum = cfg.maxPlayers; 39 + bIsUseBackupSaveData = true; 40 + RCONEnabled = false; 41 + RESTAPIEnabled = false; 42 + }; 43 + in 44 + { 45 + options.modules.games.palworld = { 46 + enable = mkOption { 47 + default = false; 48 + description = "Whether to enable Palworld Dedicated Server."; 49 + type = types.bool; 50 + }; 51 + 52 + package = mkOption { 53 + type = types.package; 54 + default = pkgs.palworld-server; 55 + }; 56 + 57 + public = mkOption { 58 + type = types.bool; 59 + default = false; 60 + description = "Whether to enable Community Server mode"; 61 + }; 62 + 63 + datadir = mkOption { 64 + type = types.path; 65 + default = "${baseCfg.datadir}/palworld"; 66 + }; 67 + 68 + ip = mkOption { 69 + type = types.nullOr types.str; 70 + default = "0.0.0.0"; 71 + }; 72 + 73 + port = mkOption { 74 + type = types.port; 75 + default = 8211; 76 + }; 77 + 78 + threads = mkOption { 79 + type = types.int; 80 + default = 5; 81 + }; 82 + 83 + maxPlayers = mkOption { 84 + type = types.int; 85 + default = 6; 86 + }; 87 + 88 + settings = mkOption { 89 + type = types.attrs; 90 + default = { }; 91 + }; 92 + }; 93 + 94 + config = mkIf isEnabled { 95 + age.secrets."palworld-passwd.raw" = { 96 + file = ./encrypt/palworld-passwd.age; 97 + group = "${baseCfg.group}"; 98 + owner = "${baseCfg.user}"; 99 + mode = "770"; 100 + }; 101 + 102 + modules.router.nftables.capturePorts = [ cfg.port ]; 103 + networking.firewall.allowedUDPPorts = [ cfg.port ]; 104 + 105 + systemd.tmpfiles.rules = [ 106 + "d ${cfg.datadir} 0755 ${baseCfg.user} ${baseCfg.group} - -" 107 + ]; 108 + 109 + systemd.sockets."${name}" = { 110 + wantedBy = [ "sockets.target" ]; 111 + partOf = [ "${name}.service" ]; 112 + listenDatagrams = [ "0.0.0.0:${port}" ]; 113 + socketConfig = { 114 + SocketUser = "${baseCfg.user}"; 115 + SocketGroup = "${baseCfg.group}"; 116 + }; 117 + }; 118 + 119 + systemd.services."${name}" = let 120 + dirs = { 121 + Pal = "${cfg.package}/Pal"; 122 + Engine = "${cfg.package}/Engine"; 123 + }; 124 + 125 + files = let 126 + settings = baseSettings // cfg.settings // { 127 + ServerPassword = "@SERVER_PASSWORD@"; 128 + }; 129 + in { 130 + "Pal/Binaries/Linux/steamclient.so" = "${pkgs.steamworks-sdk-redist}/lib/steamclient.so"; 131 + "Pal/Saved/Config/LinuxServer/PalWorldSettings.ini" = generateSettings "PalWorldSettings.ini" settings; 132 + "Pal/Saved/Config/LinuxServer/Engine.ini" = ./Engine.ini; 133 + }; 134 + 135 + script = let 136 + args = [ 137 + "Pal" 138 + "-port=${port}" 139 + "-publicport=${port}" 140 + "-useperfthreads" 141 + "-NoAsyncLoadingThread" 142 + "-UseMultithreadForDS" 143 + "-players=${toString cfg.maxPlayers}" 144 + "-NumberOfWorkerThreadsServer=${toString cfg.threads}" 145 + ] 146 + ++ optionals (cfg.ip != null) [ "-publicip=${cfg.ip}" ] 147 + ++ optionals cfg.public [ "-publiclobby" ]; 148 + bin = getExe (pkgs.mkSteamWrapper "${cfg.datadir}/Pal/Binaries/Linux/PalServer-Linux-Shipping"); 149 + forceBind = "${getExe pkgs.force-bind} -m '0.0.0.0:${port}=sd=0'"; 150 + in "${forceBind} ${bin} ${concatStringsSep " " args}"; 151 + in { 152 + after = [ "network-online.target" ]; 153 + wants = [ "network-online.target" ]; 154 + path = with pkgs; [ xdg-user-dirs util-linux ]; 155 + 156 + inherit script; 157 + preStart = let 158 + passwordFile = config.age.secrets."palworld-passwd.raw".path; 159 + in '' 160 + export SERVER_PASSWORD=$(cat "${passwordFile}") 161 + ${scripts.mkDirs name dirs} 162 + ${scripts.mkFiles name files} 163 + ''; 164 + 165 + serviceConfig = { 166 + Restart = "on-failure"; 167 + User = "${baseCfg.user}"; 168 + Group = "${baseCfg.group}"; 169 + WorkingDirectory = "${cfg.datadir}"; 170 + 171 + CPUWeight = 90; 172 + CPUQuota = "${toString ((cfg.threads + 1) * 100)}%"; 173 + 174 + /* 175 + PrivateDevices = true; 176 + PrivateTmp = true; 177 + PrivateUsers = true; 178 + ProtectClock = true; 179 + ProtectProc = "noaccess"; 180 + ProtectKernelLogs = true; 181 + ProtectKernelModules = true; 182 + ProtectKernelTunables = true; 183 + RestrictRealtime = true; 184 + */ 185 + 186 + # force-bind needs to stay unlocked and needs to be able to ptrace 187 + LockPersonality = false; 188 + CapabilityBoundingSet = [ "CAP_SYS_PTRACE" ]; 189 + 190 + # Palworld needs namespaces and system calls 191 + RestrictNamespaces = false; 192 + SystemCallFilter = []; 193 + }; 194 + }; 195 + }; 196 + }
+5
modules/games/palworld/encrypt/palworld-passwd.age
··· 1 + age-encryption.org/v1 2 + -> ssh-ed25519 QwbpPw QN+UCu72rNSGKgnZpCiAgMQGx7NgnCAvRH+7PHb01F0 3 + VxjDtBg5oFfHLcvDEzJ+gU/MVaqJKhHPVkBxlA+TMkU 4 + --- JQbohsuqLyCVe+muSKagiWVdfrk8XO2tIjGq/U4GtoM 5 + ����ϹX���E���߁�a������uɛ���������
-1
modules/router/kernel.nix
··· 65 65 "kernel.sysrq" = 4; 66 66 "kernel.unprivileged_bpf_disabled" = true; 67 67 "kernel.perf_event_paranoid" = 3; 68 - "kernel.yama.ptrace_scope" = 2; 69 68 "kernel.kexec_load_disabled" = true; 70 69 "net.core.bpf_jit_harden" = 2; 71 70 "dev.tty.ldisc_autoload" = false;
+2
secrets.nix
··· 24 24 25 25 "./modules/automation/certs/mqtt.key.age".publicKeys = keys; 26 26 "./modules/automation/certs/mqtt.crt.age".publicKeys = keys; 27 + 28 + "./modules/games/palworld/encrypt/palworld-passwd.age".publicKeys = keys; 27 29 }