diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Server/Packets/CombatLogPackets.cpp | 59 | ||||
-rw-r--r-- | src/server/game/Server/Packets/CombatLogPackets.h | 26 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 179 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.h | 71 |
5 files changed, 238 insertions, 99 deletions
diff --git a/src/server/game/Server/Packets/CombatLogPackets.cpp b/src/server/game/Server/Packets/CombatLogPackets.cpp index e44db70c76a..ac65bc09fe3 100644 --- a/src/server/game/Server/Packets/CombatLogPackets.cpp +++ b/src/server/game/Server/Packets/CombatLogPackets.cpp @@ -58,3 +58,62 @@ WorldPacket const* WorldPackets::CombatLog::EnvironmentalDamageLog::Write() return &_worldPacket; } + +WorldPacket const* WorldPackets::CombatLog::SpellExecuteLog::Write() +{ + _worldPacket << Caster; + _worldPacket << SpellID; + + _worldPacket << uint32(Effects.size()); + + for (SpellLogEffect const& effect : Effects) + { + _worldPacket << effect.Effect; + + _worldPacket << uint32(effect.PowerDrainTargets.size()); + _worldPacket << uint32(effect.ExtraAttacksTargets.size()); + _worldPacket << uint32(effect.DurabilityDamageTargets.size()); + _worldPacket << uint32(effect.GenericVictimTargets.size()); + _worldPacket << uint32(effect.TradeSkillTargets.size()); + _worldPacket << uint32(effect.FeedPetTargets.size()); + + for (SpellLogEffectPowerDrainParams const& powerDrainTarget : effect.PowerDrainTargets) + { + _worldPacket << powerDrainTarget.Victim; + _worldPacket << powerDrainTarget.Points; + _worldPacket << powerDrainTarget.PowerType; + _worldPacket << powerDrainTarget.Amplitude; + } + + for (SpellLogEffectExtraAttacksParams const& extraAttacksTarget : effect.ExtraAttacksTargets) + { + _worldPacket << extraAttacksTarget.Victim; + _worldPacket << extraAttacksTarget.NumAttacks; + } + + for (SpellLogEffectDurabilityDamageParams const& durabilityDamageTarget : effect.DurabilityDamageTargets) + { + _worldPacket << durabilityDamageTarget.Victim; + _worldPacket << durabilityDamageTarget.ItemID; + _worldPacket << durabilityDamageTarget.Amount; + } + + for (SpellLogEffectGenericVictimParams const& genericVictimTarget : effect.GenericVictimTargets) + _worldPacket << genericVictimTarget.Victim; + + for (SpellLogEffectTradeSkillItemParams const& tradeSkillTarget : effect.TradeSkillTargets) + _worldPacket << tradeSkillTarget.ItemID; + + + for (SpellLogEffectFeedPetParams const& feedPetTarget : effect.FeedPetTargets) + _worldPacket << feedPetTarget.ItemID; + } + + _worldPacket.WriteBit(LogData.HasValue); + _worldPacket.FlushBits(); + + if (LogData.HasValue) + _worldPacket << LogData.Value; + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/CombatLogPackets.h b/src/server/game/Server/Packets/CombatLogPackets.h index 606322e5d35..ad727579376 100644 --- a/src/server/game/Server/Packets/CombatLogPackets.h +++ b/src/server/game/Server/Packets/CombatLogPackets.h @@ -19,6 +19,7 @@ #define CombatLogPackets_h__ #include "Packet.h" +#include "Spell.h" #include "SpellPackets.h" namespace WorldPackets @@ -61,6 +62,31 @@ namespace WorldPackets int32 Absorbed = 0; Optional<Spells::SpellCastLogData> LogData; /// @todo: find the correct way where to use it, in sniff always false }; + + class SpellExecuteLog final : public ServerPacket + { + public: + struct SpellLogEffect + { + int32 Effect = 0; + + std::vector<SpellLogEffectPowerDrainParams> PowerDrainTargets; + std::vector<SpellLogEffectExtraAttacksParams> ExtraAttacksTargets; + std::vector<SpellLogEffectDurabilityDamageParams> DurabilityDamageTargets; + std::vector<SpellLogEffectGenericVictimParams> GenericVictimTargets; + std::vector<SpellLogEffectTradeSkillItemParams> TradeSkillTargets; + std::vector<SpellLogEffectFeedPetParams> FeedPetTargets; + }; + + SpellExecuteLog() : ServerPacket(SMSG_SPELL_EXECUTE_LOG, 16 + 4 + 4 + 1) { } + + WorldPacket const* Write() override; + + ObjectGuid Caster; + int32 SpellID = 0; + std::vector<SpellLogEffect> Effects; + Optional<Spells::SpellCastLogData> LogData; /// @todo: find the correct way where to use it, in sniff always false + }; } } diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index b5ec9e91f82..74a9e7bc76b 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -1643,7 +1643,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_DELAYED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_DISPELL_LOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_ENERGIZE_LOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_EXECUTE_LOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_EXECUTE_LOG, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_FAILED_OTHER, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_FAILURE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_GO, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 1df9fd000f6..c7e0a16c9ad 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -58,6 +58,7 @@ #include "Battlefield.h" #include "BattlefieldMgr.h" #include "SpellPackets.h" +#include "CombatLogPackets.h" #include "SpellHistory.h" extern pEffect SpellEffects[TOTAL_SPELL_EFFECTS]; @@ -667,7 +668,7 @@ m_spellValue(new SpellValue(caster->GetMap()->GetDifficultyID(), m_spellInfo)), && !m_spellInfo->IsPassive() && !m_spellInfo->IsPositive(); CleanupTargetList(); - memset(m_effectExecuteData, 0, MAX_SPELL_EFFECTS * sizeof(ByteBuffer*)); + CleanupExecuteLogList(); for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) m_destTargets[i] = SpellDestination(*m_caster); @@ -696,8 +697,7 @@ Spell::~Spell() ASSERT(m_caster->ToPlayer()->m_spellModTakingSpell != this); delete m_spellValue; - - CheckEffectExecuteData(); + CleanupExecuteLogList(); } void Spell::InitExplicitTargets(SpellCastTargets const& targets) @@ -4081,57 +4081,72 @@ void Spell::UpdateSpellCastDataTargets(WorldPackets::Spells::SpellCastData& data m_channelTargetEffectMask = 0; } -void Spell::SendLogExecute() +void Spell::SendSpellExecuteLog() { - WorldPacket data(SMSG_SPELL_EXECUTE_LOG, (8+4+4+4+4+8)); - - data << m_caster->GetPackGUID(); + WorldPackets::CombatLog::SpellExecuteLog spellExecuteLog; - data << uint32(m_spellInfo->Id); + spellExecuteLog.Caster = m_caster->GetGUID(); + spellExecuteLog.SpellID = m_spellInfo->Id; - uint8 effCount = 0; - for (SpellEffectInfo const* effect : GetEffects()) - { - if (effect && m_effectExecuteData[effect->EffectIndex]) - ++effCount; - } - - if (!effCount) + if (_powerDrainTargets->empty() && _extraAttacksTargets->empty() && + _durabilityDamageTargets->empty() && _genericVictimTargets->empty() && + _tradeSkillTargets->empty() && _feedPetTargets->empty()) return; - data << uint32(effCount); for (SpellEffectInfo const* effect : GetEffects()) { - if (!effect || !m_effectExecuteData[effect->EffectIndex]) + WorldPackets::CombatLog::SpellExecuteLog::SpellLogEffect spellLogEffect; + if (!effect) continue; - data << uint32(effect->Effect); // spell effect + spellLogEffect.Effect = effect->Effect; + + for (SpellLogEffectPowerDrainParams const& powerDrainParam : _powerDrainTargets[effect->EffectIndex]) + spellLogEffect.PowerDrainTargets.push_back(powerDrainParam); + + for (SpellLogEffectExtraAttacksParams const& extraAttacksTarget : _extraAttacksTargets[effect->EffectIndex]) + spellLogEffect.ExtraAttacksTargets.push_back(extraAttacksTarget); - data.append(*m_effectExecuteData[effect->EffectIndex]); + for (SpellLogEffectDurabilityDamageParams const& durabilityDamageTarget : _durabilityDamageTargets[effect->EffectIndex]) + spellLogEffect.DurabilityDamageTargets.push_back(durabilityDamageTarget); - delete m_effectExecuteData[effect->EffectIndex]; - m_effectExecuteData[effect->EffectIndex] = NULL; + for (SpellLogEffectGenericVictimParams const& genericVictimTarget : _genericVictimTargets[effect->EffectIndex]) + spellLogEffect.GenericVictimTargets.push_back(genericVictimTarget); + + for (SpellLogEffectTradeSkillItemParams const& tradeSkillTarget : _tradeSkillTargets[effect->EffectIndex]) + spellLogEffect.TradeSkillTargets.push_back(tradeSkillTarget); + + for (SpellLogEffectFeedPetParams const& feedPetTarget : _feedPetTargets[effect->EffectIndex]) + spellLogEffect.FeedPetTargets.push_back(feedPetTarget); + + spellExecuteLog.Effects.push_back(spellLogEffect); } - m_caster->SendMessageToSet(&data, true); + + m_caster->SendMessageToSet(spellExecuteLog.Write(), true); } -void Spell::ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit* target, uint32 powerType, uint32 powerTaken, float gainMultiplier) +void Spell::ExecuteLogEffectTakeTargetPower(int32 effect, Unit* target, uint32 powerType, uint32 points, float amplitude) { - InitEffectExecuteData(effIndex); - *m_effectExecuteData[effIndex] << target->GetPackGUID(); - *m_effectExecuteData[effIndex] << uint32(powerTaken); - *m_effectExecuteData[effIndex] << uint32(powerType); - *m_effectExecuteData[effIndex] << float(gainMultiplier); + SpellLogEffectPowerDrainParams spellLogEffectPowerDrainParams; + + spellLogEffectPowerDrainParams.Victim = target->GetGUID(); + spellLogEffectPowerDrainParams.Points = points; + spellLogEffectPowerDrainParams.PowerType = powerType; + spellLogEffectPowerDrainParams.Amplitude = amplitude; + + _powerDrainTargets[effect].push_back(spellLogEffectPowerDrainParams); } -void Spell::ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit* victim, uint32 attCount) +void Spell::ExecuteLogEffectExtraAttacks(uint8 effect, Unit* victim, uint32 numAttacks) { - InitEffectExecuteData(effIndex); - *m_effectExecuteData[effIndex] << victim->GetPackGUID(); - *m_effectExecuteData[effIndex] << uint32(attCount); + SpellLogEffectExtraAttacksParams spellLogEffectExtraAttacksParams; + spellLogEffectExtraAttacksParams.Victim = victim->GetGUID(); + spellLogEffectExtraAttacksParams.NumAttacks = numAttacks; + + _extraAttacksTargets[effect].push_back(spellLogEffectExtraAttacksParams); } -void Spell::ExecuteLogEffectInterruptCast(uint8 /*effIndex*/, Unit* victim, uint32 spellId) +void Spell::ExecuteLogEffectInterruptCast(uint8 /*effect*/, Unit* victim, uint32 spellId) { ObjectGuid casterGuid = m_caster->GetGUID(); ObjectGuid targetGuid = victim->GetGUID(); @@ -4176,48 +4191,72 @@ void Spell::ExecuteLogEffectInterruptCast(uint8 /*effIndex*/, Unit* victim, uint m_caster->SendMessageToSet(&data, true); } -void Spell::ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit* victim, int32 itemId, int32 slot) +void Spell::ExecuteLogEffectDurabilityDamage(uint8 effect, Unit* victim, int32 itemId, int32 amount) { - InitEffectExecuteData(effIndex); - *m_effectExecuteData[effIndex] << victim->GetPackGUID(); - *m_effectExecuteData[effIndex] << int32(itemId); - *m_effectExecuteData[effIndex] << int32(slot); + SpellLogEffectDurabilityDamageParams spellLogEffectDurabilityDamageParams; + spellLogEffectDurabilityDamageParams.Victim = victim->GetGUID(); + spellLogEffectDurabilityDamageParams.ItemID = itemId; + spellLogEffectDurabilityDamageParams.Amount = amount; + + _durabilityDamageTargets[effect].push_back(spellLogEffectDurabilityDamageParams); } -void Spell::ExecuteLogEffectOpenLock(uint8 effIndex, Object* obj) +void Spell::ExecuteLogEffectOpenLock(uint8 effect, Object* obj) { - InitEffectExecuteData(effIndex); - *m_effectExecuteData[effIndex] << obj->GetPackGUID(); + SpellLogEffectGenericVictimParams spellLogEffectGenericVictimParams; + spellLogEffectGenericVictimParams.Victim = obj->GetGUID(); + + _genericVictimTargets[effect].push_back(spellLogEffectGenericVictimParams); } -void Spell::ExecuteLogEffectCreateItem(uint8 effIndex, uint32 entry) +void Spell::ExecuteLogEffectCreateItem(uint8 effect, uint32 entry) { - InitEffectExecuteData(effIndex); - *m_effectExecuteData[effIndex] << uint32(entry); + SpellLogEffectTradeSkillItemParams spellLogEffectTradeSkillItemParams; + spellLogEffectTradeSkillItemParams.ItemID = entry; + + _tradeSkillTargets[effect].push_back(spellLogEffectTradeSkillItemParams); +} + +void Spell::ExecuteLogEffectDestroyItem(uint8 effect, uint32 entry) +{ + SpellLogEffectFeedPetParams spellLogEffectFeedPetParams; + spellLogEffectFeedPetParams.ItemID = entry; + + _feedPetTargets[effect].push_back(spellLogEffectFeedPetParams); } -void Spell::ExecuteLogEffectDestroyItem(uint8 effIndex, uint32 entry) +void Spell::ExecuteLogEffectSummonObject(uint8 effect, WorldObject* obj) { - InitEffectExecuteData(effIndex); - *m_effectExecuteData[effIndex] << uint32(entry); + SpellLogEffectGenericVictimParams spellLogEffectGenericVictimParams; + spellLogEffectGenericVictimParams.Victim = obj->GetGUID(); + + _genericVictimTargets[effect].push_back(spellLogEffectGenericVictimParams); } -void Spell::ExecuteLogEffectSummonObject(uint8 effIndex, WorldObject* obj) +void Spell::ExecuteLogEffectUnsummonObject(uint8 effect, WorldObject* obj) { - InitEffectExecuteData(effIndex); - *m_effectExecuteData[effIndex] << obj->GetPackGUID(); + SpellLogEffectGenericVictimParams spellLogEffectGenericVictimParams; + spellLogEffectGenericVictimParams.Victim = obj->GetGUID(); + + _genericVictimTargets[effect].push_back(spellLogEffectGenericVictimParams); } -void Spell::ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject* obj) +void Spell::ExecuteLogEffectResurrect(uint8 effect, Unit* target) { - InitEffectExecuteData(effIndex); - *m_effectExecuteData[effIndex] << obj->GetPackGUID(); + SpellLogEffectGenericVictimParams spellLogEffectGenericVictimParams; + spellLogEffectGenericVictimParams.Victim = target->GetGUID(); + + _genericVictimTargets[effect].push_back(spellLogEffectGenericVictimParams); } -void Spell::ExecuteLogEffectResurrect(uint8 effIndex, Unit* target) +void Spell::CleanupExecuteLogList() { - InitEffectExecuteData(effIndex); - *m_effectExecuteData[effIndex] << target->GetPackGUID(); + _durabilityDamageTargets->clear(); + _extraAttacksTargets->clear(); + _feedPetTargets->clear(); + _genericVictimTargets->clear(); + _powerDrainTargets->clear(); + _tradeSkillTargets->clear(); } void Spell::SendInterrupted(uint8 result) @@ -6946,35 +6985,11 @@ void Spell::SetSpellValue(SpellValueMod mod, int32 value) void Spell::PrepareTargetProcessing() { - CheckEffectExecuteData(); } void Spell::FinishTargetProcessing() { - SendLogExecute(); -} - -void Spell::InitEffectExecuteData(uint32 effIndex) -{ - ASSERT(effIndex < MAX_SPELL_EFFECTS); - if (!m_effectExecuteData[effIndex]) - { - m_effectExecuteData[effIndex] = new ByteBuffer(0x20); - // first dword - target counter - *m_effectExecuteData[effIndex] << uint32(1); - } - else - { - // increase target counter by one - uint32 count = (*m_effectExecuteData[effIndex]).read<uint32>(0); - (*m_effectExecuteData[effIndex]).put<uint32>(0, ++count); - } -} - -void Spell::CheckEffectExecuteData() -{ - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - ASSERT(!m_effectExecuteData[i]); + SendSpellExecuteLog(); } void Spell::LoadScripts() diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 4190cca0ab4..d936ebbbf00 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -105,6 +105,43 @@ struct SpellDestination Position _transportOffset; }; + +struct SpellLogEffectPowerDrainParams +{ + ObjectGuid Victim; + uint32 Points = 0; + uint32 PowerType = 0; + float Amplitude = 0; +}; + +struct SpellLogEffectExtraAttacksParams +{ + ObjectGuid Victim; + uint32 NumAttacks = 0; +}; + +struct SpellLogEffectDurabilityDamageParams +{ + ObjectGuid Victim; + int32 ItemID = 0; + int32 Amount = 0; +}; + +struct SpellLogEffectGenericVictimParams +{ + ObjectGuid Victim; +}; + +struct SpellLogEffectTradeSkillItemParams +{ + int32 ItemID = 0; +}; + +struct SpellLogEffectFeedPetParams +{ + int32 ItemID = 0; +}; + class SpellCastTargets { public: @@ -453,17 +490,18 @@ class Spell void SendSpellStart(); void SendSpellGo(); void SendSpellCooldown(); - void SendLogExecute(); - void ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit* target, uint32 powerType, uint32 powerTaken, float gainMultiplier); - void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit* victim, uint32 attCount); - void ExecuteLogEffectInterruptCast(uint8 effIndex, Unit* victim, uint32 spellId); - void ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit* victim, int32 itemId, int32 slot); - void ExecuteLogEffectOpenLock(uint8 effIndex, Object* obj); - void ExecuteLogEffectCreateItem(uint8 effIndex, uint32 entry); - void ExecuteLogEffectDestroyItem(uint8 effIndex, uint32 entry); - void ExecuteLogEffectSummonObject(uint8 effIndex, WorldObject* obj); - void ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject* obj); - void ExecuteLogEffectResurrect(uint8 effIndex, Unit* target); + void SendSpellExecuteLog(); + void ExecuteLogEffectTakeTargetPower(int32 effect, Unit* target, uint32 powerType, uint32 points, float amplitude); + void ExecuteLogEffectExtraAttacks(uint8 effect, Unit* victim, uint32 numAttacks); + void ExecuteLogEffectInterruptCast(uint8 effect, Unit* victim, uint32 spellId); + void ExecuteLogEffectDurabilityDamage(uint8 effect, Unit* victim, int32 itemId, int32 amount); + void ExecuteLogEffectOpenLock(uint8 effect, Object* obj); + void ExecuteLogEffectCreateItem(uint8 effect, uint32 entry); + void ExecuteLogEffectDestroyItem(uint8 effect, uint32 entry); + void ExecuteLogEffectSummonObject(uint8 effect, WorldObject* obj); + void ExecuteLogEffectUnsummonObject(uint8 effect, WorldObject* obj); + void ExecuteLogEffectResurrect(uint8 effect, Unit* target); + void CleanupExecuteLogList(); void SendInterrupted(uint8 result); void SendChannelUpdate(uint32 time); void SendChannelStart(uint32 duration); @@ -677,10 +715,6 @@ class Spell void PrepareTargetProcessing(); void FinishTargetProcessing(); - // spell execution log - void InitEffectExecuteData(uint32 effIndex); - void CheckEffectExecuteData(); - // Scripting system void LoadScripts(); void CallScriptBeforeCastHandlers(); @@ -735,7 +769,12 @@ class Spell uint32 m_auraScaleMask; PathGenerator m_preGeneratedPath; - ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS]; + std::vector<SpellLogEffectPowerDrainParams> _powerDrainTargets[MAX_SPELL_EFFECTS]; + std::vector<SpellLogEffectExtraAttacksParams> _extraAttacksTargets[MAX_SPELL_EFFECTS]; + std::vector<SpellLogEffectDurabilityDamageParams> _durabilityDamageTargets[MAX_SPELL_EFFECTS]; + std::vector<SpellLogEffectGenericVictimParams> _genericVictimTargets[MAX_SPELL_EFFECTS]; + std::vector<SpellLogEffectTradeSkillItemParams> _tradeSkillTargets[MAX_SPELL_EFFECTS]; + std::vector<SpellLogEffectFeedPetParams> _feedPetTargets[MAX_SPELL_EFFECTS]; #ifdef MAP_BASED_RAND_GEN int32 irand(int32 min, int32 max) { return int32 (m_caster->GetMap()->mtRand.randInt(max - min)) + min; } |