diff --git a/patch.py b/patch.py index 972d4f9..d80d595 100644 --- a/patch.py +++ b/patch.py @@ -1,13 +1,49 @@ import sys import getpass import os +import re import tempfile +from pathlib import Path + +GAME_RELATIVE = Path('steamapps/common/Trials Rising/datapack/trialsrising.exe') + + +def steam_library_candidates(user): + """Yield candidate paths to trialsrising.exe across every Steam library. + + Rather than guessing at device names or mount points (for example, assuming the microSD card + is always at /run/media/mmcblk0p1), read Steam's own libraryfolders.vdf, which lists every + installed library no matter where it lives (internal drive, SD card, external drive, ...). + """ + home = Path('/home') / user + steam_roots = [ + home / '.local/share/Steam', # standard Linux / SteamOS + home / '.steam/steam', # older / symlinked installs + home / '.var/app/com.valvesoftware.Steam/.local/share/Steam', # Flatpak Steam + home / 'snap/steam/common/.local/share/Steam', # Snap Steam + ] + for root in steam_roots: + # The library that lives directly under the Steam root (usually the default one). + yield root / GAME_RELATIVE + try: + text = (root / 'steamapps' / 'libraryfolders.vdf').read_text(encoding='utf-8', errors='replace') + except OSError: + continue + # Each library root is stored as: "path" "/run/media/mmcblk0p1" + for library in re.findall(r'"path"\s+"([^"]+)"', text): + yield Path(library) / GAME_RELATIVE + # Check if user specified a path if len(sys.argv) > 1: path = sys.argv[1] else: - path = '/home/' + getpass.getuser() + '/.local/share/Steam/steamapps/common/Trials Rising/datapack/trialsrising.exe' + user = getpass.getuser() + path = next( + (str(candidate) for candidate in steam_library_candidates(user) if candidate.is_file()), + # Last-resort default, so the "file not found" hint still names a real location. + '/home/' + user + '/.local/share/Steam/' + str(GAME_RELATIVE), + ) # Some explanation: these bytes first serve as hex representations of the program instructions we want to change # But if that was all they needed to be, they could each be 3 hex characters long: