Compare commits

..

24 Commits

Author SHA1 Message Date
da065e5835 A little more progress on refactor. 2025-06-10 01:54:56 -04:00
e3df3c4485 More games updated for the new system. 2025-05-20 19:11:21 -04:00
737432a63f Set-voice updated to support the new system. Hopefully also more reliable. 2025-05-20 18:46:17 -04:00
6526d40c68 Fixed create_game_array function. 2025-05-20 17:51:20 -04:00
d9ef202b33 more progress, but create_game_array is horribly broken. 2025-05-20 05:13:22 -04:00
faba6bcbcb Work on unifying bottles for wine. Most games should now install to 1 of 2 possible locations, ~/.local/wine32 or ~/.local/wine64. Untested, will probably break a lot of things, do not use yet. 2025-05-19 00:09:35 -04:00
31018bc55f Everything moved to it's new file for now. Cleanup is well under way. Improved the unix2dos function. 2025-05-18 20:50:52 -04:00
6e4d7bae8d More conversion to a modular system. 2025-05-18 20:16:22 -04:00
e892da65c8 First chunk of major refactor. Move code to external files located in .includes. Better code organization and easier to deal with. 2025-05-18 19:12:02 -04:00
d6cfe797bc Latest changes before huge refactor. 2025-05-18 16:39:58 -04:00
50b577d7aa Make sure variables needed for installation scripts are exported. 2025-05-14 13:58:16 -04:00
ef43dca94f Updated the clipboard translater because it could crash on some translations. 2025-05-14 04:36:30 -04:00
a38fc607a8 Updated download link for "Challenge of the Horse". 2025-05-08 23:39:52 -04:00
937b52ffd0 Added tiny game smashathon. Get angry! 2025-05-02 01:22:50 -07:00
4ee362b1c0 Added game constant motion. This is temporary until sam releases a linux version. 2025-05-01 04:17:32 -07:00
f86d25924f links for rhvoice updated. 2025-04-16 00:09:49 -04:00
6dbf578c5a Fixed a problem with the file name for BG Cricket. 2025-02-07 21:27:19 -05:00
ec8bb229f0 Actually close audiogame-manager if escape is pressed instead of trying, and failing, to launch the game. 2025-01-23 16:20:03 -05:00
3d95cefb02 Updated Mist World installer for Wine 10.0. Now requires sapi. 2025-01-23 15:47:47 -05:00
d9c6c80e00 Updated Swamp for wine 10.0. Removed ole32 dependency as it was causing it to fail. If you are on wine 9.0 run WINEPREFIX=~/.local/wine/aprone winetricks -q ole32 If you have problems. 2025-01-23 15:16:41 -05:00
8b8f01f39d Temporary work around for winetricks problems. Be sure to install winetricks with your package manager. 2025-01-20 17:55:23 -05:00
a18b2ec61b Shades 2.0 now works as well 2025-01-19 13:33:58 -08:00
e6cfa00c15 Shades of doom 1.2 is working for me on wine 9.22 2025-01-18 19:18:58 -08:00
0a1a130399 Fixed a bug with the default download check. 2025-01-17 17:36:40 -05:00
68 changed files with 967 additions and 918 deletions

197
.includes/bottle.sh Normal file
View File

