From 542c2ac04be8ecee1d09a8855ed10fb694e78e16 Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 31 Aug 2026 20:16:13 +0700 Subject: [PATCH] being summoned is a dialog, and a soulstone raises you where you fell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - being summoned becomes the dialog it should have been: the summon request was a name-table entry and nothing else, so a warlock's ritual, a meeting stone and a GM's summon all ended with the summoned player seeing nothing — now the three-field question raises CONFIRM_SUMMON and Accept sends the one guid back; the bytes settled three things a reasonable guess gets wrong: the refusal gate is dead OR ghost and lives in the handler (a ghost's wire health is 1, so the health leg alone lets one through — and refusing before the latch means an ill-timed summon can't silently overwrite a live question), the event carries no arguments because the popup re-reads all three getters every frame (the only way the summoner's name can appear after a cache miss), and there is no decline — Cancel, ESC and the clock running out are all silence plus the server's own two-minute timer; exercised end to end by a two-client live probe, the only thing that can, whose final assertion is that you land in the zone the dialog named - self-resurrect is one private field and one bodyless opcode: PLAYER_SELF_RES_SPELL carries the stored spell and CMSG_SELF_RES spends it; HasSoulstone answers the Spell.dbc NAME of that spell, because that is where Blizzard put the button text — "Use Soulstone", "Reincarnation" and "Twisting Nether" are the spells' own names — and UseSoulstone sends on the death dialog's second button; a --self-res probe runs the whole arc on the live wire and measured the thing that matters: the field arrives BEFORE the health-zero flush, which is what makes the dialog's OnShow read safe - the decode's fold-in corrected three claims we were resting on: HasSoulstone has a dead gate that runs FIRST, so a released ghost (wire health 1) loses the button at release rather than the dialog merely hiding; a zero field is not the empty answer — the client walks your carried inventory (gear, bags, backpack, keyring; no bank, no buyback) for an item whose on-use spell self-resurrects, labels the button with the ITEM's name and uses the item instead of sending, the two legs exclusive; and an unresolvable spell id labels the button "UNKNOWN" rather than hiding a self-res the server is holding for you Co-Authored-By: Claude Fable 5 --- .../benilla-app/assets/ui/ConfirmSummon.xml | 93 ++++ crates/benilla-app/assets/ui/DeathFrame.xml | 27 +- crates/benilla-app/assets/ui/UiPanels.xml | 25 +- crates/benilla-app/assets/ui/benilla.toc | 6 + crates/benilla-app/src/death.rs | 343 ++++++++++++++ crates/benilla-app/src/lib.rs | 6 + crates/benilla-app/src/net.rs | 11 + crates/benilla-app/src/net/apply.rs | 31 ++ crates/benilla-app/src/net/io.rs | 2 + crates/benilla-app/src/ui_items/mod.rs | 21 + .../benilla-app/src/ui_script/death_tests.rs | 88 +++- crates/benilla-app/src/ui_script/mod.rs | 3 + .../benilla-app/src/ui_script/summon_tests.rs | 278 +++++++++++ crates/benilla-app/src/ui_summon.rs | 432 ++++++++++++++++++ .../src/bin/benilla-world/main.rs | 25 +- .../src/bin/benilla-world/probes/mod.rs | 2 + .../src/bin/benilla-world/probes/self_res.rs | 176 +++++++ .../src/bin/benilla-world/world.rs | 6 +- crates/benilla-protocol/src/events.rs | 11 + crates/benilla-protocol/src/events/decode.rs | 9 + crates/benilla-protocol/src/messages/mod.rs | 2 + .../benilla-protocol/src/messages/opcode.rs | 18 + .../benilla-protocol/src/messages/packet.rs | 10 + crates/benilla-protocol/src/messages/parse.rs | 14 +- .../benilla-protocol/src/messages/summon.rs | 107 +++++ .../src/messages/update_object/fields/mod.rs | 14 +- .../messages/update_object/fields/player.rs | 23 + .../messages/update_object/fields/tests.rs | 21 + crates/benilla-protocol/src/world/session.rs | 7 + .../src/world/writer/death.rs | 15 +- .../benilla-protocol/src/world/writer/mod.rs | 1 + .../src/world/writer/summon.rs | 27 ++ crates/benilla-ui/src/script/death.rs | 46 +- crates/benilla-ui/src/script/mod.rs | 3 + crates/benilla-ui/src/script/model.rs | 12 + crates/benilla-ui/src/script/summon.rs | 113 +++++ 36 files changed, 1992 insertions(+), 36 deletions(-) create mode 100644 crates/benilla-app/assets/ui/ConfirmSummon.xml create mode 100644 crates/benilla-app/src/ui_script/summon_tests.rs create mode 100644 crates/benilla-app/src/ui_summon.rs create mode 100644 crates/benilla-protocol/src/bin/benilla-world/probes/self_res.rs create mode 100644 crates/benilla-protocol/src/messages/summon.rs create mode 100644 crates/benilla-protocol/src/world/writer/summon.rs create mode 100644 crates/benilla-ui/src/script/summon.rs diff --git a/crates/benilla-app/assets/ui/ConfirmSummon.xml b/crates/benilla-app/assets/ui/ConfirmSummon.xml new file mode 100644 index 00000000..0232d3c2 --- /dev/null +++ b/crates/benilla-app/assets/ui/ConfirmSummon.xml @@ -0,0 +1,93 @@ + + + + + + + + + + self:RegisterEvent("CONFIRM_SUMMON") + + BenillaConfirmSummonDriver_OnEvent() + + + diff --git a/crates/benilla-app/assets/ui/DeathFrame.xml b/crates/benilla-app/assets/ui/DeathFrame.xml index 5b71867b..a00d638d 100644 --- a/crates/benilla-app/assets/ui/DeathFrame.xml +++ b/crates/benilla-app/assets/ui/DeathFrame.xml @@ -1,7 +1,8 @@