diff --git a/src/DedicatedServer.cpp b/src/DedicatedServer.cpp index 2284676..6725c6d 100644 --- a/src/DedicatedServer.cpp +++ b/src/DedicatedServer.cpp @@ -2,6 +2,7 @@ #include "config/ServerProperties.h" #include "PacketReader.h" +#include namespace Feather { @@ -22,8 +23,13 @@ namespace Feather auto [data, clientLock] = client.GetTCPClient()->GetData().borrow(); if (data.empty()) continue; - auto reader = PacketReader(data.data()); - m_protocol.HandlePacket(client, reader); + uint32_t offset = 0; + while (offset != data.size()) + { + auto reader = PacketReader(&data[offset]); + m_protocol.HandlePacket(client, reader); + offset += reader.Size(); + } data.clear(); } } diff --git a/src/PacketReader.h b/src/PacketReader.h index da1a1b7..5f4a460 100644 --- a/src/PacketReader.h +++ b/src/PacketReader.h @@ -48,12 +48,12 @@ namespace Feather inline int32_t ReadLength() { - int32_t length = ReadVarInt(); + int32_t length = ReadVarInt(&m_lengthSize); // HACK: handle Legacy Server List Ping if (length == 0xFE) { if (PeekByte() == 0x01) { - return 2; + return 1; } } @@ -61,9 +61,9 @@ namespace Feather } template - inline T ReadVarInt() + inline T ReadVarInt(uint32_t* outCount = nullptr) { - int32_t numRead = 0; + uint32_t numRead = 0; int32_t result = 0; uint8_t read; do @@ -80,6 +80,9 @@ namespace Feather } } while ((read & 0b10000000) != 0); + if (outCount != nullptr) + *outCount = numRead; + return static_cast(result); } @@ -96,10 +99,12 @@ namespace Feather } uint32_t Length() const { return m_length; } + uint32_t Size() const { return m_length + m_lengthSize; } private: const uint8_t *const m_data; uint32_t m_offset; const uint32_t m_length; + uint32_t m_lengthSize; }; // Use fast Read and Peek for uint8_t diff --git a/src/network/TCPListener.cpp b/src/network/TCPListener.cpp index 8b77dfe..098bb15 100644 --- a/src/network/TCPListener.cpp +++ b/src/network/TCPListener.cpp @@ -116,7 +116,7 @@ namespace Feather::Network bufferevent_setcb(m_bufferEvent, [](bufferevent* be, void* self) { static_cast(self)->ReadCallback(); }, [](bufferevent* be, void* self) { static_cast(self)->WriteCallback(); }, - [](bufferevent* be, int16_t event, void* self) { static_cast(self)->EventCallback(event); }, + [](bufferevent* be, int16_t event, void* self) { static_cast(self)->EventCallback(event); }, this); bufferevent_enable(m_bufferEvent, EV_READ | EV_WRITE); }