From fd72a85003add459d50c465d2bc176aa63aa7216 Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Tue, 13 Oct 2026 15:06:01 -0400 Subject: [PATCH] Arcadelux update script added. --- .includes/functions.sh | 163 ++++++++++++++++++ .install/Arcadelux.sh | 6 +- README.md | 4 + game-scripts/arcadelux-update.sh | 24 +++ .../{update-swamp2.sh => swamp2-update.sh} | 0 5 files changed, 193 insertions(+), 4 deletions(-) create mode 100755 game-scripts/arcadelux-update.sh rename game-scripts/{update-swamp2.sh => swamp2-update.sh} (100%) diff --git a/.includes/functions.sh b/.includes/functions.sh index 5118917..353cbe4 100644 --- a/.includes/functions.sh +++ b/.includes/functions.sh @@ -251,3 +251,166 @@ install_with_progress() { ;; esac } + +# Return the latest GitHub release tag and one matching asset URL, one per line. +github_latest_release() { + local repo="$1" + local assetFilter="$2" + local response tag + local -a assetUrls=() + + if [[ -z "$repo" || "$repo" != */* ]]; then + echo "Expected a GitHub repository in owner/repo format." >&2 + return 1 + fi + + if ! response="$(curl -fsSL --retry 3 "https://api.github.com/repos/${repo}/releases/latest")"; then + echo "Could not fetch the latest release for ${repo}." >&2 + return 1 + fi + + tag="$(sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' <<< "$response" | head -n1)" + mapfile -t assetUrls < <( + sed -n 's/.*"browser_download_url"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' <<< "$response" + ) + if [[ -n "$assetFilter" ]]; then + mapfile -t assetUrls < <( + printf '%s\n' "${assetUrls[@]}" | grep -iF -- "$assetFilter" + ) + fi + + if [[ -z "$tag" || ${#assetUrls[@]} -ne 1 ]]; then + echo "Could not identify one matching release asset for ${repo}." >&2 + return 1 + fi + + printf '%s\n%s\n' "$tag" "${assetUrls[0]}" +} + +# Install or replace a game from its latest GitHub release. +# Arguments: repository, asset filter, destination, expected executable, and +# zero or more relative paths or files to preserve from the old installation. +update_github_release_game() { + local repo="$1" + local assetFilter="$2" + local destination="$3" + local expectedExecutable="$4" + shift 4 + local -a preservePaths=("$@") + local -a releaseInfo=() executablePaths=() pathParts=() + local releaseInfoText installedVersion latestTag latestUrl archiveFile + local stageRoot archiveRoot newRoot executablePath preservePath sourcePath targetPath pathPart + local updateFailed="false" + + githubReleaseGameStatus="checking" + destination="${destination%/}" + if [[ -z "$destination" || "$destination" != /* ]]; then + echo "The game destination must be an absolute path." >&2 + return 1 + fi + + for preservePath in "${preservePaths[@]}"; do + if [[ "$preservePath" == /* ]]; then + echo "Preserve paths must be relative to the game directory: ${preservePath}" >&2 + return 1 + fi + IFS='/' read -r -a pathParts <<< "$preservePath" + for pathPart in "${pathParts[@]}"; do + if [[ -z "$pathPart" || "$pathPart" == "." || "$pathPart" == ".." ]]; then + echo "Invalid preserve path: ${preservePath}" >&2 + return 1 + fi + done + done + + if ! releaseInfoText="$(github_latest_release "$repo" "$assetFilter")"; then + return 1 + fi + mapfile -t releaseInfo <<< "$releaseInfoText" + latestTag="${releaseInfo[0]}" + latestUrl="${releaseInfo[1]}" + + if [[ -f "${destination}/.agm-version" ]]; then + installedVersion="$(<"${destination}/.agm-version")" + if [[ "$installedVersion" == "$latestTag" && -f "${destination}/${expectedExecutable}" ]]; then + githubReleaseGameStatus="up-to-date" + echo "${game:-The game} is already at ${latestTag}." + return 0 + fi + fi + + archiveFile="${latestUrl##*/}" + archiveFile="${archiveFile//%20/ }" + archiveFile="${archiveFile#*\?filename=}" + archiveFile="${archiveFile%\?*}" + rm -f "${cache}/${archiveFile}" + download "$latestUrl" + + mkdir -p "$(dirname "$destination")" + stageRoot="${destination}.agm-update.$$" + archiveRoot="${stageRoot}/archive" + mkdir -p "$archiveRoot" + + if ! unzip -q "${cache}/${archiveFile}" -d "$archiveRoot"; then + echo "Could not extract ${archiveFile}." >&2 + rm -rf "$stageRoot" + return 1 + fi + + mapfile -t executablePaths < <(find "$archiveRoot" -type f -name "$expectedExecutable" -print) + if [[ ${#executablePaths[@]} -ne 1 ]]; then + echo "The release did not contain exactly one ${expectedExecutable}." >&2 + rm -rf "$stageRoot" + return 1 + fi + executablePath="${executablePaths[0]}" + newRoot="${executablePath%/*}" + + for preservePath in "${preservePaths[@]}"; do + sourcePath="${destination}/${preservePath}" + [[ -e "$sourcePath" ]] || continue + targetPath="${newRoot}/${preservePath}" + if [[ -d "$sourcePath" ]]; then + mkdir -p "$targetPath" + if ! cp -a "${sourcePath}/." "$targetPath/"; then + echo "Could not preserve ${preservePath}." >&2 + updateFailed="true" + break + fi + else + mkdir -p "${targetPath%/*}" + if ! cp -a "$sourcePath" "$targetPath"; then + echo "Could not preserve ${preservePath}." >&2 + updateFailed="true" + break + fi + fi + done + + if [[ "$updateFailed" == "true" ]]; then + rm -rf "$stageRoot" + return 1 + fi + + printf '%s\n' "$latestTag" > "${newRoot}/.agm-version" + if [[ -e "$destination" ]]; then + if ! mv "$destination" "${stageRoot}/old"; then + echo "Could not move the old installation aside." >&2 + rm -rf "$stageRoot" + return 1 + fi + fi + + if ! mv "$newRoot" "$destination"; then + echo "Could not install the new version." >&2 + if [[ -e "${stageRoot}/old" ]]; then + mv "${stageRoot}/old" "$destination" + fi + rm -rf "$stageRoot" + return 1 + fi + + rm -rf "$stageRoot" + githubReleaseGameStatus="updated" + echo "${game:-The game} has been updated to ${latestTag}." +} diff --git a/.install/Arcadelux.sh b/.install/Arcadelux.sh index 24f3e54..e58d183 100644 --- a/.install/Arcadelux.sh +++ b/.install/Arcadelux.sh @@ -1,11 +1,9 @@ # shellcheck shell=bash disable=SC2154 # cache, game, and WINEPREFIX are set by audiogame-manager -download "https://github.com/riadassoum/Arcadelux/releases/download/v1.0.0/Arcadelux1.0.0.zip" export WINEARCH=win64 export winVer="win10" install_wine_bottle -install_with_progress unzip "Extracting game files..." -d "$WINEPREFIX/drive_c/Program Files/$game" "${cache}/Arcadelux1.0.0.zip" -if [[ ! -f "$WINEPREFIX/drive_c/Program Files/$game/Arcadelux.exe" ]]; then - echo "Arcadelux.exe was not extracted." >&2 +if ! update_github_release_game "riadassoum/Arcadelux" "arcadelux" "${WINEPREFIX}/drive_c/Program Files/${game}" "Arcadelux.exe" "savedata"; then + echo "Could not install the latest Arcadelux release." >&2 exit 1 fi add_launcher "c:\Program Files\\${game}\\Arcadelux.exe" diff --git a/README.md b/README.md index 8a27263..12ffe48 100644 --- a/README.md +++ b/README.md @@ -46,3 +46,7 @@ Voice names used must exactly match the way they appear in the set-voice.sh menu - MSMike - MSSam - RHVoice + +## AI-assisted contributions + +AI-assisted contributions are welcome. The person submitting the contribution remains responsible for reviewing and testing the changes before submission. Please review the generated diff, run the relevant tests, and describe what changed and how it was tested. diff --git a/game-scripts/arcadelux-update.sh b/game-scripts/arcadelux-update.sh new file mode 100755 index 0000000..8eb56a6 --- /dev/null +++ b/game-scripts/arcadelux-update.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# shellcheck disable=SC1091,SC2154 + +scriptDir="$(readlink -f "$0")" +scriptDir="${scriptDir%/*}/.." +source "${scriptDir}/.includes/dialog-interface.sh" +source "${scriptDir}/.includes/functions.sh" + +export game="Arcadelux" +cache="${XDG_CACHE_HOME:-$HOME/.cache}/audiogame-manager" +mkdir -p "$cache" +WINEPREFIX="$HOME/.local/wine64" +gamePath="${WINEPREFIX}/drive_c/Program Files/${game}" + +if ! update_github_release_game "riadassoum/Arcadelux" "arcadelux" "$gamePath" "Arcadelux.exe" "savedata"; then + alert "Arcadelux Update" "Arcadelux Update" "Could not update Arcadelux." + exit 1 +fi + +if [[ "$githubReleaseGameStatus" == "up-to-date" ]]; then + agm_msgbox "Arcadelux Update" "Arcadelux Update" "Arcadelux is up to date." +else + agm_msgbox "Arcadelux Update" "Arcadelux Update" "Arcadelux has been updated." +fi diff --git a/game-scripts/update-swamp2.sh b/game-scripts/swamp2-update.sh similarity index 100% rename from game-scripts/update-swamp2.sh rename to game-scripts/swamp2-update.sh