Super Liam updated. Install verified working.

This commit is contained in:
Storm Dragon
2026-04-11 20:25:35 -04:00
parent d0240d1408
commit 1d9ab477db
4 changed files with 46 additions and 24 deletions

View File

@@ -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>.game` exists and `.launch/<game>.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>.game` exists and `.launch/<game>.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.

View File

@@ -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}"

View File

@@ -1,3 +1,4 @@
check_architecture x86_64
pushd "${installPath}/Super Liam"
gamePath="${installPath}/Super Liam"
pushd "${gamePath}"
${fex}./SuperLiam

View File

@@ -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