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:
+15
-38
@@ -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')"
|
||||
|
||||
Reference in New Issue
Block a user