From e94936a7b6b07f74901ced8102dc7da31677c668 Mon Sep 17 00:00:00 2001 From: "Bret R. Human" Date: Tue, 21 May 2019 09:16:51 -0400 Subject: [PATCH] initial commit --- LICENSE | 52 +++++++++ README.md | 7 ++ st34m-run.sh | 276 ++++++++++++++++++++++++++++++++++++++++++++++ st34m.sh | 306 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 641 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 st34m-run.sh create mode 100644 st34m.sh diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..fc29bec --- /dev/null +++ b/LICENSE @@ -0,0 +1,52 @@ +st34m +=== +Copyright (c) 2018, Bret R. Human +All rights reserved. + +Further documentation can be found at + https://mage.cynicaloptimist.me/en/st34m + https://psi.cynicaloptimist.me/Caffarius/st34m/ +Happy modding! -Bret + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + the documentation link and note, this list of conditions, and the following + disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. All advertising materials mentioning features or use of this + software must display the following acknowledgment: +"Built using software developed by Cynical Optimist - https://cynicaloptimist.me + Ask what we can build for you at info@cynicaloptimist.me" + +4. The names "Cynical Optimist" and "Bret R. Human" and the software name listed + at the top of this document, or the domain "cynicaloptimist.me" or any + affiliated service must not be used to endorse or promote products derived + from this software without prior written permission. For written permission, + contact info@cynicaloptimist.me. + +5. Products derived from this software may not be called the software name + listed at the top of this document nor may "Cynical Optimist" or the software + name listed at the top of this document appear in their names without prior + written permission of Bret R. Human. + +6. Redistributions of any form whatsoever must retain the following + acknowledgment: +"Built using software developed by Cynical Optimist - https://cynicaloptimist.me + Ask what we can build for you at info@cynicaloptimist.me" + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..fa69d0e --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# st34m + +How to run Steam and games easily, even under a secondary user. + + +## Usage +See the wiki article at https://mage.cynicaloptimist.me/en/st34m \ No newline at end of file diff --git a/st34m-run.sh b/st34m-run.sh new file mode 100644 index 0000000..188da44 --- /dev/null +++ b/st34m-run.sh @@ -0,0 +1,276 @@ +#!/bin/bash +## Copyright © 2018 Bret Human +## https://cynicaloptimist.me/ +## +## Documentation at: +## https://mage.cynicaloptimist.me/en/st34m +## https://psi.cynicaloptimist.me/Caffarius/st34m/ +## +## For questions or comments write: +## info@cynicaloptimist.me +##################################################################### +# st34m-run +script_ver="1.0.1" +# https://mage.cynicaloptimist.me/en/st34m +# author: Bret Human +# date: Dec 10, 2018 +# +##################################################################### +# +# A wrapper for wrappers, used to manage/own a Steam installation in +# a Linux environment. +# +# This is the second script in the line, fired off by st34m. This +# script handles conditionals for safely running Steam or +# most of its apps. The syntax makes it easily modular. +# +# If you want to add a game, search for "function game_on". +# +##################################################################### +# +# This is free software; you are free to change and redistribute it. +# There is NO WARRANTY of any kind. +# +##################################################################### + +runas_user="`whoami`" +app_name="Steam" +app_dir="/usr/bin/" +app_cmd="steam-native" +console="bash" +usage="st34m-run, version ${script_ver} +Usage: ./`basename ${0}` -g (game) -dvptch + -g | Launches the game of your choice + -d | Debug messages on (turns verbose on) + -v | Verbose messages on + -p | Runs protontricks + -t | Attempts to launch to the system tray + -c | Launch a console session as specified user (can launch Xapps) + -r | Use steam-runtime instead of steam-native + -h | Help (this message)" + +# Catch CTRL+C and cleanup +trap "echo '' && inform '---------------------------------' && inform 'Caught CTRL+C' && warp 2" 2 + +## Set default environment +cd /home/"${runas_user}" +export HOME="/home/${runas_user}" +export USER="${runas_user}" +export USERNAME="${runas_user}" +export LOGNAME="${runas_user}" +export WINEDEBUG=-all +export XAUTHORITY="/home/${runas_user}/.Xauthority" +export PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/sbin" +unset OLDPWD +unset SUDO_GID +unset SUDO_COMMAND +unset SUDO_USER +unset SUDO_UID +STEAM_FRAME_FORCE_CLOSE=1 + +## Define our functions +function debug () { + if [ ! "${WINEDEBUG}" ]; then + echo "-d- ${1}" + fi +} + +function inform () { + if [ "${app_verbose}" ]; then + echo "--- ${1}" + fi +} + +function clean { + debug "clean" + + # Var + unset script_ver + unset runas_user + unset app_name + unset app_dir + unset app_cmd + unset app_verbose + unset app_proton + unset console + unset usage + unset WINEDEBUG + unset STEAM_FRAME_FORCE_CLOSE + unset game_launch + unset game_name + unset game_id + unset nobs_mode + unset to_tray + + + # Func + unset debug + unset inform + unset game_on +} + +function warp () { + debug "warp" # exit the dungeon + inform "Cleaning up ${runas_user}-side..." + clean + unset clean + + if [ "$1" ]; then + unset warp && exit $1 + else + echo "...what...?" + unset warp && exit 5 + fi +} + +function game_on { + debug "game_on" + case "${game_launch}" in + test) + echo "glxgears!" + if [ "`which glxgears`" ]; then + glxgears + warp 0 + else + echo "glxgears is not installed, or I can't find it in PATH" + warp 1 + fi + ;; + 507490|ashes) + game_name="Ashes of the Singularity: Escalation" + game_id="507490" + ;; + 289070|civ6) + game_name="Civilization VI" + game_id="289070" + ;; + 65980|civbe) + game_name="Civilization: Beyond Earth" + game_id="65980" + ;; + 278080|dw8) + game_name="Dynasty Warriors 8" + game_id="278080" + ;; + 359320|elite) + game_name="Elite Dangerous" + game_id="359320" + ;; + 377160|fo4) + game_name="Fallout 4" + game_id="377160" + ;; + 244160|hw) + game_name="Homeworld Remastered" + game_id="244160" + ;; + 342200|mwo) + game_name="MechWarrior Online" + game_id="342200" + ;; + 204880|sins) + game_name="Sins of a Solar Empire" + game_id="204880" + ;; + *) echo "Unrecognized game: ${game_launch} - trying anyways..." + game_id="${game_launch}" + ;; + esac + + if [ "${game_id}" ]; then + if [ "${app_proton}" ]; then + if [ "${WINEDEBUG}" ]; then + protontricks "${game_id}" --gui > /dev/null 2>&1 + else + protontricks "${game_id}" --gui + fi + else + if [ ! "${game_name}" ]; then + game_name="${game_id}" + fi + echo "Attempting to run ${game_name}..." + ${app_dir}${app_cmd} steam://rungameid/${game_id} + fi + fi +} + + + +## Pick up any arguments provided +while getopts ":g:G:dDvVpPtTnNcCrRhH" option; do + case "${option}" in + "g"|"G") game_launch="${OPTARG}";; + "d"|"D") + if [ "${WINEDEBUG}" ]; then + unset WINEDEBUG + debug "Run debug enabled" + debug "`realpath "${0}"` version ${script_ver} running as ${runas_user}" + app_verbose="y" + fi + ;; + "p"|"P") + echo "Running protontricks..." + app_proton="y" + ;; + "n"|"N") + inform "...with No BS..." + nobs_mode="y" + ;; + "c"|"C") + echo "Running console..." + nobs_mode="y" + ${console} + ;; + "v"|"V") + if [ "${WINEDEBUG}" ]; then + if [ ! "${app_verbose}" ]; then + app_verbose="y" + #inform "Run verbose enabled" + inform "`realpath "${0}"` version ${script_ver} running as ${runas_user}" + fi + fi + ;; + "t"|"T") + to_tray="-silent" + inform "Attempting hide to system tray" + ;; + "r"|"R") + echo "Switching to steam-runtime..." + app_cmd="steam-runtime" + ;; + "h"|"H") + echo "${usage}" + warp 0 + ;; + *) echo "Unknown option: -${OPTARG}" + echo "${usage}" + warp 1 + ;; + esac +done + + + +## If a game was set for launch, give it a shot. Otherwise launcher. +if [ "${nobs_mode}" ]; then + debug "Skipping app launches" +else + debug "launch_select" + if [ "${game_launch}" ]; then + inform "game_launch argument: ${game_launch}" + game_on + else + echo "Running ${app_name}" + if [ "${WINEDEBUG}" ]; then + ${app_dir}${app_cmd} "${to_tray}" > /dev/null 2>&1 + else + ${app_dir}${app_cmd} "${to_tray}" + fi + fi +fi + + + +## If we still exist, clean up. +debug "final notice" +warp 0 diff --git a/st34m.sh b/st34m.sh new file mode 100644 index 0000000..e143a5e --- /dev/null +++ b/st34m.sh @@ -0,0 +1,306 @@ +#!/bin/bash +## Copyright © 2018 Bret Human +## https://cynicaloptimist.me/ +## +## Documentation at: +## https://mage.cynicaloptimist.me/en/st34m +## https://psi.cynicaloptimist.me/Caffarius/st34m/ +## +## For questions or comments write: +## info@cynicaloptimist.me +##################################################################### +# st34m +script_ver="1.0.1" +page="https://mage.cynicaloptimist.me/en/st34m" +# author: Bret Human +# date: Dec 10, 2018 +# +##################################################################### +# +# A wrapper for wrappers, used to manage Steam and Proton in a Linux +# environment. +# +# Extra handy for running Steam under a secondary account for +# added security. Can be used for lots of zany wine/proton needs. +# +# This is the first of two scripts. It is meant to be the sanitizer +# crew and the firing squad for st34m-run. st34m-run must be installed. +# +# Install st34m-run for your desired user with: +# ./st34m.sh -u username -i +# +# Then you can launch steam via: +# ./st34m.sh -u username +# +# Or I guess you could manually download the script from: +dl_addr="https://psi.cynicaloptimist.me/Caffarius/st34m/raw/branch/master/st34m-run.sh" +##################################################################### +# +# This is free software; you are free to change and redistribute it. +# There is NO WARRANTY of any kind. +# +##################################################################### + +runas_user="`whoami`" +app_name="Steam" +run_cmd="st34m-run.sh" +check_wait="3" +usage="st34m, version ${script_ver} +Usage: ./`basename ${0}` -g (game) -u (user) -dvkptcrhi + -g | Launches the game of your choice + -u | Runs ${app_name} as the user specified + -d | Debug messages on (turns verbose on) + -v | Verbose messages on + -k | Kill all processes for a user (not current user or root) + -p | Runs protontricks + -t | Attempts to launch to the system tray + -c | Launch a console session as specified user (can launch Xapps) + -r | Launch steam-runtime instead of steam-native + -h | Help (this message) + -i | Install the st34m-run script for the specified user - mandantory +See more documentation at: ${page}" + +# Catch CTRL+C and cleanup +trap "echo '' && inform '---------------------------------' && inform 'Caught CTRL+C' && check" 2 + +# Don't allow crash reports +mkdir -p /tmp/dumps +sudo chown root: /tmp/dumps +sudo chmod 700 /tmp/dumps + +## Define our functions +function refresh { + app_dir="/home/${runas_user}/.script/" + app_check="ps -ef | grep ${runas_user} | grep steam | grep -v grep" +} + +function debug () { + if [ "${app_debug}" ]; then + echo "-D- ${1}" + fi +} + +function inform () { + if [ "${app_verbose}" ]; then + echo "--- ${1}" + fi +} + +function clean { + debug "Clean" + + # Var + unset script_ver + unset page + unset dl_addr + unset runas_user + unset app_name + unset app_check + unset app_debug + unset app_verbose + unset app_dir + unset run_cmd + unset check_wait + unset usage + unset launch_opt + + + # Func + unset refresh + unset debug + unset inform + unset check +} + +function die () { + debug "die" + echo "Cleaning up..." + + if [ "`whoami`" == "${runas_user}" ]; then + debug "Launched as original user, not killing processes" + else + if [ "${runas_user}" == "root" ]; then + debug "Root? Madness. Just removing xhost then..." + inform "`xhost -SI:localuser:"${runas_user}"`" + else + debug "Launched as ${runas_user}, killing processes" + sudo -u "${runas_user}" -- bash -c "kill -9 -1" + inform "`xhost -SI:localuser:"${runas_user}"`" + fi + fi + + clean + unset clean + unset fizzle + sudo rm -rf /tmp/dumps + + if [ "$1" ]; then + unset die && exit $1 + else + echo "...what?" + unset die && exit 5 + fi + + exit 5 +} + +function fizzle () { + debug "fizzle" # https://mtg.gamepedia.com/Fizzle + echo "Exiting..." + clean + unset clean + unset die + + if [ "$1" ]; then + unset fizzle && exit $1 + else + echo "...what?" + unset fizzle && exit 5 + fi +} + +function check { + debug "check" + refresh + i="0" + while [ "${i}" -lt "${check_wait}" ]; do + if [ "$(eval ${app_check})" ]; then + inform "${app_name} is still running. Waiting to see if we need to murder... $[ ${check_wait} - ${i} ]" + sleep 1 + else + unset i + die 0 + fi + + i=$[ $i + 1 ] + done + unset i +} + + + +## Pick up any arguments provided +# None are required, we'll use default values. +launch_opt="" +while getopts ":g:G:u:U:dDvVkKpPtTnNcCrRhHiI" option; do + case "${option}" in + "k"|"K") die 0;; + "g"|"G") launch_opt="${launch_opt} -g ${OPTARG}";; + "d"|"D") + if [ ! "${app_debug}" ]; then # Let's not do this too much... + app_debug="y" + launch_opt=" -d${launch_opt}" + debug "Debug enabled" + if [ ! "${app_verbose}" ]; then + debug "`realpath "${0}"` version ${script_ver} running as `whoami`" + fi + app_verbose="y" + debug "" + debug "This is free software; you are free to change and redistribute it." + debug "There is NO WARRANTY of any kind." + debug "" + debug "Documentation at: ${page}" + debug "" + fi + ;; + "p"|"P") + inform "Protontricks mode" + launch_opt="${launch_opt} -p" + ;; + "n"|"N") + inform "No BS mode" + nobs_mode="y" + launch_opt="${launch_opt} -n" + ;; + "c"|"C") + inform "Console requested" + nobs_mode="y" + launch_opt="${launch_opt} -c" + ;; + "v"|"V") + if [ ! "${app_debug}" ]; then + if [ ! "${app_verbose}" ]; then + app_verbose="y" + inform "Verbose enabled" + inform "`realpath "${0}"` version ${script_ver} running as `whoami`" + launch_opt=" -v${launch_opt}" + fi + fi + ;; + "t"|"T") + inform "Hiding to system tray" + launch_opt="${launch_opt} -t" + ;; + "u"|"U") + debug "Setting user to ${OPTARG}" + runas_user="${OPTARG}" + ;; + "i"|"I") + debug "User-side install requested" + refresh + + if [ "`whoami`" == "${runas_user}" ]; then + debug "Running as original user, just downloading it" + mkdir -p "${app_dir}" || + (echo "Failed to make directory ${app_dir}" && fizzle 1) + + wget "${dl_addr}" -O "${app_dir}${run_cmd}" || + (echo "Failed to download script from ${dl_addr}" && fizzle 1) + + chmod 700 "${app_dir}${run_cmd}" || + (echo "Failed to change permissions on ${app_dir}${run_cmd}" && fizzle 1) + else + debug "Running as ${runas_user}, switching and downloading" + sudo -u "${runas_user}" -- mkdir -p "${app_dir}" || + (echo "Failed to make directory ${app_dir}" && fizzle 1) + + sudo -u "${runas_user}" -- wget "${dl_addr}" -O "${app_dir}${run_cmd}" || + (echo "Failed to download script from ${dl_addr}" && fizzle 1) + + sudo -u "${runas_user}" -- chmod 700 "${app_dir}${run_cmd}" || + (echo "Failed to change permissions on ${app_dir}${run_cmd}" && fizzle 1) + fi + + echo "Installed successfully." + fizzle 0 + ;; + "r"|"R") + inform "Runtime mode requested" + launch_opt="${launch_opt} -r" + ;; + "h"|"H") + echo "${usage}" + fizzle 0 + ;; + * ) echo "Unknown option: -${OPTARG}" + echo "${usage}" + fizzle 1 + ;; + esac +done +debug "launch_opt:${launch_opt}" + + + +## Pass our knowledge on. +refresh +debug "run_app" +if [ "`whoami`" == "${runas_user}" ]; then + debug "Launching as original user, going native" + ${app_dir}${run_cmd}${launch_opt} +else + debug "Launching as ${runas_user}, checking xhost" + if [ ! "`xhost | grep ${runas_user}`" ]; then + inform "`xhost +SI:localuser:"${runas_user}"`" + fi + sudo -u "${runas_user}" -- dbus-launch ${app_dir}${run_cmd}${launch_opt} +fi + + + +## If we still exist, clean up. +debug "Final Notice" +if [ "${app_check}" ]; then + check + fizzle 0 +fi