[8860] Prevent spam to clients by iupdates non-modifed threat list.

Also make more stricted access to threat list content.
This commit is contained in:
VladimirMangos 2009-11-23 01:38:43 +03:00
parent d63ea646a0
commit 67e070870b
6 changed files with 59 additions and 39 deletions

View file

@ -523,8 +523,8 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
break; break;
case ACTION_T_THREAT_ALL_PCT: case ACTION_T_THREAT_ALL_PCT:
{ {
ThreatList& threatList = m_creature->getThreatManager().getThreatList(); ThreatList const& threatList = m_creature->getThreatManager().getThreatList();
for (ThreatList::iterator i = threatList.begin(); i != threatList.end(); ++i) for (ThreatList::const_iterator i = threatList.begin(); i != threatList.end(); ++i)
if(Unit* Temp = Unit::GetUnit(*m_creature,(*i)->getUnitGuid())) if(Unit* Temp = Unit::GetUnit(*m_creature,(*i)->getUnitGuid()))
m_creature->getThreatManager().modifyThreatPercent(Temp, action.threat_all_pct.percent); m_creature->getThreatManager().modifyThreatPercent(Temp, action.threat_all_pct.percent);
break; break;
@ -634,8 +634,8 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
break; break;
case ACTION_T_CAST_EVENT_ALL: case ACTION_T_CAST_EVENT_ALL:
{ {
ThreatList& threatList = m_creature->getThreatManager().getThreatList(); ThreatList const& threatList = m_creature->getThreatManager().getThreatList();
for (ThreatList::iterator i = threatList.begin(); i != threatList.end(); ++i) for (ThreatList::const_iterator i = threatList.begin(); i != threatList.end(); ++i)
if (Unit* Temp = Unit::GetUnit(*m_creature,(*i)->getUnitGuid())) if (Unit* Temp = Unit::GetUnit(*m_creature,(*i)->getUnitGuid()))
if (Temp->GetTypeId() == TYPEID_PLAYER) if (Temp->GetTypeId() == TYPEID_PLAYER)
((Player*)Temp)->CastedCreatureOrGO(action.cast_event_all.creatureId, m_creature->GetGUID(), action.cast_event_all.spellId); ((Player*)Temp)->CastedCreatureOrGO(action.cast_event_all.creatureId, m_creature->GetGUID(), action.cast_event_all.spellId);
@ -1111,21 +1111,21 @@ bool CreatureEventAI::IsVisible(Unit *pl) const
&& pl->isVisibleForOrDetect(m_creature,m_creature,true); && pl->isVisibleForOrDetect(m_creature,m_creature,true);
} }
inline Unit* CreatureEventAI::SelectUnit(AttackingTarget target, uint32 position) inline Unit* CreatureEventAI::SelectUnit(AttackingTarget target, uint32 position) const
{ {
//ThreatList m_threatlist; //ThreatList m_threatlist;
ThreatList& m_threatlist = m_creature->getThreatManager().getThreatList(); ThreatList const& threatlist = m_creature->getThreatManager().getThreatList();
ThreatList::iterator i = m_threatlist.begin(); ThreatList::const_iterator i = threatlist.begin();
ThreatList::reverse_iterator r = m_threatlist.rbegin(); ThreatList::const_reverse_iterator r = threatlist.rbegin();
if (position >= m_threatlist.size() || !m_threatlist.size()) if (position >= threatlist.size() || !threatlist.size())
return NULL; return NULL;
switch (target) switch (target)
{ {
case ATTACKING_TARGET_RANDOM: case ATTACKING_TARGET_RANDOM:
{ {
advance ( i , position + (rand() % (m_threatlist.size() - position ) )); advance ( i , position + (rand() % (threatlist.size() - position ) ));
return Unit::GetUnit(*m_creature,(*i)->getUnitGuid()); return Unit::GetUnit(*m_creature,(*i)->getUnitGuid());
} }
case ATTACKING_TARGET_TOPAGGRO: case ATTACKING_TARGET_TOPAGGRO:

View file

@ -594,7 +594,7 @@ class MANGOS_DLL_SPEC CreatureEventAI : public CreatureAI
inline uint32 GetRandActionParam(uint32 rnd, uint32 param1, uint32 param2, uint32 param3); inline uint32 GetRandActionParam(uint32 rnd, uint32 param1, uint32 param2, uint32 param3);
inline int32 GetRandActionParam(uint32 rnd, int32 param1, int32 param2, int32 param3); inline int32 GetRandActionParam(uint32 rnd, int32 param1, int32 param2, int32 param3);
inline Unit* GetTargetByType(uint32 Target, Unit* pActionInvoker); inline Unit* GetTargetByType(uint32 Target, Unit* pActionInvoker);
inline Unit* SelectUnit(AttackingTarget target, uint32 position); inline Unit* SelectUnit(AttackingTarget target, uint32 position) const;
void DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target); void DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target);
void DoMeleeAttackIfReady(); void DoMeleeAttackIfReady();

View file

@ -351,7 +351,8 @@ HostileReference* ThreatContainer::selectNextVictim(Creature* pAttacker, Hostile
//=================== ThreatManager ========================== //=================== ThreatManager ==========================
//============================================================ //============================================================
ThreatManager::ThreatManager(Unit* owner) : iCurrentVictim(NULL), iOwner(owner), iUpdateTimer(THREAT_UPDATE_INTERVAL) ThreatManager::ThreatManager(Unit* owner)
: iCurrentVictim(NULL), iOwner(owner), iUpdateTimer(THREAT_UPDATE_INTERVAL), iUpdateNeed(false)
{ {
} }
@ -363,6 +364,7 @@ void ThreatManager::clearReferences()
iThreatOfflineContainer.clearReferences(); iThreatOfflineContainer.clearReferences();
iCurrentVictim = NULL; iCurrentVictim = NULL;
iUpdateTimer.Reset(THREAT_UPDATE_INTERVAL); iUpdateTimer.Reset(THREAT_UPDATE_INTERVAL);
iUpdateNeed = false;
} }
//============================================================ //============================================================
@ -379,7 +381,7 @@ void ThreatManager::addThreat(Unit* pVictim, float pThreat, bool crit, SpellScho
return; return;
// not to GM // not to GM
if(!pVictim || (pVictim->GetTypeId() == TYPEID_PLAYER && ((Player*)pVictim)->isGameMaster()) ) if (!pVictim || (pVictim->GetTypeId() == TYPEID_PLAYER && ((Player*)pVictim)->isGameMaster()) )
return; return;
// not to dead and not for dead // not to dead and not for dead
@ -391,8 +393,11 @@ void ThreatManager::addThreat(Unit* pVictim, float pThreat, bool crit, SpellScho
float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, crit, schoolMask, pThreatSpell); float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, crit, schoolMask, pThreatSpell);
HostileReference* ref = iThreatContainer.addThreat(pVictim, threat); HostileReference* ref = iThreatContainer.addThreat(pVictim, threat);
// Ref is online
if (ref)
iUpdateNeed = true;
// Ref is not in the online refs, search the offline refs next // Ref is not in the online refs, search the offline refs next
if(!ref) else
ref = iThreatOfflineContainer.addThreat(pVictim, threat); ref = iThreatOfflineContainer.addThreat(pVictim, threat);
if(!ref) // there was no ref => create a new one if(!ref) // there was no ref => create a new one
@ -401,6 +406,7 @@ void ThreatManager::addThreat(Unit* pVictim, float pThreat, bool crit, SpellScho
HostileReference* hostileReference = new HostileReference(pVictim, this, 0); HostileReference* hostileReference = new HostileReference(pVictim, this, 0);
iThreatContainer.addReference(hostileReference); iThreatContainer.addReference(hostileReference);
hostileReference->addThreat(threat); // now we add the real threat hostileReference->addThreat(threat); // now we add the real threat
iUpdateNeed = true;
if(pVictim->GetTypeId() == TYPEID_PLAYER && ((Player*)pVictim)->isGameMaster()) if(pVictim->GetTypeId() == TYPEID_PLAYER && ((Player*)pVictim)->isGameMaster())
hostileReference->setOnlineOfflineState(false); // GM is always offline hostileReference->setOnlineOfflineState(false); // GM is always offline
} }
@ -411,6 +417,7 @@ void ThreatManager::addThreat(Unit* pVictim, float pThreat, bool crit, SpellScho
void ThreatManager::modifyThreatPercent(Unit *pVictim, int32 pPercent) void ThreatManager::modifyThreatPercent(Unit *pVictim, int32 pPercent)
{ {
iThreatContainer.modifyThreatPercent(pVictim, pPercent); iThreatContainer.modifyThreatPercent(pVictim, pPercent);
iUpdateNeed = true;
} }
//============================================================ //============================================================
@ -440,12 +447,17 @@ float ThreatManager::getThreat(Unit *pVictim, bool pAlsoSearchOfflineList)
void ThreatManager::tauntApply(Unit* pTaunter) void ThreatManager::tauntApply(Unit* pTaunter)
{ {
HostileReference* ref = iThreatContainer.getReferenceByTarget(pTaunter); if(HostileReference* ref = iThreatContainer.getReferenceByTarget(pTaunter))
if(getCurrentVictim() && ref && (ref->getThreat() < getCurrentVictim()->getThreat()))
{ {
if(ref->getTempThreatModifyer() == 0.0f) if(getCurrentVictim() && (ref->getThreat() < getCurrentVictim()->getThreat()))
// Ok, temp threat is unused {
ref->setTempThreat(getCurrentVictim()->getThreat()); // Ok, temp threat is unused
if(ref->getTempThreatModifyer() == 0.0f)
{
ref->setTempThreat(getCurrentVictim()->getThreat());
iUpdateNeed = true;
}
}
} }
} }
@ -453,19 +465,26 @@ void ThreatManager::tauntApply(Unit* pTaunter)
void ThreatManager::tauntFadeOut(Unit *pTaunter) void ThreatManager::tauntFadeOut(Unit *pTaunter)
{ {
HostileReference* ref = iThreatContainer.getReferenceByTarget(pTaunter); if(HostileReference* ref = iThreatContainer.getReferenceByTarget(pTaunter))
if(ref) {
ref->resetTempThreat(); ref->resetTempThreat();
iUpdateNeed = true;
}
} }
//============================================================ //============================================================
void ThreatManager::setCurrentVictim(HostileReference* pHostileReference) void ThreatManager::setCurrentVictim(HostileReference* pHostileReference)
{ {
if (pHostileReference && pHostileReference != iCurrentVictim) // including NULL==NULL case
if (pHostileReference == iCurrentVictim)
return;
if (pHostileReference)
iOwner->SendHighestThreatUpdate(pHostileReference); iOwner->SendHighestThreatUpdate(pHostileReference);
iCurrentVictim = pHostileReference; iCurrentVictim = pHostileReference;
iUpdateNeed = true;
} }
//============================================================ //============================================================
@ -494,6 +513,7 @@ void ThreatManager::processThreatEvent(ThreatRefStatusChangeEvent* threatRefStat
setDirty(true); setDirty(true);
} }
iThreatContainer.remove(hostileReference); iThreatContainer.remove(hostileReference);
iUpdateNeed = true;
iThreatOfflineContainer.addReference(hostileReference); iThreatOfflineContainer.addReference(hostileReference);
} }
else else
@ -501,6 +521,7 @@ void ThreatManager::processThreatEvent(ThreatRefStatusChangeEvent* threatRefStat
if(getCurrentVictim() && hostileReference->getThreat() > (1.1f * getCurrentVictim()->getThreat())) if(getCurrentVictim() && hostileReference->getThreat() > (1.1f * getCurrentVictim()->getThreat()))
setDirty(true); setDirty(true);
iThreatContainer.addReference(hostileReference); iThreatContainer.addReference(hostileReference);
iUpdateNeed = true;
iThreatOfflineContainer.remove(hostileReference); iThreatOfflineContainer.remove(hostileReference);
} }
break; break;
@ -512,7 +533,10 @@ void ThreatManager::processThreatEvent(ThreatRefStatusChangeEvent* threatRefStat
} }
iOwner->SendThreatRemove(hostileReference); iOwner->SendThreatRemove(hostileReference);
if(hostileReference->isOnline()) if(hostileReference->isOnline())
{
iThreatContainer.remove(hostileReference); iThreatContainer.remove(hostileReference);
iUpdateNeed = true;
}
else else
iThreatOfflineContainer.remove(hostileReference); iThreatOfflineContainer.remove(hostileReference);
break; break;
@ -521,7 +545,7 @@ void ThreatManager::processThreatEvent(ThreatRefStatusChangeEvent* threatRefStat
void ThreatManager::UpdateForClient(uint32 diff) void ThreatManager::UpdateForClient(uint32 diff)
{ {
if (isThreatListEmpty()) if (!iUpdateNeed || isThreatListEmpty())
return; return;
iUpdateTimer.Update(diff); iUpdateTimer.Update(diff);
@ -529,5 +553,6 @@ void ThreatManager::UpdateForClient(uint32 diff)
{ {
iOwner->SendThreatUpdate(); iOwner->SendThreatUpdate();
iUpdateTimer.Reset(THREAT_UPDATE_INTERVAL); iUpdateTimer.Reset(THREAT_UPDATE_INTERVAL);
iUpdateNeed = false;
} }
} }

View file

@ -157,15 +157,14 @@ class MANGOS_DLL_SPEC ThreatContainer
void setDirty(bool pDirty) { iDirty = pDirty; } void setDirty(bool pDirty) { iDirty = pDirty; }
bool isDirty() { return iDirty; } bool isDirty() const { return iDirty; }
bool empty() { return(iThreatList.empty()); } bool empty() const { return(iThreatList.empty()); }
HostileReference* getMostHated() { return iThreatList.empty() ? NULL : iThreatList.front(); } HostileReference* getMostHated() { return iThreatList.empty() ? NULL : iThreatList.front(); }
HostileReference* getReferenceByTarget(Unit* pVictim); HostileReference* getReferenceByTarget(Unit* pVictim);
ThreatList& getThreatList() { return iThreatList; }
ThreatList const& getThreatList() const { return iThreatList; } ThreatList const& getThreatList() const { return iThreatList; }
}; };
@ -188,7 +187,7 @@ class MANGOS_DLL_SPEC ThreatManager
float getThreat(Unit *pVictim, bool pAlsoSearchOfflineList = false); float getThreat(Unit *pVictim, bool pAlsoSearchOfflineList = false);
bool isThreatListEmpty() { return iThreatContainer.empty();} bool isThreatListEmpty() const { return iThreatContainer.empty(); }
void processThreatEvent(ThreatRefStatusChangeEvent* threatRefStatusChangeEvent); void processThreatEvent(ThreatRefStatusChangeEvent* threatRefStatusChangeEvent);
@ -196,7 +195,7 @@ class MANGOS_DLL_SPEC ThreatManager
HostileReference* getCurrentVictim() { return iCurrentVictim; } HostileReference* getCurrentVictim() { return iCurrentVictim; }
Unit* getOwner() { return iOwner; } Unit* getOwner() const { return iOwner; }
Unit* getHostileTarget(); Unit* getHostileTarget();
@ -209,18 +208,14 @@ class MANGOS_DLL_SPEC ThreatManager
// methods to access the lists from the outside to do sume dirty manipulation (scriping and such) // methods to access the lists from the outside to do sume dirty manipulation (scriping and such)
// I hope they are used as little as possible. // I hope they are used as little as possible.
ThreatList& getThreatList() { return iThreatContainer.getThreatList(); }
ThreatList const& getThreatList() const { return iThreatContainer.getThreatList(); } ThreatList const& getThreatList() const { return iThreatContainer.getThreatList(); }
ThreatList& getOfflieThreatList() { return iThreatOfflineContainer.getThreatList(); } //FIXME: currently used in some known script hacks, but expected as non needed
ThreatList const& getOfflieThreatList() const { return iThreatOfflineContainer.getThreatList(); }
ThreatContainer& getOnlineContainer() { return iThreatContainer; } ThreatContainer& getOnlineContainer() { return iThreatContainer; }
ThreatContainer const& getOnlineContainer() const { return iThreatContainer; }
ThreatContainer& getOfflineContainer() { return iThreatOfflineContainer; }
ThreatContainer const& getOfflineContainer() const { return iThreatOfflineContainer; }
private: private:
HostileReference* iCurrentVictim; HostileReference* iCurrentVictim;
Unit* iOwner; Unit* iOwner;
TimeTrackerSmall iUpdateTimer; TimeTrackerSmall iUpdateTimer;
bool iUpdateNeed;
ThreatContainer iThreatContainer; ThreatContainer iThreatContainer;
ThreatContainer iThreatOfflineContainer; ThreatContainer iThreatOfflineContainer;
}; };

