Skip to content

fix(aura): identify a cached aura by its caster and descriptor slot - #21

Open
fuffc wants to merge 1 commit into
brues-code:masterfrom
fuffc:fix/aura-source-per-caster-identity
Open

fix(aura): identify a cached aura by its caster and descriptor slot#21
fuffc wants to merge 1 commit into
brues-code:masterfrom
fuffc:fix/aura-source-per-caster-identity

Conversation

@fuffc

@fuffc fuffc commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Two casters of one spell on one target are two auras in two descriptor slots, but Aura::Source held a single entry per (target, spellId). The second cast overwrote the first caster's casterGuid and timing, and OnAuraRemoved for either copy evicted the entry backing the survivor.

Observable from Lua, with a same-class groupmate debuffing your target: sourceUnit names the wrong caster, so a PLAYER-filtered query drops your own debuff; and the base-duration estimate stored for the other caster elapses while your talent-extended aura is still up, which PushEnriched reports as expirationTime = 0 — an aura on the unit with no timer at all.

Entries are now keyed (target, spellId, caster), the identity the server uses. Recovering which instance a descriptor slot holds needs the two halves joined: SpellGo knows the caster but no slot, OnAuraAdded knows the slot but no caster, and they arrive in that order, so the application hook seats its slot on the newest cast capture still awaiting one. Get takes that slot and resolves by it first, falling back to the unit's sole entry for the spell — every single-caster case, and the paths with no descriptor to read a slot from. Several entries and no binding resolves to a miss: the caller's unknown-caster defaults beat a coin flip between two casters.

OnAuraRemoved and EvictAbsent retire the instance in the vacated slot rather than every entry sharing its spell ID.

Two casters of one spell on one target are two auras in two descriptor
slots, but `Aura::Source` held a single entry per `(target, spellId)`.
The second cast overwrote the first caster's `casterGuid` and timing, and
`OnAuraRemoved` for either copy evicted the entry backing the survivor.

Observable from Lua, with a same-class groupmate debuffing your target:
`sourceUnit` names the wrong caster, so a `PLAYER`-filtered query drops
your own debuff; and the base-duration estimate stored for the other
caster elapses while your talent-extended aura is still up, which
`PushEnriched` reports as `expirationTime = 0` — an aura on the unit with
no timer at all.

Entries are now keyed `(target, spellId, caster)`, the identity the server
uses. Recovering which instance a descriptor slot holds needs the two
halves joined: SpellGo knows the caster but no slot, `OnAuraAdded` knows
the slot but no caster, and they arrive in that order, so the application
hook seats its slot on the newest cast capture still awaiting one.
`Get` takes that slot and resolves by it first, falling back to the unit's
sole entry for the spell — every single-caster case, and the paths with no
descriptor to read a slot from. Several entries and no binding resolves to
a miss: the caller's unknown-caster defaults beat a coin flip between two
casters.

`OnAuraRemoved` and `EvictAbsent` retire the instance in the vacated slot
rather than every entry sharing its spell ID.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant