Skip to content

fix(WG): defer ClearFakePlayer to OnPlayerUpdateZone#147

Merged
Nyeriah merged 1 commit into
azerothcore:masterfrom
Nyeriah:fix/wg-defer-clearfakeplayer
May 26, 2026
Merged

fix(WG): defer ClearFakePlayer to OnPlayerUpdateZone#147
Nyeriah merged 1 commit into
azerothcore:masterfrom
Nyeriah:fix/wg-defer-clearfakeplayer

Conversation

@Nyeriah
Copy link
Copy Markdown
Member

@Nyeriah Nyeriah commented May 26, 2026

Summary

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. A subsequent re-entry produced a fresh invite to the real team while the assigned-team war entry stayed live — .bf queue showed the same player listed on both factions.
  • 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 Battlefield/OutdoorPvP/WorldState leave+enter callbacks have completed. Core sees the assigned m_team throughout its cleanup. The _wgWarPlayers safety erase in OnBattlefieldPlayerLeaveZone is kept; only the ClearFakePlayer call moves.

Test plan

  • Join WG as Horde, get auto-flipped to Alliance by CFBG balancing
  • .tele dalaran mid-war → verify m_team flips back to Horde, faction restored, no orphan in .bf queue
  • .tele wintergrasp back → verify single clean invite on Horde, no Alliance ghost in .bf queue
  • Let invite timer expire → verify clean kick without lingering reference
  • Logout during war → relog → verify still on assigned team
  • Logout outside war → relog → verify back on real team
  • War-end while fake & in zone → verify existing OnBattlefieldWarEnd path still restores faction (no regression)

AI tool usage: this PR was authored with Claude Code (Opus 4.7).

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>
@Nyeriah Nyeriah merged commit a7d78fd into azerothcore:master May 26, 2026
1 check passed
@Nyeriah Nyeriah deleted the fix/wg-defer-clearfakeplayer branch May 26, 2026 00:40
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>
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