From a4bfe2170044160f7d3df5a2806b1d42e978de12 Mon Sep 17 00:00:00 2001 From: Eamonn Rea Date: Sat, 28 Oct 2023 00:15:24 +0100 Subject: [PATCH 01/15] Non-Steam: Add functions to get information about Non-Steam Games --- steamtinkerlaunch | 78 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 3 deletions(-) diff --git a/steamtinkerlaunch b/steamtinkerlaunch index c0494514..c74faab5 100755 --- a/steamtinkerlaunch +++ b/steamtinkerlaunch @@ -399,6 +399,16 @@ WINE_FSR_CUSTOM_RESOLUTIONS=( #PROTON50="1245040" #PROTON513="1420170" +# Hex patterns for various blocks in shortcuts.vdf that we can grep for -- Casing matters! +SHORTCUTVDFFILESTARTHEXPAT="0073686f7274637574730000300002" # Bytes denoting the beginning of the shortcuts.vdf file +SHORTCUTVDFENTRYBEGINHEXPAT="00080800.*?0002" # Pattern for beginning of shortcut entry in shortcuts.vdf -- Beginning of file has a different pattern, but every other pattern begins like this +SHORTCUTSVDFENTRYENDHEXPAT="000808" # Pattern for how shortcuts.vdf blocks end +SHORTCUTVDFAPPIDHEXPAT="617070696400" # 'appid' +SHORTCUTVDFNAMEHEXPAT="(014170704e616d6500|6170706e616d65)" # 'AppName' and 'appname' +SHORTCUTVDFEXEHEXPAT="000145786500" # 'Exe' ('exe' is 6578650a if we ever need it) +SHORTCUTVDFSTARTDIRHEXPAT="0001537461727444697200" # 'StartDir' +SHORTCUTVDFENDPAT="0001" # Generic end pattern for each shortcut.vdf column + function setGNID { # only keep alphabet chars INGN="$(tr -cd '[:alnum:]' <<< "${1^^}")" @@ -1632,15 +1642,21 @@ function getGridsForOwnedGames { } function getGridsForInstalledGames { if checkSGDbApi; then - if [ "$(listInstalledGameIDs | wc -l)" -eq 0 ]; then - writelog "SKIP" "${FUNCNAME[0]} - No installed games found!" - else + if [ "$(listInstalledGameIDs | wc -l)" -gt 0 ]; then while read -r INSTGAAID; do getSteamGridDBArtwork "$INSTGAAID" done <<< "$( listInstalledGameIDs )" + else + writelog "SKIP" "${FUNCNAME[0]} - No installed games found!" fi fi } +function getGridsForNonSteamGames { + if checkSGDbApi; then + # Get Non-Steam Game Name + ID + writelog "INFO" "${FUNCNAME[0]} - STUB" + fi +} # Search SteamGridDB endpoint using game title and return the first (best match) Game ID function getSGDBGameIDFromTitle { @@ -7889,6 +7905,55 @@ function getGameDir { fi } +function listSteamShortcuts { + writelog "INFO" "${FUNCNAME[0]} - STUB" +} + +# Convert Steam Shortcut AppID from hex to 32bit unsigned integer +function convertSteamShortcutAppID { + SHORTCUTAPPIDHEX="$1" + SHORTCUTAPPIDLITTLEENDIAN="$( echo "$SHORTCUTAPPIDHEX" | tac -rs .. | tr -d '\n' )" + echo "$((16#${SHORTCUTAPPIDLITTLEENDIAN}))" +} + +# Convert shortcuts.vdf hex to text with nullbyte stripped +function convertSteamShortcutHex { + printf "$1" | xxd -r -p | tr -d '\0' +} + +# Parse a hex shortcuts.vdf entry based on a start pattern and convert to text +# Unfortunately does not work for appid +function parseSteamShortcutEntryHex { + SHORTCUTSVDFINPUTHEX="$1" # The hex block representing the shortcut + SHORTCUTSVDFMATCHPATTERN="$2" # The pattern to match against in the block + + convertSteamShortcutHex "$( printf "$SHORTCUTSVDFINPUTHEX" | grep -oP "${SHORTCUTSVDFMATCHPATTERN}\K.*?(?=${SHORTCUTVDFENDPAT})" )" # Grep for pattern, convert to text +} + +# Get shortcuts.vdf hex and grep each entry using start and end patterns (including a special case for the beginning of shortcuts.vdf) +function getSteamShortcutHex { + SCPATH="$STUIDPATH/config/$SCVDF" + xxd -p -c 0 "$SCPATH" | grep -oP "(${SHORTCUTVDFFILESTARTHEXPAT}|${SHORTCUTVDFENTRYBEGINHEXPAT})\K.*?(?=${SHORTCUTSVDFENTRYENDHEXPAT})" # Get entire shortcuts.vdf as hex, then grep each entry using the begin and end patterns for each block +} + +# Grep and convert AppID from a given block of hex representing a shortcut entry in shortcuts.vdf by taking the first 8 bytes +function parseSteamShortcutEntryAppID { + convertSteamShortcutAppID "$( printf "$1" | grep -oP "${SHORTCUTVDFAPPIDHEXPAT}\K.{8}" )" +} + +### Functions to get information from specific parts of the shortcuts VDF ### +function parseSteamShortcutEntryAppName { + parseSteamShortcutEntryHex "$1" "${SHORTCUTVDFNAMEHEXPAT}" +} + +function parseSteamShortcutEntryExe { + parseSteamShortcutEntryHex "$1" "${SHORTCUTVDFEXEHEXPAT}" +} + +function parseSteamShortcutEntryStartDir { + parseSteamShortcutEntryHex "$1" "${SHORTCUTVDFSTARTDIRHEXPAT}" +} + function getGameWindowName { if [ -n "$GAMEWINDOW" ] && [ "$GAMEWINDOW" != "$NON" ]; then writelog "SKIP" "${FUNCNAME[0]} - Already have the gamewindow name: '$GAMEWINDOW' - skipping" @@ -21831,6 +21896,13 @@ function commandline { fetchGameSLRGui "$2" elif [ "$1" == "debug" ]; then # Why are you looking here? :-) + while read -r SCVDFE; do + SVDFENAME="$( parseSteamShortcutEntryAppName "$SCVDFE" )" + SVDFEAID="$( parseSteamShortcutEntryAppID "$SCVDFE" )" + SVDFEEXE="$( parseSteamShortcutEntryExe "$SCVDFE" )" + + printf "%s (%s) -> %s\n" "$SVDFENAME" "$SVDFEAID" "$SVDFEEXE" + done <<< "$( getSteamShortcutHex )" # writelog "INFO" "${FUNCNAME[0]} - Stub" dlX64Dbg From 387f5920a75b2eb9320ca73037b26470df121eae Mon Sep 17 00:00:00 2001 From: Eamonn Rea Date: Sat, 28 Oct 2023 00:41:42 +0100 Subject: [PATCH 02/15] Non-Steam: Integrate Non-Steam Games with getIDFromTitle and getTitleFromID --- steamtinkerlaunch | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/steamtinkerlaunch b/steamtinkerlaunch index c74faab5..e259ea72 100755 --- a/steamtinkerlaunch +++ b/steamtinkerlaunch @@ -1390,6 +1390,16 @@ function getGameDataForInstalledGames { fi } +function listSteamShortcutGameIDs { + if haveAnySteamShortcuts ; then + while read -r SCVDFE; do + parseSteamShortcutEntryAppID "$SCVDFE" + done <<< "$( getSteamShortcutHex )" + else + writelog "SKIP" "${FUNCNAME[0]} - No Steam shortcuts found!" + fi +} + function checkSGDbApi { if [ -z "$SGDBAPIKEY" ] || [ "$SGDBAPIKEY" == "$NON" ]; then writelog "SKIP" "${FUNCNAME[0]} - No SteamGrid Api Key found - Get one at 'https://www.steamgriddb.com/profile/preferences/api/' (requires a SteamGridDB account) and see the SteamGridDB wiki page for guidance on how to supply the API key." @@ -1651,6 +1661,8 @@ function getGridsForInstalledGames { fi fi } + +# NOTE we will also need to fetch icons! function getGridsForNonSteamGames { if checkSGDbApi; then # Get Non-Steam Game Name + ID @@ -7691,12 +7703,15 @@ function listSteamGames { fi } +# TODO do we want a way to specify that this function should only return Steam or Non-Steam AppIDs? function getIDFromTitle { if [ -z "$1" ]; then echo "A Game Title (part of it might be enough) is required as argument" else # Check installed game appmanifests for name matches FOUNDMATCHES=() + + # Steam games while read -r APPMA; do APPMATITLE="$( getValueFromAppManifest "name" "$APPMA" )" if [[ ${APPMATITLE,,} == *"${1,,}"* ]]; then @@ -7705,6 +7720,19 @@ function getIDFromTitle { FOUNDMATCHES+=( "$FOUNDGAMNAM" ) fi done <<< "$( listAppManifests )" + + # Steam shortcuts + if haveAnySteamShortcuts ; then + while read -r SCVDFE; do + SVDFENAME="$( parseSteamShortcutEntryAppName "$SCVDFE" )" + SVDFEAID="$( parseSteamShortcutEntryAppID "$SCVDFE" )" + + if [[ ${SVDFENAME,,} == *"${1,,}"* ]]; then + FOUNDGAMNAM="$( printf "%s\t\t(%s)" "$SVDFEAID" "$SVDFENAME" )" + FOUNDMATCHES+=( "$FOUNDGAMNAM" ) + fi + done <<< "$( getSteamShortcutHex )" + fi if [ "${#FOUNDMATCHES[@]}" -gt 0 ]; then printf "%s\n" "${FOUNDMATCHES[@]}" else @@ -7729,6 +7757,17 @@ function getTitleFromID { if [ -n "$GAMEMANIFEST" ]; then getValueFromAppManifest "name" "$GAMEMANIFEST" + elif haveAnySteamShortcuts ; then + # Steam shortcuts + while read -r SCVDFE; do + SVDFENAME="$( parseSteamShortcutEntryAppName "$SCVDFE" )" + SVDFEAID="$( parseSteamShortcutEntryAppID "$SCVDFE" )" + + if [ "$SVDFEAID" -eq "$1" ]; then + echo "$SVDFENAME" + break + fi + done <<< "$( getSteamShortcutHex )" else echo "No Title found for '$1'" @@ -7936,6 +7975,14 @@ function getSteamShortcutHex { xxd -p -c 0 "$SCPATH" | grep -oP "(${SHORTCUTVDFFILESTARTHEXPAT}|${SHORTCUTVDFENTRYBEGINHEXPAT})\K.*?(?=${SHORTCUTSVDFENTRYENDHEXPAT})" # Get entire shortcuts.vdf as hex, then grep each entry using the begin and end patterns for each block } +function haveAnySteamShortcuts { + if [ $( getSteamShortcutHex | wc -c ) -gt 0 ]; then + return 0 + else + return 1 + fi +} + # Grep and convert AppID from a given block of hex representing a shortcut entry in shortcuts.vdf by taking the first 8 bytes function parseSteamShortcutEntryAppID { convertSteamShortcutAppID "$( printf "$1" | grep -oP "${SHORTCUTVDFAPPIDHEXPAT}\K.{8}" )" From 11c7878fd1b5a1e784b686a5631bd910e7d65729 Mon Sep 17 00:00:00 2001 From: Eamonn Rea Date: Sat, 28 Oct 2023 00:54:12 +0100 Subject: [PATCH 03/15] SteamGridDB: Add command to fetch grids for Non-Steam Games Does not support icons yet --- steamtinkerlaunch | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/steamtinkerlaunch b/steamtinkerlaunch index e259ea72..c394371f 100755 --- a/steamtinkerlaunch +++ b/steamtinkerlaunch @@ -1661,12 +1661,25 @@ function getGridsForInstalledGames { fi fi } - -# NOTE we will also need to fetch icons! function getGridsForNonSteamGames { + # NOTE we shpuld also need to fetch and set icons eventually + # (will require updating shortcuts.vdf entry which we can't do yet, may just be a case of encoding an entry and updating it with sed) + if ! haveAnySteamShortcuts ; then + writelog "SKIP" "${FUNCNAME[0]} - No Non-Steam Games found, skipping" + echo "No Non-Steam Games found, not downloading grids" + + return + fi + if checkSGDbApi; then # Get Non-Steam Game Name + ID - writelog "INFO" "${FUNCNAME[0]} - STUB" + writelog "INFO" "${FUNCNAME[0]} - Fetching artwork for all Non-Steam Games" + while read -r SCVDFE; do + SVDFENAME="$( parseSteamShortcutEntryAppName "$SCVDFE" )" + SVDFEAID="$( parseSteamShortcutEntryAppID "$SCVDFE" )" + + commandlineGetSteamGridDBArtwork --search-name="$SVDFENAME" --filename-appid="$SVDFEAID" --nonsteam + done <<< "$( getSteamShortcutHex )" fi } @@ -21689,7 +21702,7 @@ function howto { echo " or only from " echo " grid Update Steam Grid for installed game(s)" echo " optional argument either a SteamAppID," - echo " 'owned' or 'installed'" + echo " 'owned', 'installed', or 'nonsteam|shortcut'" echo " (default is 'installed')" echo " allgamedata The same as above for" echo " all games in $SCV" @@ -22244,6 +22257,8 @@ function commandline { getGridsForOwnedGames elif [ "$3" == "installed" ]; then getGridsForInstalledGames + elif [ "$3" == "nonsteam" ] || [ "$3" == "shortcuts" ]; then + getGridsForNonSteamGames fi elif [ "$2" == "allgamedata" ]; then getDataForAllGamesinSharedConfig From d745af91497c57ee73cdc0edaac789b05a195a1c Mon Sep 17 00:00:00 2001 From: Eamonn Rea Date: Mon, 30 Oct 2023 20:00:42 +0000 Subject: [PATCH 04/15] Non-Steam: Add find steam shortcut by ID --- steamtinkerlaunch | 53 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/steamtinkerlaunch b/steamtinkerlaunch index c394371f..7be6c8f8 100755 --- a/steamtinkerlaunch +++ b/steamtinkerlaunch @@ -404,7 +404,7 @@ SHORTCUTVDFFILESTARTHEXPAT="0073686f7274637574730000300002" # Bytes denoting th SHORTCUTVDFENTRYBEGINHEXPAT="00080800.*?0002" # Pattern for beginning of shortcut entry in shortcuts.vdf -- Beginning of file has a different pattern, but every other pattern begins like this SHORTCUTSVDFENTRYENDHEXPAT="000808" # Pattern for how shortcuts.vdf blocks end SHORTCUTVDFAPPIDHEXPAT="617070696400" # 'appid' -SHORTCUTVDFNAMEHEXPAT="(014170704e616d6500|6170706e616d65)" # 'AppName' and 'appname' +SHORTCUTVDFNAMEHEXPAT="(014170704e616d6500|6170706e616d6500)" # 'AppName' and 'appname' SHORTCUTVDFEXEHEXPAT="000145786500" # 'Exe' ('exe' is 6578650a if we ever need it) SHORTCUTVDFSTARTDIRHEXPAT="0001537461727444697200" # 'StartDir' SHORTCUTVDFENDPAT="0001" # Generic end pattern for each shortcut.vdf column @@ -1675,8 +1675,8 @@ function getGridsForNonSteamGames { # Get Non-Steam Game Name + ID writelog "INFO" "${FUNCNAME[0]} - Fetching artwork for all Non-Steam Games" while read -r SCVDFE; do - SVDFENAME="$( parseSteamShortcutEntryAppName "$SCVDFE" )" SVDFEAID="$( parseSteamShortcutEntryAppID "$SCVDFE" )" + SVDFENAME="$( parseSteamShortcutEntryAppName "$SCVDFE" )" commandlineGetSteamGridDBArtwork --search-name="$SVDFENAME" --filename-appid="$SVDFEAID" --nonsteam done <<< "$( getSteamShortcutHex )" @@ -7957,10 +7957,6 @@ function getGameDir { fi } -function listSteamShortcuts { - writelog "INFO" "${FUNCNAME[0]} - STUB" -} - # Convert Steam Shortcut AppID from hex to 32bit unsigned integer function convertSteamShortcutAppID { SHORTCUTAPPIDHEX="$1" @@ -7982,7 +7978,50 @@ function parseSteamShortcutEntryHex { convertSteamShortcutHex "$( printf "$SHORTCUTSVDFINPUTHEX" | grep -oP "${SHORTCUTSVDFMATCHPATTERN}\K.*?(?=${SHORTCUTVDFENDPAT})" )" # Grep for pattern, convert to text } -# Get shortcuts.vdf hex and grep each entry using start and end patterns (including a special case for the beginning of shortcuts.vdf) +# Find shortcut by AppID and return the hex entry +function findSteamShortcutByAppID { + SHORTCUTENTRYAID="$1" + + writelog "INFO" "${FUNCNAME[0]} - Searching for shortcut entry with AppID '$SHORTCUTENTRYAID'" + while read -r SCVDFE; do + SVDFEAID="$( parseSteamShortcutEntryAppID "$SCVDFE" )" + if [ "$SVDFEAID" -eq "$SHORTCUTENTRYAID" ]; then + writelog "INFO" "${FUNCNAME[0]} - Found shortcut entry with AppID '$SHORTCUTENTRYAID'" # Updating it how? + echo "$SCVDFE" + break + fi + done <<< "$( getSteamShortcutHex )" +} + +# Edit shortcut entry column with new text value +# replaces content between start and end pattern and replaces it with the input string converted to hex +# function editSteamShortcutEntryColumn { +# # Take column including start and end pattern so we get an exact match +# # Edit the value between the start and end pattern + +# writelog "INFO" "${FUNCNAME[0]} - STUB" +# } + +# Takes a Steam Shortcut AppID, finds the shortcut with that AppID, and then updates a given field i.e. "name" +# example usage: editSteamShortcutEntry "123456789" "appname" "New Name" +# function editSteamShortcutEntry { + # SHORTCUTENTRYAID="$1" + # ORGSHORTCUTENTRYHEX="$( findSteamShortcutByAppID "$SHORTCUTENTRYAID" )" + # writelog "INFO" "${FUNCNAME[0]} - STUB" +# } + + + +## TODO may be unnecessary +# Find the icon column of a given Steam shortcut hex entry and update it +# example usage: editSteamShortcutEntryIcon "" "/path/to/new_icon.png" +# function editSteamShortcutEntryIcon { +# writelog "INFO" "${FUNCNAME[0]} - STUB" +# # TODO get icon block including start and end patterns +# # TODO pass this to 'editSteamShortcutEntryColumn' +# } + +# Get shortcuts.vdf hex and grep each entry using start and end patterns (including a special case for the beginning of shortcuts.vdf) function getSteamShortcutHex { SCPATH="$STUIDPATH/config/$SCVDF" xxd -p -c 0 "$SCPATH" | grep -oP "(${SHORTCUTVDFFILESTARTHEXPAT}|${SHORTCUTVDFENTRYBEGINHEXPAT})\K.*?(?=${SHORTCUTSVDFENTRYENDHEXPAT})" # Get entire shortcuts.vdf as hex, then grep each entry using the begin and end patterns for each block From 511bd53d3c3e45d9a2439f4f94552cdcd41ff198 Mon Sep 17 00:00:00 2001 From: Eamonn Rea Date: Sun, 5 Nov 2023 17:36:45 +0000 Subject: [PATCH 05/15] cleanup --- steamtinkerlaunch | 42 ++++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/steamtinkerlaunch b/steamtinkerlaunch index 68211caa..31905b27 100755 --- a/steamtinkerlaunch +++ b/steamtinkerlaunch @@ -7945,6 +7945,8 @@ function getGameDir { fi } +### BEGIN BINARY VDF FUNCTIONS ### + # Convert Steam Shortcut AppID from hex to 32bit unsigned integer function convertSteamShortcutAppID { SHORTCUTAPPIDHEX="$1" @@ -7966,7 +7968,7 @@ function parseSteamShortcutEntryHex { convertSteamShortcutHex "$( printf "$SHORTCUTSVDFINPUTHEX" | grep -oP "${SHORTCUTSVDFMATCHPATTERN}\K.*?(?=${SHORTCUTVDFENDPAT})" )" # Grep for pattern, convert to text } -# Find shortcut by AppID and return the hex entry +# Find shortcut entry by AppID and return the hex function findSteamShortcutByAppID { SHORTCUTENTRYAID="$1" @@ -7981,33 +7983,23 @@ function findSteamShortcutByAppID { done <<< "$( getSteamShortcutHex )" } -# Edit shortcut entry column with new text value -# replaces content between start and end pattern and replaces it with the input string converted to hex -# function editSteamShortcutEntryColumn { -# # Take column including start and end pattern so we get an exact match -# # Edit the value between the start and end pattern - -# writelog "INFO" "${FUNCNAME[0]} - STUB" -# } +## Takes a shortcut appid, gets the entry, updates the given column value, replaces the original hex section, writes out new hex string to `shortcuts.vdf` +function editSteamShortcutEntry { + SCPATH="$STUIDPATH/config/$SCVDF" # TODO make this a globally accessible path instead of hardcoding it everywhere -# Takes a Steam Shortcut AppID, finds the shortcut with that AppID, and then updates a given field i.e. "name" -# example usage: editSteamShortcutEntry "123456789" "appname" "New Name" -# function editSteamShortcutEntry { - # SHORTCUTENTRYAID="$1" - # ORGSHORTCUTENTRYHEX="$( findSteamShortcutByAppID "$SHORTCUTENTRYAID" )" - # writelog "INFO" "${FUNCNAME[0]} - STUB" -# } + SHORTCUTENTRYAID="$1" # i.e. 23435463 + SHORTCUTCOLUMN="$2" # i.e. "appname" + SHORTCUTNEWVAL="$3" # i.e. "New Name" + SHORTCUTSCONTENT="$( getSteamShortcutHex )" + SHORTCUTSENTRY="$( findSteamShortcutByAppID "$SHORTCUTENTRYAID" )" + # TODO get column with matching name and replace the hex value with the new value + # we will need to encode the new value, then replace the original pattern with the new one + # Once we have the update shortcut block, replace it in the SHORTCUTSCONTENT, then write to shortcuts.vdf -## TODO may be unnecessary -# Find the icon column of a given Steam shortcut hex entry and update it -# example usage: editSteamShortcutEntryIcon "" "/path/to/new_icon.png" -# function editSteamShortcutEntryIcon { -# writelog "INFO" "${FUNCNAME[0]} - STUB" -# # TODO get icon block including start and end patterns -# # TODO pass this to 'editSteamShortcutEntryColumn' -# } + # return new shortcut hex +} # Get shortcuts.vdf hex and grep each entry using start and end patterns (including a special case for the beginning of shortcuts.vdf) function getSteamShortcutHex { @@ -8041,6 +8033,8 @@ function parseSteamShortcutEntryStartDir { parseSteamShortcutEntryHex "$1" "${SHORTCUTVDFSTARTDIRHEXPAT}" } +### END BINARY VDF FUNCTIONS ### + function getGameWindowName { if [ -n "$GAMEWINDOW" ] && [ "$GAMEWINDOW" != "$NON" ]; then writelog "SKIP" "${FUNCNAME[0]} - Already have the gamewindow name: '$GAMEWINDOW' - skipping" From 87ce327485b744cb1e43423c06522622fee269d4 Mon Sep 17 00:00:00 2001 From: Eamonn Rea Date: Sun, 5 Nov 2023 17:37:12 +0000 Subject: [PATCH 06/15] version change --- steamtinkerlaunch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/steamtinkerlaunch b/steamtinkerlaunch index 31905b27..2ab2e578 100755 --- a/steamtinkerlaunch +++ b/steamtinkerlaunch @@ -6,7 +6,7 @@ PREFIX="/usr" PROGNAME="SteamTinkerLaunch" NICEPROGNAME="Steam Tinker Launch" -PROGVERS="v14.0.20231105-3" +PROGVERS="v14.0.20231106-1 (get-sgdb-for-all-nonsteam-aids)" PROGCMD="${0##*/}" PROGINTERNALPROTNAME="Proton-stl" SHOSTL="stl" From c1eb4ca09bd587bbbdfd815f8ad6dc8a610c4991 Mon Sep 17 00:00:00 2001 From: Eamonn Rea Date: Mon, 6 Nov 2023 18:42:15 +0000 Subject: [PATCH 07/15] Non-Steam: Add function to edit shortcut entry --- steamtinkerlaunch | 84 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 75 insertions(+), 9 deletions(-) diff --git a/steamtinkerlaunch b/steamtinkerlaunch index 2ab2e578..032f34f6 100755 --- a/steamtinkerlaunch +++ b/steamtinkerlaunch @@ -400,6 +400,7 @@ SHORTCUTVDFAPPIDHEXPAT="617070696400" # 'appid' SHORTCUTVDFNAMEHEXPAT="(014170704e616d6500|6170706e616d6500)" # 'AppName' and 'appname' SHORTCUTVDFEXEHEXPAT="000145786500" # 'Exe' ('exe' is 6578650a if we ever need it) SHORTCUTVDFSTARTDIRHEXPAT="0001537461727444697200" # 'StartDir' +SHORTCUTVDFICONHEXPAT="000169636f6e00" # 'icon' SHORTCUTVDFENDPAT="0001" # Generic end pattern for each shortcut.vdf column function setGNID { @@ -7959,13 +7960,21 @@ function convertSteamShortcutHex { printf "$1" | xxd -r -p | tr -d '\0' } +# Get the raw, unparsed hex for an entry from shortcuts.vdf +function getSteamShortcutEntryHex { + SHORTCUTSVDFINPUTHEX="$1" # The hex block representing the shortcut + SHORTCUTSVDFMATCHPATTERN="$2" # The pattern to match against in the block + + printf "$SHORTCUTSVDFINPUTHEX" | grep -oP "${SHORTCUTSVDFMATCHPATTERN}\K.*?(?=${SHORTCUTVDFENDPAT})" +} + # Parse a hex shortcuts.vdf entry based on a start pattern and convert to text # Unfortunately does not work for appid function parseSteamShortcutEntryHex { SHORTCUTSVDFINPUTHEX="$1" # The hex block representing the shortcut SHORTCUTSVDFMATCHPATTERN="$2" # The pattern to match against in the block - convertSteamShortcutHex "$( printf "$SHORTCUTSVDFINPUTHEX" | grep -oP "${SHORTCUTSVDFMATCHPATTERN}\K.*?(?=${SHORTCUTVDFENDPAT})" )" # Grep for pattern, convert to text + convertSteamShortcutHex "$( getSteamShortcutEntryHex "$SHORTCUTSVDFINPUTHEX" "$SHORTCUTSVDFMATCHPATTERN" )" } # Find shortcut entry by AppID and return the hex @@ -7983,28 +7992,77 @@ function findSteamShortcutByAppID { done <<< "$( getSteamShortcutHex )" } -## Takes a shortcut appid, gets the entry, updates the given column value, replaces the original hex section, writes out new hex string to `shortcuts.vdf` +function replaceSteamShortcutEntryValue { + SHORTCUTSVDFENTRY="$1" + SHORTCUTSVDFMATCHPATTERN="$2" + SHORTCUTSVDFNEWVAL="$3" + + SHORTCUTSVDFOLDVAL="$( getSteamShortcutEntryHex "$SHORTCUTSVDFENTRY" "$SHORTCUTSVDFMATCHPATTERN" | sed -E 's/0a$//g' )" # Get the value without start and end bytes + SHORTCUTSVDFOLDCOL="$( printf "$SHORTCUTSVDFENTRY" | grep -oP "${SHORTCUTSVDFMATCHPATTERN}.*?${SHORTCUTVDFENDPAT}" )" # Get value with start and end bytes + + SHORTCUTSVDFNEWCOL="${SHORTCUTSVDFOLDCOL//"$SHORTCUTSVDFOLDVAL"/"$SHORTCUTSVDFNEWVAL"}" + SHORTCUTNEWENTRY="${SHORTCUTSVDFENTRY//"$SHORTCUTSVDFOLDCOL"/"$SHORTCUTSVDFNEWCOL"}" + + printf "$SHORTCUTNEWENTRY" | tr -d '\0' +} + +## Takes a shortcut appid, finds the shortcut entry, updates the given column value, replaces the hex for that section in the hex for the shortcuts.vdf file, writes out updated hex to new file +## Note: This writes out an extra '0a' byte after the new entry value, but it seems to come all the way up from "getSteamShortcutsVdfFileHex" +## Didn't cause any problems during testing but keep in mind in case it causes problems later! function editSteamShortcutEntry { SCPATH="$STUIDPATH/config/$SCVDF" # TODO make this a globally accessible path instead of hardcoding it everywhere SHORTCUTENTRYAID="$1" # i.e. 23435463 SHORTCUTCOLUMN="$2" # i.e. "appname" - SHORTCUTNEWVAL="$3" # i.e. "New Name" + SHORTCUTNEWVAL="$( xxd -p -c 0 <<< "$3" )" # i.e. "New Name" but in hex - SHORTCUTSCONTENT="$( getSteamShortcutHex )" + SHORTCUTSCONTENT="$( getSteamShortcutsVdfFileHex )" SHORTCUTSENTRY="$( findSteamShortcutByAppID "$SHORTCUTENTRYAID" )" - # TODO get column with matching name and replace the hex value with the new value - # we will need to encode the new value, then replace the original pattern with the new one - # Once we have the update shortcut block, replace it in the SHORTCUTSCONTENT, then write to shortcuts.vdf + DEBUG_SCNAME="$( getSteamShortcutEntryHex "$SHORTCUTSENTRY" "$SHORTCUTVDFNAMEHEXPAT" )" + + ## Find bytes that represent the column in shortcuts.vdf + SHORTCUTEDITSTARTBYTES="" + case $SHORTCUTCOLUMN in + "appid") + writelog "WARN" "${FUNCNAME[0]} - AppID not supported, skipping" + shift ;; + "appname") + SHORTCUTEDITSTARTBYTES="${SHORTCUTVDFNAMEHEXPAT}" + shift ;; + "Exe") + SHORTCUTEDITSTARTBYTES="${SHORTCUTVDFEXEHEXPAT}" + shift;; + "StartDir") + SHORTCUTEDITSTARTBYTES="${SHORTCUTVDFSTARTDIRHEXPAT}" + shift ;; + "icon") + SHORTCUTEDITSTARTBYTES="${SHORTCUTVDFICONHEXPAT}" + shift ;; + esac - # return new shortcut hex + if [ -z "$SHORTCUTEDITSTARTBYTES" ]; then + writelog "INFO" "${FUNCNAME[0]} - Unknown or unsupported column name '$SHORTCUTCOLUMN', skipping" + return + fi + + # Replace original entry's value bytes with new bytes, then replace the old bytes in the entire shortcuts file with the new bytes and write it out + SHORTCUTNEWENTRY="$( replaceSteamShortcutEntryValue "$SHORTCUTSENTRY" "$SHORTCUTEDITSTARTBYTES" "$SHORTCUTNEWVAL" )" + SHORTCUTSCONTENT="${SHORTCUTSCONTENT//"$SHORTCUTSENTRY"/"$SHORTCUTNEWENTRY"}" + + echo "$SHORTCUTSCONTENT" | xxd -r -p > "$SCPATH" } # Get shortcuts.vdf hex and grep each entry using start and end patterns (including a special case for the beginning of shortcuts.vdf) function getSteamShortcutHex { SCPATH="$STUIDPATH/config/$SCVDF" - xxd -p -c 0 "$SCPATH" | grep -oP "(${SHORTCUTVDFFILESTARTHEXPAT}|${SHORTCUTVDFENTRYBEGINHEXPAT})\K.*?(?=${SHORTCUTSVDFENTRYENDHEXPAT})" # Get entire shortcuts.vdf as hex, then grep each entry using the begin and end patterns for each block + getSteamShortcutsVdfFileHex | grep -oP "(${SHORTCUTVDFFILESTARTHEXPAT}|${SHORTCUTVDFENTRYBEGINHEXPAT})\K.*?(?=${SHORTCUTSVDFENTRYENDHEXPAT})" # Get entire shortcuts.vdf as hex, then grep each entry using the begin and end patterns for each block +} + +# Get full shortcuts.vdf hex including all start and end bytes -- Used for editing shortcuts.vdf +function getSteamShortcutsVdfFileHex { + SCPATH="$STUIDPATH/config/$SCVDF" + xxd -p -c 0 "$SCPATH" } function haveAnySteamShortcuts { @@ -8033,6 +8091,10 @@ function parseSteamShortcutEntryStartDir { parseSteamShortcutEntryHex "$1" "${SHORTCUTVDFSTARTDIRHEXPAT}" } +function parseSteamShortcutEntryIcon { + parseSteamShortcutEntryHex "$1" "${SHORTCUTVDFICONHEXPAT}" +} + ### END BINARY VDF FUNCTIONS ### function getGameWindowName { @@ -21965,6 +22027,10 @@ function commandline { DEBUGNOSTAID="-222353304" + editSteamShortcutEntry "3917765712" "appname" "Horny Game" + + return + # DEBUG_LOCOVDF="$STUIDPATH/config/localconfig bsak.vdf" ## Get nested VDF section From 061bab1946746cc413fe80e35545bf409db912fb Mon Sep 17 00:00:00 2001 From: Eamonn Rea Date: Mon, 6 Nov 2023 19:08:53 +0000 Subject: [PATCH 08/15] Non-Steam: Support editing blank entries --- steamtinkerlaunch | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/steamtinkerlaunch b/steamtinkerlaunch index 032f34f6..cec5f85e 100755 --- a/steamtinkerlaunch +++ b/steamtinkerlaunch @@ -6,7 +6,7 @@ PREFIX="/usr" PROGNAME="SteamTinkerLaunch" NICEPROGNAME="Steam Tinker Launch" -PROGVERS="v14.0.20231106-1 (get-sgdb-for-all-nonsteam-aids)" +PROGVERS="v14.0.20231107-1 (get-sgdb-for-all-nonsteam-aids)" PROGCMD="${0##*/}" PROGINTERNALPROTNAME="Proton-stl" SHOSTL="stl" @@ -7997,18 +7997,22 @@ function replaceSteamShortcutEntryValue { SHORTCUTSVDFMATCHPATTERN="$2" SHORTCUTSVDFNEWVAL="$3" - SHORTCUTSVDFOLDVAL="$( getSteamShortcutEntryHex "$SHORTCUTSVDFENTRY" "$SHORTCUTSVDFMATCHPATTERN" | sed -E 's/0a$//g' )" # Get the value without start and end bytes + SHORTCUTSVDFOLDVAL="$( getSteamShortcutEntryHex "$SHORTCUTSVDFENTRY" "$SHORTCUTSVDFMATCHPATTERN" )" # Get the value without start and end bytes SHORTCUTSVDFOLDCOL="$( printf "$SHORTCUTSVDFENTRY" | grep -oP "${SHORTCUTSVDFMATCHPATTERN}.*?${SHORTCUTVDFENDPAT}" )" # Get value with start and end bytes - SHORTCUTSVDFNEWCOL="${SHORTCUTSVDFOLDCOL//"$SHORTCUTSVDFOLDVAL"/"$SHORTCUTSVDFNEWVAL"}" + + # Handle blank entries by simply hardcoding old entry and building new entry + if [ -z "$SHORTCUTSVDFOLDVAL" ]; then + SHORTCUTSVDFOLDCOL="${SHORTCUTSVDFMATCHPATTERN}${SHORTCUTVDFENDPAT}" + SHORTCUTSVDFNEWCOL="${SHORTCUTSVDFMATCHPATTERN}${SHORTCUTSVDFNEWVAL}${SHORTCUTVDFENDPAT}" + fi + SHORTCUTNEWENTRY="${SHORTCUTSVDFENTRY//"$SHORTCUTSVDFOLDCOL"/"$SHORTCUTSVDFNEWCOL"}" printf "$SHORTCUTNEWENTRY" | tr -d '\0' } ## Takes a shortcut appid, finds the shortcut entry, updates the given column value, replaces the hex for that section in the hex for the shortcuts.vdf file, writes out updated hex to new file -## Note: This writes out an extra '0a' byte after the new entry value, but it seems to come all the way up from "getSteamShortcutsVdfFileHex" -## Didn't cause any problems during testing but keep in mind in case it causes problems later! function editSteamShortcutEntry { SCPATH="$STUIDPATH/config/$SCVDF" # TODO make this a globally accessible path instead of hardcoding it everywhere @@ -8050,7 +8054,8 @@ function editSteamShortcutEntry { SHORTCUTNEWENTRY="$( replaceSteamShortcutEntryValue "$SHORTCUTSENTRY" "$SHORTCUTEDITSTARTBYTES" "$SHORTCUTNEWVAL" )" SHORTCUTSCONTENT="${SHORTCUTSCONTENT//"$SHORTCUTSENTRY"/"$SHORTCUTNEWENTRY"}" - echo "$SHORTCUTSCONTENT" | xxd -r -p > "$SCPATH" + # Write out new bytes with bad 0a byte removed (causes issues when reading paths etc, so strip it out) + echo "$SHORTCUTSCONTENT" | sed 's/0a//g' | xxd -r -p > "$SCPATH" } # Get shortcuts.vdf hex and grep each entry using start and end patterns (including a special case for the beginning of shortcuts.vdf) @@ -22027,7 +22032,7 @@ function commandline { DEBUGNOSTAID="-222353304" - editSteamShortcutEntry "3917765712" "appname" "Horny Game" + editSteamShortcutEntry "3917765712" "appname" "Updated Name" return From eb0d30b54946a7b9a4cccf0ca0d753f13406b6b6 Mon Sep 17 00:00:00 2001 From: Eamonn Rea Date: Tue, 7 Nov 2023 00:07:05 +0000 Subject: [PATCH 09/15] Non-Steam: Download icons in getGridsForNonSteamGames --- steamtinkerlaunch | 55 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/steamtinkerlaunch b/steamtinkerlaunch index cec5f85e..129a5941 100755 --- a/steamtinkerlaunch +++ b/steamtinkerlaunch @@ -1668,7 +1668,13 @@ function getGridsForNonSteamGames { SVDFEAID="$( parseSteamShortcutEntryAppID "$SCVDFE" )" SVDFENAME="$( parseSteamShortcutEntryAppName "$SCVDFE" )" + ## TODO + ## - getSteamGridDBNonSteamIcon was broken out from addNonSteamGame -- Ensure functionality still works there + ## - write out icon to shortcuts.vdf entry with editSteamShortcutEntry (need to get path for icon) + ## - strange files with SGDB AID are being generated in STL dir -- Investigate commandlineGetSteamGridDBArtwork --search-name="$SVDFENAME" --filename-appid="$SVDFEAID" --nonsteam + CMDLINEGETSGDBARTAID="$( cat "$NOSTSGDBID" )" + getSteamGridDBNonSteamIcon "$SVDFEAID" "$CMDLINEGETSGDBARTAID" done <<< "$( getSteamShortcutHex )" fi } @@ -23542,6 +23548,23 @@ function filterUnwantedSteamCategories { printf "%s" "${FILTEREDTAGS[@]}" | tr '\n' '!' | sed 's/\!*$//g' } +# Download icon for Non-Steam Game using SteamGridDB Game ID +# We can't set icons for Steam games, and right now we can't edit the `shortcuts.vdf` file to edit the path to the icon, +# so this function is only for Non-Steam Games and only when they're being added to Steam +# +# In future, if we have a function to add SteamGridDB art for all Non-Steam Games, we could break this out and use it to set icons at that time too +function getSteamGridDBNonSteamIcon { + NOSTICONAID="$1" # Non-Steam AppID + NOSTSGDBID="$2" # SteamGridDB Game ID + NOSTICONNAME="${NOSTICONAID}_icon" + SGDBSEARCHENDPOINT_ICONS="${BASESTEAMGRIDDBAPI}/icons/game" + + # Download icon and put it in Steam grids folder, which should be a safe and intuitive location + # We don't have any way to set search settings for icons and it would be confusing to have this in the Global Menu for now, so just leave blank + # In future if we have Non-Steam Game global settings, we could include icon settings there too + downloadArtFromSteamGridDB "$NOSTSGDBID" "$SGDBSEARCHENDPOINT_ICONS" "${NOSTICONNAME}" "" "" "" "" "" "" "replace" "1" +} + function addNonSteamGameGui { writelog "INFO" "${FUNCNAME[0]} - Starting the Gui for adding a $NSGA to Steam" @@ -23794,22 +23817,22 @@ function addNonSteamGame { fi } - # Download icon for Non-Steam Game using SteamGridDB Game ID - # We can't set icons for Steam games, and right now we can't edit the `shortcuts.vdf` file to edit the path to the icon, - # so this function is only for Non-Steam Games and only when they're being added to Steam - # - # In future, if we have a function to add SteamGridDB art for all Non-Steam Games, we could break this out and use it to set icons at that time too - function getSteamGridDBNonSteamIcon { - NOSTICONAID="$1" # Non-Steam AppID - NOSTSGDBID="$2" # SteamGridDB Game ID - NOSTICONNAME="${NOSTICONAID}_icon" - SGDBSEARCHENDPOINT_ICONS="${BASESTEAMGRIDDBAPI}/icons/game" - - # Download icon and put it in Steam grids folder, which should be a safe and intuitive location - # We don't have any way to set search settings for icons and it would be confusing to have this in the Global Menu for now, so just leave blank - # In future if we have Non-Steam Game global settings, we could include icon settings there too - downloadArtFromSteamGridDB "$NOSTSGDBID" "$SGDBSEARCHENDPOINT_ICONS" "${NOSTICONNAME}" "" "" "" "" "" "" "replace" "1" - } + # # Download icon for Non-Steam Game using SteamGridDB Game ID + # # We can't set icons for Steam games, and right now we can't edit the `shortcuts.vdf` file to edit the path to the icon, + # # so this function is only for Non-Steam Games and only when they're being added to Steam + # # + # # In future, if we have a function to add SteamGridDB art for all Non-Steam Games, we could break this out and use it to set icons at that time too + # function getSteamGridDBNonSteamIcon { + # NOSTICONAID="$1" # Non-Steam AppID + # NOSTSGDBID="$2" # SteamGridDB Game ID + # NOSTICONNAME="${NOSTICONAID}_icon" + # SGDBSEARCHENDPOINT_ICONS="${BASESTEAMGRIDDBAPI}/icons/game" + + # # Download icon and put it in Steam grids folder, which should be a safe and intuitive location + # # We don't have any way to set search settings for icons and it would be confusing to have this in the Global Menu for now, so just leave blank + # # In future if we have Non-Steam Game global settings, we could include icon settings there too + # downloadArtFromSteamGridDB "$NOSTSGDBID" "$SGDBSEARCHENDPOINT_ICONS" "${NOSTICONNAME}" "" "" "" "" "" "" "replace" "1" + # } NOSTHIDE=0 # Set in localconfig.vdf along with tags and overlay settings NOSTADC=1 From 222ce82df66bab479fffb3a4a1059619e4e00c78 Mon Sep 17 00:00:00 2001 From: Eamonn Rea Date: Tue, 7 Nov 2023 00:14:38 +0000 Subject: [PATCH 10/15] Non-Steam: Initial attempt to update shortcuts.vdf icon when calling getGridsForNonSteamGames --- steamtinkerlaunch | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/steamtinkerlaunch b/steamtinkerlaunch index 129a5941..fea3440b 100755 --- a/steamtinkerlaunch +++ b/steamtinkerlaunch @@ -6,7 +6,7 @@ PREFIX="/usr" PROGNAME="SteamTinkerLaunch" NICEPROGNAME="Steam Tinker Launch" -PROGVERS="v14.0.20231107-1 (get-sgdb-for-all-nonsteam-aids)" +PROGVERS="v14.0.20231107-2 (get-sgdb-for-all-nonsteam-aids)" PROGCMD="${0##*/}" PROGINTERNALPROTNAME="Proton-stl" SHOSTL="stl" @@ -1672,9 +1672,12 @@ function getGridsForNonSteamGames { ## - getSteamGridDBNonSteamIcon was broken out from addNonSteamGame -- Ensure functionality still works there ## - write out icon to shortcuts.vdf entry with editSteamShortcutEntry (need to get path for icon) ## - strange files with SGDB AID are being generated in STL dir -- Investigate + ## Initial implementation below, untested for now commandlineGetSteamGridDBArtwork --search-name="$SVDFENAME" --filename-appid="$SVDFEAID" --nonsteam + CMDLINEGETSGDBARTAID="$( cat "$NOSTSGDBID" )" - getSteamGridDBNonSteamIcon "$SVDFEAID" "$CMDLINEGETSGDBARTAID" + SVDFEICON="$( getSteamGridDBNonSteamIcon "$SVDFEAID" "$CMDLINEGETSGDBARTAID" )" + editSteamShortcutEntry "$SVDFEAID" "icon" "$SVDFEICON" done <<< "$( getSteamShortcutHex )" fi } @@ -23563,6 +23566,7 @@ function getSteamGridDBNonSteamIcon { # We don't have any way to set search settings for icons and it would be confusing to have this in the Global Menu for now, so just leave blank # In future if we have Non-Steam Game global settings, we could include icon settings there too downloadArtFromSteamGridDB "$NOSTSGDBID" "$SGDBSEARCHENDPOINT_ICONS" "${NOSTICONNAME}" "" "" "" "" "" "" "replace" "1" + find "${STUIDPATH}/config/grid/" -name "${NOSTSGDBID}_icon.*" | head -n1 2>/dev/null # Return icon path } function addNonSteamGameGui { @@ -24093,8 +24097,9 @@ function addNonSteamGame { NOSTSGDBAPIGAMEID="$( cat "$NOSTSGDBID" )" # Icon -- Only set if we successfully download an icon from SteamGridDB - getSteamGridDBNonSteamIcon "$NOSTAIDGRID" "$NOSTSGDBAPIGAMEID" - NOSTSGDBICON="$( find "${STUIDPATH}/config/grid/" -name "${NOSTAIDGRID}_icon.*" | head -n1 2>/dev/null )" + ## TODO retest after getSteamGridDBNonSteamIcon was broken out, and also now that it returns icon path which it didn't before + NOSTSGDBICON="$( getSteamGridDBNonSteamIcon "$NOSTAIDGRID" "$NOSTSGDBAPIGAMEID" )" + # NOSTSGDBICON="$( find "${STUIDPATH}/config/grid/" -name "${NOSTAIDGRID}_icon.*" | head -n1 2>/dev/null )" if [ -f "$NOSTSGDBICON" ]; then writelog "INFO" "${FUNCNAME[0]} - Found SteamGridDB icon path to '$NOSTSGDBICON' -- Using this as Non-Steam Game Icon" NOSTICONPATH="$NOSTSGDBICON" From 8f1a9b17f9388cea11a7b0461f1a355fcc173029 Mon Sep 17 00:00:00 2001 From: Eamonn Rea Date: Tue, 7 Nov 2023 02:21:46 +0000 Subject: [PATCH 11/15] Non-Steam: Fix setting grids for Non-Steam Games --- steamtinkerlaunch | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/steamtinkerlaunch b/steamtinkerlaunch index fea3440b..847d05db 100755 --- a/steamtinkerlaunch +++ b/steamtinkerlaunch @@ -6,7 +6,7 @@ PREFIX="/usr" PROGNAME="SteamTinkerLaunch" NICEPROGNAME="Steam Tinker Launch" -PROGVERS="v14.0.20231107-2 (get-sgdb-for-all-nonsteam-aids)" +PROGVERS="v14.0.20231107-3 (get-sgdb-for-all-nonsteam-aids)" PROGCMD="${0##*/}" PROGINTERNALPROTNAME="Proton-stl" SHOSTL="stl" @@ -117,7 +117,7 @@ PROTONCSV="$STLSHM/ProtonCSV.txt" SWRF="$STLSHM/SWR.txt" UWRF="$STLSHM/UWR.txt" EWRF="$STLSHM/EWR.txt" -NOSTSGDBID="$STLSHM/NOSTSGDBID.txt" +NOSTSGDBIDSHMFILE="$STLSHM/NOSTSGDBID.txt" NON="none" NOPE="nope" TMPL="template" @@ -1632,7 +1632,7 @@ function commandlineGetSteamGridDBArtwork { downloadArtFromSteamGridDB "$GSGDBA_APPID" "$SGDBSEARCHENDPOINT_BOXART" "${GSGDBA_FILENAME}" "$SGDBTENFOOTSTYLES" "$SGDBTENFOOTDIMS" "$SGDBTENFOOTTYPES" "$SGDBTENFOOTNSFW" "$SGDBTENFOOTHUMOR" "$SGDBTENFOOTEPILEPSY" "$GSGDBA_HASFILE" "$GSGDBA_APPLYARTWORK" fi - echo "$GSGDBA_APPID" > "$NOSTSGDBID" # Store ID in case other functions need it (i.e. addNonSteamGame) -- Little hacky, would rather return this somehow... + echo "$GSGDBA_APPID" > "$NOSTSGDBIDSHMFILE" # Store ID in case other functions need it (i.e. addNonSteamGame) -- Little hacky, would rather return this somehow... } function getGridsForOwnedGames { @@ -1671,13 +1671,19 @@ function getGridsForNonSteamGames { ## TODO ## - getSteamGridDBNonSteamIcon was broken out from addNonSteamGame -- Ensure functionality still works there ## - write out icon to shortcuts.vdf entry with editSteamShortcutEntry (need to get path for icon) - ## - strange files with SGDB AID are being generated in STL dir -- Investigate ## Initial implementation below, untested for now commandlineGetSteamGridDBArtwork --search-name="$SVDFENAME" --filename-appid="$SVDFEAID" --nonsteam - CMDLINEGETSGDBARTAID="$( cat "$NOSTSGDBID" )" - SVDFEICON="$( getSteamGridDBNonSteamIcon "$SVDFEAID" "$CMDLINEGETSGDBARTAID" )" - editSteamShortcutEntry "$SVDFEAID" "icon" "$SVDFEICON" + # TODO make this a reusable function? + # --- + CMDLINEGETSGDBARTAID="$( cat "$NOSTSGDBIDSHMFILE" )" + getSteamGridDBNonSteamIcon "$SVDFEAID" "$CMDLINEGETSGDBARTAID" + SVDFEICON="$( find "${STUIDPATH}/config/grid/" -name "${SVDFEAID}_icon.*" | head -n1 2>/dev/null )" # Return icon path )" + # --- + if [ -n "$SVDFEICON" ]; then + writelog "INFO" "${FUNCNAME[0]} - Found icon for game '${SVDFENAME} (${SVDFEAID})' at '$SVDFEICON'" + editSteamShortcutEntry "$SVDFEAID" "icon" "$SVDFEICON" + fi done <<< "$( getSteamShortcutHex )" fi } @@ -23566,7 +23572,6 @@ function getSteamGridDBNonSteamIcon { # We don't have any way to set search settings for icons and it would be confusing to have this in the Global Menu for now, so just leave blank # In future if we have Non-Steam Game global settings, we could include icon settings there too downloadArtFromSteamGridDB "$NOSTSGDBID" "$SGDBSEARCHENDPOINT_ICONS" "${NOSTICONNAME}" "" "" "" "" "" "" "replace" "1" - find "${STUIDPATH}/config/grid/" -name "${NOSTSGDBID}_icon.*" | head -n1 2>/dev/null # Return icon path } function addNonSteamGameGui { @@ -24094,12 +24099,12 @@ function addNonSteamGame { commandlineGetSteamGridDBArtwork --search-name="$NOSTSEARCHNAME" --search-id="$NOSTSEARCHID" --filename-appid="$NOSTAIDGRID" "$NOSTSEARCHFLAG" --apply --replace-existing # Get ID that commandlineGetSteamGridDBArtwork searched on above and use that to search for the icon - NOSTSGDBAPIGAMEID="$( cat "$NOSTSGDBID" )" + NOSTSGDBAPIGAMEID="$( cat "$NOSTSGDBIDSHMFILE" )" # Icon -- Only set if we successfully download an icon from SteamGridDB - ## TODO retest after getSteamGridDBNonSteamIcon was broken out, and also now that it returns icon path which it didn't before - NOSTSGDBICON="$( getSteamGridDBNonSteamIcon "$NOSTAIDGRID" "$NOSTSGDBAPIGAMEID" )" - # NOSTSGDBICON="$( find "${STUIDPATH}/config/grid/" -name "${NOSTAIDGRID}_icon.*" | head -n1 2>/dev/null )" + ## TODO retest after getSteamGridDBNonSteamIcon was broken out + getSteamGridDBNonSteamIcon "$NOSTAIDGRID" "$NOSTSGDBAPIGAMEID" + NOSTSGDBICON="$( find "${STUIDPATH}/config/grid/" -name "${NOSTAIDGRID}_icon.*" | head -n1 2>/dev/null )" if [ -f "$NOSTSGDBICON" ]; then writelog "INFO" "${FUNCNAME[0]} - Found SteamGridDB icon path to '$NOSTSGDBICON' -- Using this as Non-Steam Game Icon" NOSTICONPATH="$NOSTSGDBICON" From d751730615625c4d22203ce45b146e5f738fce7b Mon Sep 17 00:00:00 2001 From: Eamonn Rea Date: Tue, 7 Nov 2023 20:29:56 +0000 Subject: [PATCH 12/15] Non-Steam: Use function to find Non-Steam Game Icon --- steamtinkerlaunch | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/steamtinkerlaunch b/steamtinkerlaunch index 847d05db..3b102544 100755 --- a/steamtinkerlaunch +++ b/steamtinkerlaunch @@ -6,7 +6,7 @@ PREFIX="/usr" PROGNAME="SteamTinkerLaunch" NICEPROGNAME="Steam Tinker Launch" -PROGVERS="v14.0.20231107-3 (get-sgdb-for-all-nonsteam-aids)" +PROGVERS="v14.0.20231108-1 (get-sgdb-for-all-nonsteam-aids)" PROGCMD="${0##*/}" PROGINTERNALPROTNAME="Proton-stl" SHOSTL="stl" @@ -1670,17 +1670,12 @@ function getGridsForNonSteamGames { ## TODO ## - getSteamGridDBNonSteamIcon was broken out from addNonSteamGame -- Ensure functionality still works there - ## - write out icon to shortcuts.vdf entry with editSteamShortcutEntry (need to get path for icon) - ## Initial implementation below, untested for now commandlineGetSteamGridDBArtwork --search-name="$SVDFENAME" --filename-appid="$SVDFEAID" --nonsteam - # TODO make this a reusable function? - # --- CMDLINEGETSGDBARTAID="$( cat "$NOSTSGDBIDSHMFILE" )" getSteamGridDBNonSteamIcon "$SVDFEAID" "$CMDLINEGETSGDBARTAID" - SVDFEICON="$( find "${STUIDPATH}/config/grid/" -name "${SVDFEAID}_icon.*" | head -n1 2>/dev/null )" # Return icon path )" - # --- - if [ -n "$SVDFEICON" ]; then + SVDFEICON="$( findNonSteamGameIcon )" # Return icon path )" + if [ -n "$SVDFEICON" ]; then # Need this check because sometimes we don't get anything back from SGDB i.e. unknown name writelog "INFO" "${FUNCNAME[0]} - Found icon for game '${SVDFENAME} (${SVDFEAID})' at '$SVDFEICON'" editSteamShortcutEntry "$SVDFEAID" "icon" "$SVDFEICON" fi @@ -23739,6 +23734,10 @@ function addNonSteamGameGui { esac } +function findNonSteamGameIcon { + find "${STUIDPATH}/config/grid/" -name "${NOSTAIDGRID}_icon.*" | head -n1 2>/dev/null +} + function addNonSteamGame { if [ -z "$SUSDA" ] || [ -z "$STUIDPATH" ]; then setSteamPaths @@ -24102,9 +24101,8 @@ function addNonSteamGame { NOSTSGDBAPIGAMEID="$( cat "$NOSTSGDBIDSHMFILE" )" # Icon -- Only set if we successfully download an icon from SteamGridDB - ## TODO retest after getSteamGridDBNonSteamIcon was broken out getSteamGridDBNonSteamIcon "$NOSTAIDGRID" "$NOSTSGDBAPIGAMEID" - NOSTSGDBICON="$( find "${STUIDPATH}/config/grid/" -name "${NOSTAIDGRID}_icon.*" | head -n1 2>/dev/null )" + NOSTSGDBICON="$( findNonSteamGameIcon )" if [ -f "$NOSTSGDBICON" ]; then writelog "INFO" "${FUNCNAME[0]} - Found SteamGridDB icon path to '$NOSTSGDBICON' -- Using this as Non-Steam Game Icon" NOSTICONPATH="$NOSTSGDBICON" From 7a406558d1f937bed2406a4882f025c01161b82b Mon Sep 17 00:00:00 2001 From: Eamonn Rea Date: Tue, 7 Nov 2023 20:38:01 +0000 Subject: [PATCH 13/15] Non-Steam: Shellcheck fixes --- steamtinkerlaunch | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/steamtinkerlaunch b/steamtinkerlaunch index 3b102544..1fc2bb5c 100755 --- a/steamtinkerlaunch +++ b/steamtinkerlaunch @@ -6,7 +6,7 @@ PREFIX="/usr" PROGNAME="SteamTinkerLaunch" NICEPROGNAME="Steam Tinker Launch" -PROGVERS="v14.0.20231108-1 (get-sgdb-for-all-nonsteam-aids)" +PROGVERS="v14.0.20231108-2 (get-sgdb-for-all-nonsteam-aids)" PROGCMD="${0##*/}" PROGINTERNALPROTNAME="Proton-stl" SHOSTL="stl" @@ -1668,8 +1668,9 @@ function getGridsForNonSteamGames { SVDFEAID="$( parseSteamShortcutEntryAppID "$SCVDFE" )" SVDFENAME="$( parseSteamShortcutEntryAppName "$SCVDFE" )" - ## TODO - ## - getSteamGridDBNonSteamIcon was broken out from addNonSteamGame -- Ensure functionality still works there + writelog "INFO" "${FUNCNAME[0]} - Updating artwork for game '$SVDFENAME ('$SVDFEAID')'" + echo "Updating artwork for game '$SVDFENAME ('$SVDFEAID')'" + commandlineGetSteamGridDBArtwork --search-name="$SVDFENAME" --filename-appid="$SVDFEAID" --nonsteam CMDLINEGETSGDBARTAID="$( cat "$NOSTSGDBIDSHMFILE" )" @@ -7967,7 +7968,7 @@ function convertSteamShortcutAppID { # Convert shortcuts.vdf hex to text with nullbyte stripped function convertSteamShortcutHex { - printf "$1" | xxd -r -p | tr -d '\0' + printf "%2" "$1" | xxd -r -p | tr -d '\0' } # Get the raw, unparsed hex for an entry from shortcuts.vdf @@ -7975,7 +7976,7 @@ function getSteamShortcutEntryHex { SHORTCUTSVDFINPUTHEX="$1" # The hex block representing the shortcut SHORTCUTSVDFMATCHPATTERN="$2" # The pattern to match against in the block - printf "$SHORTCUTSVDFINPUTHEX" | grep -oP "${SHORTCUTSVDFMATCHPATTERN}\K.*?(?=${SHORTCUTVDFENDPAT})" + printf "%s" "$SHORTCUTSVDFINPUTHEX" | grep -oP "${SHORTCUTSVDFMATCHPATTERN}\K.*?(?=${SHORTCUTVDFENDPAT})" } # Parse a hex shortcuts.vdf entry based on a start pattern and convert to text @@ -8008,7 +8009,7 @@ function replaceSteamShortcutEntryValue { SHORTCUTSVDFNEWVAL="$3" SHORTCUTSVDFOLDVAL="$( getSteamShortcutEntryHex "$SHORTCUTSVDFENTRY" "$SHORTCUTSVDFMATCHPATTERN" )" # Get the value without start and end bytes - SHORTCUTSVDFOLDCOL="$( printf "$SHORTCUTSVDFENTRY" | grep -oP "${SHORTCUTSVDFMATCHPATTERN}.*?${SHORTCUTVDFENDPAT}" )" # Get value with start and end bytes + SHORTCUTSVDFOLDCOL="$( printf "%s" "$SHORTCUTSVDFENTRY" | grep -oP "${SHORTCUTSVDFMATCHPATTERN}.*?${SHORTCUTVDFENDPAT}" )" # Get value with start and end bytes SHORTCUTSVDFNEWCOL="${SHORTCUTSVDFOLDCOL//"$SHORTCUTSVDFOLDVAL"/"$SHORTCUTSVDFNEWVAL"}" # Handle blank entries by simply hardcoding old entry and building new entry @@ -8019,7 +8020,7 @@ function replaceSteamShortcutEntryValue { SHORTCUTNEWENTRY="${SHORTCUTSVDFENTRY//"$SHORTCUTSVDFOLDCOL"/"$SHORTCUTSVDFNEWCOL"}" - printf "$SHORTCUTNEWENTRY" | tr -d '\0' + printf "%s" "$SHORTCUTNEWENTRY" | tr -d '\0' } ## Takes a shortcut appid, finds the shortcut entry, updates the given column value, replaces the hex for that section in the hex for the shortcuts.vdf file, writes out updated hex to new file @@ -8033,8 +8034,6 @@ function editSteamShortcutEntry { SHORTCUTSCONTENT="$( getSteamShortcutsVdfFileHex )" SHORTCUTSENTRY="$( findSteamShortcutByAppID "$SHORTCUTENTRYAID" )" - DEBUG_SCNAME="$( getSteamShortcutEntryHex "$SHORTCUTSENTRY" "$SHORTCUTVDFNAMEHEXPAT" )" - ## Find bytes that represent the column in shortcuts.vdf SHORTCUTEDITSTARTBYTES="" case $SHORTCUTCOLUMN in @@ -8081,7 +8080,7 @@ function getSteamShortcutsVdfFileHex { } function haveAnySteamShortcuts { - if [ $( getSteamShortcutHex | wc -c ) -gt 0 ]; then + if [ "$( getSteamShortcutHex | wc -c )" -gt 0 ]; then return 0 else return 1 @@ -8090,7 +8089,7 @@ function haveAnySteamShortcuts { # Grep and convert AppID from a given block of hex representing a shortcut entry in shortcuts.vdf by taking the first 8 bytes function parseSteamShortcutEntryAppID { - convertSteamShortcutAppID "$( printf "$1" | grep -oP "${SHORTCUTVDFAPPIDHEXPAT}\K.{8}" )" + convertSteamShortcutAppID "$( printf "%s" "$1" | grep -oP "${SHORTCUTVDFAPPIDHEXPAT}\K.{8}" )" } ### Functions to get information from specific parts of the shortcuts VDF ### From 7055ba394512df511800f52741c28f98057e9158 Mon Sep 17 00:00:00 2001 From: Eamonn Rea Date: Tue, 7 Nov 2023 20:41:14 +0000 Subject: [PATCH 14/15] minor --- steamtinkerlaunch | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/steamtinkerlaunch b/steamtinkerlaunch index 1fc2bb5c..0e8eb73c 100755 --- a/steamtinkerlaunch +++ b/steamtinkerlaunch @@ -6,7 +6,7 @@ PREFIX="/usr" PROGNAME="SteamTinkerLaunch" NICEPROGNAME="Steam Tinker Launch" -PROGVERS="v14.0.20231108-2 (get-sgdb-for-all-nonsteam-aids)" +PROGVERS="v14.0.20231108-3 (get-sgdb-for-all-nonsteam-aids)" PROGCMD="${0##*/}" PROGINTERNALPROTNAME="Proton-stl" SHOSTL="stl" @@ -7968,7 +7968,7 @@ function convertSteamShortcutAppID { # Convert shortcuts.vdf hex to text with nullbyte stripped function convertSteamShortcutHex { - printf "%2" "$1" | xxd -r -p | tr -d '\0' + printf "%s" "$1" | xxd -r -p | tr -d '\0' } # Get the raw, unparsed hex for an entry from shortcuts.vdf @@ -8059,6 +8059,8 @@ function editSteamShortcutEntry { return fi + writelog "INFO" "${FUNCNAME[0]} - Proceeding to edit '$SHORTCUTCOLUMN' field of shortcut '$SHORTCUTENTRYAID'" + # Replace original entry's value bytes with new bytes, then replace the old bytes in the entire shortcuts file with the new bytes and write it out SHORTCUTNEWENTRY="$( replaceSteamShortcutEntryValue "$SHORTCUTSENTRY" "$SHORTCUTEDITSTARTBYTES" "$SHORTCUTNEWVAL" )" SHORTCUTSCONTENT="${SHORTCUTSCONTENT//"$SHORTCUTSENTRY"/"$SHORTCUTNEWENTRY"}" @@ -22041,7 +22043,7 @@ function commandline { DEBUGNOSTAID="-222353304" - editSteamShortcutEntry "3917765712" "appname" "Updated Name" + editSteamShortcutEntry "3666773025" "appname" "New Name 2" return From bcc239336dc275760c26d4db2467e25be7c5f5d8 Mon Sep 17 00:00:00 2001 From: Eamonn Rea Date: Tue, 7 Nov 2023 20:55:00 +0000 Subject: [PATCH 15/15] version bump --- steamtinkerlaunch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/steamtinkerlaunch b/steamtinkerlaunch index 0e8eb73c..87e2e954 100755 --- a/steamtinkerlaunch +++ b/steamtinkerlaunch @@ -6,7 +6,7 @@ PREFIX="/usr" PROGNAME="SteamTinkerLaunch" NICEPROGNAME="Steam Tinker Launch" -PROGVERS="v14.0.20231108-3 (get-sgdb-for-all-nonsteam-aids)" +PROGVERS="v14.0.20231108-1" PROGCMD="${0##*/}" PROGINTERNALPROTNAME="Proton-stl" SHOSTL="stl"