1
0

Protocol 1.8: Handling packet compression properly.

The compression didn't work with CommLog turned on.
This commit is contained in:
madmaxoft 2014-09-25 20:34:49 +02:00
parent 3459bc1ede
commit 27187371eb
2 changed files with 39 additions and 14 deletions

View File

@ -1711,20 +1711,43 @@ void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size)
m_ReceivedData.ResetRead(); m_ReceivedData.ResetRead();
break; break;
} }
cByteBuffer bb(PacketLen + 1);
VERIFY(m_ReceivedData.ReadToByteBuffer(bb, (int)PacketLen)); // Check packet for compression:
m_ReceivedData.CommitRead(); UInt32 CompressedSize = 0;
AString UncompressedData;
// Compressed packets
if (m_State == 3) if (m_State == 3)
{ {
UInt32 CompressedSize; UInt32 NumBytesRead = m_ReceivedData.GetReadableSpace();
if (!bb.ReadVarInt(CompressedSize)) m_ReceivedData.ReadVarInt(CompressedSize);
if (CompressedSize > 0)
{ {
// Not enough data // Decompress the data:
break; 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; UInt32 PacketType;
if (!bb.ReadVarInt(PacketType)) if (!bb.ReadVarInt(PacketType))
@ -2299,7 +2322,7 @@ void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer)
{ {
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel); HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel);
AString Data; AString Data;
a_ByteBuffer.ReadAll(Data); a_ByteBuffer.ReadString(Data, a_ByteBuffer.GetReadableSpace() - 1);
m_Client->HandlePluginMessage(Channel, Data); m_Client->HandlePluginMessage(Channel, Data);
} }
@ -2526,7 +2549,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); HANDLE_PACKET_READ(a_ByteBuffer, ReadBEShort, short, ItemType);
if (ItemType == -1) if (ItemType == -1)
@ -2547,7 +2570,7 @@ bool cProtocol180::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a
} }
AString Metadata; 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 // No metadata
return true; return true;

View File

@ -321,8 +321,10 @@ protected:
void SendCompass(const cWorld & a_World); 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 */ /** Reads an item out of the received data, sets a_Item to the values read.
virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_RemainingBytes = 0); 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. */ /** Parses item metadata as read by ReadItem(), into the item enchantments. */
void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata); void ParseItemMetadata(cItem & a_Item, const AString & a_Metadata);