diff options
Diffstat (limited to 'defaults/assets/fgmod.sh')
| -rwxr-xr-x | defaults/assets/fgmod.sh | 335 |
1 files changed, 145 insertions, 190 deletions
diff --git a/defaults/assets/fgmod.sh b/defaults/assets/fgmod.sh index fa36558..7aa62bb 100755 --- a/defaults/assets/fgmod.sh +++ b/defaults/assets/fgmod.sh @@ -1,227 +1,182 @@ #!/usr/bin/env bash +set -euo pipefail set -x -exec > >(tee -i /tmp/fgmod-install.log) 2>&1 +exec > >(tee -i /tmp/fgmod-prefix-managed.log) 2>&1 + +log() { + echo "$*" + logger -t fgmod-prefix-managed "$*" +} error_exit() { - echo "โ $1" - if [[ -n $STEAM_ZENITY ]]; then - $STEAM_ZENITY --error --text "$1" - else - zenity --error --text "$1" || echo "Zenity failed to display error" + local message="$1" + echo "โ $message" + logger -t fgmod-prefix-managed "ERROR: $message" + if [[ -n "${STEAM_ZENITY:-}" ]]; then + "$STEAM_ZENITY" --error --text "$message" || true + elif command -v zenity >/dev/null 2>&1; then + zenity --error --text "$message" || true fi - logger -t fgmod "โ ERROR: $1" exit 1 } -# === CONFIG === -fgmod_path="$HOME/fgmod" -dll_name="${DLL:-dxgi.dll}" -preserve_ini="${PRESERVE_INI:-true}" - -# === Resolve Game Path === -if [[ "$#" -lt 1 ]]; then - error_exit "Usage: $0 program [program_arguments...]" -fi +bundle_root="${HOME}/fgmod" +managed_dir_name="optiscaler-managed" +manifest_name="manifest.env" +proxy_name="${OPTISCALER_PROXY:-${DLL:-winmm}}" +proxy_name="${proxy_name%.dll}" +proxy_dll="${proxy_name}.dll" +backup_dll="${proxy_name}-original.dll" + +support_files=( + "libxess.dll" + "libxess_dx11.dll" + "libxess_fg.dll" + "libxell.dll" + "amd_fidelityfx_dx12.dll" + "amd_fidelityfx_framegeneration_dx12.dll" + "amd_fidelityfx_upscaler_dx12.dll" + "amd_fidelityfx_vk.dll" + "nvngx.dll" + "dlssg_to_fsr3_amd_is_better.dll" + "fakenvapi.dll" + "fakenvapi.ini" +) + +case "$proxy_name" in + winmm|dxgi|version|dbghelp|winhttp|wininet|d3d12) ;; + *) error_exit "Unsupported OPTISCALER_PROXY '$proxy_name'." ;; +esac + +[[ -d "$bundle_root" ]] || error_exit "OptiScaler runtime not installed at $bundle_root" +[[ -n "${STEAM_COMPAT_DATA_PATH:-}" ]] || error_exit "STEAM_COMPAT_DATA_PATH is required. Use this wrapper from a Steam/Proton launch option." +[[ $# -ge 1 ]] || error_exit "Usage: $0 program [program_arguments...]" + +compatdata_path="$STEAM_COMPAT_DATA_PATH" +system32_path="$compatdata_path/pfx/drive_c/windows/system32" +managed_root="$compatdata_path/$managed_dir_name" +manifest_path="$managed_root/$manifest_name" +managed_ini="$managed_root/OptiScaler.ini" +managed_plugins="$managed_root/plugins" + +cleanup_proxy_stage() { + local cleanup_proxy="$1" + local cleanup_proxy_dll="${cleanup_proxy}.dll" + local cleanup_backup_dll="${cleanup_proxy}-original.dll" + + rm -f "$system32_path/$cleanup_proxy_dll" + if [[ -f "$system32_path/$cleanup_backup_dll" ]]; then + mv -f "$system32_path/$cleanup_backup_dll" "$system32_path/$cleanup_proxy_dll" + fi +} -exe_folder_path="" -if [[ $# -eq 1 ]]; then - [[ "$1" == *.exe ]] && exe_folder_path=$(dirname "$1") || exe_folder_path="$1" -else - for arg in "$@"; do - if [[ "$arg" == *.exe ]]; then - [[ "$arg" == *"Cyberpunk 2077"* ]] && arg=${arg//REDprelauncher.exe/bin/x64/Cyberpunk2077.exe} - [[ "$arg" == *"Witcher 3"* ]] && arg=${arg//REDprelauncher.exe/bin/x64_dx12/witcher3.exe} - [[ "$arg" == *"Baldurs Gate 3"* ]] && arg=${arg//Launcher\/LariLauncher.exe/bin/bg3_dx11.exe} - [[ "$arg" == *"HITMAN 3"* ]] && arg=${arg//Launcher.exe/Retail/HITMAN3.exe} - [[ "$arg" == *"HITMAN World of Assassination"* ]] && arg=${arg//Launcher.exe/Retail/HITMAN3.exe} - [[ "$arg" == *"SYNCED"* ]] && arg=${arg//Launcher\/sop_launcher.exe/SYNCED.exe} - [[ "$arg" == *"2KLauncher"* ]] && arg=${arg//2KLauncher\/LauncherPatcher.exe/DoesntMatter.exe} - [[ "$arg" == *"Warhammer 40,000 DARKTIDE"* ]] && arg=${arg//launcher\/Launcher.exe/binaries/Darktide.exe} - [[ "$arg" == *"Warhammer Vermintide 2"* ]] && arg=${arg//launcher\/Launcher.exe/binaries_dx12/vermintide2_dx12.exe} - [[ "$arg" == *"Satisfactory"* ]] && arg=${arg//FactoryGameSteam.exe/Engine/Binaries/Win64/FactoryGameSteam-Win64-Shipping.exe} - [[ "$arg" == *"FINAL FANTASY XIV Online"* ]] && arg=${arg//boot\/ffxivboot.exe/game/ffxiv_dx11.exe} - exe_folder_path=$(dirname "$arg") - break - fi +cleanup_stage_files() { + local cleanup_proxy="$1" + rm -f "$system32_path/OptiScaler.ini" + for file_name in "${support_files[@]}"; do + rm -f "$system32_path/$file_name" done -fi - -for arg in "$@"; do - if [[ "$arg" == lutris:rungameid/* ]]; then - lutris_id="${arg#lutris:rungameid/}" - - # Get slug from Lutris JSON - slug=$(lutris --list-games --json 2>/dev/null | jq -r ".[] | select(.id == $lutris_id) | .slug") - - if [[ -z "$slug" || "$slug" == "null" ]]; then - echo "Could not find slug for Lutris ID $lutris_id" - break - fi - - # Find matching YAML file using slug - config_file=$(find ~/.config/lutris/games/ -iname "${slug}-*.yml" | head -1) - - if [[ -z "$config_file" ]]; then - echo "No config file found for slug '$slug'" - break - fi + rm -f "$system32_path/OptiScaler.log" + rm -rf "$system32_path/plugins" + cleanup_proxy_stage "$cleanup_proxy" +} - # Extract executable path from YAML - exe_path=$(grep -E '^\s*exe:' "$config_file" | sed 's/.*exe:[[:space:]]*//' ) +mkdir -p "$system32_path" "$managed_root" "$managed_plugins" - if [[ -n "$exe_path" ]]; then - exe_folder_path=$(dirname "$exe_path") - echo "Resolved executable path: $exe_path" - echo "Executable folder: $exe_folder_path" - else - echo "Executable path not found in $config_file" - fi +existing_proxy="" +if [[ -f "$manifest_path" ]]; then + # shellcheck disable=SC1090 + source "$manifest_path" + existing_proxy="${MANAGED_PROXY:-}" +fi - break - fi -done +if [[ -n "$existing_proxy" && "$existing_proxy" != "$proxy_name" ]]; then + log "Switching managed proxy from $existing_proxy to $proxy_name" + cleanup_stage_files "$existing_proxy" +fi -[[ -z "$exe_folder_path" && -n "$STEAM_COMPAT_INSTALL_PATH" ]] && exe_folder_path="$STEAM_COMPAT_INSTALL_PATH" +[[ -f "$bundle_root/OptiScaler.ini" ]] || error_exit "Missing OptiScaler.ini in runtime bundle" +[[ -f "$bundle_root/update-optiscaler-config.py" ]] || error_exit "Missing update-optiscaler-config.py in runtime bundle" -if [[ -d "$exe_folder_path/Engine" ]]; then - ue_exe=$(find "$exe_folder_path" -maxdepth 4 -mindepth 4 -path "*Binaries/Win64/*.exe" -not -path "*/Engine/*" | head -1) - exe_folder_path=$(dirname "$ue_exe") +python_bin="python3" +if ! command -v "$python_bin" >/dev/null 2>&1; then + python_bin="python" fi +command -v "$python_bin" >/dev/null 2>&1 || error_exit "Python interpreter not found" -[[ ! -d "$exe_folder_path" ]] && error_exit "โ Could not resolve game directory!" -[[ ! -w "$exe_folder_path" ]] && error_exit "๐ No write permission to the game folder!" +if [[ ! -f "$managed_ini" ]]; then + cp -f "$bundle_root/OptiScaler.ini" "$managed_ini" +fi -logger -t fgmod "๐ข Target directory: $exe_folder_path" -logger -t fgmod "๐งฉ Using DLL name: $dll_name" -logger -t fgmod "๐ Preserve INI: $preserve_ini" +"$python_bin" "$bundle_root/update-optiscaler-config.py" "$managed_ini" +sed -i 's/^UseHQFont[[:space:]]*=[[:space:]]*auto$/UseHQFont=false/' "$managed_ini" || true -# === Cleanup Old Injectors === -rm -f "$exe_folder_path"/{dxgi.dll,winmm.dll,nvngx.dll,_nvngx.dll,nvngx-wrapper.dll,dlss-enabler.dll,OptiScaler.dll} +if [[ -d "$bundle_root/plugins" ]]; then + rm -rf "$managed_plugins" + mkdir -p "$managed_plugins" + cp -f "$bundle_root/plugins"/* "$managed_plugins/" 2>/dev/null || true +fi -# === Optional: Backup Original DLLs === -original_dlls=("d3dcompiler_47.dll" "amd_fidelityfx_dx12.dll" "amd_fidelityfx_framegeneration_dx12.dll" "amd_fidelityfx_upscaler_dx12.dll" "amd_fidelityfx_vk.dll") -for dll in "${original_dlls[@]}"; do - [[ -f "$exe_folder_path/$dll" && ! -f "$exe_folder_path/$dll.b" ]] && mv -f "$exe_folder_path/$dll" "$exe_folder_path/$dll.b" +for file_name in "${support_files[@]}"; do + if [[ -f "$bundle_root/$file_name" ]]; then + cp -f "$bundle_root/$file_name" "$system32_path/$file_name" + fi done -# === Remove nvapi64.dll and its backup (conflicts from previous fakenvapi versions) === -rm -f "$exe_folder_path/nvapi64.dll" "$exe_folder_path/nvapi64.dll.b" -echo "๐งน Cleaned up nvapi64.dll and backup (legacy fakenvapi conflicts)" +if [[ -d "$managed_plugins" ]]; then + rm -rf "$system32_path/plugins" + mkdir -p "$system32_path/plugins" + cp -f "$managed_plugins"/* "$system32_path/plugins/" 2>/dev/null || true +fi -# === Core Install === -if [[ -f "$fgmod_path/renames/$dll_name" ]]; then - echo "โ
Using pre-renamed $dll_name" - cp "$fgmod_path/renames/$dll_name" "$exe_folder_path/$dll_name" || error_exit "โ Failed to copy $dll_name" -else - echo "โ ๏ธ Pre-renamed $dll_name not found, falling back to OptiScaler.dll" - cp "$fgmod_path/OptiScaler.dll" "$exe_folder_path/$dll_name" || error_exit "โ Failed to copy OptiScaler.dll as $dll_name" +if [[ -f "$system32_path/$proxy_dll" && ! -f "$system32_path/$backup_dll" ]]; then + mv -f "$system32_path/$proxy_dll" "$system32_path/$backup_dll" fi -# === OptiScaler.ini Handling === -if [[ "$preserve_ini" == "true" && -f "$exe_folder_path/OptiScaler.ini" ]]; then - echo "๐ Preserving existing OptiScaler.ini (user settings retained)" - logger -t fgmod "๐ Existing OptiScaler.ini preserved in $exe_folder_path" +if [[ -f "$bundle_root/renames/$proxy_dll" ]]; then + cp -f "$bundle_root/renames/$proxy_dll" "$system32_path/$proxy_dll" else - echo "๐ Installing OptiScaler.ini from plugin defaults" - cp "$fgmod_path/OptiScaler.ini" "$exe_folder_path/OptiScaler.ini" || error_exit "โ Failed to copy OptiScaler.ini" - logger -t fgmod "๐ OptiScaler.ini installed to $exe_folder_path" + cp -f "$bundle_root/OptiScaler.dll" "$system32_path/$proxy_dll" fi -# === OptiScaler env variables Handling === -if [[ -f "$fgmod_path/update-optiscaler-config.py" ]]; then - python "$fgmod_path/update-optiscaler-config.py" "$exe_folder_path/OptiScaler.ini" +cp -f "$managed_ini" "$system32_path/OptiScaler.ini" + +runtime_version="unknown" +if [[ -f "$bundle_root/version.txt" ]]; then + runtime_version="$(<"$bundle_root/version.txt")" fi -# OptiScaler 0.9.0-pre11 can assert on Proton when HQ font auto mode tries to load -# an external TTF that is not present. Only normalize the default auto value. -sed -i 's/^UseHQFont[[:space:]]*=[[:space:]]*auto$/UseHQFont=false/' "$exe_folder_path/OptiScaler.ini" || true +cat > "$manifest_path" <<EOF +MANAGED_PROXY="$proxy_name" +BUNDLE_ROOT="$bundle_root" +BUNDLE_VERSION="$runtime_version" +SYSTEM32_PATH="$system32_path" +EOF -# === ASI Plugins Directory === -if [[ -d "$fgmod_path/plugins" ]]; then - echo "๐ Installing ASI plugins directory" - cp -r "$fgmod_path/plugins" "$exe_folder_path/" || true - logger -t fgmod "๐ ASI plugins directory installed to $exe_folder_path" +export SteamDeck=0 +if [[ -n "${WINEDLLOVERRIDES:-}" ]]; then + export WINEDLLOVERRIDES="${WINEDLLOVERRIDES},${proxy_name}=n,b" else - echo "โ ๏ธ No plugins directory found in fgmod" + export WINEDLLOVERRIDES="${proxy_name}=n,b" fi -# === Supporting Libraries === -cp -f "$fgmod_path/libxess.dll" "$exe_folder_path/" || true -cp -f "$fgmod_path/libxess_dx11.dll" "$exe_folder_path/" || true -cp -f "$fgmod_path/libxess_fg.dll" "$exe_folder_path/" || true -cp -f "$fgmod_path/libxell.dll" "$exe_folder_path/" || true -cp -f "$fgmod_path/amd_fidelityfx_dx12.dll" "$exe_folder_path/" || true -cp -f "$fgmod_path/amd_fidelityfx_framegeneration_dx12.dll" "$exe_folder_path/" || true -cp -f "$fgmod_path/amd_fidelityfx_upscaler_dx12.dll" "$exe_folder_path/" || true -cp -f "$fgmod_path/amd_fidelityfx_vk.dll" "$exe_folder_path/" || true -cp -f "$fgmod_path/nvngx.dll" "$exe_folder_path/" || true - -# === Nukem FG Mod Files (now in fgmod directory) === -cp -f "$fgmod_path/dlssg_to_fsr3_amd_is_better.dll" "$exe_folder_path/" || true -# Note: dlssg_to_fsr3.ini is not included in v0.9.0-pre4 archive - -# === FakeNVAPI Files === -# Remove legacy nvapi64.dll to avoid conflicts -# rm -f "$exe_folder_path/nvapi64.dll" -# echo "๐งน Removed legacy nvapi64.dll" - -# Copy fakenvapi.dll with original name (v1.3.8.1) -cp -f "$fgmod_path/fakenvapi.dll" "$exe_folder_path/" || true -cp -f "$fgmod_path/fakenvapi.ini" "$exe_folder_path/" || true -echo "๐ฆ Installed fakenvapi.dll and fakenvapi.ini" - -# === Additional Support Files === -# cp -f "$fgmod_path/d3dcompiler_47.dll" "$exe_folder_path/" || true - -# Note: d3dcompiler_47.dll is not included in v0.9.0-pre4 archive - -echo "โ
Installation completed successfully!" -echo "๐ For Steam, add this to the launch options: \"$fgmod_path/fgmod\" %COMMAND%" -echo "๐ For Heroic, add this as a new wrapper: \"$fgmod_path/fgmod\"" -logger -t fgmod "๐ข Installation completed successfully for $exe_folder_path" - -# === Execute original command === -if [[ $# -gt 1 ]]; then - # Log to both file and system journal - logger -t fgmod "==================" - logger -t fgmod "Debug Info (Launch Mode):" - logger -t fgmod "Number of arguments: $#" - for i in $(seq 1 $#); do - logger -t fgmod "Arg $i: ${!i}" - done - logger -t fgmod "Final executable path: $exe_folder_path" - logger -t fgmod "==================" - - # Execute the original command - export SteamDeck=0 - export WINEDLLOVERRIDES="$WINEDLLOVERRIDES,dxgi=n,b" - - # Filter out leading -- separators (from Steam launch options) - while [[ $# -gt 0 && "$1" == "--" ]]; do - shift - done +while [[ $# -gt 0 && "$1" == "--" ]]; do + shift +done - exec >/dev/null 2>&1 - "$@" -else - echo "Done!" - echo "----------------------------------------" - echo "Debug Info (Standalone Mode):" - echo "Number of arguments: $#" - for i in $(seq 1 $#); do - echo "Arg $i: ${!i}" - done - echo "Final executable path: $exe_folder_path" - echo "----------------------------------------" - - # Also log standalone mode to journal - logger -t fgmod "==================" - logger -t fgmod "Debug Info (Standalone Mode):" - logger -t fgmod "Number of arguments: $#" - for i in $(seq 1 $#); do - logger -t fgmod "Arg $i: ${!i}" - done - logger -t fgmod "Final executable path: $exe_folder_path" - logger -t fgmod "==================" +log "Using compatdata path: $compatdata_path" +log "Using system32 path: $system32_path" +log "Using prefix-managed proxy: $proxy_dll" +log "Using WINEDLLOVERRIDES=$WINEDLLOVERRIDES" + +set +e +"$@" +exit_code=$? +set -e + +if [[ -f "$system32_path/OptiScaler.ini" ]]; then + cp -f "$system32_path/OptiScaler.ini" "$managed_ini" fi + +exit "$exit_code" |
