summaryrefslogtreecommitdiffstats
path: root/src/Protocol
diff options
context:
space:
mode:
Diffstat (limited to 'src/Protocol')
-rw-r--r--src/Protocol/ChunkDataSerializer.cpp2
-rw-r--r--src/Protocol/Protocol18x.cpp74
-rw-r--r--src/Protocol/Protocol18x.h6
3 files changed, 60 insertions, 22 deletions
diff --git a/src/Protocol/ChunkDataSerializer.cpp b/src/Protocol/ChunkDataSerializer.cpp
index a133cc0e3..5d080656d 100644
--- a/src/Protocol/ChunkDataSerializer.cpp
+++ b/src/Protocol/ChunkDataSerializer.cpp
@@ -191,7 +191,7 @@ void cChunkDataSerializer::Serialize47(AString & a_Data, int a_ChunkX, int a_Chu
Packet.WriteBEInt(a_ChunkX);
Packet.WriteBEInt(a_ChunkZ);
Packet.WriteBool(true); // "Ground-up continuous", or rather, "biome data present" flag
- Packet.WriteBEShort((short) 0xffff); // We're aways sending the full chunk with no additional data, so the bitmap is 0xffff
+ Packet.WriteBEUShort(0xffff); // We're aways sending the full chunk with no additional data, so the bitmap is 0xffff
// Write the chunk size:
const int BiomeDataSize = cChunkDef::Width * cChunkDef::Width;
diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp
index 0cafdeb76..9f7569ff2 100644
--- a/src/Protocol/Protocol18x.cpp
+++ b/src/Protocol/Protocol18x.cpp
@@ -1000,6 +1000,7 @@ void cProtocol180::SendPluginMessage(const AString & a_Channel, const AString &
cPacketizer Pkt(*this, 0x3f);
Pkt.WriteString(a_Channel);
+ Pkt.WriteVarInt((UInt32)a_Message.size());
Pkt.WriteBuf(a_Message.data(), a_Message.size());
}
@@ -1391,13 +1392,18 @@ void cProtocol180::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity)
void cProtocol180::SendUpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4)
{
ASSERT(m_State == 3); // In game mode?
-
+
cPacketizer Pkt(*this, 0x33);
Pkt.WritePosition(a_BlockX, a_BlockY, a_BlockZ);
- Pkt.WriteString(Printf("{\"text\": \"%s\"}", a_Line1.c_str()));
- Pkt.WriteString(Printf("{\"text\": \"%s\"}", a_Line2.c_str()));
- Pkt.WriteString(Printf("{\"text\": \"%s\"}", a_Line3.c_str()));
- Pkt.WriteString(Printf("{\"text\": \"%s\"}", a_Line4.c_str()));
+
+ Json::StyledWriter JsonWriter;
+ AString Lines[] = { a_Line1, a_Line2, a_Line3, a_Line4 };
+ for (size_t i = 0; i < ARRAYCOUNT(Lines); i++)
+ {
+ Json::Value RootValue;
+ RootValue["text"] = Lines[i];
+ Pkt.WriteString(JsonWriter.write(RootValue).c_str());
+ }
}
@@ -1711,20 +1717,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))
@@ -1966,13 +1995,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))
{
@@ -2292,8 +2327,9 @@ void cProtocol180::HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer)
void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel);
+ HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, DataLen);
AString Data;
- a_ByteBuffer.ReadAll(Data);
+ a_ByteBuffer.ReadString(Data, DataLen);
m_Client->HandlePluginMessage(Channel, Data);
}
@@ -2520,7 +2556,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)
@@ -2541,7 +2577,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);