Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GameScope: Properly handle empty GAMESCOPE_ARGS string #1049

Merged
merged 2 commits into from
Mar 6, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 46 additions & 38 deletions steamtinkerlaunch
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
PREFIX="/usr"
PROGNAME="SteamTinkerLaunch"
NICEPROGNAME="Steam Tinker Launch"
PROGVERS="v14.0.20240218-1"
PROGVERS="v14.0.20240307-1"
PROGCMD="${0##*/}"
PROGINTERNALPROTNAME="Proton-stl"
SHOSTL="stl"
Expand Down Expand Up @@ -19957,49 +19957,57 @@ function gameScopeArgs { # This implementation could be VASTLY improved!
ARGSTRING="$1"
unset GAMESCOPEARGSARR

if [ "$1" != "$NON" ]; then
# This removes paths from the GameScope args array as spaces in paths can cause issues, then builds the array, and then re-inserts the paths where it finds empty single-quotes which we wrap paths with in GameScopeGui.
# When saving from the main menu, single quotes seem to get cleared, so we need to ensure paths are wrapped with them
# Even if no args are given we always have to end GameScope commands with '--'
# $1 == NON when we save with no arguments, doing this visually preserves the GameScope "none" text while still gracefully handling blank args by forcing '--'
if [ "$1" == "$NON" ] || [ -z "$( trimWhitespaces "$1" )" ]; then # trimWhitespaces accounts for strings that are just whitespaces, i.e. ' '
writelog "INFO" "${FUNCNAME[0]} - No gamescope arguments given, but we need to end with '--', so forcing GAMESCOPEARGSARR to '--' and returning"
GAMESCOPEARGSARR=("--")
return
fi

# This removes paths from the GameScope args array as spaces in paths can cause issues, then builds the array, and then re-inserts the paths where it finds empty single-quotes which we wrap paths with in GameScopeGui.
# When saving from the main menu, single quotes seem to get cleared, so we need to ensure paths are wrapped with them

# Store paths from GameScope array string
IFS_backup=$IFS
IFS=$'\n'
mapfile -t GAMESCOPE_ARGPATHS < <( echo "$ARGSTRING" | grep -oP "'/(.+?)'" )
writelog "INFO" "${FUNCNAME[0]} - GameScope incoming args are '${ARGSTRING[*]}'"
# If the above is empty, try and surround any existing paths with quotes and then grep for the file paths from the quotes - This means paths cannot contain quotes, but oh well. Compromise!
if [ -z "${GAMESCOPE_ARGPATHS[*]}" ]; then
writelog "INFO" "${FUNCNAME[0]} - Could not find any paths from incoming GameScope arguments, checking if we need to surround any paths in quotes..."
unset GAMESCOPE_ARGPATHS

# Store paths from GameScope array string
IFS_backup=$IFS
IFS=$'\n'
# shellcheck disable=SC2001
ARGSTRING="$(echo "${ARGSTRING}" | sed "s:\(/\S* \S*\):'\1':g" )" # Finds paths and surrounds them in single quotes so the below grep works!
mapfile -t GAMESCOPE_ARGPATHS < <( echo "$ARGSTRING" | grep -oP "'/(.+?)'" )
writelog "INFO" "${FUNCNAME[0]} - GameScope incoming args are '${ARGSTRING[*]}'"
# If the above is empty, try and surround any existing paths with quotes and then grep for the file paths from the quotes - This means paths cannot contain quotes, but oh well. Compromise!
if [ -z "${GAMESCOPE_ARGPATHS[*]}" ]; then
writelog "INFO" "${FUNCNAME[0]} - Could not find any paths from incoming GameScope arguments, checking if we need to surround any paths in quotes..."
unset GAMESCOPE_ARGPATHS

# shellcheck disable=SC2001
ARGSTRING="$(echo "${ARGSTRING}" | sed "s:\(/\S* \S*\):'\1':g" )" # Finds paths and surrounds them in single quotes so the below grep works!
mapfile -t GAMESCOPE_ARGPATHS < <( echo "$ARGSTRING" | grep -oP "'/(.+?)'" )
if [ -n "${GAMESCOPE_ARGPATHS[*]}" ]; then
writelog "INFO" "${FUNCNAME[0]} - We found some paths we need to update - Updated GameScope args string is '$ARGSTRING'"
else
writelog "INFO" "${FUNCNAME[0]} - Still could not find any paths from incoming GameScope arguments, assuming we don't have any paths in our arguments"
fi
if [ -n "${GAMESCOPE_ARGPATHS[*]}" ]; then
writelog "INFO" "${FUNCNAME[0]} - We found some paths we need to update - Updated GameScope args string is '$ARGSTRING'"
else
writelog "INFO" "${FUNCNAME[0]} - Still could not find any paths from incoming GameScope arguments, assuming we don't have any paths in our arguments"
fi
IFS=$IFS_backup
fi
IFS=$IFS_backup

# Remove all text between single quotes -- We assume all text between single quotes in this context will be a GameScope path arg
writelog "INFO" "${FUNCNAME[0]} - GameScope arg paths are '${GAMESCOPE_ARGPATHS[*]}'"
# shellcheck disable=SC2001
ARGSTRING="$( echo "$ARGSTRING" | sed "s:'[^']*':'':g" )"
mapfile -d " " -t -O "${#GAMESCOPEARGSARR[@]}" GAMESCOPEARGSARR < <(printf '%s' "$ARGSTRING")
# Remove all text between single quotes -- We assume all text between single quotes in this context will be a GameScope path arg
writelog "INFO" "${FUNCNAME[0]} - GameScope arg paths are '${GAMESCOPE_ARGPATHS[*]}'"
# shellcheck disable=SC2001
ARGSTRING="$( echo "$ARGSTRING" | sed "s:'[^']*':'':g" )"
mapfile -d " " -t -O "${#GAMESCOPEARGSARR[@]}" GAMESCOPEARGSARR < <(printf '%s' "$ARGSTRING")

