mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
fix(Playerbots): Remove auras before teleporting to prevent crash
Add RemoveAurasWithInterruptFlags call before all TeleportTo operations to prevent race condition crash in battlegrounds. The crash occurs when area auras (like "Entering Battleground") are queued for removal in Aura::UpdateTargetMap's targetsToRemove list, but the unit is deleted before the 500ms update cycle completes, causing SIGSEGV when accessing the dangling pointer. This fix removes auras with AURA_INTERRUPT_FLAG_TELEPORTED and AURA_INTERRUPT_FLAG_CHANGE_MAP before teleporting, matching the behavior in Player::TeleportTo for real players. Affected locations: - BattleGround join/teleport - Spirit healer/graveyard teleport - Corpse resurrection teleport - Meeting stone teleport - Master follow teleport - RPG unstuck teleport - Random bot teleport - Chat command teleport Raid-specific teleports excluded as they require separate testing.
This commit is contained in:
@@ -1853,6 +1853,7 @@ void RandomPlayerbotMgr::RandomTeleport(Player* bot, std::vector<WorldLocation>&
|
||||
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
||||
if (botAI)
|
||||
botAI->Reset(true);
|
||||
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||
bot->TeleportTo(loc.GetMapId(), x, y, z, 0);
|
||||
bot->SendMovementFlagUpdate();
|
||||
|
||||
@@ -3245,6 +3246,7 @@ void RandomPlayerbotMgr::OnPlayerLogin(Player* player)
|
||||
} while (true);
|
||||
}
|
||||
|
||||
player->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||
player->TeleportTo(botPos);
|
||||
|
||||
// player->Relocate(botPos.getX(), botPos.getY(), botPos.getZ(), botPos.getO());
|
||||
|
||||
@@ -176,6 +176,7 @@ bool BGJoinAction::gatherArenaTeam(ArenaType type)
|
||||
continue;
|
||||
|
||||
memberBotAI->Reset();
|
||||
member->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||
member->TeleportTo(bot->GetMapId(), bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), 0);
|
||||
|
||||
LOG_INFO("playerbots", "Bot {} <{}>: Member of <{}>", member->GetGUID().ToString().c_str(),
|
||||
|
||||
@@ -4289,9 +4289,15 @@ bool ArenaTactics::moveToCenter(Battleground* bg)
|
||||
{
|
||||
// they like to hang around at the tip of the pipes doing nothing, so we just teleport them down
|
||||
if (bot->GetDistance(1333.07f, 817.18f, 13.35f) < 4)
|
||||
{
|
||||
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||
bot->TeleportTo(bg->GetMapId(), 1330.96f, 816.75f, 3.2f, bot->GetOrientation());
|
||||
}
|
||||
if (bot->GetDistance(1250.13f, 764.79f, 13.34f) < 4)
|
||||
{
|
||||
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||
bot->TeleportTo(bg->GetMapId(), 1252.19f, 765.41f, 3.2f, bot->GetOrientation());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BATTLEGROUND_RV:
|
||||
|
||||
@@ -106,6 +106,7 @@ bool FollowChatShortcutAction::Execute(Event event)
|
||||
else
|
||||
botAI->TellMaster("You are too far away from me! I will there soon.");
|
||||
|
||||
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||
bot->TeleportTo(master->GetMapId(), master->GetPositionX(), master->GetPositionY(), master->GetPositionZ(),
|
||||
master->GetOrientation()); return true;
|
||||
}
|
||||
|
||||
@@ -1148,6 +1148,7 @@ bool MovementAction::Follow(Unit* target, float distance, float angle)
|
||||
if ((target->GetMap() && target->GetMap()->IsBattlegroundOrArena()) || (bot->GetMap() &&
|
||||
bot->GetMap()->IsBattlegroundOrArena())) return false;
|
||||
|
||||
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||
bot->TeleportTo(target->GetMapId(), x, y, z, bot->GetOrientation());
|
||||
}
|
||||
else
|
||||
@@ -1175,6 +1176,7 @@ bool MovementAction::Follow(Unit* target, float distance, float angle)
|
||||
|
||||
bot->CombatStop(true);
|
||||
botAI->TellMasterNoFacing("I will there soon.");
|
||||
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||
bot->TeleportTo(target->GetMapId(), target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(),
|
||||
target->GetOrientation()); return false;
|
||||
}
|
||||
|
||||
@@ -147,6 +147,7 @@ bool AutoReleaseSpiritAction::HandleBattlegroundSpiritHealer()
|
||||
// and in IOC it's not within clicking range when they res in own base
|
||||
|
||||
// Teleport to nearest friendly Spirit Healer when not currently in range of one.
|
||||
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||
bot->TeleportTo(bot->GetMapId(), spiritHealer->GetPositionX(), spiritHealer->GetPositionY(), spiritHealer->GetPositionZ(), 0.f);
|
||||
RESET_AI_VALUE(bool, "combat::self target");
|
||||
RESET_AI_VALUE(WorldPosition, "current position");
|
||||
@@ -244,6 +245,7 @@ int64 RepopAction::CalculateDeadTime() const
|
||||
|
||||
void RepopAction::PerformGraveyardTeleport(const GraveyardStruct* graveyard) const
|
||||
{
|
||||
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||
bot->TeleportTo(graveyard->Map, graveyard->x, graveyard->y, graveyard->z, 0.f);
|
||||
RESET_AI_VALUE(bool, "combat::self target");
|
||||
RESET_AI_VALUE(WorldPosition, "current position");
|
||||
|
||||
@@ -169,6 +169,7 @@ bool FindCorpseAction::Execute(Event event)
|
||||
if (deadTime > delay)
|
||||
{
|
||||
bot->GetMotionMaster()->Clear();
|
||||
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||
bot->TeleportTo(moveToPos.getMapId(), moveToPos.getX(), moveToPos.getY(), moveToPos.getZ(), 0);
|
||||
}
|
||||
|
||||
@@ -350,6 +351,7 @@ bool SpiritHealerAction::Execute(Event event)
|
||||
// if (!botAI->HasActivePlayerMaster())
|
||||
// {
|
||||
context->GetValue<uint32>("death count")->Set(dCount + 1);
|
||||
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||
return bot->TeleportTo(ClosestGrave->Map, ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, 0.f);
|
||||
// }
|
||||
|
||||
|
||||
@@ -225,6 +225,7 @@ bool SummonAction::Teleport(Player* summoner, Player* player)
|
||||
|
||||
player->GetMotionMaster()->Clear();
|
||||
AI_VALUE(LastMovement&, "last movement").clear();
|
||||
player->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||
player->TeleportTo(mapId, x, y, z, 0);
|
||||
|
||||
if (botAI->HasStrategy("stay", botAI->GetState()))
|
||||
|
||||
@@ -67,6 +67,7 @@ bool NewRpgBaseAction::MoveFarTo(WorldPosition dest)
|
||||
bot->GetName(), bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), bot->GetMapId(),
|
||||
dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ(), dest.getMapId(), bot->GetZoneId(),
|
||||
zone_name);
|
||||
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||
return bot->TeleportTo(dest);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user