[8742] Avoid aura remove triggered casts and packets send at logout/delete

This is must speedup logout and solve some crash cases or unexpected effects.

Also fix some nonsense code with memory lost possibility.
This commit is contained in:
VladimirMangos 2009-10-27 04:03:24 +03:00
parent 7b6f4accd1
commit 15ab6794d3
6 changed files with 117 additions and 121 deletions

View file

@ -354,6 +354,9 @@ void Pet::SavePetToDB(PetSaveMode mode)
if (!pOwner) if (!pOwner)
return; return;
// current/stable/not_in_slot
if (mode >= PET_SAVE_AS_CURRENT)
{
// not save pet as current if another pet temporary unsummoned // not save pet as current if another pet temporary unsummoned
if (mode == PET_SAVE_AS_CURRENT && pOwner->GetTemporaryUnsummonedPetNumber() && if (mode == PET_SAVE_AS_CURRENT && pOwner->GetTemporaryUnsummonedPetNumber() &&
pOwner->GetTemporaryUnsummonedPetNumber() != m_charmInfo->GetPetNumber()) pOwner->GetTemporaryUnsummonedPetNumber() != m_charmInfo->GetPetNumber())
@ -370,22 +373,13 @@ void Pet::SavePetToDB(PetSaveMode mode)
uint32 curmana = GetPower(POWER_MANA); uint32 curmana = GetPower(POWER_MANA);
// stable and not in slot saves // stable and not in slot saves
if(mode > PET_SAVE_AS_CURRENT) if (mode != PET_SAVE_AS_CURRENT)
{
RemoveAllAuras(); RemoveAllAuras();
//only alive hunter pets get auras saved, the others don't
if(!(getPetType() == HUNTER_PET && isAlive()))
m_Auras.clear();
}
_SaveSpells(); _SaveSpells();
_SaveSpellCooldowns(); _SaveSpellCooldowns();
_SaveAuras(); _SaveAuras();
// current/stable/not_in_slot
if(mode >= PET_SAVE_AS_CURRENT)
{
uint32 owner = GUID_LOPART(GetOwnerGUID()); uint32 owner = GUID_LOPART(GetOwnerGUID());
std::string name = m_name; std::string name = m_name;
CharacterDatabase.escape_string(name); CharacterDatabase.escape_string(name);
@ -440,7 +434,7 @@ void Pet::SavePetToDB(PetSaveMode mode)
// delete // delete
else else
{ {
RemoveAllAuras(); RemoveAllAuras(AURA_REMOVE_BY_DELETE);
DeleteFromDB(m_charmInfo->GetPetNumber()); DeleteFromDB(m_charmInfo->GetPetNumber());
} }
} }
@ -1144,9 +1138,7 @@ void Pet::_SaveSpells()
void Pet::_LoadAuras(uint32 timediff) void Pet::_LoadAuras(uint32 timediff)
{ {
m_Auras.clear(); RemoveAllAuras();
for (int i = 0; i < TOTAL_AURAS; ++i)
m_modAuras[i].clear();
QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber()); QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber());

View file

@ -14783,9 +14783,7 @@ void Player::_LoadActions(QueryResult *result)
void Player::_LoadAuras(QueryResult *result, uint32 timediff) void Player::_LoadAuras(QueryResult *result, uint32 timediff)
{ {
m_Auras.clear(); RemoveAllAuras();
for (int i = 0; i < TOTAL_AURAS; ++i)
m_modAuras[i].clear();
//QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'",GetGUIDLow()); //QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'",GetGUIDLow());

View file

@ -1141,6 +1141,9 @@ bool Aura::_RemoveAura()
SetAura(true); SetAura(true);
SetAuraFlags(AFLAG_NONE); SetAuraFlags(AFLAG_NONE);
SetAuraLevel(0); SetAuraLevel(0);
if (m_removeMode != AURA_REMOVE_BY_DELETE)
{
SendAuraUpdate(true); SendAuraUpdate(true);
// update for out of range group members // update for out of range group members
@ -1192,8 +1195,8 @@ bool Aura::_RemoveAura()
case SPELLFAMILY_HUNTER: case SPELLFAMILY_HUNTER:
if(m_spellProto->SpellFamilyFlags & UI64LIT(0x1000000000000000)) if(m_spellProto->SpellFamilyFlags & UI64LIT(0x1000000000000000))
removeState = AURA_STATE_FAERIE_FIRE; // Sting (hunter versions) removeState = AURA_STATE_FAERIE_FIRE; // Sting (hunter versions)
} }
// Remove state (but need check other auras for it) // Remove state (but need check other auras for it)
if (removeState) if (removeState)
{ {
@ -1221,6 +1224,7 @@ bool Aura::_RemoveAura()
// note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases) // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases)
((Player*)caster)->SendCooldownEvent(GetSpellProto()); ((Player*)caster)->SendCooldownEvent(GetSpellProto());
} }
}
return true; return true;
} }

View file