INSERTARG=$((0)) # Which path arg to insert from the `GAMESCOPE_ARGPATHS` array
GAMESCOPEARGSARR_COPY=("${GAMESCOPEARGSARR[@]}")
for i in "${!GAMESCOPEARGSARR_COPY[@]}"; do
if [[ "${GAMESCOPEARGSARR_COPY[$i]}" == *"'"* ]]; then
GAMESCOPEARGSARR_COPY[$i]="${GAMESCOPE_ARGPATHS[${INSERTARG}]}"
INSERTARG=$((INSERTARG + 1))
fi
done
INSERTARG=$((0)) # Which path arg to insert from the `GAMESCOPE_ARGPATHS` array
GAMESCOPEARGSARR_COPY=("${GAMESCOPEARGSARR[@]}")
for i in "${!GAMESCOPEARGSARR_COPY[@]}"; do
if [[ "${GAMESCOPEARGSARR_COPY[$i]}" == *"'"* ]]; then
GAMESCOPEARGSARR_COPY[$i]="${GAMESCOPE_ARGPATHS[${INSERTARG}]}"
INSERTARG=$((INSERTARG + 1))
fi
done

unset GAMESCOPEARGSARR # Reset array and re-assign it to copied array with updated argument values
GAMESCOPEARGSARR=("${GAMESCOPEARGSARR_COPY[@]}")
fi
unset GAMESCOPEARGSARR # Reset array and re-assign it to copied array with updated argument values
GAMESCOPEARGSARR=("${GAMESCOPEARGSARR_COPY[@]}")

## TODO handle GameScope arguments that don't end in `--`

if [ "${#GAMESCOPEARGSARR[@]}" -ge 1 ]; then
writelog "INFO" "${FUNCNAME[0]} - Using following gamescope arguments: '${GAMESCOPEARGSARR[*]}'"
Expand Down