diff options
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 14 | ||||
-rw-r--r-- | src/server/game/Server/Packets/SpellPackets.cpp | 100 | ||||
-rw-r--r-- | src/server/game/Server/Packets/SpellPackets.h | 30 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.cpp | 58 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.h | 10 |
5 files changed, 108 insertions, 104 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index d635e9fe841..d2013c588bf 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -23314,16 +23314,20 @@ void Player::SendAurasForTarget(Unit* target) Unit::VisibleAuraMap const* visibleAuras = target->GetVisibleAuras(); - WorldPackets::Spells::SendAuraUpdate update; - update.Init(true, target->GetGUID(), visibleAuras->size()); + WorldPackets::Spells::AuraUpdate update; + update.UpdateAll = true; + update.UnitGUID = target->GetGUID(); + update.Auras.reserve(visibleAuras->size()); for (Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr) { - AuraApplication * auraApp = itr->second; - update.BuildUpdatePacket(auraApp, false, target->getLevel()); // TODO 6.x should be caster's level + AuraApplication* auraApp = itr->second; + WorldPackets::Spells::AuraInfo auraInfo; + auraApp->BuildUpdatePacket(auraInfo, false); + update.Auras.push_back(auraInfo); } - GetSession()->SendPacket(const_cast<WorldPacket*>(update.Write())); + GetSession()->SendPacket(update.Write()); } void Player::SetDailyQuestStatus(uint32 quest_id) diff --git a/src/server/game/Server/Packets/SpellPackets.cpp b/src/server/game/Server/Packets/SpellPackets.cpp index 41e2bf1d819..53ec8a7f3cf 100644 --- a/src/server/game/Server/Packets/SpellPackets.cpp +++ b/src/server/game/Server/Packets/SpellPackets.cpp @@ -90,87 +90,49 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellCastLogData return data; } -WorldPacket const* WorldPackets::Spells::SendAuraUpdate::Write() +WorldPacket const* WorldPackets::Spells::AuraUpdate::Write() { - return &_worldPacket; -} - -void WorldPackets::Spells::SendAuraUpdate::Init(bool IsFullUpdate, ObjectGuid Target, uint32 Count) -{ - _worldPacket.WriteBit(IsFullUpdate); - _worldPacket << Target; - _worldPacket << uint32(Count); -} - -void WorldPackets::Spells::SendAuraUpdate::BuildUpdatePacket(AuraApplication* aurApp, bool remove, uint16 level) -{ - _worldPacket << uint8(aurApp->GetSlot()); - _worldPacket.ResetBitPos(); - _worldPacket.WriteBit(!remove); - - if (remove) + _worldPacket.WriteBit(UpdateAll); + _worldPacket << UnitGUID; + _worldPacket << uint32(Auras.size()); + for (auto& aura : Auras) { - _worldPacket.FlushBits(); - return; - } - Aura const* aura = aurApp->GetBase(); - _worldPacket << uint32(aura->GetId()); - - uint8 flags = aurApp->GetFlags(); - if (aura->GetMaxDuration() > 0 && !(aura->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_HIDE_DURATION)) - flags |= AFLAG_DURATION; - _worldPacket << uint8(flags); - - _worldPacket << uint32(aurApp->GetEffectMask()); + _worldPacket << aura.Slot; + if (_worldPacket.WriteBit(aura.AuraData.HasValue)) + { + AuraDataInfo const& data = aura.AuraData.Value; + _worldPacket << uint32(data.SpellID); + _worldPacket << uint8(data.Flags); + _worldPacket << uint32(data.ActiveFlags); + _worldPacket << uint16(data.CastLevel); + _worldPacket << uint8(data.Applications); + _worldPacket << uint32(data.EstimatedPoints.size()); + _worldPacket << uint32(data.Points.size()); - _worldPacket << uint16(level); + if (!data.EstimatedPoints.empty()) + _worldPacket.append(data.EstimatedPoints.data(), data.EstimatedPoints.size()); - // send stack amount for aura which could be stacked (never 0 - causes incorrect display) or charges - // stack amount has priority over charges (checked on retail with spell 50262) - _worldPacket << uint8(aura->GetSpellInfo()->StackAmount ? aura->GetStackAmount() : aura->GetCharges()); + if (!data.Points.empty()) + _worldPacket.append(data.Points.data(), data.Points.size()); - uint32 int72 = 0; - _worldPacket << int72; + _worldPacket.WriteBit(data.CastUnit.HasValue); + _worldPacket.WriteBit(data.Duration.HasValue); + _worldPacket.WriteBit(data.Remaining.HasValue); - size_t pos = _worldPacket.wpos(); - uint32 count = 0; - _worldPacket << count; + if (data.CastUnit.HasValue) + _worldPacket << data.CastUnit.Value; - //for (int72) - // float + if (data.Duration.HasValue) + _worldPacket << uint32(data.Duration.Value); - if (flags & AFLAG_SCALABLE) - { - for (AuraEffect const* effect : aura->GetAuraEffects()) - { - if (effect && aurApp->HasEffect(effect->GetEffIndex())) // Not all of aura's effects have to be applied on every target - { - _worldPacket << float(effect->GetAmount()); - count++; - } + if (data.Remaining.HasValue) + _worldPacket << uint32(data.Remaining.Value); } - } - - _worldPacket.put<uint32>(pos, count); - - _worldPacket.ResetBitPos(); - - _worldPacket.WriteBit(!(flags & AFLAG_NOCASTER)); - _worldPacket.WriteBit(aura->GetDuration()); - _worldPacket.WriteBit(aura->GetMaxDuration()); - if (!(flags & AFLAG_NOCASTER)) - _worldPacket << aura->GetCasterGUID().WriteAsPacked(); - - if (aura->GetDuration()) - { - _worldPacket << uint32(aura->GetDuration()); + _worldPacket.FlushBits(); } - if (aura->GetMaxDuration()) - { - _worldPacket << uint32(aura->GetMaxDuration()); - } + return &_worldPacket; } void WorldPackets::Spells::SpellCastRequest::Read() diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h index d131eefc765..8357c470573 100644 --- a/src/server/game/Server/Packets/SpellPackets.h +++ b/src/server/game/Server/Packets/SpellPackets.h @@ -112,14 +112,36 @@ namespace WorldPackets std::vector<SpellLogPowerData> PowerData; }; - class SendAuraUpdate final : public ServerPacket + struct AuraDataInfo + { + int32 SpellID = 0; + uint8 Flags = 0; + uint32 ActiveFlags = 0; + uint16 CastLevel = 1; + uint8 Applications = 1; + Optional<ObjectGuid> CastUnit; + Optional<int32> Duration; + Optional<int32> Remaining; + std::vector<float> Points; + std::vector<float> EstimatedPoints; + }; + + struct AuraInfo + { + uint8 Slot = 0; + Optional<AuraDataInfo> AuraData; + }; + + class AuraUpdate final : public ServerPacket { public: - SendAuraUpdate() : ServerPacket(SMSG_AURA_UPDATE) { } + AuraUpdate() : ServerPacket(SMSG_AURA_UPDATE) { } WorldPacket const* Write() override; - void Init(bool IsFullUpdate, ObjectGuid Target, uint32 Count); - void BuildUpdatePacket(AuraApplication* aurApp, bool remove, uint16 level); + + bool UpdateAll = false; + ObjectGuid UnitGUID; + std::vector<AuraInfo> Auras; }; class SpellCastRequest final : public ClientPacket diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 1a5bb05044c..6aec236e2b2 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -185,53 +185,61 @@ void AuraApplication::_HandleEffect(uint8 effIndex, bool apply) SetNeedClientUpdate(); } -void AuraApplication::BuildUpdatePacket(ByteBuffer& data, bool remove) const +void AuraApplication::BuildUpdatePacket(WorldPackets::Spells::AuraInfo& auraInfo, bool remove) const { - data << uint8(_slot); + ASSERT((_target->GetVisibleAura(_slot) != nullptr) ^ remove); + auraInfo.Slot = GetSlot(); if (remove) - { - ASSERT(!_target->GetVisibleAura(_slot)); - data << uint32(0); return; - } - ASSERT(_target->GetVisibleAura(_slot)); Aura const* aura = GetBase(); - data << uint32(aura->GetId()); - uint8 flags = _flags; + + WorldPackets::Spells::AuraDataInfo auraData; + auraData.SpellID = aura->GetId(); + auraData.Flags = GetFlags(); if (aura->GetMaxDuration() > 0 && !(aura->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_HIDE_DURATION)) - flags |= AFLAG_DURATION; - data << uint16(flags); - data << uint8(aura->GetCasterLevel()); + auraData.Flags |= AFLAG_DURATION; + + auraData.ActiveFlags = GetEffectMask(); + auraData.CastLevel = aura->GetCasterLevel(); + // send stack amount for aura which could be stacked (never 0 - causes incorrect display) or charges // stack amount has priority over charges (checked on retail with spell 50262) - data << uint8(aura->GetSpellInfo()->StackAmount ? aura->GetStackAmount() : aura->GetCharges()); + auraData.Applications = aura->GetSpellInfo()->StackAmount ? aura->GetStackAmount() : aura->GetCharges(); + if (!(auraData.Flags & AFLAG_NOCASTER)) + auraData.CastUnit.Set(aura->GetCasterGUID()); - if (!(flags & AFLAG_NOCASTER)) - data << aura->GetCasterGUID().WriteAsPacked(); - - if (flags & AFLAG_DURATION) + if (auraData.Flags & AFLAG_DURATION) { - data << uint32(aura->GetMaxDuration()); - data << uint32(aura->GetDuration()); + auraData.Duration.Set(aura->GetMaxDuration()); + auraData.Remaining.Set(aura->GetDuration()); } - if (flags & AFLAG_SCALABLE) + if (auraData.Flags & AFLAG_SCALABLE) + { + auraData.Points.reserve(aura->GetAuraEffects().size()); for (AuraEffect const* effect : GetBase()->GetAuraEffects()) if (effect && HasEffect(effect->GetEffIndex())) // Not all of aura's effects have to be applied on every target - data << int32(effect->GetAmount()); + auraData.Points.push_back(float(effect->GetAmount())); + } + + auraInfo.AuraData.Set(auraData); } void AuraApplication::ClientUpdate(bool remove) { _needClientUpdate = false; - WorldPackets::Spells::SendAuraUpdate update; - update.Init(false, GetTarget()->GetGUID(), 1); - update.BuildUpdatePacket(this, remove, GetTarget()->getLevel()); // TODO 6.x should be caster's level + WorldPackets::Spells::AuraUpdate update; + update.UpdateAll = false; + update.UnitGUID = GetTarget()->GetGUID(); + + WorldPackets::Spells::AuraInfo auraInfo; + BuildUpdatePacket(auraInfo, remove); + update.Auras.push_back(auraInfo); - _target->SendMessageToSet(const_cast<WorldPacket*>(update.Write()), true); + _target->SendMessageToSet(update.Write(), true); } uint32 Aura::BuildEffectMaskForOwner(SpellInfo const* spellProto, uint32 avalibleEffectMask, WorldObject* owner) diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index efd0e49f5ae..8841d887e86 100644 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -28,6 +28,14 @@ struct SpellModifier; struct ProcTriggerSpell; struct SpellProcEntry; +namespace WorldPackets +{ + namespace Spells + { + struct AuraInfo; + } +} + // forward decl class AuraEffect; class Aura; @@ -79,7 +87,7 @@ class AuraApplication void SetNeedClientUpdate() { _needClientUpdate = true;} bool IsNeedClientUpdate() const { return _needClientUpdate;} - void BuildUpdatePacket(ByteBuffer& data, bool remove) const; + void BuildUpdatePacket(WorldPackets::Spells::AuraInfo& data, bool remove) const; void ClientUpdate(bool remove = false); }; |