diff --git a/lug-helper.sh b/lug-helper.sh index f7cee22..b90cda0 100755 --- a/lug-helper.sh +++ b/lug-helper.sh @@ -2045,6 +2045,31 @@ update_launch_script() { fi } +# MARK: edit_launch_script() +# Edit the launch script +edit_launch_script() { + # Get/Set directory paths + getdirs + if [ "$?" -eq 1 ]; then + # User cancelled and wants to return to the main menu + # or there was an error + return 0 + fi + + # Make sure the launch script exists + if [ ! -f "$wine_prefix/$wine_launch_script_name" ]; then + message error "Unable to find $wine_prefix/$wine_launch_script_name" + return 1 + fi + + # Open the launch script in the user's preferred editor + if [ -x "$(command -v xdg-open)" ]; then + xdg-open "$wine_prefix/$wine_launch_script_name" + else + message error "xdg-open is not installed.\nYou may open the launch script manually:\n\n$wine_prefix/$wine_launch_script_name" + fi +} + # MARK: call_launch_script() # Call our launch script and pass it the given command line argument call_launch_script() @@ -2084,28 +2109,50 @@ call_launch_script() "$wine_prefix/$wine_launch_script_name" "$launch_arg" } -# MARK: edit_launch_script() -# Edit the launch script -edit_launch_script() { - # Get/Set directory paths - getdirs - if [ "$?" -eq 1 ]; then - # User cancelled and wants to return to the main menu - # or there was an error - return 0 - fi +# MARK: install_powershell() +# Install powershell verb into the game's wine prefix +install_powershell() { + # Download winetricks + download_winetricks - # Make sure the launch script exists - if [ ! -f "$wine_prefix/$wine_launch_script_name" ]; then - message error "Unable to find $wine_prefix/$wine_launch_script_name" + # Abort if the winetricks download failed + if [ "$?" -eq 1 ]; then + message error "Unable to install powershell without winetricks. Aborting." return 1 fi - # Open the launch script in the user's preferred editor - if [ -x "$(command -v xdg-open)" ]; then - xdg-open "$wine_prefix/$wine_launch_script_name" + # Update directories + getdirs + + if [ "$?" -eq 1 ]; then + # User cancelled getdirs or there was an error + message warning "Unable to install powershell." + return 1 + fi + + # Get the current wine runner from the launch script + get_current_runner + if [ "$?" -ne 1 ]; then + export WINE="$launcher_winepath/wine" + export WINESERVER="$launcher_winepath/wineserver" + fi + # Set the correct wine prefix + export WINEPREFIX="$wine_prefix" + + # Show a zenity pulsating progress bar + progress_bar start "Installing PowerShell. Please wait..." + + # Install powershell + debug_print continue "Installing PowerShell into ${wine_prefix}..." + "$winetricks_bin" -q powershell + + exit_code="$?" + if [ "$exit_code" -eq 1 ] || [ "$exit_code" -eq 130 ] || [ "$exit_code" -eq 126 ]; then + progress_bar stop # Stop the zenity progress window + message warning "PowerShell could not be installed. See terminal output for details." else - message error "xdg-open is not installed.\nYou may open the launch script manually:\n\n$wine_prefix/$wine_launch_script_name" + progress_bar stop # Stop the zenity progress window + message info "PowerShell operation complete. See terminal output for details." fi } @@ -2183,6 +2230,246 @@ reset_helper() { ######## end maintenance functions ######################################### ############################################################################ +############################################################################ +######## begin dxvk functions ############################################## +############################################################################ + +# MARK: dxvk_menu() +# Menu to select and install a dxvk into the wine prefix +dxvk_menu() { + # Configure the menu + menu_text_zenity="Manage Your DXVK Version\n\nSelect which DXVK you'd like to update or install\n\nYou may choose from the following options:" + menu_text_terminal="Manage Your DXVK Version\n\nSelect which DXVK you'd like to update or install\nYou may choose from the following options:" + menu_text_height="300" + menu_type="radiolist" + + # Configure the menu options + standard_msg="Update or Switch to Standard DXVK" + async_msg="Update or Switch to Async DXVK" + nvapi_msg="Add or Update DXVK-NVAPI" + quit_msg="Return to the main menu" + + # Set the options to be displayed in the menu + menu_options=("$standard_msg" "$async_msg" "$nvapi_msg" "$quit_msg") + # Set the corresponding functions to be called for each of the options + menu_actions=("install_dxvk standard" "install_dxvk async" "install_dxvk nvapi" "menu_loop_done") + + # Calculate the total height the menu should be + # menu_option_height = pixels per menu option + # #menu_options[@] = number of menu options + # menu_text_height = height of the title/description text + # menu_text_height_zenity4 = added title/description height for libadwaita bigness + menu_height="$(($menu_option_height * ${#menu_options[@]} + $menu_text_height + $menu_text_height_zenity4))" + + # Set the label for the cancel button + cancel_label="Go Back" + + # Call the menu function. It will use the options as configured above + menu +} + +# MARK: install_dxvk() +# Entry function to install or update DXVK in the wine prefix +# +# Requires one argument to specify which type of dxvk to install +# Supports "standard", "async", "nvapi" +install_dxvk() { + # Sanity checks + if [ "$#" -lt 1 ]; then + debug_print exit "Script error: The install_dxvk function expects one argument. Aborting." + fi + + # Update directories + getdirs + + if [ "$?" -eq 1 ]; then + # User cancelled getdirs or there was an error + message warning "Unable to update dxvk." + return 1 + fi + + # Get the current wine runner from the launch script + get_current_runner + if [ "$?" -ne 1 ]; then + export WINE="$launcher_winepath/wine" + export WINESERVER="$launcher_winepath/wineserver" + fi + # Set the correct wine prefix + export WINEPREFIX="$wine_prefix" + + if [ "$1" = "standard" ]; then + install_standard_dxvk + elif [ "$1" = "async" ]; then + install_async_dxvk + elif [ "$1" = "nvapi" ]; then + install_dxvk_nvapi + else + debug_print exit "Script error: Unknown argument in install_dxvk function: $1. Aborting." + fi +} + +# MARK: install_standard_dxvk() +# Install or update standard dxvk in the wine prefix +# +# Expects that getdirs has already been called +# Expects that the env vars WINE, WINESERVER, and WINEPREFIX are already set +install_standard_dxvk() { + # Download winetricks + download_winetricks + + # Abort if the winetricks download failed + if [ "$?" -eq 1 ]; then + message error "Unable to update dxvk without winetricks. Aborting." + return 1 + fi + + # Show a zenity pulsating progress bar + progress_bar start "Updating DXVK. Please wait..." + debug_print continue "Updating DXVK in ${wine_prefix}..." + + # Update dxvk + "$winetricks_bin" -f dxvk + + exit_code="$?" + if [ "$exit_code" -eq 1 ] || [ "$exit_code" -eq 130 ] || [ "$exit_code" -eq 126 ]; then + progress_bar stop # Stop the zenity progress window + message warning "DXVK could not be installed. See terminal output for details." + else + progress_bar stop # Stop the zenity progress window + message info "DXVK update complete. See terminal output for details." + fi +} + +# MARK: install_async_dxvk() +# Install or update async dxvk in the wine prefix +# +# Expects that getdirs has already been called +# Expects that the env vars WINE, WINESERVER, and WINEPREFIX are already set +install_async_dxvk() { + # Sanity checks + if [ ! -d "$wine_prefix/drive_c/windows/system32" ]; then + message error "Unable to find the system32 directory in your Wine prefix! Your prefix may be broken.\n\n$wine_prefix/drive_c/windows/system32" + return 1 + fi + if [ ! -d "$wine_prefix/drive_c/windows/syswow64" ]; then + message error "Unable to find the syswow64 directory in your Wine prefix! Your prefix may be broken.\n\n$wine_prefix/drive_c/windows/syswow64" + return 1 + fi + + # Get the file download url + # Assume the first item returned by the API is the latest version + download_url="$(curl -sL "${dxvk_async_source}" | grep -Eo "\"direct_asset_url\": ?\"[^\"]+\"" | grep "releases" | grep -F ".tar.gz" | cut -d '"' -f4 | cut -d '?' -f1)" + + # Sanity check + if [ -z "$download_url" ]; then + message warning "Could not find the requested dxvk file. The GitLab API may be down or rate limited." + return 1 + fi + + # Get file name info + download_filename="$(basename "$download_url")" + download_basename="$(basename "$download_filename" .tar.gz)" + + # Download the item to the tmp directory + download_file "$download_url" "$download_filename" "DXVK" + + # Sanity check + if [ ! -f "$tmp_dir/$download_filename" ]; then + # Something went wrong with the download and the file doesn't exist + message error "Something went wrong and the requested DXVK file could not be downloaded!" + debug_print continue "Download failed! File not found: $tmp_dir/$download_filename" + return 1 + fi + + # Show a zenity pulsating progress bar + progress_bar start "Updating DXVK. Please wait..." + + # Extract the archive to the tmp directory + debug_print continue "Extracting DXVK into $tmp_dir/$download_basename..." + tar -xf "$tmp_dir/$download_filename" -C "$tmp_dir" + + # Make sure the expected directories exist + if [ ! -d "$tmp_dir/$download_basename/x64" ] || [ ! -d "$tmp_dir/$download_basename/x32" ]; then + progress_bar stop # Stop the zenity progress window + message warning "Unexpected file structure in the extracted DXVK. The file may be corrupt." + return 1 + fi + + # Install the dxvk into the wine prefix + debug_print continue "Copying DXVK dlls into ${wine_prefix}..." + cp "$tmp_dir"/"$download_basename"/x64/*.dll "$wine_prefix/drive_c/windows/system32" + cp "$tmp_dir"/"$download_basename"/x32/*.dll "$wine_prefix/drive_c/windows/syswow64" + + + # Make sure we can locate the launch script + if [ ! -f "$wine_prefix/$wine_launch_script_name" ]; then + progress_bar stop # Stop the zenity progress window + message warning "Unable to find launch script!\n$wine_prefix/$wine_launch_script_name\n\nTo enable async, set the environment variable: DXVK_ASYNC=1" + return 0 + fi + # Check if the DXVK_ASYNC variable is commented out in the launch script + if ! grep -q "^#export DXVK_ASYNC=" "$wine_prefix/$wine_launch_script_name" && ! grep -q "^export DXVK_ASYNC=1" "$wine_prefix/$wine_launch_script_name"; then + progress_bar stop # Stop the zenity progress window + if message question "Could not find the DXVK_ASYNC environment variable in your launch script! It may be out of date.\n\nWould you like to try updating your launch script?"; then + # Try updating the launch script + update_launch_script + + # Check if the update was successful and we now have the env var + if ! grep -q "^#export DXVK_ASYNC=" "$wine_prefix/$wine_launch_script_name"; then + message warning "Could not find the DXVK_ASYNC environment variable in your launch script! The update may have failed.\n\nTo enable async, set the environment variable: DXVK_ASYNC=1" + return 0 + fi + else + message warning "To enable async, set the environment variable: DXVK_ASYNC=1" + return 0 + fi + fi + + # Modify the launch script to uncomment the DXVK_ASYNC variable unless it's already uncommented + if ! grep -q "^export DXVK_ASYNC=1" "$wine_prefix/$wine_launch_script_name"; then + debug_print continue "Updating DXVK_ASYNC env var in launch script ${wine_prefix}/${wine_launch_script_name}..." + sed -i "s|^#export DXVK_ASYNC=.*|export DXVK_ASYNC=1|" "$wine_prefix/$wine_launch_script_name" + fi + + progress_bar stop # Stop the zenity progress window + message info "DXVK update complete." +} + +# MARK: install_dxvk_nvapi() +# Install or update dxvk-nvapi in the wine prefix +# +# Expects that getdirs has already been called +# Expects that the env vars WINE, WINESERVER, and WINEPREFIX are already set +install_dxvk_nvapi() { + # Download winetricks + download_winetricks next + + # Abort if the winetricks download failed + if [ "$?" -eq 1 ]; then + message error "Unable to install dxvk_nvapi without winetricks. Aborting." + return 1 + fi + + # Show a zenity pulsating progress bar + progress_bar start "Installing DXVK-NVAPI. Please wait..." + debug_print continue "Installing DXVK-NVAPI in ${wine_prefix}..." + + # Update dxvk + "$winetricks_bin" -f dxvk_nvapi + + exit_code="$?" + if [ "$exit_code" -eq 1 ] || [ "$exit_code" -eq 130 ] || [ "$exit_code" -eq 126 ]; then + progress_bar stop # Stop the zenity progress window + message warning "DXVK-NVAPI could not be installed. See terminal output for details." + else + progress_bar stop # Stop the zenity progress window + message info "DXVK-NVAPI update complete. See terminal output for details." + fi +} + +############################################################################ +######## end dxvk functions ################################################ +############################################################################ # MARK: install_game() # Install the game with Wine @@ -2536,286 +2823,6 @@ get_current_runner() { fi } -# MARK: install_powershell() -# Install powershell verb into the game's wine prefix -install_powershell() { - # Download winetricks - download_winetricks - - # Abort if the winetricks download failed - if [ "$?" -eq 1 ]; then - message error "Unable to install powershell without winetricks. Aborting." - return 1 - fi - - # Update directories - getdirs - - if [ "$?" -eq 1 ]; then - # User cancelled getdirs or there was an error - message warning "Unable to install powershell." - return 1 - fi - - # Get the current wine runner from the launch script - get_current_runner - if [ "$?" -ne 1 ]; then - export WINE="$launcher_winepath/wine" - export WINESERVER="$launcher_winepath/wineserver" - fi - # Set the correct wine prefix - export WINEPREFIX="$wine_prefix" - - # Show a zenity pulsating progress bar - progress_bar start "Installing PowerShell. Please wait..." - - # Install powershell - debug_print continue "Installing PowerShell into ${wine_prefix}..." - "$winetricks_bin" -q powershell - - exit_code="$?" - if [ "$exit_code" -eq 1 ] || [ "$exit_code" -eq 130 ] || [ "$exit_code" -eq 126 ]; then - progress_bar stop # Stop the zenity progress window - message warning "PowerShell could not be installed. See terminal output for details." - else - progress_bar stop # Stop the zenity progress window - message info "PowerShell operation complete. See terminal output for details." - fi -} - -# MARK: dxvk_menu() -# Menu to select and install a dxvk into the wine prefix -dxvk_menu() { - # Configure the menu - menu_text_zenity="Manage Your DXVK Version\n\nSelect which DXVK you'd like to update or install\n\nYou may choose from the following options:" - menu_text_terminal="Manage Your DXVK Version\n\nSelect which DXVK you'd like to update or install\nYou may choose from the following options:" - menu_text_height="300" - menu_type="radiolist" - - # Configure the menu options - standard_msg="Update or Switch to Standard DXVK" - async_msg="Update or Switch to Async DXVK" - nvapi_msg="Add or Update DXVK-NVAPI" - quit_msg="Return to the main menu" - - # Set the options to be displayed in the menu - menu_options=("$standard_msg" "$async_msg" "$nvapi_msg" "$quit_msg") - # Set the corresponding functions to be called for each of the options - menu_actions=("install_dxvk standard" "install_dxvk async" "install_dxvk nvapi" "menu_loop_done") - - # Calculate the total height the menu should be - # menu_option_height = pixels per menu option - # #menu_options[@] = number of menu options - # menu_text_height = height of the title/description text - # menu_text_height_zenity4 = added title/description height for libadwaita bigness - menu_height="$(($menu_option_height * ${#menu_options[@]} + $menu_text_height + $menu_text_height_zenity4))" - - # Set the label for the cancel button - cancel_label="Go Back" - - # Call the menu function. It will use the options as configured above - menu -} - -# MARK: install_dxvk() -# Entry function to install or update DXVK in the wine prefix -# -# Requires one argument to specify which type of dxvk to install -# Supports "standard", "async", "nvapi" -install_dxvk() { - # Sanity checks - if [ "$#" -lt 1 ]; then - debug_print exit "Script error: The install_dxvk function expects one argument. Aborting." - fi - - # Update directories - getdirs - - if [ "$?" -eq 1 ]; then - # User cancelled getdirs or there was an error - message warning "Unable to update dxvk." - return 1 - fi - - # Get the current wine runner from the launch script - get_current_runner - if [ "$?" -ne 1 ]; then - export WINE="$launcher_winepath/wine" - export WINESERVER="$launcher_winepath/wineserver" - fi - # Set the correct wine prefix - export WINEPREFIX="$wine_prefix" - - if [ "$1" = "standard" ]; then - install_standard_dxvk - elif [ "$1" = "async" ]; then - install_async_dxvk - elif [ "$1" = "nvapi" ]; then - install_dxvk_nvapi - else - debug_print exit "Script error: Unknown argument in install_dxvk function: $1. Aborting." - fi -} - -# MARK: install_standard_dxvk() -# Install or update standard dxvk in the wine prefix -# -# Expects that getdirs has already been called -# Expects that the env vars WINE, WINESERVER, and WINEPREFIX are already set -install_standard_dxvk() { - # Download winetricks - download_winetricks - - # Abort if the winetricks download failed - if [ "$?" -eq 1 ]; then - message error "Unable to update dxvk without winetricks. Aborting." - return 1 - fi - - # Show a zenity pulsating progress bar - progress_bar start "Updating DXVK. Please wait..." - debug_print continue "Updating DXVK in ${wine_prefix}..." - - # Update dxvk - "$winetricks_bin" -f dxvk - - exit_code="$?" - if [ "$exit_code" -eq 1 ] || [ "$exit_code" -eq 130 ] || [ "$exit_code" -eq 126 ]; then - progress_bar stop # Stop the zenity progress window - message warning "DXVK could not be installed. See terminal output for details." - else - progress_bar stop # Stop the zenity progress window - message info "DXVK update complete. See terminal output for details." - fi -} - -# MARK: install_async_dxvk() -# Install or update async dxvk in the wine prefix -# -# Expects that getdirs has already been called -# Expects that the env vars WINE, WINESERVER, and WINEPREFIX are already set -install_async_dxvk() { - # Sanity checks - if [ ! -d "$wine_prefix/drive_c/windows/system32" ]; then - message error "Unable to find the system32 directory in your Wine prefix! Your prefix may be broken.\n\n$wine_prefix/drive_c/windows/system32" - return 1 - fi - if [ ! -d "$wine_prefix/drive_c/windows/syswow64" ]; then - message error "Unable to find the syswow64 directory in your Wine prefix! Your prefix may be broken.\n\n$wine_prefix/drive_c/windows/syswow64" - return 1 - fi - - # Get the file download url - # Assume the first item returned by the API is the latest version - download_url="$(curl -sL "${dxvk_async_source}" | grep -Eo "\"direct_asset_url\": ?\"[^\"]+\"" | grep "releases" | grep -F ".tar.gz" | cut -d '"' -f4 | cut -d '?' -f1)" - - # Sanity check - if [ -z "$download_url" ]; then - message warning "Could not find the requested dxvk file. The GitLab API may be down or rate limited." - return 1 - fi - - # Get file name info - download_filename="$(basename "$download_url")" - download_basename="$(basename "$download_filename" .tar.gz)" - - # Download the item to the tmp directory - download_file "$download_url" "$download_filename" "DXVK" - - # Sanity check - if [ ! -f "$tmp_dir/$download_filename" ]; then - # Something went wrong with the download and the file doesn't exist - message error "Something went wrong and the requested DXVK file could not be downloaded!" - debug_print continue "Download failed! File not found: $tmp_dir/$download_filename" - return 1 - fi - - # Show a zenity pulsating progress bar - progress_bar start "Updating DXVK. Please wait..." - - # Extract the archive to the tmp directory - debug_print continue "Extracting DXVK into $tmp_dir/$download_basename..." - tar -xf "$tmp_dir/$download_filename" -C "$tmp_dir" - - # Make sure the expected directories exist - if [ ! -d "$tmp_dir/$download_basename/x64" ] || [ ! -d "$tmp_dir/$download_basename/x32" ]; then - progress_bar stop # Stop the zenity progress window - message warning "Unexpected file structure in the extracted DXVK. The file may be corrupt." - return 1 - fi - - # Install the dxvk into the wine prefix - debug_print continue "Copying DXVK dlls into ${wine_prefix}..." - cp "$tmp_dir"/"$download_basename"/x64/*.dll "$wine_prefix/drive_c/windows/system32" - cp "$tmp_dir"/"$download_basename"/x32/*.dll "$wine_prefix/drive_c/windows/syswow64" - - - # Make sure we can locate the launch script - if [ ! -f "$wine_prefix/$wine_launch_script_name" ]; then - progress_bar stop # Stop the zenity progress window - message warning "Unable to find launch script!\n$wine_prefix/$wine_launch_script_name\n\nTo enable async, set the environment variable: DXVK_ASYNC=1" - return 0 - fi - # Check if the DXVK_ASYNC variable is commented out in the launch script - if ! grep -q "^#export DXVK_ASYNC=" "$wine_prefix/$wine_launch_script_name" && ! grep -q "^export DXVK_ASYNC=1" "$wine_prefix/$wine_launch_script_name"; then - progress_bar stop # Stop the zenity progress window - if message question "Could not find the DXVK_ASYNC environment variable in your launch script! It may be out of date.\n\nWould you like to try updating your launch script?"; then - # Try updating the launch script - update_launch_script - - # Check if the update was successful and we now have the env var - if ! grep -q "^#export DXVK_ASYNC=" "$wine_prefix/$wine_launch_script_name"; then - message warning "Could not find the DXVK_ASYNC environment variable in your launch script! The update may have failed.\n\nTo enable async, set the environment variable: DXVK_ASYNC=1" - return 0 - fi - else - message warning "To enable async, set the environment variable: DXVK_ASYNC=1" - return 0 - fi - fi - - # Modify the launch script to uncomment the DXVK_ASYNC variable unless it's already uncommented - if ! grep -q "^export DXVK_ASYNC=1" "$wine_prefix/$wine_launch_script_name"; then - debug_print continue "Updating DXVK_ASYNC env var in launch script ${wine_prefix}/${wine_launch_script_name}..." - sed -i "s|^#export DXVK_ASYNC=.*|export DXVK_ASYNC=1|" "$wine_prefix/$wine_launch_script_name" - fi - - progress_bar stop # Stop the zenity progress window - message info "DXVK update complete." -} - -# MARK: install_dxvk_nvapi() -# Install or update dxvk-nvapi in the wine prefix -# -# Expects that getdirs has already been called -# Expects that the env vars WINE, WINESERVER, and WINEPREFIX are already set -install_dxvk_nvapi() { - # Download winetricks - download_winetricks next - - # Abort if the winetricks download failed - if [ "$?" -eq 1 ]; then - message error "Unable to install dxvk_nvapi without winetricks. Aborting." - return 1 - fi - - # Show a zenity pulsating progress bar - progress_bar start "Installing DXVK-NVAPI. Please wait..." - debug_print continue "Installing DXVK-NVAPI in ${wine_prefix}..." - - # Update dxvk - "$winetricks_bin" -f dxvk_nvapi - - exit_code="$?" - if [ "$exit_code" -eq 1 ] || [ "$exit_code" -eq 130 ] || [ "$exit_code" -eq 126 ]; then - progress_bar stop # Stop the zenity progress window - message warning "DXVK-NVAPI could not be installed. See terminal output for details." - else - progress_bar stop # Stop the zenity progress window - message info "DXVK-NVAPI update complete. See terminal output for details." - fi -} - # MARK: format_urls() # Format some URLs for Zenity format_urls() {