wolf: make 'games' interactive — pick a number to apply the EA fix

./manage.sh games now lists installed games numbered with their AppIDs,
then prompts for a number to apply the EA App install-script fix to that
game (Enter to skip). Factored the reg-fix into a shared _apply_ea_fix
helper used by both 'games' and 'fix-ea-game'. The EA Desktop installed
marker is shared across all EA titles, so the same fix works for any EA
game — the picker just supplies the right per-game AppID.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
This commit is contained in:
Claude
2026-06-21 00:02:48 +00:00
parent d32832ec75
commit 3f6e359c7b
+91 -60
View File
@@ -956,6 +956,44 @@ WOLF_STATE_DIR=$(grep '^WOLF_STATE_DIR=' "$SCRIPT_DIR/.env" 2>/dev/null | cut -d
WOLF_CFG="${WOLF_STATE_DIR:-/etc/wolf}/cfg/config.toml" WOLF_CFG="${WOLF_STATE_DIR:-/etc/wolf}/cfg/config.toml"
WOLF_TZ=$(grep '^WOLF_TZ=' "$SCRIPT_DIR/.env" 2>/dev/null | cut -d= -f2-) WOLF_TZ=$(grep '^WOLF_TZ=' "$SCRIPT_DIR/.env" 2>/dev/null | cut -d= -f2-)
# Locate the Steam home under the Wolf state folder (born on first Steam launch).
_steam_home() {
find "${WOLF_STATE_DIR:-/etc/wolf}" -maxdepth 2 -type d -name Steam 2>/dev/null | head -1
}
# Pre-satisfy the EA App install-script markers in a game's Proton prefix so
# Steam stops looping on "running install script (EA app)". The EA Desktop
# InstallSuccessful flag is shared across all EA titles; the Valve has-run key
# is per-AppID but identical in form for every EA game — so this works for any
# of them. Safe + idempotent; only touches the AppID passed in.
_apply_ea_fix() {
local appid="$1"
local steam_home reg
steam_home=$(_steam_home)
reg="$steam_home/.steam/steam/steamapps/compatdata/$appid/pfx/system.reg"
if [ ! -f "$reg" ]; then
echo "No Proton prefix for AppID $appid yet (looked for $reg)."
echo "In Steam: set the game to GE-Proton (./manage.sh ge-proton),"
echo "click Play once to build the prefix, then re-run this."
return 1
fi
if sudo grep -q 'EADesktopSetup' "$reg" 2>/dev/null; then
echo "AppID $appid already patched. Cancel the 'installing' screen in Steam and Play."
return 0
fi
echo "Patching EA install-script markers for AppID $appid..."
# Wine v2 registry format uses doubled backslashes as the path separator.
{
printf '\n[Software\\\\Electronic Arts\\\\EA Desktop] 1781772837\n"InstallSuccessful"="true"\n'
printf '\n[Software\\\\Wow6432Node\\\\Electronic Arts\\\\EA Desktop] 1781772837\n"InstallSuccessful"="true"\n'
printf '\n[Software\\\\Valve\\\\Steam\\\\Apps\\\\%s] 1781772837\n"EADesktopSetup"=dword:00000001\n' "$appid"
printf '\n[Software\\\\Wow6432Node\\\\Valve\\\\Steam\\\\Apps\\\\%s] 1781772837\n"EADesktopSetup"=dword:00000001\n' "$appid"
} | sudo tee -a "$reg" >/dev/null
# Keep the prefix owned by the in-container user or Wine rejects it.
sudo chown 1000:1000 "$reg"
echo "Done. In Steam: cancel the 'running install script' screen if shown, then Play."
}
case "$1" in case "$1" in
start) start)
docker compose up -d docker compose up -d
@@ -1572,66 +1610,55 @@ PYEOF
echo " Properties → Compatibility → Force the use of $NAME" echo " Properties → Compatibility → Force the use of $NAME"
;; ;;
games) games)
# List installed Steam games with their AppIDs, read from the Steam # List installed Steam games (numbered) with their AppIDs, then offer to
# app manifests. Use this to find the AppID to pass to fix-ea-game. # apply the EA App install-script fix to whichever one you pick. Read
STEAM_HOME=$(find "${WOLF_STATE_DIR:-/etc/wolf}" -maxdepth 2 -type d -name Steam 2>/dev/null | head -1) # straight from the Steam app manifests.
STEAM_HOME=$(_steam_home)
APPSDIR="$STEAM_HOME/.steam/steam/steamapps" APPSDIR="$STEAM_HOME/.steam/steam/steamapps"
if [ ! -d "$APPSDIR" ]; then if [ ! -d "$APPSDIR" ]; then
echo "No Steam library found yet. Launch Steam and install a game first." echo "No Steam library found yet. Launch Steam and install a game first."
exit 1 exit 1
fi fi
shopt -s nullglob shopt -s nullglob
found=0 ids=(); names=(); n=0
printf " %-10s %s\n" "AppID" "Name"
printf " %-10s %s\n" "-----" "----"
for acf in "$APPSDIR"/appmanifest_*.acf; do for acf in "$APPSDIR"/appmanifest_*.acf; do
id=$(grep -oP '"appid"\s*"\K[0-9]+' "$acf" | head -1) id=$(grep -oP '"appid"\s*"\K[0-9]+' "$acf" | head -1)
name=$(grep -oP '"name"\s*"\K[^"]+' "$acf" | head -1) name=$(grep -oP '"name"\s*"\K[^"]+' "$acf" | head -1)
printf " %-10s %s\n" "$id" "$name" [ -z "$id" ] && continue
found=1 n=$((n+1))
ids+=("$id"); names+=("$name")
done done
[ "$found" = 0 ] && echo " (no games installed yet)" if [ "$n" = 0 ]; then
echo "" echo " (no games installed yet)"
echo "EA titles stuck on 'running install script': ./manage.sh fix-ea-game <AppID>"
;;
fix-ea-game)
# Some EA titles on Steam (e.g. Star Wars Battlefront II 2017,
# AppID 1237950) bundle an EA App bootstrapper that hangs indefinitely
# under Proton inside a container, leaving the game stuck on "running
# install script (EA app)". This pre-satisfies the install-script
# markers in the game's Proton prefix so Steam skips the bootstrapper
# and launches the game directly.
#
# Safe + opt-in: only touches the AppID you pass, and only if its prefix
# already exists. No effect on other games or on users who don't own the
# title. Run AFTER setting the game to GE-Proton and clicking Play once
# (so the prefix exists). Usage: ./manage.sh fix-ea-game [appid]
APPID="${2:-1237950}"
STEAM_HOME=$(find "${WOLF_STATE_DIR:-/etc/wolf}" -maxdepth 2 -type d -name Steam 2>/dev/null | head -1)
REG="$STEAM_HOME/.steam/steam/steamapps/compatdata/$APPID/pfx/system.reg"
if [ ! -f "$REG" ]; then
echo "No Proton prefix for AppID $APPID yet (looked for $REG)."
echo "In Steam: set the game to GE-Proton (./manage.sh ge-proton),"
echo "click Play once to build the prefix, then re-run this command."
exit 1
fi
if sudo grep -q 'EADesktopSetup' "$REG" 2>/dev/null; then
echo "AppID $APPID already patched. Cancel the 'installing' screen in Steam and Play."
exit 0 exit 0
fi fi
echo "Patching EA install-script markers for AppID $APPID..." printf " %-4s %-10s %s\n" "#" "AppID" "Name"
# Wine v2 registry format uses doubled backslashes as the path separator. printf " %-4s %-10s %s\n" "-" "-----" "----"
# InstallSuccessful satisfies the EA Desktop string check; EADesktopSetup for i in $(seq 1 "$n"); do
# satisfies the Valve has-run-key check used by the bundled install script. printf " %-4s %-10s %s\n" "$i" "${ids[$((i-1))]}" "${names[$((i-1))]}"
{ done
printf '\n[Software\\\\Electronic Arts\\\\EA Desktop] 1781772837\n"InstallSuccessful"="true"\n' echo ""
printf '\n[Software\\\\Wow6432Node\\\\Electronic Arts\\\\EA Desktop] 1781772837\n"InstallSuccessful"="true"\n' echo "An EA game stuck on 'running install script (EA app)'? Enter its"
printf '\n[Software\\\\Valve\\\\Steam\\\\Apps\\\\%s] 1781772837\n"EADesktopSetup"=dword:00000001\n' "$APPID" echo "number to apply the EA fix, or just press Enter to skip."
printf '\n[Software\\\\Wow6432Node\\\\Valve\\\\Steam\\\\Apps\\\\%s] 1781772837\n"EADesktopSetup"=dword:00000001\n' "$APPID" read -r -p " Apply EA fix to # (or Enter to skip): " pick
} | sudo tee -a "$REG" >/dev/null if [ -z "$pick" ]; then
# Keep the prefix owned by the in-container user or Wine rejects it. exit 0
sudo chown 1000:1000 "$REG" fi
echo "Done. In Steam: cancel the 'running install script' screen if shown, then Play." if ! [[ "$pick" =~ ^[0-9]+$ ]] || [ "$pick" -lt 1 ] || [ "$pick" -gt "$n" ]; then
echo "Not a valid number from the list."
exit 1
fi
sel_id="${ids[$((pick-1))]}"
sel_name="${names[$((pick-1))]}"
echo "Applying EA fix to '$sel_name' (AppID $sel_id)..."
_apply_ea_fix "$sel_id"
;;
fix-ea-game)
# Apply the EA App install-script fix directly to an AppID (defaults to
# Star Wars Battlefront II 2017, AppID 1237950). For an interactive
# picker use './manage.sh games' instead. Run AFTER setting the game to
# GE-Proton and clicking Play once (so the Proton prefix exists).
_apply_ea_fix "${2:-1237950}"
;; ;;
fix-perms) fix-perms)
# Wolf creates each app's home dir under WOLF_STATE_DIR/<session-id>/<App> # Wolf creates each app's home dir under WOLF_STATE_DIR/<session-id>/<App>
@@ -1722,8 +1749,8 @@ COMPEOF
echo " ./manage.sh reorder - Reorder the Moonlight tile list" echo " ./manage.sh reorder - Reorder the Moonlight tile list"
echo " ./manage.sh add-web [name] [url] - Add a URL shortcut tile (Firefox kiosk)" echo " ./manage.sh add-web [name] [url] - Add a URL shortcut tile (Firefox kiosk)"
echo " ./manage.sh ge-proton [version] - Install GE-Proton (latest, or pin a version)" echo " ./manage.sh ge-proton [version] - Install GE-Proton (latest, or pin a version)"
echo " ./manage.sh games - List installed games + their AppIDs" echo " ./manage.sh games - List games; pick one to apply the EA fix"
echo " ./manage.sh fix-ea-game [appid] - Unstick EA App install loop (default: SWBF2 1237950)" echo " ./manage.sh fix-ea-game [appid] - Apply EA fix directly (default: SWBF2 1237950)"
echo " ./manage.sh fix-perms - Fix 'Permission denied' app startup errors" echo " ./manage.sh fix-perms - Fix 'Permission denied' app startup errors"
echo " ./manage.sh install-completion - Enable tab-completion for this script" echo " ./manage.sh install-completion - Enable tab-completion for this script"
echo " ./manage.sh backup - How to set up backups" echo " ./manage.sh backup - How to set up backups"
@@ -2064,9 +2091,8 @@ PYEOF
echo " 1. ./manage.sh ge-proton # install GE-Proton once" echo " 1. ./manage.sh ge-proton # install GE-Proton once"
echo " 2. In Steam: game → Properties → Compatibility → Force GE-Proton" echo " 2. In Steam: game → Properties → Compatibility → Force GE-Proton"
echo " 3. Click Play once (builds the Proton prefix; will hang — that's ok)" echo " 3. Click Play once (builds the Proton prefix; will hang — that's ok)"
echo " 4. ./manage.sh games # find the game's AppID" echo " 4. ./manage.sh games # pick the game's number to fix it"
echo " 5. ./manage.sh fix-ea-game <appid> # e.g. 1237950 for SWBF2 2017" echo " 5. Cancel the 'installing' screen in Steam, Play again — it launches"
echo " 6. Cancel the 'installing' screen in Steam, Play again — it launches"
echo "" echo ""
echo "── BACKUPS ───────────────────────────────────────────" echo "── BACKUPS ───────────────────────────────────────────"
echo "" echo ""
@@ -2133,17 +2159,22 @@ cd $WOLF_DIR
# Compatibility → Force GE-Proton # Compatibility → Force GE-Proton
# 3. Click Play once (builds the prefix; # 3. Click Play once (builds the prefix;
# it will hang — that's expected) # it will hang — that's expected)
./manage.sh games # 4. find the game's AppID ./manage.sh games # 4. lists games numbered; enter the
./manage.sh fix-ea-game 1237950 # 5. unstick it (1237950 = SWBF2 2017) # game's number to apply the EA fix
# 6. Cancel the 'installing' screen, # 5. Cancel the 'installing' screen,
# Play again — it launches. # Play again — it launches.
\`\`\` \`\`\`
\`games\` lists each installed game with a number and AppID, then asks which
one to fix — just type the number. (\`fix-ea-game [appid]\` does the same thing
non-interactively, defaulting to SWBF2 2017's \`1237950\`.)
Notes: Notes:
- Steam **AppIDs are global** — SWBF2 (2017) is always \`1237950\`, on every - Steam **AppIDs are global** — SWBF2 (2017) is always \`1237950\` on every
machine. \`fix-ea-game\` with no argument defaults to it. machine — but you don't need to know it; the \`games\` picker handles it.
- \`fix-ea-game\` is safe and opt-in: it only touches the AppID you pass, only - The fix is safe and opt-in: it only touches the game you pick, only if its
if that game's Proton prefix exists, and is a no-op otherwise. Proton prefix exists, and is idempotent. The EA Desktop "installed" marker is
shared across all EA titles, so the same fix works for any EA game.
- \`ge-proton\` takes an optional version to pin, e.g. - \`ge-proton\` takes an optional version to pin, e.g.
\`./manage.sh ge-proton GE-Proton10-34\`. \`./manage.sh ge-proton GE-Proton10-34\`.