From 5893346625528324a182e6209f35fc3c792f1486 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 3 Sep 2026 18:35:44 +0000 Subject: [PATCH] wolf: make ES-DE RunInBackground fix fully self-healing, no manual step MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous version only patched an already-populated es_settings.xml, requiring a manual "connect via Moonlight once" step before the fix could apply — the user correctly pointed out the script can't know whether that step has been done, so a manual dependency isn't a real fix. This embeds GOW's own real es_settings.xml template (fetched from games-on-whales/gow, RunInBackground pre-flipped false) and writes it directly whenever the on-disk file is missing or is the old broken stub (detected by the absence of ROMDirectory, which only a real GOW/ES-DE-written file has). An already-populated file still only gets the one RunInBackground line patched, leaving everything else alone. Verified against all 4 scenarios in isolated /tmp harnesses before touching the file: missing file, the exact broken stub from the user's regression, GOW's real full template, and idempotent re-runs. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01VLX1yYKJExGSXmgUhxKQG6 --- services/wolf.sh | 270 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 221 insertions(+), 49 deletions(-) diff --git a/services/wolf.sh b/services/wolf.sh index 7e34ae7..3de4e00 100644 --- a/services/wolf.sh +++ b/services/wolf.sh @@ -325,8 +325,8 @@ EOF echo " and Wii U (Cemu) in ES-DE via a second, opt-in 'Alternative emulators' command" echo " - Expose Wolf's REST API socket to the host (WOLF_SOCKET_PATH + /var/run/wolf mount)" echo " so './manage.sh controllers' can force distinct pad types per controller slot" - echo " - Mount ~/ES-DE/settings durably + force 'Run in background' off (only once" - echo " GOW's own es_settings.xml template already exists — never pre-created)" + echo " - Mount ~/ES-DE/settings durably + force 'Run in background' off automatically" + echo " (self-healing — writes GOW's real template if missing/broken, no manual step)" return 0 fi @@ -1393,7 +1393,7 @@ PS2XMLPY log_success "PS2: added PCEE2 as the default RetroArch core (custom_systems/es_systems.xml) — ES-DE's" log_info "own build doesn't ship it yet (added upstream in the not-yet-released 3.5.0)" - # ── ES-DE: force "Run in background" off (once GOW's own template exists) ── + # ── ES-DE: force "Run in background" off (self-healing, no manual step) ── # GOW's own image bakes a FULL es_settings.xml template (100+ settings — # confirmed against apps/es-de/build/configs/es/es_settings.xml in the # games-on-whales/gow repo) that deliberately sets RunInBackground=true @@ -1410,39 +1410,212 @@ PS2XMLPY # ROMDirectory (GOW's template sets it to the /ROMs this whole repo # mounts games at; ES-DE's own default is not that). # - # CONFIRMED LIVE, THE HARD WAY: an earlier version of this exact step - # pre-created a MINIMAL stub file (containing only the RunInBackground - # line) before the container had ever started — GOW's startup.sh saw - # that file "already existing", skipped its own copy, and ES-DE's - # ROMDirectory silently fell back to a default that isn't /ROMs, finding - # zero games on every single system. Root-caused by walking GOW's own - # startup.sh line by line against a real "ES-DE finds no game files" - # report. Never pre-create this file — only ever patch an ALREADY - # existing one (i.e. one GOW's own bootstrap has already populated in - # full, meaning ES-DE has been launched via Moonlight at least once). + # CONFIRMED LIVE, THE HARD WAY (twice): an earlier version of this step + # pre-created a MINIMAL stub file before the container had ever started, + # which made GOW skip its own copy and broke ROM discovery on every + # system. A second attempt only ever patched an ALREADY non-empty file + # and left a pre-existing broken stub (or a genuinely missing file) + # alone, requiring a manual "connect once via Moonlight, then re-run + # setup" step — exactly the manual dependency this version removes. This + # embeds GOW's own real template verbatim (fetched directly from + # games-on-whales/gow:apps/es-de/build/configs/es/es_settings.xml, with + # only RunInBackground flipped true→false) and writes it whenever the + # on-disk file is missing OR is that same broken stub — detected by the + # absence of the ROMDirectory key, which only a real GOW-written or + # ES-DE-written file ever has — so this fix now works unconditionally, + # regardless of whether ES-DE has ever actually launched, with no + # dependency on connection order. mkdir -p "$GAME_STORAGE_DIR/esde-settings" _ESDE_SETTINGS="$GAME_STORAGE_DIR/esde-settings/es_settings.xml" - if [ -s "$_ESDE_SETTINGS" ]; then - backup_if_exists "$_ESDE_SETTINGS" - python3 - "$_ESDE_SETTINGS" << 'ESDESETTINGSPY' + backup_if_exists "$_ESDE_SETTINGS" + python3 - "$_ESDE_SETTINGS" << 'ESDESETTINGSPY' import re, sys path = sys.argv[1] -with open(path) as f: - content = f.read() -content = re.sub(r'[ \t]*[ \t]*\n?', '', content) -line = '\n' -content = content.rstrip('\n') + '\n' + line +try: + with open(path) as f: + content = f.read() +except FileNotFoundError: + content = '' + +GOW_ESDE_SETTINGS_TEMPLATE = """ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +""" + +if 'ROMDirectory' not in content: + content = GOW_ESDE_SETTINGS_TEMPLATE +else: + content = re.sub(r'[ \t]*[ \t]*\n?', '', content) + line = '\n' + content = content.rstrip('\n') + '\n' + line + with open(path, 'w') as f: f.write(content) ESDESETTINGSPY - chown "$ACTUAL_USER:$ACTUAL_USER" "$_ESDE_SETTINGS" - log_success "ES-DE: 'Run in background (while game is launched)' forced off (esde-settings/es_settings.xml)" - else - log_info "ES-DE: 'Run in background' fix deferred — esde-settings/es_settings.xml doesn't" - log_info "exist yet (GOW writes its real, full template the first time EmulationStation" - log_info "actually launches). Connect to it via Moonlight once, then re-run" - log_info "'sudo ./setup.sh wolf' to apply this fix without touching anything else." - fi + chown "$ACTUAL_USER:$ACTUAL_USER" "$_ESDE_SETTINGS" + log_success "ES-DE: 'Run in background (while game is launched)' forced off (esde-settings/es_settings.xml)" # ── App selection ───────────────────────────────────────────────────────── echo "" @@ -4373,26 +4546,25 @@ ES-DE's own *compiled* default for this is off — but GOW's own bundled deliberately sets it **on**, which is the actual, confirmed source of the default behavior here. -**This installer forces it back off** by patching \`esde-settings/es_settings.xml\` -— but only an *already-populated* copy of that file, never by creating one -itself. That distinction matters: GOW's own container startup script only -writes its real template (100+ settings, including where ES-DE looks for -your ROMs) the very first time EmulationStation actually launches, gated -on that file not already existing — pre-creating even a minimal version of -it ourselves, before that first launch, would make GOW skip writing its -own template entirely and leave ES-DE on vanilla upstream defaults for -everything else in that file. **Confirmed live, the hard way:** an earlier -version of this exact fix did precisely that, and ROM discovery broke -completely (every system, not just one) because ES-DE's ROM path fell -back to something other than \`/ROMs\`. - -So in practice: if you've already launched EmulationStation via Moonlight -at least once, re-running \`sudo ./setup.sh wolf\` applies this immediately. -**If you haven't yet** (a genuinely fresh install), the installer says so -and skips the patch rather than guessing — connect to EmulationStation -once first, then re-run \`sudo ./setup.sh wolf\`. Setting it by hand works -too, any time: **Main Menu → Other Settings → Run in background (while -game is launched) → off**. +**This installer forces it back off automatically, with no manual step.** +It writes \`esde-settings/es_settings.xml\` directly from GOW's own real +template (100+ settings, fetched from GOW's own repo, byte-for-byte +identical except \`RunInBackground\` flipped to off) whenever that file is +either missing or still the old broken placeholder — detected by checking +for \`ROMDirectory\`, a key only GOW's own bootstrap or ES-DE itself ever +writes. If the file already has a real, fully-populated value (because +EmulationStation has already launched at least once and GOW wrote its own +copy), only the one \`RunInBackground\` line is patched, leaving every +other setting (theme, scraper prefs, etc.) untouched. Either way, one +\`sudo ./setup.sh wolf\` run is enough — no need to connect via Moonlight +first. **Confirmed live, the hard way, twice:** earlier versions of this +fix either pre-created a minimal stub that made GOW skip writing its own +template (breaking ROM discovery on every system, since the ROM path fell +back to something other than \`/ROMs\`), or only patched an already-existing +file and left a genuinely missing/broken one alone, requiring exactly the +manual Moonlight-connect step this version removes. Setting it by hand +still works too, any time: **Main Menu → Other Settings → Run in +background (while game is launched) → off**. **Why this needed its own mount, not just a one-time write:** \`~/ES-DE\` (settings, gamelists, scraped artwork, logs) had no bind mount onto the