From 937b4903bba4123536480481d0997d16b9ba15d0 Mon Sep 17 00:00:00 2001 From: Crow Date: Fri, 17 Apr 2026 13:26:29 -0500 Subject: [PATCH] Fix Potential Dereference in AttackAction (#2308) ## Pull Request Description AttackAction::Attack() uses target before checking it. This has never historically been a problem for me, but yesterday it was somehow causing me to crash every time I ordered a bot to attack. Rebuilding didn't solve the issue so it didn't seem to be a bad build. The problem was fixed by moving the target check to the beginning of the function. I restored the function to its existing ordering today and tested again, and somehow I don't crash anymore regardless. I'm confused as hell, but regardless, this is a fix that should be made. ## Feature Evaluation - Describe the **minimum logic** required to achieve the intended behavior. - Describe the **processing cost** when this logic executes across many bots. ## How to Test the Changes Order bots to "attack" a target. ## Impact Assessment - Does this change increase per-bot/per-tick processing or risk scaling poorly with thousands of bots? - - [x] No, not at all - - [ ] Minimal impact (**explain below**) - - [ ] Moderate impact (**explain below**) - Does this change modify default bot behavior? - - [x] No - - [ ] Yes (**explain why**) - Does this change add new decision branches or increase maintenance complexity? - - [x] No - - [ ] Yes (**explain below**) ## AI Assistance Was AI assistance used while working on this change? - - [ ] No - - [x] Yes (**explain below**) I had GPT-5.4 try to help me identify the source of the crash. I couldn't trace it to any particular PR, but it did identify the issue that is the subject of this PR. ## Final Checklist - - [x] Stability is not compromised. - - [x] Performance impact is understood, tested, and acceptable. - - [x] Added logic complexity is justified and explained. - - [x] Any new bot dialogue lines are translated. - - [x] Documentation updated if needed (Conf comments, WiKi commands). ## Notes for Reviewers --------- Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com> Co-authored-by: bash Co-authored-by: Revision Co-authored-by: kadeshar --- src/Ai/Base/Actions/AttackAction.cpp | 35 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/Ai/Base/Actions/AttackAction.cpp b/src/Ai/Base/Actions/AttackAction.cpp index 96bf5c4d3..af964f360 100644 --- a/src/Ai/Base/Actions/AttackAction.cpp +++ b/src/Ai/Base/Actions/AttackAction.cpp @@ -53,22 +53,6 @@ bool AttackMyTargetAction::Execute(Event /*event*/) bool AttackAction::Attack(Unit* target, bool /*with_pet*/ /*true*/) { - Unit* oldTarget = context->GetValue("current target")->Get(); - bool shouldMelee = bot->IsWithinMeleeRange(target) || botAI->IsMelee(bot); - - bool sameTarget = oldTarget == target && bot->GetVictim() == target; - bool inCombat = botAI->GetState() == BOT_STATE_COMBAT; - bool sameAttackMode = bot->HasUnitState(UNIT_STATE_MELEE_ATTACKING) == shouldMelee; - - if (bot->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE || - bot->HasUnitState(UNIT_STATE_IN_FLIGHT)) - { - if (verbose) - botAI->TellError("I cannot attack in flight"); - - return false; - } - if (!target) { if (verbose) @@ -85,6 +69,15 @@ bool AttackAction::Attack(Unit* target, bool /*with_pet*/ /*true*/) return false; } + if (bot->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE || + bot->HasUnitState(UNIT_STATE_IN_FLIGHT)) + { + if (verbose) + botAI->TellError("I cannot attack in flight"); + + return false; + } + // Check if bot OR target is in prohibited zone/area (skip for duels) if ((target->IsPlayer() || target->IsPet()) && (!bot->duel || bot->duel->Opponent != target) && @@ -121,6 +114,13 @@ bool AttackAction::Attack(Unit* target, bool /*with_pet*/ /*true*/) return false; } + Unit* oldTarget = context->GetValue("current target")->Get(); + bool shouldMelee = bot->IsWithinMeleeRange(target) || botAI->IsMelee(bot); + + bool sameTarget = oldTarget == target && bot->GetVictim() == target; + bool inCombat = botAI->GetState() == BOT_STATE_COMBAT; + bool sameAttackMode = bot->HasUnitState(UNIT_STATE_MELEE_ATTACKING) == shouldMelee; + if (sameTarget && inCombat && sameAttackMode) { if (verbose) @@ -146,8 +146,7 @@ bool AttackAction::Attack(Unit* target, bool /*with_pet*/ /*true*/) ObjectGuid guid = target->GetGUID(); bot->SetSelection(target->GetGUID()); - context->GetValue("old target")->Set(oldTarget); - + context->GetValue("old target")->Set(oldTarget); context->GetValue("current target")->Set(target); context->GetValue("available loot")->Get()->Add(guid);