#!/usr/bin/env bash # Launch the built benilla client against the local TurtleWoW install. # # ./run.sh # release build, TurtleWoW data, saved settings # ./run.sh --release # (same; argument is passed through to the client) # WOW_DATA=/path/to/Data ./run.sh # WOW_HOST=logon.turtle-wow.org ./run.sh # # Every run is logged. Two files, both overwritten-by-symlink each run so the newest is always at # the same path: # # logs/latest.log everything the client printed, as it appeared on screen # logs/errors.log just the addon/Lua failures, newest run only — this is the one to share # # The client already reports every addon and Lua error through its logger; until now that scrolled # past in the terminal and was gone. Nothing needs to be screenshotted or copied out of the game. # # The realm comes from benilla-config/config.toml (or the Realmlist button on the login # screen). Set WOW_HOST to override it for this run without touching the file; set WOW_USER # and WOW_PASS to skip the login screen. set -euo pipefail root="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$root" # The game data folder. Defaults to the TurtleWoW install; override with WOW_DATA. : "${WOW_DATA:=$HOME/Games/New-Octo/Data}" export WOW_DATA if [ ! -d "$WOW_DATA" ]; then echo "run: no Data folder at $WOW_DATA — set WOW_DATA=$HOME/Games/New-Octo/Data" >&2 exit 1 fi bin="$root/target/release/benilla" # Always build, never gate on the binary existing: cargo is the thing that knows whether anything # changed, and it is a fast no-op when nothing did. Gating on existence silently runs a stale # binary after every edit, which looks exactly like "my change did nothing". echo "run: building (release)…" cargo build --release -p benilla logs="$root/logs" mkdir -p "$logs" stamp="$(date +%Y-%m-%d_%H-%M-%S)" log="$logs/run_$stamp.log" ln -sfn "$log" "$logs/latest.log" echo "run: $bin (data: $WOW_DATA${WOW_HOST:+, realm: $WOW_HOST})" echo "run: logging to $log" # `tee` so the terminal still shows everything live while the file keeps it. `pipefail` is off for # just this pipeline: with it on, the shell would report tee's status instead of the client's, and # a Ctrl-C through tee would look like a client crash. set +o pipefail "$bin" "$@" 2>&1 | tee "$log" status=${PIPESTATUS[0]} set -o pipefail # The errors file is filtered *after* the run rather than through a second tee, so a crash cannot # leave it half-written. `ui_script` is the client's own tag for every addon and Lua failure; # `panicked`/`RUST_BACKTRACE` catch a client-side crash, which reads completely differently from an # addon bug and should not be mistaken for one. errors="$logs/errors_$stamp.log" # `-A 6` deliberately: a Lua failure's stack traceback and a panic's message body are on the # lines *after* the matched one, and those are the half that says where it came from. grep -aE -A 6 "ui_script|panicked|RUST_BACKTRACE|^thread " "$log" > "$errors" || true ln -sfn "$errors" "$logs/errors.log" n=$(grep -ac . "$errors" || true) if [ "${n:-0}" -gt 0 ]; then echo "run: $n error line(s) → $errors (symlinked as logs/errors.log)" else echo "run: no addon or Lua errors logged" fi exit "$status"