#!/usr/bin/env bash set -u if [[ $# -lt 2 ]]; then echo "Usage: $0 " >&2 exit 2 fi APPID="$1" PROCESS_REGEX="$2" START_TIMEOUT="${START_TIMEOUT:-120}" EXIT_STABLE_TIME="${EXIT_STABLE_TIME:-3}" SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" LOG_FILE="${SCRIPT_DIR}/steam-game.log" log() { printf '[%s] [STEAM:%s] %s\n' \ "$(date '+%Y-%m-%d %H:%M:%S')" \ "${APPID}" \ "$*" >> "${LOG_FILE}" } if ! command -v steam >/dev/null 2>&1; then log "ERROR: steam command not found" exit 127 fi # # PIDs du jeu. # # On inspecte /proc nous-mêmes afin d'éviter que pgrep -f ne matche # accidentellement le wrapper avec le regex passé en argument. # game_pids() { local proc local pid local cmdline local -a argv for proc in /proc/[0-9]*; do pid="${proc##*/}" # Ne jamais nous matcher nous-mêmes. [[ "${pid}" == "$$" ]] && continue [[ -r "${proc}/cmdline" ]] || continue argv=() mapfile -d '' -t argv < "${proc}/cmdline" 2>/dev/null || true [[ ${#argv[@]} -gt 0 ]] || continue cmdline="${argv[*]}" if [[ "${cmdline}" =~ ${PROCESS_REGEX} ]]; then printf '%s\n' "${pid}" fi done } terminate_game() { local -a pids mapfile -t pids < <(game_pids) if [[ ${#pids[@]} -gt 0 ]]; then log "Stopping game processes: ${pids[*]}" kill -TERM "${pids[@]}" 2>/dev/null || true sleep 3 mapfile -t pids < <(game_pids) if [[ ${#pids[@]} -gt 0 ]]; then log "Force stopping remaining processes: ${pids[*]}" kill -KILL "${pids[@]}" 2>/dev/null || true fi fi } # # Important pour la suite : # si Sunshine arrête ce wrapper, on ferme également le jeu. # trap 'log "Wrapper received termination signal"; terminate_game; exit 143' \ TERM INT HUP log "Launching Steam AppID ${APPID}" log "Process regex: ${PROCESS_REGEX}" nohup steam -applaunch "${APPID}" \ >> "${LOG_FILE}" 2>&1 & # # Attendre que le vrai processus du jeu apparaisse. # start_time="${SECONDS}" while true; do mapfile -t pids < <(game_pids) if [[ ${#pids[@]} -gt 0 ]]; then log "Game detected: ${pids[*]}" break fi if (( SECONDS - start_time >= START_TIMEOUT )); then log "ERROR: game did not appear within ${START_TIMEOUT}s" exit 124 fi sleep 1 done # # Rester vivant aussi longtemps que le jeu. # missing_since="" while true; do mapfile -t pids < <(game_pids) if [[ ${#pids[@]} -gt 0 ]]; then missing_since="" else if [[ -z "${missing_since}" ]]; then missing_since="${SECONDS}" fi if (( SECONDS - missing_since >= EXIT_STABLE_TIME )); then log "Game exited" break fi fi sleep 1 done exit 0