From 39ce52bde186762cad7073c9fabef1e9401259fb Mon Sep 17 00:00:00 2001 From: Shauren Date: Fri, 16 May 2025 19:11:12 +0200 Subject: Core/PacketIO: Move ObjectGuid and Position::PackedXYZ packet functions out of ByteBuffer (cherry picked from commit ad9984b8a36f8bdcbdd2a0c168acb56be44287a7) --- src/server/game/Entities/Object/ObjectGuid.cpp | 52 ++++++++++++---------- src/server/game/Entities/Object/ObjectGuid.h | 12 ++--- src/server/game/Entities/Object/Position.cpp | 61 ++++++++++++-------------- src/server/shared/Packets/ByteBuffer.h | 56 ----------------------- 4 files changed, 65 insertions(+), 116 deletions(-) (limited to 'src') diff --git a/src/server/game/Entities/Object/ObjectGuid.cpp b/src/server/game/Entities/Object/ObjectGuid.cpp index ea0efd9af04..069c4658533 100644 --- a/src/server/game/Entities/Object/ObjectGuid.cpp +++ b/src/server/game/Entities/Object/ObjectGuid.cpp @@ -796,12 +796,12 @@ static inline uint32 GetRealmIdForObjectGuid(uint32 realmId) return sRealmList->GetCurrentRealmId().Realm; } -ObjectGuid ObjectGuidFactory::CreateNull() +constexpr ObjectGuid ObjectGuidFactory::CreateNull() { return ObjectGuid(); } -ObjectGuid ObjectGuidFactory::CreateUniq(ObjectGuid::LowType id) +constexpr ObjectGuid ObjectGuidFactory::CreateUniq(ObjectGuid::LowType id) { return ObjectGuid(uint64(uint64(HighGuid::Uniq) << 58), id); @@ -952,37 +952,45 @@ ObjectGuid ObjectGuidFactory::CreateLMMLobby(uint32 realmId, uint32 arg2, uint8 counter); } -ObjectGuid const ObjectGuid::Empty = ObjectGuid(); +ObjectGuid const ObjectGuid::Empty = ObjectGuid::Create(); ObjectGuid const ObjectGuid::ToStringFailed = ObjectGuid::Create(UI64LIT(3)); ObjectGuid const ObjectGuid::FromStringFailed = ObjectGuid::Create(UI64LIT(4)); ObjectGuid const ObjectGuid::TradeItem = ObjectGuid::Create(UI64LIT(10)); ByteBuffer& operator<<(ByteBuffer& buf, ObjectGuid const& guid) { - uint8 lowMask = 0; - uint8 highMask = 0; - buf.FlushBits(); // flush any unwritten bits to make wpos return a meaningful value - std::size_t pos = buf.wpos(); - buf << uint8(lowMask); - buf << uint8(highMask); - - uint8 packed[8]; - if (size_t packedSize = ByteBuffer::PackUInt64(guid._data[0], &lowMask, packed)) - buf.append(packed, packedSize); - if (size_t packedSize = ByteBuffer::PackUInt64(guid._data[1], &highMask, packed)) - buf.append(packed, packedSize); - - buf.put(pos, lowMask); - buf.put(pos + 1, highMask); + static constexpr std::size_t NumUInt64s = 2; + + std::array bytes; + memset(bytes.data(), 0, NumUInt64s); + size_t packedSize = guid._data.size(); + + for (std::size_t i = 0; i < guid._data.size(); ++i) + { + for (uint32 b = 0; b < 8; ++b) + { + if (uint8 byte = uint8((guid._data[i] >> (b * 8)) & 0xFF)) + { + bytes[packedSize++] = byte; + bytes[i] |= uint8(1 << b); + } + } + } + + buf.append(bytes.data(), packedSize); return buf; } ByteBuffer& operator>>(ByteBuffer& buf, ObjectGuid& guid) { - uint8 lowMask, highMask; - buf >> lowMask >> highMask; - buf.ReadPackedUInt64(lowMask, guid._data[0]); - buf.ReadPackedUInt64(highMask, guid._data[1]); + std::array mask; + buf.read(mask); + + for (std::size_t i = 0; i < guid._data.size(); ++i) + for (uint32 b = 0; b < 8; ++b) + if (mask[i] & (uint8(1) << b)) + guid._data[i] |= uint64(buf.read()) << (b * 8); + return buf; } diff --git a/src/server/game/Entities/Object/ObjectGuid.h b/src/server/game/Entities/Object/ObjectGuid.h index d48fd879b26..d0c0fafe444 100644 --- a/src/server/game/Entities/Object/ObjectGuid.h +++ b/src/server/game/Entities/Object/ObjectGuid.h @@ -243,8 +243,8 @@ class ObjectGuid; class TC_GAME_API ObjectGuidFactory { public: - static ObjectGuid CreateNull(); - static ObjectGuid CreateUniq(uint64 id); + static constexpr ObjectGuid CreateNull(); + static constexpr ObjectGuid CreateUniq(uint64 id); static ObjectGuid CreatePlayer(uint32 realmId, uint64 dbId); static ObjectGuid CreateItem(uint32 realmId, uint64 dbId); static ObjectGuid CreateWorldObject(HighGuid type, uint8 subType, uint32 realmId, uint16 mapId, uint32 serverId, uint32 entry, uint64 counter); @@ -280,7 +280,7 @@ class TC_GAME_API ObjectGuid using LowType = uint64; - ObjectGuid() = default; + constexpr ObjectGuid() = default; uint64 GetRawValue(std::size_t i) const { return _data[i]; } std::array GetRawValue() const; @@ -359,8 +359,8 @@ class TC_GAME_API ObjectGuid static ObjectGuid FromString(std::string_view guidString); std::size_t GetHash() const; - template ::Format::value == ObjectGuidFormatType::Null, int32> = 0> static ObjectGuid Create() { return ObjectGuidFactory::CreateNull(); } - template ::Format::value == ObjectGuidFormatType::Uniq, int32> = 0> static ObjectGuid Create(LowType id) { return ObjectGuidFactory::CreateUniq(id); } + template ::Format::value == ObjectGuidFormatType::Null, int32> = 0> static constexpr ObjectGuid Create() { return ObjectGuidFactory::CreateNull(); } + template ::Format::value == ObjectGuidFormatType::Uniq, int32> = 0> static constexpr ObjectGuid Create(LowType id) { return ObjectGuidFactory::CreateUniq(id); } template ::Format::value == ObjectGuidFormatType::Player, int32> = 0> static ObjectGuid Create(LowType dbId) { return ObjectGuidFactory::CreatePlayer(0, dbId); } template ::Format::value == ObjectGuidFormatType::Item, int32> = 0> static ObjectGuid Create(LowType dbId) { return ObjectGuidFactory::CreateItem(0, dbId); } template ::Format::value == ObjectGuidFormatType::WorldObject, int32> = 0> static ObjectGuid Create(uint16 mapId, uint32 entry, LowType counter) { return ObjectGuidFactory::CreateWorldObject(type, 0, 0, mapId, 0, entry, counter); } @@ -381,7 +381,7 @@ class TC_GAME_API ObjectGuid template ::Format::value == ObjectGuidFormatType::LMMLobby, int32> = 0> static ObjectGuid Create(uint32 arg2, uint8 arg3, uint8 arg4, LowType counter) { return ObjectGuidFactory::CreateLMMLobby(0, arg2, arg3, arg4, counter); } protected: - ObjectGuid(uint64 high, uint64 low) : _data({{ low, high }}) + constexpr ObjectGuid(uint64 high, uint64 low) : _data({{ low, high }}) { } diff --git a/src/server/game/Entities/Object/Position.cpp b/src/server/game/Entities/Object/Position.cpp index aa391a0d062..1ad21820e09 100644 --- a/src/server/game/Entities/Object/Position.cpp +++ b/src/server/game/Entities/Object/Position.cpp @@ -19,9 +19,9 @@ #include "ByteBuffer.h" #include "DB2Stores.h" #include "GridDefines.h" +#include "StringFormat.h" #include "World.h" #include -#include bool Position::operator==(Position const& a) const { @@ -198,9 +198,7 @@ bool Position::HasInLine(Position const* pos, float objSize, float width) const std::string Position::ToString() const { - std::stringstream sstr; - sstr << "X: " << m_positionX << " Y: " << m_positionY << " Z: " << m_positionZ << " O: " << m_orientation; - return sstr.str(); + return Trinity::StringFormat("X: {} Y: {} Z: {} O: {}", m_positionX, m_positionY, m_positionZ, m_orientation); } float Position::NormalizeOrientation(float o) @@ -208,73 +206,72 @@ float Position::NormalizeOrientation(float o) // fmod only supports positive numbers. Thus we have // to emulate negative numbers if (o < 0) - { - float mod = o *-1; - mod = std::fmod(mod, 2.0f * static_cast(M_PI)); - mod = -mod + 2.0f * static_cast(M_PI); - return mod; - } + return -std::fmod(-o, 2.0f * static_cast(M_PI)) + 2.0f * static_cast(M_PI); + return std::fmod(o, 2.0f * static_cast(M_PI)); } ByteBuffer& operator<<(ByteBuffer& buf, Position::ConstStreamer const& streamer) { - buf << streamer.Pos->GetPositionX(); - buf << streamer.Pos->GetPositionY(); + buf << float(streamer.Pos->GetPositionX()); + buf << float(streamer.Pos->GetPositionY()); return buf; } ByteBuffer& operator>>(ByteBuffer& buf, Position::Streamer const& streamer) { - float x, y; - buf >> x >> y; - streamer.Pos->Relocate(x, y); + buf >> streamer.Pos->m_positionX; + buf >> streamer.Pos->m_positionY; return buf; } ByteBuffer& operator<<(ByteBuffer& buf, Position::ConstStreamer const& streamer) { - buf << streamer.Pos->GetPositionX(); - buf << streamer.Pos->GetPositionY(); - buf << streamer.Pos->GetPositionZ(); + buf << float(streamer.Pos->GetPositionX()); + buf << float(streamer.Pos->GetPositionY()); + buf << float(streamer.Pos->GetPositionZ()); return buf; } ByteBuffer& operator>>(ByteBuffer& buf, Position::Streamer const& streamer) { - float x, y, z; - buf >> x >> y >> z; - streamer.Pos->Relocate(x, y, z); + buf >> streamer.Pos->m_positionX; + buf >> streamer.Pos->m_positionY; + buf >> streamer.Pos->m_positionZ; return buf; } ByteBuffer& operator<<(ByteBuffer& buf, Position::ConstStreamer const& streamer) { - buf << streamer.Pos->GetPositionX(); - buf << streamer.Pos->GetPositionY(); - buf << streamer.Pos->GetPositionZ(); - buf << streamer.Pos->GetOrientation(); + buf << float(streamer.Pos->GetPositionX()); + buf << float(streamer.Pos->GetPositionY()); + buf << float(streamer.Pos->GetPositionZ()); + buf << float(streamer.Pos->GetOrientation()); return buf; } ByteBuffer& operator>>(ByteBuffer& buf, Position::Streamer const& streamer) { - float x, y, z, o; - buf >> x >> y >> z >> o; - streamer.Pos->Relocate(x, y, z, o); + buf >> streamer.Pos->m_positionX; + buf >> streamer.Pos->m_positionY; + buf >> streamer.Pos->m_positionZ; + streamer.Pos->SetOrientation(buf.read()); return buf; } ByteBuffer& operator<<(ByteBuffer& buf, Position::ConstStreamer const& streamer) { - buf.appendPackXYZ(streamer.Pos->GetPositionX(), streamer.Pos->GetPositionY(), streamer.Pos->GetPositionZ()); + int32 packed = 0; + packed |= (int32(streamer.Pos->GetPositionX() / 0.25f) & 0x7FF); + packed |= (int32(streamer.Pos->GetPositionY() / 0.25f) & 0x7FF) << 11; + packed |= (int32(streamer.Pos->GetPositionZ() / 0.25f) & 0x3FF) << 22; + buf << int32(packed); return buf; } std::string WorldLocation::GetDebugInfo() const { - std::stringstream sstr; MapEntry const* mapEntry = sMapStore.LookupEntry(m_mapId); - sstr << "MapID: " << m_mapId << " Map name: '" << (mapEntry ? mapEntry->MapName[sWorld->GetDefaultDbcLocale()] : "") <<"' " << Position::ToString(); - return sstr.str(); + return Trinity::StringFormat("MapID: {} Map name: '{}' {}", + m_mapId, mapEntry ? mapEntry->MapName[sWorld->GetDefaultDbcLocale()] : "", Position::ToString()); } diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h index 9f77823d21e..7bd6e474937 100644 --- a/src/server/shared/Packets/ByteBuffer.h +++ b/src/server/shared/Packets/ByteBuffer.h @@ -534,19 +534,6 @@ class TC_SHARED_API ByteBuffer read(arr.data(), Size); } - void ReadPackedUInt64(uint64& guid) - { - guid = 0; - ReadPackedUInt64(read(), guid); - } - - void ReadPackedUInt64(uint8 mask, uint64& value) - { - for (uint32 i = 0; i < 8; ++i) - if (mask & (uint8(1) << i)) - value |= (uint64(read()) << (i * 8)); - } - //! Method for writing strings that have their length sent separately in packet //! without null-terminating the string void WriteString(std::string const& str) @@ -620,49 +607,6 @@ class TC_SHARED_API ByteBuffer append(arr.data(), Size); } - // can be used in SMSG_MONSTER_MOVE opcode - void appendPackXYZ(float x, float y, float z) - { - uint32 packed = 0; - packed |= ((int)(x / 0.25f) & 0x7FF); - packed |= ((int)(y / 0.25f) & 0x7FF) << 11; - packed |= ((int)(z / 0.25f) & 0x3FF) << 22; - *this << packed; - } - - void AppendPackedUInt64(uint64 guid) - { - uint8 mask = 0; - size_t pos = wpos(); - *this << uint8(mask); - - uint8 packed[8]; - if (size_t packedSize = PackUInt64(guid, &mask, packed)) - append(packed, packedSize); - - put(pos, mask); - } - - static size_t PackUInt64(uint64 value, uint8* mask, uint8* result) - { - size_t resultSize = 0; - *mask = 0; - memset(result, 0, 8); - - for (uint8 i = 0; value != 0; ++i) - { - if (value & 0xFF) - { - *mask |= uint8(1 << i); - result[resultSize++] = uint8(value & 0xFF); - } - - value >>= 8; - } - - return resultSize; - } - void put(size_t pos, uint8 const* src, size_t cnt); void print_storage() const; -- cgit v1.2.3