Files
cosmoteer-pressure-relief-r…/tools/steam_paths.py
T
TotenKnopfandClaude Fable 5 07f3c89480 fix: search ~/.steam/root and Flatpak data/Steam roots
Layouts from PR #1 (Manjaro report), folded into tools/steam_paths.py.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014TkQMhvEyoFqKzeCC69N6o
2026-08-29 19:27:02 +02:00

122 lines
4.0 KiB
Python
Executable File

#!/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/root",
".steam/debian-installation",
".var/app/com.valvesoftware.Steam/.local/share/Steam",
".var/app/com.valvesoftware.Steam/data/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))