From d26c2a354912a6f23870137eeaade489de05c600 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 5 Oct 2025 16:15:09 +1100 Subject: [PATCH] fix: Clean visibility references before bot teleport to prevent crash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add PLAYERHOOK_ON_BEFORE_TELEPORT to proactively clean visibility references when a bot teleports between maps. This prevents a race condition where: 1. Bot A teleports and its visible objects start getting cleaned up 2. Bot B is simultaneously updating visibility and tries to access objects in Bot A's old visibility map 3. Those objects may already be freed, causing a segmentation fault at GridNotifiers.cpp:65 in IsWorldObjectOutOfSightRange() The fix only affects bots to avoid changing behavior for real players. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/Playerbots.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/Playerbots.cpp b/src/Playerbots.cpp index b5334ba7..e3059056 100644 --- a/src/Playerbots.cpp +++ b/src/Playerbots.cpp @@ -87,7 +87,8 @@ public: PLAYERHOOK_ON_BEFORE_CRITERIA_PROGRESS, PLAYERHOOK_ON_BEFORE_ACHI_COMPLETE, PLAYERHOOK_CAN_PLAYER_USE_PRIVATE_CHAT, - PLAYERHOOK_ON_GIVE_EXP + PLAYERHOOK_ON_GIVE_EXP, + PLAYERHOOK_ON_BEFORE_TELEPORT }) {} void OnPlayerLogin(Player* player) override @@ -121,6 +122,26 @@ public: } } + bool OnPlayerBeforeTeleport(Player* player, uint32 mapid, float /*x*/, float /*y*/, float /*z*/, float /*orientation*/, uint32 /*options*/, Unit* /*target*/) override + { + // Only apply to bots to prevent affecting real players + if (!player || !player->GetSession()->IsBot()) + return true; + + // If changing maps, proactively clean visibility references to prevent + // stale pointers in other players' visibility maps during the teleport. + // This fixes a race condition where: + // 1. Bot A teleports and its visible objects start getting cleaned up + // 2. Bot B is simultaneously updating visibility and tries to access objects in Bot A's old visibility map + // 3. Those objects may already be freed, causing a segmentation fault + if (player->GetMapId() != mapid && player->IsInWorld()) + { + player->GetObjectVisibilityContainer().CleanVisibilityReferences(); + } + + return true; // Allow teleport to continue + } + void OnPlayerAfterUpdate(Player* player, uint32 diff) override { if (PlayerbotAI* botAI = GET_PLAYERBOT_AI(player))