Files
audiogame-manager/.includes/bottle.sh
Hunter Jozwiak 825d74460b Fix things so that the global version of Wine isn't trampled over.
The specific version of wine can be set in the registry for each
app. Also, add fakejapanese to the Shadow Line installation, though it
is still shitting the bed.
2025-12-08 23:32:51 -05:00

271 lines
10 KiB
Bash

#!/usr/bin/env bash
get_bottle() {
# Simple rule: wine64 for everything, wine32 only for speech APIs
local architecture="${1:-win64}"
architecture="${architecture/win/}"
export WINEPREFIX="$HOME/.local/wine${architecture}"
# Set wine executables based on architecture - FOR LAUNCHER
if [[ "$architecture" == "32" ]] && [[ -n "$wine32" ]]; then
# Set environment variables for winetricks compatibility
export WINE="$wine32"
export WINESERVER="$wine32server"
# Also prepend to PATH for regular wine calls
export PATH="${wine32%/*}:$PATH"
# Keep WINEARCH for compatibility
echo "DEBUG: Using managed wine32 for LAUNCHER (WINE=$WINE, PATH updated)"
else
# Clear wine variables for system wine but preserve WINEARCH if set
unset WINE WINESERVER
echo "DEBUG: Using system wine for LAUNCHER (architecture $architecture)"
fi
}
# Set wine environment for installation (called from install_wine_bottle)
set_wine_env() {
local architecture="$1"
if [[ "$architecture" == "32" ]] && [[ -n "$wine32" ]]; then
export WINE="$wine32"
export WINESERVER="$wine32server"
export PATH="${wine32%/*}:$PATH"
# Don't unset WINEARCH - preserve it for proper architecture selection
echo "DEBUG: Set wine32 environment for INSTALLATION (WINE=$WINE, WINEARCH=$WINEARCH)"
else
unset WINE WINESERVER
# Don't unset WINEARCH - preserve it for proper architecture selection
echo "DEBUG: Set system wine environment for INSTALLATION (WINEARCH=$WINEARCH)"
fi
}
# Note: install_wine function removed - we now use system wine with simplified bottle management
winetricks() {
# Report used packages to the winetricks maintainer so he knows they are being used.
if ! [[ -e "${XDG_CACHE_HOME:-$HOME/.cache}/winetricks/track_usage" ]]; then
mkdir -p "${XDG_CACHE_HOME:-$HOME/.cache}/winetricks/"
echo "1" > "${XDG_CACHE_HOME:-$HOME/.cache}/winetricks/track_usage"
fi
# Temporary work around for winetricks git bugs. Requires winetricks be installed from package manager.
/usr/bin/winetricks "$@"
return
# Download or update agm's copy of winetricks
if [[ ! -e "${winetricksPath}/winetricks" ]]; then
checkWinetricksUpdate="true"
download "https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks"
mv "${cache}/winetricks" "${winetricksPath}"
chmod 755 "${winetricksPath}/winetricks"
else
if [[ "$checkWinetricksUpdate" != "true" ]]; then
checkWinetricksUpdate="true"
${winetricksPath}/winetricks --self-update
fi
fi
# Run the requested winetricks parameters
if command -v FEXLoader &> /dev/null ; then
WINE="" FEXLoader -- ${winetricksPath}/winetricks "$@"
else
${winetricksPath}/winetricks "$@"
fi
}
install_rhvoice() {
if [[ -d "${WINEPREFIX}/drive_c/Program Files/Olga Yakovleva/" ]]; then
return
fi
if [[ "$norh" == "true" ]]; then
# Try to prevent the user from breaking speech
# Also useful for games that do not work with RHVoice
if [[ "${defaultVoice}" == "RHVoice" ]]; then
unset defaultVoice
fi
return
fi
declare -A RHVoice=(
[alan]="https://github.com/RHVoice/alan-eng/releases/download/4.0/RHVoice-voice-English-Alan-v4.0.2016.21-setup.exe"
[bdl]="https://github.com/RHVoice/bdl-eng/releases/download/4.1/RHVoice-voice-English-Bdl-v4.1.2016.21-setup.exe"
[clb]="https://github.com/RHVoice/clb-eng/releases/download/4.0/RHVoice-voice-English-Clb-v4.0.2016.21-setup.exe"
[lyubov]="https://rhvoice.eu-central-1.linodeobjects.com/RHVoice-voice-English-Lyubov-v4.0.2008.15-setup.exe"
[slt]="https://github.com/RHVoice/slt-eng/releases/download/4.1/RHVoice-voice-English-Slt-v4.1.2016.21-setup.exe"
)
voiceName="${voiceName:-bdl}"
voiceName="${voiceName,,}"
if [[ "${RHVoice[${voiceName}]}" == "" ]]; then
echo "Invalid RHVoice name specified, defaulting to Bdl."
voiceName="bdl"
fi
local voiceFile="${RHVoice[${voiceName}]##*/}"
download "${RHVoice[${voiceName}]}"
winetricks -q win8 | agm_progressbox "RHVoice Setup" "Preparing Windows environment for RHVoice..."
echo "Installing RHVoice ${voiceName^}..."
wine "${cache}/${voiceFile}" &
sleep 20 | agm_progressbox "RHVoice Setup" "Installing RHVoice ${voiceName^} voice..."
wineserver -k
}
install_wine_bottle() {
# Simplified - bottles are now pre-created with dependencies
# Just set up the wine environment for game installation
# Determine architecture from WINEARCH or dependency requirements
# Preserve existing WINEARCH if already set by game installer
if [[ -z "$WINEARCH" ]]; then
# All games use wine64 now (wine32 eliminated 2025-12-06)
# SAPI support is provided by wine64 with WINETRICKS_FORCE=1
export WINEARCH="win64"
echo "DEBUG: Auto-selected wine64 (default - wine32 eliminated)"
else
echo "DEBUG: Using pre-set WINEARCH=$WINEARCH from game installer"
fi
# Set architecture for WINEPREFIX path
local architecture
if [[ "$WINEARCH" == "win32" ]]; then
architecture=32
else
architecture=64
fi
export WINEPREFIX="$HOME/.local/wine${architecture}"
# Set wine environment
set_wine_env "$architecture"
echo "Using pre-configured wine${architecture} bottle at $WINEPREFIX"
# Store winVer for per-app setting in add_launcher (don't set globally)
if [[ -n "$winVer" ]]; then
export gameWinVer="$winVer"
fi
# Install any additional game-specific dependencies if specified
if [[ $# -gt 0 ]]; then
# Filter out dependencies that are already installed in bottle creation
local depsToInstall=()
local alreadyInstalled="speechsdk sapi corefonts isolate_home"
for dep in "$@"; do
# Skip dependencies already installed during bottle creation
# Also skip winVer patterns - handled separately above
if [[ ! " $alreadyInstalled " =~ " $dep " ]] && [[ ! "$dep" =~ ^win(7|8|10)$ ]]; then
depsToInstall+=("$dep")
fi
done
if [[ ${#depsToInstall[@]} -gt 0 ]]; then
# Separate speechsdk (needs FORCE) from other deps
local regularDeps=()
local needsSpeechsdk=false
for dep in "${depsToInstall[@]}"; do
if [[ "$dep" == "speechsdk" ]]; then
needsSpeechsdk=true
else
regularDeps+=("$dep")
fi
done
# Install regular deps without FORCE
if [[ ${#regularDeps[@]} -gt 0 ]]; then
echo "Installing additional dependencies: ${regularDeps[*]}"
{
env WINE="$WINE" WINESERVER="$WINESERVER" DISPLAY="${DISPLAY:-:0}" winetricks -q isolate_home "${regularDeps[@]}" ${winetricksSettings}
} | agm_progressbox "Wine Setup" "Installing additional dependencies..."
fi
# Install speechsdk with FORCE if needed
if [[ "$needsSpeechsdk" == "true" ]]; then
echo "Installing speechsdk with WINETRICKS_FORCE=1"
{
env WINE="$WINE" WINESERVER="$WINESERVER" DISPLAY="${DISPLAY:-:0}" WINETRICKS_FORCE=1 winetricks -q speechsdk
} | agm_progressbox "Wine Setup" "Installing Speech SDK..."
fi
fi
fi
}
# Set Windows version for a specific executable (per-app, not global)
# This allows different games to use different Windows versions in the same bottle
set_app_winver() {
local exePath="$1"
local winVersion="$2"
if [[ -z "$exePath" ]] || [[ -z "$winVersion" ]]; then
return
fi
# Extract just the exe filename from path (handles both / and \ separators)
local exeName="${exePath##*\\}"
exeName="${exeName##*/}"
echo "Setting Windows version $winVersion for $exeName"
cat > /tmp/app_winver.reg << EOF
REGEDIT4
[HKEY_CURRENT_USER\\Software\\Wine\\AppDefaults\\${exeName}]
"Version"="${winVersion}"
EOF
wine regedit /tmp/app_winver.reg
rm /tmp/app_winver.reg
}
add_launcher() {
# Determine architecture from WINEPREFIX path instead of WINEARCH variable
local architecture="win64" # default
if [[ "$WINEPREFIX" =~ wine32 ]]; then
architecture="win32"
fi
# Set per-app Windows version if specified
if [[ -n "$gameWinVer" ]]; then
set_app_winver "$1" "$gameWinVer"
unset gameWinVer
fi
local launchSettings="${architecture}|${1}|${game}"
shift
while [[ $# -gt 0 ]]; do
launchSettings+="|$1"
shift
done
if ! grep -F -q -x "${launchSettings}" "${configFile}" 2> /dev/null ; then
echo "${launchSettings}" >> "${configFile}"
sort -o "${configFile}" "${configFile}"
# Remove .lnk files because they don't work.
find ~/Desktop -type f -iname '*.lnk' -exec bash -c '
for f ; do
mimeType="$(file -b "$f")"
mimeType="${mimeType%%,*}"
if [[ "$mimeType" == "MS Windows shortcut" ]]; then
rm -v "$f"
fi
done' _ {} +
if [[ "${noCache}" == "true" ]]; then
rm -f "${cache}/${1##*\\}"
fi
fi
}
# Install the Discord RPC bridge
install_discord_rpc_bridge() {
echo "Installing Discord RPC bridge for Wine compatibility..."
download "https://github.com/EnderIce2/rpc-bridge/releases/download/v1.4.0.1/bridge.zip"
if [[ -f "${cache}/bridge.zip" && ! -f "${cache}/bridge.exe" ]]; then
# the package is on the system, but not extracted just yet.
unzip "${cache}/bridge.zip" -d "${cache}"
fi
if [[ -f "${cache}/bridge.exe" ]]; then
wine "${cache}/bridge.exe" --install 2>&1 | grep -v "fixme:" || echo "Discord bridge installation attempted"
# Copy required bridge.sh script to Wine prefix
if [[ -f "${cache}/bridge.sh" ]]; then
cp "${cache}/bridge.sh" "${WINEPREFIX}/drive_c/windows/"
echo "Copied bridge.sh to Wine prefix"
else
echo "WARNING: bridge.sh not found in cache!"
fi
else
echo "ERROR: bridge.exe not found after extraction!"
return 1
fi
}