View file

@ -12771,13 +12771,13 @@ uint32 Unit::GetCombatRatingDamageReduction(CombatRating cr, float rate, float c
void Unit::SendThreatUpdate() void Unit::SendThreatUpdate()
{ {
if (uint32 count = getThreatManager().getThreatList().size()) ThreatList const& tlist = getThreatManager().getThreatList();
if (uint32 count = tlist.size())
{ {
sLog.outDebug( "WORLD: Send SMSG_THREAT_UPDATE Message" ); sLog.outDebug( "WORLD: Send SMSG_THREAT_UPDATE Message" );
WorldPacket data(SMSG_THREAT_UPDATE, 8 + count * 8); WorldPacket data(SMSG_THREAT_UPDATE, 8 + count * 8);
data.append(GetPackGUID()); data.append(GetPackGUID());
data << uint32(count); data << uint32(count);
ThreatList& tlist = getThreatManager().getThreatList();
for (ThreatList::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr) for (ThreatList::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr)
{ {
data.appendPackGUID((*itr)->getUnitGuid()); data.appendPackGUID((*itr)->getUnitGuid());
@ -12789,14 +12789,14 @@ void Unit::SendThreatUpdate()
void Unit::SendHighestThreatUpdate(HostileReference* pHostilReference) void Unit::SendHighestThreatUpdate(HostileReference* pHostilReference)
{ {
if (uint32 count = getThreatManager().getThreatList().size()) ThreatList const& tlist = getThreatManager().getThreatList();
if (uint32 count = tlist.size())
{ {
sLog.outDebug( "WORLD: Send SMSG_HIGHEST_THREAT_UPDATE Message" ); sLog.outDebug( "WORLD: Send SMSG_HIGHEST_THREAT_UPDATE Message" );
WorldPacket data(SMSG_HIGHEST_THREAT_UPDATE, 8 + 8 + count * 8); WorldPacket data(SMSG_HIGHEST_THREAT_UPDATE, 8 + 8 + count * 8);
data.append(GetPackGUID()); data.append(GetPackGUID());
data.appendPackGUID(pHostilReference->getUnitGuid()); data.appendPackGUID(pHostilReference->getUnitGuid());
data << uint32(count); data << uint32(count);
ThreatList const& tlist = getThreatManager().getThreatList();
for (ThreatList::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr) for (ThreatList::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr)
{ {
data.appendPackGUID((*itr)->getUnitGuid()); data.appendPackGUID((*itr)->getUnitGuid());

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "8859" #define REVISION_NR "8860"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__