#!/bin/sh # Purpose {{{ ## Try to centralize all game's save in order to : ## easily backup all save ## easily restore it ## be able to access it from anywhere ## … all you can do with a Nextcloud (share, versionning,…) ## ## 1. Move save directories of a list of known games from Steam's ## userdata to a remote directory (Nextcloud, remote mount,…). ## Then create a symlink in userdata directory to the remote game ## directory. ## ## 2. If a directory doesn't exist, check if a remote one is ## available and symlink it. ## ## TODO : 3. List directories without symlinks. ## ## KISS : Only manage save directories from Steam userdata. For other ## paths ($XDG_DATA_HOME,…) check other scripts. # }}} # Vars {{{ debug=0 ## Steam {{{ steam_id="112595584" steam_userdata=".steam/steam/userdata/${steam_id}" ## List of Steam games to backup ### 204360 − Castle Crashers − https://pcgamingwiki.com/wiki/Castle_Crashers steam_games="1 204360 17" ## }}} remote_dir="${HOME}/Nextcloud/games/linux.sgl.script" remote_steam_userdata="${remote_dir}/${steam_userdata}" local_steam_userdata="${HOME}/${steam_userdata}" # }}} # Functions {{{ # Move one Steam save game dir {{{ move_steam_game_dir() { _game_id="${1}" _local_game_path="${local_steam_userdata}/${_game_id}" _remote_game_path="${remote_steam_userdata}/${_game_id}" ## If a remote directory doesn't already exists for this game if [ ! -d "${_remote_game_path}" ]; then mv -- "${_local_game_path}" "${_remote_game_path}" [ "${debug}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "Move Steam game − The data of ${_game_id} − ${_local_game_path} moved to remote storage." ln -s -- "${_remote_game_path}" "${_local_game_path}" [ "${debug}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "Move Steam game − Symlink remote to data of ${_game_id} to local storage." else printf '\e[1;35m%-6s\e[m\n' "Move Steam game − ${_game_id} already have data on remote storage : ${_remote_game_path}. Abort to avoid to delete data." exit 5 fi } # }}} # Symlink one Steam save game dir from remote to local {{{ symlink_steam_game_dir() { _game_id="${1}" _local_game_path="${local_steam_userdata}/${_game_id}" _remote_game_path="${remote_steam_userdata}/${_game_id}" if [ -d "${_remote_game_path}" ]; then ln -s -- "${_remote_game_path}" "${_local_game_path}" [ "${debug}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Symlink Steam game — Symlink remote data of ${_game_id} to local storage." else [ "${debug}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Symlink Steam game — ${_game_id} doesn't have remote data." fi } # }}} # }}} # Tests {{{ ## Ensure remote dir exist {{{ if [ ! -d "${remote_dir}" ]; then printf '\e[1;35m%-6s\e[m\n' "The directory for save game doesn't exists : ${remote_dir}" exit 1 fi ## }}} ## Ensure Steam dir exist {{{ if [ ! -d "${local_steam_userdata}" ]; then printf '\e[1;35m%-6s\e[m\n' "The Steam directory for your ID (${steam_id}) doesn't exists yet… Should it must be create (for restoration,…) [Y/n] ?" read -r create_local_steam_userdata if [ "${create_local_steam_userdata}" = "" ] || [ "${create_local_steam_userdata}" = "Y" ] || [ "${create_local_steam_userdata}" = "y" ]; then mkdir -p -- "${local_steam_userdata}" else printf '\e[1;35m%-6s\e[m\n' "Steam directory doesn't exists, abort script." exit 2 fi fi ## }}} # }}} # Manage Steam save game {{{ for game_id in ${steam_games}; do local_game_path="${local_steam_userdata}/${game_id}" local_game_path_type="$(file ${local_steam_userdata}/${game_id} | cut -d' ' -f2)" case ${local_game_path_type} in ## Data is already a symlink "symbolic") [ "${debug}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Steam for loop — The data of ${game_id} are already symlinked to .... Skip." ;; ## Data is still a directory "directory") move_steam_game_dir "${game_id}" ;; ## Data can't be managed "cannot") [ "${debug}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG : Steam for loop — The data of ${game_id} − ${local_game_path} doesn't exist. Skip." symlink_steam_game_dir "${game_id}" ;; *) printf '\e[1;35m%-6s\e[m\n' "Data of ${game_id} − ${local_game_path} are not managed. Type: ${local_game_path_type}. Abort" exit 3 ;; esac done # }}}