#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/common.sh" usage() { cat <<'EOF' Usage: ./scripts/validate-build.sh dist/Elsword-GE-10-34 Elsword-GE-10-34 EOF } tool_dir="${1:-}" tool_name="${2:-}" [[ -n "$tool_dir" && -n "$tool_name" ]] || { usage >&2 exit 1 } pass() { printf "[ok] %s\n" "$1" } fail() { printf "[fail] %s\n" "$1" >&2 exit 1 } check_exists() { local path="$1" local label="$2" [[ -e "$path" ]] && pass "$label" || fail "$label" } check_contains() { local path="$1" local needle="$2" local label="$3" grep -Fq "$needle" "$path" && pass "$label" || fail "$label" } dump_dll_report() { local dll_path="$1" local label="$2" local deps arch arch="$(objdump -f "$dll_path" | awk -F'file format ' '/file format/ {print $2}' | head -n1)" deps="$(objdump -p "$dll_path" | awk '/DLL Name:/ {print $3}' | sort -u | paste -sd',' -)" printf "[dll] %s arch=%s deps=%s\n" "$label" "${arch:-unknown}" "${deps:-none}" } check_packaged_runtime_deps() { local dll_path="$1" local search_dir="$2" local dep while read -r dep; do [[ -n "$dep" ]] || continue if ! printf '%s\n' "${runtime_dll_names[@]}" | grep -Fxq "$dep"; then printf "[dep] %s requires %s ... provided by Wine/Windows runtime\n" "$(basename "$dll_path")" "$dep" continue fi printf "[dep] %s requires %s ... " "$(basename "$dll_path")" "$dep" if [[ -f "$search_dir/$dep" || -f "$(dirname "$dll_path")/$dep" ]]; then printf "present\n" else printf "missing\n" >&2 exit 1 fi done < <(objdump -p "$dll_path" | awk '/DLL Name:/ {print $3}') } check_exists "$tool_dir/compatibilitytool.vdf" "compatibilitytool.vdf exists" check_exists "$tool_dir/proton" "proton wrapper exists" [[ -x "$tool_dir/proton" ]] && pass "proton wrapper executable" || fail "proton wrapper executable" check_contains "$tool_dir/compatibilitytool.vdf" "\"$tool_name\"" "tool name in compatibilitytool.vdf matches" check_contains "$tool_dir/compatibilitytool.vdf" "\"display_name\" \"$tool_name\"" "display_name in compatibilitytool.vdf matches" for dll in d3d9.dll dxgi.dll d3d10core.dll d3d11.dll; do check_exists "$tool_dir/files/lib/wine/dxvk/i386-windows/$dll" "$dll x86 exists" check_exists "$tool_dir/files/lib/wine/dxvk/x86_64-windows/$dll" "$dll x64 exists" done check_contains "$tool_dir/proton" 'os.environ.setdefault("PROTON_DISCORD_BRIDGE", "0")' "PROTON_DISCORD_BRIDGE default 0 in wrapper" check_contains "$tool_dir/proton" 'os.environ.setdefault("PROTON_USE_OPTISCALER", "0")' "PROTON_USE_OPTISCALER default 0 in wrapper" check_contains "$tool_dir/proton" 'os.environ.setdefault("PROTON_USE_D7VK", "0")' "PROTON_USE_D7VK default 0 in wrapper" check_contains "$tool_dir/proton" 'os.environ.setdefault("MANGOHUD", "0")' "MANGOHUD default 0 in wrapper" check_contains "$tool_dir/proton" 'os.environ.setdefault("ENABLE_VKBASALT", "0")' "ENABLE_VKBASALT default 0 in wrapper" if grep -Fq 'LOW_LATENCY_LAYER' "$tool_dir/proton" && grep -Fq 'LOW_LATENCY_LAYER", "0"' "$tool_dir/proton"; then fail "LOW_LATENCY_LAYER must not be hard-disabled" else pass "LOW_LATENCY_LAYER not hard-disabled" fi for dll in d3d9.dll dxgi.dll d3d10core.dll d3d11.dll; do dump_dll_report "$tool_dir/files/lib/wine/dxvk/i386-windows/$dll" "x86 $dll" dump_dll_report "$tool_dir/files/lib/wine/dxvk/x86_64-windows/$dll" "x64 $dll" check_packaged_runtime_deps "$tool_dir/files/lib/wine/dxvk/i386-windows/$dll" "$tool_dir/files/share/default_pfx/drive_c/windows/syswow64" check_packaged_runtime_deps "$tool_dir/files/lib/wine/dxvk/x86_64-windows/$dll" "$tool_dir/files/share/default_pfx/drive_c/windows/system32" done for runtime_dll in "${runtime_dll_names[@]}"; do if objdump -p "$tool_dir/files/lib/wine/dxvk/i386-windows/"*.dll | grep -Fq "$runtime_dll"; then check_exists "$tool_dir/files/share/default_pfx/drive_c/windows/syswow64/$runtime_dll" "$runtime_dll present for x86 if needed" fi if objdump -p "$tool_dir/files/lib/wine/dxvk/x86_64-windows/"*.dll | grep -Fq "$runtime_dll"; then check_exists "$tool_dir/files/share/default_pfx/drive_c/windows/system32/$runtime_dll" "$runtime_dll present for x64 if needed" fi done