diff --git a/functions/global.sh b/functions/global.sh index 8bf070e4..73072c93 100644 --- a/functions/global.sh +++ b/functions/global.sh @@ -227,4 +227,6 @@ else multi_user_data_folder="$rdhome/multi-user-data" # The default location of multi-user environment profiles fi -logs_folder="$rdhome/logs" # The path of the logs folder, here we collect all the logs +logs_folder="$rdhome/logs" # The path of the logs folder, here we collect all the logs +steamsync_folder="$rdhome/.sync" # Folder containing all the steam sync launchers for SRM +steamsync_folder_tmp="$rdhome/.sync-tmp" # Temp folder containing all the steam sync launchers for SRM diff --git a/functions/steam_sync.sh b/functions/steam_sync.sh index 1fecdbc1..12f01abf 100644 --- a/functions/steam_sync.sh +++ b/functions/steam_sync.sh @@ -1,15 +1,16 @@ #!/bin/bash +# Function to sanitize strings for filenames +sanitize() { + # Replace sequences of underscores with a single space + echo "$1" | sed -e 's/_\{2,\}/ /g' -e 's/_/ /g' -e 's/:/ -/g' -e 's/&/and/g' -e 's%/%and%g' -e 's/ / /g' +} -# Add games to Steam function add_to_steam() { + log "i" "Starting Steam Sync" - steamsync_folder="$rdhome/.sync" - steamsync_folder_tmp="$rdhome/.sync-tmp" - create_dir $steamsync_folder - mv $steamsync_folder $steamsync_folder_tmp - create_dir $steamsync_folder + create_dir $steamsync_folder_tmp local srm_path="/var/config/steam-rom-manager/userData/userConfigurations.json" if [ ! -f "$srm_path" ]; then @@ -17,98 +18,50 @@ add_to_steam() { prepare_component "reset" "steam-rom-manager" fi - # Build the systems array from space-separated systems - local systems_string=$(jq -r '.system | keys[]' "$features" | paste -sd' ') - IFS=' ' read -r -a systems <<< "$systems_string" # TODO: do we need this line? + # Iterate through all gamelist.xml files in the folder structure + for system_path in "$rdhome/ES-DE/gamelists/"*/; do + system=$(basename "$system_path") # Extract the folder name as the system name + gamelist="${system_path}gamelist.xml" - local games=() - - for system in "${systems[@]}"; do - - local gamelist="$rdhome/ES-DE/gamelists/$system/gamelist.xml" + log d "Reading favorites for $system" + # Ensure gamelist.xml exists in the current folder if [ -f "$gamelist" ]; then + while IFS= read -r line; do + # Detect the start of a block + if [[ "$line" =~ \ ]]; then + to_be_added=false # Reset the flag for a new block + path="" + name="" + fi - # Extract all elements that are marked as favorite="true" - game_blocks=$(xmllint --recover --xpath '//game[favorite="true"]' "$gamelist" 2>/dev/null) - log d "Extracted favorite game blocks:\n\n$game_blocks\n\n" + # Check for true + if [[ "$line" =~ \true\<\/favorite\> ]]; then + to_be_added=true + fi - # Split the game_blocks into an array, where each element is a full block - IFS=$'\n' read -r -d '' -a game_array <<< "$(echo "$game_blocks" | xmllint --recover --format - | sed -n '//,/<\/game>/p' | tr '\n' ' ')" + # Extract the and remove leading "./" if present + if [[ "$line" =~ \(.*)\<\/path\> ]]; then + path="${BASH_REMATCH[1]#./}" + fi - # Iterate over each full block in the array - for game_block in "${game_array[@]}"; do - log "d" "Processing game block:\n$game_block" + # Extract and sanitize + if [[ "$line" =~ \(.*)\<\/name\> ]]; then + name=$(sanitize "${BASH_REMATCH[1]}") + fi - # Extract the game's name and path from the full game block - local name=$(echo "$game_block" | xmllint --xpath 'string(//game/name)' - 2>/dev/null) - local path=$(echo "$game_block" | xmllint --xpath 'string(//game/path)' - 2>/dev/null | sed 's|^\./||') # removing the ./ + # Detect the end of a block + if [[ "$line" =~ \<\/game\> ]]; then + # If the block is meaningful (marked as favorite), generate the launcher + if [ "$to_be_added" = true ] && [ -n "$path" ] && [ -n "$name" ]; then + local launcher="$steamsync_folder/${name}.sh" + local launcher_tmp="$steamsync_folder_tmp/${name}.sh" - log "d" "Game name: $name" - log "d" "Game path: $path" - - # Ensure the extracted name and path are valid - if [ -n "$name" ] && [ -n "$path" ]; then - # Check for an alternative emulator if it exists - # local emulator=$(echo "$game_block" | xmllint --xpath 'string(//game/altemulator)' - 2>/dev/null) - # if [ -z "$emulator" ]; then - # games+=("$name ${command_list_default[$system]} '$roms_folder/$system/$path'") - # else - # games+=("$name ${alt_command_list[$emulator]} '$roms_folder/$system/$path'") - # fi - log "d" "Steam Sync: found favorite game: $name" - else - log "w" "Steam Sync: failed to find valid name or path for favorite game" - fi - - # Sanitize the game name for the filename: replace special characters with underscores - local sanitized_name=$(echo "$name" | sed -e 's/^A-Za-z0-9._-/ /g') - local sanitized_name=$(echo "$sanitized_name" | sed -e 's/:/ -/g') - local sanitized_name=$(echo "$sanitized_name" | sed -e 's/&/and/g') - local sanitized_name=$(echo "$sanitized_name" | sed -e 's%/%and%g') - local sanitized_name=$(echo "$sanitized_name" | sed -e 's/ / - /g') - local sanitized_name=$(echo "$sanitized_name" | sed -e 's/ / /g') - log d "File Path: $path" - log d "Game Name: $name" - - # If the filename is too long, shorten it - if [ ${#sanitized_name} -gt 100 ]; then - sanitized_name=$(echo "$sanitized_name" | cut -c 1-100) - fi - - log d "Sanitized Name: $sanitized_name" - - local launcher="$steamsync_folder/${sanitized_name}.sh" - local launcher_tmp="$steamsync_folder_tmp/${sanitized_name}.sh" - - if [ ! -e "$launcher_tmp" ]; then - - log d "Creating desktop file: $launcher" - - # if [[ -v command_list_default[$system] ]]; then - # command="${command_list_default[$system]}" - # else - # log e "$system is not included in the commands array." - # continue - # fi - - # Populate the .sync script with the correct command - # TODO: if there is any emulator defined in the xml we use that, else... how we can know which is the default one? - # TODO: if steam is flatpak the command wrapping will change in .desktop - local command="flatpak run net.retrodeck.retrodeck start '$roms_folder/$system/$path'" - # Create the launcher file using a heredoc - if you enable .desktp this remember to edit .desktop in SRM userConfigurations.json and the above launcher variable (and vice versa) -# cat < "$launcher" -# [Desktop Entry] -# Version=1.0 -# Name=$name -# Comment=$name via RetroDECK -# Exec=$command -# Icon=net.retrodeck.retrodeck -# Terminal=false -# Type=Application -# Categories=Game;Emulator; -# EOF - cat < "$launcher" + # Create the launcher file + if [ ! -e "$launcher_tmp" ]; then + log d "Creating launcher file: $launcher" + command="flatpak run net.retrodeck.retrodeck start '$roms_folder/$system/$path'" + cat < "$launcher" #!/bin/bash if [ test "\$(whereis flatpak)" = "flatpak:" ]; then flatpak-spawn --host $command @@ -116,26 +69,33 @@ else $command fi EOF - chmod +x "$launcher" + chmod +x "$launcher" + else + log d "$launcher desktop file already exists" + mv "$launcher_tmp" "$launcher" + fi + fi + + # Clean up variables for safety + to_be_added=false + path="" + name="" + fi + done < "$gamelist" else - log d "$launcher desktop file already exists" - mv "$launcher_tmp" "$launcher" + log "e" "Gamelist file not found: $gamelist" fi - done + done + + rm -r $steamsync_folder_tmp + + if [ -z "$( ls -A $steamsync_folder )" ]; then + log d "No games found, cleaning shortcut" + remove_from_steam + else + log d "Updating game list" + steam-rom-manager add fi - done - - rm -r $steamsync_folder_tmp - - if [ -z "$( ls -A $steamsync_folder )" ]; then - log d "No games found, cleaning shortcut" - remove_from_steam - else - log d "Updating game list" - steam-rom-manager add - fi - - log i "Steam Sync: completed" } remove_from_steam() {