aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp4
-rw-r--r--src/server/game/Entities/Object/Object.cpp4
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateMask.h181
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp4
4 files changed, 89 insertions, 104 deletions
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 53ebcef7d12..0e864cdc479 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -2515,8 +2515,7 @@ void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* t
ByteBuffer fieldBuffer;
- UpdateMask updateMask;
- updateMask.SetCount(m_valuesCount);
+ UpdateMaskPacketBuilder updateMask(m_valuesCount);
uint32* flags = GameObjectUpdateFieldFlags;
uint32 visibleFlag = UF_FLAG_PUBLIC;
@@ -2583,7 +2582,6 @@ void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* t
}
}
- *data << uint8(updateMask.GetBlockCount());
updateMask.AppendToPacket(data);
data->append(fieldBuffer);
}
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 87a5a693e5f..1cfcbe25539 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -474,8 +474,7 @@ void Object::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* targe
return;
ByteBuffer fieldBuffer;
- UpdateMask updateMask;
- updateMask.SetCount(m_valuesCount);
+ UpdateMaskPacketBuilder updateMask(m_valuesCount);
uint32* flags = nullptr;
uint32 visibleFlag = GetUpdateFieldData(target, flags);
@@ -491,7 +490,6 @@ void Object::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* targe
}
}
- *data << uint8(updateMask.GetBlockCount());
updateMask.AppendToPacket(data);
data->append(fieldBuffer);
}
diff --git a/src/server/game/Entities/Object/Updates/UpdateMask.h b/src/server/game/Entities/Object/Updates/UpdateMask.h
index 3490c5810f7..ae65685f33a 100644
--- a/src/server/game/Entities/Object/Updates/UpdateMask.h
+++ b/src/server/game/Entities/Object/Updates/UpdateMask.h
@@ -24,101 +24,92 @@
class UpdateMask
{
- public:
- /// Type representing how client reads update mask
- typedef uint32 ClientUpdateMaskType;
-
- enum UpdateMaskCount
- {
- CLIENT_UPDATE_MASK_BITS = sizeof(ClientUpdateMaskType) * 8,
- };
-
- UpdateMask() : _fieldCount(0), _blockCount(0), _bits(nullptr) { }
-
- UpdateMask(UpdateMask const& right) : _bits(nullptr)
- {
- SetCount(right.GetCount());
- memcpy(_bits, right._bits, sizeof(uint8) * _blockCount * 32);
- }
-
- ~UpdateMask() { delete[] _bits; }
-
- void SetBit(uint32 index) { _bits[index] = 1; }
- void UnsetBit(uint32 index) { _bits[index] = 0; }
- bool GetBit(uint32 index) const { return _bits[index] != 0; }
-
- void AppendToPacket(ByteBuffer* data)
- {
- for (uint32 i = 0; i < GetBlockCount(); ++i)
- {
- ClientUpdateMaskType maskPart = 0;
- for (uint32 j = 0; j < CLIENT_UPDATE_MASK_BITS; ++j)
- if (_bits[CLIENT_UPDATE_MASK_BITS * i + j])
- maskPart |= 1 << j;
-
- *data << maskPart;
- }
- }
-
- uint32 GetBlockCount() const { return _blockCount; }
- uint32 GetCount() const { return _fieldCount; }
-
- void SetCount(uint32 valuesCount)
- {
- delete[] _bits;
-
- _fieldCount = valuesCount;
- _blockCount = (valuesCount + CLIENT_UPDATE_MASK_BITS - 1) / CLIENT_UPDATE_MASK_BITS;
-
- _bits = new uint8[_blockCount * CLIENT_UPDATE_MASK_BITS];
- memset(_bits, 0, sizeof(uint8) * _blockCount * CLIENT_UPDATE_MASK_BITS);
- }
-
- void Clear()
- {
- if (_bits)
- memset(_bits, 0, sizeof(uint8) * _blockCount * CLIENT_UPDATE_MASK_BITS);
- }
-
- UpdateMask& operator=(UpdateMask const& right)
- {
- if (this == &right)
- return *this;
-
- SetCount(right.GetCount());
- memcpy(_bits, right._bits, sizeof(uint8) * _blockCount * CLIENT_UPDATE_MASK_BITS);
- return *this;
- }
-
- UpdateMask& operator&=(UpdateMask const& right)
- {
- ASSERT(right.GetCount() <= GetCount());
- for (uint32 i = 0; i < _fieldCount; ++i)
- _bits[i] &= right._bits[i];
-
- return *this;
- }
-
- UpdateMask& operator|=(UpdateMask const& right)
- {
- ASSERT(right.GetCount() <= GetCount());
- for (uint32 i = 0; i < _fieldCount; ++i)
- _bits[i] |= right._bits[i];
-
- return *this;
- }
-
- UpdateMask operator|(UpdateMask const& right)
- {
- UpdateMask ret(*this);
- ret |= right;
- return ret;
- }
-
- private:
- uint32 _fieldCount;
- uint32 _blockCount;
- uint8* _bits;
+public:
+ UpdateMask() : _bits(nullptr), _fieldCount(0) { }
+
+ void SetBit(uint32 index)
+ {
+ _bits[index] = 1;
+ }
+
+ void UnsetBit(uint32 index)
+ {
+ _bits[index] = 0;
+ }
+
+ bool GetBit(uint32 index) const
+ {
+ return _bits[index] != 0;
+ }
+
+ void SetCount(uint32 valuesCount)
+ {
+ _bits = std::make_unique<uint8[]>(valuesCount);
+ std::uninitialized_fill_n(&_bits[0], valuesCount, 0);
+ _fieldCount = valuesCount;
+ }
+
+ void Clear()
+ {
+ if (_bits)
+ std::fill_n(&_bits[0], _fieldCount, 0);
+ }
+
+private:
+ std::unique_ptr<uint8[]> _bits;
+ uint32 _fieldCount;
+};
+
+class UpdateMaskPacketBuilder
+{
+public:
+ /// Type representing how client reads update mask
+ using ClientUpdateMaskType = uint32;
+
+ enum UpdateMaskCount
+ {
+ CLIENT_UPDATE_MASK_BITS = sizeof(ClientUpdateMaskType) * 8,
+ };
+
+ explicit UpdateMaskPacketBuilder(uint32 valuesCount) : _lastSetBit(0)
+ {
+ std::size_t blockCount = CalculateBlockCount(valuesCount);
+ _mask = std::make_unique<ClientUpdateMaskType[]>(blockCount);
+ std::uninitialized_fill_n(&_mask[0], blockCount, 0);
+ }
+
+ void SetBit(uint32 bit)
+ {
+ _mask[GetBlockIndex(bit)] |= GetBlockFlag(bit);
+ _lastSetBit = bit;
+ }
+
+ void AppendToPacket(ByteBuffer* data)
+ {
+ uint8 blockCount = CalculateBlockCount(_lastSetBit + 1);
+ *data << uint8(blockCount);
+ if (blockCount)
+ data->append(&_mask[0], blockCount);
+ }
+
+private:
+ static constexpr uint8 CalculateBlockCount(uint32 fieldCount)
+ {
+ return (fieldCount + CLIENT_UPDATE_MASK_BITS - 1) / CLIENT_UPDATE_MASK_BITS;
+ }
+
+ static constexpr std::size_t GetBlockIndex(uint32 bit)
+ {
+ return bit / 32;
+ }
+
+ static constexpr uint32 GetBlockFlag(uint32 bit)
+ {
+ return 1u << (bit % 32);
+ }
+
+ std::unique_ptr<ClientUpdateMaskType[]> _mask;
+ uint32 _lastSetBit;
};
#endif
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 0b01709c3db..0bb20566b21 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -13281,8 +13281,7 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target)
ByteBuffer fieldBuffer;
- UpdateMask updateMask;
- updateMask.SetCount(m_valuesCount);
+ UpdateMaskPacketBuilder updateMask(m_valuesCount);
uint32* flags = UnitUpdateFieldFlags;
uint32 visibleFlag = UF_FLAG_PUBLIC;
@@ -13429,7 +13428,6 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target)
}
}
- *data << uint8(updateMask.GetBlockCount());
updateMask.AppendToPacket(data);
data->append(fieldBuffer);
}