From b0864223f00a53ba9018d3992a75092b6b2828d8 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Tue, 31 Dec 2024 17:27:12 +0500 Subject: [PATCH 1/5] removeNonSteamGame --- data_from_portwine/scripts/add_in_steam.sh | 63 +++++++++++++++++----- 1 file changed, 49 insertions(+), 14 deletions(-) diff --git a/data_from_portwine/scripts/add_in_steam.sh b/data_from_portwine/scripts/add_in_steam.sh index 717da97a..69f2a166 100755 --- a/data_from_portwine/scripts/add_in_steam.sh +++ b/data_from_portwine/scripts/add_in_steam.sh @@ -48,12 +48,14 @@ generateShortcutGridAppId() { ### END MAGIC APPID FUNCTIONS getSteamShortcutsVdfFileHex() { - STCFGPATH="$(getUserPath)" - if [[ -n "${STCFGPATH}" ]]; then + if [[ -z "${STCFGPATH}" ]]; then + STCFGPATH="$(getUserPath)" + fi + if [[ -n "${STCFGPATH}" ]] && [[ -z "${SCPATH}" ]]; then SCPATH="${STCFGPATH}/shortcuts.vdf" - if [[ -f "${SCPATH}" ]]; then - LC_ALL=C perl -0777 -ne 'print unpack("H*", $_)' "${SCPATH}" - fi + fi + if [[ -n "${SCPATH}" ]] && [[ -f "${SCPATH}" ]]; then + LC_ALL=C perl -0777 -ne 'print unpack("H*", $_)' "${SCPATH}" fi } @@ -301,21 +303,54 @@ addGrids() { fi } -addNonSteamGame() { - NOSTAPPNAME="${name_desktop}" - NOSTSHPATH="${STEAM_SCRIPTS}/${name_desktop}.sh" - NOSTEXEPATH="\"${NOSTSHPATH}\"" - NOSTICONPATH="${PORT_WINE_PATH}/data/img/${name_desktop_png}.png" - if [[ -z "${NOSTSTDIR}" ]]; then - NOSTSTDIR="\"${STEAM_SCRIPTS}\"" +removeNonSteamGame() { + if [[ -z "${STCFGPATH}" ]]; then + STCFGPATH="$(getUserPath)" fi - STCFGPATH="$(getUserPath)" - if [[ -n "${STCFGPATH}" ]]; then + if [[ -n "${STCFGPATH}" ]] && [[ -z "${SCPATH}" ]]; then + SCPATH="${STCFGPATH}/shortcuts.vdf" + fi + if [[ -n "${SCPATH}" ]] && [[ -f "${SCPATH}" ]]; then + cp "${SCPATH}" "${SCPATH//.vdf}_${PROGNAME}_backup.vdf" 2>/dev/null + fi + [[ -n "${1:-}" ]] && appid="$1" + if [[ -n "${appid}" ]]; then + NOSTAIDVDFHEX=$(bigToLittleEndian $(printf '%08x' "${appid}")) + LC_ALL=C perl -pe ' + $hex = pack("H*", shift); + $pos = index($_, $hex); + if ($pos != -1) { + $start_pos = rindex($_, "\x00", $pos - 1); + $end_pos = index($_, "ppid", $pos); + $end_pos = index($_, "\x08\x08", $pos) if $end_pos == -1; + if ($start_pos != -1 && $end_pos != -1) { + $end_pos += 4; + $_ = substr($_, 0, $start_pos) . substr($_, $end_pos); + } + } + ' "${SCPATH}" "${NOSTAIDVDFHEX}" > "${SCPATH}~" + mv "${SCPATH}~" "${SCPATH}" + rm -f "${STCFGPATH}/grid/${appid}.jpg" "${STCFGPATH}/grid/${appid}p.jpg" "${STCFGPATH}/grid/${appid}_hero.jpg" "${STCFGPATH}/grid/${appid}_logo.png" + fi +} + +addNonSteamGame() { + if [[ -z "${STCFGPATH}" ]]; then + STCFGPATH="$(getUserPath)" + fi + if [[ -n "${STCFGPATH}" ]] && [[ -z "${SCPATH}" ]]; then SCPATH="${STCFGPATH}/shortcuts.vdf" fi if [[ -n "${SCPATH}" ]]; then + NOSTAPPNAME="${name_desktop}" + NOSTSHPATH="${STEAM_SCRIPTS}/${name_desktop}.sh" NOSTAIDGRID=$(getAppId "${NOSTSHPATH}") if [[ -z "${NOSTAIDGRID}" ]]; then + NOSTEXEPATH="\"${NOSTSHPATH}\"" + if [[ -z "${NOSTSTDIR}" ]]; then + NOSTSTDIR="\"${STEAM_SCRIPTS}\"" + fi + NOSTICONPATH="${PORT_WINE_PATH}/data/img/${name_desktop_png}.png" NOSTAIDVDF="$(generateShortcutVDFAppId "${NOSTAPPNAME}${NOSTEXEPATH}")" # signed integer AppID, stored in the VDF as hexidecimal - ex: -598031679 NOSTAIDVDFHEX="$(generateShortcutVDFHexAppId "$NOSTAIDVDF")" # 4byte little-endian hexidecimal of above 32bit signed integer, which we write out to the binary VDF - ex: c1c25adc NOSTAIDVDFHEXFMT="\x$(awk '{$1=$1}1' FPAT='.{2}' OFS="\\\x" <<< "$NOSTAIDVDFHEX")" # binary-formatted string hex of the above which we actually write out - ex: \xc1\xc2\x5a\xdc From f5dd208f2ad7af167d135fb8de6418024034564a Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Tue, 31 Dec 2024 19:53:44 +0500 Subject: [PATCH 2/5] getUserId getUserIds getUserPath --- data_from_portwine/scripts/add_in_steam.sh | 57 ++++++++++++++++------ 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/data_from_portwine/scripts/add_in_steam.sh b/data_from_portwine/scripts/add_in_steam.sh index 69f2a166..35425235 100755 --- a/data_from_portwine/scripts/add_in_steam.sh +++ b/data_from_portwine/scripts/add_in_steam.sh @@ -41,7 +41,8 @@ generateShortcutVDFHexAppId() { } # Takes an signed 32bit integer and converts it to an unsigned 32bit integer -generateShortcutGridAppId() { +extractSteamId32() { +# STUID32=$((STUID64 - 76561197960265728)) echo $(($1 & 0xFFFFFFFF)) } ## ---------- @@ -134,29 +135,55 @@ getSteamGridDBId() { fi } -getUserPath() { +getUserIds() { + SLUF="${HOME}/.local/share/Steam/config/loginusers.vdf" + if [[ -f "${SLUF}" ]]; then + STUIDS=() + while read -r line; do + if [[ "${line}" =~ ^[[:space:]]*\"([0-9]+)\"$ ]]; then + STUID=$(extractSteamId32 "${BASH_REMATCH[1]}") + STUIDS+=("${STUID}") + fi + done < "${SLUF}" + if [[ ${#STUIDS[@]} -gt 0 ]]; then + echo "${STUIDS[@]}" + fi + fi +} + +getUserId() { SLUF="${HOME}/.local/share/Steam/config/loginusers.vdf" if [[ -f "${SLUF}" ]]; then SLUFUB=false - STUID64="" + STUID="" while read -r line; do if [[ "${line}" =~ ^[[:space:]]*\"([0-9]+)\"$ ]]; then STUIDCUR="${BASH_REMATCH[1]}" SLUFUB=true elif [[ "${line}" == *'"MostRecent"'*'"1"' && ${SLUFUB} = true ]]; then - STUID64="${STUIDCUR}" + STUID=$(extractSteamId32 "${STUIDCUR}") break elif [[ "${line}" == "}" ]]; then SLUFUB=false fi done < "${SLUF}" - if [ -n "${STUID64}" ]; then - STUID32=$((STUID64 - 76561197960265728)) - STUIDPATH="${HOME}/.local/share/Steam/userdata/${STUID32}" - if [[ -d "${STUIDPATH}" ]]; then - if [[ -f "${STUIDPATH}/config/shortcuts.vdf" ]]; then - echo "${STUIDPATH}/config" - fi + fi + if [ -n "${STUID}" ]; then + echo "${STUID}" + fi +} + +getUserPath() { + if [[ -n "${1:-}" ]]; then + STUID="$1" + else + STUID="$(getUserId)" + fi + if [ -n "${STUID}" ]; then + STUIDPATH="${HOME}/.local/share/Steam/userdata/${STUID}" + if [[ -d "${STUIDPATH}" ]]; then + if [[ -f "${STUIDPATH}/config/shortcuts.vdf" ]]; then + echo "${STUIDPATH}/config" fi fi fi @@ -304,17 +331,15 @@ addGrids() { } removeNonSteamGame() { + [[ -n "${1:-}" ]] && appid="$1" if [[ -z "${STCFGPATH}" ]]; then STCFGPATH="$(getUserPath)" fi if [[ -n "${STCFGPATH}" ]] && [[ -z "${SCPATH}" ]]; then SCPATH="${STCFGPATH}/shortcuts.vdf" fi - if [[ -n "${SCPATH}" ]] && [[ -f "${SCPATH}" ]]; then + if [[ -n "${appid}" ]] && [[ -n "${SCPATH}" ]] && [[ -f "${SCPATH}" ]]; then cp "${SCPATH}" "${SCPATH//.vdf}_${PROGNAME}_backup.vdf" 2>/dev/null - fi - [[ -n "${1:-}" ]] && appid="$1" - if [[ -n "${appid}" ]]; then NOSTAIDVDFHEX=$(bigToLittleEndian $(printf '%08x' "${appid}")) LC_ALL=C perl -pe ' $hex = pack("H*", shift); @@ -354,7 +379,7 @@ addNonSteamGame() { NOSTAIDVDF="$(generateShortcutVDFAppId "${NOSTAPPNAME}${NOSTEXEPATH}")" # signed integer AppID, stored in the VDF as hexidecimal - ex: -598031679 NOSTAIDVDFHEX="$(generateShortcutVDFHexAppId "$NOSTAIDVDF")" # 4byte little-endian hexidecimal of above 32bit signed integer, which we write out to the binary VDF - ex: c1c25adc NOSTAIDVDFHEXFMT="\x$(awk '{$1=$1}1' FPAT='.{2}' OFS="\\\x" <<< "$NOSTAIDVDFHEX")" # binary-formatted string hex of the above which we actually write out - ex: \xc1\xc2\x5a\xdc - NOSTAIDGRID="$(generateShortcutGridAppId "$NOSTAIDVDF")" # unsigned 32bit ingeger version of "$NOSTAIDVDF", which is used as the AppID for Steam artwork ("grids"), as well as for our shortcuts + NOSTAIDGRID="$(extractSteamId32 "$NOSTAIDVDF")" # unsigned 32bit ingeger version of "$NOSTAIDVDF", which is used as the AppID for Steam artwork ("grids"), as well as for our shortcuts create_new_dir "${STEAM_SCRIPTS}" echo "#!/usr/bin/env bash" > "${NOSTSHPATH}" From df86ec04167087270c5dde32e72f9c4254fb4f26 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Tue, 31 Dec 2024 20:55:49 +0500 Subject: [PATCH 3/5] getAppExe --- data_from_portwine/scripts/add_in_steam.sh | 35 +++++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/data_from_portwine/scripts/add_in_steam.sh b/data_from_portwine/scripts/add_in_steam.sh index 35425235..8c77b2cb 100755 --- a/data_from_portwine/scripts/add_in_steam.sh +++ b/data_from_portwine/scripts/add_in_steam.sh @@ -74,10 +74,14 @@ getSteamShortcutEntryHex() { printf "%s" "${SHORTCUTSVDFINPUTHEX}" | grep -oP "${SHORTCUTSVDFMATCHPATTERN}\K.*?(?=${SHORTCUTVDFENDPAT})" } +getAppExe() { + [[ -n "$1" ]] && listNonSteamGames | jq -r --arg id "$1" 'map(select(.id == $id)) | first(.[].exe)' +} + getAppTarget() { - exe=$(listNonSteamGames | jq -r --arg id "$1" 'map(select(.id == $id)) | first(.[].exe)') + exe=$(getAppExe "$1") if [[ -n "${exe}" ]]; then - if [[ "${exe}" =~ .sh$ ]] ; then + if [[ "${exe}" =~ .sh$ ]]; then parseSteamTargetExe "${exe}" else echo "${exe}"; @@ -90,7 +94,7 @@ getSteamGameId() { } getAppId() { - listNonSteamGames | jq -r --arg exe "$1" 'map(select(.exe == $exe)) | first(.[]?.id)' + [[ -n "$1" ]] && listNonSteamGames | jq -r --arg exe "$1" 'map(select(.exe == $exe)) | first(.[]?.id)' } getSteamId() { @@ -141,8 +145,7 @@ getUserIds() { STUIDS=() while read -r line; do if [[ "${line}" =~ ^[[:space:]]*\"([0-9]+)\"$ ]]; then - STUID=$(extractSteamId32 "${BASH_REMATCH[1]}") - STUIDS+=("${STUID}") + STUIDS+=("$(extractSteamId32 "${BASH_REMATCH[1]}")") fi done < "${SLUF}" if [[ ${#STUIDS[@]} -gt 0 ]]; then @@ -332,13 +335,14 @@ addGrids() { removeNonSteamGame() { [[ -n "${1:-}" ]] && appid="$1" - if [[ -z "${STCFGPATH}" ]]; then - STCFGPATH="$(getUserPath)" - fi + [[ -n "${2:-}" ]] && NOSTSHPATH="$2" + [[ -z "${STUID}" ]] && STUID=$(getUserId) + [[ -z "${STCFGPATH}" ]] && STCFGPATH="$(getUserPath ${STUID})" if [[ -n "${STCFGPATH}" ]] && [[ -z "${SCPATH}" ]]; then SCPATH="${STCFGPATH}/shortcuts.vdf" fi if [[ -n "${appid}" ]] && [[ -n "${SCPATH}" ]] && [[ -f "${SCPATH}" ]]; then + [[ -z "${NOSTSHPATH}" ]] && NOSTSHPATH=$(getAppExe ${appid}) cp "${SCPATH}" "${SCPATH//.vdf}_${PROGNAME}_backup.vdf" 2>/dev/null NOSTAIDVDFHEX=$(bigToLittleEndian $(printf '%08x' "${appid}")) LC_ALL=C perl -pe ' @@ -357,6 +361,21 @@ removeNonSteamGame() { mv "${SCPATH}~" "${SCPATH}" rm -f "${STCFGPATH}/grid/${appid}.jpg" "${STCFGPATH}/grid/${appid}p.jpg" "${STCFGPATH}/grid/${appid}_hero.jpg" "${STCFGPATH}/grid/${appid}_logo.png" fi + if [[ -n "${STUID}" ]] && [[ -n "${NOSTSHPATH}" ]] && [[ -f "${NOSTSHPATH}" ]]; then + isInstallGame=false + for STUIDCUR in $(getUserIds); do + [[ "${STUIDCUR}" == "${STUID}" ]] && continue + STCFGPATH="$(getUserPath ${STUIDCUR})" + SCPATH="${STCFGPATH}/shortcuts.vdf" + if [[ -n "$(getAppId "${NOSTSHPATH}")" ]]; then + isInstallGame=true + break + fi + done + if [[ ${isInstallGame} == false ]]; then + rm "${NOSTSHPATH}" + fi + fi } addNonSteamGame() { From 23be9fc637107b406c67cb1f33da98d84db84247 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Thu, 2 Jan 2025 03:09:24 +0500 Subject: [PATCH 4/5] addEntry --- data_from_portwine/scripts/add_in_steam.sh | 203 ++++++++++++--------- 1 file changed, 116 insertions(+), 87 deletions(-) diff --git a/data_from_portwine/scripts/add_in_steam.sh b/data_from_portwine/scripts/add_in_steam.sh index 8c77b2cb..54ae69b1 100755 --- a/data_from_portwine/scripts/add_in_steam.sh +++ b/data_from_portwine/scripts/add_in_steam.sh @@ -210,19 +210,22 @@ listInstalledSteamGames() { } listNonSteamGames() { - getSteamShortcutHex | while read -r SCVDFE; do - jq -n \ - --arg id "$(parseSteamShortcutEntryAppID "${SCVDFE}")" \ - --arg name "$(parseSteamShortcutEntryAppName "${SCVDFE}")" \ - --arg exe "$(parseSteamShortcutEntryExe "${SCVDFE}")" \ - '{id: $id, name: $name, exe: $exe}' - done | jq -s '.' + getSteamShortcutHex | while read -r SCVDFE; do + jq -n \ + --arg id "$(parseSteamShortcutEntryAppID "${SCVDFE}")" \ + --arg name "$(parseSteamShortcutEntryAppName "${SCVDFE}")" \ + --arg exe "$(parseSteamShortcutEntryExe "${SCVDFE}")" \ + --arg dir "$(parseSteamShortcutEntryStartDir "${SCVDFE}")" \ + --arg icon "$(parseSteamShortcutEntryIcon "${SCVDFE}")" \ + --arg args "$(parseSteamShortcutEntryLaunchOptions "${SCVDFE}")" \ + '{id: $id, name: $name, exe: $exe, dir: $dir, icon: $icon, args: $args}' + done | jq -s '.' } listSteamGames() { ( jq -r 'map({AppId: .id, SteamAppId: .id, SteamGameId: .id, Name: .name}) | .[] | tostring' <<< "$(listInstalledSteamGames)" - jq -r '.[] | tostring' <<< "$(listNonSteamGames)" | while read game; do + jq -r '.[] | tostring' <<< "$(listNonSteamGames)" | while read -r game; do id=$(jq -r '.id' <<< "${game}") name=$(jq -r '.name' <<< "${game}") jq -r \ @@ -240,19 +243,22 @@ convertSteamShortcutAppID() { } convertSteamShortcutHex() { - # printf "%s" "$1" | xxd -r -p | tr -d '\0' LC_ALL=C perl -le 'print pack "H*", $ARGV[0]' "$1" | tr -d '\0' } +convertStringToSteamShortcutHex() { + LC_ALL=C perl -e 'print unpack "H*", "$ARGV[0]" . "\x00"' "$(echo "$1" | tr -cd '[:alpha:]')" +} + parseSteamShortcutEntryHex() { SHORTCUTSVDFINPUTHEX="$1" # The hex block representing the shortcut SHORTCUTSVDFMATCHPATTERN="$2" # The pattern to match against in the block convertSteamShortcutHex "$(getSteamShortcutEntryHex "${SHORTCUTSVDFINPUTHEX}" "${SHORTCUTSVDFMATCHPATTERN}")" } -parseSteamShortcutEntryExe() { - SHORTCUTVDFEXEHEXPAT="000145786500" # 'Exe' ('exe' is 6578650a if we ever need it) - parseSteamShortcutEntryHex "$1" "${SHORTCUTVDFEXEHEXPAT}" | tr -d '"' +parseSteamShortcutEntryAppID() { + SHORTCUTVDFAPPIDHEXPAT="617070696400" # 'appid' + convertSteamShortcutAppID "$(printf "%s" "$1" | grep -oP "${SHORTCUTVDFAPPIDHEXPAT}\K.{8}")" } parseSteamShortcutEntryAppName() { @@ -260,9 +266,24 @@ parseSteamShortcutEntryAppName() { parseSteamShortcutEntryHex "$1" "${SHORTCUTVDFNAMEHEXPAT}" } -parseSteamShortcutEntryAppID() { - SHORTCUTVDFAPPIDHEXPAT="617070696400" # 'appid' - convertSteamShortcutAppID "$(printf "%s" "$1" | grep -oP "${SHORTCUTVDFAPPIDHEXPAT}\K.{8}")" +parseSteamShortcutEntryExe() { + SHORTCUTVDFEXEHEXPAT="000145786500" # 'Exe' ('exe' is 6578650a if we ever need it) + parseSteamShortcutEntryHex "$1" "${SHORTCUTVDFEXEHEXPAT}" | tr -d '"' +} + +parseSteamShortcutEntryStartDir() { + SHORTCUTVDFSTARTDIRHEXPAT="0001537461727444697200" + parseSteamShortcutEntryHex "$1" "${SHORTCUTVDFSTARTDIRHEXPAT}" | tr -d '"' +} + +parseSteamShortcutEntryIcon() { + SHORTCUTVDFICONHEXPAT="000169636f6e00" + parseSteamShortcutEntryHex "$1" "${SHORTCUTVDFICONHEXPAT}" +} + +parseSteamShortcutEntryLaunchOptions() { + SHORTCUTVDFARGHEXPAT="00014c61756e63684f7074696f6e7300" # echo "0001$(convertStringToSteamShortcutHex "LaunchOptions")" + parseSteamShortcutEntryHex "$1" "${SHORTCUTVDFARGHEXPAT}" | tr '\002' '\n' | head -n 1 | tr -d '\000' } parseSteamTargetExe() { @@ -333,47 +354,90 @@ addGrids() { fi } +addEntry() { + if [[ -n "${SCPATH}" ]]; then + if [[ -f "${SCPATH}" ]] ; then + truncate -s-2 "${SCPATH}" + OLDSET="$(grep -aPo '\x00[0-9]\x00\x02appid' "${SCPATH}" | tail -n1 | tr -dc '0-9')" + NEWSET=$((OLDSET + 1)) + else + printf '\x00%s\x00' "shortcuts" > "${SCPATH}" + NEWSET=0 + fi + NOSTAIDVDFHEXFMT="\x$(awk '{$1=$1}1' FPAT='.{2}' OFS="\\\x" <<< "$NOSTAIDVDFHEX")" # binary-formatted string hex of the above which we actually write out - ex: \xc1\xc2\x5a\xdc + + { + printf '\x00%s\x00' "${NEWSET}" + printf '\x02%s\x00%b' "appid" "${NOSTAIDVDFHEXFMT}" + printf '\x01%s\x00%s\x00' "AppName" "${NOSTAPPNAME}" + printf '\x01%s\x00%s\x00' "Exe" "\"${NOSTEXEPATH}\"" + printf '\x01%s\x00%s\x00' "StartDir" "\"${NOSTSTDIR}\"" + printf '\x01%s\x00%s\x00' "icon" "${NOSTICONPATH}" + printf '\x01%s\x00%s\x00' "ShortcutPath" "" + printf '\x01%s\x00%s\x00' "LaunchOptions" "${NOSTARGS:-}" + + printf '\x02%s\x00%b\x00\x00\x00' "IsHidden" "\x00" + printf '\x02%s\x00%b\x00\x00\x00' "AllowDesktopConfig" "\x00" + + # These values are now stored in localconfig.vdf under the "Apps" section, + # under a block using the Non-Steam Game Signed 32bit AppID. (i.e., -223056321) + # This is handled by `updateLocalConfigAppsValue` below + # + # Unsure if required, but still write these to the shortcuts.vdf file for consistency + printf '\x02%s\x00%b\x00\x00\x00' "AllowOverlay" "\x00" + printf '\x02%s\x00%b\x00\x00\x00' "OpenVR" "\x00" + + printf '\x02%s\x00\x00\x00\x00\x00' "Devkit" + printf '\x01%s\x00\x00' "DevkitGameID" + printf '\x02%s\x00\x00\x00\x00\x00' "DevkitOverrideAppID" + printf '\x02%s\x00\x00\x00\x00\x00' "LastPlayTime" + printf '\x01%s\x00\x00' "FlatpakAppID" + printf '\x00%s\x00' "tags" + printf '\x08\x08\x08\x08' + } >> "${SCPATH}" + fi +} + removeNonSteamGame() { - [[ -n "${1:-}" ]] && appid="$1" - [[ -n "${2:-}" ]] && NOSTSHPATH="$2" + [[ -n "$1" ]] && appid="$1" [[ -z "${STUID}" ]] && STUID=$(getUserId) [[ -z "${STCFGPATH}" ]] && STCFGPATH="$(getUserPath ${STUID})" if [[ -n "${STCFGPATH}" ]] && [[ -z "${SCPATH}" ]]; then SCPATH="${STCFGPATH}/shortcuts.vdf" fi - if [[ -n "${appid}" ]] && [[ -n "${SCPATH}" ]] && [[ -f "${SCPATH}" ]]; then - [[ -z "${NOSTSHPATH}" ]] && NOSTSHPATH=$(getAppExe ${appid}) - cp "${SCPATH}" "${SCPATH//.vdf}_${PROGNAME}_backup.vdf" 2>/dev/null - NOSTAIDVDFHEX=$(bigToLittleEndian $(printf '%08x' "${appid}")) - LC_ALL=C perl -pe ' - $hex = pack("H*", shift); - $pos = index($_, $hex); - if ($pos != -1) { - $start_pos = rindex($_, "\x00", $pos - 1); - $end_pos = index($_, "ppid", $pos); - $end_pos = index($_, "\x08\x08", $pos) if $end_pos == -1; - if ($start_pos != -1 && $end_pos != -1) { - $end_pos += 4; - $_ = substr($_, 0, $start_pos) . substr($_, $end_pos); - } - } - ' "${SCPATH}" "${NOSTAIDVDFHEX}" > "${SCPATH}~" - mv "${SCPATH}~" "${SCPATH}" - rm -f "${STCFGPATH}/grid/${appid}.jpg" "${STCFGPATH}/grid/${appid}p.jpg" "${STCFGPATH}/grid/${appid}_hero.jpg" "${STCFGPATH}/grid/${appid}_logo.png" - fi - if [[ -n "${STUID}" ]] && [[ -n "${NOSTSHPATH}" ]] && [[ -f "${NOSTSHPATH}" ]]; then - isInstallGame=false - for STUIDCUR in $(getUserIds); do - [[ "${STUIDCUR}" == "${STUID}" ]] && continue - STCFGPATH="$(getUserPath ${STUIDCUR})" - SCPATH="${STCFGPATH}/shortcuts.vdf" - if [[ -n "$(getAppId "${NOSTSHPATH}")" ]]; then - isInstallGame=true - break + if [[ -n "${appid}" ]]; then + games=$(listNonSteamGames) + NOSTSHPATH=$(jq -r --arg id "${appid}" 'map(select(.id == $id)) | first(.[].exe)' <<< "${games}") + if [[ -n "${NOSTSHPATH}" ]]; then + mv "${SCPATH}" "${SCPATH//.vdf}_${PROGNAME}_backup.vdf" 2>/dev/null + jq --arg id "${appid}" 'map(select(.id != $id))' <<< "${games}" | jq -c '.[]' | while read -r game; do + NOSTAIDGRID=$(jq -r '.id' <<< "${game}") + NOSTAPPNAME=$(jq -r '.name' <<< "${game}") + NOSTEXEPATH=$(jq -r '.exe' <<< "${game}") + NOSTSTDIR=$(jq -r '.dir' <<< "${game}") + NOSTICONPATH=$(jq -r '.icon' <<< "${game}") + NOSTARGS=$(jq -r '.args' <<< "${game}") + NOSTAIDVDFHEX=$(bigToLittleEndian $(printf '%08x' "${NOSTAIDGRID}")) + addEntry + done + rm -f "${STCFGPATH}/grid/${appid}.jpg" "${STCFGPATH}/grid/${appid}p.jpg" "${STCFGPATH}/grid/${appid}_hero.jpg" "${STCFGPATH}/grid/${appid}_logo.png" + if [[ -f "${NOSTSHPATH}" ]]; then + isInstallGame=false + for STUIDCUR in $(getUserIds); do + [[ "${STUIDCUR}" == "${STUID}" ]] && continue + STCFGPATH="$(getUserPath ${STUIDCUR})" + SCPATH="${STCFGPATH}/shortcuts.vdf" + if [[ -n "$(getAppId "${NOSTSHPATH}")" ]]; then + isInstallGame=true + break + fi + done + unset STCFGPATH SCPATH + if [[ ${isInstallGame} == false ]]; then + rm "${NOSTSHPATH}" + fi fi - done - if [[ ${isInstallGame} == false ]]; then - rm "${NOSTSHPATH}" + restartSteam fi fi } @@ -390,14 +454,13 @@ addNonSteamGame() { NOSTSHPATH="${STEAM_SCRIPTS}/${name_desktop}.sh" NOSTAIDGRID=$(getAppId "${NOSTSHPATH}") if [[ -z "${NOSTAIDGRID}" ]]; then - NOSTEXEPATH="\"${NOSTSHPATH}\"" + NOSTEXEPATH="${NOSTSHPATH}" if [[ -z "${NOSTSTDIR}" ]]; then - NOSTSTDIR="\"${STEAM_SCRIPTS}\"" + NOSTSTDIR="${STEAM_SCRIPTS}" fi NOSTICONPATH="${PORT_WINE_PATH}/data/img/${name_desktop_png}.png" NOSTAIDVDF="$(generateShortcutVDFAppId "${NOSTAPPNAME}${NOSTEXEPATH}")" # signed integer AppID, stored in the VDF as hexidecimal - ex: -598031679 NOSTAIDVDFHEX="$(generateShortcutVDFHexAppId "$NOSTAIDVDF")" # 4byte little-endian hexidecimal of above 32bit signed integer, which we write out to the binary VDF - ex: c1c25adc - NOSTAIDVDFHEXFMT="\x$(awk '{$1=$1}1' FPAT='.{2}' OFS="\\\x" <<< "$NOSTAIDVDFHEX")" # binary-formatted string hex of the above which we actually write out - ex: \xc1\xc2\x5a\xdc NOSTAIDGRID="$(extractSteamId32 "$NOSTAIDVDF")" # unsigned 32bit ingeger version of "$NOSTAIDVDF", which is used as the AppID for Steam artwork ("grids"), as well as for our shortcuts create_new_dir "${STEAM_SCRIPTS}" @@ -413,43 +476,9 @@ addNonSteamGame() { if [[ -f "${SCPATH}" ]] ; then cp "${SCPATH}" "${SCPATH//.vdf}_${PROGNAME}_backup.vdf" 2>/dev/null - truncate -s-2 "${SCPATH}" - OLDSET="$(grep -aPo '\x00[0-9]\x00\x02appid' "${SCPATH}" | tail -n1 | tr -dc '0-9')" - NEWSET=$((OLDSET + 1)) - else - printf '\x00%s\x00' "shortcuts" > "${SCPATH}" - NEWSET=0 fi - { - printf '\x00%s\x00' "${NEWSET}" - printf '\x02%s\x00%b' "appid" "${NOSTAIDVDFHEXFMT}" - printf '\x01%s\x00%s\x00' "AppName" "${NOSTAPPNAME}" - printf '\x01%s\x00%s\x00' "Exe" "${NOSTEXEPATH}" - printf '\x01%s\x00%s\x00' "StartDir" "${NOSTSTDIR}" - printf '\x01%s\x00%s\x00' "icon" "${NOSTICONPATH}" - printf '\x01%s\x00%s\x00' "ShortcutPath" "" - printf '\x01%s\x00%s\x00' "LaunchOptions" "" - - printf '\x02%s\x00%b\x00\x00\x00' "IsHidden" "\x00" - printf '\x02%s\x00%b\x00\x00\x00' "AllowDesktopConfig" "\x00" - - # These values are now stored in localconfig.vdf under the "Apps" section, - # under a block using the Non-Steam Game Signed 32bit AppID. (i.e., -223056321) - # This is handled by `updateLocalConfigAppsValue` below - # - # Unsure if required, but still write these to the shortcuts.vdf file for consistency - printf '\x02%s\x00%b\x00\x00\x00' "AllowOverlay" "\x00" - printf '\x02%s\x00%b\x00\x00\x00' "OpenVR" "\x00" - - printf '\x02%s\x00\x00\x00\x00\x00' "Devkit" - printf '\x01%s\x00\x00' "DevkitGameID" - printf '\x02%s\x00\x00\x00\x00\x00' "DevkitOverrideAppID" - printf '\x02%s\x00\x00\x00\x00\x00' "LastPlayTime" - printf '\x01%s\x00\x00' "FlatpakAppID" - printf '\x00%s\x00' "tags" - printf '\x08\x08\x08\x08' - } >> "${SCPATH}" + addEntry # TODO: замень использование steamgriddb на steam так как сайт steamgriddb у многих без VPN не работает # а пока просто блочим использование From 59d3ee4f4ec609067dd1b1b101d875ad79777238 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Tue, 7 Jan 2025 17:59:14 +0500 Subject: [PATCH 5/5] portwine_delete_shortcut --- data_from_portwine/scripts/add_in_steam.sh | 5 +- data_from_portwine/scripts/functions_helper | 56 ++++++++++++++------- 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/data_from_portwine/scripts/add_in_steam.sh b/data_from_portwine/scripts/add_in_steam.sh index 54ae69b1..de27bb9b 100755 --- a/data_from_portwine/scripts/add_in_steam.sh +++ b/data_from_portwine/scripts/add_in_steam.sh @@ -400,6 +400,7 @@ addEntry() { removeNonSteamGame() { [[ -n "$1" ]] && appid="$1" + [[ -n "$2" ]] && NOSTSHPATH="$2" [[ -z "${STUID}" ]] && STUID=$(getUserId) [[ -z "${STCFGPATH}" ]] && STCFGPATH="$(getUserPath ${STUID})" if [[ -n "${STCFGPATH}" ]] && [[ -z "${SCPATH}" ]]; then @@ -407,7 +408,7 @@ removeNonSteamGame() { fi if [[ -n "${appid}" ]]; then games=$(listNonSteamGames) - NOSTSHPATH=$(jq -r --arg id "${appid}" 'map(select(.id == $id)) | first(.[].exe)' <<< "${games}") + [[ -z "${NOSTSHPATH}" ]] && NOSTSHPATH=$(jq -r --arg id "${appid}" 'map(select(.id == $id)) | first(.[].exe)' <<< "${games}") if [[ -n "${NOSTSHPATH}" ]]; then mv "${SCPATH}" "${SCPATH//.vdf}_${PROGNAME}_backup.vdf" 2>/dev/null jq --arg id "${appid}" 'map(select(.id != $id))' <<< "${games}" | jq -c '.[]' | while read -r game; do @@ -450,8 +451,8 @@ addNonSteamGame() { SCPATH="${STCFGPATH}/shortcuts.vdf" fi if [[ -n "${SCPATH}" ]]; then + [[ -z "${NOSTSHPATH}" ]] && NOSTSHPATH="${STEAM_SCRIPTS}/${name_desktop}.sh" NOSTAPPNAME="${name_desktop}" - NOSTSHPATH="${STEAM_SCRIPTS}/${name_desktop}.sh" NOSTAIDGRID=$(getAppId "${NOSTSHPATH}") if [[ -z "${NOSTAIDGRID}" ]]; then NOSTEXEPATH="${NOSTSHPATH}" diff --git a/data_from_portwine/scripts/functions_helper b/data_from_portwine/scripts/functions_helper index f7d31fcd..3eb57ea9 100755 --- a/data_from_portwine/scripts/functions_helper +++ b/data_from_portwine/scripts/functions_helper @@ -6308,7 +6308,18 @@ portwine_change_shortcut () { then PW_SHORTCUT_DESKTOP="TRUE" else PW_SHORTCUT_DESKTOP="FALSE" fi - PW_SHORTCUT_STEAM="FALSE" + if [[ -n $PW_DELETE_STEAM ]]; then + source "${PORT_SCRIPTS_PATH}/add_in_steam.sh" + NOSTSHPATH="${PW_DELETE_SHORTCUT_STEAM[0]//#@_@#/ }" + NOSTAIDGRID=$(getAppId "${NOSTSHPATH}") + if [[ -n "${NOSTSHPATH}" ]] && [[ -n "${NOSTAIDGRID}" ]]; then + PW_SHORTCUT_STEAM="TRUE" + else + PW_SHORTCUT_STEAM="FALSE" + fi + else + PW_SHORTCUT_STEAM="FALSE" + fi unset name_desktop create_name_desktop @@ -6334,6 +6345,7 @@ portwine_change_shortcut () { PORTWINE_CHANGE_SHORTCUT=1 if [[ $PW_YAD_OUT == 1 ]] ; then [[ "$PW_GUI_START" == "NOTEBOOK" ]] && unset PW_YAD_FORM_TAB + PW_SHORTCUT_STEAM="FALSE" portwine_delete_shortcut restart_pp fi @@ -6341,24 +6353,29 @@ portwine_change_shortcut () { } portwine_search_shortcut () { - unset PW_DELETE_SHORTCUT_MENU PW_DELETE_SHORTCUT_DESKTOP - PW_DELETE_MENU="$(grep -il "${portwine_exe}" "${HOME}/.local/share/applications"/*.desktop 2>/dev/null)" - read -r -d '' -a PW_DELETE_SHORTCUT_MENU <<< "${PW_DELETE_SHORTCUT_MENU[*]} ${PW_DELETE_MENU// /#@_@#}" + unset PW_DELETE_SHORTCUT_MENU PW_DELETE_SHORTCUT_STEAM PW_DELETE_SHORTCUT_DESKTOP + if [[ -n "${portwine_exe}" ]]; then + PW_DELETE_MENU="$(grep -il "${portwine_exe}" "${HOME}/.local/share/applications"/*.desktop 2>/dev/null)" + read -r -d '' -a PW_DELETE_SHORTCUT_MENU <<< "${PW_DELETE_SHORTCUT_MENU[*]} ${PW_DELETE_MENU// /#@_@#}" - PW_DELETE_PP="$(grep -il "${portwine_exe}" "${PORT_WINE_PATH}"/*.desktop 2>/dev/null)" - read -r -d '' -a PW_DELETE_SHORTCUT_MENU <<< "${PW_DELETE_SHORTCUT_MENU[*]} ${PW_DELETE_PP// /#@_@#}" + PW_DELETE_PP="$(grep -il "${portwine_exe}" "${PORT_WINE_PATH}"/*.desktop 2>/dev/null)" + read -r -d '' -a PW_DELETE_SHORTCUT_MENU <<< "${PW_DELETE_SHORTCUT_MENU[*]} ${PW_DELETE_PP// /#@_@#}" - if [[ -d "${HOME}/Desktop" ]] ; then - PW_DELETE_DESKTOP="$(grep -il "${portwine_exe}" "${HOME}/Desktop"/*.desktop 2>/dev/null)" - read -r -d '' -a PW_DELETE_SHORTCUT_DESKTOP <<< "${PW_DELETE_SHORTCUT_DESKTOP[*]} ${PW_DELETE_DESKTOP// /#@_@#}" - fi - if [[ -d "${HOME}/Рабочий стол" ]] ; then - PW_DELETE_DESKTOP="$(grep -il "${portwine_exe}" "${HOME}/Рабочий стол"/*.desktop 2>/dev/null)" - read -r -d '' -a PW_DELETE_SHORTCUT_DESKTOP <<< "${PW_DELETE_SHORTCUT_DESKTOP[*]} ${PW_DELETE_DESKTOP// /#@_@#}" - fi - if [[ $(xdg-user-dir DESKTOP) ]] ; then - PW_DELETE_DESKTOP="$(grep -il "${portwine_exe}" "$(xdg-user-dir DESKTOP)"/*.desktop 2>/dev/null)" - read -r -d '' -a PW_DELETE_SHORTCUT_DESKTOP <<< "${PW_DELETE_SHORTCUT_DESKTOP[*]} ${PW_DELETE_DESKTOP// /#@_@#}" + PW_DELETE_STEAM="$(grep -il "${portwine_exe}" "${STEAM_SCRIPTS}"/*.sh 2>/dev/null)" + read -r -d '' -a PW_DELETE_SHORTCUT_STEAM <<< "${PW_DELETE_SHORTCUT_STEAM[*]} ${PW_DELETE_STEAM// /#@_@#}" + + if [[ -d "${HOME}/Desktop" ]] ; then + PW_DELETE_DESKTOP="$(grep -il "${portwine_exe}" "${HOME}/Desktop"/*.desktop 2>/dev/null)" + read -r -d '' -a PW_DELETE_SHORTCUT_DESKTOP <<< "${PW_DELETE_SHORTCUT_DESKTOP[*]} ${PW_DELETE_DESKTOP// /#@_@#}" + fi + if [[ -d "${HOME}/Рабочий стол" ]] ; then + PW_DELETE_DESKTOP="$(grep -il "${portwine_exe}" "${HOME}/Рабочий стол"/*.desktop 2>/dev/null)" + read -r -d '' -a PW_DELETE_SHORTCUT_DESKTOP <<< "${PW_DELETE_SHORTCUT_DESKTOP[*]} ${PW_DELETE_DESKTOP// /#@_@#}" + fi + if [[ $(xdg-user-dir DESKTOP) ]] ; then + PW_DELETE_DESKTOP="$(grep -il "${portwine_exe}" "$(xdg-user-dir DESKTOP)"/*.desktop 2>/dev/null)" + read -r -d '' -a PW_DELETE_SHORTCUT_DESKTOP <<< "${PW_DELETE_SHORTCUT_DESKTOP[*]} ${PW_DELETE_DESKTOP// /#@_@#}" + fi fi } @@ -6371,6 +6388,11 @@ portwine_delete_shortcut () { for delete_shortcut in "${PW_DELETE_SHORTCUT_MENU[@]}" "${PW_DELETE_SHORTCUT_DESKTOP[@]}" ; do rm -f "${delete_shortcut//#@_@#/ }" done + + if [[ "${PW_SHORTCUT_STEAM}" == "FALSE" ]] && [[ -n "${NOSTSHPATH}" ]] && [[ -n "${NOSTAIDGRID}" ]]; then + source "${PORT_SCRIPTS_PATH}/add_in_steam.sh" + removeNonSteamGame "${NOSTAIDGRID}" "${NOSTSHPATH}" + fi } portwine_missing_shortcut () {