From 8af6a27a0d0fced43e80cc17815a5c12d4fad055 Mon Sep 17 00:00:00 2001 From: Jeremy Lorelli Date: Sun, 5 May 2024 18:39:52 -0700 Subject: [PATCH 1/3] chore: Restructure to allow some reuse of Python code --- {dev => scripts}/compile-map.py | 6 +++++- {dev => scripts}/dev_setup.ps1 | 0 {dev => scripts}/get_hammer_content.ps1 | 0 {dev => scripts}/get_latest_js_types.ps1 | 0 {dev => scripts}/graph-map-results.py | 0 scripts/steampath.py | 18 ++++++++++++++++++ .../utils/steamtools.py | 15 --------------- 7 files changed, 23 insertions(+), 16 deletions(-) rename {dev => scripts}/compile-map.py (98%) rename {dev => scripts}/dev_setup.ps1 (100%) rename {dev => scripts}/get_hammer_content.ps1 (100%) rename {dev => scripts}/get_latest_js_types.ps1 (100%) rename {dev => scripts}/graph-map-results.py (100%) create mode 100644 scripts/steampath.py rename util/steampath.py => scripts/utils/steamtools.py (76%) diff --git a/dev/compile-map.py b/scripts/compile-map.py similarity index 98% rename from dev/compile-map.py rename to scripts/compile-map.py index 4013dd2..03bbb39 100755 --- a/dev/compile-map.py +++ b/scripts/compile-map.py @@ -9,7 +9,11 @@ import json import string import sys -import tomllib +try: + import tomllib +except Exception as e: + print('Python 3.11 or later is required to run this script!') + raise e """ Summary of available subs: diff --git a/dev/dev_setup.ps1 b/scripts/dev_setup.ps1 similarity index 100% rename from dev/dev_setup.ps1 rename to scripts/dev_setup.ps1 diff --git a/dev/get_hammer_content.ps1 b/scripts/get_hammer_content.ps1 similarity index 100% rename from dev/get_hammer_content.ps1 rename to scripts/get_hammer_content.ps1 diff --git a/dev/get_latest_js_types.ps1 b/scripts/get_latest_js_types.ps1 similarity index 100% rename from dev/get_latest_js_types.ps1 rename to scripts/get_latest_js_types.ps1 diff --git a/dev/graph-map-results.py b/scripts/graph-map-results.py similarity index 100% rename from dev/graph-map-results.py rename to scripts/graph-map-results.py diff --git a/scripts/steampath.py b/scripts/steampath.py new file mode 100644 index 0000000..63f4c79 --- /dev/null +++ b/scripts/steampath.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 + +import argparse +from utils.steamtools import get_appid_path + +def main(): + parser = argparse.ArgumentParser(description='Finds the installation directory of a Steam app') + parser.add_argument('-a', '--app', dest='APP', type=int, required=True, help='AppID to look for') + args = parser.parse_args() + p = get_appid_path(args.APP) + if p is not None: + print(p) + else: + exit(1) + + +if __name__ == '__main__': + main() diff --git a/util/steampath.py b/scripts/utils/steamtools.py similarity index 76% rename from util/steampath.py rename to scripts/utils/steamtools.py index 0931e26..fadba48 100755 --- a/util/steampath.py +++ b/scripts/utils/steamtools.py @@ -39,18 +39,3 @@ def get_appid_path(id: int) -> str | None: am = vdf.parse(fp)['AppState'] return f'{lf}/steamapps/common/{am["installdir"]}' return None - - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument('-a', '--app', dest='APP', type=int, required=True, help='AppID to look for') - args = parser.parse_args() - p = get_appid_path(args.APP) - if p is not None: - print(p) - else: - exit(1) - - -if __name__ == '__main__': - main() From 158ed1ad1a59dda1e7a57c2fbdc00b014c978fd3 Mon Sep 17 00:00:00 2001 From: Jeremy Lorelli Date: Sun, 5 May 2024 19:36:07 -0700 Subject: [PATCH 2/3] feat: Make steampath.py work without any external python packages Also makes this tool work on Windows --- scripts/compile-map.py | 7 ++-- scripts/steampath.py | 0 scripts/utils/steamtools.py | 72 +++++++++++++++++++++++++++---------- 3 files changed, 57 insertions(+), 22 deletions(-) mode change 100644 => 100755 scripts/steampath.py diff --git a/scripts/compile-map.py b/scripts/compile-map.py index 03bbb39..d65f719 100755 --- a/scripts/compile-map.py +++ b/scripts/compile-map.py @@ -9,11 +9,10 @@ import json import string import sys -try: +if sys.version_info >= (3,11): import tomllib -except Exception as e: - print('Python 3.11 or later is required to run this script!') - raise e +else: + raise Exception('Python 3.11 or later is required to run this script!') """ Summary of available subs: diff --git a/scripts/steampath.py b/scripts/steampath.py old mode 100644 new mode 100755 diff --git a/scripts/utils/steamtools.py b/scripts/utils/steamtools.py index fadba48..08ee0ab 100755 --- a/scripts/utils/steamtools.py +++ b/scripts/utils/steamtools.py @@ -1,20 +1,55 @@ -#!/usr/bin/env python3 - -import vdf -import argparse import os +import sys +import re +if sys.platform.startswith('win'): + import winreg + + +def get_library_folders() -> list[str]: + """ + Returns a list of Steam libraries on this system + + Returns + ------- + list[str] + List of paths for the Steam libraries + """ + sp = '' + if sys.platform.startswith('linux'): + # Flatpak steam will also create the ~/.steam symlink + sp = os.path.expanduser(f'~/.steam/steam/steamapps/libraryfolders.vdf') + elif sys.platform.startswith('win'): + # Registry trash for Windows. + with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, 'Software\\Wow6432Node\\Valve\\Steam', access=winreg.KEY_READ | winreg.KEY_WOW64_32KEY) as key: + value = winreg.QueryValueEx(key, 'InstallPath') + if value is not None and value[1] == winreg.REG_SZ: + sp = f'{value[0]}\\steamapps\\libraryfolders.vdf' + else: + sp = f'C:\\Program Files (x86)\\Steam\\steamapps\\libraryfolders.vdf' + # Check that the file *actually* exists; Steam in Proton doesn't use registry... + if not os.path.exists(sp): + sp = f'Z:{os.getenv("STEAM_COMPAT_CLIENT_INSTALL_PATH")}\\steam\\steamapps\\libraryfolders.vdf'.replace('/', '\\') + + with open(sp, 'r') as fp: + return [x[1] for x in re.findall(r'\n\s+(\"path\")\s+\"(.+)\"\s*\n', fp.read())] + + +def get_library_for_appid(id: int) -> str | None: + """ + Returns the steam library path that contains the app + + Returns + ------- + str|None + Steam library that contains the appid + """ + folders = get_library_folders() + if folders is None: + return None -def _find_appid_folder(id: int) -> str | None: - lf = {} - # Flatpak steam will also create the ~/.steam symlink - with open(os.path.expanduser(f'~/.steam/steam/steamapps/libraryfolders.vdf'), 'r') as fp: - lf = vdf.parse(fp)['libraryfolders'] - - lfp = None - for k in lf.keys(): - for m in lf[k]['apps'].keys(): - if int(m) == id: - return lf[k]['path'] + for folder in folders: + if os.path.exists(f'{folder}/steamapps/appmanifest_{id}.acf'): + return folder return None @@ -32,10 +67,11 @@ def get_appid_path(id: int) -> str | None: str|None Install path location or None if it could not be found """ - lf = _find_appid_folder(id) + lf = get_library_for_appid(id) if lf is not None: am = {} with open(f'{lf}/steamapps/appmanifest_{id}.acf', 'r') as fp: - am = vdf.parse(fp)['AppState'] - return f'{lf}/steamapps/common/{am["installdir"]}' + m = re.findall(r'\n\s+(\"installdir\")\s+\"(.+)\"\s*\n', fp.read()) + if len(m) > 0: + return f'{lf}/steamapps/common/{m[0][1]}' return None From bdce86834a1142e52b1910fb94786efa0c51c1d2 Mon Sep 17 00:00:00 2001 From: Jeremy Lorelli Date: Sun, 5 May 2024 21:20:09 -0700 Subject: [PATCH 3/3] chore: Ignore stuff --- .gitignore | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index e915029..98b5ac1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,2 @@ -################################################################################ -# This .gitignore file was automatically created by Microsoft(R) Visual Studio. -################################################################################ - -/.vs +.vs +__pycache__