@ -4021,7 +4021,7 @@ void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase)
} }
void Unit::RemoveAura(Aura* aura) void Unit::RemoveAura(Aura* aura, AuraRemoveMode mode /*= AURA_REMOVE_BY_DEFAULT*/)
{ {
AuraMap::iterator i = m_Auras.lower_bound(spellEffectPair(aura->GetId(), aura->GetEffIndex())); AuraMap::iterator i = m_Auras.lower_bound(spellEffectPair(aura->GetId(), aura->GetEffIndex()));
AuraMap::iterator upperBound = m_Auras.upper_bound(spellEffectPair(aura->GetId(), aura->GetEffIndex())); AuraMap::iterator upperBound = m_Auras.upper_bound(spellEffectPair(aura->GetId(), aura->GetEffIndex()));
@ -4029,7 +4029,7 @@ void Unit::RemoveAura(Aura* aura)
{ {
if (i->second == aura) if (i->second == aura)
{ {
RemoveAura(i); RemoveAura(i,mode);
return; return;
} }
} }
@ -4079,12 +4079,13 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
} }
sLog.outDebug("Aura %u now is remove mode %d",Aur->GetModifier()->m_auraname, mode); sLog.outDebug("Aura %u now is remove mode %d",Aur->GetModifier()->m_auraname, mode);
if (mode != AURA_REMOVE_BY_DELETE) // not unapply if target will deleted
Aur->ApplyModifier(false,true); Aur->ApplyModifier(false,true);
if (Aur->_RemoveAura()) if (Aur->_RemoveAura())
{ {
// last aura in stack removed // last aura in stack removed
if(IsSpellLastAuraEffect(Aur->GetSpellProto(),Aur->GetEffIndex())) if (mode != AURA_REMOVE_BY_DELETE && IsSpellLastAuraEffect(Aur->GetSpellProto(),Aur->GetEffIndex()))
Aur->HandleSpellSpecificBoosts(false); Aur->HandleSpellSpecificBoosts(false);
} }
@ -4108,12 +4109,12 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
i = m_Auras.begin(); i = m_Auras.begin();
} }
void Unit::RemoveAllAuras() void Unit::RemoveAllAuras(AuraRemoveMode mode /*= AURA_REMOVE_BY_DEFAULT*/)
{ {
while (!m_Auras.empty()) while (!m_Auras.empty())
{ {
AuraMap::iterator iter = m_Auras.begin(); AuraMap::iterator iter = m_Auras.begin();
RemoveAura(iter); RemoveAura(iter,mode);
} }
} }
@ -11105,7 +11106,7 @@ void Unit::CleanupsBeforeDelete()
ClearComboPointHolders(); ClearComboPointHolders();
DeleteThreatList(); DeleteThreatList();
getHostileRefManager().setOnlineOfflineState(false); getHostileRefManager().setOnlineOfflineState(false);
RemoveAllAuras(); RemoveAllAuras(AURA_REMOVE_BY_DELETE);
RemoveAllGameObjects(); RemoveAllGameObjects();
RemoveAllDynObjects(); RemoveAllDynObjects();
GetMotionMaster()->Clear(false); // remove different non-standard movement generators. GetMotionMaster()->Clear(false); // remove different non-standard movement generators.

View file

@ -323,7 +323,8 @@ enum AuraRemoveMode
AURA_REMOVE_BY_STACK, // at replace by similar aura AURA_REMOVE_BY_STACK, // at replace by similar aura
AURA_REMOVE_BY_CANCEL, AURA_REMOVE_BY_CANCEL,
AURA_REMOVE_BY_DISPEL, AURA_REMOVE_BY_DISPEL,
AURA_REMOVE_BY_DEATH AURA_REMOVE_BY_DEATH,
AURA_REMOVE_BY_DELETE, // use for speedup and prevent unexpected effects at player logout/pet unsummon (must be used _only_ after save), delete.
}; };
enum UnitMods enum UnitMods
@ -1206,7 +1207,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
bool AddAura(Aura *aur); bool AddAura(Aura *aur);
void RemoveAura(Aura* aura); void RemoveAura(Aura* aura, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
void RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT); void RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
void RemoveAura(uint32 spellId, uint32 effindex, Aura* except = NULL); void RemoveAura(uint32 spellId, uint32 effindex, Aura* except = NULL);
void RemoveSingleSpellAurasFromStack(uint32 spellId); void RemoveSingleSpellAurasFromStack(uint32 spellId);
@ -1228,7 +1229,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
void RemoveAurasWithInterruptFlags(uint32 flags); void RemoveAurasWithInterruptFlags(uint32 flags);
void RemoveAurasWithDispelType( DispelType type ); void RemoveAurasWithDispelType( DispelType type );
void RemoveAllAuras(); void RemoveAllAuras(AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
void RemoveArenaAuras(bool onleave = false); void RemoveArenaAuras(bool onleave = false);
void RemoveAllAurasOnDeath(); void RemoveAllAurasOnDeath();
void DelayAura(uint32 spellId, uint32 effindex, int32 delaytime); void DelayAura(uint32 spellId, uint32 effindex, int32 delaytime);

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 "8741" #define REVISION_NR "8742"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__