diff options
author | Shauren <shauren.trinity@gmail.com> | 2021-04-25 14:56:25 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2021-04-25 14:56:25 +0200 |
commit | 2f04c48919664524c0036fa5923ea082e45f435f (patch) | |
tree | 15f03b1bd450923a5b02071780652173e40b8765 /src/server | |
parent | ab1a5b7fc8fca3b6540a49c39fc00cb63f16dc6a (diff) |
Core/PacketIO: Reduce size of SMSG_UPDATE_OBJECT by trimming trailing zeros in values updatemask
Diffstat (limited to 'src/server')
-rw-r--r-- | src/server/game/Entities/GameObject/GameObject.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateMask.h | 181 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 4 |
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); } |