Merge pull request #449 from outis1one/claude/steam-non-steam-apps-visibility-p1uqc2

wolf: auto-add downloaded emulators to Steam's library on rerun
This commit is contained in:
Outis
2026-09-09 23:01:18 -04:00
committed by GitHub
+122 -29
View File
@@ -4191,17 +4191,21 @@ VDFPY
echo "other native Linux AppImages don't run through Proton." echo "other native Linux AppImages don't run through Proton."
;; ;;
steam-setup-frontends) steam-setup-frontends)
# One command covering what the ES-DE/RetroArch AppImage download # One command covering what the emulator AppImage download step in
# step in setup.sh can't finish on its own: that step runs before # setup.sh can't finish on its own: that step runs before Wolf/Steam
# Wolf/Steam containers even exist, so it can only download the # containers even exist, so it can only download the AppImages and
# AppImages and print instructions. This picks up from there — # print instructions. This picks up from there — start Steam if
# start Steam if needed, WAIT for it to be signed in (Steam Guard's # needed, WAIT for it to be signed in (Steam Guard's QR-code sign-in
# QR-code sign-in itself can't be scripted: it needs a phone # itself can't be scripted: it needs a phone approving a prompt, so
# approving a prompt, so this only polls for the result, never # this only polls for the result, never performs the sign-in), then
# performs the sign-in), then add whichever AppImage(s) already got # add EVERY AppImage already sitting in emulators/ (ES-DE, RetroArch,
# downloaded as Steam non-Steam games via the existing # Cemu, Azahar, PCSX2, Dolphin — whatever setup.sh's download prompts
# were said yes to) as a Steam non-Steam game via the existing
# steam-add-nonsteam-game command above (re-invoked, not # steam-add-nonsteam-game command above (re-invoked, not
# reimplemented, so the two never drift apart). # reimplemented, so the two never drift apart). Safe to re-run any
# time — already-added shortcuts are updated in place, never
# duplicated, so running this again after downloading one more
# emulator only adds the new one.
if ! docker ps --format '{{.Names}}' | grep -qi WolfSteam; then if ! docker ps --format '{{.Names}}' | grep -qi WolfSteam; then
echo "Starting Wolf (docker compose up -d)..." echo "Starting Wolf (docker compose up -d)..."
docker compose up -d docker compose up -d
@@ -4241,15 +4245,51 @@ VDFPY
if [ -z "$GAME_DIR" ]; then read -r -p " Game storage path: " GAME_DIR; fi if [ -z "$GAME_DIR" ]; then read -r -p " Game storage path: " GAME_DIR; fi
_SSF_EMU_DIR="$GAME_DIR/emulators" _SSF_EMU_DIR="$GAME_DIR/emulators"
_SSF_ADDED_ANY=0 _SSF_ADDED_ANY=0
if [ -f "$_SSF_EMU_DIR/ES-DE.AppImage" ]; then # realpaths already registered — so a fixed-name symlink
"$0" steam-add-nonsteam-game es-de "EmulationStation (ES-DE)" && _SSF_ADDED_ANY=1 # (ES-DE.AppImage, RetroArch.AppImage, Dolphin_Emulator.AppImage) and the
# real versioned file it points at don't both end up as separate Steam
# tiles for the same emulator.
_SSF_SEEN=""
_ssf_add_appimage() {
# $1 = filename inside emulators/, $2 = display name (optional —
# falls back to steam-add-nonsteam-game's own filename-derived default).
local _file="$1" _name="${2:-}" _real
[ -f "$_SSF_EMU_DIR/$_file" ] || return 1
_real=$(readlink -f "$_SSF_EMU_DIR/$_file")
case " $_SSF_SEEN " in *" $_real "*) return 1 ;; esac
_SSF_SEEN="$_SSF_SEEN $_real"
if [ -n "$_name" ]; then
"$0" steam-add-nonsteam-game "$_file" "$_name"
else else
echo "ES-DE.AppImage not found in $_SSF_EMU_DIR — download it first: sudo ./setup.sh wolf" "$0" steam-add-nonsteam-game "$_file"
fi fi
if [ -f "$_SSF_EMU_DIR/RetroArch.AppImage" ]; then }
"$0" steam-add-nonsteam-game retroarch "RetroArch" && _SSF_ADDED_ANY=1
else # Fixed-name symlinks first, so their friendly display names win over
echo "RetroArch.AppImage not found in $_SSF_EMU_DIR — download it first: sudo ./setup.sh wolf" # the versioned real filename each one points at (see the emulator
# download step in setup.sh for why these symlinks exist).
_ssf_add_appimage "ES-DE.AppImage" "EmulationStation (ES-DE)" && _SSF_ADDED_ANY=1
_ssf_add_appimage "RetroArch.AppImage" "RetroArch" && _SSF_ADDED_ANY=1
_ssf_add_appimage "Dolphin_Emulator.AppImage" "Dolphin (GameCube/Wii)" && _SSF_ADDED_ANY=1
# Everything else already downloaded into emulators/ — Cemu, Azahar,
# PCSX2, and any future emulator this list doesn't yet special-case by
# name. The realpath dedupe above skips the Dolphin/ES-DE/RetroArch
# symlinks' own real targets when this glob reaches them.
shopt -s nullglob
for _appimg in "$_SSF_EMU_DIR"/*.AppImage; do
_base=$(basename "$_appimg")
case "${_base,,}" in
cemu*) _ssf_add_appimage "$_base" "Cemu (Wii U)" && _SSF_ADDED_ANY=1 ;;
azahar*) _ssf_add_appimage "$_base" "Azahar (3DS)" && _SSF_ADDED_ANY=1 ;;
pcsx2*) _ssf_add_appimage "$_base" "PCSX2 (PS2)" && _SSF_ADDED_ANY=1 ;;
*) _ssf_add_appimage "$_base" && _SSF_ADDED_ANY=1 ;;
esac
done
shopt -u nullglob
if [ "$_SSF_ADDED_ANY" = 0 ]; then
echo "No emulator AppImages found in $_SSF_EMU_DIR yet — download them first: sudo ./setup.sh wolf"
fi fi
if [ "$_SSF_ADDED_ANY" = 1 ]; then if [ "$_SSF_ADDED_ANY" = 1 ]; then
@@ -4573,7 +4613,8 @@ SYNCPY
echo " ./manage.sh steam-add-nonsteam-game [name] [display name]" echo " ./manage.sh steam-add-nonsteam-game [name] [display name]"
echo " - Add an emulator (emulators/) as a non-Steam game, no GUI needed" echo " - Add an emulator (emulators/) as a non-Steam game, no GUI needed"
echo " ./manage.sh steam-setup-frontends - Wait for Steam sign-in (QR code via Moonlight), then add" echo " ./manage.sh steam-setup-frontends - Wait for Steam sign-in (QR code via Moonlight), then add"
echo " downloaded ES-DE/RetroArch AppImages to Steam" echo " EVERY downloaded emulator AppImage (ES-DE, RetroArch,"
echo " Cemu, Azahar, PCSX2, Dolphin, ...) to Steam"
echo " ./manage.sh cemu-clone-controller [slot 0-3] [uuid] [display name]" echo " ./manage.sh cemu-clone-controller [slot 0-3] [uuid] [display name]"
echo " - Clone a working Cemu controller mapping onto a new device slot" echo " - Clone a working Cemu controller mapping onto a new device slot"
echo " ./manage.sh cemu-sync-controllers - Auto-detect connected controllers via SDL and clone mappings onto all of them" echo " ./manage.sh cemu-sync-controllers - Auto-detect connected controllers via SDL and clone mappings onto all of them"
@@ -4962,6 +5003,35 @@ PYEOF
# Hand the folder back to the real user # Hand the folder back to the real user
chown -R "$ACTUAL_USER:$ACTUAL_USER" "$WOLF_DIR" chown -R "$ACTUAL_USER:$ACTUAL_USER" "$WOLF_DIR"
# ── Optional: auto-wire already-downloaded emulators into Steam ──────────
# Steam's own shortcuts.vdf (and the userdata/<id>/ dir it lives under)
# only exists once Steam has actually been signed into at least once —
# meaningless on a brand-new install, since Steam hasn't even been opened
# in Moonlight yet at this point in a first run. But on a RERUN of this
# module (sudo ./setup.sh wolf again, after you've since signed in),
# every AppImage already sitting in emulators/ can go straight into
# Steam's library with no extra manual step. No blocking here: this is
# a quick, one-shot check for a Steam profile that already exists — the
# actual up-to-10-minutes sign-in wait lives in
# 'manage.sh steam-setup-frontends' itself (re-invoked below, not
# duplicated), and only ever triggers there if this check somehow raced
# against a sign-in that hadn't finished landing on disk yet.
if echo "$_APP_KEYS" | grep -qw steam; then
local _WOLF_ANY_STEAM_UID=""
_WOLF_ANY_STEAM_UID=$(find "$WOLF_STATE_DIR" -maxdepth 2 -type d -name Steam 2>/dev/null \
| while IFS= read -r _sd; do ls "$_sd/.steam/steam/userdata/" 2>/dev/null | head -1; done | head -1)
if [ -n "$_WOLF_ANY_STEAM_UID" ]; then
log_info "Steam is already signed in — adding downloaded emulators to Steam's library..."
(cd "$WOLF_DIR" && bash manage.sh steam-setup-frontends) \
|| log_warning "Couldn't auto-add emulators to Steam — run manually: cd $WOLF_DIR && ./manage.sh steam-setup-frontends"
else
log_info "Once you've signed into Steam via Moonlight, run this to add every downloaded"
log_info "emulator (Cemu, ES-DE, RetroArch, etc.) to Steam's library — or just re-run"
log_info "'sudo ./setup.sh wolf' after signing in and it'll be done automatically:"
log_info " cd $WOLF_DIR && ./manage.sh steam-setup-frontends"
fi
fi
local ALL_IPS local ALL_IPS
ALL_IPS=$(ip -4 addr show | grep -oP '(?<=inet )\d+\.\d+\.\d+\.\d+(?=/)' | grep -v '^127\.') ALL_IPS=$(ip -4 addr show | grep -oP '(?<=inet )\d+\.\d+\.\d+\.\d+(?=/)' | grep -v '^127\.')
@@ -5069,8 +5139,7 @@ PYEOF
echo " 4 controllers, one game (e.g. Cemu/Wii U)? Steam Input tells identical" echo " 4 controllers, one game (e.g. Cemu/Wii U)? Steam Input tells identical"
echo " controllers apart by device path, not just SDL GUID — add the emulator" echo " controllers apart by device path, not just SDL GUID — add the emulator"
echo " to Steam as a non-Steam game instead of launching it from ES-DE:" echo " to Steam as a non-Steam game instead of launching it from ES-DE:"
echo " ./manage.sh steam-setup-frontends # ES-DE/RetroArch AppImages into Steam" echo " ./manage.sh steam-setup-frontends # adds every downloaded emulator AppImage to Steam"
echo " ./manage.sh steam-add-nonsteam-game cemu"
echo " ./manage.sh cemu-clone-controller / cemu-sync-controllers" echo " ./manage.sh cemu-clone-controller / cemu-sync-controllers"
echo " For the ES-DE/RetroArch Wolf apps directly, force distinct virtual pad" echo " For the ES-DE/RetroArch Wolf apps directly, force distinct virtual pad"
echo " types per slot instead: ./manage.sh controllers (see README.md)" echo " types per slot instead: ./manage.sh controllers (see README.md)"
@@ -5155,10 +5224,33 @@ cd $WOLF_DIR
Run \`./manage.sh install-completion\` once, then re-open your shell (or Run \`./manage.sh install-completion\` once, then re-open your shell (or
\`source ~/.bashrc\`). After that, \`./manage.sh <TAB><TAB>\` lists all commands. \`source ~/.bashrc\`). After that, \`./manage.sh <TAB><TAB>\` lists all commands.
## Adding an emulator to Steam as a non-Steam game ## Getting downloaded emulators into Steam — the easy way
Steam's own "Add a Non-Steam Game" is a Big Picture file-browser flow — Downloading an emulator AppImage (\`sudo ./setup.sh wolf\`'s Cemu/Azahar/
usable through Moonlight, but slow to click through for something you're PCSX2/Dolphin/ES-DE/RetroArch prompts) only puts the file in \`emulators/\`
scripting or repeating. This does the same thing directly: — it doesn't touch Steam's own library on its own, since that step runs
before Steam has even been signed into. Once you've signed into Steam via
Moonlight, one command adds everything already downloaded:
\`\`\`bash
cd $WOLF_DIR && ./manage.sh steam-setup-frontends
\`\`\`
This scans \`emulators/\` and adds every AppImage found (Cemu, Azahar,
PCSX2, Dolphin, ES-DE, RetroArch — whichever prompts you said yes to) as
a Steam non-Steam game in one pass; see the section below for exactly how
it waits for sign-in. **You don't even need to run this yourself on a
rerun** — \`sudo ./setup.sh wolf\` run again after you've signed into Steam
detects the signed-in profile automatically and adds everything for you
as the last step, no extra command needed. It's still worth knowing the
command directly for downloading one more emulator later without
re-running the whole installer.
## Adding a single emulator to Steam as a non-Steam game
\`steam-add-nonsteam-game\` is the one-off building block
\`steam-setup-frontends\` above calls for each emulator it finds — reach
for it directly when you only want to (re-)add one specific file, e.g.
after manually dropping in an AppImage the setup script doesn't know
about. Steam's own "Add a Non-Steam Game" is a Big Picture file-browser
flow — usable through Moonlight, but slow to click through for something
you're scripting or repeating. This does the same thing directly:
\`\`\`bash \`\`\`bash
cd $WOLF_DIR && ./manage.sh steam-add-nonsteam-game cemu cd $WOLF_DIR && ./manage.sh steam-add-nonsteam-game cemu
\`\`\` \`\`\`
@@ -5219,11 +5311,12 @@ cd $WOLF_DIR && ./manage.sh steam-setup-frontends
Starts Wolf if it isn't already up, checks whether Steam's already Starts Wolf if it isn't already up, checks whether Steam's already
signed in (proceeds immediately if so), otherwise prints the QR-code signed in (proceeds immediately if so), otherwise prints the QR-code
steps and waits (up to 10 minutes) for sign-in to complete, then adds steps and waits (up to 10 minutes) for sign-in to complete, then adds
whichever of ES-DE.AppImage/RetroArch.AppImage was downloaded as a Steam every AppImage already sitting in \`emulators/\` — not just ES-DE and
non-Steam game — re-using \`steam-add-nonsteam-game\` above rather than RetroArch, but Cemu/Azahar/PCSX2/Dolphin too — as a Steam non-Steam game,
duplicating its shortcuts.vdf-writing logic. Safe to re-run any time re-using \`steam-add-nonsteam-game\` above rather than duplicating its
(e.g. if it timed out waiting, or you downloaded the second AppImage shortcuts.vdf-writing logic. Safe to re-run any time (e.g. if it timed
later) — already-added shortcuts are updated in place, not duplicated. out waiting, or you downloaded another emulator since) — already-added
shortcuts are updated in place, not duplicated.
**Returning to Steam from ES-DE, without a second instance:** if ES-DE **Returning to Steam from ES-DE, without a second instance:** if ES-DE
is running as a Steam non-Steam game (via the AppImage above, not the is running as a Steam non-Steam game (via the AppImage above, not the