|
|
@@ -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
|