Core/PacketIO: Fixed duration field order in SMSG_AURA_UPDATE
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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 << uint16(level);
|
||||
|
||||
// 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());
|
||||
|
||||
uint32 int72 = 0;
|
||||
_worldPacket << int72;
|
||||
|
||||
size_t pos = _worldPacket.wpos();
|
||||
uint32 count = 0;
|
||||
_worldPacket << count;
|
||||
|
||||
//for (int72)
|
||||
// float
|
||||
|
||||
if (flags & AFLAG_SCALABLE)
|
||||
{
|
||||
for (AuraEffect const* effect : aura->GetAuraEffects())
|
||||
_worldPacket << aura.Slot;
|
||||
if (_worldPacket.WriteBit(aura.AuraData.HasValue))
|
||||
{
|
||||
if (effect && aurApp->HasEffect(effect->GetEffIndex())) // Not all of aura's effects have to be applied on every target
|
||||
{
|
||||
_worldPacket << float(effect->GetAmount());
|
||||
count++;
|
||||
}
|
||||
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());
|
||||
|
||||
if (!data.EstimatedPoints.empty())
|
||||
_worldPacket.append(data.EstimatedPoints.data(), data.EstimatedPoints.size());
|
||||
|
||||
if (!data.Points.empty())
|
||||
_worldPacket.append(data.Points.data(), data.Points.size());
|
||||
|
||||
_worldPacket.WriteBit(data.CastUnit.HasValue);
|
||||
_worldPacket.WriteBit(data.Duration.HasValue);
|
||||
_worldPacket.WriteBit(data.Remaining.HasValue);
|
||||
|
||||
if (data.CastUnit.HasValue)
|
||||
_worldPacket << data.CastUnit.Value;
|
||||
|
||||
if (data.Duration.HasValue)
|
||||
_worldPacket << uint32(data.Duration.Value);
|
||||
|
||||
if (data.Remaining.HasValue)
|
||||
_worldPacket << uint32(data.Remaining.Value);
|
||||
}
|
||||
|
||||
_worldPacket.FlushBits();
|
||||
}
|
||||
|
||||
_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());
|
||||
}
|
||||
|
||||
if (aura->GetMaxDuration())
|
||||
{
|
||||
_worldPacket << uint32(aura->GetMaxDuration());
|
||||
}
|
||||
return &_worldPacket;
|
||||
}
|
||||
|
||||
void WorldPackets::Spells::SpellCastRequest::Read()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
_target->SendMessageToSet(const_cast<WorldPacket*>(update.Write()), true);
|
||||
WorldPackets::Spells::AuraInfo auraInfo;
|
||||
BuildUpdatePacket(auraInfo, remove);
|
||||
update.Auras.push_back(auraInfo);
|
||||
|
||||
_target->SendMessageToSet(update.Write(), true);
|
||||
}
|
||||
|
||||
uint32 Aura::BuildEffectMaskForOwner(SpellInfo const* spellProto, uint32 avalibleEffectMask, WorldObject* owner)
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user