From 31ee16720227aa2f2f529798393d5ecd4d0dc94e Mon Sep 17 00:00:00 2001 From: icenine451 Date: Tue, 25 Mar 2025 16:22:17 -0400 Subject: [PATCH] Upgrade steam_sync to better handle unfavorited games. Previously entire SRM manifest would have been hard synced (remove everything, add current set of favorites), now will only remove specifically unfavorited items and add all new ones --- functions/steam_sync.sh | 89 +++++++++++++++++++++++++++-------------- 1 file changed, 60 insertions(+), 29 deletions(-) diff --git a/functions/steam_sync.sh b/functions/steam_sync.sh index 2605d4c3..5a34e290 100644 --- a/functions/steam_sync.sh +++ b/functions/steam_sync.sh @@ -21,7 +21,6 @@ steam_sync() { # Prepare new favorites manifest echo "[]" > "${retrodeck_favorites_file}.new" # Initialize favorites JSON file - favorites_found="false" # Static definitions for all JSON objects target="flatpak" @@ -33,63 +32,101 @@ steam_sync() { if [[ "$system_path" == *"/CLEANUP/"* ]]; then continue fi + # Skip folders with no gamelists + if [[ ! -f "${system_path}gamelist.xml" ]]; then + continue + fi system=$(basename "$system_path") # Extract the folder name as the system name gamelist="${system_path}gamelist.xml" system_favorites=$(xml sel -t -m "//game[favorite='true']" -v "path" -n "$gamelist") while read -r game; do if [[ -n "$game" ]]; then # Avoid empty lines created by xmlstarlet - favorites_found="true" local game="${game#./}" # Remove leading ./ - # Construct launch options with the rom path in quotes, to handle spaces - local launchOptions="$launch_command -s $system \"$roms_folder/$system/$game\"" - jq --arg title "${game%.*}" --arg target "$target" --arg launchOptions "$launchOptions" \ - '. += [{"title": $title, "target": $target, "launchOptions": $launchOptions}]' "${retrodeck_favorites_file}.new" > "${retrodeck_favorites_file}.tmp" \ - && mv "${retrodeck_favorites_file}.tmp" "${retrodeck_favorites_file}.new" + if [[ -f "$roms_folder/$system/$game" ]]; then # Validate file exists and isn't a stale ES-DE entry for a removed file + # Construct launch options with the rom path in quotes, to handle spaces + local launchOptions="$launch_command -s $system \"$roms_folder/$system/$game\"" + jq --arg title "${game%.*}" --arg target "$target" --arg launchOptions "$launchOptions" \ + '. += [{"title": $title, "target": $target, "launchOptions": $launchOptions}]' "${retrodeck_favorites_file}.new" > "${retrodeck_favorites_file}.tmp" \ + && mv "${retrodeck_favorites_file}.tmp" "${retrodeck_favorites_file}.new" + fi fi done <<< "$system_favorites" done + if [[ -f "$retrodeck_favorites_file" && -f "${retrodeck_favorites_file}.new" ]]; then + # Look for favorites removed between steam_sync runs, if any + removed_items=$(jq -n \ + --slurpfile source "$retrodeck_favorites_file" \ + --slurpfile target "${retrodeck_favorites_file}.new" \ + '[$source[0][] | select(. as $item | ($target[0] | map(. == $item) | any | not))]') + fi + + # Check if there are any missing objects + if [[ "$(echo "$removed_items" | jq 'length')" -gt 0 ]]; then + log d "Some favorites were removed between sync, writing to $retrodeck_removed_favorites" + echo "$removed_items" > "$retrodeck_removed_favorites" + fi + + # Decide if sync needs to happen if [[ -f "$retrodeck_favorites_file" ]]; then # If an existing favorites manifest exists - if [[ $favorites_found == "false" ]]; then # If no favorites were found in the gamelists + if [[ ! "$(cat "${retrodeck_favorites_file}.new" | jq 'length')" -gt 0 ]]; then # If all favorites were removed from all gamelists, meaning new manifest is empty log i "No favorites were found in current ES-DE gamelists, removing old entries" if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then ( # Remove old entries - steam-rom-manager enable --names "RetroDECK Steam Sync" >> "$srm_log" 2>&1 steam-rom-manager disable --names "RetroDECK Launcher" >> "$srm_log" 2>&1 + steam-rom-manager enable --names "RetroDECK Steam Sync" >> "$srm_log" 2>&1 steam-rom-manager remove >> "$srm_log" 2>&1 ) | rd_zenity --progress \ --title="Syncing with Steam" \ --window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \ - --text="\t\t\t\tSyncing favorite games with Steam\n\nNOTE: This operation may take some time depending on the size of your library.\nFeel free to leave this in the background and switch to another application.\n\n" \ + --text="\t\t\t\tRemoving unfavorited games from Steam\n\nNOTE: This operation may take some time depending on the size of your library.\nFeel free to leave this in the background and switch to another application.\n\n" \ --pulsate --width=500 --height=150 --auto-close --no-cancel else # Remove old entries - steam-rom-manager enable --names "RetroDECK Steam Sync" >> "$srm_log" 2>&1 steam-rom-manager disable --names "RetroDECK Launcher" >> "$srm_log" 2>&1 + steam-rom-manager enable --names "RetroDECK Steam Sync" >> "$srm_log" 2>&1 steam-rom-manager remove >> "$srm_log" 2>&1 fi # Old manifest cleanup rm "$retrodeck_favorites_file" rm "${retrodeck_favorites_file}.new" - else + else # The new favorites manifest is not empty if cmp -s "$retrodeck_favorites_file" "${retrodeck_favorites_file}.new"; then # See if the favorites manifests are the same, meaning there were no changes log i "ES-DE favorites have not changed, no need to sync again" rm "${retrodeck_favorites_file}.new" else log d "New and old manifests are different, running sync" + if [[ -f "$retrodeck_removed_favorites" ]]; then # If some favorites were removed between syncs + log d "Some favorites removed between syncs, removing unfavorited games" + # Load removed favorites as manifest and run SRM remove + mv "$retrodeck_removed_favorites" "$retrodeck_favorites_file" + if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then + ( + steam-rom-manager disable --names "RetroDECK Launcher" >> "$srm_log" 2>&1 + steam-rom-manager enable --names "RetroDECK Steam Sync" >> "$srm_log" 2>&1 + steam-rom-manager remove >> "$srm_log" 2>&1 + ) | + rd_zenity --progress \ + --title="Syncing with Steam" \ + --window-icon="/app/share/icons/hicolor/scalable/apps/net.retrodeck.retrodeck.svg" \ + --text="\t\t\t\tRemoving unfavorited games from Steam\n\nNOTE: This operation may take some time depending on the size of your library.\nFeel free to leave this in the background and switch to another application.\n\n" \ + --pulsate --width=500 --height=150 --auto-close --no-cancel + else + steam-rom-manager disable --names "RetroDECK Launcher" >> "$srm_log" 2>&1 + steam-rom-manager enable --names "RetroDECK Steam Sync" >> "$srm_log" 2>&1 + steam-rom-manager remove >> "$srm_log" 2>&1 + fi + fi + + # Load new favorites manifest as games to add during sync + mv "${retrodeck_favorites_file}.new" "$retrodeck_favorites_file" + if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then ( - # Remove old entries - steam-rom-manager enable --names "RetroDECK Steam Sync" >> "$srm_log" 2>&1 - steam-rom-manager disable --names "RetroDECK Launcher" >> "$srm_log" 2>&1 - steam-rom-manager remove >> "$srm_log" 2>&1 - - # Load new favorites manifest - mv "${retrodeck_favorites_file}.new" "$retrodeck_favorites_file" - # Add new favorites manifest + steam-rom-manager disable --names "RetroDECK Launcher" >> "$srm_log" 2>&1 steam-rom-manager enable --names "RetroDECK Steam Sync" >> "$srm_log" 2>&1 steam-rom-manager add >> "$srm_log" 2>&1 ) | @@ -99,26 +136,19 @@ steam_sync() { --text="\t\t\t\tSyncing favorite games with Steam\n\nNOTE: This operation may take some time depending on the size of your library.\nFeel free to leave this in the background and switch to another application.\n\n" \ --pulsate --width=500 --height=150 --auto-close --no-cancel else - # Remove old entries - steam-rom-manager enable --names "RetroDECK Steam Sync" >> "$srm_log" 2>&1 steam-rom-manager disable --names "RetroDECK Launcher" >> "$srm_log" 2>&1 - steam-rom-manager remove >> "$srm_log" 2>&1 - - # Load new favorites manifest - mv "${retrodeck_favorites_file}.new" "$retrodeck_favorites_file" - - # Add new favorites manifest steam-rom-manager enable --names "RetroDECK Steam Sync" >> "$srm_log" 2>&1 steam-rom-manager add >> "$srm_log" 2>&1 fi fi fi - elif [[ $favorites_found == "true" ]]; then # Only sync if some favorites were found + elif [[ "$(cat "${retrodeck_favorites_file}.new" | jq 'length')" -gt 0 ]]; then # No existing favorites manifest was found, so check if new manifest has entries log d "First time building favorites manifest, running sync" mv "${retrodeck_favorites_file}.new" "$retrodeck_favorites_file" if [[ "$CONFIGURATOR_GUI" == "zenity" ]]; then ( # Add new favorites manifest + steam-rom-manager disable --names "RetroDECK Launcher" >> "$srm_log" 2>&1 steam-rom-manager enable --names "RetroDECK Steam Sync" >> "$srm_log" 2>&1 steam-rom-manager add >> "$srm_log" 2>&1 ) | @@ -129,6 +159,7 @@ steam_sync() { --pulsate --width=500 --height=150 --auto-close --no-cancel else # Add new favorites manifest + steam-rom-manager disable --names "RetroDECK Launcher" >> "$srm_log" 2>&1 steam-rom-manager enable --names "RetroDECK Steam Sync" >> "$srm_log" 2>&1 steam-rom-manager add >> "$srm_log" 2>&1 fi