diff --git a/.includes/bottle.sh b/.includes/bottle.sh new file mode 100644 index 0000000..cc81266 --- /dev/null +++ b/.includes/bottle.sh @@ -0,0 +1,261 @@ +get_bottle() { + # Handles games that use the same wine bottle + case "${game}" in + # Aprone (Jeremy Kaldobsky) games. + "castaways"*) ;& + "castaways-2"*) ;& + "daytona-and-the-book-of-gold"*) ;& + "dog-who-hates-toast"*) ;& + "lunimals"*) ;& + "paw-prints"*) ;& + "penta-path"*) ;& + "preludeamals"*) ;& + "puzzle-divided"*) ;& + "rettou"*) ;& + "revelation"*) ;& + "swamp"*) ;& + "tarot-assistant"*) ;& + "triple-triad"*) + export WINEPREFIX="${HOME}/.local/wine/aprone" ;; + "bg-"*) export WINEPREFIX="${HOME}/.local/wine/bg";; + # draconis games + "esp-pinball-classic"*) ;& + "esp-pinball-extreme"*) ;& + "esp-pinball-party-pack"*) ;& + "silver-dollar"*) ;& + "monkey-business"*) ;& + "alien-outback"*) ;& + "dyna-man"*) ;& + "change-reaction"*) ;& + "ten-pin-alley"*) export WINEPREFIX="${HOME}/.local/wine/draconis";; + # l-works games group + "duck-hunt"*) ;& + "judgement-day"*) ;& + "lockpick"*) ;& + "pigeon-panic"*) ;& + "smashathon"*) ;& + "super-egg-hunt"*) ;& + "super-liam"*) ;& + "the-great-toy-robbery"*) export WINEPREFIX="${HOME}/.local/wine/l-works";; + # Nyanchan games group + "bokurano-daibouken"*) ;& + "laser-breakout"*) ;& + "marina-break"*) ;& + "mp5"*) ;& + "screaming-strike-2"*) ;& + "world-of-war"*) export WINEPREFIX="${HOME}/.local/wine/nyanchan";; + # Oriol Gomez games group + "bombercats"*) ;& + "copter-mission"*) ;& + "danger-on-the-wheel"*) ;& + "death-on-the-road"*) ;& + "fuck-that-bird"*) ;& + "hammer-of-glory"*) ;& + "insect-therapy"*) ;& + "rhythm-rage"*) ;& + "run-for-your-life"*) ;& + "thief"*) ;& + "villains-from-beyond"*) export WINEPREFIX="${HOME}/.local/wine/oriol-gomez";; + # pbgames group + "dark-destroyer"*) ;& + "PBGames TMP") export WINEPREFIX="$HOME/.local/wine/pbgames" ;; + # tunmi13 games group + "battle-of-the-hunter"*) ;& + "clashes-of-the-sky"*) ;& + "challenge-of-the-horse"*) export WINEPREFIX="${HOME}/.local/wine/tunmi13";; + # tunmi13-64bit games group + "battlefield-2d"*) ;& + "haunted-party"*) ;& + "skateboarder-pro"*) export WINEPREFIX="${HOME}/.local/wine/tunmi13-64bit";; + # Dan Z games group + "lost"*) ;& + "maze-craze"*) ;& + "super-deekout"*) + export norh="true" + export WINEPREFIX="$HOME/.local/wine/dan-z" + ;; + *) export WINEPREFIX="${HOME}/.local/wine/${game%|*}";; + esac + # Wine version for bottles + if [[ "$game" =~ entombed ]]; then + install_wine "6.18" "32" + fi + if [[ "$game" =~ rs-games ]]; then + install_wine "7.0" "32" + fi + if [[ "$game" =~ shadow-line ]]; then + install_wine "7.7" "32" + fi +} + +install_wine() { + # Requires wine version, e.g. 7.7 and architecture, 32|64 + if [[ $# -ne 2 ]]; then + exit 1 + fi + # Figure out wineInstallationPath + wineInstallationPath="${XDG_DATA_HOME:-$HOME/.local/share}/audiogame-manager/wine_$2/$1" + export wine="${wineInstallationPath}/bin/wine" + # If the path exists, wine should already be installed. + # Just make sure we didn't wind up with a empty directory for some reason + rmdir "${wineInstallationPath}" 2> /dev/null + if [[ -d "${wineInstallationPath}" ]]; then + return + fi + mkdir -p "${wineInstallationPath}" 2> /dev/null + # This probably does not need to be cached, so download to tmp. + installationFile="$(mktemp)" + local v=$2 + v="${v/32/x86}" + v="${v/64/x64}" # Probably wrong, so just a place holder. + # If this goes wrong, bail out + set -e + { curl -L --output "${installationFile}" "https://www.playonlinux.com/wine/binaries/phoenicis/upstream-linux-x86/PlayOnLinux-wine-${1}-upstream-linux-${v}.tar.gz" + tar xf "${installationFile}" -C "${wineInstallationPath}"; } | dialog --progressbox "Installing $2 bit Wine version $1." -1 -1 + set +e +} + +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 "$HOME/.local/wine/${bottle}/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 + echo "Installing RHVoice ${voiceName^}..." + ${wine} "${cache}/${voiceFile}" & + sleep 20 + ${wine}server -k +} + +install_wine_bottle() { + # 32 bit installations work best and are the default here, if you need to override it, do it in the game specific installation steps. + export WINEARCH="${WINEARCH:-win32}" + # Figure out if we are using a specific version of wine + export wine="${wine:-$(command -v wine)}" + # Set the WINE and WINESERVER environmental variables so winetricks will use the right installation. + export WINE="${wine}" + export WINESERVER="${wine}server" + if [[ -z "$bottle" ]]; then + local bottle="${game,,}" + bottle="${bottle//[[:space:]]/-}" + if [[ -d "$HOME/.local/wine/${bottle}" ]]; then + echo "$HOME/.local/wine/${bottle} exists. Please remove it before running this installer." + exit 1 + fi + fi + export WINEPREFIX="$HOME/.local/wine/${bottle}" + # Arguments to the function are dependancies to be installed. + # Get location of mono and gecko. + monoPath="$(find /usr/share/wine/ -maxdepth 1 -type d -name mono 2> /dev/null)" + geckoPath="$(find /usr/share/wine/ -maxdepth 1 -type d -name "gecko" 2> /dev/null)" + if [[ -z "$monoPath" ]]; then + download 'http://dl.winehq.org/wine/wine-mono/6.0.0/wine-mono-6.0.0-x86.msi' + monoPath="${cache}/wine-mono-6.0.0-x86.msi" + fi + if [[ -z "$geckoPath" ]]; then + download 'http://dl.winehq.org/wine/wine-gecko/2.40/wine_gecko-2.40-x86.msi' + geckoPath="${cache}/wine_gecko-2.40-x86.msi" + fi + # This is in a brace list to pipe through dialog. + { echo -n "Using " + ${wine} --version + DISPLAY="" ${wine}boot -u + ${wine} msiexec /i z:"$monoPath" /quiet + ${wine} msiexec /i z:"$geckoPath" /quiet + if [[ "${*}" =~ (speechsdk|sapi) ]]; then + install_rhvoice + fi + if [[ "${WINEARCH}" == "win64" ]]; then + download "https://github.com/RastislavKish/nvda2speechd/releases/download/v0.1/nvda2speechd" + fi + if [[ "${WINEARCH}" == "win64" ]] && [[ ! -f "${XDG_DATA_HOME:-$HOME/.local/share}/audiogame-manager/nvda2speechd" ]]; then + cp "${cache}/nvda2speechd" "${XDG_DATA_HOME:-$HOME/.local/share}/audiogame-manager/nvda2speechd" + chmod +x "${XDG_DATA_HOME:-$HOME/.local/share}/audiogame-manager/nvda2speechd" + fi + winetricks -q isolate_home $@ ${winVer:-winxp} ${winetricksSettings}; } | dialog --progressbox "Installing wine bottle, please wait..." -1 -1 + # make it easy for game scripts to know which version of wine to use. + echo "WINE=\"${WINE}\"" > "$HOME/.local/wine/${bottle}/agm.conf" + echo "WINESERVER=\"${WINESERVER}\"" >> "$HOME/.local/wine/${bottle}/agm.conf" + # If default voice is set, change it for the bottle + if [[ ${#defaultVoice} -ge 2 ]] && [[ "${*}" =~ (speechsdk|sapi) ]]; then + echo "Setting default voice for bottle \"${bottle}\" to \"${defaultVoice}\"." + "${0%/*}/speech/set-voice.sh" -b "${bottle}" -r "${defaultRate:-7}" -v "${defaultVoice}" + fi +} + +add_launcher() { + local launchSettings="${game,,}" + launchSettings="${launchSettings//[[:space:]]/-}|${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 +} diff --git a/.includes/functions.sh b/.includes/functions.sh index 6a39edf..1d98a1d 100644 --- a/.includes/functions.sh +++ b/.includes/functions.sh @@ -22,6 +22,26 @@ check_requirements() { return 0 } +clear_cache() { + local answer + if [[ ! -d "${cache}" ]]; then + echo "No cache found at ${cache}." + return + fi + while ! [[ "${answer,,}" =~ ^yes$|^no$ ]]; do + echo "This will delete all contents of ${cache}. Are you sure you want to continue?" + echo "Please type yes or no." + echo + read -r answer + done + if [[ "$answer" == "no" ]]; then + return + fi + # All safety checks done. Delete the cache. + rm -rfv "${cache}" + echo "Cache deleted." +} + download() { local source=($@) for i in "${source[@]}" ; do @@ -83,6 +103,81 @@ download() { done } +get_installer() { + trap "exit 0" SIGINT + # If the file is in cache nothing else needs to be done. + if [[ -f "${cache}/$1" ]]; then + return + fi + # Create message for dialog. + local message="Make sure $1 is available in either your Downloads or Desktop directory and press enter to continue." + if [[ -n "$2" ]]; then + message+="\n\nThe last good known URL for $game is:" + message+="\n$2" + fi + if echo "$2" | xclip -selection clipboard 2> /dev/null ; then + message+="\n\nThe URL has been copied to the clipboard." + fi + dialog --ok-label "Continue" \ + --backtitle "Audiogame Manager" \ + --msgbox "$message" -1 -1 + # Search the Desktop and Downloads directories for the installation file + for i in ~/Downloads ~/Desktop ; do + find $i -type f -name "$1" -exec cp -v {} "${cache}/" \; + done + # If the file is still not available abort. + if [[ ! -f "${cache}/$1" ]]; then + echo "couldn't find $1. Please download the file and try again." + exit 1 + fi +} + +get_steam() { + # Arguments: $1 id of item for download, $2 url for game + trap "exit 0" SIGINT + echo "manual intervention required." + alert + dialog --backtitle "Audiogame Manager" \ + --yes-label "Continue with Steam" \ + --no-label "Install manually" \ + --extra-button \ + --extra-label "Exit" \ + --yesno "To install the game manually, place files in \"${WINEPREFIX}/drive_c/Program Files/${game}\"" -1 -1 --stdout + case $? in + 0) echo "The next steps will install through steamcmd." ;; + 1) + mkdir -p "${WINEPREFIX}/drive_c/Program Files/${game}" + dialog --backtitle "Audiogame Manager" \ + --msgbox "Place game files in \"${WINEPREFIX}/drive_c/Program Files/${game}\" and press enter to continue." -1 -1 --stdout + return + ;; + *) exit 0 ;; + esac + # Check for steamcmd + if ! command -v steamcmd &> /dev/null ; then + dialog --backtitle "Audiogame Manager" \ + --infobox "This installer requires steamcmd. Please install steamcmd and try again." -1 -1 + exit 1 + fi + # Create message for dialog. + local message="Make sure ${game} is available in your Steam library and press enter to continue. The URL for ${game} is $2" + if echo "$2" | xclip -selection clipboard 2> /dev/null ; then + message+="\n\nThe URL has been copied to the clipboard." + fi + dialog --ok-label "Continue" \ + --backtitle "Audiogame Manager" \ + --msgbox "$message" -1 -1 + # Get Steam user name. + steamUser="$(dialog --ok-label "Continue" \ + --backtitle "Audiogame Manager" \ + --inputbox "Please enter your Steam user name:" -1 -1 --stdout)" + # Download the game + mkdir -p "${WINEPREFIX}/drive_c/Program Files/${game}" + steamcmd +@sSteamCmdForcePlatformType windows +force_install_dir "${WINEPREFIX}/drive_c/Program Files/$game" +login "$steamUser" +app_update "$1" +quit || { dialog --backtitle "Audiogame Manager" \ + --infobox "Something went wrong. Please make sure you have a stable internet connection, and if the problem persists, contact audiogame-manager's developers." -1 -1 + exit 1; } +} + # Function to open urls across OS. open_url() { if [[ "$(uname)" == "Darwin" ]]; then @@ -91,3 +186,13 @@ open_url() { xdg-open "${*}" 2> /dev/null fi } + +unix2dos() { + if [[ $# -eq 0 ]]; then + echo "Usage: unix2dos file(s)." + exit 1 + fi + for file in "$@"; do + sed -i 's/\r\{0,\}$/\r/' "$file" + done +} diff --git a/audiogame-manager.sh b/audiogame-manager.sh index 8bdc0ae..1822ad0 100755 --- a/audiogame-manager.sh +++ b/audiogame-manager.sh @@ -3,352 +3,6 @@ # Dialog accessibility export DIALOGOPTS='--no-lines --visit-items' -# Wine configuration section - -clear_cache() { - local answer - if [[ ! -d "${cache}" ]]; then - echo "No cache found at ${cache}." - return - fi - while ! [[ "${answer,,}" =~ ^yes$|^no$ ]]; do - echo "This will delete all contents of ${cache}. Are you sure you want to continue?" - echo "Please type yes or no." - echo - read -r answer - done - if [[ "$answer" == "no" ]]; then - return - fi - # All safety checks done. Delete the cache. - rm -rfv "${cache}" - echo "Cache deleted." -} - -get_bottle() { - # Handles games that use the same wine bottle - case "${game}" in - # Aprone (Jeremy Kaldobsky) games. - "castaways"*) ;& - "castaways-2"*) ;& - "daytona-and-the-book-of-gold"*) ;& - "dog-who-hates-toast"*) ;& - "lunimals"*) ;& - "paw-prints"*) ;& - "penta-path"*) ;& - "preludeamals"*) ;& - "puzzle-divided"*) ;& - "rettou"*) ;& - "revelation"*) ;& - "swamp"*) ;& - "tarot-assistant"*) ;& - "triple-triad"*) - export WINEPREFIX="${HOME}/.local/wine/aprone" ;; - "bg-"*) export WINEPREFIX="${HOME}/.local/wine/bg";; - # draconis games - "esp-pinball-classic"*) ;& - "esp-pinball-extreme"*) ;& - "esp-pinball-party-pack"*) ;& - "silver-dollar"*) ;& - "monkey-business"*) ;& - "alien-outback"*) ;& - "dyna-man"*) ;& - "change-reaction"*) ;& - "ten-pin-alley"*) export WINEPREFIX="${HOME}/.local/wine/draconis";; - # l-works games group - "duck-hunt"*) ;& - "judgement-day"*) ;& - "lockpick"*) ;& - "pigeon-panic"*) ;& - "smashathon"*) ;& - "super-egg-hunt"*) ;& - "super-liam"*) ;& - "the-great-toy-robbery"*) export WINEPREFIX="${HOME}/.local/wine/l-works";; - # Nyanchan games group - "bokurano-daibouken"*) ;& - "laser-breakout"*) ;& - "marina-break"*) ;& - "mp5"*) ;& - "screaming-strike-2"*) ;& - "world-of-war"*) export WINEPREFIX="${HOME}/.local/wine/nyanchan";; - # Oriol Gomez games group - "bombercats"*) ;& - "copter-mission"*) ;& - "danger-on-the-wheel"*) ;& - "death-on-the-road"*) ;& - "fuck-that-bird"*) ;& - "hammer-of-glory"*) ;& - "insect-therapy"*) ;& - "rhythm-rage"*) ;& - "run-for-your-life"*) ;& - "thief"*) ;& - "villains-from-beyond"*) export WINEPREFIX="${HOME}/.local/wine/oriol-gomez";; - # pbgames group - "dark-destroyer"*) ;& - "PBGames TMP") export WINEPREFIX="$HOME/.local/wine/pbgames" ;; - # tunmi13 games group - "battle-of-the-hunter"*) ;& - "clashes-of-the-sky"*) ;& - "challenge-of-the-horse"*) export WINEPREFIX="${HOME}/.local/wine/tunmi13";; - # tunmi13-64bit games group - "battlefield-2d"*) ;& - "haunted-party"*) ;& - "skateboarder-pro"*) export WINEPREFIX="${HOME}/.local/wine/tunmi13-64bit";; - # Dan Z games group - "lost"*) ;& - "maze-craze"*) ;& - "super-deekout"*) - export norh="true" - export WINEPREFIX="$HOME/.local/wine/dan-z" - ;; - *) export WINEPREFIX="${HOME}/.local/wine/${game%|*}";; - esac - # Wine version for bottles - if [[ "$game" =~ entombed ]]; then - install_wine "6.18" "32" - fi - if [[ "$game" =~ rs-games ]]; then - install_wine "7.0" "32" - fi - if [[ "$game" =~ shadow-line ]]; then - install_wine "7.7" "32" - fi -} - -get_installer() { - trap "exit 0" SIGINT - # If the file is in cache nothing else needs to be done. - if [[ -f "${cache}/$1" ]]; then - return - fi - # Create message for dialog. - local message="Make sure $1 is available in either your Downloads or Desktop directory and press enter to continue." - if [[ -n "$2" ]]; then - message+="\n\nThe last good known URL for $game is:" - message+="\n$2" - fi - if echo "$2" | xclip -selection clipboard 2> /dev/null ; then - message+="\n\nThe URL has been copied to the clipboard." - fi - dialog --ok-label "Continue" \ - --backtitle "Audiogame Manager" \ - --msgbox "$message" -1 -1 - # Search the Desktop and Downloads directories for the installation file - for i in ~/Downloads ~/Desktop ; do - find $i -type f -name "$1" -exec cp -v {} "${cache}/" \; - done - # If the file is still not available abort. - if [[ ! -f "${cache}/$1" ]]; then - echo "couldn't find $1. Please download the file and try again." - exit 1 - fi -} - -get_steam() { - # Arguments: $1 id of item for download, $2 url for game - trap "exit 0" SIGINT - echo "manual intervention required." - alert - dialog --backtitle "Audiogame Manager" \ - --yes-label "Continue with Steam" \ - --no-label "Install manually" \ - --extra-button \ - --extra-label "Exit" \ - --yesno "To install the game manually, place files in \"${WINEPREFIX}/drive_c/Program Files/${game}\"" -1 -1 --stdout - case $? in - 0) echo "The next steps will install through steamcmd." ;; - 1) - mkdir -p "${WINEPREFIX}/drive_c/Program Files/${game}" - dialog --backtitle "Audiogame Manager" \ - --msgbox "Place game files in \"${WINEPREFIX}/drive_c/Program Files/${game}\" and press enter to continue." -1 -1 --stdout - return - ;; - *) exit 0 ;; - esac - # Check for steamcmd - if ! command -v steamcmd &> /dev/null ; then - dialog --backtitle "Audiogame Manager" \ - --infobox "This installer requires steamcmd. Please install steamcmd and try again." -1 -1 - exit 1 - fi - # Create message for dialog. - local message="Make sure ${game} is available in your Steam library and press enter to continue. The URL for ${game} is $2" - if echo "$2" | xclip -selection clipboard 2> /dev/null ; then - message+="\n\nThe URL has been copied to the clipboard." - fi - dialog --ok-label "Continue" \ - --backtitle "Audiogame Manager" \ - --msgbox "$message" -1 -1 - # Get Steam user name. - steamUser="$(dialog --ok-label "Continue" \ - --backtitle "Audiogame Manager" \ - --inputbox "Please enter your Steam user name:" -1 -1 --stdout)" - # Download the game - mkdir -p "${WINEPREFIX}/drive_c/Program Files/${game}" - steamcmd +@sSteamCmdForcePlatformType windows +force_install_dir "${WINEPREFIX}/drive_c/Program Files/$game" +login "$steamUser" +app_update "$1" +quit || { dialog --backtitle "Audiogame Manager" \ - --infobox "Something went wrong. Please make sure you have a stable internet connection, and if the problem persists, contact audiogame-manager's developers." -1 -1 - exit 1; } -} - -install_wine() { - # Requires wine version, e.g. 7.7 and architecture, 32|64 - if [[ $# -ne 2 ]]; then - exit 1 - fi - # Figure out wineInstallationPath - wineInstallationPath="${XDG_DATA_HOME:-$HOME/.local/share}/audiogame-manager/wine_$2/$1" - export wine="${wineInstallationPath}/bin/wine" - # If the path exists, wine should already be installed. - # Just make sure we didn't wind up with a empty directory for some reason - rmdir "${wineInstallationPath}" 2> /dev/null - if [[ -d "${wineInstallationPath}" ]]; then - return - fi - mkdir -p "${wineInstallationPath}" 2> /dev/null - # This probably does not need to be cached, so download to tmp. - installationFile="$(mktemp)" - local v=$2 - v="${v/32/x86}" - v="${v/64/x64}" # Probably wrong, so just a place holder. - # If this goes wrong, bail out - set -e - { curl -L --output "${installationFile}" "https://www.playonlinux.com/wine/binaries/phoenicis/upstream-linux-x86/PlayOnLinux-wine-${1}-upstream-linux-${v}.tar.gz" - tar xf "${installationFile}" -C "${wineInstallationPath}"; } | dialog --progressbox "Installing $2 bit Wine version $1." -1 -1 - set +e -} - - -unix2dos() { - if [[ $# -eq 0 ]]; then - echo "Usage: unix2dos file(s)." - exit 1 - fi - for file in "${@}" ; do - sed -i 's/$/\r/' "${file}" - done -} - - -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 "$HOME/.local/wine/${bottle}/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 - echo "Installing RHVoice ${voiceName^}..." - ${wine} "${cache}/${voiceFile}" & - sleep 20 - ${wine}server -k -} - -install_wine_bottle() { - # 32 bit installations work best and are the default here, if you need to override it, do it in the game specific installation steps. - export WINEARCH="${WINEARCH:-win32}" - # Figure out if we are using a specific version of wine - export wine="${wine:-$(command -v wine)}" - # Set the WINE and WINESERVER environmental variables so winetricks will use the right installation. - export WINE="${wine}" - export WINESERVER="${wine}server" - if [[ -z "$bottle" ]]; then - local bottle="${game,,}" - bottle="${bottle//[[:space:]]/-}" - if [[ -d "$HOME/.local/wine/${bottle}" ]]; then - echo "$HOME/.local/wine/${bottle} exists. Please remove it before running this installer." - exit 1 - fi - fi - export WINEPREFIX="$HOME/.local/wine/${bottle}" - # Arguments to the function are dependancies to be installed. - # Get location of mono and gecko. - monoPath="$(find /usr/share/wine/ -maxdepth 1 -type d -name mono 2> /dev/null)" - geckoPath="$(find /usr/share/wine/ -maxdepth 1 -type d -name "gecko" 2> /dev/null)" - if [[ -z "$monoPath" ]]; then - download 'http://dl.winehq.org/wine/wine-mono/6.0.0/wine-mono-6.0.0-x86.msi' - monoPath="${cache}/wine-mono-6.0.0-x86.msi" - fi - if [[ -z "$geckoPath" ]]; then - download 'http://dl.winehq.org/wine/wine-gecko/2.40/wine_gecko-2.40-x86.msi' - geckoPath="${cache}/wine_gecko-2.40-x86.msi" - fi - # This is in a brace list to pipe through dialog. - { echo -n "Using " - ${wine} --version - DISPLAY="" ${wine}boot -u - ${wine} msiexec /i z:"$monoPath" /quiet - ${wine} msiexec /i z:"$geckoPath" /quiet - if [[ "${*}" =~ (speechsdk|sapi) ]]; then - install_rhvoice - fi - if [[ "${WINEARCH}" == "win64" ]]; then - download "https://github.com/RastislavKish/nvda2speechd/releases/download/v0.1/nvda2speechd" - fi - if [[ "${WINEARCH}" == "win64" ]] && [[ ! -f "${XDG_DATA_HOME:-$HOME/.local/share}/audiogame-manager/nvda2speechd" ]]; then - cp "${cache}/nvda2speechd" "${XDG_DATA_HOME:-$HOME/.local/share}/audiogame-manager/nvda2speechd" - chmod +x "${XDG_DATA_HOME:-$HOME/.local/share}/audiogame-manager/nvda2speechd" - fi - winetricks -q isolate_home $@ ${winVer:-winxp} ${winetricksSettings}; } | dialog --progressbox "Installing wine bottle, please wait..." -1 -1 - # make it easy for game scripts to know which version of wine to use. - echo "WINE=\"${WINE}\"" > "$HOME/.local/wine/${bottle}/agm.conf" - echo "WINESERVER=\"${WINESERVER}\"" >> "$HOME/.local/wine/${bottle}/agm.conf" - # If default voice is set, change it for the bottle - if [[ ${#defaultVoice} -ge 2 ]] && [[ "${*}" =~ (speechsdk|sapi) ]]; then - echo "Setting default voice for bottle \"${bottle}\" to \"${defaultVoice}\"." - "${0%/*}/speech/set-voice.sh" -b "${bottle}" -r "${defaultRate:-7}" -v "${defaultVoice}" - fi -} - - # Install games game_installer() { export LANG="en_US.UTF-8" @@ -421,6 +75,7 @@ game_installer() { # remove games game_removal() { + source .includes/bottle.sh if [[ "$(uname -m)" == "aarch64" ]]; then export wine="${wine:-/usr/bin/wine}" else @@ -481,6 +136,7 @@ game_removal() { # kill games that are stuck kill_game() { + source .includes/bottle.sh if [[ "$(uname -m)" == "aarch64" ]]; then export wine="${wine:-/usr/bin/wine}" else @@ -636,6 +292,7 @@ create_game_array() { game_launcher() { # For use by update scripts that want to source functions in this file. [[ "$agmNoLaunch" == "true" ]] && return + source .includes/bottle.sh pgrep -u "$USER" nvda2speechd &> /dev/null || { if [[ -x ${XDG_DATA_HOME:-$HOME/.local/share}/audiogame-manager/nvda2speechd ]]; then if command -v FEXLoader &> /dev/null ; then @@ -725,34 +382,6 @@ game_launcher() { # main script -#functions - -add_launcher() { - local launchSettings="${game,,}" - launchSettings="${launchSettings//[[:space:]]/-}|${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 -} - trap "exit 0" SIGINT # If display isn't set assume we are launching from console and an X environment is running using display :0 @@ -797,6 +426,8 @@ export nvdaControllerClientDll="${ipfsGateway}/ipfs/QmWu7YdSbKMk1Qm5DKvEA5hk1YuA # Source helper functions +source .includes/bottle.sh # Also sourced in functions that need it +source .includes/desktop.sh source .includes/functions.sh source .includes/help.sh source .includes/update.sh