1
0
Fork 0

Reduce duplication in CompressPacket

- Remove line 1742 that wrote data which was then immediately cleared
* Store the compress/no compress threshold in a constant
- Remove adding a noncompressed header in SendPacket, CompressPacket handles everything now
This commit is contained in:
Tiger Wang 2020-07-19 16:21:05 +01:00
parent c99ddbc376
commit bedddfffbc
1 changed files with 75 additions and 41 deletions

View File

@ -87,6 +87,7 @@ Implements the 1.8 protocol classes:
const int MAX_ENC_LEN = 512; // Maximum size of the encrypted message; should be 128, but who knows... const int MAX_ENC_LEN = 512; // Maximum size of the encrypted message; should be 128, but who knows...
const uLongf MAX_COMPRESSED_PACKET_LEN = 200 KiB; // Maximum size of compressed packets. const uLongf MAX_COMPRESSED_PACKET_LEN = 200 KiB; // Maximum size of compressed packets.
static const UInt32 CompressionThreshold = 256; // After how large a packet should we compress it.
@ -328,16 +329,12 @@ void cProtocol_1_8_0::SendChatRaw(const AString & a_MessageRaw, eChatType a_Type
void cProtocol_1_8_0::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) void cProtocol_1_8_0::SendChunkData(const std::string_view a_ChunkData)
{ {
ASSERT(m_State == 3); // In game mode? ASSERT(m_State == 3); // In game mode?
// Serialize first, before creating the Packetizer (the packetizer locks a CS)
// This contains the flags and bitmasks, too
const AString & ChunkData = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_8_0, a_ChunkX, a_ChunkZ);
cCSLock Lock(m_CSPacket); cCSLock Lock(m_CSPacket);
SendData(ChunkData.data(), ChunkData.size()); SendData(a_ChunkData.data(), a_ChunkData.size());
} }
@ -805,7 +802,7 @@ void cProtocol_1_8_0::SendLoginSuccess(void)
// Enable compression: // Enable compression:
{ {
cPacketizer Pkt(*this, pktStartCompression); cPacketizer Pkt(*this, pktStartCompression);
Pkt.WriteVarInt32(256); Pkt.WriteVarInt32(CompressionThreshold);
} }
m_State = 3; // State = Game m_State = 3; // State = Game
@ -1712,6 +1709,52 @@ void cProtocol_1_8_0::SendWindowProperty(const cWindow & a_Window, short a_Prope
bool cProtocol_1_8_0::CompressPacket(const AString & a_Packet, AString & a_CompressedData) bool cProtocol_1_8_0::CompressPacket(const AString & a_Packet, AString & a_CompressedData)
{ {
const auto UncompressedSize = static_cast<size_t>(a_Packet.size());
if (UncompressedSize < CompressionThreshold)
{
/* Size doesn't reach threshold, not worth compressing.
--------------- Packet format ----------------
|--- Header ---------------------------------|
| PacketSize: Size of all fields below |
| DataSize: Zero, means below not compressed |
|--- Body -----------------------------------|
| a_Packet: copy of uncompressed data |
----------------------------------------------
*/
const UInt32 DataSize = 0;
const auto PacketSize = cByteBuffer::GetVarIntSize(DataSize) + UncompressedSize;
cByteBuffer LengthHeaderBuffer(
cByteBuffer::GetVarIntSize(PacketSize) +
cByteBuffer::GetVarIntSize(DataSize)
);
LengthHeaderBuffer.WriteVarInt32(PacketSize);
LengthHeaderBuffer.WriteVarInt32(DataSize);
AString LengthData;
LengthHeaderBuffer.ReadAll(LengthData);
a_CompressedData.reserve(LengthData.size() + UncompressedSize);
a_CompressedData.append(LengthData.data(), LengthData.size());
a_CompressedData.append(a_Packet);
return true;
}
/* Definitely worth compressing.
--------------- Packet format ----------------
|--- Header ---------------------------------|
| PacketSize: Size of all fields below |
| DataSize: Size of uncompressed a_Packet |
|--- Body -----------------------------------|
| CompressedData: compressed a_Packet |
----------------------------------------------
*/
// Compress the data: // Compress the data:
char CompressedData[MAX_COMPRESSED_PACKET_LEN]; char CompressedData[MAX_COMPRESSED_PACKET_LEN];
@ -1722,30 +1765,34 @@ bool cProtocol_1_8_0::CompressPacket(const AString & a_Packet, AString & a_Compr
return false; return false;
} }
int Status = compress2( if (
reinterpret_cast<Bytef *>(CompressedData), &CompressedSize, compress2(
reinterpret_cast<const Bytef *>(a_Packet.data()), static_cast<uLongf>(a_Packet.size()), Z_DEFAULT_COMPRESSION reinterpret_cast<Bytef *>(CompressedData), &CompressedSize,
); reinterpret_cast<const Bytef *>(a_Packet.data()), static_cast<uLongf>(a_Packet.size()), Z_DEFAULT_COMPRESSION
if (Status != Z_OK) ) != Z_OK
)
{ {
return false; return false;
} }
const UInt32 DataSize = UncompressedSize;
const auto PacketSize = cByteBuffer::GetVarIntSize(DataSize) + CompressedSize;
cByteBuffer LengthHeaderBuffer(
cByteBuffer::GetVarIntSize(PacketSize) +
cByteBuffer::GetVarIntSize(DataSize)
);
LengthHeaderBuffer.WriteVarInt32(PacketSize);
LengthHeaderBuffer.WriteVarInt32(DataSize);
AString LengthData; AString LengthData;
cByteBuffer Buffer(20); LengthHeaderBuffer.ReadAll(LengthData);
Buffer.WriteVarInt32(static_cast<UInt32>(a_Packet.size()));
Buffer.ReadAll(LengthData);
Buffer.CommitRead();
Buffer.WriteVarInt32(static_cast<UInt32>(CompressedSize + LengthData.size())); a_CompressedData.reserve(LengthData.size() + DataSize);
Buffer.WriteVarInt32(static_cast<UInt32>(a_Packet.size()));
Buffer.ReadAll(LengthData);
Buffer.CommitRead();
a_CompressedData.clear();
a_CompressedData.reserve(LengthData.size() + CompressedSize);
a_CompressedData.append(LengthData.data(), LengthData.size()); a_CompressedData.append(LengthData.data(), LengthData.size());
a_CompressedData.append(CompressedData, CompressedSize); a_CompressedData.append(CompressedData, CompressedSize);
return true; return true;
} }
@ -3150,22 +3197,16 @@ void cProtocol_1_8_0::SendPacket(cPacketizer & a_Pkt)
m_OutPacketBuffer.ReadAll(PacketData); m_OutPacketBuffer.ReadAll(PacketData);
m_OutPacketBuffer.CommitRead(); m_OutPacketBuffer.CommitRead();
if ((m_State == 3) && (PacketLen >= 256)) if (m_State == 3)
{ {
// Compress the packet payload: // Compress the packet payload:
if (!cProtocol_1_8_0::CompressPacket(PacketData, CompressedPacket)) if (!cProtocol_1_8_0::CompressPacket(PacketData, CompressedPacket))
{ {
return; return;
} }
}
else if (m_State == 3) // Send the packet's payload compressed:
{ SendData(CompressedPacket.data(), CompressedPacket.size());
// The packet is not compressed, indicate this in the packet header:
m_OutPacketLenBuffer.WriteVarInt32(PacketLen + 1);
m_OutPacketLenBuffer.WriteVarInt32(0);
AString LengthData;
m_OutPacketLenBuffer.ReadAll(LengthData);
SendData(LengthData.data(), LengthData.size());
} }
else else
{ {
@ -3174,18 +3215,11 @@ void cProtocol_1_8_0::SendPacket(cPacketizer & a_Pkt)
AString LengthData; AString LengthData;
m_OutPacketLenBuffer.ReadAll(LengthData); m_OutPacketLenBuffer.ReadAll(LengthData);
SendData(LengthData.data(), LengthData.size()); SendData(LengthData.data(), LengthData.size());
}
// Send the packet's payload, either direct or compressed: // Send the packet's payload directly:
if (CompressedPacket.empty())
{
m_OutPacketLenBuffer.CommitRead(); m_OutPacketLenBuffer.CommitRead();
SendData(PacketData.data(), PacketData.size()); SendData(PacketData.data(), PacketData.size());
} }
else
{
SendData(CompressedPacket.data(), CompressedPacket.size());
}
// Log the comm into logfile: // Log the comm into logfile:
if (g_ShouldLogCommOut && m_CommLogFile.IsOpen()) if (g_ShouldLogCommOut && m_CommLogFile.IsOpen())