@ -0,0 +1,197 @@
get_bottle() {
local architecture="${1/win/}"
export WINEPREFIX="$HOME/.local/wine${architecture}"
# 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 "${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
echo "Installing RHVoice ${voiceName^}..."
${wine} "${cache}/${voiceFile}" &
sleep 20
${wine}server -k
}
install_wine_bottle() {
# Wine defaults to 64, so if you need 32 bit, don't forget export WINEARCH=win32
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"
# Installation paths are based on WINEARCH unless game is set for custom bottle.
local bottle=""
if [[ ${#game} -gt 0 ]]; then
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
if [[ ( -z "$WINEARCH" || "$WINEARCH" == "win64" ) && ! "$*" =~ speechsdk ]]; then
local architecture=64
else
local architecture=32
fi
export WINEPREFIX="$HOME/.local/wine${bottle:+/}${bottle:-$architecture}"
# 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
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:-win7} ${winetricksSettings}
# make it easy for game scripts to know which version of wine to use.
if [[ ${#bottle} -gt 1 ]]; then
echo "WINE=\"${WINE}\"" > "$HOME/.local/wine/${bottle}/agm.conf"
echo "WINESERVER=\"${WINESERVER}\"" >> "$HOME/.local/wine/${bottle}/agm.conf"
echo "Setting default voice for bottle \"${bottle}\" to \"${defaultVoice}\"."
"${0%/*}/speech/set-voice.sh" -b "${bottle}" -r "${defaultRate:-7}" -v "${defaultVoice}"
fi
# If default voice is set, change it for the current architecture
if [[ -z "$bottle" ]]; then
if [[ ${#defaultVoice} -ge 2 ]] && [[ "${*}" =~ (speechsdk|sapi) ]]; then
echo "Setting default voice for wine${architecture}."
"${0%/*}/speech/set-voice.sh" -b "${bottle}" -r "${defaultRate:-7}" -v "${defaultVoice}"
fi
fi
}
add_launcher() {
local launchSettings="${WINEARCH:-win64}|${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
}

109
.includes/checkup.sh Executable file
View File

@ -0,0 +1,109 @@
declare -a errorList
declare -a packageList
if [[ $# -eq 0 ]]; then
echo "Checking your system..."
echo
fi
if command -v wine &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Wine is installed."
else
errorList+=("Critical: Wine is not installed. You will not be able to play any games.")
fi
packageList+=("wine")
if command -v curl &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Curl is installed."
else
errorList+=("Critical: Curl is not installed. Critical functionality will not work.")
fi
packageList+=("curl")
if command -v dialog &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Dialog is installed."
else
errorList+=("Critical: Dialog is not installed. You will not be able to install, launch, or remove any games.")
fi
packageList+=("dialog")
for i in 7z cabextract unzip xz ; do
if command -v $i &> /dev/null ; then
[[ $# -eq 0 ]] && echo "${i^} is installed."
else
errorList+=("Critical: ${i^} is not installed. You will not be able to install some games or their components.")
fi
packageList+=("$i")
done
if command -v gawk &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Gawk is installed."
else
errorList+=("Warning: gawk is not installed. Game removal with -r will not work.")
fi
packageList+=("gawk")
if command -v ocrdesktop &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Ocrdesktop is installed."
else
errorList+=("Warning: ocrdesktop is not installed. It can help if the installer gets stuck to figure out what is happening.")
fi
packageList+=("ocrdesktop")
if command -v qjoypad &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Qjoypad is installed."
else
errorList+=("Warning: qjoypad is not installed. Qjoypad allows you to play keyboard only games with a gamepad.")
fi
packageList+=("qjoypad")
if command -v sox &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Sox is installed."
else
errorList+=("Warning: Sox is not installed. Audio will not work.")
fi
packageList+=("sox")
if command -v trans &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Translate-shell is installed."
else
errorList+=("Warning: translate-shell is not installed. Games that require translation will not be translated.")
fi
packageList+=("translate-shell")
if command -v sqlite3 &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Sqlite3 is installed."
else
errorList+=("Warning: sqlite is not installed. Required for games that need to be translated.")
fi
if command -v perl &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Perl is installed."
else
errorList+=("Warning: perl is not installed. Required for games that need to be translated.")
fi
packageList+=("perl")
packageList+=("sqlite")
if command -v w3m &> /dev/null ; then
[[ $# -eq 0 ]] && echo "W3m is installed."
else
errorList+=("Warning: w3m is not installed. W3m is used to view game documentation.")
fi
packageList+=("w3m")
if command -v xclip &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Xclip is installed."
else
errorList+=("Warning: Xclip is not installed. Some games may not speak or register properly.")
fi
packageList+=("xclip")
if command -v xdotool &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Xdotool is installed."
else
errorList+=("Warning: Xdotool is not installed. Some installers may not work or may need manual intervention.")
fi
packageList+=("xdotool")
# Show the results
if [[ $# -ne 0 ]]; then
for i in "${packageList[@]}" ; do
echo "$i"
done | sort
exit 0
fi
if [[ ${#errorList[@]} -eq 0 ]]; then
echo "No problems found, you are good to go."
exit 0
fi
echo "Errors detected, here is a list along with the severity."
echo "Note that errors marked critical mean that you will not be able to install and play games until they are resolved."
for i in "${errorList[@]}" ; do
echo "$i"
done
exit 0

35
.includes/desktop.sh Normal file
View File

@ -0,0 +1,35 @@
# Create desktop launcher file
desktop_launcher() {
local desktopFile="${HOME}/audiogame-manager.desktop"
if [[ -e "${desktopFile}" ]]; then
echo "the file ${desktopFile} exists. Cannot create the launcher."
exit 1
fi
local dotDesktop
local terminal
# Try to find an accessible terminal
for i in mate-terminal lxterminal terminator gnome-terminal ; do
if command -v $i &> /dev/null ; then
terminal="$i"
break
fi
done
dotDesktop=('[Desktop Entry]'
'Name=Audiogame manager'
'GenericName=Audiogame Manager'
'Comment=Play audio games'
"Exec=${terminal} -t \"Audiogame Manager\" -e \"/usr/bin/bash -c 'nohup $(readlink -e "$0") 2> /dev/null'\""
'Terminal=false'
'Type=Application'
'StartupNotify=false'
'Keywords=game;'
'Categories=Game;'
'Version=1.0')
for i in "${dotDesktop[@]}" ; do
echo "$i" >> "${desktopFile}"
done
desktop-file-install --dir "${HOME}/.local/share/applications" -m 755 "${desktopFile}"
xdg-desktop-icon install ~/.local/share/applications/audiogame-manager.desktop
rm "${desktopFile}"
exit 0
}

198
.includes/functions.sh Normal file
View File

@ -0,0 +1,198 @@
# Alerts, for when user needs to read something.
alert() {
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
echo
read -rp "Press enter to continue." continue
}
check_requirements() {
# Make sure the minimum of curl, sox, wine, and winetricks are installed or fex-emu on aarch64
if [[ "$(uname -m)" == "aarch64" ]]; then
minimumDependencies=("FEXLoader")
wine="FEXLoader -- /usr/bin/wine"
else
minimumDependencies=("curl" "sox" "wine")
fi
for i in "${minimumDependencies[@]}" ; do
if ! command -v $i &> /dev/null ; then
echo "Please install $i before continuing."
return 1
fi
done
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
local dest="${i##*/}"
dest="${dest//%20/ }"
dest="${dest#*\?filename=}"
dest="${dest%\?*}"
# Remove the destination file if it is empty.
[[ -s "${cache}/${dest}" ]] || rm -f "${cache}/${dest}" 2> /dev/null
if [[ "${redownload}" == "true" ]] && [[ -e "${cache}/${dest}" ]]; then
rm -v "${cache}/${dest}"
fi
# Skip if the item is in cache.
[[ -e "${cache}/${dest}" ]] && continue
{ if ! curl -L4 -C - --retry 10 --output "${cache}/${dest}" "${i}" ; then
echo "Could not download \"$i\"..."
exit 1
fi; } | dialog --backtitle "Audio Game Manager" \
--progressbox "Downloading \"$dest\" from \"$i\"" -1 -1
local downloadError=1
case "${dest##*.}" in
"pk3"|"zip")
unzip -tq "${cache}/${dest}" | dialog --backtitle "Audio Game Manager" \
--progressbox "Validating ${dest##*.} file" -1 -1 --stdout
downloadError=$?
;;
"7z")
7z t "${cache}/${dest}" | dialog --backtitle "Audio Game Manager" \
--progressbox "Validating 7z file" -1 -1 --stdout
downloadError=$?
;;
"exe")
# Check if it's a valid Windows executable by looking at the MZ header
hexdump -n 2 -v -e '/1 "%02X"' "${cache}/${dest}" | grep -q "4D5A"
downloadError=$?
;;
"wad")
if [[ "$(file -b --mime-type "${cache}/${dest}")" != "application/octet-stream" ]]; then
downloadError=0
fi
;;
*)
# Add HTML check for other file types
if file -b "${cache}/${dest}" | grep -q "HTML document" ; then
echo "File not found: \"$i\" (HTML document probably 404)"
downloadError=1
else
downloadError=0
fi
;;
esac
if [[ $downloadError -ne 0 ]]; then
rm -fv "${cache}/${dest}"
dialog --backtitle "Audio Game Manager" \
--infobox "Error downloading \"${dest}\". Installation cannot continue." -1 -1 --stdout
alert
exit 1
fi
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
open "${*}" 2> /dev/null
else
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
}

125
.includes/help.sh Normal file
View File

@ -0,0 +1,125 @@
documentation() {
if [[ "$2" == "Become a Patron" ]]; then
return
fi
if [[ "$2" == "Donate" ]]; then
return
fi
if ! command -v w3m &> /dev/null ; then
echo "This feature of audiogame-manager requires w3m. Please install it before continuing."
exit 1
fi
get_bottle "$1"
echo "Loading documentation, please wait..."
# Try to find documentation based on common naming conventions.
local gamePath="$(winepath -u "$2" 2> /dev/null)"
gamePath="${gamePath%/*}"
local gameDoc="$(find "$gamePath" -type f -iname 'user_manual.htm*' -or -iname 'user manual.htm*' -or -iname '*user guide.htm*' | head -1)"
# Game name specific docs, add the name to the for loop.
if [[ -z "$gameDoc" ]]; then
for i in "troopanum.txt" "superdeekout.txt" scw.html ; do
gameDoc="$(find "$gamePath" -type f -iname "$i" -or -iname 'manual.htm' | head -1)"
done
fi
if [[ -z "$gameDoc" ]]; then
gameDoc="$(find "$gamePath" -type f -path '*/Manual/index.html' | head -1)"
fi
if [[ -z "$gameDoc" ]]; then
gameDoc="$(find "$gamePath" -type f -iname '[A-Z]*Help.htm' -or -iname '[A-Z]*Help.html' | head -1)"
fi
if [[ -z "$gameDoc" ]]; then
gameDoc="$(find "$gamePath" -type f -iname 'manual.html' -or -iname 'manual.htm' | head -1)"
fi
if [[ -z "$gameDoc" ]]; then
gameDoc="$(find "$gamePath" -type f -iname 'en.html' -or -iname 'en.htm' | head -1)"
fi
if [[ -z "$gameDoc" ]]; then
gameDoc="$(find "$gamePath" -type f -iname 'readme.html' -or -iname 'readme.htm' | head -1)"
fi
if [[ -z "$gameDoc" ]]; then
gameDoc="$(find "$gamePath" -type f -iname 'manual.txt' | head -1)"
fi
if [[ -z "$gameDoc" ]]; then
gameDoc="$(find "$gamePath" -type f -iname 'readme.txt' -or -iname 'help.txt' | head -1)"
fi
if [[ -z "$gameDoc" ]]; then
gameDoc="$(find "$gamePath" -type f -iname '*.url' -exec grep -i 'url=' {} \; | grep -iv 'score' | head -1)"
gameDoc="${gameDoc#*=}"
gameDoc="${gameDoc//[[:cntrl:]]/}"
fi
# Display documentation if available.
if [[ -n "$gameDoc" ]]; then
w3m "$gameDoc"
else
echo "No documentation found."
fi
exit 0
}
help() {
echo "${0##*/}"
echo "Released under the terms of the Common Public Attribution License Version 1.0"
echo -e "This is a Stormux project: https://stormux.org\n"
echo -e "Usage:\n"
echo "With no arguments, open the game launcher."
for i in "${!command[@]}" ; do
echo "-${i/:/ <parameter>}: ${command[${i}]}"
done | sort
echo
echo "Some settings that are often used can be stored in a settings.conf file."
echo "If wanted, place it at the following location:"
echo "${configFile%/*}/settings.conf"
echo "The syntax is variable=\"value\""
echo
echo "ipfsGateway=\"https://ipfs.stormux.org\" # Gateway to be used for ipfs downloads."
echo "noCache=\"true\" # Do not keep downloaded items in the cache."
echo "noqjoypad=\"true\" # Do not launch qjoypad."
echo "norh=\"true\" # Do not install RHVoice."
echo "redownload=\"true\" # Redownload sources, do not use the version stored in cache."
echo "voiceName=\"voicename\" # Select the voice to be installed (default Bdl)."
echo "defaultVoice=\"voicename\" # Select the default voice to use for the bottle, e.g. MSMike or RHVoice."
echo "defaultRate=\"Default voice rate for the bottle, default 7, may not work in all games. Values 1-9 or A."
echo "winedebug=\"flag(s)\" # Set wine debug flags, useful for development."
exit 0
}
license() {
cat << EOF
■The contents of this file are subject to the Common Public Attribution
License Version 1.0 (the ■License■); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
https://opensource.org/licenses/CPAL-1.0. The License is based on the Mozilla Public License Version
1.1 but Sections 14 and 15 have been added to cover use of software over a
computer network and provide for limited attribution for the Original
Developer. In addition, Exhibit A has been modified to be consistent with
Exhibit B.
Software distributed under the License is distributed on an ■AS IS■ basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is audiogame manager.
The Original Developer is not the Initial Developer and is . If
left blank, the Original Developer is the Initial Developer.
The Initial Developer of the Original Code is Billy "Storm Dragon" Wolfe. All portions of
the code written by Billy Wolfe are Copyright (c) 2020, 2024. All Rights
Reserved.
Contributor Michael Taboada.
Attribution Copyright Notice: Audiogame manager copyright 2020 Storm Dragon. All rights reserved.
Attribution Phrase (not exceeding 10 words): A Stormux project
Attribution URL: https://stormgames.wolfe.casa
Graphic Image as provided in the Covered Code, if any.
Display of Attribution Information is required in Larger
Works which are defined in the CPAL as a work which combines Covered Code
or portions thereof with code not governed by the terms of the CPAL.
EOF
}

46
.includes/update.sh Normal file
View File

@ -0,0 +1,46 @@
# Check for latest news
check_news() {
# For use by update scripts that want to source functions in this file.
[[ "$agmNoLaunch" == "true" ]] && return
trap return INT
# url for news file
local newsFile="https://stormgames.wolfe.casa/media/agm.ogg"
local newsPath="${configFile%/*.conf}/.news"
local newsTag="$(curl --connect-timeout 5 -sI "$newsFile" | grep -i '^etag: "' | cut -d '"' -f2)"
if [[ -z "${newsTag}" ]]; then
return
fi
local newsOldTag="$(cat "$newsPath" 2> /dev/null)"
if [[ "$newsTag" != "$newsOldTag" ]]; then
dialog --yes-label 'Play' \
--no-label 'Later' \
--backtitle 'Audiogame Manager News' \
--yesno 'Audiogame manager news is available. Please use left and right arrows to navigate and enter to confirm.' -1 -1 || return
sox -qV0 "$newsFile" -d &> /dev/null
echo -n "$newsTag" > "$newsPath"
fi
}
# Automatic update function
# Automatic update function
update() {
if ! [[ -d ".git" ]]; then
return
fi
local url="$(git ls-remote --get-url)"
if [[ "$url" =~ ^ssh://|git@|gitea@ ]] || [[ -z "$url" ]]; then
return
fi
git remote update &> /dev/null
local upstream='@{u}'
local home="$(git rev-parse @)"
local remote="$(git rev-parse "$upstream")"
if [[ "$home" == "$remote" ]]; then
return
fi
dialog --backtitle "Audiogame Manager" \
--yesno "Updates are available. Would you like to update now?" -1 -1 --stdout || return
{ git pull
git log '@{1}..' --pretty=format:'%an: %s' | tac; }
exit $?
}

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmQiocMpMXoxejDftKKvmrR5xxpj1qcWcgkhBBwTcyijXg?filename=FPB32Setup10a.exe"
install_wine_bottle speechsdk
wine "${cache}/FPB32Setup10a.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmPNt3c78UBgEMrTH3eJ5eD2mCMdth6jwes1iDKGW24Uj5?filename=BG204832Setup10a.exe"
install_wine_bottle speechsdk
wine "${cache}/BG204832Setup10a.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmTshtHBEV9dh7wFtaQpNUEYHZ3fBpuhSRZqc7k8HwmtPM?filename=ASB32Setup10.exe"
install_wine_bottle speechsdk
wine "${cache}/ASB32Setup10.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/Qma76HXBhmKgMDeHH1XLePsaWzzzLsBS2HRL3c7MVwDokg?filename=BAC32Setup10.exe"
install_wine_bottle speechsdk
wine "${cache}/BAC32Setup10.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/Qmaq9P9fxdLTEFMGg4mhHrRuUbPg6HgU3eYVJNqZUimHjo?filename=BGB32Setup10.exe"
install_wine_bottle speechsdk
wine "${cache}/BGB32Setup10.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmQwWiJw9hDiPdfwDyL4XepeoD66ztVRi3HwbSjFFP4CNg?filename=BGB32Setup10a.exe"
install_wine_bottle speechsdk
wine "${cache}/BGB32Setup10a.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmRn21tREXxXVSaDe9i54zEPzPSespjJAFBqu4DWocuagD?filename=BXB32Setup10.exe"
install_wine_bottle speechsdk
wine "${cache}/BXB32Setup10.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmWEdmTkQsjSqBgWUgnDajMf8QvQBbEF4Nxo6mhkXYzBtQ?filename=BRN32Setup10a.exe"
install_wine_bottle speechsdk
wine "${cache}/BRN32Setup10a.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmT2yBpU5Jqna18FxYtyWzi4xMGAY9PyJWStAskxCHqBDw?filename=BGC32Setup10d.exe"
install_wine_bottle speechsdk
wine "${cache}/BGC32Setup10d.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmU486SssAdM7kPKwDyAKDLQs3Z92bG6wFjaLhzqDZCxAF?filename=BCB32Setup10.exe"
install_wine_bottle speechsdk
wine "${cache}/BCB32Setup10.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmbRUiknnNcibWD3NwK4DFZGNHWswBgsFidUzU1TFGJ5Ra?filename=BCS32Setup10.exe"
install_wine_bottle speechsdk
wine "${cache}/BCS32Setup10.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmeFud3EPHy7wQe8UENgvh96HdAazEkwqA2AutCNkYvB3t?filename=BGC32Setup12e.exe"
install_wine_bottle speechsdk
wine "${cache}/BGC32Setup12e.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmZQGY9CeATEiWrSqsKBz4AN6jPgQuvbBZSpQoLiMjoDr2?filename=BGX32Setup10h.exe"
install_wine_bottle speechsdk
wine "${cache}/BGX32Setup10h.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmZQGY9CeATEiWrSqsKBz4AN6jPgQuvbBZSpQoLiMjoDr2?filename=BDD32Setup.exe"
install_wine_bottle speechsdk
wine "${cache}/BDD32Setup.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmWWZByYL5CsDSi6gQLGcMyBL7zqD5hWXbPXJr3shRt5AQ?filename=ESB32Setup10.exe"
install_wine_bottle speechsdk
wine "${cache}/ESB32Setup10.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmSZt6dz7WQkNrFBmYq9n4WdYrrZyQAebTBPo46uHqCuNi?filename=BFD32Setup10.exe"
install_wine_bottle speechsdk
wine "${cache}/BFD32Setup10.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmVfQMMnqTD9Zm8Xwv7rGrUTdS9FXToq7Fv6wtQQVgbQGR?filename=BGF32Setup20.exe"
install_wine_bottle speechsdk
wine "${cache}/BGF32Setup20.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmfAp9EYou1pndLwYSdpYdUCHBv2DR94oFccQh1ii9JVLD?filename=GSB32Setup10a.exe"
install_wine_bottle speechsdk
wine "${cache}/GSB32Setup10a.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmXTPMmvw7JE2eLuPBLGSpkZqUn12TX7QEQZbX8qtp7GBx?filename=HMB32Setup10.exe"
install_wine_bottle speechsdk
wine "${cache}/HMB32Setup10.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmdU5ag1PRjvG28wNX7aNuJqZSVxaqEEKjgG6GoRoDT8k4?filename=BGH32Setup10b.exe"
install_wine_bottle speechsdk
wine "${cache}/${BGH32Setup10b.exe}" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmctBDvhQWwER94LvgauR7sMDxv9D1mS9cToV47orTCdzU?filename=BGK32Setup10b.exe"
install_wine_bottle speechsdk
wine "${cache}/BGK32Setup10b.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/Qma5WeCC9B2P5abRGX9nGYV8Zi9F8vfCCr4ehejP2bgmNm?filename=LAP32Setup10.exe"
install_wine_bottle speechsdk
wine "${cache}/LAP32Setup10.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmP6cwMbirbBqAaG9JLfNRnD2dvJfh6nq74kfwxs5hN2RQ?filename=BMM32Setup10.exe"
install_wine_bottle speechsdk
wine "${cache}/BMM32Setup10.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmRa54HroWjwxHYfKr6hdmP34sHW5G3ecuzcjMA5UBBVKa?filename=MSB32Setup10.exe"
install_wine_bottle speechsdk
wine "${cache}/MSB32Setup10.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/Qmb7eGTMDgiaDC9muMW9n8bHoistGcNm1VgHc6sr7dRyHU?filename=BNW32Setup10a.exe"
install_wine_bottle speechsdk
wine "${cache}/BNW32Setup10a.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmXKvQ6WNNSnDiSyYmvAhZXVdALnuhUGK7dSMQVkQNReJr?filename=BPS32Setup10c.exe"
install_wine_bottle speechsdk
wine "${cache}/BPS32Setup10c.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmPLv74LiDgVGuiGhu9HuPhx3uoMm9QyCYk6jgeFUHjj3S?filename=BPS32Setup10.exe"
install_wine_bottle speechsdk
wine "${cache}/BPS32Setup10.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmaqXaBKD3xY2smhU2LcejXRTPnWZHqaTW9se8yRepLsHu?filename=PSB32Setup10a.exe"
install_wine_bottle speechsdk
wine "${cache}/PSB32Setup10a.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmSxJs2MiLQ61Fgx6vCpSD7GmQziLiCEU3sZ3mgWc7RsJ8?filename=BSS32Setup10.exe"
install_wine_bottle speechsdk
wine "${cache}/BSS32Setup10.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmVrwyPdJBnmc4wLW7oT2hexxXnXxs8bA7gfiqbnJsWJ16?filename=BGS32Setup20.exe"
install_wine_bottle speechsdk
wine "${cache}/BGS32Setup20.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmXtBCqB6VCFPaDYuLaFNP1BDtJSLCJdJZzgm61zMtrsQt?filename=BGS32Setup10.exe"
install_wine_bottle speechsdk
wine "${cache}/BGS32Setup10.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmdWBaDnLVbKCJSpiqF675ew6nJ6KHUVXA5FEH3t3E7UAu?filename=SPB32Setup10b.exe"
install_wine_bottle speechsdk
wine "${cache}/SPB32Setup10b.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmXCAHEVRGZBc8t45Jgn2vkxicwF9Aox6yz9XrQBdkv7WY?filename=SDB32Setup10a.exe"
install_wine_bottle speechsdk
wine "${cache}/SDB32Setup10a.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmYoiFQ6JuSXfZfZXT3SQDsYzMWLBu9rW9yivi1xiPjqZx?filename=SDB32Setup10a.exe"
install_wine_bottle speechsdk
wine "${cache}/SDB32Setup10a.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmWJGvSR6iaQfMHM3XuGCkWxx285jkzSDdNSvvk3bSCH8S?filename=TPB32Setup10a.exe"
install_wine_bottle speechsdk
wine "${cache}/TPB32Setup10a.exe" /silent

View File

@ -1,5 +1,5 @@
export bottle="bg"
download "${ipfsGateway}/ipfs/QmWAk2TMHMvW6Kjc1sZBEPsxmCNHfY3nF1K723PCqaTa57?filename=TPB32Setup10a.exe"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmWAk2TMHMvW6Kjc1sZBEPsxmCNHfY3nF1K723PCqaTa57?filename=T20B32Setup10.exe"
install_wine_bottle speechsdk
wine "${cache}/T20B32Setup10.exe" /silent
add_launcher "c:\Program Files\Games\T20CricketB\CricketB.exe"

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmVsfPkebSoTDwYSXF1n7y4P9eGJTgTcGXdrEjpcV8A3Dv?filename=BGU32Setup11a.exe"
install_wine_bottle speechsdk
wine "${cache}/BGU32Setup11a.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmXtR49EZShyj15Tc9CXQpBYVmKNfZpp4515Epm16bviuH?filename=BWB32Setup10.exe"
install_wine_bottle speechsdk
wine "${cache}/BWB32Setup10.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmfTgfRzd4JMRqKSfDiz76iMorkaG19BqH1K7nRCCDwo4H?filename=WCB32Setup10a.exe"
install_wine_bottle speechsdk
wine "${cache}/WCB32Setup10a.exe" /silent

View File

@ -1,5 +1,5 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmYQWZZifzKJSuVRCC1SabwRmEDz95GdFvbzRvsBMmTt6e?filename=BWJ32Setup10.exe"
install_wine_bottle speechsdk
wine "${cache}/BWJ32Setup10.wineExec" /silent
wine "${cache}/BWJ32Setup10.exe" /silent
add_launcher "c:\Program Files\Games\WordJumbleB\WordJumbleB.exe"

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmXPtj5PkVZjXpU3m6FAfm8MwVL6bQCvhEDoR385u6FGTL?filename=BWM32Setup10.exe"
install_wine_bottle speechsdk
wine "${cache}/BWM32Setup10.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmZp73ARDPqgnCz7zxfKeBHjNoHrgZSgg2NdQZR2sMyZGD?filename=WSB32Setup10.exe"
install_wine_bottle speechsdk
wine "${cache}/WSB32Setup10.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmWWZFXVHNtmNkH55oermWWtrMcQ8qVqL687B7kGFyeezq?filename=WTB32Setup10a.exe"
install_wine_bottle speechsdk
wine "${cache}/WTB32Setup10a.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmdicAVDegDktY3euVAC2PPn4YBGz96KedxYXNe4WDQaoq?filename=BWY32Setup10.exe"
install_wine_bottle speechsdk
wine "${cache}/BWY32Setup10.exe" /silent

View File

@ -1,4 +1,4 @@
export bottle="bg"
export WINEARCH="win32"
download "${ipfsGateway}/ipfs/QmZebvkKgFAADnb1cgW6Bz7wTYdUh82X61QdtW66KcvmpF?filename=BGY32Setup10a.exe"
install_wine_bottle speechsdk
wine "${cache}/BGY32Setup10a.exe" /silent

View File

@ -1,4 +1,4 @@
download "http://tunmi13.ddns.net/projects/bth.zip"
download "http://files.tunmi13.com/projects_archive/bth.zip"
export bottle="tunmi13"
export winVer="win7"
install_wine_bottle speechsdk

View File

@ -1,5 +1,4 @@
download "${ipfsGateway}/ipfs/QmcTCTMep4zp5zTw8ZaXYpjtu9inNPn8bNzwhW6cX97egw?filename=bloodshed.exe"
export winVer="win7"
install_wine_bottle speechsdk
cp "${cache}/bloodshed.exe" "$WINEPREFIX/drive_c/Program Files/"
add_launcher "c:\Program Files\bloodshed.exe"

View File

@ -1,7 +1,6 @@
export WINEARCH=win64
get_installer "bounce_bounce.rar" "https://kavyapriya.itch.io/bounce-bounce"
download "https://github.com/RastislavKish/nvda2speechd/releases/download/v0.1/nvda2speechd64.dll"
export winVer="win7"
export WINEARCH=win64
install_wine_bottle
unrar x "${cache}/bounce_bounce.rar" -op"$WINEPREFIX/drive_c/Program Files"
find "${WINEPREFIX}/drive_c/Program Files/bounce_bounce" -type f -name 'nvdaControllerClient64.dll' -exec cp -v "${cache}/nvda2speechd64.dll" "{}" \;

View File

@ -1,4 +1,4 @@
download "http://tunmi13.ddns.net/projects/coth.zip"
download "http://files.tunmi13.com/projects_archive/coth.zip"
export bottle="tunmi13"
export winVer="win7"
install_wine_bottle speechsdk

View File

@ -0,0 +1,7 @@
export WINEARCH=win64
export winVer="win7"
download "https://samtupy.com/games/cm.zip" "https://github.com/RastislavKish/nvda2speechd/releases/download/v0.1/nvda2speechd64.dll"
install_wine_bottle
unzip -d "$WINEPREFIX/drive_c/Program Files/ConstantMotion" "$cache/cm.zip"
find "$WINEPREFIX/drive_c/Program Files/ConstantMotion" -name "nvdaControllerClient64.dll" -exec cp -v "$cache/nvda2speechd64.dll" "{}" \;
add_launcher 'c:\Program Files\ConstantMotion\cm.exe'

View File

@ -1,7 +1,7 @@
export winVer="win7"
get_installer "Mist World_Setup.exe" "https://drive.google.com/uc?export=download&id=12YeUqorkkMT46ZSR5pcfWxSY8DHOLxZ-"
download "https://github.com/RastislavKish/nvda2speechd/releases/download/v0.1/nvda2speechd32.dll"
install_wine_bottle ole32
install_wine_bottle sapi
7z x -o"$WINEPREFIX/drive_c/Program Files/Mist World" "$cache/Mist World_Setup.exe"
sed -i 's/1024m/768m/g' "$WINEPREFIX/drive_c/Program Files/Mist World/mw.exe.vmoptions"
cp "$WINEPREFIX/drive_c/Program Files/Mist World/"{mw.exe.vmoptions,update.exe.vmoptions}

View File

@ -1,8 +1,5 @@
export version="7.0"
download "http://rsgames.org/rsdownloads/rsgclient/rsgames-client-setup-2.01.exe" "${nvdaControllerClientDll}"
install_wine "$version" "32"
export winVer="win7"
install_wine_bottle speechsdk
${wine} "${cache}/rsgames-client-setup-2.01.exe" /silent
find "${WINEPREFIX}" -type f -name 'nvdaControllerClient32.dll' -exec cp -v "${cache}/nvdaControllerClient32.dll" "{}" \;
find "${WINEPREFIX}/drive_c/Program Files/RS Games Client" -type f -name 'nvdaControllerClient32.dll' -exec cp -v "${cache}/nvdaControllerClient32.dll" "{}" \;
add_launcher "c:\Program Files\RS Games Client\rsg.exe"

View File

@ -1,4 +1,3 @@
#
download "http://gmagames.com/sod1208.exe"
install_wine_bottle vb6run dx8vb speechsdk
wine "${cache}/sod1208.exe" /sp- /verysilent

View File

@ -1,5 +1,5 @@
export winVer="win7"
download "http://www.gmagames.com/sod20022.exe"
download "http://www.gmagames.com/sod20024.exe"
install_wine_bottle vb6run dx8vb speechsdk
wine "${cache}/sod20022.exe" /silent
wine "${cache}/sod20024.exe" /silent
add_launcher "c:\Program Files\Shades of Doom 2.0\sod.exe"

5
.install/Smashathon.sh Normal file
View File

@ -0,0 +1,5 @@
export bottle="l-works"
download "https://agarchive.net/games/lworks/Smashathon0.02.zip"
install_wine_bottle speechsdk
unzip -d "$WINEPREFIX/drive_c/Program Files" "$cache/Smashathon0.02.zip"
add_launcher 'c:\Program Files\Smashathon0.02\smashathon.exe'

View File

@ -1,5 +1,5 @@
export bottle="l-works"
download "http://files.l-works.net/superegghuntsetup.exe"
download "https://agarchive.net/games/lworks/super%20egg%20hunt+%20setup.exe"
install_wine_bottle
wine "${cache}/superegghuntsetup.exe" /silent
wine "${cache}/super egg hunt+ setup.exe" /silent
add_launcher "c:\Program Files\Lworks\super egg hunt\superegghunt.exe"

View File

@ -4,7 +4,7 @@ export winetricksSettings="vd=1024x768"
dialog --backtitle "Audiogame manager" --yesno "If you do not have a full 32 bit gstreamer installation, the Swamp music can cause stuttering and crashes. Would you like to remove the music directory after installation?" -1 -1 --stdout
deleteMusic=$?
download "https://www.kaldobsky.com/audiogames/Swamp.zip"
install_wine_bottle dx8vb quartz corefonts vb6run speechsdk ole32
install_wine_bottle dx8vb quartz corefonts vb6run speechsdk
unzip -d "$WINEPREFIX/drive_c/Program Files/swamp" "${cache}/Swamp.zip"
# make sure the latest version is installed.
if curl -L --output "${cache}/SwampPatch.zip" "https://www.kaldobsky.com/audiogames/SwampPatch.zip" ; then

7
.install/Toy Mania.sh Normal file
View File

@ -0,0 +1,7 @@
export WINEARCH=win64
export winVer="win7"
get_installer "ToyMania_windows_portable_password_is_GrateCollector.7z" "https://tsatria03.itch.io/toymania"
install_wine_bottle
7z x -o"$WINEPREFIX/drive_c/Program Files/ToyMania" "${cache}/ToyMania_windows_portable_password_is_GrateCollector.7z" -pGrateCollector
find "${WINEPREFIX}/drive_c/Program Files/ToyMania" -type f -name 'nvdaControllerClient64.dll' -exec cp -v "${cache}/nvda2speechd64.dll" "{}" \;
add_launcher "c:\Program Files\ToyMania\tm.exe"

View File

@ -1,4 +1,3 @@
#
export WINEARCH=win64
export winVer="win7"
download "https://dl.dropbox.com/scl/fi/ukvou0y4gwg21nhhdpj40/Wave-of-the-Undead-Setup.exe?rlkey=4xnuwicpmbkx6w2jo2i56mijg" "https://github.com/RastislavKish/nvda2speechd/releases/download/v0.1/nvda2speechd64.dll"

View File

@ -1,748 +1,8 @@
#!/usr/bin/env bash
license() {
cat << EOF
■The contents of this file are subject to the Common Public Attribution
License Version 1.0 (the ■License■); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
https://opensource.org/licenses/CPAL-1.0. The License is based on the Mozilla Public License Version
1.1 but Sections 14 and 15 have been added to cover use of software over a
computer network and provide for limited attribution for the Original
Developer. In addition, Exhibit A has been modified to be consistent with
Exhibit B.
Software distributed under the License is distributed on an ■AS IS■ basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is audiogame manager.
The Original Developer is not the Initial Developer and is . If
left blank, the Original Developer is the Initial Developer.
The Initial Developer of the Original Code is Billy "Storm Dragon" Wolfe. All portions of
the code written by Billy Wolfe are Copyright (c) 2020, 2024. All Rights
Reserved.
Contributor Michael Taboada.
Attribution Copyright Notice: Audiogame manager copyright 2020 Storm Dragon. All rights reserved.
Attribution Phrase (not exceeding 10 words): A Stormux project
Attribution URL: https://stormgames.wolfe.casa
Graphic Image as provided in the Covered Code, if any.
Display of Attribution Information is required in Larger
Works which are defined in the CPAL as a work which combines Covered Code
or portions thereof with code not governed by the terms of the CPAL.
EOF
}
# Dialog accessibility
export DIALOGOPTS='--no-lines --visit-items'
# Alerts, for when user needs to read something.
alert() {
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
echo
read -rp "Press enter to continue." continue
}
# Check for latest news
check_news() {
# For use by update scripts that want to source functions in this file.
[[ "$agmNoLaunch" == "true" ]] && return
trap return INT
# url for news file
local newsFile="https://stormgames.wolfe.casa/media/agm.ogg"
local newsPath="${configFile%/*.conf}/.news"
local newsTag="$(curl --connect-timeout 5 -sI "$newsFile" | grep -i '^etag: "' | cut -d '"' -f2)"
if [[ -z "${newsTag}" ]]; then
return
fi
local newsOldTag="$(cat "$newsPath" 2> /dev/null)"
if [[ "$newsTag" != "$newsOldTag" ]]; then
dialog --yes-label 'Play' \
--no-label 'Later' \
--backtitle 'Audiogame Manager News' \
--yesno 'Audiogame manager news is available. Please use left and right arrows to navigate and enter to confirm.' -1 -1 || return
sox -qV0 "$newsFile" -d &> /dev/null
echo -n "$newsTag" > "$newsPath"
fi
}
# Automatic update function
# Automatic update function
update() {
if ! [[ -d ".git" ]]; then
return
fi
local url="$(git ls-remote --get-url)"
if [[ "$url" =~ ^ssh://|git@|gitea@ ]] || [[ -z "$url" ]]; then
return
fi
git remote update &> /dev/null
local upstream='@{u}'
local home="$(git rev-parse @)"
local remote="$(git rev-parse "$upstream")"
if [[ "$home" == "$remote" ]]; then
return
fi
dialog --backtitle "Audiogame Manager" \
--yesno "Updates are available. Would you like to update now?" -1 -1 --stdout || return
{ git pull
git log '@{1}..' --pretty=format:'%an: %s' | tac; }
exit $?
}
# Function to open urls across OS.
open_url() {
if [[ "$(uname)" == "Darwin" ]]; then
open "${*}" 2> /dev/null
else
xdg-open "${*}" 2> /dev/null
fi
}
# Create desktop launcher file
desktop_launcher() {
local desktopFile="${HOME}/audiogame-manager.desktop"
if [[ -e "${desktopFile}" ]]; then
echo "the file ${desktopFile} exists. Cannot create the launcher."
exit 1
fi
local dotDesktop
local terminal
# Try to find an accessible terminal
for i in mate-terminal lxterminal terminator gnome-terminal ; do
if command -v $i &> /dev/null ; then
terminal="$i"
break
fi
done
dotDesktop=('[Desktop Entry]'
'Name=Audiogame manager'
'GenericName=Audiogame Manager'
'Comment=Play audio games'
"Exec=${terminal} -t \"Audiogame Manager\" -e \"/usr/bin/bash -c 'nohup $(readlink -e "$0") 2> /dev/null'\""
'Terminal=false'
'Type=Application'
'StartupNotify=false'
'Keywords=game;'
'Categories=Game;'
'Version=1.0')
for i in "${dotDesktop[@]}" ; do
echo "$i" >> "${desktopFile}"
done
desktop-file-install --dir "${HOME}/.local/share/applications" -m 755 "${desktopFile}"
xdg-desktop-icon install ~/.local/share/applications/audiogame-manager.desktop
rm "${desktopFile}"
exit 0
}
# Wine configuration section
checklist() {
declare -a errorList
declare -a packageList
if [[ $# -eq 0 ]]; then
echo "Checking your system..."
echo
fi
if command -v wine &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Wine is installed."
else
errorList+=("Critical: Wine is not installed. You will not be able to play any games.")
fi
packageList+=("wine")
if command -v curl &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Curl is installed."
else
errorList+=("Critical: Curl is not installed. Critical functionality will not work.")
fi
packageList+=("curl")
if command -v dialog &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Dialog is installed."
else
errorList+=("Critical: Dialog is not installed. You will not be able to install, launch, or remove any games.")
fi
packageList+=("dialog")
for i in 7z cabextract unzip xz ; do
if command -v $i &> /dev/null ; then
[[ $# -eq 0 ]] && echo "${i^} is installed."
else
errorList+=("Critical: ${i^} is not installed. You will not be able to install some games or their components.")
fi
packageList+=("$i")
done
if command -v gawk &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Gawk is installed."
else
errorList+=("Warning: gawk is not installed. Game removal with -r will not work.")
fi
packageList+=("gawk")
if command -v ocrdesktop &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Ocrdesktop is installed."
else
errorList+=("Warning: ocrdesktop is not installed. It can help if the installer gets stuck to figure out what is happening.")
fi
packageList+=("ocrdesktop")
if command -v qjoypad &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Qjoypad is installed."
else
errorList+=("Warning: qjoypad is not installed. Qjoypad allows you to play keyboard only games with a gamepad.")
fi
packageList+=("qjoypad")
if command -v sox &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Sox is installed."
else
errorList+=("Warning: Sox is not installed. Audio will not work.")
fi
packageList+=("sox")
if command -v trans &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Translate-shell is installed."
else
errorList+=("Warning: translate-shell is not installed. Games that require translation will not be translated.")
fi
packageList+=("translate-shell")
if command -v sqlite3 &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Sqlite3 is installed."
else
errorList+=("Warning: sqlite is not installed. Required for games that need to be translated.")
fi
if command -v perl &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Perl is installed."
else
errorList+=("Warning: perl is not installed. Required for games that need to be translated.")
fi
packageList+=("perl")
packageList+=("sqlite")
if command -v w3m &> /dev/null ; then
[[ $# -eq 0 ]] && echo "W3m is installed."
else
errorList+=("Warning: w3m is not installed. W3m is used to view game documentation.")
fi
packageList+=("w3m")
if command -v xclip &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Xclip is installed."
else
errorList+=("Warning: Xclip is not installed. Some games may not speak or register properly.")
fi
packageList+=("xclip")
if command -v xdotool &> /dev/null ; then
[[ $# -eq 0 ]] && echo "Xdotool is installed."
else
errorList+=("Warning: Xdotool is not installed. Some installers may not work or may need manual intervention.")
fi
packageList+=("xdotool")
# Show the results
if [[ $# -ne 0 ]]; then
for i in "${packageList[@]}" ; do
echo "$i"
done | sort
exit 0
fi
if [[ ${#errorList[@]} -eq 0 ]]; then
echo "No problems found, you are good to go."
exit 0
fi
echo "Errors detected, here is a list along with the severity."
echo "Note that errors marked critical mean that you will not be able to install and play games until they are resolved."
for i in "${errorList[@]}" ; do
echo "$i"
done
exit 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
local dest="${i##*/}"
dest="${dest//%20/ }"
dest="${dest#*\?filename=}"
dest="${dest%\?*}"
# Remove the destination file if it is empty.
[[ -s "${cache}/${dest}" ]] || rm -f "${cache}/${dest}" 2> /dev/null
if [[ "${redownload}" == "true" ]] && [[ -e "${cache}/${dest}" ]]; then
rm -v "${cache}/${dest}"
fi
# Skip if the item is in cache.
[[ -e "${cache}/${dest}" ]] && continue
{ if ! curl -L4 -C - --retry 10 --output "${cache}/${dest}" "${i}" ; then
echo "Could not download \"$i\"..."
exit 1
fi; } | dialog --backtitle "Audio Game Manager" \
--progressbox "Downloading \"$dest\" from \"$i\"" -1 -1
local downloadError=1
case "${dest##*.}" in
"pk3"|"zip")
unzip -tq "${cache}/${dest}" | dialog --backtitle "Audio Game Manager" \
--progressbox "Validating ${dest##*.} file" -1 -1 --stdout
downloadError=$?
;;
"7z")
7z t "${cache}/${dest}" | dialog --backtitle "Audio Game Manager" \
--progressbox "Validating 7z file" -1 -1 --stdout
downloadError=$?
;;
"exe")
# Check if it's a valid Windows executable by looking at the MZ header
hexdump -n 2 -v -e '/1 "%02X"' "${cache}/${dest}" | grep -q "4D5A"
downloadError=$?
;;
"wad")
if [[ "$(file -b --mime-type "${cache}/${dest}")" != "application/octet-stream" ]]; then
downloadError=0
fi
;;
*)
# Add HTML check for other file types
if file -b "${cache}/${dest}" | grep -q "HTML document" ; then
echo "File not found: \"$i\" (HTML document probably 404)"
downloadError=0
fi
;;
esac
if [[ $downloadError -ne 0 ]]; then
rm -fv "${cache}/${dest}"
dialog --backtitle "Audio Game Manager" \
--infobox "Error downloading \"${dest}\". Installation cannot continue." -1 -1 --stdout
alert
exit 1
fi
done
}
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"*) ;&
"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; }
}
help() {
echo "${0##*/}"
echo "Released under the terms of the Common Public Attribution License Version 1.0"
echo -e "This is a Stormux project: https://stormux.org\n"
echo -e "Usage:\n"
echo "With no arguments, open the game launcher."
for i in "${!command[@]}" ; do
echo "-${i/:/ <parameter>}: ${command[${i}]}"
done | sort
echo
echo "Some settings that are often used can be stored in a settings.conf file."
echo "If wanted, place it at the following location:"
echo "${configFile%/*}/settings.conf"
echo "The syntax is variable=\"value\""
echo
echo "ipfsGateway=\"https://ipfs.stormux.org\" # Gateway to be used for ipfs downloads."
echo "noCache=\"true\" # Do not keep downloaded items in the cache."
echo "noqjoypad=\"true\" # Do not launch qjoypad."
echo "norh=\"true\" # Do not install RHVoice."
echo "redownload=\"true\" # Redownload sources, do not use the version stored in cache."
echo "voiceName=\"voicename\" # Select the voice to be installed (default Bdl)."
echo "defaultVoice=\"voicename\" # Select the default voice to use for the bottle, e.g. MSMike or RHVoice."
echo "defaultRate=\"Default voice rate for the bottle, default 7, may not work in all games. Values 1-9 or A."
echo "winedebug=\"flag(s)\" # Set wine debug flags, useful for development."
exit 0
}
documentation() {
if [[ "$2" == "Become a Patron" ]]; then
return
fi
if [[ "$2" == "Donate" ]]; then
return
fi
if ! command -v w3m &> /dev/null ; then
echo "This feature of audiogame-manager requires w3m. Please install it before continuing."
exit 1
fi
get_bottle "$1"
echo "Loading documentation, please wait..."
# Try to find documentation based on common naming conventions.
local gamePath="$(winepath -u "$2" 2> /dev/null)"
gamePath="${gamePath%/*}"
local gameDoc="$(find "$gamePath" -type f -iname 'user_manual.htm*' -or -iname 'user manual.htm*' -or -iname '*user guide.htm*' | head -1)"
# Game name specific docs, add the name to the for loop.
if [[ -z "$gameDoc" ]]; then
for i in "troopanum.txt" "superdeekout.txt" scw.html ; do
gameDoc="$(find "$gamePath" -type f -iname "$i" -or -iname 'manual.htm' | head -1)"
done
fi
if [[ -z "$gameDoc" ]]; then
gameDoc="$(find "$gamePath" -type f -path '*/Manual/index.html' | head -1)"
fi
if [[ -z "$gameDoc" ]]; then
gameDoc="$(find "$gamePath" -type f -iname '[A-Z]*Help.htm' -or -iname '[A-Z]*Help.html' | head -1)"
fi
if [[ -z "$gameDoc" ]]; then
gameDoc="$(find "$gamePath" -type f -iname 'manual.html' -or -iname 'manual.htm' | head -1)"
fi
if [[ -z "$gameDoc" ]]; then
gameDoc="$(find "$gamePath" -type f -iname 'en.html' -or -iname 'en.htm' | head -1)"
fi
if [[ -z "$gameDoc" ]]; then
gameDoc="$(find "$gamePath" -type f -iname 'readme.html' -or -iname 'readme.htm' | head -1)"
fi
if [[ -z "$gameDoc" ]]; then
gameDoc="$(find "$gamePath" -type f -iname 'manual.txt' | head -1)"
fi
if [[ -z "$gameDoc" ]]; then
gameDoc="$(find "$gamePath" -type f -iname 'readme.txt' -or -iname 'help.txt' | head -1)"
fi
if [[ -z "$gameDoc" ]]; then
gameDoc="$(find "$gamePath" -type f -iname '*.url' -exec grep -i 'url=' {} \; | grep -iv 'score' | head -1)"
gameDoc="${gameDoc#*=}"
gameDoc="${gameDoc//[[:cntrl:]]/}"
fi
# Display documentation if available.
if [[ -n "$gameDoc" ]]; then
w3m "$gameDoc"
else
echo "No documentation found."
fi
exit 0
}
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
# 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://rhvoice.eu-central-1.linodeobjects.com/RHVoice-voice-English-Alan-v4.0.2008.15-setup.exe"
[bdl]="https://rhvoice.eu-central-1.linodeobjects.com/RHVoice-voice-English-Bdl-v4.1.2008.15-setup.exe"
[clb]="https://rhvoice.eu-central-1.linodeobjects.com/RHVoice-voice-English-Clb-v4.0.2008.15-setup.exe"
[lyubov]="https://rhvoice.eu-central-1.linodeobjects.com/RHVoice-voice-English-Lyubov-v4.0.2008.15-setup.exe"
[slt]="https://rhvoice.eu-central-1.linodeobjects.com/RHVoice-voice-English-Slt-v4.0.2008.15-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"
@ -815,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
@ -875,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
@ -965,10 +227,10 @@ custom_launch_parameters() {
if [[ "${game[0]}" == "sequence-storm" ]]; then
"${0%/*}/speech/clipboard_reader.sh" SequenceStorm &
fi
if [[ "${game[0]}" == "shadow-line" ]]; then
find "${WINEPREFIX}/drive_c/" -type f -name 'nvdaControllerClient.dll' -exec rm -v "{}" \;
"${0%/*}/speech/clipboard_translator.sh" play_sr.exe shadow-line &
fi
#if [[ "${game[0]}" == "shadow-line" ]]; then
#find "${WINEPREFIX}/drive_c/" -type f -name 'nvdaControllerClient.dll' -exec rm -v "{}" \;
#"${0%/*}/speech/clipboard_translator.sh" play_sr.exe shadow-line &
#fi
if [[ "${game[0]}" == "sketchbook" ]]; then
find "${WINEPREFIX}" -type f -name 'nvdaControllerClient32.dll' -exec cp -v "${cache}/nvdaControllerClient32.dll" "{}" \;
fi
@ -1005,7 +267,7 @@ custom_launch_parameters() {
}
# Process game launcher flags
process_launcher-flags() {
process_launcher_flags() {
flags=("${game[@]:3}")
for i in "${flags[@]}" ; do
if [[ "${i}" =~ ^export\ [a-zA-Z_][a-zA-Z0-9_]*=\'?.*\'?$ ]]; then
@ -1016,10 +278,13 @@ process_launcher-flags() {
create_game_array() {
# Game array 0 bottle, 1 path, 2 title, 3+ flags
game="$1"
for i in "${lines[@]}" ; do
if [[ "${game}" =~ ^${i} ]]; then
# This is weird. Why do I have to set game to i before making the array?
game="$i"
# Only compare the launcher section
j="${game#*|}"
k="${i#*|}"
k="${k%%|*}"
if [[ "$j" == "$k" ]]; then
IFS='|' read -ra game <<< "$i"
break
fi
@ -1030,6 +295,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
@ -1052,6 +318,7 @@ game_launcher() {
done
menuList+=("Donate" "Donate")
menuList+=("Become a Patron" "Become a Patron")
local game=""
game="$(dialog --backtitle "Audio Game Launcher" \
--clear \
--extra-button \
@ -1060,14 +327,15 @@ game_launcher() {
--no-tags \
--menu "Please select a game to play" 0 0 0 "${menuList[@]}" --stdout)"
local menuCode=$?
if [[ $menuCode -eq 1 ]]; then
if [[ $menuCode -eq 1 ]] || [[ $menuCode -eq 255 ]]; then
exit 0
elif [[ $menuCode -eq 3 ]]; then
source .includes/help.sh # Make available in this function
documentation "$game" "$(echo "$game" | cut -d '|' -f2)"
fi
create_game_array
create_game_array "$game"
else
create_game_array
create_game_array "$game"
if [[ -z "$game" ]]; then
echo "Game $1 not found."
exit 1
@ -1107,7 +375,7 @@ game_launcher() {
fi
fi
fi
process_launcher-flags
process_launcher_flags
custom_launch_parameters
${wine:-/usr/bin/wine} start /d "${game[1]%\\*}" "${game[1]##*\\}" /realtime
fi
@ -1117,44 +385,15 @@ 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
# Check for updates
update
# If display isn't set assume we are launching from console and an X environment is running using display :0
if [[ -z "$DISPLAY" ]]; then
export DISPLAY=":0"
fi
# Settings file
cache="${XDG_CACHE_HOME:-$HOME/.cache}/audiogame-manager"
configFile="${XDG_CONFIG_HOME:-$HOME/.config}/storm-games/audiogame-manager/games.conf"
export cache="${XDG_CACHE_HOME:-$HOME/.cache}/audiogame-manager"
export configFile="${XDG_CONFIG_HOME:-$HOME/.config}/storm-games/audiogame-manager/games.conf"
mkdir -p "${cache}"
mkdir -p "${configFile%/*}"
# Create the path for AGM's helper programs.
@ -1189,21 +428,20 @@ export ipfsGateway="${ipfsGateway:-https://ipfs.stormux.org}"
export nvdaControllerClientDll="${ipfsGateway}/ipfs/QmWu7YdSbKMk1Qm5DKvEA5hk1YuAK8wVkwhDf2CsmPkmF1?filename=nvdaControllerClient32.dll"
# Make sure the minimum of curl, sox, wine, and winetricks are installed or fex-emu on aarch64
if [[ "$(uname -m)" == "aarch64" ]]; then
minimumDependencies=("FEXLoader")
wine="FEXLoader -- /usr/bin/wine"
else
minimumDependencies=("curl" "sox" "wine")
fi
for i in "${minimumDependencies[@]}" ; do
if ! command -v $i &> /dev/null ; then
echo "Please install $i before continuing."
exit 1
fi
done
# 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
# Check minimum requirements
check_requirements || exit 1
# Check for updates
update
# Get latest news if available
check_news
# With no arguments, open the game launcher.
if [[ $# -eq 0 ]]; then
game_launcher
@ -1238,7 +476,7 @@ args="${!command[*]}"
args="${args//[[:space:]]/}"
while getopts "${args}" i ; do
case "$i" in
c) checklist;;
c) ./.includes/checkup.sh;;
C) clear_cache;;
D) desktop_launcher;;
d)
@ -1248,7 +486,7 @@ while getopts "${args}" i ; do
h) help;;
i) game_installer;;
I)
game="${OPTARG}"
export game="${OPTARG}"
break;;
k) kill_game;;
L) license;;
@ -1263,7 +501,7 @@ while getopts "${args}" i ; do
r) game_removal;;
S) defaultRate="${OPTARG}";;
t)
gameCount=$(find .install -type f -iname "*.sh" | wc -l)
gameCount=$(find ".install" -type f -iname "*.sh" | wc -l)
dialog --backtitle "Linux Game Manager" \
--infobox "There are currently ${gameCount} games available." -1 -1
exit 0
@ -1273,8 +511,17 @@ while getopts "${args}" i ; do
esac
done
# If agmNoLaunch is set, exit (script is being sourced)
[[ "$agmNoLaunch" == "true" ]] && exit 0
# If no game specified, exit
[[ ${#game} -lt 1 ]] && exit 0
[[ "$agmNoLaunch" != "true" ]] && winetricks sandbox
[[ "$agmNoLaunch" != "true" ]] && exit 0
# Install the specified game noninteractively
if [[ -f ".install/${game}.sh" ]]; then
export LANG="en_US.UTF-8"
. ".install/${game}.sh"
else
echo "Error: Game '${game}' not found in .install directory"
exit 1
fi

View File

@ -7,7 +7,6 @@
# set -Eeuo pipefail # https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/#:~:text=set%20%2Du,is%20often%20highly%20desirable%20behavior.
shopt -s expand_aliases
if [[ $# -ne 2 ]]; then
echo "Usage: $0 \"application name\" \"file name\"."
exit 1
@ -22,6 +21,40 @@ fileName="${2,,}"
fileName="${fileName//[[:space:]]/-}.sqlite"
translationFile="${XDG_CACHE_HOME:-$HOME/.cache}/audiogame-manager/${fileName}"
# Make sure the directory exists
mkdir -p "$(dirname "$translationFile")"
# Initialize database if it doesn't exist
if [[ ! -s "$translationFile" ]]; then
rm -f "$translationFile"
sqlite3 "$translationFile" <<EOF
CREATE TABLE translations(
text TEXT NOT NULL,
translation TEXT NOT NULL,
PRIMARY KEY (text)
);
CREATE INDEX translations_text_idx ON translations (text);
EOF
fi
# Define a function to safely query the database
query_database() {
local db_file="$1"
local sql_query="$2"
sqlite3 -line "$db_file" "$sql_query"
}
# Define a function to safely insert into the database
insert_database() {
local db_file="$1"
local text="$2"
local translation="$3"
# Use sqlite3 .import feature which is more robust for special characters
echo "$text|$translation" | sqlite3 -separator "|" "$db_file" ".import /dev/stdin temp_import"
sqlite3 "$db_file" "INSERT OR IGNORE INTO translations SELECT * FROM temp_import; DROP TABLE IF EXISTS temp_import;"
}
# Read so long as the application is running
while pgrep -u "$USER" ^$1 &> /dev/null ; do
sleep 0.05
@ -37,24 +70,6 @@ while pgrep -u "$USER" ^$1 &> /dev/null ; do
if [[ -z "$text" ]]; then
continue
fi
q() { sqlite3 -column -init "" "$translationFile" "$@" 2> /dev/null ; }
if [[ ! -s "$translationFile" ]]; then
rm -f "$translationFile"
cat << EOF | sqlite3 -init "" "$translationFile" 2> /dev/null
.bail on
CREATE TABLE translations(
text TEXT NOT NULL,
translation TEXT NOT NULL,
PRIMARY KEY (text)
);
CREATE INDEX translations_text_idx ON translations (text);
EOF
fi
# https://en.wikipedia.org/wiki/Unicode_equivalence#Combining_and_precomposed_characters
# https://www.effectiveperlprogramming.com/2011/09/normalize-your-perl-source/
@ -65,18 +80,32 @@ EOF
alias normalize_spaces="perl -CSDA -plE 's/[^\\S\\t]/ /g'"
alias normalize_unicode="normalize_spaces | nfc"
textEscaped="$(echo "$text" | sed "s/'/''/g" | normalize_unicode)" # escape single quotes for sqlite
translated="$(q "SELECT translation FROM translations WHERE text = '$textEscaped' LIMIT 1" | sed 's/\s*$//')"
# Normalize text
normalized_text="$(echo "$text" | normalize_unicode)"
# Create a temporary database for import
sqlite3 "$translationFile" "CREATE TABLE IF NOT EXISTS temp_import(text TEXT, translation TEXT);"
# Check if we already have a translation
translated=$(sqlite3 "$translationFile" "SELECT translation FROM translations WHERE text = '$normalized_text' LIMIT 1;" 2>/dev/null)
if [[ -z "$translated" ]]; then
translated="$(trans -no-autocorrect -no-warn -brief "$text" | head -1 | sed 's/\s*$//' | normalize_unicode)"
# Get translation from the trans utility
translated="$(trans -no-autocorrect -no-warn -brief "$normalized_text" | head -1 | sed 's/\s*$//' | normalize_unicode)"
if [[ -n "$translated" ]]; then
translatedEscaped="$(echo "$translated" | sed "s/'/''/g")"
q "INSERT OR IGNORE INTO translations (text, translation) VALUES ('$textEscaped', '$translatedEscaped')"
# Insert using echo piping to avoid escaping issues
echo "$normalized_text|$translated" | sqlite3 -separator "|" "$translationFile" ".import /dev/stdin temp_import"
sqlite3 "$translationFile" "INSERT OR IGNORE INTO translations SELECT * FROM temp_import; DELETE FROM temp_import;"
fi
fi
spd-say -- "$translated"
# If we got a translation, speak it
if [[ -n "$translated" ]]; then
spd-say -- "$translated"
fi
# Clear clipboard
echo "" | xclip -d "${DISPLAY:-:0}" -selection clipboard 2> /dev/null
done

View File

@ -1,18 +1,18 @@
#!/usr/bin/env bash
# Set Voice
# Set the default wine voice ba$sed on installed options.
# Set the default wine voice based on installed options.
#
# ■The contents of this file are subject to the Common Public Attribution
# License Version 1.0 (the ■License■); you may not use this file except in
# âe contents of this file are subject to the Common Public Attribution
# License Version 1.0 (the âcenseâ you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# https://opensource.org/licenses/CPAL-1.0. The License is ba$sed on the Mozilla Public License Version
# https://opensource.org/licenses/CPAL-1.0. The License is based on the Mozilla Public License Version
# 1.1 but Sections 14 and 15 have been added to cover use of software over a
# computer network and provide for limited attribution for the Original
# Developer. In addition, Exhibit A has been modified to be consistent with
# Exhibit B.
#
# Software distributed under the License is distributed on an ■AS IS■ basis,
# Software distributed under the License is distributed on an â ISâasis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
@ -81,7 +81,6 @@ declare -A command=(
)
msgbox() {
# Returns: None
# Shows the provided message on the screen with an ok button.
@ -143,10 +142,18 @@ set_voice() {
[[ "$x" = "$tmp" ]] && break
counter=$(( $counter + 1 ))
done
local RHVoiceName="$(find "${WINEPREFIX}/drive_c/ProgramData/Olga Yakovleva/RHVoice/data/voices/" -maxdepth 1 -type d)"
RHVoiceName="${RHVoiceName##*/}"
local RHVoiceName=""
local RHVoicePath="${WINEPREFIX}/drive_c/ProgramData/Olga Yakovleva/RHVoice/data/voices/"
if [[ -d "$RHVoicePath" ]]; then
RHVoiceName="$(find "$RHVoicePath" -maxdepth 1 -type d -not -path "$RHVoicePath" | head -1)"
if [[ -n "$RHVoiceName" ]]; then
RHVoiceName="${RHVoiceName##*/}"
fi
fi
fullVoice="${voiceListFullName[$counter]}"
fullVoice="${fullVoice/RHVoice/RHVoice\\\\${RHVoiceName}}"
if [[ -n "$RHVoiceName" ]]; then
fullVoice="${fullVoice/RHVoice/RHVoice\\\\${RHVoiceName}}"
fi
${wine}server -k # If we don't do this it's likely wine will overwrite our reverted change or even clobber the registry key entirely
# Remove any existing rate change for voices
$sed -i '/"DefaultTTSRate"=dword:/d' "${WINEPREFIX}/user.reg"
@ -162,13 +169,21 @@ test_voice() {
[ "$x" = "$tmp" ] && break
counter=$(( $counter + 1 ))
done
local RHVoiceName="$(find "${WINEPREFIX}/drive_c/ProgramData/Olga Yakovleva/RHVoice/data/voices/" -maxdepth 1 -type d)"
RHVoiceName="${RHVoiceName##*/}"
local RHVoiceName=""
local RHVoicePath="${WINEPREFIX}/drive_c/ProgramData/Olga Yakovleva/RHVoice/data/voices/"
if [[ -d "$RHVoicePath" ]]; then
RHVoiceName="$(find "$RHVoicePath" -maxdepth 1 -type d -not -path "$RHVoicePath" | head -1)"
if [[ -n "$RHVoiceName" ]]; then
RHVoiceName="${RHVoiceName##*/}"
fi
fi
fullVoice="${voiceListFullName[$counter]}"
fullVoice="${fullVoice/RHVoice/RHVoice\\\\${RHVoiceName}}"
if [[ -n "$RHVoiceName" ]]; then
fullVoice="${fullVoice/RHVoice/RHVoice\\\\${RHVoiceName}}"
fi
${wine}server -k # If we don't do this it's likely wine will overwrite our reverted change or even clobber the registry key entirely
$sed -i -E -e 's/"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\(SOFTWARE|Software)\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Token(Enum|)s\\\\[^"]+"/"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\'"${fullVoice//\\/\\\\}"'"/g' "${WINEPREFIX}/user.reg"
cat << "EOF" > "${bottle}/drive_c/windows/temp/speak.vbs"
$sed -i -E -e 's/"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\(SOFTWARE|Software)\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Token(Enum|)s\\\\[^"]+"/"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\'"${fullVoice//\\/\\\\}"'"/g' "${WINEPREFIX}/user.reg"
cat << "EOF" > "${WINEPREFIX}/drive_c/windows/temp/speak.vbs"
dim speechobject
set speechobject=createobject("sapi.spvoice")
speechobject.speak "This is a test of your chosen voice. It contains multiple sentences and punctuation, and is designed to give a full representation of this voices qualities."
@ -186,12 +201,20 @@ args="${args//[[:space:]]/}"
while getopts "${args}" i ; do
case "$i" in
b)
if ! [[ -d ~/".local/wine/${OPTARG}" ]]; then
# Check for valid bottles in all possible locations
if [[ -d ~/.local/wine/${OPTARG} ]]; then
export bottle=~/.local/wine/${OPTARG}
export WINEPREFIX=~/.local/wine/${OPTARG}
elif [[ -d ~/.local/wine32 && ${OPTARG} == "wine32" ]]; then
export bottle=~/.local/wine32
export WINEPREFIX=~/.local/wine32
elif [[ -d ~/.local/wine64 && ${OPTARG} == "wine64" ]]; then
export bottle=~/.local/wine64
export WINEPREFIX=~/.local/wine64
else
echo "Invalid wine bottle specified."
exit 1
fi
export bottle=~/".local/wine/${OPTARG}"
export WINEPREFIX=~/".local/wine/${OPTARG}"
;;
h) help;;
r)
@ -210,14 +233,28 @@ done
# Offer a list of wine bottles if one isn't specified on the command line.
if [[ -z "${bottle}" ]]; then
declare -a bottle
for i in $(find ~/.local/wine/ -maxdepth 1 -type d -not -name 'wine' | sort) ; do
bottle+=("$i" "${i##*/}")
declare -a bottles=()
# Check for wine32 and wine64 bottles
[[ -d ~/.local/wine32 ]] && bottles+=("$HOME/.local/wine32" "wine32")
[[ -d ~/.local/wine64 ]] && bottles+=("$HOME/.local/wine64" "wine64")
# Add bottles from ~/.local/wine directory
if [[ -d ~/.local/wine ]]; then
for i in $(find ~/.local/wine/ -maxdepth 1 -type d -not -name 'wine' | sort); do
bottles+=("$i" "${i##*/}")
done
fi
if [[ ${#bottles[@]} -eq 0 ]]; then
echo "No wine bottles found in ~/.local/wine32, ~/.local/wine64, or ~/.local/wine/"
exit 1
fi
export WINEPREFIX="$(dialog --backtitle "Use the up and down arrow keys to find the option you want, then press enter to select it." \
--clear \
--no-tags \
--menu "Select A Wine Bottle" 0 0 0 "${bottle[@]}" --stdout)"
--no-tags \
--menu "Select A Wine Bottle" 0 0 0 "${bottles[@]}" --stdout)"
fi
if [[ -z "${WINEPREFIX}" ]]; then
@ -231,9 +268,16 @@ if [[ -r "${WINEPREFIX}/agm.conf" ]]; then
export WINESERVER
fi
wine="${WINE:-$(command -v wine)}"
wineserver="${WINESERVER:-$(command -v wineserver)}"
# Debug information - comment out or delete when not needed
# echo "Using wine bottle: ${WINEPREFIX}"
# echo "Wine executable: ${wine}"
# echo "Wineserver executable: ${wineserver}"
# In case the user hasn't run a game using sapi in this prefix yet, let's try to initialize all the registry keys properly.
cat << "EOF" > "${bottle}/drive_c/windows/temp/speak.vbs"
mkdir -p "${WINEPREFIX}/drive_c/windows/temp"
cat << "EOF" > "${WINEPREFIX}/drive_c/windows/temp/speak.vbs"
dim speechobject
set speechobject=createobject("sapi.spvoice")
speechobject.speak ""
@ -245,6 +289,13 @@ ifs="$IFS"
IFS=$'\n'
voiceListFullName=($($grep -P '\[Software\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Token(Enum|)s\\\\[^\\]+\].*' "${WINEPREFIX}/system.reg" | $sed -E -e 's/\[([^]]+)\].*/\1/g'))
IFS="$ifs"
# Debug the voice list - comment out or delete when not needed
# echo "Found ${#voiceListFullName[@]} voices in registry"
# for voice in "${voiceListFullName[@]}"; do
# echo "Voice: $voice"
# done
voiceList=()
for x in "${voiceListFullName[@]}" ; do
voiceList+=("$(echo "$x" | $sed -E -e 's/Software\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Token(Enum|)s\\\\(.+)/\3/g')")
@ -252,7 +303,7 @@ done
oldVoice="$($grep -P '"DefaultTokenId"="HKEY_LOCAL_MACHINE\\\\(SOFTWARE|Software)\\\\(Wow6432Node\\\\|)Microsoft\\\\Speech\\\\Voices\\\\Token(Enum|)s\\\\[^"]+"' "${WINEPREFIX}/user.reg" | $sed -E -e 's/"DefaultTokenId"="([^"]+)"/\1/g')"
exit=1
if [[ "${#voiceList[@]}" -eq 0 ]]; then
dialog --msgbox "No voices found." -1 -1
dialog --msgbox "No voices found in ${WINEPREFIX}. Make sure SAPI voices are installed in this Wine prefix." 0 0
exit 1
fi
while [[ $exit -ne 0 ]] ; do