fix(WG): defer ClearFakePlayer to OnPlayerUpdateZone#147
Merged
Conversation
OnBattlefieldPlayerLeaveZone fires from BattlefieldMgr BEFORE core's Battlefield::HandlePlayerLeaveZone runs. Calling ClearFakePlayer there flipped m_team back to the real team, after which core's PlayersInWar[GetTeamId()].erase keyed on the wrong team and orphaned the assigned-team entry until the next StartBattle. Symptoms when a fake player left WG mid-war (e.g. `.tele dalaran`): - PlayersInWar[ASSIGNED] retained the GUID for the rest of the battle, visible in `.bf queue` as the same player on both factions after a subsequent re-entry produced a fresh invite to the real team. - OnPlayerLeaveWar / OnBattlefieldPlayerLeaveWar never fired (the `if (PlayersInWar[team].erase(...))` guard returned false), so group cleanup and the leave message were skipped. - HasWarVacancy was off by one for the assigned team for the rest of the battle. Also restores the intent of OnPlayerLogout's "keep fake intact during war for relog" gate: Player::RemoveFromWorld calls HandlePlayerLeaveZone (triggering the buggy clear) before OnPlayerLogout runs, so the fake was being cleared at logout regardless of war state. Fix: defer ClearFakePlayer to a new OnPlayerUpdateZone hook, which fires at the end of Player::UpdateZone after all leave/enter zone callbacks have completed. Core sees the assigned m_team throughout its cleanup. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6 tasks
Nyeriah
added a commit
that referenced
this pull request
May 30, 2026
OnBattlefieldPlayerLeaveZone stopped clearing the fake in #147, and the deferred OnPlayerUpdateZone path added alongside #148 has an InBattleground() guard that prevents the clear once the teleport lands on the BG map. The WG fake therefore persists into the BG, where it short-circuits both BalanceTeamsOnEntry (its IsPlayerFake guard) and SetFakeRaceAndMorph (same guard), and can desync bgTeamId from GetTeamId() -- most visibly when a player queues for a BG before WG war pops, gets faked Horde mid-queue, and lands on the Alliance queue-side with a Horde faction and visual. Clear any pre-existing fake at the top of ValidatePlayerForBG so the BG entry path re-evaluates against bgTeamId. The #147 timing concern does not apply here -- Battlefield::HandlePlayerLeaveZone has already finished by the time Battleground::AddPlayer runs on the new map. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
OnBattlefieldPlayerLeaveZonefires fromBattlefieldMgrbefore core'sBattlefield::HandlePlayerLeaveZoneruns. CallingClearFakePlayerthere flippedm_teamback to the real team, after which core'sPlayersInWar[GetTeamId()].erasekeyed on the wrong team and orphaned the assigned-team entry until the nextStartBattle.Symptoms
When a fake player left WG mid-war (e.g.
.tele dalaran):PlayersInWar[ASSIGNED]retained the GUID for the rest of the battle. A subsequent re-entry produced a fresh invite to the real team while the assigned-team war entry stayed live —.bf queueshowed the same player listed on both factions.OnPlayerLeaveWar/OnBattlefieldPlayerLeaveWarnever fired (theif (PlayersInWar[team].erase(...))guard returned false), so group cleanup and the leave message were skipped.HasWarVacancywas off by one for the assigned team for the rest of the battle.Also restores the intent of
OnPlayerLogout's "keep fake intact during war for relog" gate:Player::RemoveFromWorldcallsHandlePlayerLeaveZone(triggering the buggy clear) beforeOnPlayerLogoutruns, so the fake was being cleared at logout regardless of war state.Fix
Defer
ClearFakePlayerto a newOnPlayerUpdateZonehook, which fires at the end ofPlayer::UpdateZoneafter all Battlefield/OutdoorPvP/WorldState leave+enter callbacks have completed. Core sees the assignedm_teamthroughout its cleanup. The_wgWarPlayerssafety erase inOnBattlefieldPlayerLeaveZoneis kept; only theClearFakePlayercall moves.Test plan
.tele dalaranmid-war → verifym_teamflips back to Horde, faction restored, no orphan in.bf queue.tele wintergraspback → verify single clean invite on Horde, no Alliance ghost in.bf queueOnBattlefieldWarEndpath still restores faction (no regression)AI tool usage: this PR was authored with Claude Code (Opus 4.7).