Procházet zdrojové kódy

Mise à jour de 'scripts/run-steam-game'

penta před 4 týdny
rodič
revize
063bc20530
1 změnil soubory, kde provedl 61 přidání a 31 odebrání
  1. 61 31
      scripts/run-steam-game

+ 61 - 31
scripts/run-steam-game

@@ -3,12 +3,13 @@
 set -u
 
 if [[ $# -lt 2 ]]; then
-    echo "Usage: $0 <Steam AppID> <process regex>" >&2
+    echo "Usage: $0 <Steam AppID> <process name>" >&2
+    echo "Example: $0 108800 Crysis2.exe" >&2
     exit 2
 fi
 
 APPID="$1"
-PROCESS_REGEX="$2"
+PROCESS_NAME="$2"
 
 START_TIMEOUT="${START_TIMEOUT:-120}"
 EXIT_STABLE_TIME="${EXIT_STABLE_TIME:-3}"
@@ -16,6 +17,8 @@ EXIT_STABLE_TIME="${EXIT_STABLE_TIME:-3}"
 SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
 LOG_FILE="${SCRIPT_DIR}/steam-game.log"
 
+WRAPPER_PID="$$"
+
 log() {
     printf '[%s] [STEAM:%s] %s\n' \
         "$(date '+%Y-%m-%d %H:%M:%S')" \
@@ -23,16 +26,9 @@ log() {
         "$*" >> "${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.
+# Retourne les PID dont la ligne de commande contient littéralement
+# le nom de processus demandé.
 #
 game_pids() {
     local proc
@@ -43,8 +39,15 @@ game_pids() {
     for proc in /proc/[0-9]*; do
         pid="${proc##*/}"
 
-        # Ne jamais nous matcher nous-mêmes.
-        [[ "${pid}" == "$$" ]] && continue
+        # Ne jamais matcher le wrapper principal.
+        [[ "${pid}" == "${WRAPPER_PID}" ]] && continue
+
+        # game_pids() tourne dans un sous-shell à cause de :
+        #
+        #   mapfile -t pids < <(game_pids)
+        #
+        # Il faut donc également ignorer ce sous-shell.
+        [[ "${pid}" == "${BASHPID}" ]] && continue
 
         [[ -r "${proc}/cmdline" ]] || continue
 
@@ -56,48 +59,72 @@ game_pids() {
 
         cmdline="${argv[*]}"
 
-        if [[ "${cmdline}" =~ ${PROCESS_REGEX} ]]; then
+        if [[ "${cmdline}" == *"${PROCESS_NAME}"* ]]; then
             printf '%s\n' "${pid}"
         fi
     done
 }
 
+#
+# Termine le ou les processus correspondant au jeu.
+#
 terminate_game() {
     local -a pids
 
     mapfile -t pids < <(game_pids)
 
-    if [[ ${#pids[@]} -gt 0 ]]; then
-        log "Stopping game processes: ${pids[*]}"
+    if [[ ${#pids[@]} -eq 0 ]]; then
+        log "No game process to terminate"
+        return 0
+    fi
 
-        kill -TERM "${pids[@]}" 2>/dev/null || true
+    log "Stopping game processes: ${pids[*]}"
 
-        sleep 3
+    kill -TERM "${pids[@]}" 2>/dev/null || true
 
-        mapfile -t pids < <(game_pids)
+    sleep 3
 
-        if [[ ${#pids[@]} -gt 0 ]]; then
-            log "Force stopping remaining processes: ${pids[*]}"
-            kill -KILL "${pids[@]}" 2>/dev/null || true
-        fi
+    mapfile -t pids < <(game_pids)
+
+    if [[ ${#pids[@]} -gt 0 ]]; then
+        log "Force stopping remaining processes: ${pids[*]}"
+        kill -KILL "${pids[@]}" 2>/dev/null || true
     fi
 }
 
 #
-# Important pour la suite :
-# si Sunshine arrête ce wrapper, on ferme également le jeu.
+# Si Sunshine termine le wrapper, terminer également le jeu.
 #
-trap 'log "Wrapper received termination signal"; terminate_game; exit 143' \
-    TERM INT HUP
+on_termination() {
+    log "Wrapper received termination signal"
+
+    terminate_game
+
+    exit 143
+}
 
+trap on_termination TERM INT HUP
+
+#
+# Vérifications.
+#
+if ! command -v steam >/dev/null 2>&1; then
+    log "ERROR: steam command not found"
+    exit 127
+fi
+
+log "Wrapper started with PID ${WRAPPER_PID}"
 log "Launching Steam AppID ${APPID}"
-log "Process regex: ${PROCESS_REGEX}"
+log "Process name: ${PROCESS_NAME}"
 
-nohup steam -applaunch "${APPID}" \
+#
+# Demander à Steam de lancer le jeu.
+#
+steam -applaunch "${APPID}" \
     >> "${LOG_FILE}" 2>&1 &
 
 #
-# Attendre que le vrai processus du jeu apparaisse.
+# Attendre l'apparition du véritable processus du jeu.
 #
 start_time="${SECONDS}"
 
@@ -110,7 +137,7 @@ while true; do
     fi
 
     if (( SECONDS - start_time >= START_TIMEOUT )); then
-        log "ERROR: game did not appear within ${START_TIMEOUT}s"
+        log "ERROR: Game did not appear within ${START_TIMEOUT} seconds"
         exit 124
     fi
 
@@ -130,6 +157,7 @@ while true; do
     else
         if [[ -z "${missing_since}" ]]; then
             missing_since="${SECONDS}"
+            log "Game process disappeared, waiting ${EXIT_STABLE_TIME}s"
         fi
 
         if (( SECONDS - missing_since >= EXIT_STABLE_TIME )); then
@@ -141,4 +169,6 @@ while true; do
     sleep 1
 done
 
+log "Wrapper exiting normally"
+
 exit 0