Files
gaming-image-files/usr/local/bin/stormux_install_helper.sh
2025-10-09 23:58:40 -04:00

258 lines
8.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# Stormux Installation Helper
# Provides automatic installation with speech feedback and progress indicators
# Configuration
GAMES_REGISTRY="/usr/share/stormux/downloadable_games.json"
PACKAGES_REGISTRY="/usr/share/stormux/installable_packages.json"
LOG_DIR="$HOME/Logs"
LOG_FILE="$LOG_DIR/installer.log"
INSTALL_BASE="$HOME/.local/games"
NVDA_DLL_SOURCE="$HOME/.local/games/nvda"
# Initialize logging
init_logging() {
mkdir -p "$LOG_DIR"
# Clear previous log and start fresh
echo "=== Installation started at $(date) ===" > "$LOG_FILE"
}
# Speech output
speak() {
local message="$1"
echo "$message" >> "$LOG_FILE"
spd-say "$message" 2>/dev/null || echo "$message"
}
# Progress beep
progress_beep() {
# Simple beep using speaker-test or paplay
if command -v paplay &> /dev/null && [[ -f /usr/share/sounds/freedesktop/stereo/message.oga ]]; then
paplay /usr/share/sounds/freedesktop/stereo/message.oga 2>/dev/null &
fi
}
# Download with progress feedback
download_with_progress() {
local url="$1"
local output="$2"
local name="$3"
speak "Downloading $name"
echo "Downloading from: $url" >> "$LOG_FILE"
# Start background process for progress beeps
(
while kill -0 $$ 2>/dev/null; do
sleep 5
progress_beep
done
) &
local beep_pid=$!
# Download with curl
if curl -L -f --progress-bar -o "$output" "$url" 2>> "$LOG_FILE"; then
kill $beep_pid 2>/dev/null
wait $beep_pid 2>/dev/null
echo "Download successful" >> "$LOG_FILE"
return 0
else
kill $beep_pid 2>/dev/null
wait $beep_pid 2>/dev/null
echo "Download failed" >> "$LOG_FILE"
return 1
fi
}
# Replace NVDA DLLs in game directory
replace_nvda_dlls() {
local game_dir="$1"
if [[ ! -d "$NVDA_DLL_SOURCE" ]]; then
echo "Warning: NVDA DLL source directory not found" >> "$LOG_FILE"
return 0
fi
# Replace all NVDA DLLs
{
find "$game_dir" -type f -name "nvdaControllerClient32.dll" -exec cp -v "$NVDA_DLL_SOURCE/nvdaControllerClient32.dll" '{}' \;
find "$game_dir" -type f -name "nvdaControllerClient64.dll" -exec cp -v "$NVDA_DLL_SOURCE/nvdaControllerClient64.dll" '{}' \;
find "$game_dir" -type f -name "nvdaControllerClient.dll" -exec cp -v "$NVDA_DLL_SOURCE/nvdaControllerClient64.dll" '{}' \;
} >> "$LOG_FILE" 2>&1
}
# Extract and setup game from ZIP
setup_game_zip() {
local zipfile="$1"
local game_dir="$2"
local game_name="$3"
speak "Installing $game_name"
echo "Extracting to: $game_dir" >> "$LOG_FILE"
# Remove old installation
rm -rf "$game_dir"
mkdir -p "$game_dir"
# Extract to temp location first to handle any ZIP structure
local temp_extract="/tmp/stormux_install_$$"
mkdir -p "$temp_extract"
if ! unzip -q "$zipfile" -d "$temp_extract" 2>> "$LOG_FILE"; then
echo "Extraction failed" >> "$LOG_FILE"
rm -rf "$temp_extract"
return 2
fi
# Check if everything extracted into a single subdirectory
local extracted_items
extracted_items=("$temp_extract"/*)
if [[ ${#extracted_items[@]} -eq 1 ]] && [[ -d "${extracted_items[0]}" ]]; then
# Single directory - move its contents to game_dir
echo "Single directory extracted, moving contents" >> "$LOG_FILE"
mv "${extracted_items[0]}"/* "$game_dir/" 2>> "$LOG_FILE"
else
# Multiple items or single file - move everything
echo "Multiple items extracted, moving all" >> "$LOG_FILE"
mv "$temp_extract"/* "$game_dir/" 2>> "$LOG_FILE"
fi
rm -rf "$temp_extract"
# Replace NVDA DLLs
replace_nvda_dlls "$game_dir"
# Clean up temp file
rm -f "$zipfile"
echo "Installation complete" >> "$LOG_FILE"
return 0
}
# Install system package via yay
install_system_package() {
local package="$1"
local name="$2"
speak "Installing $name"
echo "Installing package: $package" >> "$LOG_FILE"
if yay -Sy --noconfirm "$package" >> "$LOG_FILE" 2>&1; then
echo "Package installation successful" >> "$LOG_FILE"
return 0
else
echo "Package installation failed" >> "$LOG_FILE"
speak "Installation of $name failed. Check logs."
return 1
fi
}
# Check if game is installed
is_game_installed() {
local game_dir="$1"
local executable="$2"
[[ -e "$game_dir/$executable" ]]
}
# Check if package is installed
is_package_installed() {
local verify_command="$1"
eval "$verify_command" &>/dev/null
}
# Auto-install: Main function
# Usage: auto_install <item_id>
# Returns: 0 if ready to launch, non-zero on failure
auto_install() {
local item_id="$1"
init_logging
# Try to find in games registry
if [[ -f "$GAMES_REGISTRY" ]]; then
echo "Reading games registry: $GAMES_REGISTRY" >> "$LOG_FILE"
local game_info
game_info=$(jq -r ".downloadable_games[\"$item_id\"] // empty" "$GAMES_REGISTRY" 2>> "$LOG_FILE")
echo "Game info result: ${game_info:-empty}" >> "$LOG_FILE"
if [[ -n "$game_info" ]]; then
local name url directory executable game_dir
name=$(echo "$game_info" | jq -r '.name')
url=$(echo "$game_info" | jq -r '.url')
directory=$(echo "$game_info" | jq -r '.directory')
executable=$(echo "$game_info" | jq -r '.executable')
game_dir="$INSTALL_BASE/$directory"
# Check if already installed
if is_game_installed "$game_dir" "$executable"; then
echo "Game already installed: $name" >> "$LOG_FILE"
return 0
fi
# Download and install
local temp_zip="/tmp/${directory}_download.zip"
if download_with_progress "$url" "$temp_zip" "$name"; then
if setup_game_zip "$temp_zip" "$game_dir" "$name"; then
# Verify installation
if is_game_installed "$game_dir" "$executable"; then
speak "Installation complete"
return 0
else
speak "Installation failed. Executable not found."
echo "Error: Executable not found after installation: $executable" >> "$LOG_FILE"
return 3
fi
else
speak "Installation failed. Could not extract game."
return 2
fi
else
speak "Download failed. Check your internet connection."
return 1
fi
fi
fi
# Try to find in packages registry
if [[ -f "$PACKAGES_REGISTRY" ]]; then
local package_info
package_info=$(jq -r ".installable_packages[\"$item_id\"] // empty" "$PACKAGES_REGISTRY" 2>/dev/null)
if [[ -n "$package_info" ]]; then
local name package verify_command
name=$(echo "$package_info" | jq -r '.name')
package=$(echo "$package_info" | jq -r '.package')
verify_command=$(echo "$package_info" | jq -r '.verify_command')
# Check if already installed
if is_package_installed "$verify_command"; then
echo "Package already installed: $name" >> "$LOG_FILE"
return 0
fi
# Install package
if install_system_package "$package" "$name"; then
speak "Installation complete"
return 0
else
return 1
fi
fi
fi
# Item not found in any registry
if [[ ! -f "$GAMES_REGISTRY" ]] && [[ ! -f "$PACKAGES_REGISTRY" ]]; then
echo "Error: Registry files not found!" >> "$LOG_FILE"
echo " Expected: $GAMES_REGISTRY" >> "$LOG_FILE"
echo " Expected: $PACKAGES_REGISTRY" >> "$LOG_FILE"
speak "Error: Installation registry files not found. This may be a development system."
else
echo "Error: Item not found in registries: $item_id" >> "$LOG_FILE"
speak "Error: $item_id not found in installation registry"
fi
return 4
}