From 647e97a1054dbd18053f1da1c837563cc602684d Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Mon, 2 Mar 2026 22:56:05 -0500 Subject: [PATCH] Added game The Omega Reach Update the alert function to show the actual guidance in a single acknowledgement dialog instead of a generic OK prompt followed by a separate message. --- .../references/core-map.md | 9 ++-- .install/Slay the Spire.sh | 46 +++++++++-------- .install/Stardew Valley.sh | 7 ++- .install/The Omega Reach.sh | 7 +++ .install/The Tornado Chicken.sh | 4 +- .install/Upheaval Gui.sh | 4 +- .install/Wheels of Prio.sh | 4 +- .launch/The Omega Reach.game | 4 ++ linux-game-manager.sh | 49 +++++++++++++++---- 9 files changed, 86 insertions(+), 48 deletions(-) create mode 100644 .install/The Omega Reach.sh create mode 100644 .launch/The Omega Reach.game 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 26cab52..788ea97 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-02-21 +Last refreshed: 2026-03-03 ## Top-Level Structure @@ -14,9 +14,9 @@ Last refreshed: 2026-02-21 ## Catalog Snapshot -- Installers: 38 (`.install/*.sh`) -- Launcher definitions: 38 (`.launch/*.game`) -- Launcher runnable entries: 26 (`.launch/*.sh`, both symlinks and files) +- Installers: 39 (`.install/*.sh`) +- Launcher definitions: 39 (`.launch/*.game`) +- Launcher runnable entries: 27 (`.launch/*.sh`, both symlinks and files) - Update scripts: 5 (`.update/*.sh`) Regenerate this snapshot with: @@ -74,4 +74,5 @@ 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. +- 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/Slay the Spire.sh b/.install/Slay the Spire.sh index 7adc970..647775e 100644 --- a/.install/Slay the Spire.sh +++ b/.install/Slay the Spire.sh @@ -1,29 +1,22 @@ +# shellcheck shell=bash disable=SC2154 # installPath and cache are set by linux-game-manager.sh check_architecture x86_64 -alert -ui_msgbox "Game Installer" "Game Installer" "Please note this requires the game to be available either in your Steam library or as the installer purchased from gog.com.\n\nIf using the gog.com installer, please use the default path when prompted." +alert "Game Installer" "Game Installer" "Please note this requires the game to be available either in your Steam library or as the installer purchased from gog.com.\n\nIf using the gog.com installer, please use the default path when prompted." installMethod=$(ui_menu "Installation Method" "Installation Method" "Select installation method" "gog" "GOG" "steam" "Steam") -if [[ "$installMethod" == "steam" ]]; then - installationMethod=1 -else - installationMethod=0 -fi appId="646570" gogFileName="slay_the_spire_2020_12_15_8735c9fe3cc2280b76aa3ec47c953352a7df1f65_43444.sh" -if [[ $installMethod -eq 1 ]]; then +if [[ "$installMethod" == "steam" ]]; then # Steam Installation check_dependencies steamcmd steamUser=$(ui_inputbox "Game Installer" "Game Installer" "Please enter Steam user name:" "") - steamcmd +@sSteamCmdForcePlatformType linux +force_install_dir "${HOME}/.local/games/SlayTheSpire" +login "$steamUser" +app_update "$appId" +quit - if [[ $? -ne 0 ]]; then + if ! steamcmd +@sSteamCmdForcePlatformType linux +force_install_dir "${HOME}/.local/games/SlayTheSpire" +login "$steamUser" +app_update "$appId" +quit; then ui_msgbox "Game Installer" "Game Installer" "Error installing game through Steam." exit 1 fi else # GOG Installation get_installer "$gogFileName" "https://www.gog.com/en/game/slay_the_spire" - DISPLAY="" find ~/Downloads -maxdepth 1 -type f -name "$gogFileName" -exec bash "{}" \; || - DISPLAY="" find ~/Desktop -maxdepth 1 -type f -name "$gogFileName" -exec bash "{}" \; - if [[ $? -eq 0 ]]; then + if DISPLAY="" find ~/Downloads -maxdepth 1 -type f -name "$gogFileName" -exec bash "{}" \; || + DISPLAY="" find ~/Desktop -maxdepth 1 -type f -name "$gogFileName" -exec bash "{}" \;; then ln -sf "${HOME}/GOG Games/Slay the Spire/game" "${installPath}/SlayTheSpire" || { ui_msgbox "Game Installer" "Game Installer" "Error creating link to game directory." exit 1; } @@ -50,24 +43,29 @@ declare -A modsMap=( [achievement enabler]=1692554109 [say the spire]=2239220106 ) -installString="" -for modId in ${modsMap[@]} ; do - installString="$installString +workshop_download_item $appId $modId" +declare -a installArgs=() +for modId in "${modsMap[@]}" ; do + installArgs+=("+workshop_download_item" "$appId" "$modId") done -steamcmd +@sSteamCmdForcePlatformType linux +force_install_dir "${HOME}/.local/games/SlayTheSpire/" +login anonymous $installString +quit -if [[ $? -ne 0 ]]; then +if ! steamcmd +@sSteamCmdForcePlatformType linux +force_install_dir "${HOME}/.local/games/SlayTheSpire/" +login anonymous "${installArgs[@]}" +quit; then ui_msgbox "Game Installer" "Game Installer" "Error installing required mods. Some accessibility features may not be available." exit 1 fi mkdir -p "$HOME/.local/games/SlayTheSpire/mods" for modName in "${!modsMap[@]}" ; do if [[ "$modName" == "mod the spire" ]]; then - ln -sr "$HOME/.local/games/SlayTheSpire/steamapps/workshop/content/$appId/${modsMap[$modName]}"/* "$HOME/.local/games/SlayTheSpire/" + if ! ln -sr "$HOME/.local/games/SlayTheSpire/steamapps/workshop/content/$appId/${modsMap[$modName]}"/* "$HOME/.local/games/SlayTheSpire/"; then + if [[ "$modName" == "say the spire" ]]; then + ui_msgbox "Game Installer" "Game Installer" "Error installing SayTheSpire mod. Screen reader support will not be available." + exit 1 + fi + fi else - ln -sr "$HOME/.local/games/SlayTheSpire/steamapps/workshop/content/$appId/${modsMap[$modName]}"/* "$HOME/.local/games/SlayTheSpire/mods/" - fi - if [[ $? -ne 0 ]] && [[ "$modName" == "say the spire" ]]; then - ui_msgbox "Game Installer" "Game Installer" "Error installing SayTheSpire mod. Screen reader support will not be available." - exit 1 + if ! ln -sr "$HOME/.local/games/SlayTheSpire/steamapps/workshop/content/$appId/${modsMap[$modName]}"/* "$HOME/.local/games/SlayTheSpire/mods/"; then + if [[ "$modName" == "say the spire" ]]; then + ui_msgbox "Game Installer" "Game Installer" "Error installing SayTheSpire mod. Screen reader support will not be available." + exit 1 + fi + fi fi done diff --git a/.install/Stardew Valley.sh b/.install/Stardew Valley.sh index 7a590b3..9829d17 100644 --- a/.install/Stardew Valley.sh +++ b/.install/Stardew Valley.sh @@ -1,7 +1,7 @@ +# shellcheck shell=bash disable=SC2154 # installPath and cache are set by linux-game-manager.sh check_architecture x86_64 DISPLAY="" -alert -ui_msgbox "Game Installer" "Game Installer" "Please select the default path when prompted by the installer." +alert "Game Installer" "Game Installer" "Please select the default path when prompted by the installer." get_installer "stardew_valley_1_5_6_1988831614_53040.sh" "https://www.gog.com/game/stardew_valley" bash "${cache}/stardew_valley_1_5_6_1988831614_53040.sh" || { ui_msgbox "Game Installer" "Game Installer" "Error installing game." @@ -10,8 +10,7 @@ smapiVersion="3.18.4" download "https://github.com/Pathoschild/SMAPI/releases/download/${smapiVersion}/SMAPI-${smapiVersion}-installer.zip" "https://stormgames.wolfe.casa/downloads/stardew-valley/Mods.tar.xz" smapiTmp="$(mktemp -d)" unzip "${cache}/SMAPI-${smapiVersion}-installer.zip" -d "$smapiTmp" -alert -ui_msgbox "Game Installer" "Game Installer" "Preparing to install mods. Please select the same path as before when prompted.\n\nWhen it says SMAPI has been installed, press enter to finish installation." +alert "Game Installer" "Game Installer" "Preparing to install mods. Please select the same path as before when prompted.\n\nWhen it says SMAPI has been installed, press enter to finish installation." bash "${smapiTmp}/SMAPI ${smapiVersion} installer/install on Linux.sh" ln -sf "${HOME}/GOG Games/Stardew Valley/game" "${installPath}/StardewValley" tar -xvf "${cache}/Mods.tar.xz" -C "${installPath}/StardewValley/" diff --git a/.install/The Omega Reach.sh b/.install/The Omega Reach.sh new file mode 100644 index 0000000..4c347e5 --- /dev/null +++ b/.install/The Omega Reach.sh @@ -0,0 +1,7 @@ +# shellcheck shell=bash disable=SC2154 # installPath and cache are set by linux-game-manager.sh +check_architecture x86_64 +get_installer "omega-reach-linux-x64.zip" "https://shiftbacktick.itch.io/the-omega-reach" +mkdir -p "${installPath}/Omega Reach" +unzip -d "${installPath}/Omega Reach" "${cache}/omega-reach-linux-x64.zip" +chmod +x "${installPath}/Omega Reach/omega-reach" +chmod +x "${installPath}/Omega Reach/chrome-sandbox" diff --git a/.install/The Tornado Chicken.sh b/.install/The Tornado Chicken.sh index 0712a3b..9a8f096 100644 --- a/.install/The Tornado Chicken.sh +++ b/.install/The Tornado Chicken.sh @@ -1,6 +1,6 @@ +# shellcheck shell=bash disable=SC2154 # installPath and cache are set by linux-game-manager.sh check_architecture x86_64 get_installer "Ttc v3.2 linux.zip" "https://renzivan.itch.io/the-tornado-chicken" unzip -d "${installPath}/The Tornado Chicken" "${cache}/Ttc v3.2 linux.zip" chmod +x "${installPath}/The Tornado Chicken/Ttc" -alert -ui_msgbox "Game Installer" "Game Installer" "Note: When the game first starts it will be playing very loud music with the built in suboptimal voice.\n\nYou are recommended to press page down several times to turn down the music, then go to settings and enable speech with screen reader, using speech dispatcher.\n\nYou may then press page up to set the music to your liking." +alert "Game Installer" "Game Installer" "Note: When the game first starts it will be playing very loud music with the built in suboptimal voice.\n\nYou are recommended to press page down several times to turn down the music, then go to settings and enable speech with screen reader, using speech dispatcher.\n\nYou may then press page up to set the music to your liking." diff --git a/.install/Upheaval Gui.sh b/.install/Upheaval Gui.sh index f577673..8df4f4b 100644 --- a/.install/Upheaval Gui.sh +++ b/.install/Upheaval Gui.sh @@ -1,7 +1,7 @@ +# shellcheck shell=bash disable=SC2154 # installPath and cache are set by linux-game-manager.sh check_architecture x86_64 check_dependencies dmidecode get_installer "upheaval-linux.zip" "https://leonegaming.itch.io/upheaval" mkdir -p "${installPath}/Upheaval_Gui" unzip -d "${installPath}/Upheaval_Gui" "${cache}/upheaval-linux.zip" -alert -ui_msgbox "Game Installer" "Game Installer" "To enable accessibility, press shift t when the game starts." +alert "Game Installer" "Game Installer" "To enable accessibility, press shift t when the game starts." diff --git a/.install/Wheels of Prio.sh b/.install/Wheels of Prio.sh index 0f15495..3b5e304 100644 --- a/.install/Wheels of Prio.sh +++ b/.install/Wheels of Prio.sh @@ -1,6 +1,6 @@ +# shellcheck shell=bash disable=SC2154 # installPath and cache are set by linux-game-manager.sh check_architecture x86_64 get_installer "Wp v3.0 linux.zip" "https://psyra-productions.itch.io/wheels-of-prio" unzip -d "${installPath}/Wheels of Prio" "${cache}/Wp v3.0 linux.zip" chmod +x "${installPath}/Wheels of Prio/Wp" -alert -ui_msgbox "Game Installer" "Game Installer" "Note: When the game first starts it will be playing very loud music with the built in suboptimal voice.\n\nYou are recommended to press page down several times to turn down the music, then go to settings and enable speech with screen reader, using speech dispatcher.\n\nYou may then press page up to set the music to your liking." +alert "Game Installer" "Game Installer" "Note: When the game first starts it will be playing very loud music with the built in suboptimal voice.\n\nYou are recommended to press page down several times to turn down the music, then go to settings and enable speech with screen reader, using speech dispatcher.\n\nYou may then press page up to set the music to your liking." diff --git a/.launch/The Omega Reach.game b/.launch/The Omega Reach.game new file mode 100644 index 0000000..99108f8 --- /dev/null +++ b/.launch/The Omega Reach.game @@ -0,0 +1,4 @@ +# shellcheck shell=bash disable=SC2154 # installPath is set by linux-game-manager.sh +gamePath="${installPath}/Omega Reach" +pushd "${gamePath}" || return 1 +"${gamePath}/omega-reach" diff --git a/linux-game-manager.sh b/linux-game-manager.sh index 9e4b684..02814c3 100755 --- a/linux-game-manager.sh +++ b/linux-game-manager.sh @@ -340,7 +340,8 @@ check_architecture() { export fex="FEXLoader -- " return fi - local architecture="$(uname -m)" + local architecture + architecture="$(uname -m)" for i in "$@" ; do if [[ "${architecture}" == "$i" ]]; then return @@ -408,6 +409,8 @@ desktop_launcher() { exit 1 fi local dotDesktop + local execLine + local launchDirectory local terminal # Try to find an accessible terminal for i in mate-terminal lxterminal terminator gnome-terminal ; do @@ -416,11 +419,13 @@ desktop_launcher() { break fi done + launchDirectory="$(readlink -e "${0%/*}")" + 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' 'GenericName=Linux game Manager' 'Comment=Install and launch games that are accessible to the blind' - "Exec=${terminal} -t \"Linux Game Manager\" -e \"/usr/bin/bash -c 'pushd $(readlink -e "${0%/*}");nohup ./"${0##*/}" 2> /dev/null'\"" + "${execLine}" 'Terminal=false' 'Type=Application' 'StartupNotify=false' @@ -438,8 +443,25 @@ desktop_launcher() { # Alerts, for when user needs to read something. alert() { + local title="Linux Game Manager" + local backTitle="Linux Game Manager" + local message="Press OK to continue." + + if [[ $# -eq 1 ]]; then + message="$1" + elif [[ $# -eq 2 ]]; then + title="$1" + backTitle="$1" + message="$2" + elif [[ $# -ge 3 ]]; then + title="$1" + backTitle="$2" + shift 2 + message="$*" + fi + play -qnV0 synth 3 pluck D3 pluck A3 pluck D4 pluck F4 pluck A4 delay 0 .1 .2 .3 .4 remix - chorus 0.9 0.9 38 0.75 0.3 0.5 -t - ui_msgbox "Linux Game Manager" "Linux Game Manager" "Press OK to continue." + ui_msgbox "${title}" "${backTitle}" "${message}" } clear_cache() { @@ -549,8 +571,7 @@ download() { esac if [[ $downloadError -ne 0 ]]; then rm -fv "${cache}/${dest}" - ui_infobox "Linux Game Manager" "Linux Game Manager" "Error downloading \"${dest}\". Installation cannot continue." - alert + alert "Linux Game Manager" "Linux Game Manager" "Error downloading \"${dest}\". Installation cannot continue." exit 1 fi done @@ -593,11 +614,10 @@ get_installer() { if echo "$2" | xclip -selection clipboard 2> /dev/null ; then message+="\n\nThe URL has been copied to the clipboard." fi - alert - ui_msgbox "Linux Game Manager" "Linux Game Manager" "$message" + alert "Linux Game Manager" "Linux Game Manager" "$message" # Search the Desktop and Downloads directories for the installation file for i in ~/Downloads ~/Desktop ; do - find $i -type f -name "$1" -exec mv -v {} "${cache}/" \; + find "$i" -type f -name "$1" -exec mv -v {} "${cache}/" \; done # If the file is still not available abort. if [[ ! -f "${cache}/$1" ]]; then @@ -624,6 +644,7 @@ help() { help_text+="spd_voice=\" # set speech-dispatcher voice. Be sure module is correct.\n" help_text+="spd_volume=\" # set speech-dispatcher speech volume.\n\n" help_text+="INSTALLER SCRIPT DIALOG FUNCTIONS:\n" + help_text+="alert [\"title\" \"backtitle\"] \"message\" - Play alert sound and show acknowledgement dialog\n" help_text+="ui_msgbox \"title\" \"backtitle\" \"message\" - Show information message\n" help_text+="ui_yesno \"title\" \"backtitle\" \"question\" - Ask yes/no question\n" help_text+="ui_inputbox \"title\" \"backtitle\" \"prompt\" \"default\" - Get text input\n" @@ -643,6 +664,7 @@ help() { game_installer() { # Create the menu of available games by reading from .install directory 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 # Skip if first line starts with #// @@ -687,6 +709,7 @@ game_installer() { # Check if install script exists if [[ -f "$installScript" ]]; then # Source and execute the install script + # shellcheck disable=SC1090 # install scripts are selected dynamically from .install source "$installScript" # Show success message ui_msgbox "Game Installer" "Game Installer" "${game} has been installed." @@ -732,7 +755,8 @@ game_removal() { # Get the actual game file paths local gameName="${selectedGame##*/}" gameName="${gameName%.sh}" - local gameFile="$(readlink -f "${0%/*}/.launch/${gameName}.sh")" + local gameFile + gameFile="$(readlink -f "${0%/*}/.launch/${gameName}.sh")" # Get the actual installation path from the .game file local gameInstallPath gameInstallPath="$(grep -F "installPath" "$gameFile" | grep -v 'pushd' | head -n1)" @@ -774,7 +798,8 @@ game_update() { done menuList+=("Donate" "Donate") menuList+=("Become a Patron" "Become a Patron") - local game="$(ui_menu "Audio Game Updater" "Audio Game Updater" "Please select a game to update" "${menuList[@]}")" + local game + game="$(ui_menu "Audio Game Updater" "Audio Game Updater" "Please select a game to update" "${menuList[@]}")" if [[ ${#game} -gt 0 ]]; then if [[ "$game" == "Donate" ]]; then open_url "https://ko-fi.com/stormux" @@ -787,6 +812,7 @@ game_update() { # Get the game name for success message local updateGameName="${game##*/}" updateGameName="${updateGameName%.sh}" + # shellcheck disable=SC1090 # update scripts are selected dynamically from .update source "${game}" else exit 0 @@ -827,6 +853,7 @@ game_launcher() { if [[ $menuCode -ne 0 ]] || [[ -z "$selectedGame" ]]; then exit 0 fi + # shellcheck disable=SC1090 # launcher scripts are selected dynamically from .launch . "${selectedGame}" exit 0 } @@ -876,6 +903,7 @@ cache="${XDG_CACHE_HOME:-$HOME/.cache}/linux-game-manager" configFile="${XDG_CONFIG_HOME:-$HOME/.config}/storm-games/linux-game-manager/games.conf" mkdir -p "${cache}" mkdir -p "${configFile%/*}" +declare -a installedGames=() # Load any arguments from settings.conf file if [[ -r "${configFile%/*}/settings.conf" ]]; then source "${configFile%/*}/settings.conf" @@ -949,5 +977,6 @@ while getopts "${args}" i ; do esac done +[[ "${noCache}" == "true" ]] && : exit 0