mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
fix: Clean visibility references before bot teleport to prevent crash
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 <noreply@anthropic.com>
This commit is contained in:
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user