diff --git a/services/wolf.sh b/services/wolf.sh index 7cc3f7b..501c1b7 100644 --- a/services/wolf.sh +++ b/services/wolf.sh @@ -4191,17 +4191,21 @@ VDFPY echo "other native Linux AppImages don't run through Proton." ;; steam-setup-frontends) - # One command covering what the ES-DE/RetroArch AppImage download - # step in setup.sh can't finish on its own: that step runs before - # Wolf/Steam containers even exist, so it can only download the - # AppImages and print instructions. This picks up from there — - # start Steam if needed, WAIT for it to be signed in (Steam Guard's - # QR-code sign-in itself can't be scripted: it needs a phone - # approving a prompt, so this only polls for the result, never - # performs the sign-in), then add whichever AppImage(s) already got - # downloaded as Steam non-Steam games via the existing + # One command covering what the emulator AppImage download step in + # setup.sh can't finish on its own: that step runs before Wolf/Steam + # containers even exist, so it can only download the AppImages and + # print instructions. This picks up from there — start Steam if + # needed, WAIT for it to be signed in (Steam Guard's QR-code sign-in + # itself can't be scripted: it needs a phone approving a prompt, so + # this only polls for the result, never performs the sign-in), then + # add EVERY AppImage already sitting in emulators/ (ES-DE, RetroArch, + # 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 - # 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 echo "Starting Wolf (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 _SSF_EMU_DIR="$GAME_DIR/emulators" _SSF_ADDED_ANY=0 - if [ -f "$_SSF_EMU_DIR/ES-DE.AppImage" ]; then - "$0" steam-add-nonsteam-game es-de "EmulationStation (ES-DE)" && _SSF_ADDED_ANY=1 - else - echo "ES-DE.AppImage not found in $_SSF_EMU_DIR — download it first: sudo ./setup.sh wolf" - fi - if [ -f "$_SSF_EMU_DIR/RetroArch.AppImage" ]; then - "$0" steam-add-nonsteam-game retroarch "RetroArch" && _SSF_ADDED_ANY=1 - else - echo "RetroArch.AppImage not found in $_SSF_EMU_DIR — download it first: sudo ./setup.sh wolf" + # realpaths already registered — so a fixed-name symlink + # (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 + "$0" steam-add-nonsteam-game "$_file" + fi + } + + # Fixed-name symlinks first, so their friendly display names win over + # 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 if [ "$_SSF_ADDED_ANY" = 1 ]; then @@ -4573,7 +4613,8 @@ SYNCPY echo " ./manage.sh steam-add-nonsteam-game [name] [display name]" 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 " 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 " - 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" @@ -4962,6 +5003,35 @@ PYEOF # Hand the folder back to the real user chown -R "$ACTUAL_USER:$ACTUAL_USER" "$WOLF_DIR" + # ── Optional: auto-wire already-downloaded emulators into Steam ────────── + # Steam's own shortcuts.vdf (and the userdata// 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 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 " 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 " ./manage.sh steam-setup-frontends # ES-DE/RetroArch AppImages into Steam" - echo " ./manage.sh steam-add-nonsteam-game cemu" + echo " ./manage.sh steam-setup-frontends # adds every downloaded emulator AppImage to Steam" echo " ./manage.sh cemu-clone-controller / cemu-sync-controllers" echo " For the ES-DE/RetroArch Wolf apps directly, force distinct virtual pad" 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 \`source ~/.bashrc\`). After that, \`./manage.sh \` lists all commands. -## Adding an emulator to Steam as a non-Steam game -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: +## Getting downloaded emulators into Steam — the easy way +Downloading an emulator AppImage (\`sudo ./setup.sh wolf\`'s Cemu/Azahar/ +PCSX2/Dolphin/ES-DE/RetroArch prompts) only puts the file in \`emulators/\` +— 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 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 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 -whichever of ES-DE.AppImage/RetroArch.AppImage was downloaded as a Steam -non-Steam game — re-using \`steam-add-nonsteam-game\` above rather than -duplicating its shortcuts.vdf-writing logic. Safe to re-run any time -(e.g. if it timed out waiting, or you downloaded the second AppImage -later) — already-added shortcuts are updated in place, not duplicated. +every AppImage already sitting in \`emulators/\` — not just ES-DE and +RetroArch, but Cemu/Azahar/PCSX2/Dolphin too — as a Steam non-Steam game, +re-using \`steam-add-nonsteam-game\` above rather than duplicating its +shortcuts.vdf-writing logic. Safe to re-run any time (e.g. if it timed +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 is running as a Steam non-Steam game (via the AppImage above, not the