#!/usr/bin/env python3 # ABOUT ME # Finds the installed Cosmoteer game data and the user Mods folder, wherever # Steam put them. Shared by install.sh and tests/test_mod.py. # # Why it exists: Steam lives in different places (native, Flatpak, Snap, # Debian package, Windows) and a game can sit in any library listed in # steamapps/libraryfolders.vdf, often on another disk. Hard-coded globs miss # those; this reads Steam's own library list instead. # # Environment overrides always win: COSMOTEER_DATA for the Data folder, # COSMOTEER_MODS_DIR for the Mods folder. # # Usage: python3 tools/steam_paths.py --data print the Data folder # python3 tools/steam_paths.py --mods print the Mods folder # Exit 1 with the roots tried on stderr when nothing is found. import glob import os import re import sys APP_ID = "799600" PROTON_PROFILE = "compatdata/" + APP_ID + "/pfx/drive_c/users/steamuser/Saved Games/Cosmoteer" # Steam roots relative to HOME, in the order they are tried. STEAM_ROOTS_UNDER_HOME = [ ".local/share/Steam", ".steam/steam", ".steam/debian-installation", ".var/app/com.valvesoftware.Steam/.local/share/Steam", ".snap/steam/common/.local/share/Steam", "snap/steam/common/.local/share/Steam", ] _VDF_PATH = re.compile(r'"path"\s+"([^"]+)"') def steam_roots(env=None): """Candidate Steam install roots for this environment (existing or not).""" env = os.environ if env is None else env home = env.get("HOME") roots = [os.path.join(home, rel) for rel in STEAM_ROOTS_UNDER_HOME] if home else [] program_files = env.get("PROGRAMFILES(X86)") or env.get("ProgramFiles(x86)") if program_files: roots.append(os.path.join(program_files, "Steam")) return roots def libraries(env=None): """Every Steam library folder: each root plus what its libraryfolders.vdf lists.""" seen = [] for root in steam_roots(env): for candidate in [root] + _vdf_libraries(root): candidate = os.path.realpath(candidate) if candidate not in seen and os.path.isdir(os.path.join(candidate, "steamapps")): seen.append(candidate) return seen def _vdf_libraries(root): vdf = os.path.join(root, "steamapps", "libraryfolders.vdf") if not os.path.isfile(vdf): return [] with open(vdf, encoding="utf-8", errors="replace") as f: return [p.replace("\\\\", "\\") for p in _VDF_PATH.findall(f.read())] def find_data_dir(env=None): env = os.environ if env is None else env override = env.get("COSMOTEER_DATA") if override: return override for library in libraries(env): data = os.path.join(library, "steamapps", "common", "Cosmoteer", "Data") if os.path.isdir(data): return data return None def find_mods_dir(env=None): env = os.environ if env is None else env override = env.get("COSMOTEER_MODS_DIR") if override: return override patterns = [ os.path.join(library, "steamapps", PROTON_PROFILE, "*", "Mods") for library in libraries(env) ] profile = env.get("USERPROFILE") if profile: patterns.append(os.path.join(profile, "Saved Games", "Cosmoteer", "*", "Mods")) for pattern in patterns: for match in sorted(glob.glob(pattern)): if os.path.isdir(match): return match return None def main(argv): if argv[1:] == ["--data"]: found = find_data_dir() what = "Cosmoteer Data folder" elif argv[1:] == ["--mods"]: found = find_mods_dir() what = "Cosmoteer Mods folder" else: print(__doc__ or "usage: steam_paths.py --data | --mods", file=sys.stderr) return 2 if found: print(found) return 0 print(f"Could not find the {what}. Steam roots tried:", file=sys.stderr) for root in steam_roots(): print(f" {root}", file=sys.stderr) return 1 if __name__ == "__main__": sys.exit(main(sys.argv))