Skip to content

Commit

Permalink
Vortex: Add option to use Steam Linux Runtime
Browse files Browse the repository at this point in the history
Vortex runs with Proton, but doesn't run inside of the SLR. This may be
causing compatibility issues on Steam Deck.

This PR adds a new option to the Vortex options in the Global Menu to
enable the Steam Linux Runtime with Vortex. The changes required to
implement this were non-trivial, but a combination of Proton and native
games were tested before and after launching Vortex from the Global Menu
(to ensure SLRCMD from the Vortex launch was not being re-used for the
game launch). Everything in testing appears to still work fine.

The `setSLRReap` function was changed significantly to enable this
functionality. It can now take an option to force Proton (instead of
falling back to ISGAME=3 which causes native Linux SLR to be selected).
It can also take a custom Proton version to use, so we don't use
RUNPROTON by default. This means we can pass the Vortex version to
getSLRReap and fetch the correct Steam Linux Runtime specified in its
toolmanifest.

This implementation has the issue of very old compatibility tools which
pass the SLR to use from the launch command will probably not work, as
Vortex cannot detect this. However, recent Vortex versions require an
up-to-date Wine anyway, so I doubt this is a problem.

The changes made to setSLRReap here should make it more straightforward
to integrate with One-Time Run, MO2, and any other third-party
application. It could also help with a future custom command overhaul
where custom-commands could have a dedicated Proton version separate
from the game (#625).
  • Loading branch information
sonic2kk committed May 20, 2023
1 parent bb8142c commit faa4225
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 12 deletions.
2 changes: 2 additions & 0 deletions lang/english.txt
Expand Up @@ -1157,3 +1157,5 @@ GUI_DLSTEAMDECKCOMPATINFO="Download Steam Deck compatibility information"
DESC_DLSTEAMDECKCOMPATINFO="Fetch Steam Deck compatibility information from Steam - Previously fetched compatibility information will be preserved"
GUI_DISABLEVORTEXAUTOUPDATE="Disable Vortex Auto Updates"
DESC_DISABLEVORTEXAUTOUPDATE="sets Vortex update channel to 'No automatic updates' which can help prevent breakages - if disabled, will set to stable/beta depending on value of 'USEVORTEXPRERELEASE' checkbox"
GUI_VORTEXUSESLR="Use Steam Linux Runtime"
DESC_VORTEXUSESLR="(EXPERIMENTAL) start Vortex inside the Steam Linux Runtime (if available), which may improve compatibility"
106 changes: 94 additions & 12 deletions steamtinkerlaunch
Expand Up @@ -6,7 +6,7 @@
PREFIX="/usr"
PROGNAME="SteamTinkerLaunch"
NICEPROGNAME="Steam Tinker Launch"
PROGVERS="v14.0.20230516-4"
PROGVERS="v14.0.20230520-3 (vortex-slr)"
PROGCMD="${0##*/}"
SHOSTL="stl"
GHURL="https://github.com"
Expand Down Expand Up @@ -2661,6 +2661,7 @@ function setDefaultCfgValues {
if [ -z "$VORTEXCOMPDATA" ] ; then VORTEXCOMPDATA="$STLVORTEXDIR/$CODA"; fi
if [ -z "$VORTEXDOWNLOADPATH" ] ; then VORTEXDOWNLOADPATH="$STLVORTEXDIR/downloads"; fi
if [ -z "$USEVORTEXPRERELEASE" ] ; then USEVORTEXPRERELEASE="0"; fi
if [ -z "$VORTEXUSESLR" ] ; then VORTEXUSESLR="0"; fi
if [ -z "$DISABLEVORTEXAUTOUPDATE" ] ; then DISABLEVORTEXAUTOUPDATE="0"; fi
if [ -z "$DISABLE_AUTOSTAGES" ] ; then DISABLE_AUTOSTAGES="0"; fi
if [ -z "$NOSTEAMSTLDEF" ] ; then NOSTEAMSTLDEF="0"; fi
Expand Down Expand Up @@ -3117,6 +3118,8 @@ function saveCfg {
echo "VORTEXDOWNLOADPATH=\"$VORTEXDOWNLOADPATH\""
echo "## $DESC_USEVORTEXPRERELEASE"
echo "USEVORTEXPRERELEASE=\"$USEVORTEXPRERELEASE\""
echo "## $DESC_VORTEXUSESLR"
echo "VORTEXUSESLR=\"$VORTEXUSESLR\""
echo "## $DESC_DISABLEVORTEXAUTOUPDATE"
echo "DISABLEVORTEXAUTOUPDATE=\"$DISABLEVORTEXAUTOUPDATE\""
echo "## $(strFix "$DESC_DISABLE_AUTOSTAGES" "$PROGNAME")"
Expand Down Expand Up @@ -5306,6 +5309,7 @@ function AllSettingsEntriesDummyFunction {
--field=" $GUI_RUN_VORTEX_WINETRICKS!$DESC_RUN_VORTEX_WINETRICKS ('RUN_VORTEX_WINETRICKS')":CHK "${RUN_VORTEX_WINETRICKS/#-/ -}" `#CAT_Vortex` `#MENU_GAME` \
--field=" $GUI_RUN_VORTEX_WINECFG!$DESC_RUN_VORTEX_WINECFG ('RUN_VORTEX_WINECFG')":CHK "${RUN_VORTEX_WINECFG/#-/ -}" `#CAT_Vortex` `#MENU_GAME` \
--field=" $GUI_USEVORTEXPRERELEASE!$DESC_USEVORTEXPRERELEASE ('USEVORTEXPRERELEASE')":CHK "${USEVORTEXPRERELEASE/#-/ -}" `#CAT_Vortex` `#SUB_Checkbox` `#MENU_GLOBAL` \
--field=" $GUI_VORTEXUSESLR!$DESC_VORTEXUSESLR ('VORTEXUSESLR')":CHK "${VORTEXUSESLR#-/ -}" `#CAT_Vortex` `#SUB_Checkbox` `#MENU_GLOBAL` \
--field=" $GUI_DISABLEVORTEXAUTOUPDATE!$DESC_DISABLEVORTEXAUTOUPDATE ('DISABLEVORTEXAUTOUPDATE')":CHK "${DISABLEVORTEXAUTOUPDATE/#-/ -}" `#CAT_Vortex` `#SUB_Checkbox` `#MENU_GLOBAL` \
--field=" $GUI_VORTEXDOWNLOADPATH!$DESC_VORTEXDOWNLOADPATH ('VORTEXDOWNLOADPATH')":DIR "${VORTEXDOWNLOADPATH/#-/ -}" `#CAT_Vortex` `#SUB_Directories` `#MENU_GLOBAL` \
--field=" $GUI_VORTEXCOMPDATA!$DESC_VORTEXCOMPDATA ('VORTEXCOMPDATA')":DIR "${VORTEXCOMPDATA/#-/ -}" `#CAT_Vortex` `#SUB_Directories` `#MENU_GLOBAL` \
Expand Down Expand Up @@ -13982,9 +13986,16 @@ function addVortexStage {
}

function wineVortexRun {
sleep 1 # required!
# LC_ALL may not be required anymore
PATH="$STLPATH" LD_LIBRARY_PATH="" LD_PRELOAD="" WINE="$VORTEXWINE" WINEARCH="win64" WINEDEBUG="-all" WINEPREFIX="$VORTEXPFX" "$@" > "$VWRUN" 2>/dev/null
sleep 1 # required!

# Is there a way to improve this without the duplicated start cmd?
if [ -n "${SLRCMD[*]}" ]; then # Should only be set if VORTEXUSESLR is defined
PATH="$STLPATH" LD_LIBRARY_PATH="" LD_PRELOAD="" WINE="$VORTEXWINE" WINEARCH="win64" WINEDEBUG="-all" WINEPREFIX="$VORTEXPFX" "${SLRCMD[@]}" "$@" > "$VWRUN" 2>/dev/null
else
PATH="$STLPATH" LD_LIBRARY_PATH="" LD_PRELOAD="" WINE="$VORTEXWINE" WINEARCH="win64" WINEDEBUG="-all" WINEPREFIX="$VORTEXPFX" "$@" > "$VWRUN" 2>/dev/null
fi

unset "${SLRCMD[@]}" # Ensure SLR is removed so that it won't be fetched and set for games launched after Vortex
}

function cleanVortex {
Expand Down Expand Up @@ -15005,6 +15016,24 @@ function setModWine {
fi
}

# Custom function to force SLR for a program outside of Steam running with Proton e.g. Vortex (may also work for One-Time Run)
function setNonGameSLRReap {
USESLR=1
HAVESLR=0
HAVEREAP="${HAVEREAP:-0}"
HAVESLRCT="${HAVESLRCT:-0}"

FORCEPROTONSLR="$1"

# Only get SLRPROTONNAME if we're forcing Proton, otherwise ignore
if [ -n "$FORCEPROTONSLR" ] && [ "$FORCEPROTONSLR" -eq 1 ]; then
SLRPROTONNAME="$( getProtPathFromCSV "$2" )" # This could be the name of the Proton version to run i.e. Vortex
fi

unset "${SLRCMD[@]}"
setSLRReap "1" "$FORCEPROTONSLR" "$SLRPROTONNAME" # Get SLRCMD, optionally enforcing Proton (so we don't fall back to native Linux) and setting the Proton version to fetch the SLR info from (e.g. whether to use soldier, sniper, etc)
}

function setVortexVars {
VORTEXPFX="${VORTEXCOMPDATA//\"/}/pfx"
if [ -z "$VORTEXEXE" ]; then
Expand Down Expand Up @@ -15047,6 +15076,11 @@ function setVortexVars {
if [ -z "$VORTEXWINE" ] || [ ! -f "$VORTEXWINE" ]; then
setModWine "SETVTXPROT" "VORTEXPROTON" "VORTEXWINE"
fi

if [ "$VORTEXUSESLR" -eq 1 ]; then
writelog "INFO" "${FUNCNAME[0]} - VORTEXUSESLR is '$VORTEXUSESLR', using Steam Linux Runtime with Vortex"
setNonGameSLRReap "1" "$USEVORTEXPROTON" # Force Proton SLR for Vortex if we enable SLR option
fi
}

function installVortex {
Expand Down Expand Up @@ -19095,24 +19129,63 @@ function getRequireToolAppidPath {
fi
}

# Function to get SLR to append to game/program launch
# Primarily used to set SLRCMD so it can be appended, but also sets the reaper command
function setSLRReap {
if [ -n "$USESLR" ] && [ -n "$HAVESLR" ]; then

# This function has gotten a bit messy with all the override options,
# but these are used to allow setSLRReap to be re-used outside of regular game launches
# such as for Vortex.

# These variables are only passed for Non-Game SLR launches i.e. Vortex, they are ignored for game launches and use fallback values

OVERRIDESLR="$1" # Always get SLR, ignoring other vars that specify otherwise
SLRFORCEPROTON="${2:-0}" # Force fetch the Proton SLR ignoring value of ISGAME
SLRPROTONVER="$3" # Proton version to fetch the SLR version from (where to find the toolmanifest.vdf from) -- Optional, will fall back to RUNPROTON set by game

# Allow overriding USESLR/HAVESLR and forcing to fetch the SLR anyway (used for times when SLR is needed outside of regular game launch e.g. Vortex)
if [ -n "$OVERRIDESLR" ]; then
writelog "INFO" "${FUNCNAME[0]} - OVERRIDESLR is enabled, ignoring user settings and fetching SLR anyway"
fi

# Set the Proton path to look for the toolmanifest.vdf file in for game launches we want RUNPROTON, but for non-game SLR cases
# we want to set a custom Proton path without overriding RUNPROTON which could interfere with subsequent game launches)
if [ -z "$SLRPROTONVER" ]; then
writelog "INFO" "${FUNCNAME[0]} - SLRPROTONVER is not defined, this is fine as regular game launches don't pass this"

writelog "INFO" "${FUNCNAME[0]} - Falling back to RUNPROTON which is '$RUNPROTON'"
SLRPROTONVER="${RUNPROTON}"
fi

# USESLR tells whether the user has chosen to get the SLR, HAVESLR refers to the legacy check for the SLR passed from the compat tool/Steam launch command
if [[ ( -n "$USESLR" && -n "$HAVESLR" ) || -n "$OVERRIDESLR" ]]; then

# Legacy SLR fetching (from Steam start command)
# --------------
# This is very legacy and won't happen anymore outside of very old compat tools
if [ "$HAVESLRCT" -eq 1 ] && [ "$USESLR" -eq 1 ]; then
writelog "INFO" "${FUNCNAME[0]} - ## SLR is enabled via USESLR=$USESLR - prepending SLR from Compatibility Tool to the current launch command"
SLRCMD=("${RUNSLRCT[@]}")
fi

# This is very legacy as well, same as above but for native games
if [ "$HAVESLR" -eq 1 ] && [ "$USESLR" -eq 1 ]; then
writelog "INFO" "${FUNCNAME[0]} - ## SLR is enabled via USESLR=$USESLR - prepending SLR from command line to the current launch command"
SLRCMD=("${RUNSLR[@]}")
fi

# Legacy case to ignore SLR gotten from commandline
if [ "$HAVESLR" -eq 1 ] && [ "$USESLR" -eq 0 ] ; then
writelog "SKIP" "${FUNCNAME[0]} - USESLR is disabled, so skipping '$SLR' found in the commandline: '${RUNSLR[*]}'"
fi
RUNFORCESLR=0
# --------------



if [ "$HAVESLR" -eq 0 ] && [ "$USESLR" -eq 1 ] ; then
# Modern SLR fetching (from toolmanifest.vdf / native Linux SLR AppID)
# ---------------
RUNFORCESLR=0
if [[ ( "$HAVESLR" -eq 0 && "$USESLR" -eq 1 ) || -n "$OVERRIDESLR" ]]; then
if [ -n "$LASTSLR" ] && [ -f "${LASTSLR% --verb*}" ] && [ "$FORCESLR" -eq 1 ]; then
writelog "INFO" "${FUNCNAME[0]} - ## No SLR provided from command line, but FORCESLR is $FORCESLR, so prepending LASTSLR '$LASTSLR' to the current launch command"
mapfile -d " " -t -O "${#LASTSLRARR[@]}" LASTSLRARR < <(printf '%s' "$LASTSLR")
Expand All @@ -19132,7 +19205,8 @@ function setSLRReap {
# Pressure Vessel Funtime 2nd Edition Ver. 2.31
writelog "INFO" "${FUNCNAME[0]} - Now executing Pressure Vessel Funtime 2nd Edition Ver. 2.31"
# Get SLR Paths
if [ "$ISGAME" -eq 3 ]; then
if [ "$ISGAME" -eq 3 ] && [ "$SLRFORCEPROTON" -eq 0 ]; then

# Native games already have a hardcoded initial native SLR AppID, so we can get the path from this hardcoded AppID
# However they need to get the required "nested" SLR from the toolmanifest from the hardcoded native SLR - This is the SLR that the regular native SLR runs inside of
# This nested AppID is stored in the hardcoded SLR's toolmanifest
Expand All @@ -19151,8 +19225,7 @@ function setSLRReap {
writelog "WARN" "${FUNCNAME[0]} - Could not find Steam Linux Runtime with AppID '$SLRAID' for native Linux game - This will need to be installed manually!"
fi
else
# Path to SLR based on AppID in Proton's `toolmanifest.vdf`
SLR_PATH="$( getRequireToolAppidPath "$( dirname "$RUNPROTON" )" )"
SLR_PATH="$( getRequireToolAppidPath "$( dirname "$SLRPROTONVER" )" )" # Path to SLR based on AppID in Proton's `toolmanifest.vdf`
fi

# Build SLRCMD
Expand All @@ -19174,18 +19247,26 @@ function setSLRReap {
SLRCMD=("${PROTON_SLRCMD[@]}" "${NATIVE_SLRCMD[@]}") # Not really "Proton" for native games, but naming is hard
else
writelog "INFO" "${FUNCNAME[0]} - Building Steam Linux Runtime command for Proton game"
SLRCMD=("${PROTON_SLRCMD[@]}")
SLRCMD=("${PROTON_SLRCMD[@]}")
fi
fi
fi

# ---------------



# Set Reaper command (currently no way to toggle this if we call setSLRReap for non-game launches, doesn't seem to have any negative impact though?)
# ---------------
if [ "$HAVEREAP" -eq 1 ] && [ "$USEREAP" -eq 1 ]; then
writelog "INFO" "${FUNCNAME[0]} - ## reaper command is enabled via USEREAP=$USEREAP - prepending to the current launch command"
SLRCMD=("${REAPCMD[@]}" "${SLRCMD[@]}")
elif [ "$HAVEREAP" -eq 0 ] && [ "$USEREAP" -eq 1 ] && [ -n "$LASTREAP" ] && [ -f "$LASTREAP" ] && [ "$FORCEREAP" -eq 1 ]; then
writelog "INFO" "${FUNCNAME[0]} - ## No reaper command provided from command line, but FORCEREAP is $FORCEREAP, so prepending LASTREAP '$LASTREAP' to the current launch command"
SLRCMD=("$LASTREAP" "SteamLaunch" "AppId=$AID" "--" "${SLRCMD[@]}")
fi
# ---------------



if [ -n "${SLRCMD[0]}" ]; then
writelog "INFO" "${FUNCNAME[0]} - Adding SLR '${SLRCMD[*]}' to the launch command"
Expand Down Expand Up @@ -19437,6 +19518,7 @@ function launchSteamGame {

writelog "INFO" "${FUNCNAME[0]} - Initial game command is '${INGCMD[*]}'"

unset "${SLRCMD[@]}"
setSLRReap

if [ "$USEBOXTRON" -eq 1 ] || [ "$USEROBERTA" -eq 1 ] || [ "$USELUXTORPEDA" -eq 1 ]; then
Expand Down

0 comments on commit faa4225

Please sign in to comment.