Permalink
Browse files

Added more 1.8 protocol stuff.

  • Loading branch information...
Howaner committed Sep 6, 2014
1 parent da28c70 commit f83cdd974d939d6aee21bb88786a75e2cd68d008
View
@@ -611,7 +611,7 @@ bool cByteBuffer::WriteVarInt(UInt32 a_Value)
{
CHECK_THREAD;
CheckValid();
// A 32-bit integer can be encoded by at most 5 bytes:
unsigned char b[5];
size_t idx = 0;
@@ -8,6 +8,7 @@
#include "Globals.h"
#include "ChunkDataSerializer.h"
#include "zlib/zlib.h"
#include "ByteBuffer.h"
@@ -181,40 +182,48 @@ void cChunkDataSerializer::Serialize80(AString & a_Data)
// TODO: Do not copy data and then compress it; rather, compress partial blocks of data (zlib *can* stream)
// Blocktypes converter (1.8 included the meta into the blocktype):
unsigned short Blocks[ARRAYCOUNT(m_BlockTypes)];
/*unsigned short Blocks[ARRAYCOUNT(m_BlockTypes)];
for (size_t Index = 0; Index < cChunkDef::NumBlocks; Index++)
{
BLOCKTYPE BlockType = m_BlockTypes[Index];
NIBBLETYPE BlockMeta = m_BlockMetas[Index / 2] >> ((Index & 1) * 4) & 0x0f;
Blocks[Index] = ((unsigned short)BlockType << 4) | ((unsigned short)BlockMeta);
}
}*/
cByteBuffer ByteBuffer(256 KiB);
const int BiomeDataSize = cChunkDef::Width * cChunkDef::Width;
const int BlockLightOffset = sizeof(Blocks);
const int MetadataOffset = sizeof(m_BlockTypes);
const int BlockLightOffset = MetadataOffset + sizeof(m_BlockMetas);
const int SkyLightOffset = BlockLightOffset + sizeof(m_BlockLight);
const int BiomeOffset = SkyLightOffset + sizeof(m_BlockSkyLight);
const int DataSize = BiomeOffset + BiomeDataSize;
// Temporary buffer for the composed data:
char AllData [DataSize];
memcpy(AllData, Blocks, sizeof(Blocks));
memcpy(AllData, m_BlockTypes, sizeof(m_BlockTypes));
memcpy(AllData + MetadataOffset, m_BlockMetas, sizeof(m_BlockMetas));
memcpy(AllData + BlockLightOffset, m_BlockLight, sizeof(m_BlockLight));
memcpy(AllData + SkyLightOffset, m_BlockSkyLight, sizeof(m_BlockSkyLight));
memcpy(AllData + BiomeOffset, m_BiomeData, BiomeDataSize);
// Put all those data into a_Data:
a_Data.push_back('\x01'); // "Ground-up continuous", or rather, "biome data present" flag
ByteBuffer.WriteBool(true); // "Ground-up continuos", or rather, "biome data present" flag
// Two bitmaps; we're aways sending the full chunk with no additional data, so the bitmaps are 0xffff and 0, respectively
// Also, no endian flipping is needed because of the const values
unsigned short BitMap = 0xffff;
a_Data.append((const char *)&BitMap, sizeof(unsigned short));
ByteBuffer.WriteBEShort(BitMap);
// Write chunk size:
UInt32 ChunkSize = htonl((UInt32)DataSize);
a_Data.append((const char *)&ChunkSize, 4);
UInt32 ChunkSize = sizeof(AllData);
ByteBuffer.WriteVarInt(ChunkSize);
// Write chunk data:
ByteBuffer.WriteBuf(AllData, ChunkSize);
a_Data.append(AllData, DataSize); // Chunk data
// Return content:
ByteBuffer.ReadAll(a_Data);
ByteBuffer.CommitRead();
}
@@ -14,6 +14,7 @@ Implements the 1.7.x protocol classes:
#include "Protocol17x.h"
#include "ChunkDataSerializer.h"
#include "PolarSSL++/Sha1Checksum.h"
#include "zlib/zlib.h"
#include "../ClientHandle.h"
#include "../Root.h"
@@ -97,7 +98,7 @@ cProtocol172::cProtocol172(cClientHandle * a_Client, const AString & a_ServerAdd
m_ServerPort(a_ServerPort),
m_State(a_State),
m_ReceivedData(32 KiB),
m_OutPacketBuffer(64 KiB),
m_OutPacketBuffer(256 KiB),
m_OutPacketLenBuffer(20), // 20 bytes is more than enough for one VarInt
m_IsEncrypted(false),
m_LastSentDimension(dimNotSet)
@@ -351,7 +352,7 @@ void cProtocol172::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerialize
cPacketizer Pkt(*this, 0x21); // Chunk Data packet
Pkt.WriteInt(a_ChunkX);
Pkt.WriteInt(a_ChunkZ);
Pkt.WriteBuf(ChunkData.data(), ChunkData.size());
Pkt.WriteBuf(ChunkData.data(), sizeof(ChunkData.data()));
}
@@ -2507,28 +2508,68 @@ void cProtocol172::AddChatPartStyle(Json::Value & a_Value, const AString & a_Par
cProtocol172::cPacketizer::~cPacketizer()
{
AString DataToSend;
// Send the packet length
UInt32 PacketLen = (UInt32)m_Out.GetUsedSpace();
AString LengthToWrite;
m_Protocol.m_OutPacketLenBuffer.WriteVarInt(PacketLen);
m_Protocol.m_OutPacketLenBuffer.ReadAll(DataToSend);
m_Protocol.SendData(DataToSend.data(), DataToSend.size());
m_Protocol.m_OutPacketLenBuffer.ReadAll(LengthToWrite);
m_Protocol.m_OutPacketLenBuffer.CommitRead();
// Send the packet data:
m_Out.ReadAll(DataToSend);
m_Protocol.SendData(DataToSend.data(), DataToSend.size());
// Write packet data into a string
AString PacketDataWithoutLength;
m_Out.ReadAll(PacketDataWithoutLength);
m_Out.CommitRead();
// Create PacketData:
AString PacketData;
PacketData.resize(LengthToWrite.size() + PacketDataWithoutLength.size());
PacketData.append(LengthToWrite.data(), sizeof(LengthToWrite.data()));
PacketData.append(PacketDataWithoutLength.data(), sizeof(PacketDataWithoutLength.data()));
PacketLen = (UInt32)sizeof(PacketData.data());
// Send all:
cByteBuffer PacketBuffer(64 KiB);
if ((m_Protocol.m_State == 3) && (PacketLen >= 256))
{
LOG("Crypt packet!");
PacketBuffer.WriteVarInt(PacketLen); // Write uncompressed packet length
// Compress the data:
// In order not to use allocation, use a fixed-size buffer, with the size
// that uses the same calculation as compressBound():
const uLongf CompressedMaxSize = 64 KiB - sizeof(UInt32);
char CompressedData[CompressedMaxSize];
uLongf CompressedSize = compressBound(PacketLen);
// Run-time check that our compile-time guess about CompressedMaxSize was enough:
ASSERT(CompressedSize <= CompressedMaxSize);
compress2((Bytef*)CompressedData, &CompressedSize, (const Bytef*)PacketData.data(), PacketData.size(), Z_DEFAULT_COMPRESSION);
PacketBuffer.WriteBuf(CompressedData, CompressedSize);
}
else
{
if (m_Protocol.m_State == 3)
{
PacketBuffer.WriteByte(0); // 0 stands for "no compression"
}
PacketBuffer.WriteBuf(PacketData.data(), sizeof(PacketData.data()));
}
AString DataToSend;
PacketBuffer.ReadAll(DataToSend);
m_Protocol.SendData(DataToSend.data(), sizeof(PacketData.data()));
PacketBuffer.CommitRead();
// Log the comm into logfile:
if (g_ShouldLogCommOut)
{
AString Hex;
ASSERT(DataToSend.size() > 0);
CreateHexDump(Hex, DataToSend.data() + 1, DataToSend.size() - 1, 16);
ASSERT(PacketData.size() > 0);
CreateHexDump(Hex, PacketData.data() + 1, PacketData.size() - 1, 16);
m_Protocol.m_CommLogFile.Printf("Outgoing packet: type %d (0x%x), length %u (0x%x), state %d. Payload:\n%s\n",
DataToSend[0], DataToSend[0], PacketLen, PacketLen, m_Protocol.m_State, Hex.c_str()
PacketDataWithoutLength[0], PacketDataWithoutLength[0], PacketLen, PacketLen, m_Protocol.m_State, Hex.c_str()
);
}
}
@@ -205,9 +205,9 @@ class cProtocol172 :
WriteInt64(((Int64)a_Position.x & 0x3FFFFFF) << 38 | ((Int64)a_Position.y & 0xFFF) << 26 | ((Int64)a_Position.z & 0x3FFFFFF));
}
void WriteBuf(const char * a_Data, size_t a_Size)
bool WriteBuf(const char * a_Data, size_t a_Size)
{
m_Out.Write(a_Data, a_Size);
return m_Out.Write(a_Data, a_Size);
}
void WriteItem(const cItem & a_Item);
@@ -61,19 +61,19 @@ void cProtocol180::SendLoginSuccess(void)
{
ASSERT(m_State == 2); // State: login?
// Disable compression:
// Enable compression:
{
cPacketizer Pkt(*this, 0x03); // Set compression packet
Pkt.WriteVarInt(-1);
Pkt.WriteVarInt(256);
}
m_State = 3; // State = Game
{
cPacketizer Pkt(*this, 0x02); // Login success packet
Pkt.WriteString(cMojangAPI::MakeUUIDDashed(m_Client->GetUUID()));
Pkt.WriteString(m_Client->GetUsername());
}
m_State = 3; // State = Game
}
@@ -414,7 +414,7 @@ void cProtocol180::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerialize
cPacketizer Pkt(*this, 0x21); // Chunk Data packet
Pkt.WriteInt(a_ChunkX);
Pkt.WriteInt(a_ChunkZ);
Pkt.WriteBuf(ChunkData.data(), ChunkData.size());
Pkt.WriteBuf(ChunkData.data(), sizeof(ChunkData.data()));
}

0 comments on commit f83cdd9

Please sign in to comment.