diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Protocol/Protocol18x.cpp | 57 | ||||
-rw-r--r-- | src/Protocol/Protocol18x.h | 6 |
2 files changed, 47 insertions, 16 deletions
diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index 33b6ca68e..3e1863f97 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -1716,20 +1716,43 @@ void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size) m_ReceivedData.ResetRead(); break; } - cByteBuffer bb(PacketLen + 1); - VERIFY(m_ReceivedData.ReadToByteBuffer(bb, (int)PacketLen)); - m_ReceivedData.CommitRead(); - - // Compressed packets + + // Check packet for compression: + UInt32 CompressedSize = 0; + AString UncompressedData; if (m_State == 3) { - UInt32 CompressedSize; - if (!bb.ReadVarInt(CompressedSize)) + UInt32 NumBytesRead = m_ReceivedData.GetReadableSpace(); + m_ReceivedData.ReadVarInt(CompressedSize); + if (CompressedSize > 0) { - // Not enough data - break; + // Decompress the data: + AString CompressedData; + m_ReceivedData.ReadString(CompressedData, CompressedSize); + InflateString(CompressedData.data(), CompressedSize, UncompressedData); + PacketLen = UncompressedData.size(); } + else + { + NumBytesRead -= m_ReceivedData.GetReadableSpace(); // How many bytes has the CompressedSize taken up? + ASSERT(PacketLen > NumBytesRead); + PacketLen -= NumBytesRead; + } + } + + // Move the packet payload to a separate cByteBuffer, bb: + cByteBuffer bb(PacketLen + 1); + if (CompressedSize == 0) + { + // No compression was used, move directly + VERIFY(m_ReceivedData.ReadToByteBuffer(bb, (int)PacketLen)); } + else + { + // Compression was used, move the uncompressed data: + VERIFY(bb.Write(UncompressedData.data(), UncompressedData.size())); + } + m_ReceivedData.CommitRead(); UInt32 PacketType; if (!bb.ReadVarInt(PacketType)) @@ -1971,13 +1994,19 @@ void cProtocol180::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) void cProtocol180::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer) { UInt32 EncKeyLength, EncNonceLength; - a_ByteBuffer.ReadVarInt(EncKeyLength); + if (!a_ByteBuffer.ReadVarInt(EncKeyLength)) + { + return; + } AString EncKey; if (!a_ByteBuffer.ReadString(EncKey, EncKeyLength)) { return; } - a_ByteBuffer.ReadVarInt(EncNonceLength); + if (!a_ByteBuffer.ReadVarInt(EncNonceLength)) + { + return; + } AString EncNonce; if (!a_ByteBuffer.ReadString(EncNonce, EncNonceLength)) { @@ -2298,7 +2327,7 @@ void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) { HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel); AString Data; - a_ByteBuffer.ReadAll(Data); + a_ByteBuffer.ReadString(Data, a_ByteBuffer.GetReadableSpace() - 1); m_Client->HandlePluginMessage(Channel, Data); } @@ -2525,7 +2554,7 @@ void cProtocol180::SendData(const char * a_Data, size_t a_Size) -bool cProtocol180::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_RemainingBytes) +bool cProtocol180::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_KeepRemainingBytes) { HANDLE_PACKET_READ(a_ByteBuffer, ReadBEShort, short, ItemType); if (ItemType == -1) @@ -2546,7 +2575,7 @@ bool cProtocol180::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a } AString Metadata; - if (!a_ByteBuffer.ReadString(Metadata, a_ByteBuffer.GetReadableSpace() - a_RemainingBytes) || (Metadata.size() == 0) || (Metadata[0] == 0)) + if (!a_ByteBuffer.ReadString(Metadata, a_ByteBuffer.GetReadableSpace() - a_KeepRemainingBytes - 1) || (Metadata.size() == 0) || (Metadata[0] == 0)) { // No metadata return true; diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index eb0253663..df188b70f 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -321,8 +321,10 @@ protected: void SendCompass(const cWorld & a_World); - /** Reads an item out of the received data, sets a_Item to the values read. Returns false if not enough received data */ - virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_RemainingBytes = 0); + /** Reads an item out of the received data, sets a_Item to the values read. + Returns false if not enough received data. + a_KeepRemainingBytes tells the function to keep that many bytes at the end of the buffer. */ + virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_KeepRemainingBytes = 0); /** Parses item metadata as read by ReadItem(), into the item enchantments. */ void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata); |