From 1d9ab477db64a9f18c024c5e789c6a62ba8d9fc8 Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Sat, 11 Apr 2026 20:25:35 -0400 Subject: [PATCH] Super Liam updated. Install verified working. --- .../references/core-map.md | 12 +++-- .install/Super Liam.sh | 1 - .launch/Super Liam.game | 3 +- linux-game-manager.sh | 54 +++++++++++++------ 4 files changed, 46 insertions(+), 24 deletions(-) diff --git a/.codex/skills/linux-game-manager-dev/references/core-map.md b/.codex/skills/linux-game-manager-dev/references/core-map.md index 788ea97..d6a6a99 100644 --- a/.codex/skills/linux-game-manager-dev/references/core-map.md +++ b/.codex/skills/linux-game-manager-dev/references/core-map.md @@ -1,6 +1,6 @@ # Linux Game Manager Core Map -Last refreshed: 2026-03-03 +Last refreshed: 2026-04-11 ## Top-Level Structure @@ -14,9 +14,9 @@ Last refreshed: 2026-03-03 ## Catalog Snapshot -- Installers: 39 (`.install/*.sh`) -- Launcher definitions: 39 (`.launch/*.game`) -- Launcher runnable entries: 27 (`.launch/*.sh`, both symlinks and files) +- Installers: 40 (`.install/*.sh`) +- Launcher definitions: 40 (`.launch/*.game`) +- Launcher runnable entries: 28 (`.launch/*.sh`, both symlinks and files) - Update scripts: 5 (`.update/*.sh`) Regenerate this snapshot with: @@ -30,7 +30,8 @@ python3 .codex/skills/linux-game-manager-dev/scripts/audit_game_catalog.py 1. **Install flow** - `game_installer` builds menu from `.install/*.sh`. - Selected installer is sourced in the current shell. -- If `.launch/.game` exists and `.launch/.sh` does not, the manager creates a symlink. +- Shared downloads try `curl` first, fall back to `wget` when available, and reject obvious HTML error pages for unknown file types. +- If `.launch/.game` exists and `.launch/.sh` does not, the manager creates a symlink using the repository root, even if the installer changed directories. 2. **Launch flow** - `game_launcher` enumerates `.launch/*.sh` entries. @@ -74,5 +75,6 @@ python3 .codex/skills/linux-game-manager-dev/scripts/audit_game_catalog.py - `game_removal` parses the first `installPath` match in launcher text, so comments containing `installPath` can break removal path detection. - Missing `run_update()` in `.update` scripts breaks update flow. - Bypassing shared download helpers risks cache and validation regressions. +- Installers may change the working directory; repository-relative manager paths must therefore use the resolved script root rather than `${0%/*}`. - Use `alert` with its message arguments instead of chaining `alert` and `ui_msgbox`, otherwise `yad` users can get an extra acknowledgement dialog that does not include the actual guidance. - For `uv`-based Python games that need `speechd`, copy host Python `speechd` bindings into a game-local directory and export `PYTHONPATH` from the launcher. diff --git a/.install/Super Liam.sh b/.install/Super Liam.sh index a8e9d37..4f5aee2 100644 --- a/.install/Super Liam.sh +++ b/.install/Super Liam.sh @@ -1,5 +1,4 @@ # shellcheck shell=bash disable=SC2154 # installPath and cache are set by linux-game-manager.sh check_architecture x86_64 download "https://l-works.net/files/SuperLiam_linux.tar.gz" -cd "${installPath}" tar -xzf "$cache/SuperLiam_linux.tar.gz" -C "${installPath}" diff --git a/.launch/Super Liam.game b/.launch/Super Liam.game index 88b15e8..8a1923c 100644 --- a/.launch/Super Liam.game +++ b/.launch/Super Liam.game @@ -1,3 +1,4 @@ check_architecture x86_64 -pushd "${installPath}/Super Liam" +gamePath="${installPath}/Super Liam" +pushd "${gamePath}" ${fex}./SuperLiam diff --git a/linux-game-manager.sh b/linux-game-manager.sh index 02814c3..a6ff5a9 100755 --- a/linux-game-manager.sh +++ b/linux-game-manager.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash +scriptRoot="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)" + license() { cat << EOF â– The contents of this file are subject to the Common Public Attribution @@ -419,7 +421,7 @@ desktop_launcher() { break fi done - launchDirectory="$(readlink -e "${0%/*}")" + launchDirectory="${scriptRoot}" printf -v execLine "Exec=%s -t \"Linux Game Manager\" -e \"/usr/bin/bash -c 'pushd %q;nohup ./%q 2> /dev/null'\"" "${terminal}" "${launchDirectory}" "${0##*/}" dotDesktop=('[Desktop Entry]' 'Name=Linux game manager' @@ -483,8 +485,9 @@ download_with_fallback() { local firstExitCode=0 local secondExitCode=0 local thirdExitCode=0 + local wgetExitCode=0 local errorFile="" - downloadCurlExitCodes="" + downloadAttemptExitCodes="" downloadErrorLog="" if ! errorFile="$(mktemp)"; then @@ -513,7 +516,19 @@ download_with_fallback() { fi thirdExitCode=$? - downloadCurlExitCodes="${firstExitCode}, ${secondExitCode}, ${thirdExitCode}" + if command -v wget > /dev/null 2>&1; then + rm -f "${outputPath}" + if wget --tries=10 --output-document="${outputPath}" "${sourceUrl}" 2>> "${errorFile}"; then + rm -f "${errorFile}" + return 0 + fi + wgetExitCode=$? + fi + + downloadAttemptExitCodes="curl: ${firstExitCode}, ${secondExitCode}, ${thirdExitCode}" + if [[ "${wgetExitCode}" -ne 0 ]]; then + downloadAttemptExitCodes+="; wget: ${wgetExitCode}" + fi if cp -f "${errorFile}" "${cache}/curl-error.log" 2> /dev/null; then downloadErrorLog="${cache}/curl-error.log" rm -f "${errorFile}" @@ -538,10 +553,10 @@ download() { # Skip if the item is in cache. [[ -e "${cache}/${dest}" ]] && continue { if ! download_with_fallback "${cache}/${dest}" "${i}" ; then - ui_msgbox "Linux Game Manager" "Linux Game Manager" "Could not download \"$i\"...\n\ncurl exit codes: ${downloadCurlExitCodes}\nError details: ${downloadErrorLog}" + ui_msgbox "Linux Game Manager" "Linux Game Manager" "Could not download \"$i\"...\n\ndownload exit codes: ${downloadAttemptExitCodes}\nError details: ${downloadErrorLog}" exit 1 fi; } | ui_progressbox "Linux Game Manager" "Downloading \"$dest\" from \"$i\"" - local downloadError=1 + local downloadError=0 case "${dest##*.}" in "pk3"|"zip") unzip -tq "${cache}/${dest}" | ui_progressbox "Linux Game Manager" "Validating ${dest##*.} file" @@ -566,6 +581,8 @@ download() { # Add HTML check for other file types if file -b "${cache}/${dest}" | grep -q "HTML document" ; then downloadError=1 + else + downloadError=0 fi ;; esac @@ -594,7 +611,7 @@ download_named() { # Skip if the item is in cache. test -e "${cache}/${dest}" && return if ! download_with_fallback "${cache}/${dest}" "${2}" ; then - ui_msgbox "Linux Game Manager" "Linux Game Manager" "Could not download \"$dest\"...\n\ncurl exit codes: ${downloadCurlExitCodes}\nError details: ${downloadErrorLog}" + ui_msgbox "Linux Game Manager" "Linux Game Manager" "Could not download \"$dest\"...\n\ndownload exit codes: ${downloadAttemptExitCodes}\nError details: ${downloadErrorLog}" exit 1 fi } @@ -666,7 +683,7 @@ game_installer() { declare -a menuList # shellcheck disable=SC2154 # installedGames may be populated by sourced config or launch migration # Get all .sh files from .install directory, excluding those starting with #//, and sort them - mapfile -t sortedGames < <(for f in "${0%/*}/.install/"*.sh; do + mapfile -t sortedGames < <(for f in "${scriptRoot}/.install/"*.sh; do # Skip if first line starts with #// [[ $(head -n1 "$f") == "#//"* ]] && continue # Output filename without .sh extension @@ -705,7 +722,7 @@ game_installer() { exit 0 fi # Convert game name to filename format - local installScript="${0%/*}/.install/${game}.sh" + local installScript="${scriptRoot}/.install/${game}.sh" # Check if install script exists if [[ -f "$installScript" ]]; then # Source and execute the install script @@ -718,8 +735,8 @@ game_installer() { exit 1 fi fi - if [[ -e "${0%/*}/.launch/${game}.game" ]] && ! [[ -L "${0%/*}/.launch/${game}.sh" ]]; then - ln -srf "${0%/*}/.launch/${game}.game" "${0%/*}/.launch/${game}.sh" + if [[ -e "${scriptRoot}/.launch/${game}.game" ]] && ! [[ -L "${scriptRoot}/.launch/${game}.sh" ]]; then + ln -srf "${scriptRoot}/.launch/${game}.game" "${scriptRoot}/.launch/${game}.sh" fi exit 0 } @@ -730,7 +747,8 @@ game_removal() { # Initialize array for menu construction mapfile -t menuList < <( if [[ -d ".launch" ]]; then - find -L "${0%/*}/.launch" -maxdepth 1 -type f -iname "*.sh" -print0 | sort -z | xargs -0 bash -c ' + # shellcheck disable=SC2016 # variables expand in the child bash, not this single-quoted string + find -L "${scriptRoot}/.launch" -maxdepth 1 -type f -iname "*.sh" -print0 | sort -z | xargs -0 bash -c ' for f; do name="${f##*/}" echo "$f" @@ -756,7 +774,7 @@ game_removal() { local gameName="${selectedGame##*/}" gameName="${gameName%.sh}" local gameFile - gameFile="$(readlink -f "${0%/*}/.launch/${gameName}.sh")" + gameFile="$(readlink -f "${scriptRoot}/.launch/${gameName}.sh")" # Get the actual installation path from the .game file local gameInstallPath gameInstallPath="$(grep -F "installPath" "$gameFile" | grep -v 'pushd' | head -n1)" @@ -766,7 +784,7 @@ game_removal() { # No install path found, just remove from list ui_yesno "Linux Game Manager" "Linux Game Manager" "This will remove the game from your game list, but will not remove any files. Do you want to continue?" || exit 0 # Remove only the .sh symlink - rm -fv "${0%/*}/.launch/${gameName}.sh" | \ + rm -fv "${scriptRoot}/.launch/${gameName}.sh" | \ ui_progressbox "Linux Game Manager" "Removing game from list..." # Show success message ui_msgbox "Linux Game Manager" "Linux Game Manager" "${gameName} has been removed from the list." @@ -775,7 +793,7 @@ game_removal() { ui_yesno "Linux Game Manager" "Linux Game Manager" "This will remove the directory \"${gameInstallPath}\" and all of its contents. Do you want to continue?" || exit 0 # Remove the game directory and symlink { rm -rfv "${gameInstallPath}" - rm -fv "${0%/*}/.launch/${gameName}.sh"; + rm -fv "${scriptRoot}/.launch/${gameName}.sh"; } | ui_progressbox "Linux Game Manager" "Removing game..." # Show success message ui_msgbox "Linux Game Manager" "Linux Game Manager" "${gameName} has been removed." @@ -829,7 +847,8 @@ game_launcher() { # Initialize array for menu construction mapfile -t menuList < <( if [[ -d ".launch" ]]; then - find -L "${0%/*}/.launch" -maxdepth 1 -type f -iname "*.sh" -print0 | sort -z | xargs -0 bash -c ' + # shellcheck disable=SC2016 # variables expand in the child bash, not this single-quoted string + find -L "${scriptRoot}/.launch" -maxdepth 1 -type f -iname "*.sh" -print0 | sort -z | xargs -0 bash -c ' for f; do [[ $(head -n1 "$f") == "#//"* ]] && continue name="${f##*/}" @@ -869,8 +888,8 @@ migrate_launcher() { # Extract game name and path gameName="${line%|*}" # Create launcher script if it doesn't exist - if [[ ! -L "${0%/*}/.launch/${gameName}.sh" ]]; then - ln -srf "${0%/*}/.launch/${gameName}.game" "${0%/*}/.launch/${gameName}.sh" + if [[ ! -L "${scriptRoot}/.launch/${gameName}.sh" ]]; then + ln -srf "${scriptRoot}/.launch/${gameName}.game" "${scriptRoot}/.launch/${gameName}.sh" fi done < <(sed '/^$/d' "${configFile}") # Move the old config file and notify user @@ -906,6 +925,7 @@ mkdir -p "${configFile%/*}" declare -a installedGames=() # Load any arguments from settings.conf file if [[ -r "${configFile%/*}/settings.conf" ]]; then + # shellcheck disable=SC1091 # settings.conf is optional and resolved from the runtime config directory source "${configFile%/*}/settings.conf" fi unset noCache