comments: the scripts say what they do and how to run them

Each header is a one-line summary, the environment it reads and its
usage; the history, measurements and record numbers go. Only comment
lines change: with comments stripped the scripts are byte-identical.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sam
2026-09-23 19:23:35 +07:00
co-authored by Claude Opus 5.5
parent 449324b7be
commit b484fe0d27
10 changed files with 123 additions and 375 deletions
+15 -38
View File
@@ -1,27 +1,11 @@
#!/usr/bin/env bash
# **The two-client live summon probe** (decision 1747) — the instrument that closes the loop on
# being summoned, because nothing smaller can.
# Two-client live summon probe: a second account summons this checkout's character, which accepts.
#
# The summon flow is the one confirm in the client that a single session cannot exercise at all:
# vmangos has exactly two `SendSummonRequest` callers (`Spell::EffectSummonPlayer` and
# `HandleGroupSummonCommand`), and **both skip you** — the ritual needs a warlock plus two
# clickers, and `.group summon` explicitly `continue`s past the caster. So the question can only
# be asked by somebody else, and the whole seam behind it (apply → feed → VM → drain → wire) is
# exactly the part unit tests cannot reach.
#
# What it does: a summoner client on a second account invites this checkout's probe character
# into a group and runs `.group summon`; the receiver reads its own CONFIRM_SUMMON dialog back
# through `ProbeLog`, presses Accept, and re-reads its zone once the teleport has landed. The
# receiver also writes the `summon` trace tag, so all three links report:
#
# summon recv SMSG_SUMMON_REQUEST summoner=… zone=… delay_ms=… dead_or_ghost=false
# summon fire CONFIRM_SUMMON summoner=… zone=…
# summon SEND CMSG_SUMMON_RESPONSE summoner=… n=1
#
# **The summoner is a second account the shell names** — `SUMMON_USER`, `SUMMON_PASS`,
# `SUMMON_CHAR`, a GM-level test account whose login kicks nobody. The summoner's run carries
# `WOW_ALLOW_ACCOUNT=1`, because it is not the account this checkout declares; that the shell
# named it is what makes the override legitimate.
# Both vmangos summon-request callers skip the caster (`Spell::EffectSummonPlayer`,
# `HandleGroupSummonCommand`), so a second client summons. The summoner is SUMMON_USER/
# SUMMON_PASS/SUMMON_CHAR, a GM test account whose login kicks nobody; the receiver is
# `.probe-identity`, else WOW_USER/WOW_PASS/WOW_CHAR. WOW_HOST is the server, SUMMON_LIVE_KEEP=1
# keeps the logs.
#
# SUMMON_USER=… SUMMON_PASS=… SUMMON_CHAR=… scripts/summon-live.sh # ~90 s, two small windows
set -uo pipefail
@@ -31,13 +15,11 @@ root="$(git -C "$PWD" rev-parse --show-toplevel 2>/dev/null || true)"
cd "$root" || exit 1
echo "summon-live: $root"
# The receiver is this run's own identity — smoke.sh's rule (scripts/probe-identity.sh), for its
# reason: a login kicks whoever holds the account.
# The receiver logs in as this checkout's identity: a login kicks whoever holds the account.
. "$root/scripts/probe-identity.sh"
probe_identity summon-live "$root" || exit 1
rx_user="$PROBE_USER"; rx_pass="$PROBE_PASS"; rx_char="$PROBE_CHAR"
# The summoner is the shell's to name (see the header).
if [ -z "${SUMMON_USER:-}" ] || [ -z "${SUMMON_PASS:-}" ] || [ -z "${SUMMON_CHAR:-}" ]; then
echo "summon-live: REFUSING — the summoner needs a second account: SUMMON_USER, SUMMON_PASS"
echo " and SUMMON_CHAR, a GM-level test account whose login kicks nobody."
@@ -48,16 +30,14 @@ echo "summon-live: $tx_char ($tx_user) summons $rx_char ($rx_user)"
probe_server_or_skip summon-live || exit 0
# Build once, so the two `cargo run`s below start together instead of one waiting on the other's
# build lock — the timings are wall-clock from process start (smoke.sh's build-then-time rule).
# Build first so both clients start together: the probe timings count from process start.
echo "summon-live: building…"
cargo build -q -p benilla || { echo "summon-live: the client did not build"; exit 1; }
work="$(mktemp -d "${TMPDIR:-/tmp}/benilla-summon.XXXXXX")"
trap '[ -n "${SUMMON_LIVE_KEEP:-}" ] || rm -rf "$work"' EXIT
# The receiver's chunk. `tostring` on every getter on purpose: a missing dialog must REPORT rather
# than raise at line 2, or a failed run says "attempt to concatenate a nil value" and names nothing.
# The receiver's Lua: `tostring` on every getter, so a missing dialog reports instead of raising.
read -r -d '' chunk <<'LUA'
ProbeLog("dialog visible=" .. tostring(StaticPopup1:IsVisible()))
ProbeLog("dialog text=[" .. tostring(StaticPopup1Text:GetText()) .. "]")
@@ -81,10 +61,8 @@ end)
LUA
echo "summon-live: running (~90 s, opens two windows)…"
# **The receiver is parked first, and the run is worthless without it.** Its character starts
# wherever the last run left it — which, after one green run, is the destination — so a
# before/after zone compare silently stops discriminating on the second run. It did exactly that.
# Parking in Stormwind makes "before" the same on every run, whatever the previous one did.
# The receiver parks in Stormwind first: a green run leaves it at the destination, and the
# before/after zone compare needs the same "before" on every run.
WOW_UNATTENDED=1 WOW_NOSOUND=1 WOW_USER="$rx_user" WOW_PASS="$rx_pass" WOW_CHAR="$rx_char" \
WOW_PROBE=partner \
WOW_PROBE_CHAT=".go xyz -8913 554 94" WOW_PROBE_CHAT_AT=10 \
@@ -94,8 +72,8 @@ WOW_UNATTENDED=1 WOW_NOSOUND=1 WOW_USER="$rx_user" WOW_PASS="$rx_pass" WOW_CHAR=
timeout 150 cargo run -q -p benilla >"$work/rx.log" 2>&1 &
rx=$!
# `WOW_ALLOW_ACCOUNT=1` is the account guard's own escape hatch, and the shell naming the account
# is what earns it. `.group summon` rather than `.summon`: the latter teleports without ever asking.
# WOW_ALLOW_ACCOUNT=1 lifts the account guard for the shell-named summoner. `.group summon`, not
# `.summon`, because `.summon` teleports without asking.
WOW_UNATTENDED=1 WOW_NOSOUND=1 WOW_USER="$tx_user" WOW_PASS="$tx_pass" WOW_CHAR="$tx_char" WOW_ALLOW_ACCOUNT=1 \
WOW_PROBE_CHAT="/invite $rx_char;.group summon" \
WOW_PROBE_CHAT_AT=18 WOW_PROBE_CHAT_EVERY=10 \
@@ -128,9 +106,8 @@ printf '%s' "$trace" | grep -q "recv SMSG_SUMMON_REQUEST" ||
printf '%s' "$trace" | grep -q "fire CONFIRM_SUMMON" || fail "the request landed but no event fired"
printf '%s' "$trace" | grep -q "SEND CMSG_SUMMON_RESPONSE" || fail "Accept sent no packet"
printf '%s' "$plog" | grep -q "wants to summon you to" || fail "the dialog text never composed"
# The two that cannot be faked by any amount of client-side bookkeeping: the character actually
# moved, and it moved to **the place the dialog named**. The second is what ties
# GetSummonConfirmAreaName to reality rather than to our own AreaTable lookup agreeing with itself.
# The character must move, and land where the dialog said: that ties GetSummonConfirmAreaName to
# the server rather than to our own AreaTable lookup.
before="$(printf '%s' "$plog" | sed -n 's/^zone before=\[\(.*\)\]$/\1/p')"
after="$(printf '%s' "$plog" | sed -n 's/^zone after=\[\(.*\)\]$/\1/p')"
area="$(printf '%s' "$plog" | sed -n 's/^area=\[\(.*\)\]$/\1/p')"