diff options
29 files changed, 902 insertions, 197 deletions
diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp index 8407e0b72d2..c5621e86986 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp @@ -891,6 +891,32 @@ void AreaTrigger::BuildValuesUpdate(ByteBuffer* data, Player const* target) cons data->put<uint32>(sizePos, data->wpos() - sizePos - 4); } +void AreaTrigger::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, + UF::AreaTriggerData::Mask const& requestedAreaTriggerMask, Player const* target) const +{ + UpdateMask<NUM_CLIENT_OBJECT_TYPES> valuesMask; + if (requestedObjectMask.IsAnySet()) + valuesMask.Set(TYPEID_OBJECT); + + if (requestedAreaTriggerMask.IsAnySet()) + valuesMask.Set(TYPEID_AREATRIGGER); + + ByteBuffer buffer = PrepareValuesUpdateBuffer(); + std::size_t sizePos = buffer.wpos(); + buffer << uint32(0); + buffer << uint32(valuesMask.GetBlock(0)); + + if (valuesMask[TYPEID_OBJECT]) + m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target); + + if (valuesMask[TYPEID_AREATRIGGER]) + m_areaTriggerData->WriteUpdate(buffer, requestedAreaTriggerMask, true, this, target); + + buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4); + + data->AddUpdateBlock(buffer); +} + void AreaTrigger::ClearUpdateMask(bool remove) { m_values.ClearChangesMask(&AreaTrigger::m_areaTriggerData); diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.h b/src/server/game/Entities/AreaTrigger/AreaTrigger.h index 5c79d67da7f..e2862369a17 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.h +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.h @@ -44,10 +44,15 @@ class TC_GAME_API AreaTrigger : public WorldObject, public GridObject<AreaTrigge AreaTrigger(); ~AreaTrigger(); + protected: void BuildValuesCreate(ByteBuffer* data, Player const* target) const override; void BuildValuesUpdate(ByteBuffer* data, Player const* target) const override; void ClearUpdateMask(bool remove) override; + public: + void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, + UF::AreaTriggerData::Mask const& requestedAreaTriggerMask, Player const* target) const; + void AddToWorld() override; void RemoveFromWorld() override; diff --git a/src/server/game/Entities/Conversation/Conversation.cpp b/src/server/game/Entities/Conversation/Conversation.cpp index 61f57107517..32648507033 100644 --- a/src/server/game/Entities/Conversation/Conversation.cpp +++ b/src/server/game/Entities/Conversation/Conversation.cpp @@ -226,6 +226,32 @@ void Conversation::BuildValuesUpdate(ByteBuffer* data, Player const* target) con data->put<uint32>(sizePos, data->wpos() - sizePos - 4); } +void Conversation::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, + UF::ConversationData::Mask const& requestedConversationMask, Player const* target) const +{ + UpdateMask<NUM_CLIENT_OBJECT_TYPES> valuesMask; + if (requestedObjectMask.IsAnySet()) + valuesMask.Set(TYPEID_OBJECT); + + if (requestedConversationMask.IsAnySet()) + valuesMask.Set(TYPEID_CONVERSATION); + + ByteBuffer buffer = PrepareValuesUpdateBuffer(); + std::size_t sizePos = buffer.wpos(); + buffer << uint32(0); + buffer << uint32(valuesMask.GetBlock(0)); + + if (valuesMask[TYPEID_OBJECT]) + m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target); + + if (valuesMask[TYPEID_CONVERSATION]) + m_conversationData->WriteUpdate(buffer, requestedConversationMask, true, this, target); + + buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4); + + data->AddUpdateBlock(buffer); +} + void Conversation::ClearUpdateMask(bool remove) { m_values.ClearChangesMask(&Conversation::m_conversationData); diff --git a/src/server/game/Entities/Conversation/Conversation.h b/src/server/game/Entities/Conversation/Conversation.h index cbd3b5feaac..b17dbd9d393 100644 --- a/src/server/game/Entities/Conversation/Conversation.h +++ b/src/server/game/Entities/Conversation/Conversation.h @@ -39,10 +39,15 @@ class TC_GAME_API Conversation : public WorldObject, public GridObject<Conversat Conversation(); ~Conversation(); + protected: void BuildValuesCreate(ByteBuffer* data, Player const* target) const override; void BuildValuesUpdate(ByteBuffer* data, Player const* target) const override; void ClearUpdateMask(bool remove) override; + public: + void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, + UF::ConversationData::Mask const& requestedConversationMask, Player const* target) const; + void AddToWorld() override; void RemoveFromWorld() override; diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp index 60b36d96b64..2251f570af3 100644 --- a/src/server/game/Entities/Corpse/Corpse.cpp +++ b/src/server/game/Entities/Corpse/Corpse.cpp @@ -245,6 +245,32 @@ void Corpse::BuildValuesUpdate(ByteBuffer* data, Player const* target) const data->put<uint32>(sizePos, data->wpos() - sizePos - 4); } +void Corpse::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, + UF::CorpseData::Mask const& requestedCorpseMask, Player const* target) const +{ + UpdateMask<NUM_CLIENT_OBJECT_TYPES> valuesMask; + if (requestedObjectMask.IsAnySet()) + valuesMask.Set(TYPEID_OBJECT); + + if (requestedCorpseMask.IsAnySet()) + valuesMask.Set(TYPEID_CORPSE); + + ByteBuffer buffer = PrepareValuesUpdateBuffer(); + std::size_t sizePos = buffer.wpos(); + buffer << uint32(0); + buffer << uint32(valuesMask.GetBlock(0)); + + if (valuesMask[TYPEID_OBJECT]) + m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target); + + if (valuesMask[TYPEID_CORPSE]) + m_corpseData->WriteUpdate(buffer, requestedCorpseMask, true, this, target); + + buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4); + + data->AddUpdateBlock(buffer); +} + void Corpse::ClearUpdateMask(bool remove) { m_values.ClearChangesMask(&Corpse::m_corpseData); diff --git a/src/server/game/Entities/Corpse/Corpse.h b/src/server/game/Entities/Corpse/Corpse.h index 4156fbf7eb3..8828c92e21a 100644 --- a/src/server/game/Entities/Corpse/Corpse.h +++ b/src/server/game/Entities/Corpse/Corpse.h @@ -52,10 +52,15 @@ class TC_GAME_API Corpse : public WorldObject, public GridObject<Corpse> explicit Corpse(CorpseType type = CORPSE_BONES); ~Corpse(); + protected: void BuildValuesCreate(ByteBuffer* data, Player const* target) const override; void BuildValuesUpdate(ByteBuffer* data, Player const* target) const override; void ClearUpdateMask(bool remove) override; + public: + void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, + UF::CorpseData::Mask const& requestedCorpseMask, Player const* target) const; + void AddToWorld() override; void RemoveFromWorld() override; diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.cpp b/src/server/game/Entities/DynamicObject/DynamicObject.cpp index 315d781631c..58e277f61f8 100644 --- a/src/server/game/Entities/DynamicObject/DynamicObject.cpp +++ b/src/server/game/Entities/DynamicObject/DynamicObject.cpp @@ -273,6 +273,32 @@ void DynamicObject::BuildValuesUpdate(ByteBuffer* data, Player const* target) co data->put<uint32>(sizePos, data->wpos() - sizePos - 4); } +void DynamicObject::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, + UF::DynamicObjectData::Mask const& requestedDynamicObjectMask, Player const* target) const +{ + UpdateMask<NUM_CLIENT_OBJECT_TYPES> valuesMask; + if (requestedObjectMask.IsAnySet()) + valuesMask.Set(TYPEID_OBJECT); + + if (requestedDynamicObjectMask.IsAnySet()) + valuesMask.Set(TYPEID_DYNAMICOBJECT); + + ByteBuffer buffer = PrepareValuesUpdateBuffer(); + std::size_t sizePos = buffer.wpos(); + buffer << uint32(0); + buffer << uint32(valuesMask.GetBlock(0)); + + if (valuesMask[TYPEID_OBJECT]) + m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target); + + if (valuesMask[TYPEID_DYNAMICOBJECT]) + m_dynamicObjectData->WriteUpdate(buffer, requestedDynamicObjectMask, true, this, target); + + buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4); + + data->AddUpdateBlock(buffer); +} + void DynamicObject::ClearUpdateMask(bool remove) { m_values.ClearChangesMask(&DynamicObject::m_dynamicObjectData); diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.h b/src/server/game/Entities/DynamicObject/DynamicObject.h index ca08043faeb..4786dd763f3 100644 --- a/src/server/game/Entities/DynamicObject/DynamicObject.h +++ b/src/server/game/Entities/DynamicObject/DynamicObject.h @@ -38,10 +38,15 @@ class TC_GAME_API DynamicObject : public WorldObject, public GridObject<DynamicO DynamicObject(bool isWorldObject); ~DynamicObject(); + protected: void BuildValuesCreate(ByteBuffer* data, Player const* target) const override; void BuildValuesUpdate(ByteBuffer* data, Player const* target) const override; void ClearUpdateMask(bool remove) override; + public: + void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, + UF::DynamicObjectData::Mask const& requestedDynamicObjectMask, Player const* target) const; + void AddToWorld() override; void RemoveFromWorld() override; diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 151f9419d51..b9e17565702 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -2609,6 +2609,32 @@ void GameObject::BuildValuesUpdate(ByteBuffer* data, Player const* target) const data->put<uint32>(sizePos, data->wpos() - sizePos - 4); } +void GameObject::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, + UF::GameObjectData::Mask const& requestedGameObjectMask, Player const* target) const +{ + UpdateMask<NUM_CLIENT_OBJECT_TYPES> valuesMask; + if (requestedObjectMask.IsAnySet()) + valuesMask.Set(TYPEID_OBJECT); + + if (requestedGameObjectMask.IsAnySet()) + valuesMask.Set(TYPEID_GAMEOBJECT); + + ByteBuffer buffer = PrepareValuesUpdateBuffer(); + std::size_t sizePos = buffer.wpos(); + buffer << uint32(0); + buffer << uint32(valuesMask.GetBlock(0)); + + if (valuesMask[TYPEID_OBJECT]) + m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target); + + if (valuesMask[TYPEID_GAMEOBJECT]) + m_gameObjectData->WriteUpdate(buffer, requestedGameObjectMask, true, this, target); + + buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4); + + data->AddUpdateBlock(buffer); +} + void GameObject::ClearUpdateMask(bool remove) { m_values.ClearChangesMask(&GameObject::m_gameObjectData); diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 81bd5f1e340..b34f5e7951d 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -84,10 +84,15 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> explicit GameObject(); ~GameObject(); + protected: void BuildValuesCreate(ByteBuffer* data, Player const* target) const override; void BuildValuesUpdate(ByteBuffer* data, Player const* target) const override; void ClearUpdateMask(bool remove) override; + public: + void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, + UF::GameObjectData::Mask const& requestedGameObjectMask, Player const* target) const; + void AddToWorld() override; void RemoveFromWorld() override; void CleanupsBeforeDelete(bool finalCleanup = true) override; diff --git a/src/server/game/Entities/Item/AzeriteItem/AzeriteEmpoweredItem.cpp b/src/server/game/Entities/Item/AzeriteItem/AzeriteEmpoweredItem.cpp index d36d3120ee4..bf8047b5d20 100644 --- a/src/server/game/Entities/Item/AzeriteItem/AzeriteEmpoweredItem.cpp +++ b/src/server/game/Entities/Item/AzeriteItem/AzeriteEmpoweredItem.cpp @@ -19,6 +19,7 @@ #include "DatabaseEnv.h" #include "DB2Stores.h" #include "Player.h" +#include "UpdateData.h" AzeriteEmpoweredItem::AzeriteEmpoweredItem() { @@ -184,6 +185,41 @@ void AzeriteEmpoweredItem::BuildValuesUpdate(ByteBuffer* data, Player const* tar data->put<uint32>(sizePos, data->wpos() - sizePos - 4); } +void AzeriteEmpoweredItem::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, + UF::ItemData::Mask const& requestedItemMask, UF::AzeriteEmpoweredItemData::Mask const& requestedAzeriteEmpoweredItemMask, Player const* target) const +{ + UF::UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target); + UpdateMask<NUM_CLIENT_OBJECT_TYPES> valuesMask; + if (requestedObjectMask.IsAnySet()) + valuesMask.Set(TYPEID_OBJECT); + + UF::ItemData::Mask itemMask = requestedItemMask; + m_itemData->FilterDisallowedFieldsMaskForFlag(itemMask, flags); + if (itemMask.IsAnySet()) + valuesMask.Set(TYPEID_ITEM); + + if (requestedAzeriteEmpoweredItemMask.IsAnySet()) + valuesMask.Set(TYPEID_AZERITE_EMPOWERED_ITEM); + + ByteBuffer buffer = PrepareValuesUpdateBuffer(); + std::size_t sizePos = buffer.wpos(); + buffer << uint32(0); + buffer << uint32(valuesMask.GetBlock(0)); + + if (valuesMask[TYPEID_OBJECT]) + m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target); + + if (valuesMask[TYPEID_ITEM]) + m_itemData->WriteUpdate(buffer, itemMask, true, this, target); + + if (valuesMask[TYPEID_AZERITE_EMPOWERED_ITEM]) + m_azeriteEmpoweredItemData->WriteUpdate(buffer, requestedAzeriteEmpoweredItemMask, true, this, target); + + buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4); + + data->AddUpdateBlock(buffer); +} + void AzeriteEmpoweredItem::ClearUpdateMask(bool remove) { m_values.ClearChangesMask(&AzeriteEmpoweredItem::m_azeriteEmpoweredItemData); diff --git a/src/server/game/Entities/Item/AzeriteItem/AzeriteEmpoweredItem.h b/src/server/game/Entities/Item/AzeriteItem/AzeriteEmpoweredItem.h index 25e00ba139a..a0c66f2f43d 100644 --- a/src/server/game/Entities/Item/AzeriteItem/AzeriteEmpoweredItem.h +++ b/src/server/game/Entities/Item/AzeriteItem/AzeriteEmpoweredItem.h @@ -42,10 +42,15 @@ public: int64 GetRespecCost() const; +protected: void BuildValuesCreate(ByteBuffer* data, Player const* target) const override; void BuildValuesUpdate(ByteBuffer* data, Player const* target) const override; void ClearUpdateMask(bool remove) override; +public: + void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, UF::ItemData::Mask const& requestedItemMask, + UF::AzeriteEmpoweredItemData::Mask const& requestedAzeriteEmpoweredItemMask, Player const* target) const; + UF::UpdateField<UF::AzeriteEmpoweredItemData, 0, TYPEID_AZERITE_EMPOWERED_ITEM> m_azeriteEmpoweredItemData; private: diff --git a/src/server/game/Entities/Item/AzeriteItem/AzeriteItem.cpp b/src/server/game/Entities/Item/AzeriteItem/AzeriteItem.cpp index f156f14ccaa..3429055b7e4 100644 --- a/src/server/game/Entities/Item/AzeriteItem/AzeriteItem.cpp +++ b/src/server/game/Entities/Item/AzeriteItem/AzeriteItem.cpp @@ -22,6 +22,7 @@ #include "GameObject.h" #include "GameTime.h" #include "Player.h" +#include "UpdateData.h" #include <boost/date_time/gregorian/gregorian_types.hpp> #include <boost/date_time/posix_time/conversion.hpp> @@ -433,15 +434,52 @@ void AzeriteItem::BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFla UF::ItemData::Mask mask; m_itemData->AppendAllowedFieldsMaskForFlag(mask, flags); - m_itemData->WriteUpdate(*data, mask, flags, this, target); + m_itemData->WriteUpdate(*data, mask, true, this, target); UF::AzeriteItemData::Mask mask2; m_azeriteItemData->AppendAllowedFieldsMaskForFlag(mask2, flags); - m_azeriteItemData->WriteUpdate(*data, mask2, flags, this, target); + m_azeriteItemData->WriteUpdate(*data, mask2, true, this, target); data->put<uint32>(sizePos, data->wpos() - sizePos - 4); } +void AzeriteItem::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, + UF::ItemData::Mask const& requestedItemMask, UF::AzeriteItemData::Mask const& requestedAzeriteItemMask, Player const* target) const +{ + UF::UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target); + UpdateMask<NUM_CLIENT_OBJECT_TYPES> valuesMask; + if (requestedObjectMask.IsAnySet()) + valuesMask.Set(TYPEID_OBJECT); + + UF::ItemData::Mask itemMask = requestedItemMask; + m_itemData->FilterDisallowedFieldsMaskForFlag(itemMask, flags); + if (itemMask.IsAnySet()) + valuesMask.Set(TYPEID_ITEM); + + UF::AzeriteItemData::Mask azeriteItemMask = requestedAzeriteItemMask; + m_azeriteItemData->FilterDisallowedFieldsMaskForFlag(azeriteItemMask, flags); + if (azeriteItemMask.IsAnySet()) + valuesMask.Set(TYPEID_AZERITE_ITEM); + + ByteBuffer buffer = PrepareValuesUpdateBuffer(); + std::size_t sizePos = buffer.wpos(); + buffer << uint32(0); + buffer << uint32(valuesMask.GetBlock(0)); + + if (valuesMask[TYPEID_OBJECT]) + m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target); + + if (valuesMask[TYPEID_ITEM]) + m_itemData->WriteUpdate(buffer, itemMask, true, this, target); + + if (valuesMask[TYPEID_AZERITE_ITEM]) + m_azeriteItemData->WriteUpdate(buffer, azeriteItemMask, true, this, target); + + buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4); + + data->AddUpdateBlock(buffer); +} + void AzeriteItem::ClearUpdateMask(bool remove) { m_values.ClearChangesMask(&AzeriteItem::m_azeriteItemData); diff --git a/src/server/game/Entities/Item/AzeriteItem/AzeriteItem.h b/src/server/game/Entities/Item/AzeriteItem/AzeriteItem.h index d1049e9ff66..14fba648e53 100644 --- a/src/server/game/Entities/Item/AzeriteItem/AzeriteItem.h +++ b/src/server/game/Entities/Item/AzeriteItem/AzeriteItem.h @@ -73,11 +73,16 @@ public: void CreateSelectedAzeriteEssences(uint32 specializationId); void SetSelectedAzeriteEssence(uint8 slot, uint32 azeriteEssenceId); +protected: void BuildValuesCreate(ByteBuffer* data, Player const* target) const override; void BuildValuesUpdate(ByteBuffer* data, Player const* target) const override; - void BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override; void ClearUpdateMask(bool remove) override; +public: + void BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override; + void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, UF::ItemData::Mask const& requestedItemMask, + UF::AzeriteItemData::Mask const& requestedAzeriteItemMask, Player const* target) const; + UF::UpdateField<UF::AzeriteItemData, 0, TYPEID_AZERITE_ITEM> m_azeriteItemData; private: diff --git a/src/server/game/Entities/Item/Container/Bag.cpp b/src/server/game/Entities/Item/Container/Bag.cpp index ccf44e3dc0d..f7216c89bd7 100644 --- a/src/server/game/Entities/Item/Container/Bag.cpp +++ b/src/server/game/Entities/Item/Container/Bag.cpp @@ -212,6 +212,41 @@ void Bag::BuildValuesUpdate(ByteBuffer* data, Player const* target) const data->put<uint32>(sizePos, data->wpos() - sizePos - 4); } +void Bag::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, + UF::ItemData::Mask const& requestedItemMask, UF::ContainerData::Mask const& requestedContainerMask, Player const* target) const +{ + UF::UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target); + UpdateMask<NUM_CLIENT_OBJECT_TYPES> valuesMask; + if (requestedObjectMask.IsAnySet()) + valuesMask.Set(TYPEID_OBJECT); + + UF::ItemData::Mask itemMask = requestedItemMask; + m_itemData->FilterDisallowedFieldsMaskForFlag(itemMask, flags); + if (itemMask.IsAnySet()) + valuesMask.Set(TYPEID_ITEM); + + if (requestedContainerMask.IsAnySet()) + valuesMask.Set(TYPEID_CONTAINER); + + ByteBuffer buffer = PrepareValuesUpdateBuffer(); + std::size_t sizePos = buffer.wpos(); + buffer << uint32(0); + buffer << uint32(valuesMask.GetBlock(0)); + + if (valuesMask[TYPEID_OBJECT]) + m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target); + + if (valuesMask[TYPEID_ITEM]) + m_itemData->WriteUpdate(buffer, itemMask, true, this, target); + + if (valuesMask[TYPEID_CONTAINER]) + m_containerData->WriteUpdate(buffer, requestedContainerMask, true, this, target); + + buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4); + + data->AddUpdateBlock(buffer); +} + void Bag::ClearUpdateMask(bool remove) { m_values.ClearChangesMask(&Bag::m_containerData); diff --git a/src/server/game/Entities/Item/Container/Bag.h b/src/server/game/Entities/Item/Container/Bag.h index 72074ea4911..6ef24ee9db1 100644 --- a/src/server/game/Entities/Item/Container/Bag.h +++ b/src/server/game/Entities/Item/Container/Bag.h @@ -56,11 +56,16 @@ class TC_GAME_API Bag : public Item // overwrite virtual Item::DeleteFromDB void DeleteFromDB(CharacterDatabaseTransaction& trans) override; + protected: void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const override; void BuildValuesCreate(ByteBuffer* data, Player const* target) const override; void BuildValuesUpdate(ByteBuffer* data, Player const* target) const override; void ClearUpdateMask(bool remove) override; + public: + void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, UF::ItemData::Mask const& requestedItemMask, + UF::ContainerData::Mask const& requestedContainerMask, Player const* target) const; + UF::UpdateField<UF::ContainerData, 0, TYPEID_CONTAINER> m_containerData; protected: diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index e0d19a8b86b..57be82a51ef 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -1628,11 +1628,40 @@ void Item::BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag flags UF::ItemData::Mask mask; m_itemData->AppendAllowedFieldsMaskForFlag(mask, flags); - m_itemData->WriteUpdate(*data, mask, flags, this, target); + m_itemData->WriteUpdate(*data, mask, true, this, target); data->put<uint32>(sizePos, data->wpos() - sizePos - 4); } +void Item::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, + UF::ItemData::Mask const& requestedItemMask, Player const* target) const +{ + UF::UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target); + UpdateMask<NUM_CLIENT_OBJECT_TYPES> valuesMask; + if (requestedObjectMask.IsAnySet()) + valuesMask.Set(TYPEID_OBJECT); + + UF::ItemData::Mask itemMask = requestedItemMask; + m_itemData->FilterDisallowedFieldsMaskForFlag(itemMask, flags); + if (itemMask.IsAnySet()) + valuesMask.Set(TYPEID_ITEM); + + ByteBuffer buffer = PrepareValuesUpdateBuffer(); + std::size_t sizePos = buffer.wpos(); + buffer << uint32(0); + buffer << uint32(valuesMask.GetBlock(0)); + + if (valuesMask[TYPEID_OBJECT]) + m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target); + + if (valuesMask[TYPEID_ITEM]) + m_itemData->WriteUpdate(buffer, itemMask, true, this, target); + + buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4); + + data->AddUpdateBlock(buffer); +} + void Item::ClearUpdateMask(bool remove) { m_values.ClearChangesMask(&Item::m_itemData); diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index f9839baa41f..13f0cb7de66 100644 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -373,11 +373,17 @@ class TC_GAME_API Item : public Object bool CheckSoulboundTradeExpire(); void BuildUpdate(UpdateDataMapType&) override; + + protected: UF::UpdateFieldFlag GetUpdateFieldFlagsFor(Player const* target) const override; void BuildValuesCreate(ByteBuffer* data, Player const* target) const override; void BuildValuesUpdate(ByteBuffer* data, Player const* target) const override; - void BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override; void ClearUpdateMask(bool remove) override; + + public: + void BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override; + void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, + UF::ItemData::Mask const& requestedItemMask, Player const* target) const; void AddToObjectUpdate() override; void RemoveFromObjectUpdate() override; diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 645cfb92e5f..b34b3523fc4 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -237,10 +237,7 @@ void Object::SendUpdateToPlayer(Player* player) void Object::BuildValuesUpdateBlockForPlayer(UpdateData* data, Player const* target) const { - ByteBuffer buf(500); - - buf << uint8(UPDATETYPE_VALUES); - buf << GetGUID(); + ByteBuffer buf = PrepareValuesUpdateBuffer(); BuildValuesUpdate(&buf, target); @@ -249,10 +246,7 @@ void Object::BuildValuesUpdateBlockForPlayer(UpdateData* data, Player const* tar void Object::BuildValuesUpdateBlockForPlayerWithFlag(UpdateData* data, UF::UpdateFieldFlag flags, Player const* target) const { - ByteBuffer buf(500); - - buf << uint8(UPDATETYPE_VALUES); - buf << GetGUID(); + ByteBuffer buf = PrepareValuesUpdateBuffer(); BuildValuesUpdateWithFlag(&buf, flags, target); @@ -269,6 +263,14 @@ void Object::BuildOutOfRangeUpdateBlock(UpdateData* data) const data->AddOutOfRangeGUID(GetGUID()); } +ByteBuffer Object::PrepareValuesUpdateBuffer() const +{ + ByteBuffer buffer(500); + buffer << uint8(UPDATETYPE_VALUES); + buffer << GetGUID(); + return buffer; +} + void Object::DestroyForPlayer(Player* target) const { ASSERT(target); diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 30879ce1194..c5e22c86c3a 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -155,6 +155,7 @@ class TC_GAME_API Object void BuildValuesUpdateBlockForPlayerWithFlag(UpdateData* data, UF::UpdateFieldFlag flags, Player const* target) const; void BuildDestroyUpdateBlock(UpdateData* data) const; void BuildOutOfRangeUpdateBlock(UpdateData* data) const; + ByteBuffer PrepareValuesUpdateBuffer() const; virtual void DestroyForPlayer(Player* target) const; @@ -311,8 +312,11 @@ class TC_GAME_API Object virtual UF::UpdateFieldFlag GetUpdateFieldFlagsFor(Player const* target) const; virtual void BuildValuesCreate(ByteBuffer* data, Player const* target) const = 0; virtual void BuildValuesUpdate(ByteBuffer* data, Player const* target) const = 0; + + public: virtual void BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const; + protected: uint16 m_objectType; TypeID m_objectTypeId; diff --git a/src/server/game/Entities/Object/Updates/UpdateField.cpp b/src/server/game/Entities/Object/Updates/UpdateField.cpp index 03f430f5661..79b7c3732dc 100644 --- a/src/server/game/Entities/Object/Updates/UpdateField.cpp +++ b/src/server/game/Entities/Object/Updates/UpdateField.cpp @@ -39,3 +39,25 @@ void UF::WriteDynamicFieldUpdateMask(std::size_t size, std::vector<uint32> const if (size % 32) data.WriteBits(updateMask.back(), size % 32); } + +void UF::WriteCompleteDynamicFieldUpdateMask(std::size_t size, ByteBuffer& data) +{ + data.WriteBits(size, 32); + if (size > 32) + { + if (data.HasUnfinishedBitPack()) + for (std::size_t block = 0; block < size / 32; ++block) + data.WriteBits(0xFFFFFFFFu, 32); + else + for (std::size_t block = 0; block < size / 32; ++block) + data << uint32(0xFFFFFFFFu); + } + else if (size == 32) + { + data.WriteBits(0xFFFFFFFFu, 32); + return; + } + + if (size % 32) + data.WriteBits(0xFFFFFFFFu, size % 32); +} diff --git a/src/server/game/Entities/Object/Updates/UpdateField.h b/src/server/game/Entities/Object/Updates/UpdateField.h index 346c3a0d09b..5c399c86f80 100644 --- a/src/server/game/Entities/Object/Updates/UpdateField.h +++ b/src/server/game/Entities/Object/Updates/UpdateField.h @@ -236,7 +236,7 @@ namespace UF std::conditional_t<std::is_base_of<IsUpdateFieldStructureTag, V>::value, MutableFieldReference<V, PublicSet>, std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>> - ModifyValue(UpdateField<V, BlockBit, Bit>(T:: * field)) + ModifyValue(UpdateField<V, BlockBit, Bit>(T::* field)) { _value._changesMask.Set(BlockBit); _value._changesMask.Set(Bit); @@ -248,7 +248,7 @@ namespace UF std::conditional_t<std::is_base_of<IsUpdateFieldStructureTag, V>::value, MutableFieldReference<V, PublicSet>, std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>> - ModifyValue(UpdateFieldArray<V, Size, Bit, FirstElementBit>(T:: * field), uint32 index) + ModifyValue(UpdateFieldArray<V, Size, Bit, FirstElementBit>(T::* field), uint32 index) { _value._changesMask.Set(Bit); _value._changesMask.Set(FirstElementBit + index); @@ -269,7 +269,7 @@ namespace UF std::conditional_t<std::is_base_of<IsUpdateFieldStructureTag, V>::value, MutableFieldReference<V, PublicSet>, std::conditional_t<PublicSet, UpdateFieldPublicSetter<V>, UpdateFieldSetter<V>>>> - ModifyValue(DynamicUpdateField<V, BlockBit, Bit>(T:: * field), uint32 index) + ModifyValue(DynamicUpdateField<V, BlockBit, Bit>(T::* field), uint32 index) { if (index >= (_value.*field).size()) { @@ -353,24 +353,21 @@ namespace UF template<typename Derived, typename T, uint32 BlockBit, uint32 Bit> MutableFieldReference<T, false> ModifyValue(UpdateField<T, BlockBit, Bit>(Derived::* field)) { - _changesMask.Set(BlockBit); - _changesMask.Set(Bit); + MarkChanged(field); return { (static_cast<Derived*>(this)->*field)._value }; } template<typename Derived, typename T, std::size_t Size, uint32 Bit, uint32 FirstElementBit> MutableFieldReference<T, false> ModifyValue(UpdateFieldArray<T, Size, Bit, FirstElementBit>(Derived::* field), uint32 index) { - _changesMask.Set(Bit); - _changesMask.Set(FirstElementBit + index); + MarkChanged(field, index); return { (static_cast<Derived*>(this)->*field)._values[index] }; } template<typename Derived, typename T, uint32 BlockBit, uint32 Bit> MutableFieldReference<T, false> ModifyValue(DynamicUpdateField<T, BlockBit, Bit>(Derived::* field)) { - _changesMask.Set(BlockBit); - _changesMask.Set(Bit); + MarkChanged(field); return { (static_cast<Derived*>(this)->*field)._values }; } @@ -385,8 +382,7 @@ namespace UF uf._updateMask.resize((uf._values.size() + 31) / 32); } - _changesMask.Set(BlockBit); - _changesMask.Set(Bit); + MarkChanged(field); (static_cast<Derived*>(this)->*field).MarkChanged(index); return { uf._values[index] }; } @@ -394,20 +390,59 @@ namespace UF template<typename Derived, typename T, uint32 BlockBit, uint32 Bit> MutableFieldReference<T, false> ModifyValue(OptionalUpdateField<T, BlockBit, Bit>(Derived::* field)) { + MarkChanged(field); + return { *((static_cast<Derived*>(this)->*field)._value) }; + } + + template<typename Derived, typename T, uint32 BlockBit, uint32 Bit> + void MarkChanged(UpdateField<T, BlockBit, Bit>(Derived::*)) + { + static_assert(std::is_base_of<Base, Derived>::value, "Given field argument must belong to the same structure as this HasChangesMask"); + + _changesMask.Set(BlockBit); + _changesMask.Set(Bit); + } + + template<typename Derived, typename T, std::size_t Size, uint32 Bit, uint32 FirstElementBit> + void MarkChanged(UpdateFieldArray<T, Size, Bit, FirstElementBit>(Derived::*), uint32 index) + { + static_assert(std::is_base_of<Base, Derived>::value, "Given field argument must belong to the same structure as this HasChangesMask"); + + _changesMask.Set(Bit); + _changesMask.Set(FirstElementBit + index); + } + + template<typename Derived, typename T, uint32 BlockBit, uint32 Bit> + void MarkChanged(DynamicUpdateField<T, BlockBit, Bit>(Derived::*), uint32) + { + static_assert(std::is_base_of<Base, Derived>::value, "Given field argument must belong to the same structure as this HasChangesMask"); + + _changesMask.Set(BlockBit); + _changesMask.Set(Bit); + } + + template<typename Derived, typename T, uint32 BlockBit, uint32 Bit> + void MarkChanged(OptionalUpdateField<T, BlockBit, Bit>(Derived::*)) + { + static_assert(std::is_base_of<Base, Derived>::value, "Given field argument must belong to the same structure as this HasChangesMask"); + _changesMask.Set(BlockBit); _changesMask.Set(Bit); - return { *((static_cast<Derived*>(this)->*field)._value) }; } template<typename Derived, typename T, uint32 BlockBit, uint32 Bit> void ClearChanged(UpdateField<T, BlockBit, Bit>(Derived::*)) { + static_assert(std::is_base_of<Base, Derived>::value, "Given field argument must belong to the same structure as this HasChangesMask"); + _changesMask.Reset(Bit); } template<typename Derived, typename T, std::size_t Size, uint32 Bit, uint32 FirstElementBit> void ClearChanged(UpdateFieldArray<T, Size, Bit, FirstElementBit>(Derived::*), uint32 index) { + static_assert(std::is_base_of<Base, Derived>::value, "Given field argument must belong to the same structure as this HasChangesMask"); + _changesMask.Reset(Bit); _changesMask.Reset(FirstElementBit + index); } @@ -422,9 +457,13 @@ namespace UF template<typename Derived, typename T, uint32 BlockBit, uint32 Bit> void ClearChanged(OptionalUpdateField<T, BlockBit, Bit>(Derived::*)) { + static_assert(std::is_base_of<Base, Derived>::value, "Given field argument must belong to the same structure as this HasChangesMask"); + _changesMask.Reset(Bit); } + Mask const& GetChangesMask() const { return _changesMask; } + protected: template<typename T, uint32 BlockBit, uint32 Bit> void ClearChangesMask(UpdateField<T, BlockBit, Bit>& field) @@ -597,6 +636,7 @@ namespace UF }; void WriteDynamicFieldUpdateMask(std::size_t size, std::vector<uint32> const& updateMask, ByteBuffer& data); + void WriteCompleteDynamicFieldUpdateMask(std::size_t size, ByteBuffer& data); template<typename T, uint32 BlockBit, uint32 Bit> class DynamicUpdateField diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.cpp b/src/server/game/Entities/Object/Updates/UpdateFields.cpp index 56bade88f2d..f6494ed1fde 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFields.cpp +++ b/src/server/game/Entities/Object/Updates/UpdateFields.cpp @@ -39,7 +39,11 @@ void ObjectData::WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fi void ObjectData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const { - UpdateMask<4> const& changesMask = _changesMask; + WriteUpdate(data, _changesMask, false, owner, receiver); +} + +void ObjectData::WriteUpdate(ByteBuffer& data, UpdateMask<4> const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) const +{ data.WriteBits(changesMask.GetBlock(0), 4); data.FlushBits(); @@ -76,9 +80,12 @@ void ItemEnchantment::WriteCreate(ByteBuffer& data, Item const* owner, Player co data << uint16(Inactive); } -void ItemEnchantment::WriteUpdate(ByteBuffer& data, Item const* owner, Player const* receiver) const +void ItemEnchantment::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Item const* owner, Player const* receiver) const { - UpdateMask<5> const& changesMask = _changesMask; + UpdateMask<5> changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + data.WriteBits(changesMask.GetBlock(0), 5); data.FlushBits(); @@ -119,7 +126,7 @@ void ArtifactPower::WriteCreate(ByteBuffer& data, Item const* owner, Player cons data << uint8(CurrentRankWithBonus); } -void ArtifactPower::WriteUpdate(ByteBuffer& data, Item const* owner, Player const* receiver) const +void ArtifactPower::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Item const* owner, Player const* receiver) const { data << int16(ArtifactPowerID); data << uint8(PurchasedRank); @@ -136,9 +143,12 @@ void SocketedGem::WriteCreate(ByteBuffer& data, Item const* owner, Player const* data << uint8(Context); } -void SocketedGem::WriteUpdate(ByteBuffer& data, Item const* owner, Player const* receiver) const +void SocketedGem::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Item const* owner, Player const* receiver) const { - UpdateMask<20> const& changesMask = _changesMask; + UpdateMask<20> changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + data.WriteBits(changesMask.GetBlocksMask(0), 1); if (changesMask.GetBlock(0)) data.WriteBits(changesMask.GetBlock(0), 32); @@ -241,7 +251,7 @@ void ItemData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fiel { UpdateMask<40> allowedMaskForTarget({ 0xFC0149FFu, 0x000000FFu }); AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); - WriteUpdate(data, _changesMask & allowedMaskForTarget, fieldVisibilityFlags, owner, receiver); + WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver); } void ItemData::AppendAllowedFieldsMaskForFlag(UpdateMask<40>& allowedMaskForTarget, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags) const @@ -250,7 +260,13 @@ void ItemData::AppendAllowedFieldsMaskForFlag(UpdateMask<40>& allowedMaskForTarg allowedMaskForTarget |= { 0x03FEB600u, 0x00000000u }; } -void ItemData::WriteUpdate(ByteBuffer& data, UpdateMask<40> const& changesMask, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Item const* owner, Player const* receiver) const +void ItemData::FilterDisallowedFieldsMaskForFlag(UpdateMask<40>& changesMask, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags) const +{ + if (!fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + changesMask &= { 0xFC0149FFu, 0xFFFFFFFFu }; +} + +void ItemData::WriteUpdate(ByteBuffer& data, UpdateMask<40> const& changesMask, bool ignoreNestedChangesMask, Item const* owner, Player const* receiver) const { data.WriteBits(changesMask.GetBlocksMask(0), 2); for (std::size_t i = 0; i < 2; ++i) @@ -273,15 +289,24 @@ void ItemData::WriteUpdate(ByteBuffer& data, UpdateMask<40> const& changesMask, { if (changesMask[2]) { - Modifiers.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + Modifiers.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Modifiers.size(), data); } if (changesMask[3]) { - ArtifactPowers.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + ArtifactPowers.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(ArtifactPowers.size(), data); } if (changesMask[4]) { - Gems.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + Gems.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Gems.size(), data); } } data.FlushBits(); @@ -291,7 +316,7 @@ void ItemData::WriteUpdate(ByteBuffer& data, UpdateMask<40> const& changesMask, { for (std::size_t i = 0; i < Modifiers.size(); ++i) { - if (Modifiers.HasChanged(i)) + if (Modifiers.HasChanged(i) || ignoreNestedChangesMask) { data << int32(Modifiers[i]); } @@ -301,9 +326,9 @@ void ItemData::WriteUpdate(ByteBuffer& data, UpdateMask<40> const& changesMask, { for (std::size_t i = 0; i < ArtifactPowers.size(); ++i) { - if (ArtifactPowers.HasChanged(i)) + if (ArtifactPowers.HasChanged(i) || ignoreNestedChangesMask) { - ArtifactPowers[i].WriteUpdate(data, owner, receiver); + ArtifactPowers[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } @@ -311,9 +336,9 @@ void ItemData::WriteUpdate(ByteBuffer& data, UpdateMask<40> const& changesMask, { for (std::size_t i = 0; i < Gems.size(); ++i) { - if (Gems.HasChanged(i)) + if (Gems.HasChanged(i) || ignoreNestedChangesMask) { - Gems[i].WriteUpdate(data, owner, receiver); + Gems[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } @@ -394,7 +419,7 @@ void ItemData::WriteUpdate(ByteBuffer& data, UpdateMask<40> const& changesMask, { if (changesMask[27 + i]) { - Enchantment[i].WriteUpdate(data, owner, receiver); + Enchantment[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } @@ -437,7 +462,11 @@ void ContainerData::WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> void ContainerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Bag const* owner, Player const* receiver) const { - UpdateMask<39> const& changesMask = _changesMask; + WriteUpdate(data, _changesMask, false, owner, receiver); +} + +void ContainerData::WriteUpdate(ByteBuffer& data, UpdateMask<39> const& changesMask, bool ignoreNestedChangesMask, Bag const* owner, Player const* receiver) const +{ data.WriteBits(changesMask.GetBlocksMask(0), 2); for (std::size_t i = 0; i < 2; ++i) if (changesMask.GetBlock(i)) @@ -480,7 +509,11 @@ void AzeriteEmpoweredItemData::WriteCreate(ByteBuffer& data, EnumClassFlag<Updat void AzeriteEmpoweredItemData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, AzeriteEmpoweredItem const* owner, Player const* receiver) const { - UpdateMask<6> const& changesMask = _changesMask; + WriteUpdate(data, _changesMask, false, owner, receiver); +} + +void AzeriteEmpoweredItemData::WriteUpdate(ByteBuffer& data, UpdateMask<6> const& changesMask, bool ignoreNestedChangesMask, AzeriteEmpoweredItem const* owner, Player const* receiver) const +{ data.WriteBits(changesMask.GetBlocksMask(0), 1); if (changesMask.GetBlock(0)) data.WriteBits(changesMask.GetBlock(0), 32); @@ -510,7 +543,7 @@ void UnlockedAzeriteEssence::WriteCreate(ByteBuffer& data, AzeriteItem const* ow data << uint32(Rank); } -void UnlockedAzeriteEssence::WriteUpdate(ByteBuffer& data, AzeriteItem const* owner, Player const* receiver) const +void UnlockedAzeriteEssence::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AzeriteItem const* owner, Player const* receiver) const { data << uint32(AzeriteEssenceID); data << uint32(Rank); @@ -527,9 +560,12 @@ void SelectedAzeriteEssences::WriteCreate(ByteBuffer& data, AzeriteItem const* o data.FlushBits(); } -void SelectedAzeriteEssences::WriteUpdate(ByteBuffer& data, AzeriteItem const* owner, Player const* receiver) const +void SelectedAzeriteEssences::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AzeriteItem const* owner, Player const* receiver) const { - UpdateMask<8> const& changesMask = _changesMask; + UpdateMask<8> changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + data.WriteBits(changesMask.GetBlocksMask(0), 1); if (changesMask.GetBlock(0)) data.WriteBits(changesMask.GetBlock(0), 32); @@ -598,7 +634,7 @@ void AzeriteItemData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFla { UpdateMask<9> allowedMaskForTarget({ 0x0000000Fu }); AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); - WriteUpdate(data, _changesMask & allowedMaskForTarget, fieldVisibilityFlags, owner, receiver); + WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver); } void AzeriteItemData::AppendAllowedFieldsMaskForFlag(UpdateMask<9>& allowedMaskForTarget, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags) const @@ -607,7 +643,13 @@ void AzeriteItemData::AppendAllowedFieldsMaskForFlag(UpdateMask<9>& allowedMaskF allowedMaskForTarget |= { 0x000001F0u }; } -void AzeriteItemData::WriteUpdate(ByteBuffer& data, UpdateMask<9> const& changesMask, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, AzeriteItem const* owner, Player const* receiver) const +void AzeriteItemData::FilterDisallowedFieldsMaskForFlag(UpdateMask<9>& changesMask, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags) const +{ + if (!fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + changesMask &= { 0xFFFFFE0Fu }; +} + +void AzeriteItemData::WriteUpdate(ByteBuffer& data, UpdateMask<9> const& changesMask, bool ignoreNestedChangesMask, AzeriteItem const* owner, Player const* receiver) const { data.WriteBits(changesMask.GetBlock(0), 9); @@ -615,15 +657,24 @@ void AzeriteItemData::WriteUpdate(ByteBuffer& data, UpdateMask<9> const& changes { if (changesMask[1]) { - UnlockedEssences.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + UnlockedEssences.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(UnlockedEssences.size(), data); } if (changesMask[2]) { - SelectedEssences.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + SelectedEssences.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(SelectedEssences.size(), data); } if (changesMask[3]) { - UnlockedEssenceMilestones.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + UnlockedEssenceMilestones.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(UnlockedEssenceMilestones.size(), data); } } data.FlushBits(); @@ -633,9 +684,9 @@ void AzeriteItemData::WriteUpdate(ByteBuffer& data, UpdateMask<9> const& changes { for (std::size_t i = 0; i < UnlockedEssences.size(); ++i) { - if (UnlockedEssences.HasChanged(i)) + if (UnlockedEssences.HasChanged(i) || ignoreNestedChangesMask) { - UnlockedEssences[i].WriteUpdate(data, owner, receiver); + UnlockedEssences[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } @@ -643,7 +694,7 @@ void AzeriteItemData::WriteUpdate(ByteBuffer& data, UpdateMask<9> const& changes { for (std::size_t i = 0; i < UnlockedEssenceMilestones.size(); ++i) { - if (UnlockedEssenceMilestones.HasChanged(i)) + if (UnlockedEssenceMilestones.HasChanged(i) || ignoreNestedChangesMask) { data << uint32(UnlockedEssenceMilestones[i]); } @@ -653,9 +704,9 @@ void AzeriteItemData::WriteUpdate(ByteBuffer& data, UpdateMask<9> const& changes { for (std::size_t i = 0; i < SelectedEssences.size(); ++i) { - if (SelectedEssences.HasChanged(i)) + if (SelectedEssences.HasChanged(i) || ignoreNestedChangesMask) { - SelectedEssences[i].WriteUpdate(data, owner, receiver); + SelectedEssences[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } @@ -701,7 +752,7 @@ void UnitChannel::WriteCreate(ByteBuffer& data, Unit const* owner, Player const* data << int32(SpellXSpellVisualID); } -void UnitChannel::WriteUpdate(ByteBuffer& data, Unit const* owner, Player const* receiver) const +void UnitChannel::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Unit const* owner, Player const* receiver) const { data << int32(SpellID); data << int32(SpellXSpellVisualID); @@ -714,9 +765,12 @@ void VisibleItem::WriteCreate(ByteBuffer& data, Unit const* owner, Player const* data << uint16(ItemVisual); } -void VisibleItem::WriteUpdate(ByteBuffer& data, Unit const* owner, Player const* receiver) const +void VisibleItem::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Unit const* owner, Player const* receiver) const { - UpdateMask<4> const& changesMask = _changesMask; + UpdateMask<4> changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + data.WriteBits(changesMask.GetBlock(0), 4); data.FlushBits(); @@ -751,7 +805,7 @@ void PassiveSpellHistory::WriteCreate(ByteBuffer& data, Unit const* owner, Playe data << int32(AuraSpellID); } -void PassiveSpellHistory::WriteUpdate(ByteBuffer& data, Unit const* owner, Player const* receiver) const +void PassiveSpellHistory::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Unit const* owner, Player const* receiver) const { data << int32(SpellID); data << int32(AuraSpellID); @@ -957,7 +1011,7 @@ void UnitData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fiel { UpdateMask<192> allowedMaskForTarget({ 0xFFFFEFFFu, 0xFC3FBFFFu, 0x0001EFFFu, 0xFFBFFFF9u, 0x003F8007u, 0x00000000u }); AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); - WriteUpdate(data, _changesMask & allowedMaskForTarget, fieldVisibilityFlags, owner, receiver); + WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver); } void UnitData::AppendAllowedFieldsMaskForFlag(UpdateMask<192>& allowedMaskForTarget, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags) const @@ -970,7 +1024,17 @@ void UnitData::AppendAllowedFieldsMaskForFlag(UpdateMask<192>& allowedMaskForTar allowedMaskForTarget |= { 0x00000000u, 0x03C00000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x000007F8u }; } -void UnitData::WriteUpdate(ByteBuffer& data, UpdateMask<192> const& changesMask, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Unit const* owner, Player const* receiver) const +void UnitData::FilterDisallowedFieldsMaskForFlag(UpdateMask<192>& changesMask, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags) const +{ + if (!fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Owner)) + changesMask &= { 0xFFFFEFFFu, 0xFC3FBFFFu, 0x0001EFFFu, 0xFFBFFFF9u, 0x003F8007u, 0x00000000u }; + if (!fieldVisibilityFlags.HasFlag(UpdateFieldFlag::UnitAll)) + changesMask &= { 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFBFFFFFu, 0xFFFF8007u, 0xFFFFFFFFu }; + if (!fieldVisibilityFlags.HasFlag(UpdateFieldFlag::Empath)) + changesMask &= { 0xFFFFFFFFu, 0xFC3FFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFF807u }; +} + +void UnitData::WriteUpdate(ByteBuffer& data, UpdateMask<192> const& changesMask, bool ignoreNestedChangesMask, Unit const* owner, Player const* receiver) const { data.WriteBits(changesMask.GetBlocksMask(0), 6); for (std::size_t i = 0; i < 6; ++i) @@ -993,15 +1057,24 @@ void UnitData::WriteUpdate(ByteBuffer& data, UpdateMask<192> const& changesMask, { if (changesMask[2]) { - PassiveSpells.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + PassiveSpells.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(PassiveSpells.size(), data); } if (changesMask[3]) { - WorldEffects.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + WorldEffects.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(WorldEffects.size(), data); } if (changesMask[4]) { - ChannelObjects.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + ChannelObjects.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(ChannelObjects.size(), data); } } data.FlushBits(); @@ -1011,9 +1084,9 @@ void UnitData::WriteUpdate(ByteBuffer& data, UpdateMask<192> const& changesMask, { for (std::size_t i = 0; i < PassiveSpells.size(); ++i) { - if (PassiveSpells.HasChanged(i)) + if (PassiveSpells.HasChanged(i) || ignoreNestedChangesMask) { - PassiveSpells[i].WriteUpdate(data, owner, receiver); + PassiveSpells[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } @@ -1021,7 +1094,7 @@ void UnitData::WriteUpdate(ByteBuffer& data, UpdateMask<192> const& changesMask, { for (std::size_t i = 0; i < WorldEffects.size(); ++i) { - if (WorldEffects.HasChanged(i)) + if (WorldEffects.HasChanged(i) || ignoreNestedChangesMask) { data << int32(WorldEffects[i]); } @@ -1031,7 +1104,7 @@ void UnitData::WriteUpdate(ByteBuffer& data, UpdateMask<192> const& changesMask, { for (std::size_t i = 0; i < ChannelObjects.size(); ++i) { - if (ChannelObjects.HasChanged(i)) + if (ChannelObjects.HasChanged(i) || ignoreNestedChangesMask) { data << ChannelObjects[i]; } @@ -1103,7 +1176,7 @@ void UnitData::WriteUpdate(ByteBuffer& data, UpdateMask<192> const& changesMask, } if (changesMask[21]) { - ChannelData->WriteUpdate(data, owner, receiver); + ChannelData->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } if (changesMask[22]) { @@ -1513,7 +1586,7 @@ void UnitData::WriteUpdate(ByteBuffer& data, UpdateMask<192> const& changesMask, { if (changesMask[144 + i]) { - VirtualItems[i].WriteUpdate(data, owner, receiver); + VirtualItems[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } @@ -1712,9 +1785,12 @@ void QuestLog::WriteCreate(ByteBuffer& data, Player const* owner, Player const* } } -void QuestLog::WriteUpdate(ByteBuffer& data, Player const* owner, Player const* receiver) const +void QuestLog::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const { - UpdateMask<31> const& changesMask = _changesMask; + UpdateMask<31> changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + data.WriteBits(changesMask.GetBlocksMask(0), 1); if (changesMask.GetBlock(0)) data.WriteBits(changesMask.GetBlock(0), 32); @@ -1777,9 +1853,12 @@ void ArenaCooldown::WriteCreate(ByteBuffer& data, Player const* owner, Player co data << uint8(MaxCharges); } -void ArenaCooldown::WriteUpdate(ByteBuffer& data, Player const* owner, Player const* receiver) const +void ArenaCooldown::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const { - UpdateMask<8> const& changesMask = _changesMask; + UpdateMask<8> changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + data.WriteBits(changesMask.GetBlock(0), 8); data.FlushBits(); @@ -1905,7 +1984,7 @@ void PlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fi { UpdateMask<192> allowedMaskForTarget({ 0xFFFFFFF5u, 0x000001FFu, 0x00000000u, 0x00000000u, 0x00000000u, 0xFFFFFF80u }); AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); - WriteUpdate(data, _changesMask & allowedMaskForTarget, fieldVisibilityFlags, owner, receiver); + WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver); } void PlayerData::AppendAllowedFieldsMaskForFlag(UpdateMask<192>& allowedMaskForTarget, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags) const @@ -1914,7 +1993,13 @@ void PlayerData::AppendAllowedFieldsMaskForFlag(UpdateMask<192>& allowedMaskForT allowedMaskForTarget |= { 0x0000000Au, 0xFFFFFE00u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x0000007Fu }; } -void PlayerData::WriteUpdate(ByteBuffer& data, UpdateMask<192> const& changesMask, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const +void PlayerData::FilterDisallowedFieldsMaskForFlag(UpdateMask<192>& changesMask, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags) const +{ + if (!fieldVisibilityFlags.HasFlag(UpdateFieldFlag::PartyMember)) + changesMask &= { 0xFFFFFFF5u, 0x000001FFu, 0x00000000u, 0x00000000u, 0x00000000u, 0xFFFFFF80u }; +} + +void PlayerData::WriteUpdate(ByteBuffer& data, UpdateMask<192> const& changesMask, bool ignoreNestedChangesMask, Player const* owner, Player const* receiver) const { data.WriteBits(changesMask.GetBlocksMask(0), 6); for (std::size_t i = 0; i < 6; ++i) @@ -1934,11 +2019,17 @@ void PlayerData::WriteUpdate(ByteBuffer& data, UpdateMask<192> const& changesMas } if (changesMask[3]) { - QuestSessionQuestLog.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + QuestSessionQuestLog.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(QuestSessionQuestLog.size(), data); } if (changesMask[4]) { - ArenaCooldowns.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + ArenaCooldowns.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(ArenaCooldowns.size(), data); } } data.FlushBits(); @@ -1948,12 +2039,12 @@ void PlayerData::WriteUpdate(ByteBuffer& data, UpdateMask<192> const& changesMas { for (std::size_t i = 0; i < QuestSessionQuestLog.size(); ++i) { - if (QuestSessionQuestLog.HasChanged(i)) + if (QuestSessionQuestLog.HasChanged(i) || ignoreNestedChangesMask) { if (noQuestLogChangesMask) QuestSessionQuestLog[i].WriteCreate(data, owner, receiver); else - QuestSessionQuestLog[i].WriteUpdate(data, owner, receiver); + QuestSessionQuestLog[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } @@ -1961,9 +2052,9 @@ void PlayerData::WriteUpdate(ByteBuffer& data, UpdateMask<192> const& changesMas { for (std::size_t i = 0; i < ArenaCooldowns.size(); ++i) { - if (ArenaCooldowns.HasChanged(i)) + if (ArenaCooldowns.HasChanged(i) || ignoreNestedChangesMask) { - ArenaCooldowns[i].WriteUpdate(data, owner, receiver); + ArenaCooldowns[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } @@ -2114,7 +2205,7 @@ void PlayerData::WriteUpdate(ByteBuffer& data, UpdateMask<192> const& changesMas if (noQuestLogChangesMask) QuestLog[i].WriteCreate(data, owner, receiver); else - QuestLog[i].WriteUpdate(data, owner, receiver); + QuestLog[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } @@ -2124,7 +2215,7 @@ void PlayerData::WriteUpdate(ByteBuffer& data, UpdateMask<192> const& changesMas { if (changesMask[168 + i]) { - VisibleItems[i].WriteUpdate(data, owner, receiver); + VisibleItems[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } @@ -2199,9 +2290,12 @@ void SkillInfo::WriteCreate(ByteBuffer& data, Player const* owner, Player const* } } -void SkillInfo::WriteUpdate(ByteBuffer& data, Player const* owner, Player const* receiver) const +void SkillInfo::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const { - UpdateMask<1793> const& changesMask = _changesMask; + UpdateMask<1793> changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + for (std::size_t i = 0; i < 1; ++i) data << uint32(changesMask.GetBlocksMask(i)); data.WriteBits(changesMask.GetBlocksMask(1), 25); @@ -2264,9 +2358,12 @@ void RestInfo::WriteCreate(ByteBuffer& data, Player const* owner, Player const* data << uint8(StateID); } -void RestInfo::WriteUpdate(ByteBuffer& data, Player const* owner, Player const* receiver) const +void RestInfo::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const { - UpdateMask<3> const& changesMask = _changesMask; + UpdateMask<3> changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + data.WriteBits(changesMask.GetBlock(0), 3); data.FlushBits(); @@ -2304,9 +2401,12 @@ void PVPInfo::WriteCreate(ByteBuffer& data, Player const* owner, Player const* r data.FlushBits(); } -void PVPInfo::WriteUpdate(ByteBuffer& data, Player const* owner, Player const* receiver) const +void PVPInfo::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const { - UpdateMask<10> const& changesMask = _changesMask; + UpdateMask<10> changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + data.WriteBits(changesMask.GetBlock(0), 10); data.FlushBits(); @@ -2375,7 +2475,7 @@ void CharacterRestriction::WriteCreate(ByteBuffer& data, Player const* owner, Pl data.FlushBits(); } -void CharacterRestriction::WriteUpdate(ByteBuffer& data, Player const* owner, Player const* receiver) const +void CharacterRestriction::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const { data << int32(Field_0); data << int32(Field_4); @@ -2391,7 +2491,7 @@ void SpellPctModByLabel::WriteCreate(ByteBuffer& data, Player const* owner, Play data << int32(LabelID); } -void SpellPctModByLabel::WriteUpdate(ByteBuffer& data, Player const* owner, Player const* receiver) const +void SpellPctModByLabel::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const { data << int32(ModIndex); data << float(ModifierValue); @@ -2405,7 +2505,7 @@ void SpellFlatModByLabel::WriteCreate(ByteBuffer& data, Player const* owner, Pla data << int32(LabelID); } -void SpellFlatModByLabel::WriteUpdate(ByteBuffer& data, Player const* owner, Player const* receiver) const +void SpellFlatModByLabel::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const { data << int32(ModIndex); data << int32(ModifierValue); @@ -2417,7 +2517,7 @@ void Research::WriteCreate(ByteBuffer& data, Player const* owner, Player const* data << int16(ResearchProjectID); } -void Research::WriteUpdate(ByteBuffer& data, Player const* owner, Player const* receiver) const +void Research::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const { data << int16(ResearchProjectID); } @@ -2428,9 +2528,12 @@ void ReplayedQuest::WriteCreate(ByteBuffer& data, Player const* owner, Player co data << uint32(ReplayTime); } -void ReplayedQuest::WriteUpdate(ByteBuffer& data, Player const* owner, Player const* receiver) const +void ReplayedQuest::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const { - UpdateMask<3> const& changesMask = _changesMask; + UpdateMask<3> changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + data.WriteBits(changesMask.GetBlock(0), 3); data.FlushBits(); @@ -2463,9 +2566,12 @@ void QuestSession::WriteCreate(ByteBuffer& data, Player const* owner, Player con } } -void QuestSession::WriteUpdate(ByteBuffer& data, Player const* owner, Player const* receiver) const +void QuestSession::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const { - UpdateMask<878> const& changesMask = _changesMask; + UpdateMask<878> changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + data.WriteBits(changesMask.GetBlocksMask(0), 28); for (std::size_t i = 0; i < 28; ++i) if (changesMask.GetBlock(i)) @@ -2743,7 +2849,11 @@ void ActivePlayerData::WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const { - UpdateMask<1494> const& changesMask = _changesMask; + WriteUpdate(data, _changesMask, false, owner, receiver); +} + +void ActivePlayerData::WriteUpdate(ByteBuffer& data, UpdateMask<1494> const& changesMask, bool ignoreNestedChangesMask, Player const* owner, Player const* receiver) const +{ for (std::size_t i = 0; i < 1; ++i) data << uint32(changesMask.GetBlocksMask(i)); data.WriteBits(changesMask.GetBlocksMask(1), 15); @@ -2771,63 +2881,108 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl } if (changesMask[5]) { - KnownTitles.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + KnownTitles.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(KnownTitles.size(), data); } if (changesMask[6]) { - ResearchSites.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + ResearchSites.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(ResearchSites.size(), data); } if (changesMask[7]) { - ResearchSiteProgress.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + ResearchSiteProgress.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(ResearchSiteProgress.size(), data); } if (changesMask[8]) { - DailyQuestsCompleted.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + DailyQuestsCompleted.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(DailyQuestsCompleted.size(), data); } if (changesMask[9]) { - AvailableQuestLineXQuestIDs.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + AvailableQuestLineXQuestIDs.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(AvailableQuestLineXQuestIDs.size(), data); } if (changesMask[10]) { - Heirlooms.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + Heirlooms.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Heirlooms.size(), data); } if (changesMask[11]) { - HeirloomFlags.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + HeirloomFlags.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(HeirloomFlags.size(), data); } if (changesMask[12]) { - Toys.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + Toys.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Toys.size(), data); } if (changesMask[13]) { - ToyFlags.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + ToyFlags.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(ToyFlags.size(), data); } if (changesMask[14]) { - Transmog.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + Transmog.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Transmog.size(), data); } if (changesMask[15]) { - ConditionalTransmog.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + ConditionalTransmog.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(ConditionalTransmog.size(), data); } if (changesMask[16]) { - SelfResSpells.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + SelfResSpells.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(SelfResSpells.size(), data); } if (changesMask[17]) { - CharacterRestrictions.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + CharacterRestrictions.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(CharacterRestrictions.size(), data); } if (changesMask[18]) { - SpellPctModByLabel.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + SpellPctModByLabel.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(SpellPctModByLabel.size(), data); } if (changesMask[19]) { - SpellFlatModByLabel.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + SpellFlatModByLabel.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(SpellFlatModByLabel.size(), data); } } if (changesMask[22]) @@ -2836,7 +2991,10 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { if (changesMask[23 + i]) { - Research[i].WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + Research[i].WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Research[i].size(), data); } } } @@ -2848,9 +3006,9 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { for (std::size_t j = 0; j < Research[i].size(); ++j) { - if (Research[i].HasChanged(j)) + if (Research[i].HasChanged(j) || ignoreNestedChangesMask) { - Research[i][j].WriteUpdate(data, owner, receiver); + Research[i][j].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } @@ -2861,11 +3019,17 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { if (changesMask[20]) { - ReplayedQuests.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + ReplayedQuests.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(ReplayedQuests.size(), data); } if (changesMask[21]) { - DisabledSpells.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + DisabledSpells.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(DisabledSpells.size(), data); } } data.FlushBits(); @@ -2875,7 +3039,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { for (std::size_t i = 0; i < KnownTitles.size(); ++i) { - if (KnownTitles.HasChanged(i)) + if (KnownTitles.HasChanged(i) || ignoreNestedChangesMask) { data << uint64(KnownTitles[i]); } @@ -2885,7 +3049,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { for (std::size_t i = 0; i < ResearchSites.size(); ++i) { - if (ResearchSites.HasChanged(i)) + if (ResearchSites.HasChanged(i) || ignoreNestedChangesMask) { data << uint16(ResearchSites[i]); } @@ -2895,7 +3059,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { for (std::size_t i = 0; i < ResearchSiteProgress.size(); ++i) { - if (ResearchSiteProgress.HasChanged(i)) + if (ResearchSiteProgress.HasChanged(i) || ignoreNestedChangesMask) { data << uint32(ResearchSiteProgress[i]); } @@ -2905,7 +3069,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { for (std::size_t i = 0; i < DailyQuestsCompleted.size(); ++i) { - if (DailyQuestsCompleted.HasChanged(i)) + if (DailyQuestsCompleted.HasChanged(i) || ignoreNestedChangesMask) { data << int32(DailyQuestsCompleted[i]); } @@ -2915,7 +3079,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { for (std::size_t i = 0; i < AvailableQuestLineXQuestIDs.size(); ++i) { - if (AvailableQuestLineXQuestIDs.HasChanged(i)) + if (AvailableQuestLineXQuestIDs.HasChanged(i) || ignoreNestedChangesMask) { data << int32(AvailableQuestLineXQuestIDs[i]); } @@ -2925,7 +3089,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { for (std::size_t i = 0; i < Heirlooms.size(); ++i) { - if (Heirlooms.HasChanged(i)) + if (Heirlooms.HasChanged(i) || ignoreNestedChangesMask) { data << int32(Heirlooms[i]); } @@ -2935,7 +3099,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { for (std::size_t i = 0; i < HeirloomFlags.size(); ++i) { - if (HeirloomFlags.HasChanged(i)) + if (HeirloomFlags.HasChanged(i) || ignoreNestedChangesMask) { data << uint32(HeirloomFlags[i]); } @@ -2945,7 +3109,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { for (std::size_t i = 0; i < Toys.size(); ++i) { - if (Toys.HasChanged(i)) + if (Toys.HasChanged(i) || ignoreNestedChangesMask) { data << int32(Toys[i]); } @@ -2955,7 +3119,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { for (std::size_t i = 0; i < ToyFlags.size(); ++i) { - if (ToyFlags.HasChanged(i)) + if (ToyFlags.HasChanged(i) || ignoreNestedChangesMask) { data << uint32(ToyFlags[i]); } @@ -2965,7 +3129,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { for (std::size_t i = 0; i < Transmog.size(); ++i) { - if (Transmog.HasChanged(i)) + if (Transmog.HasChanged(i) || ignoreNestedChangesMask) { data << uint32(Transmog[i]); } @@ -2975,7 +3139,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { for (std::size_t i = 0; i < ConditionalTransmog.size(); ++i) { - if (ConditionalTransmog.HasChanged(i)) + if (ConditionalTransmog.HasChanged(i) || ignoreNestedChangesMask) { data << int32(ConditionalTransmog[i]); } @@ -2985,7 +3149,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { for (std::size_t i = 0; i < SelfResSpells.size(); ++i) { - if (SelfResSpells.HasChanged(i)) + if (SelfResSpells.HasChanged(i) || ignoreNestedChangesMask) { data << int32(SelfResSpells[i]); } @@ -2995,9 +3159,9 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { for (std::size_t i = 0; i < SpellPctModByLabel.size(); ++i) { - if (SpellPctModByLabel.HasChanged(i)) + if (SpellPctModByLabel.HasChanged(i) || ignoreNestedChangesMask) { - SpellPctModByLabel[i].WriteUpdate(data, owner, receiver); + SpellPctModByLabel[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } @@ -3005,9 +3169,9 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { for (std::size_t i = 0; i < SpellFlatModByLabel.size(); ++i) { - if (SpellFlatModByLabel.HasChanged(i)) + if (SpellFlatModByLabel.HasChanged(i) || ignoreNestedChangesMask) { - SpellFlatModByLabel[i].WriteUpdate(data, owner, receiver); + SpellFlatModByLabel[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } @@ -3015,9 +3179,9 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { for (std::size_t i = 0; i < ReplayedQuests.size(); ++i) { - if (ReplayedQuests.HasChanged(i)) + if (ReplayedQuests.HasChanged(i) || ignoreNestedChangesMask) { - ReplayedQuests[i].WriteUpdate(data, owner, receiver); + ReplayedQuests[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } @@ -3025,7 +3189,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { for (std::size_t i = 0; i < DisabledSpells.size(); ++i) { - if (DisabledSpells.HasChanged(i)) + if (DisabledSpells.HasChanged(i) || ignoreNestedChangesMask) { data << int32(DisabledSpells[i]); } @@ -3035,9 +3199,9 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { for (std::size_t i = 0; i < CharacterRestrictions.size(); ++i) { - if (CharacterRestrictions.HasChanged(i)) + if (CharacterRestrictions.HasChanged(i) || ignoreNestedChangesMask) { - CharacterRestrictions[i].WriteUpdate(data, owner, receiver); + CharacterRestrictions[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } @@ -3067,7 +3231,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl } if (changesMask[30]) { - Skill->WriteUpdate(data, owner, receiver); + Skill->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } if (changesMask[31]) { @@ -3363,7 +3527,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { if (QuestSession.is_initialized()) { - QuestSession->WriteUpdate(data, owner, receiver); + QuestSession->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } @@ -3403,7 +3567,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { if (changesMask[501 + i]) { - RestInfo[i].WriteUpdate(data, owner, receiver); + RestInfo[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } @@ -3519,7 +3683,7 @@ void ActivePlayerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { if (changesMask[591 + i]) { - PvpInfo[i].WriteUpdate(data, owner, receiver); + PvpInfo[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } @@ -3684,7 +3848,11 @@ void GameObjectData::WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag void GameObjectData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, GameObject const* owner, Player const* receiver) const { - UpdateMask<20> const& changesMask = _changesMask; + WriteUpdate(data, _changesMask, false, owner, receiver); +} + +void GameObjectData::WriteUpdate(ByteBuffer& data, UpdateMask<20> const& changesMask, bool ignoreNestedChangesMask, GameObject const* owner, Player const* receiver) const +{ data.WriteBits(changesMask.GetBlock(0), 20); if (changesMask[0]) @@ -3703,7 +3871,10 @@ void GameObjectData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag { if (changesMask[2]) { - EnableDoodadSets.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + EnableDoodadSets.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(EnableDoodadSets.size(), data); } } data.FlushBits(); @@ -3713,7 +3884,7 @@ void GameObjectData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag { for (std::size_t i = 0; i < EnableDoodadSets.size(); ++i) { - if (EnableDoodadSets.HasChanged(i)) + if (EnableDoodadSets.HasChanged(i) || ignoreNestedChangesMask) { data << int32(EnableDoodadSets[i]); } @@ -3829,7 +4000,11 @@ void DynamicObjectData::WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldF void DynamicObjectData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, DynamicObject const* owner, Player const* receiver) const { - UpdateMask<7> const& changesMask = _changesMask; + WriteUpdate(data, _changesMask, false, owner, receiver); +} + +void DynamicObjectData::WriteUpdate(ByteBuffer& data, UpdateMask<7> const& changesMask, bool ignoreNestedChangesMask, DynamicObject const* owner, Player const* receiver) const +{ data.WriteBits(changesMask.GetBlock(0), 7); data.FlushBits(); @@ -3902,7 +4077,11 @@ void CorpseData::WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fi void CorpseData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Corpse const* owner, Player const* receiver) const { - UpdateMask<40> const& changesMask = _changesMask; + WriteUpdate(data, _changesMask, false, owner, receiver); +} + +void CorpseData::WriteUpdate(ByteBuffer& data, UpdateMask<40> const& changesMask, bool ignoreNestedChangesMask, Corpse const* owner, Player const* receiver) const +{ data.WriteBits(changesMask.GetBlocksMask(0), 2); for (std::size_t i = 0; i < 2; ++i) if (changesMask.GetBlock(i)) @@ -4028,9 +4207,12 @@ void ScaleCurve::WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player data.FlushBits(); } -void ScaleCurve::WriteUpdate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const +void ScaleCurve::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const { - UpdateMask<7> const& changesMask = _changesMask; + UpdateMask<7> changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + data.WriteBits(changesMask.GetBlock(0), 7); if (changesMask[0]) @@ -4093,7 +4275,11 @@ void AreaTriggerData::WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldFla void AreaTriggerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, AreaTrigger const* owner, Player const* receiver) const { - UpdateMask<14> const& changesMask = _changesMask; + WriteUpdate(data, _changesMask, false, owner, receiver); +} + +void AreaTriggerData::WriteUpdate(ByteBuffer& data, UpdateMask<14> const& changesMask, bool ignoreNestedChangesMask, AreaTrigger const* owner, Player const* receiver) const +{ data.WriteBits(changesMask.GetBlock(0), 14); data.FlushBits(); @@ -4101,7 +4287,7 @@ void AreaTriggerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFla { if (changesMask[1]) { - OverrideScaleCurve->WriteUpdate(data, owner, receiver); + OverrideScaleCurve->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } if (changesMask[3]) { @@ -4149,7 +4335,7 @@ void AreaTriggerData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFla } if (changesMask[2]) { - ExtraScaleCurve->WriteUpdate(data, owner, receiver); + ExtraScaleCurve->WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } @@ -4182,7 +4368,11 @@ void SceneObjectData::WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldFla void SceneObjectData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const { - UpdateMask<5> const& changesMask = _changesMask; + WriteUpdate(data, _changesMask, false, owner, receiver); +} + +void SceneObjectData::WriteUpdate(ByteBuffer& data, UpdateMask<5> const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) const +{ data.WriteBits(changesMask.GetBlock(0), 5); data.FlushBits(); @@ -4225,7 +4415,7 @@ void ConversationLine::WriteCreate(ByteBuffer& data, Conversation const* owner, data << uint8(Flags); } -void ConversationLine::WriteUpdate(ByteBuffer& data, Conversation const* owner, Player const* receiver) const +void ConversationLine::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Conversation const* owner, Player const* receiver) const { data << int32(ConversationLineID); data << uint32(StartTime); @@ -4244,7 +4434,7 @@ void ConversationActor::WriteCreate(ByteBuffer& data, Conversation const* owner, data.FlushBits(); } -void ConversationActor::WriteUpdate(ByteBuffer& data, Conversation const* owner, Player const* receiver) const +void ConversationActor::WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Conversation const* owner, Player const* receiver) const { data << uint32(CreatureID); data << uint32(CreatureDisplayInfoID); @@ -4272,7 +4462,11 @@ void ConversationData::WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl void ConversationData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Conversation const* owner, Player const* receiver) const { - UpdateMask<5> const& changesMask = _changesMask; + WriteUpdate(data, _changesMask, false, owner, receiver); +} + +void ConversationData::WriteUpdate(ByteBuffer& data, UpdateMask<5> const& changesMask, bool ignoreNestedChangesMask, Conversation const* owner, Player const* receiver) const +{ data.WriteBits(changesMask.GetBlock(0), 5); if (changesMask[0]) @@ -4282,7 +4476,7 @@ void ConversationData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl data.WriteBits(Lines->size(), 32); for (std::size_t i = 0; i < Lines->size(); ++i) { - (*Lines)[i].WriteUpdate(data, owner, receiver); + (*Lines)[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } @@ -4291,7 +4485,10 @@ void ConversationData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { if (changesMask[2]) { - Actors.WriteUpdateMask(data); + if (!ignoreNestedChangesMask) + Actors.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Actors.size(), data); } } data.FlushBits(); @@ -4301,9 +4498,9 @@ void ConversationData::WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFl { for (std::size_t i = 0; i < Actors.size(); ++i) { - if (Actors.HasChanged(i)) + if (Actors.HasChanged(i) || ignoreNestedChangesMask) { - Actors[i].WriteUpdate(data, owner, receiver); + Actors[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.h b/src/server/game/Entities/Object/Updates/UpdateFields.h index 0335b90b4ac..31a36490913 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFields.h +++ b/src/server/game/Entities/Object/Updates/UpdateFields.h @@ -50,6 +50,7 @@ struct ObjectData : public IsUpdateFieldStructureTag, public HasChangesMask<4> void WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, UpdateMask<4> const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) const; void ClearChangesMask(); }; @@ -61,7 +62,7 @@ struct ItemEnchantment : public IsUpdateFieldStructureTag, public HasChangesMask UpdateField<uint16, 0, 4> Inactive; void WriteCreate(ByteBuffer& data, Item const* owner, Player const* receiver) const; - void WriteUpdate(ByteBuffer& data, Item const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Item const* owner, Player const* receiver) const; void ClearChangesMask(); }; @@ -72,7 +73,7 @@ struct ArtifactPower : public IsUpdateFieldStructureTag uint8 CurrentRankWithBonus; void WriteCreate(ByteBuffer& data, Item const* owner, Player const* receiver) const; - void WriteUpdate(ByteBuffer& data, Item const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Item const* owner, Player const* receiver) const; }; struct SocketedGem : public IsUpdateFieldStructureTag, public HasChangesMask<20> @@ -82,7 +83,7 @@ struct SocketedGem : public IsUpdateFieldStructureTag, public HasChangesMask<20> UpdateFieldArray<uint16, 16, 3, 4> BonusListIDs; void WriteCreate(ByteBuffer& data, Item const* owner, Player const* receiver) const; - void WriteUpdate(ByteBuffer& data, Item const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Item const* owner, Player const* receiver) const; void ClearChangesMask(); }; @@ -112,8 +113,9 @@ struct ItemData : public IsUpdateFieldStructureTag, public HasChangesMask<40> void WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Item const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Item const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, UpdateMask<40> const& changesMask, bool ignoreNestedChangesMask, Item const* owner, Player const* receiver) const; void AppendAllowedFieldsMaskForFlag(UpdateMask<40>& allowedMaskForTarget, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags) const; - void WriteUpdate(ByteBuffer& data, UpdateMask<40> const& changesMask, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Item const* owner, Player const* receiver) const; + void FilterDisallowedFieldsMaskForFlag(UpdateMask<40>& changesMask, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags) const; void ClearChangesMask(); }; @@ -124,6 +126,7 @@ struct ContainerData : public IsUpdateFieldStructureTag, public HasChangesMask<3 void WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Bag const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Bag const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, UpdateMask<39> const& changesMask, bool ignoreNestedChangesMask, Bag const* owner, Player const* receiver) const; void ClearChangesMask(); }; @@ -133,6 +136,7 @@ struct AzeriteEmpoweredItemData : public IsUpdateFieldStructureTag, public HasCh void WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, AzeriteEmpoweredItem const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, AzeriteEmpoweredItem const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, UpdateMask<6> const& changesMask, bool ignoreNestedChangesMask, AzeriteEmpoweredItem const* owner, Player const* receiver) const; void ClearChangesMask(); }; @@ -142,7 +146,7 @@ struct UnlockedAzeriteEssence : public IsUpdateFieldStructureTag uint32 Rank; void WriteCreate(ByteBuffer& data, AzeriteItem const* owner, Player const* receiver) const; - void WriteUpdate(ByteBuffer& data, AzeriteItem const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AzeriteItem const* owner, Player const* receiver) const; }; struct SelectedAzeriteEssences : public IsUpdateFieldStructureTag, public HasChangesMask<8> @@ -152,7 +156,7 @@ struct SelectedAzeriteEssences : public IsUpdateFieldStructureTag, public HasCha UpdateFieldArray<uint32, 4, 3, 4> AzeriteEssenceID; void WriteCreate(ByteBuffer& data, AzeriteItem const* owner, Player const* receiver) const; - void WriteUpdate(ByteBuffer& data, AzeriteItem const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AzeriteItem const* owner, Player const* receiver) const; void ClearChangesMask(); }; @@ -169,8 +173,9 @@ struct AzeriteItemData : public IsUpdateFieldStructureTag, public HasChangesMask void WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, AzeriteItem const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, AzeriteItem const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, UpdateMask<9> const& changesMask, bool ignoreNestedChangesMask, AzeriteItem const* owner, Player const* receiver) const; void AppendAllowedFieldsMaskForFlag(UpdateMask<9>& allowedMaskForTarget, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags) const; - void WriteUpdate(ByteBuffer& data, UpdateMask<9> const& changesMask, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, AzeriteItem const* owner, Player const* receiver) const; + void FilterDisallowedFieldsMaskForFlag(UpdateMask<9>& changesMask, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags) const; void ClearChangesMask(); }; @@ -180,7 +185,7 @@ struct UnitChannel : public IsUpdateFieldStructureTag int32 SpellXSpellVisualID; void WriteCreate(ByteBuffer& data, Unit const* owner, Player const* receiver) const; - void WriteUpdate(ByteBuffer& data, Unit const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Unit const* owner, Player const* receiver) const; }; struct VisibleItem : public IsUpdateFieldStructureTag, public HasChangesMask<4> @@ -190,7 +195,7 @@ struct VisibleItem : public IsUpdateFieldStructureTag, public HasChangesMask<4> UpdateField<uint16, 0, 3> ItemVisual; void WriteCreate(ByteBuffer& data, Unit const* owner, Player const* receiver) const; - void WriteUpdate(ByteBuffer& data, Unit const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Unit const* owner, Player const* receiver) const; void ClearChangesMask(); }; @@ -200,7 +205,7 @@ struct PassiveSpellHistory : public IsUpdateFieldStructureTag int32 AuraSpellID; void WriteCreate(ByteBuffer& data, Unit const* owner, Player const* receiver) const; - void WriteUpdate(ByteBuffer& data, Unit const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Unit const* owner, Player const* receiver) const; }; struct UnitData : public IsUpdateFieldStructureTag, public HasChangesMask<192> @@ -339,8 +344,9 @@ struct UnitData : public IsUpdateFieldStructureTag, public HasChangesMask<192> void WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Unit const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Unit const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, UpdateMask<192> const& changesMask, bool ignoreNestedChangesMask, Unit const* owner, Player const* receiver) const; void AppendAllowedFieldsMaskForFlag(UpdateMask<192>& allowedMaskForTarget, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags) const; - void WriteUpdate(ByteBuffer& data, UpdateMask<192> const& changesMask, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Unit const* owner, Player const* receiver) const; + void FilterDisallowedFieldsMaskForFlag(UpdateMask<192>& changesMask, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags) const; void ClearChangesMask(); }; @@ -354,7 +360,7 @@ struct QuestLog : public IsUpdateFieldStructureTag, public HasChangesMask<31> UpdateFieldArray<int16, 24, 6, 7> ObjectiveProgress; void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const; - void WriteUpdate(ByteBuffer& data, Player const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const; void ClearChangesMask(); }; @@ -369,7 +375,7 @@ struct ArenaCooldown : public IsUpdateFieldStructureTag, public HasChangesMask<8 UpdateField<uint8, 0, 7> MaxCharges; void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const; - void WriteUpdate(ByteBuffer& data, Player const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const; void ClearChangesMask(); }; @@ -417,8 +423,9 @@ struct PlayerData : public IsUpdateFieldStructureTag, public HasChangesMask<192> void WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, UpdateMask<192> const& changesMask, bool ignoreNestedChangesMask, Player const* owner, Player const* receiver) const; void AppendAllowedFieldsMaskForFlag(UpdateMask<192>& allowedMaskForTarget, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags) const; - void WriteUpdate(ByteBuffer& data, UpdateMask<192> const& changesMask, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const; + void FilterDisallowedFieldsMaskForFlag(UpdateMask<192>& changesMask, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags) const; void ClearChangesMask(); bool IsQuestLogChangesMaskSkipped() const { return false; } // bandwidth savings aren't worth the cpu time }; @@ -434,7 +441,7 @@ struct SkillInfo : public IsUpdateFieldStructureTag, public HasChangesMask<1793> UpdateFieldArray<uint16, 256, 0, 1537> SkillPermBonus; void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const; - void WriteUpdate(ByteBuffer& data, Player const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const; void ClearChangesMask(); }; @@ -444,7 +451,7 @@ struct RestInfo : public IsUpdateFieldStructureTag, public HasChangesMask<3> UpdateField<uint8, 0, 2> StateID; void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const; - void WriteUpdate(ByteBuffer& data, Player const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const; void ClearChangesMask(); }; @@ -461,7 +468,7 @@ struct PVPInfo : public IsUpdateFieldStructureTag, public HasChangesMask<10> UpdateField<uint32, 0, 9> Field_20; void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const; - void WriteUpdate(ByteBuffer& data, Player const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const; void ClearChangesMask(); }; @@ -473,7 +480,7 @@ struct CharacterRestriction : public IsUpdateFieldStructureTag uint32 Type; void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const; - void WriteUpdate(ByteBuffer& data, Player const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const; }; struct SpellPctModByLabel : public IsUpdateFieldStructureTag @@ -483,7 +490,7 @@ struct SpellPctModByLabel : public IsUpdateFieldStructureTag int32 LabelID; void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const; - void WriteUpdate(ByteBuffer& data, Player const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const; }; struct SpellFlatModByLabel : public IsUpdateFieldStructureTag @@ -493,7 +500,7 @@ struct SpellFlatModByLabel : public IsUpdateFieldStructureTag int32 LabelID; void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const; - void WriteUpdate(ByteBuffer& data, Player const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const; }; struct Research : public IsUpdateFieldStructureTag @@ -501,7 +508,7 @@ struct Research : public IsUpdateFieldStructureTag int16 ResearchProjectID; void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const; - void WriteUpdate(ByteBuffer& data, Player const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const; }; struct ReplayedQuest : public IsUpdateFieldStructureTag, public HasChangesMask<3> @@ -510,7 +517,7 @@ struct ReplayedQuest : public IsUpdateFieldStructureTag, public HasChangesMask<3 UpdateField<uint32, 0, 2> ReplayTime; void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const; - void WriteUpdate(ByteBuffer& data, Player const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const; void ClearChangesMask(); }; @@ -520,7 +527,7 @@ struct QuestSession : public IsUpdateFieldStructureTag, public HasChangesMask<87 UpdateFieldArray<uint64, 875, 2, 3> QuestCompleted; void WriteCreate(ByteBuffer& data, Player const* owner, Player const* receiver) const; - void WriteUpdate(ByteBuffer& data, Player const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Player const* owner, Player const* receiver) const; void ClearChangesMask(); }; @@ -646,6 +653,7 @@ struct ActivePlayerData : public IsUpdateFieldStructureTag, public HasChangesMas void WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Player const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, UpdateMask<1494> const& changesMask, bool ignoreNestedChangesMask, Player const* owner, Player const* receiver) const; void ClearChangesMask(); }; @@ -676,6 +684,7 @@ struct GameObjectData : public IsUpdateFieldStructureTag, public HasChangesMask< void WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, GameObject const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, GameObject const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, UpdateMask<20> const& changesMask, bool ignoreNestedChangesMask, GameObject const* owner, Player const* receiver) const; void ClearChangesMask(); }; @@ -690,6 +699,7 @@ struct DynamicObjectData : public IsUpdateFieldStructureTag, public HasChangesMa void WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, DynamicObject const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, DynamicObject const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, UpdateMask<7> const& changesMask, bool ignoreNestedChangesMask, DynamicObject const* owner, Player const* receiver) const; void ClearChangesMask(); }; @@ -715,6 +725,7 @@ struct CorpseData : public IsUpdateFieldStructureTag, public HasChangesMask<40> void WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Corpse const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Corpse const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, UpdateMask<40> const& changesMask, bool ignoreNestedChangesMask, Corpse const* owner, Player const* receiver) const; void ClearChangesMask(); }; @@ -726,7 +737,7 @@ struct ScaleCurve : public IsUpdateFieldStructureTag, public HasChangesMask<7> UpdateFieldArray<TaggedPosition<Position::XY>, 2, 4, 5> Points; void WriteCreate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const; - void WriteUpdate(ByteBuffer& data, AreaTrigger const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, AreaTrigger const* owner, Player const* receiver) const; void ClearChangesMask(); }; @@ -748,6 +759,7 @@ struct AreaTriggerData : public IsUpdateFieldStructureTag, public HasChangesMask void WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, AreaTrigger const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, AreaTrigger const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, UpdateMask<14> const& changesMask, bool ignoreNestedChangesMask, AreaTrigger const* owner, Player const* receiver) const; void ClearChangesMask(); }; @@ -760,6 +772,7 @@ struct SceneObjectData : public IsUpdateFieldStructureTag, public HasChangesMask void WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Object const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, UpdateMask<5> const& changesMask, bool ignoreNestedChangesMask, Object const* owner, Player const* receiver) const; void ClearChangesMask(); }; @@ -772,7 +785,7 @@ struct ConversationLine : public IsUpdateFieldStructureTag uint8 Flags; void WriteCreate(ByteBuffer& data, Conversation const* owner, Player const* receiver) const; - void WriteUpdate(ByteBuffer& data, Conversation const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Conversation const* owner, Player const* receiver) const; }; struct ConversationActor : public IsUpdateFieldStructureTag @@ -784,7 +797,7 @@ struct ConversationActor : public IsUpdateFieldStructureTag uint32 Type; void WriteCreate(ByteBuffer& data, Conversation const* owner, Player const* receiver) const; - void WriteUpdate(ByteBuffer& data, Conversation const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, bool ignoreChangesMask, Conversation const* owner, Player const* receiver) const; }; struct ConversationData : public IsUpdateFieldStructureTag, public HasChangesMask<5> @@ -796,6 +809,7 @@ struct ConversationData : public IsUpdateFieldStructureTag, public HasChangesMas void WriteCreate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Conversation const* owner, Player const* receiver) const; void WriteUpdate(ByteBuffer& data, EnumClassFlag<UpdateFieldFlag> fieldVisibilityFlags, Conversation const* owner, Player const* receiver) const; + void WriteUpdate(ByteBuffer& data, UpdateMask<5> const& changesMask, bool ignoreNestedChangesMask, Conversation const* owner, Player const* receiver) const; void ClearChangesMask(); }; diff --git a/src/server/game/Entities/Object/Updates/UpdateMask.h b/src/server/game/Entities/Object/Updates/UpdateMask.h index e2f848eda81..e3ccf0682d6 100644 --- a/src/server/game/Entities/Object/Updates/UpdateMask.h +++ b/src/server/game/Entities/Object/Updates/UpdateMask.h @@ -59,6 +59,14 @@ public: return (_blocks[index / 32] & (1 << (index % 32))) != 0; } + bool IsAnySet() const + { + return std::any_of(std::begin(_blocksMask), std::end(_blocksMask), [](uint32 blockMask) + { + return blockMask != 0; + }); + } + void Reset(uint32 index) { std::size_t blockIndex = UpdateMaskHelpers::GetBlockIndex(index); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 3e60cf4f502..daeaf3d8877 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -3677,15 +3677,58 @@ void Player::BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag fla UF::UnitData::Mask mask; m_unitData->AppendAllowedFieldsMaskForFlag(mask, flags); - m_unitData->WriteUpdate(*data, mask, flags, this, target); + m_unitData->WriteUpdate(*data, mask, true, this, target); UF::PlayerData::Mask mask2; m_playerData->AppendAllowedFieldsMaskForFlag(mask2, flags); - m_playerData->WriteUpdate(*data, mask2, flags, this, target); + m_playerData->WriteUpdate(*data, mask2, true, this, target); data->put<uint32>(sizePos, data->wpos() - sizePos - 4); } +void Player::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, + UF::UnitData::Mask const& requestedUnitMask, UF::PlayerData::Mask const& requestedPlayerMask, + UF::ActivePlayerData::Mask const& requestedActivePlayerMask, Player const* target) const +{ + UF::UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target); + UpdateMask<NUM_CLIENT_OBJECT_TYPES> valuesMask; + if (requestedObjectMask.IsAnySet()) + valuesMask.Set(TYPEID_OBJECT); + + UF::UnitData::Mask unitMask = requestedUnitMask; + m_unitData->FilterDisallowedFieldsMaskForFlag(unitMask, flags); + if (unitMask.IsAnySet()) + valuesMask.Set(TYPEID_UNIT); + + UF::PlayerData::Mask playerMask = requestedPlayerMask; + if (playerMask.IsAnySet()) + valuesMask.Set(TYPEID_PLAYER); + + if (target == this && requestedActivePlayerMask.IsAnySet()) + valuesMask.Set(TYPEID_ACTIVE_PLAYER); + + ByteBuffer buffer = PrepareValuesUpdateBuffer(); + std::size_t sizePos = buffer.wpos(); + buffer << uint32(0); + buffer << uint32(valuesMask.GetBlock(0)); + + if (valuesMask[TYPEID_OBJECT]) + m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target); + + if (valuesMask[TYPEID_UNIT]) + m_unitData->WriteUpdate(buffer, unitMask, true, this, target); + + if (valuesMask[TYPEID_PLAYER]) + m_playerData->WriteUpdate(buffer, playerMask, true, this, target); + + if (valuesMask[TYPEID_ACTIVE_PLAYER]) + m_activePlayerData->WriteUpdate(buffer, requestedActivePlayerMask, true, this, target); + + buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4); + + data->AddUpdateBlock(buffer); +} + void Player::DestroyForPlayer(Player* target) const { Unit::DestroyForPlayer(target); @@ -24803,7 +24846,25 @@ void Player::UpdateForQuestWorldObjects() if (itr->IsGameObject()) { if (GameObject* obj = ObjectAccessor::GetGameObject(*this, *itr)) - obj->BuildValuesUpdateBlockForPlayer(&udata, this); + { + switch (obj->GetGoType()) + { + case GAMEOBJECT_TYPE_QUESTGIVER: + case GAMEOBJECT_TYPE_CHEST: + case GAMEOBJECT_TYPE_GOOBER: + case GAMEOBJECT_TYPE_GENERIC: + if (sObjectMgr->IsGameObjectForQuests(obj->GetEntry())) + { + UF::ObjectData::Base objMask; + UF::GameObjectData::Base goMask; + objMask.MarkChanged(&UF::ObjectData::DynamicFlags); + obj->BuildValuesUpdateForPlayerWithMask(&udata, objMask.GetChangesMask(), goMask.GetChangesMask(), this); + } + break; + default: + break; + } + } } else if (itr->IsCreatureOrVehicle()) { @@ -24829,7 +24890,10 @@ void Player::UpdateForQuestWorldObjects() if (buildUpdateBlock) { - obj->BuildValuesUpdateBlockForPlayer(&udata, this); + UF::ObjectData::Base objMask; + UF::UnitData::Base unitMask; + unitMask.MarkChanged(&UF::UnitData::NpcFlags, 0); // NpcFlags[0] has UNIT_NPC_FLAG_SPELLCLICK + obj->BuildValuesUpdateForPlayerWithMask(&udata, objMask.GetChangesMask(), unitMask.GetChangesMask(), this); break; } } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index bf654be6dc7..476aa0d7492 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1821,13 +1821,18 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> WorldSession* GetSession() const { return m_session; } - void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const override; + protected: UF::UpdateFieldFlag GetUpdateFieldFlagsFor(Player const* target) const override; void BuildValuesCreate(ByteBuffer* data, Player const* target) const override; void BuildValuesUpdate(ByteBuffer* data, Player const* target) const override; + void ClearUpdateMask(bool remove) override; + + public: + void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const override; void BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override; + void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, UF::UnitData::Mask const& requestedUnitMask, + UF::PlayerData::Mask const& requestedPlayerMask, UF::ActivePlayerData::Mask const& requestedActivePlayerMask, Player const* target) const; void DestroyForPlayer(Player* target) const override; - void ClearUpdateMask(bool remove) override; // notifiers void SendAttackSwingCantAttack() const; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index cf86f82f55c..62790919a9c 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -14098,11 +14098,40 @@ void Unit::BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag flags UF::UnitData::Mask mask; m_unitData->AppendAllowedFieldsMaskForFlag(mask, flags); - m_unitData->WriteUpdate(*data, mask, flags, this, target); + m_unitData->WriteUpdate(*data, mask, true, this, target); data->put<uint32>(sizePos, data->wpos() - sizePos - 4); } +void Unit::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, + UF::UnitData::Mask const& requestedUnitMask, Player const* target) const +{ + UF::UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target); + UpdateMask<NUM_CLIENT_OBJECT_TYPES> valuesMask; + if (requestedObjectMask.IsAnySet()) + valuesMask.Set(TYPEID_OBJECT); + + UF::UnitData::Mask unitMask = requestedUnitMask; + m_unitData->FilterDisallowedFieldsMaskForFlag(unitMask, flags); + if (unitMask.IsAnySet()) + valuesMask.Set(TYPEID_UNIT); + + ByteBuffer buffer = PrepareValuesUpdateBuffer(); + std::size_t sizePos = buffer.wpos(); + buffer << uint32(0); + buffer << uint32(valuesMask.GetBlock(0)); + + if (valuesMask[TYPEID_OBJECT]) + m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target); + + if (valuesMask[TYPEID_UNIT]) + m_unitData->WriteUpdate(buffer, unitMask, true, this, target); + + buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4); + + data->AddUpdateBlock(buffer); +} + void Unit::DestroyForPlayer(Player* target) const { if (Battleground* bg = target->GetBattleground()) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index b4ffcc85ce3..1f9de500ad1 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -2011,7 +2011,13 @@ class TC_GAME_API Unit : public WorldObject UF::UpdateFieldFlag GetUpdateFieldFlagsFor(Player const* target) const override; void BuildValuesCreate(ByteBuffer* data, Player const* target) const override; void BuildValuesUpdate(ByteBuffer* data, Player const* target) const override; + + public: void BuildValuesUpdateWithFlag(ByteBuffer* data, UF::UpdateFieldFlag flags, Player const* target) const override; + void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask, + UF::UnitData::Mask const& requestedUnitMask, Player const* target) const; + + protected: void DestroyForPlayer(Player* target) const override; void ClearUpdateMask(bool remove) override; |