From ab4ee8b9d6ee731a21e8634bfefd2c7db13086ff Mon Sep 17 00:00:00 2001 From: bilal Date: Sat, 27 Jun 2026 18:47:58 +0300 Subject: [PATCH] Fix Steam login flicker with 2GB shm and stable launch scripts. Use tini-backed entrypoint, two-phase Steam startup, and a window keeper so CEF UI and the fluxbox toolbar stay visible in Moonlight. Co-authored-by: Cursor --- Dockerfile | 31 ++----- docker-compose.yml | 1 + players/p1_config/apps.json | 15 +--- players/p1_config/keep-steam-window.sh | 47 ++++++++++ players/p1_config/start-steam.sh | 118 +++++++++++++++++++++++++ players/p2_config/apps.json | 15 +--- players/p2_config/keep-steam-window.sh | 47 ++++++++++ players/p2_config/start-steam.sh | 118 +++++++++++++++++++++++++ players/p3_config/apps.json | 15 +--- players/p3_config/keep-steam-window.sh | 47 ++++++++++ players/p3_config/start-steam.sh | 118 +++++++++++++++++++++++++ players/p4_config/apps.json | 15 +--- players/p4_config/keep-steam-window.sh | 47 ++++++++++ players/p4_config/start-steam.sh | 118 +++++++++++++++++++++++++ scripts/entrypoint.sh | 31 +++++++ scripts/fluxbox/init | 17 ++++ 16 files changed, 720 insertions(+), 80 deletions(-) create mode 100644 players/p1_config/keep-steam-window.sh create mode 100644 players/p1_config/start-steam.sh create mode 100644 players/p2_config/keep-steam-window.sh create mode 100644 players/p2_config/start-steam.sh create mode 100644 players/p3_config/keep-steam-window.sh create mode 100644 players/p3_config/start-steam.sh create mode 100644 players/p4_config/keep-steam-window.sh create mode 100644 players/p4_config/start-steam.sh create mode 100644 scripts/entrypoint.sh create mode 100644 scripts/fluxbox/init diff --git a/Dockerfile b/Dockerfile index 251107e..e21d7ce 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,7 @@ RUN if [ -n "$APT_PROXY" ]; then \ RUN dpkg --add-architecture i386 && \ apt-get update && apt-get install -y \ xserver-xorg-core xserver-xorg-video-dummy xserver-xorg-input-libinput \ - fluxbox dbus-x11 xauth xfonts-base x11-xserver-utils xinput \ + fluxbox dbus-x11 xauth xfonts-base x11-xserver-utils xinput xdotool tini \ software-properties-common wget curl ca-certificates locales pciutils \ libboost-chrono1.74.0 libboost-filesystem1.74.0 libboost-locale1.74.0 \ libboost-program-options1.74.0 libboost-thread1.74.0 \ @@ -23,8 +23,7 @@ RUN dpkg --add-architecture i386 && \ && add-apt-repository multiverse \ && apt-get update -# 2. Скачиваем оригинальный рабочий пакет Sunshine по вашей ссылке -# ВНИМАНИЕ: Замените маркер ниже на вашу ссылку из браузера, сохранив кавычки! +# 2. Скачиваем проверенный пакет Sunshine RUN wget "https://github.com/LizardByte/Sunshine/releases/download/v0.20.0/sunshine-ubuntu-22.04-amd64.deb" -O /tmp/sunshine.deb \ && chmod +x /tmp/sunshine.deb @@ -84,26 +83,10 @@ EndSubSection\n\ EndSection\n\ ' > /etc/X11/xorg-dummy.conf -# 5. Поднимаем Xorg dummy, fluxbox и Sunshine -RUN echo '#!/bin/bash\n\ -set -e\n\ -rm -f /tmp/.X99-lock /tmp/.X11-unix/X99\n\ -id steam >/dev/null 2>&1 || useradd -m -s /bin/bash steam\n\ -mkdir -p /home/steam/.local/share/Steam /tmp/xdg-steam\n\ -ln -sfn /home/steam/.local/share/Steam /home/steam/.steam\n\ -chown -R steam:steam /home/steam /tmp/xdg-steam\n\ -mkdir -p /run/dbus\n\ -dbus-daemon --system --fork || true\n\ -Xorg :99 -config /etc/X11/xorg-dummy.conf -nolisten tcp -noreset +extension GLX +extension RANDR +extension RENDER &\n\ -export DISPLAY=:99\n\ -export HOME=/root\n\ -export LANG=en_US.UTF-8\n\ -export LC_ALL=en_US.UTF-8\n\ -sleep 3\n\ -fluxbox &\n\ -sleep 2\n\ -exec /usr/bin/sunshine' > /entrypoint.sh && chmod +x /entrypoint.sh \ - && chmod +x /entrypoint.sh +# 5. Entrypoint, fluxbox и tini +COPY scripts/entrypoint.sh /entrypoint.sh +COPY scripts/fluxbox /etc/game-server/fluxbox +RUN chmod +x /entrypoint.sh USER root -ENTRYPOINT ["/entrypoint.sh"] +ENTRYPOINT ["/usr/bin/tini", "--", "/entrypoint.sh"] diff --git a/docker-compose.yml b/docker-compose.yml index d73eb30..b9081ba 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,6 +9,7 @@ x-game-template: &game-template - seccomp:unconfined - apparmor:unconfined ipc: shareable + shm_size: "2gb" environment: NVIDIA_DRIVER_CAPABILITIES: all DISPLAY: ":99" diff --git a/players/p1_config/apps.json b/players/p1_config/apps.json index 40e90b3..1eebac1 100644 --- a/players/p1_config/apps.json +++ b/players/p1_config/apps.json @@ -6,7 +6,7 @@ { "name": "Steam Big Picture", "detached": [ - "bash -lc 'id steam >/dev/null 2>&1 || useradd -m -s /bin/bash steam; ROOT=/home/steam/.local/share/Steam/debian-installation; mkdir -p ${ROOT} /tmp/xdg-steam /home/steam/tmp; ln -sfn /home/steam/.local/share/Steam /home/steam/.steam; chown -R steam:steam /home/steam /tmp/xdg-steam; pkill -u steam -f \"steam|steamwebhelper|steam-runtime\" >/dev/null 2>&1 || true; sleep 1; runuser -u steam -- env DISPLAY=:99 HOME=/home/steam XDG_RUNTIME_DIR=/tmp/xdg-steam TMPDIR=/home/steam/tmp LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 nohup bash -lc \"cd ${ROOT} && exec /usr/games/steam -gamepadui -fullscreen -no-cef-sandbox\" >/home/steam/steam-app.log 2>&1 < /dev/null &'" + "bash -lc '/root/.config/sunshine/start-steam.sh'" ], "prep-cmd": [ { @@ -28,19 +28,6 @@ } ], "image-path": "desktop.png" - }, - { - "name": "Steam Manual Start", - "detached": [ - "bash -lc 'id steam >/dev/null 2>&1 || useradd -m -s /bin/bash steam; ROOT=/home/steam/.local/share/Steam/debian-installation; mkdir -p ${ROOT} /tmp/xdg-steam /home/steam/tmp; ln -sfn /home/steam/.local/share/Steam /home/steam/.steam; chown -R steam:steam /home/steam /tmp/xdg-steam; pkill -u steam -f \"steam|steamwebhelper|steam-runtime\" >/dev/null 2>&1 || true; sleep 1; runuser -u steam -- env DISPLAY=:99 HOME=/home/steam XDG_RUNTIME_DIR=/tmp/xdg-steam TMPDIR=/home/steam/tmp LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 nohup bash -lc \"cd ${ROOT} && exec /usr/games/steam -gamepadui -fullscreen -no-cef-sandbox\" >/home/steam/steam-app.log 2>&1 < /dev/null &'" - ], - "prep-cmd": [ - { - "do": "", - "undo": "" - } - ], - "image-path": "steam.png" } ] } diff --git a/players/p1_config/keep-steam-window.sh b/players/p1_config/keep-steam-window.sh new file mode 100644 index 0000000..019010a --- /dev/null +++ b/players/p1_config/keep-steam-window.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +export DISPLAY=:99 + +SCREEN_W=1920 +SCREEN_H=1080 +TOOLBAR_H=32 + +find_window() { + local title="$1" + xwininfo -root -tree 2>/dev/null | grep "\"${title}\"" | head -1 | awk '{print $1}' +} + +window_state() { + xwininfo -id "$1" 2>/dev/null | awk '/Map State/{print $NF}' +} + +center_window() { + local wid="$1" + local geom w h x y + geom="$(xwininfo -id "${wid}" 2>/dev/null | awk '/-geometry/{print $2}')" + w="${geom%%x*}" + h="${geom#*x}"; h="${h%%+*}" + [ -n "${w}" ] && [ -n "${h}" ] || return 0 + x=$(( (SCREEN_W - w) / 2 )) + y=$(( (SCREEN_H - TOOLBAR_H - h) / 2 )) + [ "${y}" -lt 0 ] && y=0 + xdotool windowmove "${wid}" "${x}" "${y}" 2>/dev/null || true +} + +while pgrep -u steam -f "steam -srt-logger-opened" >/dev/null 2>&1; do + wid="" + for title in "Sign in to Steam" "Steam Big Picture Mode"; do + wid="$(find_window "${title}")" + [ -n "${wid}" ] && break + done + + if [ -n "${wid}" ]; then + state="$(window_state "${wid}")" + if [ "${state}" = "IsUnMapped" ] || [ -z "${state}" ]; then + xdotool windowmap "${wid}" 2>/dev/null || true + fi + xdotool windowraise "${wid}" 2>/dev/null || true + center_window "${wid}" + xdotool windowactivate "${wid}" 2>/dev/null || true + fi + sleep 0.5 +done diff --git a/players/p1_config/start-steam.sh b/players/p1_config/start-steam.sh new file mode 100644 index 0000000..8a172e4 --- /dev/null +++ b/players/p1_config/start-steam.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash +set -euo pipefail + +exec 9>/tmp/start-steam.lock +flock -n 9 || exit 0 + +id steam >/dev/null 2>&1 || useradd -m -s /bin/bash steam +STEAM_UID="$(id -u steam)" + +ROOT=/home/steam/.local/share/Steam/debian-installation +mkdir -p "${ROOT}" /tmp/xdg-steam /home/steam/tmp /run/dbus +ln -sfn /home/steam/.local/share/Steam /home/steam/.steam +chown -R steam:steam /home/steam /tmp/xdg-steam + +ensure_dbus() { + if ! dbus-send --system --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.ListNames >/dev/null 2>&1; then + rm -f /run/dbus/pid + dbus-daemon --system --fork >/dev/null 2>&1 || true + fi +} + +ensure_fluxbox() { + cp -f /etc/game-server/fluxbox/init /root/.fluxbox/init 2>/dev/null || true + if ps -eo stat=,comm= 2>/dev/null | awk '$2=="fluxbox" && $1 !~ /Z/ { exit 0 } END { exit 1 }'; then + FB="$(ps -eo pid=,stat=,comm= | awk '$3=="fluxbox" && $2 !~ /Z/ {print $1; exit}')" + DISPLAY=:99 fluxbox-remote reloadconfig 2>/dev/null || kill -USR1 "${FB}" 2>/dev/null || true + return 0 + fi + DISPLAY=:99 HOME=/root fluxbox >/dev/null 2>&1 & + sleep 1 +} + +restart_fluxbox() { + pkill -x fluxbox >/dev/null 2>&1 || true + sleep 1 + cp -f /etc/game-server/fluxbox/init /root/.fluxbox/init 2>/dev/null || true + DISPLAY=:99 HOME=/root fluxbox >/dev/null 2>&1 & + sleep 1 + DISPLAY=:99 xsetroot -solid "#3c3c3c" 2>/dev/null || true +} + +steam_running() { + pgrep -u steam -f "${ROOT}/ubuntu12_32/steam -srt-logger-opened" >/dev/null 2>&1 +} + +steam_ui_visible() { + DISPLAY=:99 xwininfo -root -tree 2>/dev/null | grep -qE "Steam Big Picture Mode|Sign in to Steam" +} + +ensure_window_keeper() { + command -v xdotool >/dev/null 2>&1 || return 0 + pgrep -f keep-steam-window.sh >/dev/null 2>&1 && return 0 + setsid bash /root/.config/sunshine/keep-steam-window.sh >/dev/null 2>&1 & +} + +schedule_gamepadui_once() { + [ -f /tmp/steam-gamepadui-done ] && return 0 + setsid bash -lc ' + for _ in $(seq 1 90); do + pgrep -u steam -f steamwebhelper >/dev/null 2>&1 && break + sleep 1 + done + sleep 5 + runuser -u steam -- env \ + DISPLAY=:99 \ + HOME=/home/steam \ + XDG_RUNTIME_DIR=/tmp/xdg-steam \ + TMPDIR=/home/steam/tmp \ + LANG=en_US.UTF-8 \ + LC_ALL=en_US.UTF-8 \ + /usr/games/steam steam://open/gamepadui >/dev/null 2>&1 || true + touch /tmp/steam-gamepadui-done + ' >/dev/null 2>&1 & +} + +stop_steam() { + pkill -9 -u steam -f "steam|steamwebhelper|steam-runtime|steam-runtime-launcher" >/dev/null 2>&1 || true + pkill -f keep-steam-window.sh >/dev/null 2>&1 || true + sleep 1 + rm -f /home/steam/.local/share/Steam/steam.pid \ + /home/steam/.local/share/Steam/steam.pipe \ + /home/steam/.local/share/Steam/steam.token \ + /tmp/steam-gamepadui-done + rm -rf /home/steam/.local/share/Steam/debian-installation/config/htmlcache + rm -rf /tmp/dumps/completed /tmp/dumps/*.lock 2>/dev/null || true + rm -f /dev/shm/u"${STEAM_UID}"-* /dev/shm/u"${STEAM_UID}"-ValveIPC* /dev/shm/.org.chromium.* /dev/shm/pulse-* 2>/dev/null || true +} + +ensure_dbus +restart_fluxbox + +if steam_running; then + if steam_ui_visible; then + ensure_window_keeper + exit 0 + fi + schedule_gamepadui_once + ensure_window_keeper + exit 0 +fi + +stop_steam +ensure_dbus +restart_fluxbox + +setsid runuser -u steam -- env \ + DISPLAY=:99 \ + HOME=/home/steam \ + XDG_RUNTIME_DIR=/tmp/xdg-steam \ + TMPDIR=/home/steam/tmp \ + LANG=en_US.UTF-8 \ + LC_ALL=en_US.UTF-8 \ + bash -lc "cd ${ROOT} && exec /usr/games/steam -silent -no-cef-sandbox" \ + >>/home/steam/steam-app.log 2>&1 & + +schedule_gamepadui_once +ensure_window_keeper +exit 0 diff --git a/players/p2_config/apps.json b/players/p2_config/apps.json index 40e90b3..1eebac1 100644 --- a/players/p2_config/apps.json +++ b/players/p2_config/apps.json @@ -6,7 +6,7 @@ { "name": "Steam Big Picture", "detached": [ - "bash -lc 'id steam >/dev/null 2>&1 || useradd -m -s /bin/bash steam; ROOT=/home/steam/.local/share/Steam/debian-installation; mkdir -p ${ROOT} /tmp/xdg-steam /home/steam/tmp; ln -sfn /home/steam/.local/share/Steam /home/steam/.steam; chown -R steam:steam /home/steam /tmp/xdg-steam; pkill -u steam -f \"steam|steamwebhelper|steam-runtime\" >/dev/null 2>&1 || true; sleep 1; runuser -u steam -- env DISPLAY=:99 HOME=/home/steam XDG_RUNTIME_DIR=/tmp/xdg-steam TMPDIR=/home/steam/tmp LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 nohup bash -lc \"cd ${ROOT} && exec /usr/games/steam -gamepadui -fullscreen -no-cef-sandbox\" >/home/steam/steam-app.log 2>&1 < /dev/null &'" + "bash -lc '/root/.config/sunshine/start-steam.sh'" ], "prep-cmd": [ { @@ -28,19 +28,6 @@ } ], "image-path": "desktop.png" - }, - { - "name": "Steam Manual Start", - "detached": [ - "bash -lc 'id steam >/dev/null 2>&1 || useradd -m -s /bin/bash steam; ROOT=/home/steam/.local/share/Steam/debian-installation; mkdir -p ${ROOT} /tmp/xdg-steam /home/steam/tmp; ln -sfn /home/steam/.local/share/Steam /home/steam/.steam; chown -R steam:steam /home/steam /tmp/xdg-steam; pkill -u steam -f \"steam|steamwebhelper|steam-runtime\" >/dev/null 2>&1 || true; sleep 1; runuser -u steam -- env DISPLAY=:99 HOME=/home/steam XDG_RUNTIME_DIR=/tmp/xdg-steam TMPDIR=/home/steam/tmp LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 nohup bash -lc \"cd ${ROOT} && exec /usr/games/steam -gamepadui -fullscreen -no-cef-sandbox\" >/home/steam/steam-app.log 2>&1 < /dev/null &'" - ], - "prep-cmd": [ - { - "do": "", - "undo": "" - } - ], - "image-path": "steam.png" } ] } diff --git a/players/p2_config/keep-steam-window.sh b/players/p2_config/keep-steam-window.sh new file mode 100644 index 0000000..019010a --- /dev/null +++ b/players/p2_config/keep-steam-window.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +export DISPLAY=:99 + +SCREEN_W=1920 +SCREEN_H=1080 +TOOLBAR_H=32 + +find_window() { + local title="$1" + xwininfo -root -tree 2>/dev/null | grep "\"${title}\"" | head -1 | awk '{print $1}' +} + +window_state() { + xwininfo -id "$1" 2>/dev/null | awk '/Map State/{print $NF}' +} + +center_window() { + local wid="$1" + local geom w h x y + geom="$(xwininfo -id "${wid}" 2>/dev/null | awk '/-geometry/{print $2}')" + w="${geom%%x*}" + h="${geom#*x}"; h="${h%%+*}" + [ -n "${w}" ] && [ -n "${h}" ] || return 0 + x=$(( (SCREEN_W - w) / 2 )) + y=$(( (SCREEN_H - TOOLBAR_H - h) / 2 )) + [ "${y}" -lt 0 ] && y=0 + xdotool windowmove "${wid}" "${x}" "${y}" 2>/dev/null || true +} + +while pgrep -u steam -f "steam -srt-logger-opened" >/dev/null 2>&1; do + wid="" + for title in "Sign in to Steam" "Steam Big Picture Mode"; do + wid="$(find_window "${title}")" + [ -n "${wid}" ] && break + done + + if [ -n "${wid}" ]; then + state="$(window_state "${wid}")" + if [ "${state}" = "IsUnMapped" ] || [ -z "${state}" ]; then + xdotool windowmap "${wid}" 2>/dev/null || true + fi + xdotool windowraise "${wid}" 2>/dev/null || true + center_window "${wid}" + xdotool windowactivate "${wid}" 2>/dev/null || true + fi + sleep 0.5 +done diff --git a/players/p2_config/start-steam.sh b/players/p2_config/start-steam.sh new file mode 100644 index 0000000..8a172e4 --- /dev/null +++ b/players/p2_config/start-steam.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash +set -euo pipefail + +exec 9>/tmp/start-steam.lock +flock -n 9 || exit 0 + +id steam >/dev/null 2>&1 || useradd -m -s /bin/bash steam +STEAM_UID="$(id -u steam)" + +ROOT=/home/steam/.local/share/Steam/debian-installation +mkdir -p "${ROOT}" /tmp/xdg-steam /home/steam/tmp /run/dbus +ln -sfn /home/steam/.local/share/Steam /home/steam/.steam +chown -R steam:steam /home/steam /tmp/xdg-steam + +ensure_dbus() { + if ! dbus-send --system --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.ListNames >/dev/null 2>&1; then + rm -f /run/dbus/pid + dbus-daemon --system --fork >/dev/null 2>&1 || true + fi +} + +ensure_fluxbox() { + cp -f /etc/game-server/fluxbox/init /root/.fluxbox/init 2>/dev/null || true + if ps -eo stat=,comm= 2>/dev/null | awk '$2=="fluxbox" && $1 !~ /Z/ { exit 0 } END { exit 1 }'; then + FB="$(ps -eo pid=,stat=,comm= | awk '$3=="fluxbox" && $2 !~ /Z/ {print $1; exit}')" + DISPLAY=:99 fluxbox-remote reloadconfig 2>/dev/null || kill -USR1 "${FB}" 2>/dev/null || true + return 0 + fi + DISPLAY=:99 HOME=/root fluxbox >/dev/null 2>&1 & + sleep 1 +} + +restart_fluxbox() { + pkill -x fluxbox >/dev/null 2>&1 || true + sleep 1 + cp -f /etc/game-server/fluxbox/init /root/.fluxbox/init 2>/dev/null || true + DISPLAY=:99 HOME=/root fluxbox >/dev/null 2>&1 & + sleep 1 + DISPLAY=:99 xsetroot -solid "#3c3c3c" 2>/dev/null || true +} + +steam_running() { + pgrep -u steam -f "${ROOT}/ubuntu12_32/steam -srt-logger-opened" >/dev/null 2>&1 +} + +steam_ui_visible() { + DISPLAY=:99 xwininfo -root -tree 2>/dev/null | grep -qE "Steam Big Picture Mode|Sign in to Steam" +} + +ensure_window_keeper() { + command -v xdotool >/dev/null 2>&1 || return 0 + pgrep -f keep-steam-window.sh >/dev/null 2>&1 && return 0 + setsid bash /root/.config/sunshine/keep-steam-window.sh >/dev/null 2>&1 & +} + +schedule_gamepadui_once() { + [ -f /tmp/steam-gamepadui-done ] && return 0 + setsid bash -lc ' + for _ in $(seq 1 90); do + pgrep -u steam -f steamwebhelper >/dev/null 2>&1 && break + sleep 1 + done + sleep 5 + runuser -u steam -- env \ + DISPLAY=:99 \ + HOME=/home/steam \ + XDG_RUNTIME_DIR=/tmp/xdg-steam \ + TMPDIR=/home/steam/tmp \ + LANG=en_US.UTF-8 \ + LC_ALL=en_US.UTF-8 \ + /usr/games/steam steam://open/gamepadui >/dev/null 2>&1 || true + touch /tmp/steam-gamepadui-done + ' >/dev/null 2>&1 & +} + +stop_steam() { + pkill -9 -u steam -f "steam|steamwebhelper|steam-runtime|steam-runtime-launcher" >/dev/null 2>&1 || true + pkill -f keep-steam-window.sh >/dev/null 2>&1 || true + sleep 1 + rm -f /home/steam/.local/share/Steam/steam.pid \ + /home/steam/.local/share/Steam/steam.pipe \ + /home/steam/.local/share/Steam/steam.token \ + /tmp/steam-gamepadui-done + rm -rf /home/steam/.local/share/Steam/debian-installation/config/htmlcache + rm -rf /tmp/dumps/completed /tmp/dumps/*.lock 2>/dev/null || true + rm -f /dev/shm/u"${STEAM_UID}"-* /dev/shm/u"${STEAM_UID}"-ValveIPC* /dev/shm/.org.chromium.* /dev/shm/pulse-* 2>/dev/null || true +} + +ensure_dbus +restart_fluxbox + +if steam_running; then + if steam_ui_visible; then + ensure_window_keeper + exit 0 + fi + schedule_gamepadui_once + ensure_window_keeper + exit 0 +fi + +stop_steam +ensure_dbus +restart_fluxbox + +setsid runuser -u steam -- env \ + DISPLAY=:99 \ + HOME=/home/steam \ + XDG_RUNTIME_DIR=/tmp/xdg-steam \ + TMPDIR=/home/steam/tmp \ + LANG=en_US.UTF-8 \ + LC_ALL=en_US.UTF-8 \ + bash -lc "cd ${ROOT} && exec /usr/games/steam -silent -no-cef-sandbox" \ + >>/home/steam/steam-app.log 2>&1 & + +schedule_gamepadui_once +ensure_window_keeper +exit 0 diff --git a/players/p3_config/apps.json b/players/p3_config/apps.json index 40e90b3..1eebac1 100644 --- a/players/p3_config/apps.json +++ b/players/p3_config/apps.json @@ -6,7 +6,7 @@ { "name": "Steam Big Picture", "detached": [ - "bash -lc 'id steam >/dev/null 2>&1 || useradd -m -s /bin/bash steam; ROOT=/home/steam/.local/share/Steam/debian-installation; mkdir -p ${ROOT} /tmp/xdg-steam /home/steam/tmp; ln -sfn /home/steam/.local/share/Steam /home/steam/.steam; chown -R steam:steam /home/steam /tmp/xdg-steam; pkill -u steam -f \"steam|steamwebhelper|steam-runtime\" >/dev/null 2>&1 || true; sleep 1; runuser -u steam -- env DISPLAY=:99 HOME=/home/steam XDG_RUNTIME_DIR=/tmp/xdg-steam TMPDIR=/home/steam/tmp LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 nohup bash -lc \"cd ${ROOT} && exec /usr/games/steam -gamepadui -fullscreen -no-cef-sandbox\" >/home/steam/steam-app.log 2>&1 < /dev/null &'" + "bash -lc '/root/.config/sunshine/start-steam.sh'" ], "prep-cmd": [ { @@ -28,19 +28,6 @@ } ], "image-path": "desktop.png" - }, - { - "name": "Steam Manual Start", - "detached": [ - "bash -lc 'id steam >/dev/null 2>&1 || useradd -m -s /bin/bash steam; ROOT=/home/steam/.local/share/Steam/debian-installation; mkdir -p ${ROOT} /tmp/xdg-steam /home/steam/tmp; ln -sfn /home/steam/.local/share/Steam /home/steam/.steam; chown -R steam:steam /home/steam /tmp/xdg-steam; pkill -u steam -f \"steam|steamwebhelper|steam-runtime\" >/dev/null 2>&1 || true; sleep 1; runuser -u steam -- env DISPLAY=:99 HOME=/home/steam XDG_RUNTIME_DIR=/tmp/xdg-steam TMPDIR=/home/steam/tmp LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 nohup bash -lc \"cd ${ROOT} && exec /usr/games/steam -gamepadui -fullscreen -no-cef-sandbox\" >/home/steam/steam-app.log 2>&1 < /dev/null &'" - ], - "prep-cmd": [ - { - "do": "", - "undo": "" - } - ], - "image-path": "steam.png" } ] } diff --git a/players/p3_config/keep-steam-window.sh b/players/p3_config/keep-steam-window.sh new file mode 100644 index 0000000..019010a --- /dev/null +++ b/players/p3_config/keep-steam-window.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +export DISPLAY=:99 + +SCREEN_W=1920 +SCREEN_H=1080 +TOOLBAR_H=32 + +find_window() { + local title="$1" + xwininfo -root -tree 2>/dev/null | grep "\"${title}\"" | head -1 | awk '{print $1}' +} + +window_state() { + xwininfo -id "$1" 2>/dev/null | awk '/Map State/{print $NF}' +} + +center_window() { + local wid="$1" + local geom w h x y + geom="$(xwininfo -id "${wid}" 2>/dev/null | awk '/-geometry/{print $2}')" + w="${geom%%x*}" + h="${geom#*x}"; h="${h%%+*}" + [ -n "${w}" ] && [ -n "${h}" ] || return 0 + x=$(( (SCREEN_W - w) / 2 )) + y=$(( (SCREEN_H - TOOLBAR_H - h) / 2 )) + [ "${y}" -lt 0 ] && y=0 + xdotool windowmove "${wid}" "${x}" "${y}" 2>/dev/null || true +} + +while pgrep -u steam -f "steam -srt-logger-opened" >/dev/null 2>&1; do + wid="" + for title in "Sign in to Steam" "Steam Big Picture Mode"; do + wid="$(find_window "${title}")" + [ -n "${wid}" ] && break + done + + if [ -n "${wid}" ]; then + state="$(window_state "${wid}")" + if [ "${state}" = "IsUnMapped" ] || [ -z "${state}" ]; then + xdotool windowmap "${wid}" 2>/dev/null || true + fi + xdotool windowraise "${wid}" 2>/dev/null || true + center_window "${wid}" + xdotool windowactivate "${wid}" 2>/dev/null || true + fi + sleep 0.5 +done diff --git a/players/p3_config/start-steam.sh b/players/p3_config/start-steam.sh new file mode 100644 index 0000000..8a172e4 --- /dev/null +++ b/players/p3_config/start-steam.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash +set -euo pipefail + +exec 9>/tmp/start-steam.lock +flock -n 9 || exit 0 + +id steam >/dev/null 2>&1 || useradd -m -s /bin/bash steam +STEAM_UID="$(id -u steam)" + +ROOT=/home/steam/.local/share/Steam/debian-installation +mkdir -p "${ROOT}" /tmp/xdg-steam /home/steam/tmp /run/dbus +ln -sfn /home/steam/.local/share/Steam /home/steam/.steam +chown -R steam:steam /home/steam /tmp/xdg-steam + +ensure_dbus() { + if ! dbus-send --system --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.ListNames >/dev/null 2>&1; then + rm -f /run/dbus/pid + dbus-daemon --system --fork >/dev/null 2>&1 || true + fi +} + +ensure_fluxbox() { + cp -f /etc/game-server/fluxbox/init /root/.fluxbox/init 2>/dev/null || true + if ps -eo stat=,comm= 2>/dev/null | awk '$2=="fluxbox" && $1 !~ /Z/ { exit 0 } END { exit 1 }'; then + FB="$(ps -eo pid=,stat=,comm= | awk '$3=="fluxbox" && $2 !~ /Z/ {print $1; exit}')" + DISPLAY=:99 fluxbox-remote reloadconfig 2>/dev/null || kill -USR1 "${FB}" 2>/dev/null || true + return 0 + fi + DISPLAY=:99 HOME=/root fluxbox >/dev/null 2>&1 & + sleep 1 +} + +restart_fluxbox() { + pkill -x fluxbox >/dev/null 2>&1 || true + sleep 1 + cp -f /etc/game-server/fluxbox/init /root/.fluxbox/init 2>/dev/null || true + DISPLAY=:99 HOME=/root fluxbox >/dev/null 2>&1 & + sleep 1 + DISPLAY=:99 xsetroot -solid "#3c3c3c" 2>/dev/null || true +} + +steam_running() { + pgrep -u steam -f "${ROOT}/ubuntu12_32/steam -srt-logger-opened" >/dev/null 2>&1 +} + +steam_ui_visible() { + DISPLAY=:99 xwininfo -root -tree 2>/dev/null | grep -qE "Steam Big Picture Mode|Sign in to Steam" +} + +ensure_window_keeper() { + command -v xdotool >/dev/null 2>&1 || return 0 + pgrep -f keep-steam-window.sh >/dev/null 2>&1 && return 0 + setsid bash /root/.config/sunshine/keep-steam-window.sh >/dev/null 2>&1 & +} + +schedule_gamepadui_once() { + [ -f /tmp/steam-gamepadui-done ] && return 0 + setsid bash -lc ' + for _ in $(seq 1 90); do + pgrep -u steam -f steamwebhelper >/dev/null 2>&1 && break + sleep 1 + done + sleep 5 + runuser -u steam -- env \ + DISPLAY=:99 \ + HOME=/home/steam \ + XDG_RUNTIME_DIR=/tmp/xdg-steam \ + TMPDIR=/home/steam/tmp \ + LANG=en_US.UTF-8 \ + LC_ALL=en_US.UTF-8 \ + /usr/games/steam steam://open/gamepadui >/dev/null 2>&1 || true + touch /tmp/steam-gamepadui-done + ' >/dev/null 2>&1 & +} + +stop_steam() { + pkill -9 -u steam -f "steam|steamwebhelper|steam-runtime|steam-runtime-launcher" >/dev/null 2>&1 || true + pkill -f keep-steam-window.sh >/dev/null 2>&1 || true + sleep 1 + rm -f /home/steam/.local/share/Steam/steam.pid \ + /home/steam/.local/share/Steam/steam.pipe \ + /home/steam/.local/share/Steam/steam.token \ + /tmp/steam-gamepadui-done + rm -rf /home/steam/.local/share/Steam/debian-installation/config/htmlcache + rm -rf /tmp/dumps/completed /tmp/dumps/*.lock 2>/dev/null || true + rm -f /dev/shm/u"${STEAM_UID}"-* /dev/shm/u"${STEAM_UID}"-ValveIPC* /dev/shm/.org.chromium.* /dev/shm/pulse-* 2>/dev/null || true +} + +ensure_dbus +restart_fluxbox + +if steam_running; then + if steam_ui_visible; then + ensure_window_keeper + exit 0 + fi + schedule_gamepadui_once + ensure_window_keeper + exit 0 +fi + +stop_steam +ensure_dbus +restart_fluxbox + +setsid runuser -u steam -- env \ + DISPLAY=:99 \ + HOME=/home/steam \ + XDG_RUNTIME_DIR=/tmp/xdg-steam \ + TMPDIR=/home/steam/tmp \ + LANG=en_US.UTF-8 \ + LC_ALL=en_US.UTF-8 \ + bash -lc "cd ${ROOT} && exec /usr/games/steam -silent -no-cef-sandbox" \ + >>/home/steam/steam-app.log 2>&1 & + +schedule_gamepadui_once +ensure_window_keeper +exit 0 diff --git a/players/p4_config/apps.json b/players/p4_config/apps.json index 40e90b3..1eebac1 100644 --- a/players/p4_config/apps.json +++ b/players/p4_config/apps.json @@ -6,7 +6,7 @@ { "name": "Steam Big Picture", "detached": [ - "bash -lc 'id steam >/dev/null 2>&1 || useradd -m -s /bin/bash steam; ROOT=/home/steam/.local/share/Steam/debian-installation; mkdir -p ${ROOT} /tmp/xdg-steam /home/steam/tmp; ln -sfn /home/steam/.local/share/Steam /home/steam/.steam; chown -R steam:steam /home/steam /tmp/xdg-steam; pkill -u steam -f \"steam|steamwebhelper|steam-runtime\" >/dev/null 2>&1 || true; sleep 1; runuser -u steam -- env DISPLAY=:99 HOME=/home/steam XDG_RUNTIME_DIR=/tmp/xdg-steam TMPDIR=/home/steam/tmp LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 nohup bash -lc \"cd ${ROOT} && exec /usr/games/steam -gamepadui -fullscreen -no-cef-sandbox\" >/home/steam/steam-app.log 2>&1 < /dev/null &'" + "bash -lc '/root/.config/sunshine/start-steam.sh'" ], "prep-cmd": [ { @@ -28,19 +28,6 @@ } ], "image-path": "desktop.png" - }, - { - "name": "Steam Manual Start", - "detached": [ - "bash -lc 'id steam >/dev/null 2>&1 || useradd -m -s /bin/bash steam; ROOT=/home/steam/.local/share/Steam/debian-installation; mkdir -p ${ROOT} /tmp/xdg-steam /home/steam/tmp; ln -sfn /home/steam/.local/share/Steam /home/steam/.steam; chown -R steam:steam /home/steam /tmp/xdg-steam; pkill -u steam -f \"steam|steamwebhelper|steam-runtime\" >/dev/null 2>&1 || true; sleep 1; runuser -u steam -- env DISPLAY=:99 HOME=/home/steam XDG_RUNTIME_DIR=/tmp/xdg-steam TMPDIR=/home/steam/tmp LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 nohup bash -lc \"cd ${ROOT} && exec /usr/games/steam -gamepadui -fullscreen -no-cef-sandbox\" >/home/steam/steam-app.log 2>&1 < /dev/null &'" - ], - "prep-cmd": [ - { - "do": "", - "undo": "" - } - ], - "image-path": "steam.png" } ] } diff --git a/players/p4_config/keep-steam-window.sh b/players/p4_config/keep-steam-window.sh new file mode 100644 index 0000000..019010a --- /dev/null +++ b/players/p4_config/keep-steam-window.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +export DISPLAY=:99 + +SCREEN_W=1920 +SCREEN_H=1080 +TOOLBAR_H=32 + +find_window() { + local title="$1" + xwininfo -root -tree 2>/dev/null | grep "\"${title}\"" | head -1 | awk '{print $1}' +} + +window_state() { + xwininfo -id "$1" 2>/dev/null | awk '/Map State/{print $NF}' +} + +center_window() { + local wid="$1" + local geom w h x y + geom="$(xwininfo -id "${wid}" 2>/dev/null | awk '/-geometry/{print $2}')" + w="${geom%%x*}" + h="${geom#*x}"; h="${h%%+*}" + [ -n "${w}" ] && [ -n "${h}" ] || return 0 + x=$(( (SCREEN_W - w) / 2 )) + y=$(( (SCREEN_H - TOOLBAR_H - h) / 2 )) + [ "${y}" -lt 0 ] && y=0 + xdotool windowmove "${wid}" "${x}" "${y}" 2>/dev/null || true +} + +while pgrep -u steam -f "steam -srt-logger-opened" >/dev/null 2>&1; do + wid="" + for title in "Sign in to Steam" "Steam Big Picture Mode"; do + wid="$(find_window "${title}")" + [ -n "${wid}" ] && break + done + + if [ -n "${wid}" ]; then + state="$(window_state "${wid}")" + if [ "${state}" = "IsUnMapped" ] || [ -z "${state}" ]; then + xdotool windowmap "${wid}" 2>/dev/null || true + fi + xdotool windowraise "${wid}" 2>/dev/null || true + center_window "${wid}" + xdotool windowactivate "${wid}" 2>/dev/null || true + fi + sleep 0.5 +done diff --git a/players/p4_config/start-steam.sh b/players/p4_config/start-steam.sh new file mode 100644 index 0000000..8a172e4 --- /dev/null +++ b/players/p4_config/start-steam.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash +set -euo pipefail + +exec 9>/tmp/start-steam.lock +flock -n 9 || exit 0 + +id steam >/dev/null 2>&1 || useradd -m -s /bin/bash steam +STEAM_UID="$(id -u steam)" + +ROOT=/home/steam/.local/share/Steam/debian-installation +mkdir -p "${ROOT}" /tmp/xdg-steam /home/steam/tmp /run/dbus +ln -sfn /home/steam/.local/share/Steam /home/steam/.steam +chown -R steam:steam /home/steam /tmp/xdg-steam + +ensure_dbus() { + if ! dbus-send --system --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.ListNames >/dev/null 2>&1; then + rm -f /run/dbus/pid + dbus-daemon --system --fork >/dev/null 2>&1 || true + fi +} + +ensure_fluxbox() { + cp -f /etc/game-server/fluxbox/init /root/.fluxbox/init 2>/dev/null || true + if ps -eo stat=,comm= 2>/dev/null | awk '$2=="fluxbox" && $1 !~ /Z/ { exit 0 } END { exit 1 }'; then + FB="$(ps -eo pid=,stat=,comm= | awk '$3=="fluxbox" && $2 !~ /Z/ {print $1; exit}')" + DISPLAY=:99 fluxbox-remote reloadconfig 2>/dev/null || kill -USR1 "${FB}" 2>/dev/null || true + return 0 + fi + DISPLAY=:99 HOME=/root fluxbox >/dev/null 2>&1 & + sleep 1 +} + +restart_fluxbox() { + pkill -x fluxbox >/dev/null 2>&1 || true + sleep 1 + cp -f /etc/game-server/fluxbox/init /root/.fluxbox/init 2>/dev/null || true + DISPLAY=:99 HOME=/root fluxbox >/dev/null 2>&1 & + sleep 1 + DISPLAY=:99 xsetroot -solid "#3c3c3c" 2>/dev/null || true +} + +steam_running() { + pgrep -u steam -f "${ROOT}/ubuntu12_32/steam -srt-logger-opened" >/dev/null 2>&1 +} + +steam_ui_visible() { + DISPLAY=:99 xwininfo -root -tree 2>/dev/null | grep -qE "Steam Big Picture Mode|Sign in to Steam" +} + +ensure_window_keeper() { + command -v xdotool >/dev/null 2>&1 || return 0 + pgrep -f keep-steam-window.sh >/dev/null 2>&1 && return 0 + setsid bash /root/.config/sunshine/keep-steam-window.sh >/dev/null 2>&1 & +} + +schedule_gamepadui_once() { + [ -f /tmp/steam-gamepadui-done ] && return 0 + setsid bash -lc ' + for _ in $(seq 1 90); do + pgrep -u steam -f steamwebhelper >/dev/null 2>&1 && break + sleep 1 + done + sleep 5 + runuser -u steam -- env \ + DISPLAY=:99 \ + HOME=/home/steam \ + XDG_RUNTIME_DIR=/tmp/xdg-steam \ + TMPDIR=/home/steam/tmp \ + LANG=en_US.UTF-8 \ + LC_ALL=en_US.UTF-8 \ + /usr/games/steam steam://open/gamepadui >/dev/null 2>&1 || true + touch /tmp/steam-gamepadui-done + ' >/dev/null 2>&1 & +} + +stop_steam() { + pkill -9 -u steam -f "steam|steamwebhelper|steam-runtime|steam-runtime-launcher" >/dev/null 2>&1 || true + pkill -f keep-steam-window.sh >/dev/null 2>&1 || true + sleep 1 + rm -f /home/steam/.local/share/Steam/steam.pid \ + /home/steam/.local/share/Steam/steam.pipe \ + /home/steam/.local/share/Steam/steam.token \ + /tmp/steam-gamepadui-done + rm -rf /home/steam/.local/share/Steam/debian-installation/config/htmlcache + rm -rf /tmp/dumps/completed /tmp/dumps/*.lock 2>/dev/null || true + rm -f /dev/shm/u"${STEAM_UID}"-* /dev/shm/u"${STEAM_UID}"-ValveIPC* /dev/shm/.org.chromium.* /dev/shm/pulse-* 2>/dev/null || true +} + +ensure_dbus +restart_fluxbox + +if steam_running; then + if steam_ui_visible; then + ensure_window_keeper + exit 0 + fi + schedule_gamepadui_once + ensure_window_keeper + exit 0 +fi + +stop_steam +ensure_dbus +restart_fluxbox + +setsid runuser -u steam -- env \ + DISPLAY=:99 \ + HOME=/home/steam \ + XDG_RUNTIME_DIR=/tmp/xdg-steam \ + TMPDIR=/home/steam/tmp \ + LANG=en_US.UTF-8 \ + LC_ALL=en_US.UTF-8 \ + bash -lc "cd ${ROOT} && exec /usr/games/steam -silent -no-cef-sandbox" \ + >>/home/steam/steam-app.log 2>&1 & + +schedule_gamepadui_once +ensure_window_keeper +exit 0 diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh new file mode 100644 index 0000000..e4fa5cb --- /dev/null +++ b/scripts/entrypoint.sh @@ -0,0 +1,31 @@ +#!/bin/bash +set -e + +rm -f /tmp/.X99-lock /tmp/.X11-unix/X99 + +id steam >/dev/null 2>&1 || useradd -m -s /bin/bash steam +mkdir -p /home/steam/.local/share/Steam /tmp/xdg-steam /home/steam/tmp +ln -sfn /home/steam/.local/share/Steam /home/steam/.steam +chown -R steam:steam /home/steam /tmp/xdg-steam + +mkdir -p /run/dbus +rm -f /run/dbus/pid +dbus-daemon --system --fork || true + +Xorg :99 -config /etc/X11/xorg-dummy.conf -nolisten tcp -noreset \ + +extension GLX +extension RANDR +extension RENDER & + +export DISPLAY=:99 +export HOME=/root +export LANG=en_US.UTF-8 +export LC_ALL=en_US.UTF-8 + +mkdir -p /root/.fluxbox +cp -f /etc/game-server/fluxbox/init /root/.fluxbox/init + +sleep 3 +fluxbox & +sleep 2 +xsetroot -solid "#3c3c3c" 2>/dev/null || true + +exec /usr/bin/sunshine diff --git a/scripts/fluxbox/init b/scripts/fluxbox/init new file mode 100644 index 0000000..577e5df --- /dev/null +++ b/scripts/fluxbox/init @@ -0,0 +1,17 @@ +session.menuFile: ~/.fluxbox/menu +session.keyFile: ~/.fluxbox/keys +session.styleFile: /usr/share/fluxbox/styles/Emerge +session.configVersion: 13 + +session.screen0.toolbar.visible: true +session.screen0.toolbar.placement: BottomCenter +session.screen0.toolbar.height: 32 +session.screen0.toolbar.autoHide: false +session.screen0.toolbar.widthPercent: 100 +session.screen0.toolbar.layer: Top +session.screen0.toolbar.onhead: 0 +session.screen0.toolbar.maxOver: true +session.screen0.toolbar.alpha: 255 +session.screen0.toolbar.tools: clock, iconbar, systemtray + +session.screen0.strftimeFormat: %d %b %H:%M