Merge pull request #436 from outis1one/claude/wolf-pair-port-conflict-7nz8qg
Claude/wolf pair port conflict 7nz8qg
This commit is contained in:
+102
-59
@@ -325,7 +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 " - Force ES-DE's 'Run in background' off durably (mounts + writes esde-settings/es_settings.xml)"
|
||||
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)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
@@ -1392,48 +1393,56 @@ 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 ────────────────────────────────
|
||||
# ES-DE's own compiled default for this IS already off (confirmed against
|
||||
# its real Settings.cpp: mBoolMap["RunInBackground"] = {false, false}) —
|
||||
# this write exists purely so that default stays durable and explicit
|
||||
# rather than relying on it never having been toggled. Real, confirmed
|
||||
# cause of a genuine bug otherwise: with it on, ES-DE keeps running and
|
||||
# listening to every controller even after a game/emulator has launched
|
||||
# and taken visual focus — a second controller's input can still reach
|
||||
# ES-DE's own menu in the background and launch (and start playing audio
|
||||
# for) a completely different game while the first one is still up
|
||||
# front. ES-DE's own USERGUIDE.md explicitly names this failure mode
|
||||
# ("make sure that the setting Run in background... is disabled").
|
||||
# Confirmed live: this affects any system, not just Cemu.
|
||||
# ── ES-DE: force "Run in background" off (once GOW's own template exists) ──
|
||||
# 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
|
||||
# (NOT ES-DE's own compiled default, which is false — GOW's template is
|
||||
# what actually causes the real, confirmed cross-system bug this exists
|
||||
# to fix: with it on, ES-DE keeps listening to every controller even
|
||||
# after a game/emulator has focus, so a second controller's input can
|
||||
# reach ES-DE's own menu and launch a different game underneath whatever
|
||||
# is already running). GOW's own startup.sh copies that template exactly
|
||||
# ONCE, the very first time the container starts, gated on
|
||||
# `test -f $ES_CFG_DIR/settings/es_settings.xml` — if a file is already
|
||||
# sitting there, GOW's own copy is skipped entirely and ES-DE falls back
|
||||
# to its own vanilla defaults for EVERYTHING ELSE in that file, including
|
||||
# ROMDirectory (GOW's template sets it to the /ROMs this whole repo
|
||||
# mounts games at; ES-DE's own default is not that).
|
||||
#
|
||||
# es_settings.xml is the user's OWN full settings state (theme, scraper
|
||||
# prefs, everything) — unlike es_systems.xml this is never a full
|
||||
# rewrite, only a surgical strip-and-reappend of this one <bool> entry,
|
||||
# same idempotent pattern as everywhere else in this file. Written as a
|
||||
# plain top-level element with no <settings> wrapper, matching what
|
||||
# ES-DE's own Settings::saveFile() actually produces today (confirmed
|
||||
# against its source — the "wrap everything in <settings>" format is
|
||||
# loader-side forward-compatibility for a future ES-DE release, not
|
||||
# what gets written now); either format loads fine either way.
|
||||
# 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).
|
||||
mkdir -p "$GAME_STORAGE_DIR/esde-settings"
|
||||
_ESDE_SETTINGS="$GAME_STORAGE_DIR/esde-settings/es_settings.xml"
|
||||
backup_if_exists "$_ESDE_SETTINGS"
|
||||
python3 - "$_ESDE_SETTINGS" << 'ESDESETTINGSPY'
|
||||
if [ -s "$_ESDE_SETTINGS" ]; then
|
||||
backup_if_exists "$_ESDE_SETTINGS"
|
||||
python3 - "$_ESDE_SETTINGS" << 'ESDESETTINGSPY'
|
||||
import re, sys
|
||||
path = sys.argv[1]
|
||||
try:
|
||||
with open(path) as f:
|
||||
content = f.read()
|
||||
except FileNotFoundError:
|
||||
content = ''
|
||||
with open(path) as f:
|
||||
content = f.read()
|
||||
content = re.sub(r'[ \t]*<bool name="RunInBackground" value="[^"]*"[ \t]*/>[ \t]*\n?', '', content)
|
||||
line = ' <bool name="RunInBackground" value="false" />\n'
|
||||
content = (content.rstrip('\n') + '\n' + line) if content.strip() else line
|
||||
line = '<bool name="RunInBackground" value="false" />\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)"
|
||||
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
|
||||
|
||||
# ── App selection ─────────────────────────────────────────────────────────
|
||||
echo ""
|
||||
@@ -3423,8 +3432,24 @@ COMPEOF
|
||||
# recognize ("oh, that's my gaming PC").
|
||||
SESSIONS_JSON=$(sudo curl -fsS --unix-socket "$SOCK" http://localhost/api/v1/sessions 2>/dev/null)
|
||||
|
||||
# Wolf doesn't dedupe repeated pairings of the same device (confirmed
|
||||
# live: re-pairing the same PC 6 times over produced 6 separate list
|
||||
# entries, all with the identical client_id) — and Wolf's own
|
||||
# get_client_by_id() (config.hpp) resolves by taking the FIRST match
|
||||
# for a given id anyway, so every duplicate beyond the first is a
|
||||
# dead ringer with no functional difference. Rather than force a
|
||||
# choice between 6 identical-outcome options (confirmed live: this
|
||||
# was a real, confusing thing to be asked to do), the picker only
|
||||
# ever shows DISTINCT client_ids, first-occurrence order — matching
|
||||
# what Wolf itself would actually resolve to regardless of which
|
||||
# duplicate got picked.
|
||||
CLIENT_IDS=()
|
||||
while IFS= read -r cid; do CLIENT_IDS+=("$cid"); done < <(echo "$CLIENTS_JSON" | python3 -c "
|
||||
while IFS= read -r cid; do
|
||||
for existing in "${CLIENT_IDS[@]}"; do
|
||||
[ "$existing" = "$cid" ] && continue 2
|
||||
done
|
||||
CLIENT_IDS+=("$cid")
|
||||
done < <(echo "$CLIENTS_JSON" | python3 -c "
|
||||
import json, sys
|
||||
for c in json.load(sys.stdin)['clients']:
|
||||
print(c['client_id'])
|
||||
@@ -3435,7 +3460,7 @@ for c in json.load(sys.stdin)['clients']:
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Paired clients (ACTIVE = streaming from this IP right now — the"
|
||||
echo "Paired devices (ACTIVE = streaming from this IP right now — the"
|
||||
echo "reliable way to tell which entry is yours. If nothing shows"
|
||||
echo "ACTIVE, start streaming from the device you want to configure,"
|
||||
echo "leave it connected, and re-run this in another terminal):"
|
||||
@@ -3446,21 +3471,21 @@ try:
|
||||
active = {s['client_id']: s['client_ip'] for s in json.loads(sys.argv[1]).get('sessions', []) if s.get('client_id')}
|
||||
except Exception:
|
||||
active = {}
|
||||
for i, c in enumerate(d['clients']):
|
||||
ov = c['settings'].get('controllers_override') or []
|
||||
seen = []
|
||||
counts = {}
|
||||
for c in d['clients']:
|
||||
cid = c['client_id']
|
||||
counts[cid] = counts.get(cid, 0) + 1
|
||||
if cid not in seen:
|
||||
seen.append(cid)
|
||||
for i, cid in enumerate(seen):
|
||||
first = next(c for c in d['clients'] if c['client_id'] == cid)
|
||||
ov = first['settings'].get('controllers_override') or []
|
||||
tag = 'ACTIVE - streaming from ' + active[cid] if cid in active else 'not currently connected'
|
||||
print(f\" {i+1}) {cid} [{tag}]\")
|
||||
dup = f\" (paired {counts[cid]}x)\" if counts[cid] > 1 else ''
|
||||
print(f\" {i+1}) {cid}{dup} [{tag}]\")
|
||||
print(f\" current override: {ov if ov else 'none - auto-detect'}\")
|
||||
" "$SESSIONS_JSON"
|
||||
DUP_COUNT=$(printf '%s\n' "${CLIENT_IDS[@]}" | sort | uniq -d | wc -l)
|
||||
if [ "$DUP_COUNT" -gt 0 ]; then
|
||||
echo ""
|
||||
echo "Note: some client_ids above are repeated — the same device was"
|
||||
echo "paired more than once (each pairing gets its own entry, Wolf"
|
||||
echo "doesn't dedupe). Harmless, but if you want a clean list, forget"
|
||||
echo "/ re-pair this PC from Moonlight's own settings on the client."
|
||||
fi
|
||||
|
||||
ACTIVE_CLIENT_ID=$(python3 -c "
|
||||
import json, sys
|
||||
@@ -4246,10 +4271,12 @@ is actively streaming right now with its real IP address, e.g.
|
||||
it's used automatically with no prompt. **For the clearest result: start
|
||||
streaming from the device you want to configure, leave it connected, and
|
||||
run this command while it's still connected** — then there's no
|
||||
guessing. It's also normal to see the same client_id listed more than
|
||||
once (Wolf doesn't dedupe repeated pairings of the same device) — every
|
||||
duplicate of an active ID is tagged ACTIVE together, so it doesn't matter
|
||||
which one you'd have picked by hand.
|
||||
guessing. Wolf doesn't dedupe repeated pairings of the same device — if
|
||||
you've paired the same PC more than once, this tool collapses those
|
||||
into a single listed entry tagged e.g. \`(paired 6x)\` instead of forcing
|
||||
a choice between several options that all resolve identically (confirmed
|
||||
live: being asked to pick between 6 identical-outcome entries was
|
||||
genuinely confusing before this).
|
||||
|
||||
**It labels controllers "1st"/"2nd"/"3rd"/"4th" — always meaning Wolf's own
|
||||
"controller 0"/"controller 1"/"controller 2"/"controller 3".** Wolf's own
|
||||
@@ -4341,15 +4368,31 @@ playing underneath whatever already has focus.
|
||||
setting. When it's on, ES-DE keeps running and listening to every
|
||||
controller even after something else has launched and taken visual
|
||||
focus — ES-DE's own USERGUIDE.md names this exact failure mode directly.
|
||||
ES-DE's compiled default for this is already off, but nothing durably
|
||||
enforced that in this setup before now, so it's easy for it to have
|
||||
gotten toggled on at some point and stick that way.
|
||||
ES-DE's own *compiled* default for this is off — but GOW's own bundled
|
||||
\`es_settings.xml\` template (baked into \`ghcr.io/games-on-whales/es-de\`)
|
||||
deliberately sets it **on**, which is the actual, confirmed source of the
|
||||
default behavior here.
|
||||
|
||||
**This installer now forces it off automatically** (\`esde-settings/es_settings.xml\`,
|
||||
written fresh on every install/reinstall) — no menu digging required. If
|
||||
you're on an install from before this existed, re-run \`sudo ./setup.sh wolf\`
|
||||
to pick it up, or set it by hand: **Main Menu → Other Settings → Run in
|
||||
background (while game is launched) → off**.
|
||||
**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**.
|
||||
|
||||
**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
|
||||
|
||||
Reference in New Issue
Block a user