Created
September 20, 2018 01:07
-
-
Save grepwood/ddc9e41779fa5414b9946fe4b212c84d to your computer and use it in GitHub Desktop.
Revisions
-
grepwood created this gist
Sep 20, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,154 @@ #!/usr/bin/env bash SCRIPT_NAME="$(basename "${0}")" FALLOUT4_EXECUTABLE="Fallout4.exe" WINE_REGISTRY_KEY="HKEY_CURRENT_USER\\Software\\Wine" FALLOUT4_APPDEFAULTS_REGISTRY_KEY="HKEY_CURRENT_USER\\Software\\Wine\\AppDefaults\\${FALLOUT4_EXECUTABLE}" FALLOUT4_INSTALL_REGISTRY_KEY='HKEY_LOCAL_MACHINE\Software\Bethesda Softworks\Fallout4' USER_SHELL_FOLDERS_REGISTRY_KEY='HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders' function die() { printf "%s : %s() : %s\\n" "${SCRIPT_NAME}" "${FUNCNAME[1]}" "${1}" >&2 exit 1 } # get_registry_value() # Returns "data" from a specified Registry key and value, where "value"="data". # Note: the Wine reg query result will use \r\n CR linefeeds - strip these! function get_registry_value() { local registry_key="${1}" registry_value="${2}" declare -n data="${3}" data="$(wine reg query "${registry_key}" /v "${registry_value}" 2>/dev/null \ | awk -F 'REG_[A-Z]*' \ -vregistry_value="${registry_value}" \ '{ for (i=1;i<=NF;++i) gsub("(^[[:blank:]]*|[[:blank:]]*$)","",$i) if ($1 == registry_value) print $2 }' 2>/dev/null \ | sed 's/\r//g' )" [[ -z "${data}" ]] && die "Registry key data lookup [${registry_key}] \"${registry_value}\"=... failed" } # add_registry_value() # Adds a Wine Registry key or a key plus "value"="data". function add_registry_value() { local registry_key="${1}" registry_value="${2}" data="${3}" type="${4}" if [[ -z "${registry_value}" ]]; then wine reg add "${registry_key}" /f 2>/dev/null \ || die "Failed to add Registry key [${registry_key}]" else wine reg add "${registry_key}" /v "${registry_value}" /t "${type}" /d "${data}" /f 2>/dev/null \ || die "Failed to add Registry key+value: [${registry_key}] \"${registry_value}\"=\"${data}\" (${type})" fi } # delete_registry_value() # Deletes a Wine Registry key or key plus value pair. function delete_registry_value() { local registry_key="${1}" registry_value="${2}" if [[ -z "${registry_value}" ]]; then wine reg delete "${registry_key}" /va /f &>/dev/null else wine reg delete "${registry_key}" /v "${registry_value}" /f &>/dev/null fi } # convert_windows_to_unix_path() # Convert a Windows path to a canonical Unix path - follows all symbolic links. # Note: winepath outputs \r\n CR linefeeds - so we must strip these! function convert_windows_to_unix_path() { local windows_path="${1}" unix_path declare -n canonical_unix_path="${2}" unix_path="$(winepath -u ''"${windows_path}"'' 2>/dev/null | sed 's/\r//g')" canonical_unix_path="$(readlink -f "${unix_path}")" if [[ ! -d "${canonical_unix_path}" ]]; then die "Unable to convert Windows directory: \"${windows_path}\"; to a Unix directory." fi } # find_file() # Finds a specified file, using a specified base directory+relative path offset. # Note: must use a case-insensitive search! function find_file() { local search_path="${1}" relative_path="${2}" depth relative_path_regex declare -n target="${3}" [[ -d "${search_path}" ]] || die "File search directory does not exist \"${search_path}\"" depth="$(echo "${relative_path}" | awk -F'/' '{ print NF }')" relative_path_regex=".*$(echo "${relative_path}" | sed 's/[-.()\/]/\\&/g' 2>/dev/null)" # Without this last grep you will end up finding multiple directories target="$(find "${search_path}" -mindepth "$((depth-1))" -maxdepth "$((depth))" -iregex "${relative_path_regex}" 2>/dev/null | grep "${2}")" [[ -f "${target}" ]] || die "File search failed: \"${search_path}${relative_path}\"" } # ini_file_overwrite_value() # Add/Overwrite name=value pair in a specified .ini file section. # Note: Windows .ini files will use \r\n CR linefeeds - don't break this! function ini_file_overwrite_value() { local ini_file="${1}" name="${2}" value="${3}" section="${4}" [[ -f "${ini_file}" ]] || die ".ini file path not valid: \"${ini_file}\"" # shellcheck disable=SC1004 sed -i -e '\|^'"${name}"'=|d' -e '\|^\['"${section}"'\]|a\ '"${name}=${value}\\r" "${ini_file}" 2>/dev/null \ || die "sed operation failed on: \"${ini_file}\"" } # I don't like it when scripts are messy and dirty like they lack a main function. # Makes it so much harder to read them. function main { [[ -z "${WINEPREFIX}" ]] && die "WINEPREFIX env variable not set" [[ -d "${WINEPREFIX}" ]] || die "WINEPREFIX env variable is set to an invalid path: \"${WINEPREFIX}\"" ((EUID==0)) && die "Do not run this script as the root user!" # Get Wine user 'My Documents' folder from Wine Registry. get_registry_value "${USER_SHELL_FOLDERS_REGISTRY_KEY}" \ 'Personal' "WINDOWS_USER_DOCUMENTS_PATH" convert_windows_to_unix_path "${WINDOWS_USER_DOCUMENTS_PATH}" "UNIX_USER_DOCUMENTS_PATH" # Get install directory of Fallout 4 from Wine Registry. get_registry_value "${FALLOUT4_INSTALL_REGISTRY_KEY}" \ 'installed path' "WINDOWS_FALLOUT4_INSTALL_PATH" convert_windows_to_unix_path "${WINDOWS_FALLOUT4_INSTALL_PATH}" "UNIX_FALLOUT4_INSTALL_PATH" # Find 2 main Fallout 4 configuration files. find_file "${UNIX_USER_DOCUMENTS_PATH}" '/My Games/Fallout4/Fallout4.ini' "USER_FALLOUT4_INI_FILE" find_file "${UNIX_FALLOUT4_INSTALL_PATH}" 'Fallout4_Default.ini' "GAME_FALLOUT4DEFAULT_INI_FILE" # Set bBackgroundMouse=1 : Switches between the game controlling the mouse position (0) or the operating system (1). ini_file_overwrite_value "${USER_FALLOUT4_INI_FILE}" "bBackgroundMouse" "1" "Controls" ini_file_overwrite_value "${GAME_FALLOUT4DEFAULT_INI_FILE}" "bBackgroundMouse" "1" "Controls" # GrabFullscreen=Y add_registry_value "${WINE_REGISTRY_KEY}\\X11 Driver" 'GrabFullscreen' 'Y' 'REG_SZ' # Version=win7 add_registry_value "${FALLOUT4_APPDEFAULTS_REGISTRY_KEY}" 'Version' 'win7' 'REG_SZ' # Setup winetricks xact winetricks -q --force xact &>/dev/null || die "winetricks xact failed" # Move xact audio Dll Overrides to Fallout 4 AppDefaults. So this set of DLL Overrides # doesn't affect other games/applications in the same Wineprefix. for dll in "xaudio2_0" "xaudio2_1" "xaudio2_2" "xaudio2_3" "xaudio2_4" "xaudio2_5" "xaudio2_6" "xaudio2_7" "x3daudio1_0" "x3daudio1_1" "x3daudio1_2" "x3daudio1_3" "x3daudio1_4" "x3daudio1_5" "x3daudio1_6" "x3daudio1_7"; do delete_registry_value "${WINE_REGISTRY_KEY}\\DllOverrides" "*${dll}" delete_registry_value "${WINE_REGISTRY_KEY}\\DllOverrides" "*${dll}" delete_registry_value "${FALLOUT4_APPDEFAULTS_REGISTRY_KEY}\\DllOverrides" "*${dll}" add_registry_value "${FALLOUT4_APPDEFAULTS_REGISTRY_KEY}\\DllOverrides" "${dll}" 'native,builtin' 'REG_SZ' done # Delete all xact DLL Overrides we don't required (2D audio as well?) for dll in "xapofx1_1" "xapofx1_2" "xapofx1_3" "xapofx1_4" "xapofx1_5"; do delete_registry_value "${WINE_REGISTRY_KEY}\\DllOverrides" "${dll}" delete_registry_value "${WINE_REGISTRY_KEY}\\DllOverrides" "*${dll}" done } main $@