deckless/bin/deckless-steam

259 lines
6.5 KiB
Bash
Executable file

#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
config_dir="${XDG_CONFIG_HOME:-$HOME/.config}/deckless"
settings_env="${DECKLESS_SETTINGS_ENV:-${config_dir}/deckless.env}"
legacy_proxy_env="${HOME}/.config/network/proxy-env.sh"
proxy_env="${DECKLESS_PROXY_ENV:-${config_dir}/proxy-env.sh}"
steam_bin="${DECKLESS_STEAM_BIN:-/usr/bin/steam}"
if [[ -r "$settings_env" ]]; then
# shellcheck disable=SC1090
. "$settings_env"
fi
steam_root="$(readlink -e "$HOME/.steam/steam" || true)"
if [[ -z "$steam_root" ]]; then
steam_root="${XDG_DATA_HOME:-$HOME/.local/share}/Steam"
fi
target="${steam_root}/ubuntu12_64/steamwebhelper_sniper_wrap.sh"
target_dir="${target%/*}"
state_dir="${XDG_STATE_HOME:-$HOME/.local/state}/deckless/steam"
session_state="${state_dir}/session.env"
original_wrapper="${state_dir}/steamwebhelper_sniper_wrap.sh.original"
sync_helper="${script_dir}/deckless-sync-webhelper-wrapper"
heal_helper="${script_dir}/deckless-webhelper-heal"
cleanup_helper="${script_dir}/deckless-webhelper-cleanup"
cleanup_done=0
if [[ ! -d "$target_dir" ]]; then
printf 'Steam runtime directory not found: %s\n' "$target_dir" >&2
exit 1
fi
if [[ ! -x "$steam_bin" ]]; then
printf 'Steam binary not found: %s\n' "$steam_bin" >&2
exit 1
fi
for helper in "$sync_helper" "$heal_helper" "$cleanup_helper"; do
if [[ ! -x "$helper" ]]; then
printf 'Deckless helper not found: %s\n' "$helper" >&2
exit 1
fi
done
mkdir -p "$state_dir"
steam_activity_running() {
local args
while IFS= read -r args; do
if [[ "$args" == *"${steam_root}/ubuntu12_32/steam"* ]] || \
[[ "$args" == *"${steam_root}/ubuntu12_64/steamwebhelper"* ]] || \
[[ "$args" == *"${target}"* ]] || \
[[ "$args" == *"${steam_bin}"* ]]; then
return 0
fi
done < <(ps -ww -eo args=)
return 1
}
terminate_stale_helpers() {
local pid
local args
while read -r pid args; do
case "$args" in
"$sync_helper"|\
"$sync_helper "*|\
"$heal_helper"|\
"$heal_helper "*|\
"$cleanup_helper"|\
"$cleanup_helper "*|\
"bash $sync_helper"|\
"bash $sync_helper "*|\
"bash $heal_helper"|\
"bash $heal_helper "*|\
"bash $cleanup_helper"|\
"bash $cleanup_helper "*|\
"/usr/bin/bash $sync_helper"|\
"/usr/bin/bash $sync_helper "*|\
"/usr/bin/bash $heal_helper"|\
"/usr/bin/bash $heal_helper "*|\
"/usr/bin/bash $cleanup_helper"|\
"/usr/bin/bash $cleanup_helper "*)
kill -TERM "$pid" 2>/dev/null || true
;;
esac
done < <(ps -ww -eo pid=,args=)
}
start_detached_helper() {
local helper="$1"
if command -v setsid >/dev/null 2>&1; then
setsid -f "$helper" >/dev/null 2>&1 </dev/null || true
else
nohup "$helper" >/dev/null 2>&1 </dev/null &
fi
}
restore_official_wrapper() {
if (( cleanup_done == 1 )); then
return 0
fi
if grep -Fq 'deckless-managed steam webhelper wrapper' "$target" 2>/dev/null && [[ -f "$original_wrapper" ]]; then
cp -a "$original_wrapper" "$target"
fi
rm -f "$session_state" "$original_wrapper"
cleanup_done=1
}
apply_optional_locale() {
if [[ -n "${DECKLESS_LANG:-}" ]]; then
while IFS='=' read -r name _; do
[[ $name == LC_* ]] && unset "$name"
done < <(env)
export LANG="$DECKLESS_LANG"
export LC_CTYPE="$DECKLESS_LANG"
fi
if [[ -n "${DECKLESS_FC_LANG:-}" ]]; then
export FC_LANG="$DECKLESS_FC_LANG"
fi
case "${DECKLESS_INPUT_METHOD:-}" in
fcitx|fcitx5)
export GTK_IM_MODULE='fcitx'
export QT_IM_MODULE='fcitx'
export XMODIFIERS='@im=fcitx'
export SDL_IM_MODULE='fcitx'
export INPUT_METHOD='fcitx'
;;
ibus)
export GTK_IM_MODULE='ibus'
export QT_IM_MODULE='ibus'
export XMODIFIERS='@im=ibus'
export SDL_IM_MODULE='ibus'
export INPUT_METHOD='ibus'
;;
esac
}
normalize_proxy_server() {
case "$1" in
socks5h://*)
printf 'socks5://%s\n' "${1#socks5h://}"
;;
socks5://*|http://*|https://*)
printf '%s\n' "$1"
;;
*)
return 1
;;
esac
}
build_chromium_bypass_list() {
local raw="$1"
local entry
local -a entries=()
if [[ "$raw" == *';'* ]]; then
printf '%s\n' "$raw"
return 0
fi
IFS=',' read -r -a input_entries <<< "$raw"
for entry in "${input_entries[@]}"; do
entry="${entry//[[:space:]]/}"
[[ -z "$entry" ]] && continue
[[ "$entry" == .* ]] && entry="*${entry}"
entries+=("$entry")
done
((${#entries[@]} == 0)) && return 0
local IFS=';'
printf '%s\n' "${entries[*]}"
}
if ! steam_activity_running; then
terminate_stale_helpers
restore_official_wrapper
fi
apply_optional_locale
if [[ -z "${SDL_VIDEODRIVER:-}" ]]; then
if [[ -n "${WAYLAND_DISPLAY:-}" ]]; then
export SDL_VIDEODRIVER='wayland'
elif [[ -n "${DISPLAY:-}" ]]; then
export SDL_VIDEODRIVER='x11'
fi
fi
if [[ -z "${XDG_RUNTIME_DIR:-}" ]]; then
xdg_runtime_dir="/run/user/$(id -u)"
export XDG_RUNTIME_DIR="$xdg_runtime_dir"
fi
if [[ -r "$proxy_env" ]]; then
# shellcheck disable=SC1090
. "$proxy_env"
elif [[ -r "$legacy_proxy_env" ]]; then
# shellcheck disable=SC1090
. "$legacy_proxy_env"
fi
proxy_candidate="${DECKLESS_PROXY_SERVER:-${DECKLESS_WEBHELPER_PROXY_SERVER:-${HTTPS_PROXY:-${https_proxy:-${HTTP_PROXY:-${http_proxy:-${ALL_PROXY:-${all_proxy:-}}}}}}}}"
bypass_candidate="${DECKLESS_PROXY_BYPASS_LIST:-${DECKLESS_WEBHELPER_PROXY_BYPASS_LIST:-${NO_PROXY:-${no_proxy:-steamloopback.host,localhost,127.0.0.1,::1,.local,.lan,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12}}}}"
proxy_server=''
proxy_bypass=''
if [[ -n "$proxy_candidate" ]]; then
proxy_server="$(normalize_proxy_server "$proxy_candidate" || true)"
fi
if [[ -n "$bypass_candidate" ]]; then
proxy_bypass="$(build_chromium_bypass_list "$bypass_candidate")"
fi
tmp_state="$(mktemp "${state_dir}/.session.env.XXXXXX")"
trap 'rm -f "${tmp_state:-}"' EXIT
{
printf '# deckless session state\n'
printf 'DECKLESS_WEBHELPER_PROXY_SERVER=%q\n' "$proxy_server"
printf 'DECKLESS_WEBHELPER_PROXY_BYPASS_LIST=%q\n' "$proxy_bypass"
} >"$tmp_state"
chmod 0600 "$tmp_state"
mv -f "$tmp_state" "$session_state"
trap - EXIT
unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY
unset ALL_PROXY all_proxy
unset no_proxy NO_PROXY
unset DECKLESS_WEBHELPER_PROXY_SERVER DECKLESS_WEBHELPER_PROXY_BYPASS_LIST
trap 'restore_official_wrapper' EXIT HUP INT TERM
start_detached_helper "$heal_helper"
start_detached_helper "$cleanup_helper"
set +e
"$steam_bin" "$@"
steam_status=$?
set -e
restore_official_wrapper
trap - EXIT HUP INT TERM
exit "$steam_status"