From a97e58f4e224b237be9e8df70b89f4c4275944a5 Mon Sep 17 00:00:00 2001 From: "Bret R. Human" Date: Tue, 21 May 2019 08:44:34 -0400 Subject: [PATCH] initial commit --- LICENSE | 52 ++++++++ README.md | 7 ++ bn3t-run.sh | 351 ++++++++++++++++++++++++++++++++++++++++++++++++++++ bn3t.sh | 317 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 727 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 bn3t-run.sh create mode 100644 bn3t.sh diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5264e41 --- /dev/null +++ b/LICENSE @@ -0,0 +1,52 @@ +bn3t +=== +Copyright (c) 2018, Bret R. Human +All rights reserved. + +Further documentation can be found at + https://mage.cynicaloptimist.me/en/bn3t + https://psi.cynicaloptimist.me/Caffarius/bn3t/ +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..87410a6 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# bn3t + +Wrapper for setting up/maintaining a Battle.net install, handy for running it as a secondary user. + + +## Usage +See the wiki article at https://mage.cynicaloptimist.me/en/Bn3t \ No newline at end of file diff --git a/bn3t-run.sh b/bn3t-run.sh new file mode 100644 index 0000000..36d279a --- /dev/null +++ b/bn3t-run.sh @@ -0,0 +1,351 @@ +#!/bin/bash +## Copyright © 2018 Bret Human +## https://cynicaloptimist.me/ +## +## Documentation at: +## https://mage.cynicaloptimist.me/en/bn3t +## https://psi.cynicaloptimist.me/Caffarius/bn3t/ +## +## For questions or comments write: +## info@cynicaloptimist.me +##################################################################### +# bn3t-run +script_ver="0.1" +page="https://mage.cynicaloptimist.me/en/bn3t" +# author: Bret Human +# date: Dec 6, 2018 +# +##################################################################### +# +# A wrapper for wrappers, used to install/manage/own a Battle.net +# installation within Wine in a Linux environment. +# +# This script is intended to be run by bn3t, Hence the name. +# +# This is the second script in the line, fired off by bn3t. This +# script handles conditionals for safely running Battle.net 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="Battle.net" +dl_addr="https://www.battle.net/download/getInstallerForGame?os=win&locale=enUS&version=LIVE&gameProgram=BATTLENET_APP" +install_dir="/drive_c/Program Files (x86)" +app_loc="/Battle.net/Battle.net.exe" +console="bash" +usage="bn3t-run, version ${script_ver} +Usage: ./`basename ${0}` -g (game) -p (prefix) -a (arch) -dvsbwtnchx + -g | Launches the game of your choice + -p | Selects the location of the Wine prefix + -a | Selects the architecture to run as (32 | 64) + -d | Debug messages on (turns verbose on) + -v | Verbose messages on + -s | Runs ${app_name} setup + -b | Runs wineboot + -w | Runs winetricks + -t | Attempts to launch to the system tray + -n | No BS mode - doesn't launch an app (for boot/tricks/console safety) + -c | Launch a console session as specified user (can launch Xapps) + -h | Help (this message) + -x | Force upgrade DXVK +See more documentation at: ${page}" + +# Catch CTRL+C and cleanup +trap "echo '' && inform '---------------------------------' && inform 'Caught CTRL+C' && warp 2" 2 + +## Set default environment +cd /home/"${runas_user}" +export WINEPREFIX="/home/${runas_user}/.bnet" +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 + +## 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 dl_addr + unset install_dir + unset app_loc + unset console + unset usage + unset WINEPREFIX + unset WINEDEBUG + unset WINEARCH + unset game_launch + unset game_name + unset game_start + unset to_tray + + # Func + unset debug + unset inform + unset game_on + unset run_wine +} + +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 + else + echo "glxgears is not installed, or I can't find it in PATH" + warp 1 + fi + ;; + wtcg|Wtcg|WTCG|hearth|hearthstone|HEARTH|HEARTHSTONE|hs|HS) + game_name="Hearthstone" + game_start="/Hearthstone/Hearthstone Beta Launcher.exe" + ;; + d3|D3|diablo3|Diablo3|DIABLO3) + game_name="Diablo 3" + game_start="/Diablo III/Diablo III Launcher.exe" + ;; + sc2|SC2|starcraft2|Starcraft2|StarCraft2|STARCRAFT2) + game_name="StarCraft II" + game_start="/StarCraft II/StarCraft II.exe" + ;; + sc|SC|starcraft|Starcraft|StarCraft|STARCRAFT) + game_name="StarCraft" + game_start="/StarCraft/StarCraft Launcher.exe" + ;; + wow|Wow|woW|WoW|WOW|worldofwarcraft|WorldofWarcraft|WorldOfWarcraft|WorldofWarCraft|WorldOfWarCraft|WORLDOFWARCRAFT) + game_name="World of WarCraft" + game_start="/World of Warcraft/World of Warcraft Launcher.exe" + ;; + hero|Hero|HERO|heros|Heros|HEROS|hots|HotS|HOTS) + game_name="Heroes of the Storm" + game_start="/Heroes of the Storm/Heroes of the Storm.exe" + ;; + pro|Pro|PRO|ow|OW|overwatch|Overwatch|OverWatch|OVERWATCH) + game_name="Overwatch" + game_start="/Overwatch/Overwatch Launcher.exe" + ;; + dst2|Dst2|DST2|destiny2|Destiny2|DESTINY2) + echo "Destiny 2 cannot currently run on Linux without being banned." + warp 1 + ;; + *) echo "Unrecognized game: ${game_launch} - Can't launch!" + echo "${usage}" + warp 1 + ;; + esac + + if [ "${game_launch}" != "test" ]; then + echo "Attempting to run ${game_name}..." + if [ -f "${WINEPREFIX}${install_dir}${game_start}" ]; then + run_wine "${WINEPREFIX}${install_dir}${game_start}" + else + echo "${game_name} is not currently installed." + warp 1 + fi + fi +} + +function run_wine () { + debug "run_wine ${1}" + if [ "${WINEARCH}" == "win64" ]; then + debug "arch: win64" + if [ "${WINEDEBUG}" ]; then + wine64 "${1}" "${to_tray}" > /dev/null 2>&1 + else + wine64 "${1}" "${to_tray}" + fi + wine64 "${1}" "${to_tray}" + elif [ "${WINEARCH}" == "win32" ]; then + debug "arch: win32" + if [ "${WINEDEBUG}" ]; then + wine "${1}" "${to_tray}" > /dev/null 2>&1 + else + wine "${1}" "${to_tray}" + fi + else # Default to AMD64 + debug "arch: default (AMD64)" + export WINEARCH=win64 + if [ "${WINEDEBUG}" ]; then + wine64 "${1}" "${to_tray}" > /dev/null 2>&1 + else + wine64 "${1}" "${to_tray}" + fi + fi +} + + + +## Pick up any arguments provided +while getopts ":g:G:p:P:a:A:dDvVsSbBwWtTnNcChHxX" 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") export WINEPREFIX="${OPTARG}";; + "a"|"A") + case "${OPTARG}" in + 32) export WINEARCH=win32;; + 64) export WINEARCH=win64;; + *) inform "Weird architecture: ${OPTARG}, ignoring";; + esac + ;; + "w"|"W") + echo "Running winetricks..." + nobs_mode="y" + if [ ! "${app_verbose}" ]; then + winetricks > /dev/null 2>&1 + else + winetricks + fi + ;; + "s"|"S") + nobs_mode="y" + if [ -f "${WINEPREFIX}${install_dir}${app_loc}" ]; then + echo "${app_name} looks like it's already installed. Aborting setup." + warp 1 + else + echo "Running setup..." + if [ ! -f "/tmp/${app_name}-Setup.exe" ]; then + inform "/tmp/${app_name}-Setup.exe was not found. Retreiving." + wget -O "/tmp/${app_name}-Setup.exe" "${dl_addr}" || + (echo "Failed to download installer from ${dl_addr}" && warp 1) + else + inform "Looks like the installer is in place. Executing." + fi + run_wine "/tmp/${app_name}-Setup.exe" + fi + ;; + "x"|"X") + echo "Upgrading dxvk..." + nobs_mode="y" + if [ ! "${app_verbose}" ]; then + winetricks --force dxvk > /dev/null 2>&1 + else + winetricks --force dxvk + fi + ;; + "b"|"B") + echo "Running wineboot..." + nobs_mode="y" + if [ -d "${WINEPREFIX}" ]; then + echo "${WINEPREFIX} already exists! Refusing to wineboot." + else + if [ "${WINEDEBUG}" ]; then + wineboot > /dev/null 2>&1 + else + wineboot + fi + fi + ;; + "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="--autostarted" + inform "Attempting hide to system tray" + ;; + "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 [[ -d "${WINEPREFIX}" || "${game_launch}" == "test" ]]; then + if [ "${game_launch}" ]; then + inform "game_launch argument: ${game_launch}" + game_on + else + echo "Running ${app_name}" + run_wine "${WINEPREFIX}${install_dir}${app_loc}" + fi + else + echo "Prefix ${WINEPREFIX} does not exist! Prep with -bs first" + warp 1 + fi +fi + + + +## If we still exist, clean up. +debug "final notice" +warp 0 diff --git a/bn3t.sh b/bn3t.sh new file mode 100644 index 0000000..374ad71 --- /dev/null +++ b/bn3t.sh @@ -0,0 +1,317 @@ +#!/bin/bash +## Copyright © 2018 Bret Human +## https://cynicaloptimist.me/ +## +## Documentation at: +## https://mage.cynicaloptimist.me/en/bn3t +## https://psi.cynicaloptimist.me/Caffarius/bn3t/ +## +## For questions or comments write: +## info@cynicaloptimist.me +##################################################################### +# bn3t +script_ver="0.1" +page="https://mage.cynicaloptimist.me/en/bn3t" +# author: Bret Human +# date: Dec 6, 2018 +# +##################################################################### +# +# A wrapper for wrappers, used to install/manage/own a Battle.net +# installation within Wine in a Linux environment. +# +# Extra handy for running Battle.net under a secondary account for +# added security. Can be used for lots of zany wine needs, like +# spawning a multitude of Wine prefixes and installing Battle.net in +# all of them. +# +# This is the first of two scripts. It is meant to be the sanitizer +# crew and the firing squad for bn3t-run. bn3t-run must be installed. +# +# Install bn3t-run for your desired user with: +# ./bn3t.sh -u username -i +# +# Then you can prep the environment and install Battle.net via: +# ./bn3t.sh -u username -bxs +# +# Or I guess you could manually download the script from: +dl_addr="https://psi.cynicaloptimist.me/Caffarius/bn3t/raw/branch/master/bn3t-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="Battle.net" +run_cmd="bn3t-run.sh" +check_wait="3" +usage="bn3t, version ${script_ver} +Usage: ./`basename ${0}` -g (game) -u (user) -p (prefix) -a (arch) -dvksbwtnchxi + -g | Launches the game of your choice + -u | Runs ${app_name} as the user specified + -p | Selects the location of the Wine prefix + -a | Selects the architecture to run as (32 | 64) + -d | Debug messages on (turns verbose on) + -v | Verbose messages on + -k | Kill all processes for a user (not current user or root) + -s | Runs ${app_name} setup + -b | Runs wineboot + -w | Runs winetricks + -t | Attempts to launch to the system tray + -n | No BS mode - doesn't launch an app (for boot/tricks/console safety) + -c | Launch a console session as specified user (can launch Xapps) + -h | Help (this message) + -x | Force upgrade DXVK + -i | Install the bn3t-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 + +## Define our functions +function refresh { + app_dir="/home/${runas_user}/.script/" + app_check="ps -ef | grep ${runas_user} | grep Battle.net.exe | 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 runas_user + unset app_name + unset run_cmd + unset check_wait + unset usage + unset app_dir + unset app_check + unset app_debug + unset app_verbose + unset launch_opt + unset nobs_mode + unset dl_addr + + # 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 + + 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 + exit 5 +} + +function check { + debug "check" + 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:p:P:a:A:dDvVkKsSbBwWtTnNcChHxXiI" option; do + case "${option}" in + "k"|"K") die 0;; + "g"|"G") launch_opt="${launch_opt} -g ${OPTARG}";; + "p"|"P") launch_opt="${launch_opt} -p ${OPTARG}";; + "a"|"A") launch_opt="${launch_opt} -a ${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 + ;; + "w"|"W") + inform "Winetricks mode" + launch_opt="${launch_opt} -w" + ;; + "s"|"S") + inform "Setup mode" + nobs_mode="y" + launch_opt="${launch_opt} -s" + ;; + "x"|"X") + inform "Force upgrading dxvk" + launch_opt="${launch_opt} -x" + ;; + "b"|"B") + inform "Wineboot mode" + launch_opt="${launch_opt} -b" + ;; + "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") + debug "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 + ;; + "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