diff options
author | megamage <none@none> | 2009-03-02 16:59:14 -0600 |
---|---|---|
committer | megamage <none@none> | 2009-03-02 16:59:14 -0600 |
commit | d7d7c3562a9e33f0d655b86572e7a73e0ee384a6 (patch) | |
tree | 07b0541f811a95011b0131824d13309f29a69f71 /src | |
parent | c6fc7f7bca19eb9acf52a6abac55df84e66ade08 (diff) |
[7364] Really implenent server-side anti-cheating cooldown check for spells with SPELL_ATTR_DISABLED_WHILE_ACTIVE. Author: VladimirMangos
Move apply cooldown for like spells to aura apply (GO registering for owner in GO summon spell case)
Store "infinity" cooldown for like spells, ignore it at save and reapply it at aura loading.
Note: one problem still exist for like spells: at loading/far teleport spell icon lost diabled state at client.
Need sedn some unknown data in SendInitialPacketsBeforeAddToMap or SendInitialPacketsAfterAddToMap for restore it state.
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/game/Player.cpp | 69 | ||||
-rw-r--r-- | src/game/Player.h | 2 | ||||
-rw-r--r-- | src/game/Spell.cpp | 9 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 10 | ||||
-rw-r--r-- | src/game/Unit.cpp | 9 | ||||
-rw-r--r-- | src/shared/revision_nr.h | 2 |
6 files changed, 70 insertions, 31 deletions
diff --git a/src/game/Player.cpp b/src/game/Player.cpp index a2f5f05b83e..7bb518c130b 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2496,6 +2496,9 @@ void Player::InitStatsForLevel(bool reapplyMods) void Player::SendInitialSpells() { + time_t curTime = time(NULL); + time_t infTime = curTime + MONTH/2; + uint16 spellCount = 0; WorldPacket data(SMSG_INITIAL_SPELLS, (1+2+4*m_spells.size()+2+m_spellCooldowns.size()*(2+2+2+4+4))); @@ -2528,10 +2531,13 @@ void Player::SendInitialSpells() if(!sEntry) continue; + // not send infinity cooldown + if(itr->second.end > infTime) + continue; + data << uint16(itr->first); time_t cooldown = 0; - time_t curTime = time(NULL); if(itr->second.end > curTime) cooldown = (itr->second.end-curTime)*IN_MILISECONDS; @@ -3258,7 +3264,7 @@ void Player::RemoveAllSpellCooldown() void Player::_LoadSpellCooldowns(QueryResult *result) { - m_spellCooldowns.clear(); + // some cooldowns can be already set at aura loading... //QueryResult *result = CharacterDatabase.PQuery("SELECT spell,item,time FROM character_spell_cooldown WHERE guid = '%u'",GetGUIDLow()); @@ -3299,17 +3305,20 @@ void Player::_SaveSpellCooldowns() CharacterDatabase.PExecute("DELETE FROM character_spell_cooldown WHERE guid = '%u'", GetGUIDLow()); time_t curTime = time(NULL); + time_t infTime = curTime + MONTH/2; // remove outdated and save active for(SpellCooldowns::iterator itr = m_spellCooldowns.begin();itr != m_spellCooldowns.end();) { if(itr->second.end <= curTime) m_spellCooldowns.erase(itr++); - else + else if(itr->second.end <= infTime) // not save locked cooldowns, it will be reset or set at reload { CharacterDatabase.PExecute("INSERT INTO character_spell_cooldown (guid,spell,item,time) VALUES ('%u', '%u', '%u', '" I64FMTD "')", GetGUIDLow(), itr->first, itr->second.itemid, uint64(itr->second.end)); ++itr; } + else + ++itr; } } @@ -18030,7 +18039,7 @@ void Player::UpdatePvP(bool state, bool ovrride) } } -void Player::AddSpellAndCategoryCooldowns(SpellEntry const* spellInfo, uint32 itemId, Spell* spell) +void Player::AddSpellAndCategoryCooldowns(SpellEntry const* spellInfo, uint32 itemId, Spell* spell, bool infinityCooldown) { // init cooldown values uint32 cat = 0; @@ -18066,37 +18075,51 @@ void Player::AddSpellAndCategoryCooldowns(SpellEntry const* spellInfo, uint32 it catrec = spellInfo->CategoryRecoveryTime; } - // shoot spells used equipped item cooldown values already assigned in GetAttackTime(RANGED_ATTACK) - // prevent 0 cooldowns set by another way - if (rec <= 0 && catrec <= 0 && (cat == 76 || IsAutoRepeatRangedSpell(spellInfo) && spellInfo->Id != SPELL_ID_AUTOSHOT)) - rec = GetAttackTime(RANGED_ATTACK); + time_t curTime = time(NULL); + + time_t catrecTime; + time_t recTime; - // Now we have cooldown data (if found any), time to apply mods - if(rec > 0) - ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, rec, spell); + // overwrite time for selected category + if(infinityCooldown) + { + // use +MONTH as infinity mark for spell cooldown (will checked as MONTH/2 at save ans skipped) + // but not allow ignore until reset or re-login + catrecTime = catrec > 0 ? curTime+MONTH : 0; + recTime = rec > 0 ? curTime+MONTH : catrecTime; + } + else + { + // shoot spells used equipped item cooldown values already assigned in GetAttackTime(RANGED_ATTACK) + // prevent 0 cooldowns set by another way + if (rec <= 0 && catrec <= 0 && (cat == 76 || IsAutoRepeatRangedSpell(spellInfo) && spellInfo->Id != SPELL_ID_AUTOSHOT)) + rec = GetAttackTime(RANGED_ATTACK); - if(catrec > 0) - ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, catrec, spell); + // Now we have cooldown data (if found any), time to apply mods + if(rec > 0) + ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, rec, spell); - // replace negative cooldowns by 0 - if (rec < 0) rec = 0; - if (catrec < 0) catrec = 0; + if(catrec > 0) + ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, catrec, spell); - // no cooldown after applying spell mods - if( rec == 0 && catrec == 0) - return; + // replace negative cooldowns by 0 + if (rec < 0) rec = 0; + if (catrec < 0) catrec = 0; - time_t curTime = time(NULL); + // no cooldown after applying spell mods + if( rec == 0 && catrec == 0) + return; - time_t catrecTime = catrec ? curTime+catrec/IN_MILISECONDS : 0; // in secs - time_t recTime = rec ? curTime+rec/IN_MILISECONDS : catrecTime;// in secs + catrecTime = catrec ? curTime+catrec/IN_MILISECONDS : 0; + recTime = rec ? curTime+rec/IN_MILISECONDS : catrecTime; + } // self spell cooldown if(recTime > 0) AddSpellCooldown(spellInfo->Id, itemId, recTime); // category spells - if (catrec > 0) + if (cat && catrec > 0) { SpellCategoryStore::const_iterator i_scstore = sSpellCategoryStore.find(cat); if(i_scstore != sSpellCategoryStore.end()) diff --git a/src/game/Player.h b/src/game/Player.h index 55f789848da..086fae3e391 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1491,7 +1491,7 @@ class TRINITY_DLL_SPEC Player : public Unit time_t t = time(NULL); return itr != m_spellCooldowns.end() && itr->second.end > t ? itr->second.end - t : 0; } - void AddSpellAndCategoryCooldowns(SpellEntry const* spellInfo, uint32 itemId, Spell* spell = NULL); + void AddSpellAndCategoryCooldowns(SpellEntry const* spellInfo, uint32 itemId, Spell* spell = NULL, bool infinityCooldown = false ); void AddSpellCooldown(uint32 spell_id, uint32 itemid, time_t end_time); void SendCooldownEvent(SpellEntry const *spellInfo, uint32 itemId = 0, Spell* spell = NULL); void ProhibitSpellScholl(SpellSchoolMask idSchoolMask, uint32 unTimeMs ); diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index c70dd4c2c08..1e36ee5e231 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -2432,13 +2432,10 @@ void Spell::SendSpellCooldown() return; Player* _player = (Player*)m_caster; - // Add cooldown for max (disable spell) - // Cooldown started on SendCooldownEvent call - if (m_spellInfo->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE) - { - _player->AddSpellCooldown(m_spellInfo->Id, 0, time(NULL) - 1); + + // have infinity cooldown but set at aura apply + if(m_spellInfo->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE) return; - } _player->AddSpellAndCategoryCooldowns(m_spellInfo,m_CastItem ? m_CastItem->GetEntry() : 0, this); } diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index eb5157b28c0..94ecf0b198d 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -786,6 +786,16 @@ void Aura::_AddAura() Unit* caster = GetCaster(); + // set infinity cooldown state for spells + if(caster && caster->GetTypeId() == TYPEID_PLAYER) + { + if (m_spellProto->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE) + { + Item* castItem = m_castItemGuid ? ((Player*)caster)->GetItemByGuid(m_castItemGuid) : NULL; + ((Player*)caster)->AddSpellAndCategoryCooldowns(m_spellProto,castItem ? castItem->GetEntry() : 0, NULL,true); + } + } + // passive auras (except totem auras) do not get placed in the slots // area auras with SPELL_AURA_NONE are not shown on target // all further code applies only to active spells diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 64daa48d612..c6170a2f18d 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4445,6 +4445,15 @@ void Unit::AddGameObject(GameObject* gameObj) assert(gameObj && gameObj->GetOwnerGUID()==0); m_gameObj.push_back(gameObj); gameObj->SetOwnerGUID(GetGUID()); + + if ( GetTypeId()==TYPEID_PLAYER && gameObj->GetSpellId() ) + { + SpellEntry const* createBySpell = sSpellStore.LookupEntry(gameObj->GetSpellId()); + // Need disable spell use for owner + if (createBySpell && createBySpell->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE) + // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases) + ((Player*)this)->AddSpellAndCategoryCooldowns(createBySpell,0,NULL,true); + } } void Unit::RemoveGameObject(GameObject* gameObj, bool del) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index ee63de4fc22..7e292898bc9 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7363" + #define REVISION_NR "7364" #endif // __REVISION_NR_H__ |