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);
|
PlayerbotAI* botAI = GET_PLAYERBOT_AI(bot);
|
||||||
if (botAI)
|
if (botAI)
|
||||||
botAI->Reset(true);
|
botAI->Reset(true);
|
||||||
|
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||||
bot->TeleportTo(loc.GetMapId(), x, y, z, 0);
|
bot->TeleportTo(loc.GetMapId(), x, y, z, 0);
|
||||||
bot->SendMovementFlagUpdate();
|
bot->SendMovementFlagUpdate();
|
||||||
|
|
||||||
@@ -3245,6 +3246,7 @@ void RandomPlayerbotMgr::OnPlayerLogin(Player* player)
|
|||||||
} while (true);
|
} while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
player->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||||
player->TeleportTo(botPos);
|
player->TeleportTo(botPos);
|
||||||
|
|
||||||
// player->Relocate(botPos.getX(), botPos.getY(), botPos.getZ(), botPos.getO());
|
// player->Relocate(botPos.getX(), botPos.getY(), botPos.getZ(), botPos.getO());
|
||||||
|
|||||||
@@ -176,6 +176,7 @@ bool BGJoinAction::gatherArenaTeam(ArenaType type)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
memberBotAI->Reset();
|
memberBotAI->Reset();
|
||||||
|
member->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||||
member->TeleportTo(bot->GetMapId(), bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), 0);
|
member->TeleportTo(bot->GetMapId(), bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), 0);
|
||||||
|
|
||||||
LOG_INFO("playerbots", "Bot {} <{}>: Member of <{}>", member->GetGUID().ToString().c_str(),
|
LOG_INFO("playerbots", "Bot {} <{}>: Member of <{}>", member->GetGUID().ToString().c_str(),
|
||||||
|
|||||||
@@ -4289,10 +4289,16 @@ bool ArenaTactics::moveToCenter(Battleground* bg)
|
|||||||
{
|
{
|
||||||
// they like to hang around at the tip of the pipes doing nothing, so we just teleport them down
|
// 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)
|
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());
|
bot->TeleportTo(bg->GetMapId(), 1330.96f, 816.75f, 3.2f, bot->GetOrientation());
|
||||||
|
}
|
||||||
if (bot->GetDistance(1250.13f, 764.79f, 13.34f) < 4)
|
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());
|
bot->TeleportTo(bg->GetMapId(), 1252.19f, 765.41f, 3.2f, bot->GetOrientation());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case BATTLEGROUND_RV:
|
case BATTLEGROUND_RV:
|
||||||
MoveTo(bg->GetMapId(), 764.65f + frand(-2, +2), -283.85f + frand(-2, +2), 28.28f, false, true);
|
MoveTo(bg->GetMapId(), 764.65f + frand(-2, +2), -283.85f + frand(-2, +2), 28.28f, false, true);
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ bool FollowChatShortcutAction::Execute(Event event)
|
|||||||
else
|
else
|
||||||
botAI->TellMaster("You are too far away from me! I will there soon.");
|
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(),
|
bot->TeleportTo(master->GetMapId(), master->GetPositionX(), master->GetPositionY(), master->GetPositionZ(),
|
||||||
master->GetOrientation()); return true;
|
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() &&
|
if ((target->GetMap() && target->GetMap()->IsBattlegroundOrArena()) || (bot->GetMap() &&
|
||||||
bot->GetMap()->IsBattlegroundOrArena())) return false;
|
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());
|
bot->TeleportTo(target->GetMapId(), x, y, z, bot->GetOrientation());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1175,6 +1176,7 @@ bool MovementAction::Follow(Unit* target, float distance, float angle)
|
|||||||
|
|
||||||
bot->CombatStop(true);
|
bot->CombatStop(true);
|
||||||
botAI->TellMasterNoFacing("I will there soon.");
|
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(),
|
bot->TeleportTo(target->GetMapId(), target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(),
|
||||||
target->GetOrientation()); return false;
|
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
|
// 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.
|
// 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);
|
bot->TeleportTo(bot->GetMapId(), spiritHealer->GetPositionX(), spiritHealer->GetPositionY(), spiritHealer->GetPositionZ(), 0.f);
|
||||||
RESET_AI_VALUE(bool, "combat::self target");
|
RESET_AI_VALUE(bool, "combat::self target");
|
||||||
RESET_AI_VALUE(WorldPosition, "current position");
|
RESET_AI_VALUE(WorldPosition, "current position");
|
||||||
@@ -244,6 +245,7 @@ int64 RepopAction::CalculateDeadTime() const
|
|||||||
|
|
||||||
void RepopAction::PerformGraveyardTeleport(const GraveyardStruct* graveyard) 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);
|
bot->TeleportTo(graveyard->Map, graveyard->x, graveyard->y, graveyard->z, 0.f);
|
||||||
RESET_AI_VALUE(bool, "combat::self target");
|
RESET_AI_VALUE(bool, "combat::self target");
|
||||||
RESET_AI_VALUE(WorldPosition, "current position");
|
RESET_AI_VALUE(WorldPosition, "current position");
|
||||||
|
|||||||
@@ -169,6 +169,7 @@ bool FindCorpseAction::Execute(Event event)
|
|||||||
if (deadTime > delay)
|
if (deadTime > delay)
|
||||||
{
|
{
|
||||||
bot->GetMotionMaster()->Clear();
|
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);
|
bot->TeleportTo(moveToPos.getMapId(), moveToPos.getX(), moveToPos.getY(), moveToPos.getZ(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,6 +351,7 @@ bool SpiritHealerAction::Execute(Event event)
|
|||||||
// if (!botAI->HasActivePlayerMaster())
|
// if (!botAI->HasActivePlayerMaster())
|
||||||
// {
|
// {
|
||||||
context->GetValue<uint32>("death count")->Set(dCount + 1);
|
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);
|
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();
|
player->GetMotionMaster()->Clear();
|
||||||
AI_VALUE(LastMovement&, "last movement").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);
|
player->TeleportTo(mapId, x, y, z, 0);
|
||||||
|
|
||||||
if (botAI->HasStrategy("stay", botAI->GetState()))
|
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(),
|
bot->GetName(), bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), bot->GetMapId(),
|
||||||
dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ(), dest.getMapId(), bot->GetZoneId(),
|
dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ(), dest.getMapId(), bot->GetZoneId(),
|
||||||
zone_name);
|
zone_name);
|
||||||
|
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
|
||||||
return bot->TeleportTo(dest);
|
return bot->TeleportTo(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user