#!/bin/ash # shellcheck shell=ash # --- Configuration --- . /recalbox/share/system/configs/savesync/savesync.conf log() { local level="$1" local msg="$2" local timestamp=$(date '+%Y-%m-%d %H:%M:%S') local log_line="[$timestamp] [$level] $msg" if [ "$level" = "ERROR" ]; then mkdir -p "$(dirname "$ERROR_LOG")" printf "%s\n" "$log_line" >>"$ERROR_LOG" fi # FIX: Corrected port to 1883 and added -m mosquitto_pub -h 127.0.0.1 -p 1883 -q 0 -t "$LOG_TOPIC" -m "SaveLog=$log_line" 2>/dev/null [ "${DEBUG_MODE:-0}" -eq 1 ] && printf "%s\n" "$log_line" } sleep 2 log "INFO" "--- ES Event Daemon Started ---" # --- Main Listener Loop --- mosquitto_sub -h 127.0.0.1 -p 1883 -q 0 -t "$TOPIC" | while IFS="=" read -r key value; do # 1. Clean input value=$(echo "$value" | tr -d '\r') case "$key" in "SystemId") this_system_id="$value" ;; "GamePath") this_game_path="$value" # Replace 'roms' with 'saves' and change extension to .srm tmp_path="${value/roms/saves}" this_save_path="${tmp_path%.*}.srm" # Replace 'saves' with 'archives' for backup this_backup_path="${this_save_path/saves/archives}" ;; "Action") this_action="$value" ;; "State") this_state="$value" if [ "$this_state" = "playing" ] && [ "$this_action" = "rungame" ]; then # PASS CURRENT VARS TO SUBSHELL ( # We use local copies inside the subshell to be safe sid="$this_system_id" gp="$this_game_path" sp="$this_save_path" bp="$this_backup_path" log "INFO" "Game Started: $(basename "$gp")" filename=$(basename "$sp") remote_full="$REMOTE_BASE/$sid/$filename" # rclone operations... local_size=$(stat -c %s "$sp" 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}" if [ "$local_size" -lt "$remote_size" ]; then log "WARN" "Cloud save LARGER. Restoring..." mkdir -p "$(dirname "$bp")" rclone copyto "$remote_full" "$sp" --backup-dir "$(dirname "$bp")" else log "INFO" "Local save safe. Updating..." rclone update "$remote_full" "$sp" fi # FIX: Ensure you are sending the EXACT key the publisher is waiting for # If your publisher is looking for "SaveSync", change "SaveContinue" below mosquitto_pub -h 127.0.0.1 -p 1883 -t "$RESPONSE_TOPIC" -m "SaveSync=0" ) & log "DEBUG" "Sync backgrounded." fi # Variable resets happen here, safely outside the child process this_system_id="" this_game_path="" this_save_path="" this_action="" this_backup_path="" ;; esac done