From 497562f39766f403e6c25fcdd085253300c30907 Mon Sep 17 00:00:00 2001 From: Roy <88516395+moraroy@users.noreply.github.com> Date: Thu, 25 Apr 2024 03:33:02 -0700 Subject: [PATCH] Added Itchio Games to the NSLGame Scanner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ~ Itchio Game Shortcuts are now added automatically🎮 ~ added a check for users that are unable to download dependencies, the script will now exit immediately and log the error --- NSLGameScanner.py | 77 ++++++++++++++++++++++++++++++++++++++++++++ NonSteamLaunchers.sh | 12 ++++--- 2 files changed, 85 insertions(+), 4 deletions(-) diff --git a/NSLGameScanner.py b/NSLGameScanner.py index 4ddcadd..bacf624 100644 --- a/NSLGameScanner.py +++ b/NSLGameScanner.py @@ -4,6 +4,7 @@ import json import shutil import binascii import ctypes +import gzip import zipfile import time import sys @@ -59,6 +60,8 @@ ea_app_launcher = os.environ.get('ea_app_launcher', '') gog_galaxy_launcher = os.environ.get('gog_galaxy_launcher', '') bnet_launcher = os.environ.get('bnet_launcher', '') amazon_launcher = os.environ.get('amazon_launcher', '') +itchio_launcher = os.environ.get('itchio_launcher', '') + #Variables of the Launchers @@ -957,6 +960,80 @@ if amazon_games: +#Itchio Scanner +def get_itch_games(itch_db_location): + print(f"Checking if {itch_db_location} exists...") + if not os.path.exists(itch_db_location): + print(f"Path not found: {itch_db_location}. Continuing with the rest of the code...") + return [] + + print("Opening and reading the database file...") + with open(itch_db_location, 'rb') as f: + shortcut_bytes = f.read() + + print("Parsing the database file...") + paths = parse_butler_db(shortcut_bytes) + + print("Converting paths to games...") + games = [dbpath_to_game(path) for path in paths if dbpath_to_game(path) is not None] + # Remove duplicates + games = list(set(games)) + print(f"Found {len(games)} unique games.") + return games + +def parse_butler_db(content): + print("Finding matches in the database content...") + pattern = rb'\{"basePath":"(.*?)","totalSize".*?"candidates":\[(.*?)\]\}' + matches = re.findall(pattern, content) + print(f"Found {len(matches)} matches.") + + print("Converting matches to database paths...") + db_paths = [] + for match in matches: + base_path = match[0].decode(errors='ignore') + candidates_json = b'[' + match[1] + b']' + candidates = json.loads(candidates_json.decode(errors='ignore')) + paths = [candidate['path'] for candidate in candidates] + db_paths.append((base_path, paths)) + print(f"Converted {len(matches)} matches to {len(db_paths)} database paths.") + return db_paths + +def dbpath_to_game(paths): + # Convert the Windows-style path from the database to a Unix-style path + db_path = paths[0].replace("\\\\", "/").replace("C:", "") + linux_path = "/home/deck/.local/share/Steam/steamapps/compatdata/NonSteamLaunchers/pfx/drive_c" + db_path + receipt_path = os.path.join(linux_path, ".itch", "receipt.json.gz") + if not os.path.exists(receipt_path): + return None + + for executable in paths[1]: + exe_path = os.path.join(linux_path, executable) + if os.access(exe_path, os.X_OK): # check if file is executable + with gzip.open(receipt_path, 'rb') as f: + receipt_str = f.read().decode() + receipt = json.loads(receipt_str) + return (linux_path, executable, receipt['game']['title']) +# Usage: +itch_db_location = f"{logged_in_home}/.local/share/Steam/steamapps/compatdata/{itchio_launcher}/pfx/drive_c/users/steamuser/AppData/Roaming/itch/db/butler.db-wal" +print(f"Getting games from {itch_db_location}...") +games = get_itch_games(itch_db_location) +print("Printing games...") +for game in games: + print(game) + +for game in games: + linux_path, executable, game_title = game + exe_path = f"\"{os.path.join(linux_path, executable)}\"" + start_dir = f"\"{linux_path}\"" + launchoptions = f"STEAM_COMPAT_DATA_PATH=\"{logged_in_home}/.local/share/Steam/steamapps/compatdata/{itchio_launcher}/\" %command%" + create_new_entry(exe_path, game_title, launchoptions, start_dir) + + + +#End of Itchio Scanner + + + # Only write back to the shortcuts.vdf and config.vdf files if new shortcuts were added or compattools changed if new_shortcuts_added or shortcuts_updated: diff --git a/NonSteamLaunchers.sh b/NonSteamLaunchers.sh index 4055917..33cbb67 100755 --- a/NonSteamLaunchers.sh +++ b/NonSteamLaunchers.sh @@ -29,7 +29,7 @@ download_dir="${logged_in_home}/Downloads/NonSteamLaunchersInstallation" exec >> "${logged_in_home}/Downloads/NonSteamLaunchers-install.log" 2>&1 # Version number (major.minor) -version=v3.8.1 +version=v3.8.5 # TODO: tighten logic to check whether major/minor version is up-to-date via `-eq`, `-lt`, or `-gt` operators # Check repo releases via GitHub API then display current stable version @@ -105,17 +105,17 @@ if [ "${deckyplugin}" = false ]; then if [ "${folders_exist}" = false ]; then # Download the repository as a zip file zip_file_path="${parent_folder}/repo.zip" - wget -O "${zip_file_path}" "${repo_url}" + wget -O "${zip_file_path}" "${repo_url}" || { echo 'Download failed with error code: $?'; exit 1; } # Extract the zip file - unzip -d "${parent_folder}" "${zip_file_path}" + unzip -d "${parent_folder}" "${zip_file_path}" || { echo 'Unzip failed with error code: $?'; exit 1; } # Move the folders to the parent directory and delete the unnecessary files for folder in "${folders_to_clone[@]}"; do destination_path="${parent_folder}/${folder}" source_path="${parent_folder}/NonSteamLaunchers-On-Steam-Deck-main/Modules/${folder}" if [ ! -d "${destination_path}" ]; then - mv "${source_path}" "${destination_path}" + mv "${source_path}" "${destination_path}" || { echo 'Move failed with error code: $?'; exit 1; } fi done @@ -2367,6 +2367,8 @@ if [[ -f "$itchio_path1" ]]; then echo "export itchioshortcutdirectory=$itchioshortcutdirectory" >> ${logged_in_home}/.config/systemd/user/env_vars echo "export itchiolaunchoptions=$itchiolaunchoptions" >> ${logged_in_home}/.config/systemd/user/env_vars echo "export itchiostartingdir=$itchiostartingdir" >> ${logged_in_home}/.config/systemd/user/env_vars + echo "export itchio_launcher=NonSteamLaunchers" >> ${logged_in_home}/.config/systemd/user/env_vars + echo "itchio Launcher found at path 1" elif [[ -f "$itchio_path2" ]]; then # itchio Launcher is installed at path 2 itchioshortcutdirectory="\"$itchio_path2\"" @@ -2375,6 +2377,8 @@ elif [[ -f "$itchio_path2" ]]; then echo "export itchioshortcutdirectory=$itchioshortcutdirectory" >> ${logged_in_home}/.config/systemd/user/env_vars echo "export itchiolaunchoptions=$itchiolaunchoptions" >> ${logged_in_home}/.config/systemd/user/env_vars echo "export itchiostartingdir=$itchiostartingdir" >> ${logged_in_home}/.config/systemd/user/env_vars + echo "export itchio_launcher=itchioLauncher" >> ${logged_in_home}/.config/systemd/user/env_vars + echo "itchio Launcher found at path 2" fi if [[ -f "$legacygames_path1" ]]; then