@@ -331,6 +331,34 @@ create_external_shortcut() {
331331 [ -n " $extracted " ] && app_icon=" $extracted "
332332 fi
333333
334+ # GOG: goggame-*.info marks a GOG game; prefer GalaxyClient for auth/DRM/overlay.
335+ local launch_exe=" $exe_bin " launch_dir=" $exe_dir " launch_args=" "
336+ local gog_info
337+ gog_info=$( find " $exe_dir " -maxdepth 1 -name " goggame-*.info" 2> /dev/null | head -1)
338+ if [ -n " $gog_info " ]; then
339+ local gog_id; gog_id=$( basename " $gog_info " | sed ' s/goggame-//;s/\.info//' )
340+ if command -v python3 & > /dev/null && [ -z " ${2:- } " ]; then
341+ local json_name
342+ json_name=$( python3 -c "
343+ import json,sys
344+ try:
345+ d=json.load(open(sys.argv[1]))
346+ print(d.get('name',''))
347+ except: pass
348+ " " $gog_info " 2> /dev/null)
349+ [ -n " $json_name " ] && display_name=" $json_name "
350+ fi
351+ local galaxy_exe=" $WINEPREFIX /pfx/drive_c/Program Files (x86)/GOG Galaxy/GalaxyClient.exe"
352+ if [ -f " $galaxy_exe " ]; then
353+ launch_exe=" GalaxyClient.exe"
354+ launch_dir=" $WINEPREFIX /pfx/drive_c/Program Files (x86)/GOG Galaxy"
355+ launch_args=" /command=runGame /gameId=${gog_id} "
356+ print_info " GOG game ID ${gog_id} — launching via GalaxyClient"
357+ else
358+ print_warning " GOG Galaxy not found in prefix; launching game exe directly"
359+ fi
360+ fi
361+
334362 local launcher=" $BIN_DIR /${app_key} "
335363 local desktop=" $APPS_DIR /${app_key} .desktop"
336364
@@ -345,8 +373,8 @@ export WINEDLLOVERRIDES="winemenubuilder.exe=d"
345373export WINEESYNC="\$ {WINEESYNC:-1}" WINEFSYNC="\$ {WINEFSYNC:-1}"
346374
347375[ -d "\$ {_dd}" ] && rm -f "\$ {_dd}/z:" "\$ {_dd}/z::" 2>/dev/null || true
348- cd "${exe_dir } " || exit 1
349- "${PROTON_DIR} /proton" run "${exe_bin} " >"${WINE_DIR} /${app_key} .log" 2>&1 &
376+ cd "${launch_dir } " || exit 1
377+ "${PROTON_DIR} /proton" run "${launch_exe} " ${launch_args} >"${WINE_DIR} /${app_key} .log" 2>&1 &
350378( _i=0; while [ \$ {_i} -lt 20 ]; do rm -f "\$ {_dd}/z:" "\$ {_dd}/z::" 2>/dev/null; sleep 0.5; _i=\$ ((\$ {_i}+1)); done ) &
351379LAUNCHER_EOF
352380 chmod +x " $launcher "
@@ -369,3 +397,89 @@ DESKTOP_EOF
369397 print_success " Shortcut created: ${display_name} "
370398 print_info " Key: ${app_key} | Icon: $( basename " ${app_icon} " ) "
371399}
400+
401+ # Scan a path (or default prefix + common GOG locations) for GOG games and Windows .lnk
402+ # shortcuts, then create Proton-based .desktop entries for each discovered game.
403+ # Usage: scan_shortcuts [path]
404+ scan_shortcuts () {
405+ local scan_arg=" ${1:- } "
406+ local created=0 skipped=0
407+
408+ print_info " Scanning for GOG games and Windows shortcuts..."
409+
410+ # Build list of directories to search
411+ local -a roots=()
412+ if [ -n " $scan_arg " ]; then
413+ roots=(" $scan_arg " )
414+ else
415+ for d in \
416+ " $WINEPREFIX /pfx/drive_c/users/steamuser/Desktop" \
417+ " $WINEPREFIX /pfx/drive_c/ProgramData/Microsoft/Windows/Start Menu/Programs" \
418+ " ${HOME} /Games" " ${HOME} /GOG Games" " ${HOME} /Games/GOG Galaxy" ; do
419+ [ -d " $d " ] && roots+=(" $d " )
420+ done
421+ fi
422+
423+ if [ ${# roots[@]} -eq 0 ]; then
424+ print_warning " No directories to scan. Try: wig scan-shortcuts /path/to/games/"
425+ return 1
426+ fi
427+
428+ # Track processed dirs to avoid duplicate shortcuts from .lnk + goggame-*.info in same dir
429+ local -A _seen=()
430+
431+ # Pass 1: GOG game directories identified by goggame-*.info
432+ while IFS= read -r -d ' ' info_file; do
433+ local game_dir; game_dir=$( dirname " $info_file " )
434+ [[ -n " ${_seen[$game_dir]:- } " ]] && continue
435+ _seen[$game_dir ]=1
436+
437+ # Parse primary play task exe from the info JSON
438+ local primary_exe=" "
439+ if command -v python3 & > /dev/null; then
440+ primary_exe=$( python3 -c "
441+ import json, sys
442+ try:
443+ d = json.load(open(sys.argv[1]))
444+ for t in d.get('playTasks', []):
445+ if t.get('isPrimary') and t.get('type') == 'FileTask':
446+ print(t.get('path', '').replace('\\\\\\\\ ', '/').strip('/'))
447+ break
448+ except: pass
449+ " " $info_file " 2> /dev/null)
450+ fi
451+
452+ # Fallback: largest .exe in the game dir
453+ if [ -z " $primary_exe " ] || [ ! -f " $game_dir /$primary_exe " ]; then
454+ local _bf=" " _bsz=0 _f _sz
455+ while IFS= read -r -d ' ' _f; do
456+ _sz=$( stat -c%s " $_f " 2> /dev/null || echo 0)
457+ (( _sz > _bsz )) && { _bsz=$_sz ; _bf=" $_f " ; }
458+ done < <( find " $game_dir " -maxdepth 1 -name " *.exe" -print0 2> /dev/null)
459+ [ -n " $_bf " ] && primary_exe=$( basename " $_bf " )
460+ fi
461+
462+ if [ -n " $primary_exe " ] && [ -f " $game_dir /$primary_exe " ]; then
463+ print_info " GOG game: $( basename " $game_dir " ) → $primary_exe "
464+ create_external_shortcut " $game_dir /$primary_exe " && (( created++ )) || (( skipped++ ))
465+ fi
466+ done < <( find " ${roots[@]} " -name " goggame-*.info" -print0 2> /dev/null)
467+
468+ # Pass 2: Windows .lnk shortcuts not already covered by goggame detection
469+ while IFS= read -r -d ' ' lnk; do
470+ local lnk_dir; lnk_dir=$( dirname " $lnk " )
471+ [[ -n " ${_seen[$lnk_dir]:- } " ]] && continue
472+ local lnk_name; lnk_name=$( basename " $lnk " .lnk)
473+ case " ${lnk_name,,} " in
474+ " gog galaxy" |" gog launcher" |" gog galaxy updater" ) continue ;;
475+ esac
476+ print_info " LNK: $lnk_name "
477+ create_external_shortcut " $lnk " " $lnk_name " && (( created++ )) || (( skipped++ ))
478+ done < <( find " ${roots[@]} " -name " *.lnk" -print0 2> /dev/null)
479+
480+ if (( created + skipped == 0 )) ; then
481+ print_warning " No games found. Try specifying the games directory: wig scan-shortcuts /path/to/games/"
482+ else
483+ print_success " Scan complete — created: $created skipped/failed: $skipped "
484+ fi
485+ }
0 commit comments