summaryrefslogtreecommitdiffstats
path: root/src/Protocol
diff options
context:
space:
mode:
authorHowaner <franzi.moos@googlemail.com>2014-09-08 17:02:54 +0200
committerHowaner <franzi.moos@googlemail.com>2014-09-08 17:02:54 +0200
commit8f8693a71eb896ccc7c14c4033ae8d07dae27ac3 (patch)
tree8c9e19b4c5155eae5986943293a6cd8f77c8b831 /src/Protocol
parentUpdated chunk sending to 1.8 (diff)
downloadcuberite-8f8693a71eb896ccc7c14c4033ae8d07dae27ac3.tar
cuberite-8f8693a71eb896ccc7c14c4033ae8d07dae27ac3.tar.gz
cuberite-8f8693a71eb896ccc7c14c4033ae8d07dae27ac3.tar.bz2
cuberite-8f8693a71eb896ccc7c14c4033ae8d07dae27ac3.tar.lz
cuberite-8f8693a71eb896ccc7c14c4033ae8d07dae27ac3.tar.xz
cuberite-8f8693a71eb896ccc7c14c4033ae8d07dae27ac3.tar.zst
cuberite-8f8693a71eb896ccc7c14c4033ae8d07dae27ac3.zip
Diffstat (limited to 'src/Protocol')
-rw-r--r--src/Protocol/Protocol17x.cpp59
-rw-r--r--src/Protocol/Protocol17x.h14
-rw-r--r--src/Protocol/Protocol18x.cpp196
-rw-r--r--src/Protocol/Protocol18x.h9
4 files changed, 243 insertions, 35 deletions
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index 34bfbc82b..9a7111a43 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -1567,7 +1567,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size)
PacketType, PacketType, PacketLen, PacketLen, m_State, PacketDataHex.c_str()
);
}
-
+
if (!HandlePacket(bb, PacketType))
{
// Unknown packet, already been reported, but without the length. Log the length here:
@@ -1592,7 +1592,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size)
return;
}
-
+
if (bb.GetReadableSpace() != 1)
{
// Read more or less than packet length, report as error
@@ -1613,7 +1613,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size)
m_Client->PacketError(PacketType);
}
} // for (ever)
-
+
// Log any leftover bytes into the logfile:
if (g_ShouldLogCommIn && (m_ReceivedData.GetReadableSpace() > 0))
{
@@ -2332,25 +2332,32 @@ bool cProtocol172::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item)
-void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata)
+void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata, bool a_IsCompressed)
{
- // Uncompress the GZIPped data:
- AString Uncompressed;
- if (UncompressStringGZIP(a_Metadata.data(), a_Metadata.size(), Uncompressed) != Z_OK)
+ AString Metadata;
+ if (a_IsCompressed)
{
- AString HexDump;
- CreateHexDump(HexDump, a_Metadata.data(), a_Metadata.size(), 16);
- LOGWARNING("Cannot unGZIP item metadata (" SIZE_T_FMT " bytes):\n%s", a_Metadata.size(), HexDump.c_str());
- return;
+ // Uncompress the GZIPped data:
+ if (UncompressStringGZIP(a_Metadata.data(), a_Metadata.size(), Metadata) != Z_OK)
+ {
+ AString HexDump;
+ CreateHexDump(HexDump, a_Metadata.data(), a_Metadata.size(), 16);
+ LOGWARNING("Cannot unGZIP item metadata (" SIZE_T_FMT " bytes):\n%s", a_Metadata.size(), HexDump.c_str());
+ return;
+ }
+ }
+ else
+ {
+ Metadata = a_Metadata;
}
// Parse into NBT:
- cParsedNBT NBT(Uncompressed.data(), Uncompressed.size());
+ cParsedNBT NBT(Metadata.data(), Metadata.size());
if (!NBT.IsValid())
{
AString HexDump;
- CreateHexDump(HexDump, Uncompressed.data(), Uncompressed.size(), 16);
- LOGWARNING("Cannot parse NBT item metadata: (" SIZE_T_FMT " bytes)\n%s", Uncompressed.size(), HexDump.c_str());
+ CreateHexDump(HexDump, Metadata.data(), Metadata.size(), 16);
+ LOGWARNING("Cannot parse NBT item metadata: (" SIZE_T_FMT " bytes)\n%s", Metadata.size(), HexDump.c_str());
return;
}
@@ -2580,7 +2587,7 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item)
if (a_Item.m_Enchantments.IsEmpty() && a_Item.IsBothNameAndLoreEmpty() && (a_Item.m_ItemType != E_ITEM_FIREWORK_ROCKET) && (a_Item.m_ItemType != E_ITEM_FIREWORK_STAR))
{
- WriteShort(-1);
+ WriteChar(0);
return;
}
@@ -2626,10 +2633,24 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item)
cFireworkItem::WriteToNBTCompound(a_Item.m_FireworkItem, Writer, (ENUM_ITEM_ID)a_Item.m_ItemType);
}
Writer.Finish();
- AString Compressed;
- CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed);
- WriteShort((short)Compressed.size());
- WriteBuf(Compressed.data(), Compressed.size());
+
+ AString Result = Writer.GetResult();
+ if (m_Protocol.GetProtocolVersion() == cProtocolRecognizer::PROTO_VERSION_1_8_0)
+ {
+ if (Result.size() == 0)
+ {
+ WriteChar(0);
+ return;
+ }
+ WriteBuf(Result.data(), Result.size());
+ }
+ else
+ {
+ AString Compressed;
+ CompressStringGZIP(Result.data(), Result.size(), Compressed);
+ WriteShort((short)Compressed.size());
+ WriteBuf(Compressed.data(), Compressed.size());
+ }
}
diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h
index 289545bc7..1e716a761 100644
--- a/src/Protocol/Protocol17x.h
+++ b/src/Protocol/Protocol17x.h
@@ -200,9 +200,9 @@ protected:
m_Out.WriteVarUTF8String(a_Value);
}
- void WritePosition(const Vector3i a_Position)
+ void WritePosition(int a_BlockX, int a_BlockY, int a_BlockZ)
{
- WriteInt64(((Int64)a_Position.x & 0x3FFFFFF) << 38 | ((Int64)a_Position.y & 0xFFF) << 26 | ((Int64)a_Position.z & 0x3FFFFFF));
+ m_Out.WritePosition(a_BlockX, a_BlockY, a_BlockZ);
}
void WriteBuf(const char * a_Data, size_t a_Size)
@@ -273,12 +273,12 @@ protected:
// Packet handlers while in the Game state (m_State == 3):
void HandlePacketAnimation (cByteBuffer & a_ByteBuffer);
- void HandlePacketBlockDig (cByteBuffer & a_ByteBuffer);
- void HandlePacketBlockPlace (cByteBuffer & a_ByteBuffer);
+ virtual void HandlePacketBlockDig (cByteBuffer & a_ByteBuffer);
+ virtual void HandlePacketBlockPlace (cByteBuffer & a_ByteBuffer);
void HandlePacketChatMessage (cByteBuffer & a_ByteBuffer);
virtual void HandlePacketClientSettings (cByteBuffer & a_ByteBuffer);
virtual void HandlePacketClientStatus (cByteBuffer & a_ByteBuffer);
- void HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer);
+ virtual void HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer);
virtual void HandlePacketEntityAction (cByteBuffer & a_ByteBuffer);
virtual void HandlePacketKeepAlive (cByteBuffer & a_ByteBuffer);
void HandlePacketPlayer (cByteBuffer & a_ByteBuffer);
@@ -306,10 +306,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 */
- bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item);
+ virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item);
/** 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, bool a_IsCompressed = true);
void StartEncryption(const Byte * a_Key);
diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp
index 386e3dfb2..ffa8d5ecb 100644
--- a/src/Protocol/Protocol18x.cpp
+++ b/src/Protocol/Protocol18x.cpp
@@ -39,6 +39,21 @@ Implements the 1.8.x protocol classes:
+#define HANDLE_PACKET_READ(ByteBuf, Proc, Type, Var) \
+ Type Var; \
+ { \
+ if (!ByteBuf.Proc(Var)) \
+ { \
+ ByteBuf.CheckValid(); \
+ return false; \
+ } \
+ ByteBuf.CheckValid(); \
+ }
+
+
+
+
+
const int MAX_ENC_LEN = 512; // Maximum size of the encrypted message; should be 128, but who knows...
class cProtocol176;
@@ -59,13 +74,83 @@ cProtocol180::cProtocol180(cClientHandle * a_Client, const AString & a_ServerAdd
+void cProtocol180::SendPlayerSpawn(const cPlayer & a_Player)
+{
+ // Called to spawn another player for the client
+ cPacketizer Pkt(*this, 0x0c); // Spawn Player packet
+ Pkt.WriteVarInt(a_Player.GetUniqueID());
+
+ // Send UUID:
+ AString UUID = cMojangAPI::MakeUUIDShort(a_Player.GetClientHandle()->GetUUID());
+
+ Int64 MostSignificantBits = 0;
+ Int64 LeastSignificantBits = 0;
+
+ for (size_t i = 0; i < UUID.length(); i++)
+ {
+ MostSignificantBits += (UUID[i] & 0xff) >> 7;
+ LeastSignificantBits += UUID[i] & 1;
+ }
+ Pkt.WriteInt64(4053239666997989821);
+ Pkt.WriteInt64(-5603022497796657139);
+ LOG("Bits: %i, %i", (int)MostSignificantBits, (int)LeastSignificantBits);
+
+ // Pkt.WriteString(cMojangAPI::MakeUUIDDashed(a_Player.GetClientHandle()->GetUUID()));
+
+ Pkt.WriteFPInt(a_Player.GetPosX());
+ Pkt.WriteFPInt(a_Player.GetPosY());
+ Pkt.WriteFPInt(a_Player.GetPosZ());
+ Pkt.WriteByteAngle(a_Player.GetYaw());
+ Pkt.WriteByteAngle(a_Player.GetPitch());
+ short ItemType = a_Player.GetEquippedItem().IsEmpty() ? 0 : a_Player.GetEquippedItem().m_ItemType;
+ Pkt.WriteShort(ItemType);
+ Pkt.WriteByte((3 << 5) | 6); // Metadata: float + index 6
+ Pkt.WriteFloat((float)a_Player.GetHealth());
+ Pkt.WriteByte((4 << 5 | (2 & 0x1F)) & 0xFF);
+ Pkt.WriteString(a_Player.GetName());
+ Pkt.WriteByte(0x7f); // Metadata: end
+}
+
+
+
+
+
+void cProtocol180::SendPlayerMaxSpeed(void)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x20); // Entity Properties
+ cPlayer * Player = m_Client->GetPlayer();
+ Pkt.WriteVarInt(Player->GetUniqueID());
+ Pkt.WriteInt(1); // Count
+ Pkt.WriteString("generic.movementSpeed");
+ // The default game speed is 0.1, multiply that value by the relative speed:
+ Pkt.WriteDouble(0.1 * Player->GetNormalMaxSpeed());
+ if (Player->IsSprinting())
+ {
+ Pkt.WriteVarInt(1); // Modifier count
+ Pkt.WriteInt64(0x662a6b8dda3e4c1c);
+ Pkt.WriteInt64(0x881396ea6097278d); // UUID of the modifier
+ Pkt.WriteDouble(Player->GetSprintingMaxSpeed() - Player->GetNormalMaxSpeed());
+ Pkt.WriteByte(2);
+ }
+ else
+ {
+ Pkt.WriteVarInt(0); // Modifier count
+ }
+}
+
+
+
+
+
void cProtocol180::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data)
{
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, 0x28); // Effect packet
Pkt.WriteInt(a_EffectID);
- Pkt.WritePosition(Vector3i(a_SrcX, a_SrcY, a_SrcZ));
+ Pkt.WritePosition(a_SrcX, a_SrcY, a_SrcZ);
Pkt.WriteInt(a_Data);
Pkt.WriteBool(false);
}
@@ -144,7 +229,7 @@ void cProtocol180::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_Bloc
cPacketizer Pkt(*this, 0x0a);
Pkt.WriteVarInt(a_Entity.GetUniqueID());
- Pkt.WritePosition(Vector3i(a_BlockX, a_BlockY, a_BlockZ));
+ Pkt.WritePosition(a_BlockX, a_BlockY, a_BlockZ);
}
@@ -441,7 +526,7 @@ void cProtocol180::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLO
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, 0x23); // Block Change packet
- Pkt.WritePosition(Vector3i(a_BlockX, a_BlockY, a_BlockZ));
+ Pkt.WritePosition(a_BlockX, a_BlockY, a_BlockZ);
UInt32 Block = ((UInt32)a_BlockType << 4) | ((UInt32)a_BlockMeta & 15);
Pkt.WriteVarInt(Block);
@@ -624,8 +709,7 @@ void cProtocol180::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
// Send the spawn position:
{
cPacketizer Pkt(*this, 0x05); // Spawn Position packet
- Vector3i Position(a_World.GetSpawnX(), a_World.GetSpawnY(), a_World.GetSpawnZ());
- Pkt.WritePosition(Position);
+ Pkt.WritePosition(a_World.GetSpawnX(), a_World.GetSpawnY(), a_World.GetSpawnZ());
}
// Send player abilities:
@@ -636,6 +720,61 @@ void cProtocol180::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
+bool cProtocol180::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item)
+{
+ HANDLE_PACKET_READ(a_ByteBuffer, ReadBEShort, short, ItemType);
+ if (ItemType == -1)
+ {
+ // The item is empty, no more data follows
+ a_Item.Empty();
+ return true;
+ }
+ a_Item.m_ItemType = ItemType;
+
+ HANDLE_PACKET_READ(a_ByteBuffer, ReadChar, char, ItemCount);
+ HANDLE_PACKET_READ(a_ByteBuffer, ReadBEShort, short, ItemDamage);
+ a_Item.m_ItemCount = ItemCount;
+ a_Item.m_ItemDamage = ItemDamage;
+ if (ItemCount <= 0)
+ {
+ a_Item.Empty();
+ }
+
+ HANDLE_PACKET_READ(a_ByteBuffer, ReadChar, char, FirstChar);
+ if (FirstChar == 0)
+ {
+ // No metadata
+ return true;
+ }
+ a_ByteBuffer.ReverseRead(1);
+
+ // Read the metadata
+ AString Metadata;
+ a_ByteBuffer.ReadAll(Metadata);
+
+ ParseItemMetadata(a_Item, Metadata, false);
+ return true;
+}
+
+
+
+
+
+void cProtocol180::HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer)
+{
+ HANDLE_READ(a_ByteBuffer, ReadBEShort, short, SlotNum);
+ cItem Item;
+ if (!ReadItem(a_ByteBuffer, Item))
+ {
+ return;
+ }
+ m_Client->HandleCreativeInventory(SlotNum, Item);
+}
+
+
+
+
+
void cProtocol180::HandlePacketClientStatus(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadChar, char, ActionID);
@@ -672,7 +811,10 @@ void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel);
AString Data;
- a_ByteBuffer.ReadAll(Data);
+ if (!a_ByteBuffer.ReadString(Data, a_ByteBuffer.GetReadableSpace() - 1))
+ {
+ return;
+ }
m_Client->HandlePluginMessage(Channel, Data);
}
@@ -940,7 +1082,7 @@ void cProtocol180::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer)
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Locale);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ViewDistance);
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ChatFlags);
- HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ChatColors);
+ HANDLE_READ(a_ByteBuffer, ReadBool, bool, ChatColors);
HANDLE_READ(a_ByteBuffer, ReadChar, char, SkinFlags);
m_Client->SetLocale(Locale);
@@ -950,3 +1092,43 @@ void cProtocol180::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer)
+
+void cProtocol180::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer)
+{
+ int BlockX, BlockY, BlockZ;
+ if (!a_ByteBuffer.ReadPosition(BlockX, BlockY, BlockZ))
+ {
+ return;
+ }
+
+ HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Face);
+ cItem Item;
+ ReadItem(a_ByteBuffer, Item);
+
+ HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorX);
+ HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorY);
+ HANDLE_READ(a_ByteBuffer, ReadByte, Byte, CursorZ);
+ m_Client->HandleRightClick(BlockX, BlockY, BlockZ, static_cast<eBlockFace>(Face), CursorX, CursorY, CursorZ, m_Client->GetPlayer()->GetEquippedItem());
+}
+
+
+
+
+
+void cProtocol180::HandlePacketBlockDig(cByteBuffer & a_ByteBuffer)
+{
+ HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Status);
+
+ int BlockX, BlockY, BlockZ;
+ if (!a_ByteBuffer.ReadPosition(BlockX, BlockY, BlockZ))
+ {
+ return;
+ }
+
+ HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Face);
+ m_Client->HandleLeftClick(BlockX, BlockY, BlockZ, static_cast<eBlockFace>(Face), Status);
+}
+
+
+
+
diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h
index d9fd5d573..dc3739369 100644
--- a/src/Protocol/Protocol18x.h
+++ b/src/Protocol/Protocol18x.h
@@ -54,12 +54,12 @@ public:
cProtocol180(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State);
+ virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
+ virtual void SendPlayerMaxSpeed (void) override;
virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override;
virtual void SendLoginSuccess (void) override;
virtual void SendPickupSpawn (const cPickup & a_Pickup) override {}
virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) override {}
- virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) override {}
- virtual void SendWholeInventory (const cWindow & a_Window) override {}
virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount) override;
virtual void SendPlayerMoveLook (void) override;
virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override;
@@ -92,6 +92,8 @@ public:
protected:
+ virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item) override;
+
virtual void HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) override;
// Packet handlers while in the Login state (m_State == 2):
@@ -99,6 +101,7 @@ protected:
virtual void HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer) override;
// Packet handlers while in the Game state (m_State == 3):
+ virtual void HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer) override;
virtual void HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) override;
virtual void HandlePacketClientStatus(cByteBuffer & a_ByteBuffer) override;
virtual void HandlePacketSteerVehicle(cByteBuffer & a_ByteBuffer) override;
@@ -108,6 +111,8 @@ protected:
virtual void HandlePacketPlayerPos(cByteBuffer & a_ByteBuffer) override;
virtual void HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer) override;
virtual void HandlePacketClientSettings(cByteBuffer & a_ByteBuffer) override;
+ virtual void HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer) override;
+ virtual void HandlePacketBlockDig(cByteBuffer & a_ByteBuffer);
} ;