mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-18 00:18:43 +01:00
Core/SAI: properly validate stored targets when using SmartTrigger and fix a related crash
(cherry picked from commit 866074b689)
This commit is contained in:
@@ -236,7 +236,7 @@ void SmartAI::EndPath(bool fail)
|
||||
else
|
||||
GetScript()->SetPathId(0);
|
||||
|
||||
ObjectVector const* targets = GetScript()->GetStoredTargetVector(SMART_ESCORT_TARGETS);
|
||||
ObjectVector const* targets = GetScript()->GetStoredTargetVector(SMART_ESCORT_TARGETS, *me);
|
||||
if (targets && mEscortQuestID)
|
||||
{
|
||||
if (targets->size() == 1 && GetScript()->IsPlayer((*targets->begin())))
|
||||
@@ -410,7 +410,7 @@ void SmartAI::UpdateAI(uint32 diff)
|
||||
|
||||
bool SmartAI::IsEscortInvokerInRange()
|
||||
{
|
||||
if (ObjectVector const* targets = GetScript()->GetStoredTargetVector(SMART_ESCORT_TARGETS))
|
||||
if (ObjectVector const* targets = GetScript()->GetStoredTargetVector(SMART_ESCORT_TARGETS, *me))
|
||||
{
|
||||
float checkDist = me->GetInstanceScript() ? SMART_ESCORT_MAX_PLAYER_DIST * 2 : SMART_ESCORT_MAX_PLAYER_DIST;
|
||||
if (targets->size() == 1 && GetScript()->IsPlayer((*targets->begin())))
|
||||
|
||||
@@ -1871,7 +1871,14 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
}
|
||||
case SMART_ACTION_SEND_TARGET_TO_TARGET:
|
||||
{
|
||||
ObjectVector const* storedTargets = GetStoredTargetVector(e.action.sendTargetToTarget.id);
|
||||
WorldObject* ref = GetBaseObject();
|
||||
if (!ref)
|
||||
ref = unit;
|
||||
|
||||
if (!ref)
|
||||
break;
|
||||
|
||||
ObjectVector const* storedTargets = GetStoredTargetVector(e.action.sendTargetToTarget.id, *ref);
|
||||
if (!storedTargets)
|
||||
break;
|
||||
|
||||
@@ -2613,8 +2620,13 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e,
|
||||
}
|
||||
case SMART_TARGET_STORED:
|
||||
{
|
||||
if (ObjectVector const* stored = GetStoredTargetVector(e.target.stored.id))
|
||||
targets.assign(stored->begin(), stored->end());
|
||||
WorldObject* ref = GetBaseObject();
|
||||
if (!ref)
|
||||
ref = scriptTrigger;
|
||||
|
||||
if (ref)
|
||||
if (ObjectVector const* stored = GetStoredTargetVector(e.target.stored.id, *ref))
|
||||
targets.assign(stored->begin(), stored->end());
|
||||
break;
|
||||
}
|
||||
case SMART_TARGET_CLOSEST_CREATURE:
|
||||
|
||||
@@ -79,14 +79,14 @@ class TC_GAME_API SmartScript
|
||||
{
|
||||
// insert or replace
|
||||
_storedTargets.erase(id);
|
||||
_storedTargets.emplace(id, ObjectGuidVector(GetBaseObject(), targets));
|
||||
_storedTargets.emplace(id, ObjectGuidVector(targets));
|
||||
}
|
||||
|
||||
ObjectVector const* GetStoredTargetVector(uint32 id) const
|
||||
ObjectVector const* GetStoredTargetVector(uint32 id, WorldObject const& ref) const
|
||||
{
|
||||
auto itr = _storedTargets.find(id);
|
||||
if (itr != _storedTargets.end())
|
||||
return itr->second.GetObjectVector();
|
||||
return itr->second.GetObjectVector(ref);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -1554,34 +1554,32 @@ typedef std::vector<WorldObject*> ObjectVector;
|
||||
class ObjectGuidVector
|
||||
{
|
||||
public:
|
||||
ObjectGuidVector(WorldObject* baseObject, ObjectVector const& objectVector) : _baseObject(baseObject), _objectVector(objectVector)
|
||||
explicit ObjectGuidVector(ObjectVector const& objectVector) : _objectVector(objectVector)
|
||||
{
|
||||
_guidVector.reserve(_objectVector.size());
|
||||
for (WorldObject* obj : _objectVector)
|
||||
_guidVector.push_back(obj->GetGUID());
|
||||
}
|
||||
|
||||
ObjectVector const* GetObjectVector() const
|
||||
ObjectVector const* GetObjectVector(WorldObject const& ref) const
|
||||
{
|
||||
UpdateObjects();
|
||||
UpdateObjects(ref);
|
||||
return &_objectVector;
|
||||
}
|
||||
|
||||
~ObjectGuidVector() { }
|
||||
|
||||
private:
|
||||
WorldObject* const _baseObject;
|
||||
GuidVector _guidVector;
|
||||
mutable ObjectVector _objectVector;
|
||||
|
||||
GuidVector _guidVector;
|
||||
|
||||
//sanitize vector using _guidVector
|
||||
void UpdateObjects() const
|
||||
void UpdateObjects(WorldObject const& ref) const
|
||||
{
|
||||
_objectVector.clear();
|
||||
|
||||
for (ObjectGuid const& guid : _guidVector)
|
||||
if (WorldObject* obj = ObjectAccessor::GetWorldObject(*_baseObject, guid))
|
||||
if (WorldObject* obj = ObjectAccessor::GetWorldObject(ref, guid))
|
||||
_objectVector.push_back(obj);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user