Core/PacketIO: Move ObjectGuid and Position::PackedXYZ packet functions out of ByteBuffer

This commit is contained in:
Shauren
2025-05-16 19:11:12 +02:00
parent 85d9ecab9d
commit ad9984b8a3
4 changed files with 63 additions and 114 deletions

View File

@@ -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<HighGuid::Null>();
ObjectGuid const ObjectGuid::ToStringFailed = ObjectGuid::Create<HighGuid::Uniq>(UI64LIT(3));
ObjectGuid const ObjectGuid::FromStringFailed = ObjectGuid::Create<HighGuid::Uniq>(UI64LIT(4));
ObjectGuid const ObjectGuid::TradeItem = ObjectGuid::Create<HighGuid::Uniq>(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);
static constexpr std::size_t NumUInt64s = 2;
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);
std::array<uint8, NumUInt64s + ObjectGuid::BytesSize> bytes;
memset(bytes.data(), 0, NumUInt64s);
size_t packedSize = guid._data.size();
buf.put(pos, lowMask);
buf.put(pos + 1, highMask);
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<uint8, 2> 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<uint8>()) << (b * 8);
return buf;
}

View File

@@ -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<uint8, 16> GetRawValue() const;
@@ -359,8 +359,8 @@ class TC_GAME_API ObjectGuid
static ObjectGuid FromString(std::string_view guidString);
std::size_t GetHash() const;
template <HighGuid type, std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::Null, int32> = 0> static ObjectGuid Create() { return ObjectGuidFactory::CreateNull(); }
template <HighGuid type, std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::Uniq, int32> = 0> static ObjectGuid Create(LowType id) { return ObjectGuidFactory::CreateUniq(id); }
template <HighGuid type, std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::Null, int32> = 0> static constexpr ObjectGuid Create() { return ObjectGuidFactory::CreateNull(); }
template <HighGuid type, std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::Uniq, int32> = 0> static constexpr ObjectGuid Create(LowType id) { return ObjectGuidFactory::CreateUniq(id); }
template <HighGuid type, std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::Player, int32> = 0> static ObjectGuid Create(LowType dbId) { return ObjectGuidFactory::CreatePlayer(0, dbId); }
template <HighGuid type, std::enable_if_t<ObjectGuidTraits<type>::Format::value == ObjectGuidFormatType::Item, int32> = 0> static ObjectGuid Create(LowType dbId) { return ObjectGuidFactory::CreateItem(0, dbId); }
template <HighGuid type, std::enable_if_t<ObjectGuidTraits<type>::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 <HighGuid type, std::enable_if_t<ObjectGuidTraits<type>::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 }})
{
}

View File

@@ -19,9 +19,9 @@
#include "ByteBuffer.h"
#include "DB2Stores.h"
#include "GridDefines.h"
#include "StringFormat.h"
#include "World.h"
#include <G3D/g3dmath.h>
#include <sstream>
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<float>(M_PI));
mod = -mod + 2.0f * static_cast<float>(M_PI);
return mod;
}
return -std::fmod(-o, 2.0f * static_cast<float>(M_PI)) + 2.0f * static_cast<float>(M_PI);
return std::fmod(o, 2.0f * static_cast<float>(M_PI));
}
ByteBuffer& operator<<(ByteBuffer& buf, Position::ConstStreamer<Position::XY> 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<Position::XY> 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<Position::XYZ> 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<Position::XYZ> 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<Position::XYZO> 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<Position::XYZO> 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<float>());
return buf;
}
ByteBuffer& operator<<(ByteBuffer& buf, Position::ConstStreamer<Position::PackedXYZ> 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()] : "<not found>") <<"' " << Position::ToString();
return sstr.str();
return Trinity::StringFormat("MapID: {} Map name: '{}' {}",
m_mapId, mapEntry ? mapEntry->MapName[sWorld->GetDefaultDbcLocale()] : "<not found>", Position::ToString());
}

View File

@@ -534,19 +534,6 @@ class TC_SHARED_API ByteBuffer
read(arr.data(), Size);
}
void ReadPackedUInt64(uint64& guid)
{
guid = 0;
ReadPackedUInt64(read<uint8>(), guid);
}
void ReadPackedUInt64(uint8 mask, uint64& value)
{
for (uint32 i = 0; i < 8; ++i)
if (mask & (uint8(1) << i))
value |= (uint64(read<uint8>()) << (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<uint8>(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;