mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-11 01:37:02 +01:00
Grouped by the state each function touches rather than by size:
steam_requirements.sh 199 requirement parsing, scoring, and the hardware
detection that feeds it
steam_report.sh 156 the run loop and the cache it reads
steam_api.sh 124 library discovery, Steam and ProtonDB calls
steam_credentials.sh 103 credentials, usage text, presentation helpers
The grouping was forced by the SC2034 writer/reader rule, not chosen. Two
arrangements were discarded: detect_system alone in a lib writes the three
SYSTEM_* globals without reading them, and load_cache_map alone writes
CACHE_MAP without reading it. Both were fixed by putting the writer next to
its reader - detect_system beside score_game, load_cache_map beside main.
Verified: all 33 functions verbatim; every lib passes shellcheck standalone
with no suppression; and the script actually runs - `--help` prints the usage
block and exits 0, which is what proves the four source lines resolve and
main still dispatches.
Over-cap files 26 -> 25.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
125 lines
4.6 KiB
Bash
Executable File
125 lines
4.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Steam library discovery, the Steam and ProtonDB API calls, and requirement
|
|
# extraction for steam_compatibility.sh.
|
|
|
|
find_steamapps_dirs() {
|
|
local dirs=()
|
|
for base in "${STEAM_DIRS[@]}"; do
|
|
[[ -d $base ]] || continue
|
|
if [[ -f "$base/steamapps/libraryfolders.vdf" ]]; then
|
|
# Newer format includes nested objects with paths
|
|
local paths
|
|
paths=$(grep -oE '"path"\s+"[^"]+"' "$base/steamapps/libraryfolders.vdf" | sed -E 's/.*"([^"]+)"/\1/' || true)
|
|
if [[ -n $paths ]]; then
|
|
while IFS= read -r p; do
|
|
[[ -d "$p/steamapps" ]] && dirs+=("$p/steamapps")
|
|
done <<< "$paths"
|
|
fi
|
|
fi
|
|
[[ -d "$base/steamapps" ]] && dirs+=("$base/steamapps")
|
|
done
|
|
# de-dupe
|
|
printf "%s\n" "${dirs[@]}" 2> /dev/null | awk '!seen[$0]++'
|
|
}
|
|
|
|
list_installed_games() {
|
|
local d appid name
|
|
while IFS= read -r d; do
|
|
[[ -d $d ]] || continue
|
|
for mf in "$d"/appmanifest_*.acf; do
|
|
[[ -f $mf ]] || continue
|
|
appid=$(grep -oE '"appid"\s+"[0-9]+"' "$mf" | sed -E 's/.*"([0-9]+)"/\1/' | head -n1)
|
|
name=$(grep -oE '"name"\s+"[^"]+"' "$mf" | sed -E 's/.*"([^"]+)"/\1/' | head -n1)
|
|
if [[ -n $appid ]]; then
|
|
printf "%s\t%s\n" "$appid" "${name:-Unknown}"
|
|
fi
|
|
done
|
|
done < <(find_steamapps_dirs)
|
|
}
|
|
|
|
list_owned_games_via_api() {
|
|
local key="${STEAM_API_KEY:-}" sid="${STEAM_ID64:-}"
|
|
if [[ -z $key || -z $sid ]]; then
|
|
return 1
|
|
fi
|
|
local url="https://api.steampowered.com/IPlayerService/GetOwnedGames/v0001/?key=${key}&steamid=${sid}&include_appinfo=1&include_played_free_games=1&format=json"
|
|
http_get "$url" | jq -r '.response.games[]? | "\(.appid)\t\(.name)"' || return 1
|
|
}
|
|
|
|
fetch_appdetails_json() {
|
|
local appid="$1"
|
|
# Using store API (no key)
|
|
local url="https://store.steampowered.com/api/appdetails?appids=${appid}&l=en&cc=us"
|
|
http_get "$url" || true
|
|
}
|
|
|
|
extract_requirements_and_platforms() {
|
|
# Input: JSON from appdetails; Output: TSV of fields
|
|
# Fields: success, linux, windows, mac, min_text, rec_text, type
|
|
local appid="$1" json="$2"
|
|
# Some apps return {"APPID": {"success":true, "data":{...}}}
|
|
local out
|
|
out=$(jq -r --arg APP "$appid" '
|
|
.[$APP] as $root | if ($root.success==true and ($root.data|type)=="object") then
|
|
($root.data.platforms.linux // false) as $linux |
|
|
($root.data.platforms.windows // false) as $windows |
|
|
($root.data.platforms.mac // false) as $mac |
|
|
($root.data.type // "") as $type |
|
|
# Prefer Linux reqs when present
|
|
($root.data.linux_requirements.minimum // $root.data.pc_requirements.minimum // "") as $min |
|
|
($root.data.linux_requirements.recommended // $root.data.pc_requirements.recommended // "") as $rec |
|
|
["ok", ($linux|tostring), ($windows|tostring), ($mac|tostring), ($min|tostring), ($rec|tostring), ($type|tostring)] | @tsv
|
|
else
|
|
["fail", "false", "false", "false", "", "", ""] | @tsv
|
|
end' 2> /dev/null <<< "$json") || true
|
|
if [[ -z $out ]]; then
|
|
out=$'fail false false false '
|
|
fi
|
|
printf '%s\n' "$out"
|
|
}
|
|
|
|
# Read JSON from stdin (avoids storing large/binary data in variables)
|
|
extract_requirements_and_platforms_stdin() {
|
|
local appid="$1"
|
|
local out
|
|
out=$(jq -r --arg APP "$appid" '
|
|
.[$APP] as $root | if ($root.success==true and ($root.data|type)=="object") then
|
|
($root.data.platforms.linux // false) as $linux |
|
|
($root.data.platforms.windows // false) as $windows |
|
|
($root.data.platforms.mac // false) as $mac |
|
|
($root.data.type // "") as $type |
|
|
($root.data.linux_requirements.minimum // $root.data.pc_requirements.minimum // "") as $min |
|
|
($root.data.linux_requirements.recommended // $root.data.pc_requirements.recommended // "") as $rec |
|
|
["ok", ($linux|tostring), ($windows|tostring), ($mac|tostring), ($min|tostring), ($rec|tostring), ($type|tostring)] | @tsv
|
|
else
|
|
["fail", "false", "false", "false", "", "", ""] | @tsv
|
|
end' 2> /dev/null) || true
|
|
if [[ -z $out ]]; then
|
|
out=$'fail\tfalse\tfalse\tfalse\t\t\t'
|
|
fi
|
|
printf '%s\n' "$out"
|
|
}
|
|
|
|
fetch_protondb_tier() {
|
|
local appid="$1"
|
|
local url="https://www.protondb.com/api/v1/reports/summaries/${appid}.json"
|
|
# Returns minimal JSON including .tier, .confidence; we only need .tier
|
|
local tier
|
|
tier=$(http_get "$url" | jq -r 'try .tier // "unknown"' 2> /dev/null || true)
|
|
if [[ -z $tier || $tier == "null" ]]; then
|
|
echo "unknown"
|
|
else
|
|
tr '[:upper:]' '[:lower:]' <<< "$tier" | tr -d '\r\n'
|
|
fi
|
|
}
|
|
|
|
protondb_allowed() {
|
|
local tier
|
|
tier=$(tr '[:upper:]' '[:lower:]' <<< "${1:-}")
|
|
case "$tier" in
|
|
platinum | native | gold | silver | unknown | "") return 0 ;;
|
|
bronze | pending | borked | unsupported | broken) return 1 ;;
|
|
*) return 0 ;;
|
|
esac
|
|
}
|