From eaeb6aa4c6f4bd0a217f54984ff40bafb463e407 Mon Sep 17 00:00:00 2001 From: Nikolaos Karaolidis Date: Fri, 30 Aug 2024 12:06:48 +0300 Subject: [PATCH] Add steam games directory sync Signed-off-by: Nikolaos Karaolidis --- .../user/configs/gui/gaming/default.nix | 50 +++++++++++++++- .../configs/gui/gaming/scripts/steam-ln.sh | 57 +++++++++++++++++++ 2 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 hosts/common/user/configs/gui/gaming/scripts/steam-ln.sh diff --git a/hosts/common/user/configs/gui/gaming/default.nix b/hosts/common/user/configs/gui/gaming/default.nix index 8dc5f32..32ffa9c 100644 --- a/hosts/common/user/configs/gui/gaming/default.nix +++ b/hosts/common/user/configs/gui/gaming/default.nix @@ -2,7 +2,12 @@ user ? throw "user argument is required", home ? throw "home argument is required", }: -{ pkgs, ... }: +{ + config, + lib, + pkgs, + ... +}: { environment.persistence."/persist" = { "${home}/.steam" = { }; @@ -29,6 +34,49 @@ }; home-manager.users.${user} = { + systemd.user = { + tmpfiles.rules = [ "d ${home}/.local/share/Steam/steamapps/common 0755 ${user} users -" ]; + + services.steam-ln = + let + steamLn = lib.meta.getExe ( + pkgs.writeShellApplication { + name = "steam-ln"; + runtimeInputs = with pkgs; [ coreutils ]; + text = builtins.readFile ./scripts/steam-ln.sh; + } + ); + in + { + Unit = { + Description = "Sync Steam games with Games directory"; + After = [ + config.environment.persistence."/persist"."${home}/.local/share/Steam".mount + config.environment.persistence."/persist"."${home}/Games".mount + ]; + DefaultDependencies = false; + }; + + Service = { + ExecStart = steamLn; + Type = "oneshot"; + }; + }; + + paths.steam-ln = { + Unit = { + Description = "Monitor Steam games directory for changes"; + After = [ + config.environment.persistence."/persist"."${home}/.local/share/Steam".mount + config.environment.persistence."/persist"."${home}/Games".mount + ]; + }; + + Path.PathChanged = "${home}/.local/share/Steam/steamapps/common"; + Install.WantedBy = [ "graphical-session.target" ]; + }; + }; + home = { packages = with pkgs; [ protonup ]; sessionVariables.STEAM_EXTRA_COMPAT_TOOLS_PATHS = "${home}/.steam/root/compatibilitytools.d"; diff --git a/hosts/common/user/configs/gui/gaming/scripts/steam-ln.sh b/hosts/common/user/configs/gui/gaming/scripts/steam-ln.sh new file mode 100644 index 0000000..9822050 --- /dev/null +++ b/hosts/common/user/configs/gui/gaming/scripts/steam-ln.sh @@ -0,0 +1,57 @@ +STEAM="${HOME}/.local/share/Steam/steamapps/common" +GAMES="${HOME}/Games" + +EXCLUDE=( + "Proton - Experimental" + "SteamLinuxRuntime_sniper" + "Steamworks Shared" + "Steam.dll" +) + +is_excluded() { + local dir=$1 + for exclude in "${EXCLUDE[@]}"; do + if [[ "${dir}" == "${exclude}" ]]; then + return 0 + fi + done + return 1 +} + +for game in "${STEAM}"/*/; do + name=$(basename "${game}") + + if is_excluded "${name}"; then + echo "Excluding ${name} from symlink creation." + continue + fi + + if [[ -L "${GAMES}/${name}" ]]; then + continue + fi + + if [[ -d "${GAMES}/${name}" || -f "${GAMES}/${name}" ]]; then + >&2 echo "Error: ${name} is already a regular directory or file." + continue + fi + + echo "Creating symlink for ${name}..." + ln -s "${game}" "${GAMES}/${name}" +done + +for link in "${GAMES}"/*; do + target=$(readlink "${link}") + + if [[ ! "${target}" == "${STEAM}/"* ]]; then + continue + fi + + name=$(basename "${target}") + + if [[ -e "${target}" ]] && ! is_excluded "${name}"; then + continue + fi + + echo "Removing symlink ${link}..." + rm "${link}" +done