commit 276b84b9aad4ce4a2c83357ab7abb1f00a7523e6 Author: wytch Date: Fri Feb 27 14:21:33 2026 -0600 Recreating the script diff --git a/pub_event[rungame,endgame](sync).ash b/pub_event[rungame,endgame](sync).ash new file mode 100644 index 0000000..a0fa249 --- /dev/null +++ b/pub_event[rungame,endgame](sync).ash @@ -0,0 +1,26 @@ +#!/bin/ash +# shellcheck shell=ash +# +# +eventfile="/tmp/es_state.inf" + +# 1. Check if the file exists and is not empty +if [ ! -s "$eventfile" ]; then + echo "Error: $eventfile is missing or empty." + exit 1 +fi + +# 2. Read the payload safely +PAYLOAD=$(cat "$eventfile") + +# 3. Publish (using double quotes to handle spaces/newlines in the file) +mosquitto_pub -h 127.0.0.1 -p 1883 -t /Recalbox/EmulationStation/Event -m "$PAYLOAD" + +# 4. Optional: check if the publish succeeded +if [ $? -eq 0 ]; then + echo "Successfully published event." +else + echo "Failed to connect to mosquitto broker." +fi + +sleep 4 diff --git a/savesync.conf b/savesync.conf new file mode 100644 index 0000000..fa8cf92 --- /dev/null +++ b/savesync.conf @@ -0,0 +1,4 @@ +export LOG_FILE="/recalbox/share/system/logs/es_event_monitor.log" +export DEBUG_MODE=1 # Set to 0 to only log to file, 1 to also print to screen +export RNAME="saves" +export RPATH="gamepi-tv" diff --git a/savesync[start](permanent).ash b/savesync[start](permanent).ash new file mode 100644 index 0000000..44d5897 --- /dev/null +++ b/savesync[start](permanent).ash @@ -0,0 +1,75 @@ +#!/bin/ash +# shellcheck shell=ash + +# --- Configuration --- +LOG_FILE="/recalbox/share/system/logs/es_event_monitor.log" +DEBUG_MODE=1 +REMOTE_BASE="saves:gamepi-tv" + +# --- Logger Function --- +log() { + local level="$1" + local msg="$2" + mkdir -p "$(dirname "$LOG_FILE")" + local timestamp=$(date '+%Y-%m-%d %H:%M:%S') + local log_line="[$timestamp] [$level] $msg" + + printf "%s\n" "$log_line" >> "$LOG_FILE" 2>/dev/null + [ "$DEBUG_MODE" -eq 1 ] && printf "%s\n" "$log_line" +} + +log "INFO" "--- ES Event Daemon Started ---" + +# --- Main Listener Loop --- +mosquitto_sub -h 127.0.0.1 -p 1883 -t /Recalbox/EmulationStation/Event | while IFS="=" read -r key value +do + # 1. Clean Carriage Returns from Windows-style line endings + value=$(echo "$value" | tr -d '\r') + + case "$key" in + "SystemId") this_system_id="$value" ;; + "GamePath") + this_game_path="$value" + # Logic: Change .gba/.zip to .srm + this_save_path="${value%.*}.srm" + ;; + "Action") this_action="$value" ;; + "State") + this_state="$value" + + # --- TRIGGER: Only act when a game actually starts or ends --- + if [ "$this_state" = "playing" ] && [ "$this_action" = "rungame" ]; then + log "INFO" "Game Started: $(basename "$this_game_path")" + + # Setup paths for rclone + filename=$(basename "$this_save_path") + remote_full="$REMOTE_BASE/$this_system_id/$filename" + + # 2. Safety Valve: Compare Sizes + local_size=$(stat -c %s "$this_save_path" 2>/dev/null || echo 0) + remote_size=$(rclone lsjson "$remote_full" 2>/dev/null | grep -o '"Size":[0-9]*' | cut -d: -f2) + : "${remote_size:=0}" # Default to 0 if empty + + if [ "$local_size" -lt "$remote_size" ]; then + log "WARN" "Cloud save is LARGER ($remote_size vs $local_size). Restoring..." + rclone copyto "$remote_full" "$this_save_path" + else + log "INFO" "Local save is safe. Running update check..." + rclone update "$remote_full" "$this_save_path" + fi + + elif [ "$this_state" = "endgame" ]; then + log "INFO" "Game Ended. Backing up save..." + filename=$(basename "$this_save_path") + remote_full="$REMOTE_BASE/$this_system_id/$filename" + + # Push the local save to the cloud if it's newer + rclone update "$this_save_path" "$REMOTE_BASE/$this_system_id/" + log "INFO" "Sync Complete." + fi + + # Reset variables for the next event block + this_system_id=""; this_game_path=""; this_save_path=""; this_action="" + ;; + esac +done