summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHowaner <franzi.moos@googlemail.com>2014-09-04 03:22:35 +0200
committerHowaner <franzi.moos@googlemail.com>2014-09-04 03:22:35 +0200
commit07fba5c98ec94f98b742e8aa76dcec5572bfcecb (patch)
treeace9397744465e070ebb79d68c88e4ca15d970aa
parentStarted implementing of the 1.8 protocol. (diff)
downloadcuberite-07fba5c98ec94f98b742e8aa76dcec5572bfcecb.tar
cuberite-07fba5c98ec94f98b742e8aa76dcec5572bfcecb.tar.gz
cuberite-07fba5c98ec94f98b742e8aa76dcec5572bfcecb.tar.bz2
cuberite-07fba5c98ec94f98b742e8aa76dcec5572bfcecb.tar.lz
cuberite-07fba5c98ec94f98b742e8aa76dcec5572bfcecb.tar.xz
cuberite-07fba5c98ec94f98b742e8aa76dcec5572bfcecb.tar.zst
cuberite-07fba5c98ec94f98b742e8aa76dcec5572bfcecb.zip
Diffstat (limited to '')
-rw-r--r--src/Protocol/ChunkDataSerializer.cpp64
-rw-r--r--src/Protocol/ChunkDataSerializer.h4
-rw-r--r--src/Protocol/Protocol17x.cpp1
-rw-r--r--src/Protocol/Protocol17x.h18
-rw-r--r--src/Protocol/Protocol18x.cpp523
-rw-r--r--src/Protocol/Protocol18x.h36
6 files changed, 632 insertions, 14 deletions
diff --git a/src/Protocol/ChunkDataSerializer.cpp b/src/Protocol/ChunkDataSerializer.cpp
index ebe61631b..9eadc4f0b 100644
--- a/src/Protocol/ChunkDataSerializer.cpp
+++ b/src/Protocol/ChunkDataSerializer.cpp
@@ -43,6 +43,7 @@ const AString & cChunkDataSerializer::Serialize(int a_Version)
{
case RELEASE_1_2_5: Serialize29(data); break;
case RELEASE_1_3_2: Serialize39(data); break;
+ case RELEASE_1_8_0: Serialize80(data); break;
// TODO: Other protocol versions may serialize the data differently; implement here
default:
@@ -174,3 +175,66 @@ void cChunkDataSerializer::Serialize39(AString & a_Data)
+
+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)];
+ for (int RelX = 0; RelX < cChunkDef::Width; RelX++)
+ {
+ for (int RelZ = 0; RelZ < cChunkDef::Width; RelZ++)
+ {
+ for (int RelY = 0; RelY < cChunkDef::Height; RelY++)
+ {
+ int Index = cChunkDef::MakeIndexNoCheck(RelX, RelY, RelZ);
+ BLOCKTYPE BlockType = m_BlockTypes[Index];
+ NIBBLETYPE BlockMeta = m_BlockMetas[Index / 2] >> ((Index & 1) * 4) & 0x0f;
+
+ Blocks[Index] = ((unsigned short)BlockType << 4) | ((unsigned short)BlockMeta & 15);
+ }
+ }
+ }
+
+ const int BiomeDataSize = cChunkDef::Width * cChunkDef::Width;
+ const int BlockLightOffset = sizeof(Blocks);
+ 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 + 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
+
+ // 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(short));
+
+ // Write chunk size:
+ UInt32 ChunkSize = htonl((UInt32)DataSize);
+
+ unsigned char b[5]; // // A 32-bit integer can be encoded by at most 5 bytes
+ size_t idx = 0;
+ UInt32 Value = ChunkSize;
+ do
+ {
+ b[idx] = (Value & 0x7f) | ((Value > 0x7f) ? 0x80 : 0x00);
+ Value = Value >> 7;
+ idx++;
+ } while (Value > 0);
+ a_Data.append((const char *)b, idx);
+
+ a_Data.append(AllData, ChunkSize); // Chunk data
+}
+
+
+
+
diff --git a/src/Protocol/ChunkDataSerializer.h b/src/Protocol/ChunkDataSerializer.h
index a42856356..4c33aede1 100644
--- a/src/Protocol/ChunkDataSerializer.h
+++ b/src/Protocol/ChunkDataSerializer.h
@@ -23,13 +23,15 @@ protected:
Serializations m_Serializations;
void Serialize29(AString & a_Data); // Release 1.2.4 and 1.2.5
- void Serialize39(AString & a_Data); // Release 1.3.1 and 1.3.2
+ void Serialize39(AString & a_Data); // Release 1.3.1 to 1.7.10
+ void Serialize80(AString & a_Data); // Release 1.8
public:
enum
{
RELEASE_1_2_5 = 29,
RELEASE_1_3_2 = 39,
+ RELEASE_1_8_0 = 47,
} ;
cChunkDataSerializer(
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index 00b115c8f..88b4693c9 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -2614,6 +2614,7 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item)
+
void cProtocol172::cPacketizer::WriteBlockEntity(const cBlockEntity & a_BlockEntity)
{
cFastNBTWriter Writer;
diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h
index ec948e8a1..be94c0d61 100644
--- a/src/Protocol/Protocol17x.h
+++ b/src/Protocol/Protocol17x.h
@@ -146,6 +146,7 @@ protected:
m_Lock(a_Protocol.m_CSPacket)
{
m_Out.WriteVarInt(a_PacketType);
+ LOG("Send packet %i", a_PacketType);
}
~cPacketizer();
@@ -211,6 +212,7 @@ protected:
}
void WriteItem(const cItem & a_Item);
+ void WriteItem180(const cItem & a_Item);
void WriteByteAngle(double a_Angle); // Writes the specified angle using a single byte
void WriteFPInt(double a_Value); // Writes the double value as a 27:5 fixed-point integer
void WriteEntityMetadata(const cEntity & a_Entity); // Writes the metadata for the specified entity, not including the terminating 0x7f
@@ -277,21 +279,21 @@ protected:
void HandlePacketBlockPlace (cByteBuffer & a_ByteBuffer);
void HandlePacketChatMessage (cByteBuffer & a_ByteBuffer);
void HandlePacketClientSettings (cByteBuffer & a_ByteBuffer);
- void HandlePacketClientStatus (cByteBuffer & a_ByteBuffer);
+ virtual void HandlePacketClientStatus (cByteBuffer & a_ByteBuffer);
void HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer);
- void HandlePacketEntityAction (cByteBuffer & a_ByteBuffer);
- void HandlePacketKeepAlive (cByteBuffer & a_ByteBuffer);
+ virtual void HandlePacketEntityAction (cByteBuffer & a_ByteBuffer);
+ virtual void HandlePacketKeepAlive (cByteBuffer & a_ByteBuffer);
void HandlePacketPlayer (cByteBuffer & a_ByteBuffer);
void HandlePacketPlayerAbilities (cByteBuffer & a_ByteBuffer);
void HandlePacketPlayerLook (cByteBuffer & a_ByteBuffer);
- void HandlePacketPlayerPos (cByteBuffer & a_ByteBuffer);
- void HandlePacketPlayerPosLook (cByteBuffer & a_ByteBuffer);
- void HandlePacketPluginMessage (cByteBuffer & a_ByteBuffer);
+ virtual void HandlePacketPlayerPos (cByteBuffer & a_ByteBuffer);
+ virtual void HandlePacketPlayerPosLook (cByteBuffer & a_ByteBuffer);
+ virtual void HandlePacketPluginMessage (cByteBuffer & a_ByteBuffer);
void HandlePacketSlotSelect (cByteBuffer & a_ByteBuffer);
- void HandlePacketSteerVehicle (cByteBuffer & a_ByteBuffer);
+ virtual void HandlePacketSteerVehicle (cByteBuffer & a_ByteBuffer);
void HandlePacketTabComplete (cByteBuffer & a_ByteBuffer);
void HandlePacketUpdateSign (cByteBuffer & a_ByteBuffer);
- void HandlePacketUseEntity (cByteBuffer & a_ByteBuffer);
+ virtual void HandlePacketUseEntity (cByteBuffer & a_ByteBuffer);
void HandlePacketEnchantItem (cByteBuffer & a_ByteBuffer);
void HandlePacketWindowClick (cByteBuffer & a_ByteBuffer);
void HandlePacketWindowClose (cByteBuffer & a_ByteBuffer);
diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp
index 0a455c70e..4dbb2207c 100644
--- a/src/Protocol/Protocol18x.cpp
+++ b/src/Protocol/Protocol18x.cpp
@@ -11,6 +11,7 @@ Implements the 1.8.x protocol classes:
#include "Globals.h"
#include "Bindings/PluginManager.h"
#include "json/json.h"
+#include "ChunkDataSerializer.h"
#include "Protocol18x.h"
#include "../ClientHandle.h"
@@ -20,14 +21,25 @@ Implements the 1.8.x protocol classes:
#include "../World.h"
#include "../Entities/Player.h"
+#include "Entities/Painting.h"
-class cProtocol176;
+
+
+
+
+#define HANDLE_READ(ByteBuf, Proc, Type, Var) \
+ Type Var; \
+ if (!ByteBuf.Proc(Var))\
+ {\
+ return;\
+ }
const int MAX_ENC_LEN = 512; // Maximum size of the encrypted message; should be 128, but who knows...
+class cProtocol176;
@@ -45,6 +57,347 @@ cProtocol180::cProtocol180(cClientHandle * a_Client, const AString & a_ServerAdd
+void cProtocol180::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)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ /*cPacketizer Pkt(*this, 0x2A);
+ Pkt.WriteString(a_ParticleName);
+ Pkt.WriteFloat(a_SrcX);
+ Pkt.WriteFloat(a_SrcY);
+ Pkt.WriteFloat(a_SrcZ);
+ Pkt.WriteFloat(a_OffsetX);
+ Pkt.WriteFloat(a_OffsetY);
+ Pkt.WriteFloat(a_OffsetZ);
+ Pkt.WriteFloat(a_ParticleData);
+ Pkt.WriteInt(a_ParticleAmmount);*/
+}
+
+
+
+
+
+void cProtocol180::SendPlayerMoveLook(void)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x08); // Player Position And Look packet
+ cPlayer * Player = m_Client->GetPlayer();
+ Pkt.WriteDouble(Player->GetPosX());
+
+ // The "+ 0.001" is there because otherwise the player falls through the block they were standing on.
+ Pkt.WriteDouble(Player->GetStance() + 0.001);
+
+ Pkt.WriteDouble(Player->GetPosZ());
+ Pkt.WriteFloat((float)Player->GetYaw());
+ Pkt.WriteFloat((float)Player->GetPitch());
+ Pkt.WriteByte(0);
+}
+
+
+
+
+
+void cProtocol180::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x0a);
+ Pkt.WriteVarInt(a_Entity.GetUniqueID());
+ Pkt.WritePosition(Vector3i(a_BlockX, a_BlockY, a_BlockZ));
+}
+
+
+
+
+
+void cProtocol180::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x0d); // Collect Item packet
+ Pkt.WriteVarInt(a_Entity.GetUniqueID());
+ Pkt.WriteVarInt(a_Player.GetUniqueID());
+}
+
+
+
+
+
+void cProtocol180::SendEntityVelocity(const cEntity & a_Entity)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x12); // Entity Velocity packet
+ Pkt.WriteVarInt(a_Entity.GetUniqueID());
+ // 400 = 8000 / 20 ... Conversion from our speed in m/s to 8000 m/tick
+ Pkt.WriteShort((short)(a_Entity.GetSpeedX() * 400));
+ Pkt.WriteShort((short)(a_Entity.GetSpeedY() * 400));
+ Pkt.WriteShort((short)(a_Entity.GetSpeedZ() * 400));
+}
+
+
+
+
+
+void cProtocol180::SendDestroyEntity(const cEntity & a_Entity)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x13); // Destroy Entities packet
+ Pkt.WriteVarInt(1);
+ Pkt.WriteVarInt(a_Entity.GetUniqueID());
+}
+
+
+
+
+
+void cProtocol180::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x15); // Entity Relative Move packet
+ Pkt.WriteVarInt(a_Entity.GetUniqueID());
+ Pkt.WriteByte(a_RelX);
+ Pkt.WriteByte(a_RelY);
+ Pkt.WriteByte(a_RelZ);
+ Pkt.WriteBool(true); // TODO: IsOnGround() on entities
+}
+
+
+
+
+
+void cProtocol180::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x17); // Entity Look And Relative Move packet
+ Pkt.WriteVarInt(a_Entity.GetUniqueID());
+ Pkt.WriteByte(a_RelX);
+ Pkt.WriteByte(a_RelY);
+ Pkt.WriteByte(a_RelZ);
+ Pkt.WriteByteAngle(a_Entity.GetYaw());
+ Pkt.WriteByteAngle(a_Entity.GetPitch());
+ Pkt.WriteBool(true); // TODO: IsOnGround() on entities
+}
+
+
+
+
+
+void cProtocol180::SendEntityLook(const cEntity & a_Entity)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x16); // Entity Look packet
+ Pkt.WriteVarInt(a_Entity.GetUniqueID());
+ Pkt.WriteByteAngle(a_Entity.GetYaw());
+ Pkt.WriteByteAngle(a_Entity.GetPitch());
+ Pkt.WriteBool(true); // TODO: IsOnGround() on entities
+}
+
+
+
+
+
+void cProtocol180::SendTeleportEntity(const cEntity & a_Entity)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x18);
+ Pkt.WriteVarInt(a_Entity.GetUniqueID());
+ Pkt.WriteFPInt(a_Entity.GetPosX());
+ Pkt.WriteFPInt(a_Entity.GetPosY());
+ Pkt.WriteFPInt(a_Entity.GetPosZ());
+ Pkt.WriteByteAngle(a_Entity.GetYaw());
+ Pkt.WriteByteAngle(a_Entity.GetPitch());
+ Pkt.WriteBool(true); // TODO: IsOnGrond() on entities
+}
+
+
+
+
+
+void cProtocol180::SendEntityHeadLook(const cEntity & a_Entity)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x19); // Entity Head Look packet
+ Pkt.WriteVarInt((UInt32)a_Entity.GetUniqueID());
+ Pkt.WriteByteAngle(a_Entity.GetHeadYaw());
+}
+
+
+
+
+
+void cProtocol180::SendEntityMetadata(const cEntity & a_Entity)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x1c); // Entity Metadata packet
+ Pkt.WriteVarInt(a_Entity.GetUniqueID());
+ Pkt.WriteEntityMetadata(a_Entity);
+ Pkt.WriteByte(0x7f); // The termination byte
+}
+
+
+
+
+
+void cProtocol180::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x1D); // Entity Effect packet
+ Pkt.WriteVarInt(a_Entity.GetUniqueID());
+ Pkt.WriteByte(a_EffectID);
+ Pkt.WriteByte(a_Amplifier);
+ Pkt.WriteVarInt((UInt32)a_Duration);
+ Pkt.WriteBool(false); // Hide particles
+}
+
+
+
+
+
+void cProtocol180::SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x1e);
+ Pkt.WriteVarInt(a_Entity.GetUniqueID());
+ Pkt.WriteByte(a_EffectID);
+}
+
+
+
+
+
+void cProtocol180::SendEntityProperties(const cEntity & a_Entity)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x20); // Entity Properties packet
+ Pkt.WriteVarInt(a_Entity.GetUniqueID());
+ Pkt.WriteEntityProperties(a_Entity);
+}
+
+
+
+
+
+void cProtocol180::SendKeepAlive(int a_PingID)
+{
+ // Drop the packet if the protocol is not in the Game state yet (caused a client crash):
+ if (m_State != 3)
+ {
+ LOGWARNING("Trying to send a KeepAlive packet to a player who's not yet fully logged in (%d). The protocol class prevented the packet.", m_State);
+ return;
+ }
+
+ cPacketizer Pkt(*this, 0x00); // Keep Alive packet
+ Pkt.WriteVarInt(a_PingID);
+}
+
+
+
+
+
+void cProtocol180::SendHealth(void)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x06); // Update Health packet
+ cPlayer * Player = m_Client->GetPlayer();
+ Pkt.WriteFloat((float)Player->GetHealth());
+ Pkt.WriteVarInt((UInt32)Player->GetFoodLevel());
+ Pkt.WriteFloat((float)Player->GetFoodSaturationLevel());
+}
+
+
+
+
+
+void cProtocol180::SendExperience(void)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x1f); // Experience Packet
+ cPlayer * Player = m_Client->GetPlayer();
+ Pkt.WriteFloat(Player->GetXpPercentage());
+ Pkt.WriteVarInt((UInt32)Player->GetXpLevel());
+ Pkt.WriteVarInt((UInt32)Player->GetCurrentXp());
+}
+
+
+
+
+
+void cProtocol180::SendPaintingSpawn(const cPainting & a_Painting)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x10); // Spawn Painting packet
+ Pkt.WriteVarInt(a_Painting.GetUniqueID());
+ Pkt.WriteString(a_Painting.GetName().c_str());
+ Pkt.WritePosition(Vector3i(a_Painting.GetPosX(), a_Painting.GetPosY(), a_Painting.GetPosZ()));
+ Pkt.WriteChar(a_Painting.GetDirection());
+}
+
+
+
+
+
+void cProtocol180::SendPluginMessage(const AString & a_Channel, const AString & a_Message)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ /*cPacketizer Pkt(*this, 0x3f);
+ Pkt.WriteString(a_Channel);
+ Pkt.WriteBuf(a_Message.data(), a_Message.size());*/
+}
+
+
+
+
+
+void cProtocol180::SendUnloadChunk(int a_ChunkX, int a_ChunkZ)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x21); // Chunk Data packet
+ Pkt.WriteInt(a_ChunkX);
+ Pkt.WriteInt(a_ChunkZ);
+ Pkt.WriteBool(true);
+ Pkt.WriteShort(0); // Primary bitmap
+ Pkt.WriteVarInt(0); // Data size
+}
+
+
+
+
+
+void cProtocol180::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer)
+{
+ 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);
+
+ cPacketizer Pkt(*this, 0x21); // Chunk Data packet
+ Pkt.WriteInt(a_ChunkX);
+ Pkt.WriteInt(a_ChunkZ);
+ Pkt.WriteBuf(ChunkData.data(), ChunkData.size());*/
+}
+
+
+
+
+
void cProtocol180::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
ASSERT(m_State == 3); // In game mode?
@@ -64,7 +417,7 @@ void cProtocol180::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockV
{
ASSERT(m_State == 3); // In game mode?
- cPacketizer Pkt(*this, 0x22); // Multi Block Change packet
+ /*cPacketizer Pkt(*this, 0x22); // Multi Block Change packet
Pkt.WriteInt(a_ChunkX);
Pkt.WriteInt(a_ChunkZ);
Pkt.WriteVarInt((UInt32)a_Changes.size());
@@ -75,7 +428,7 @@ void cProtocol180::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockV
UInt32 Block = ((UInt32)itr->BlockType << 4) | ((UInt32)itr->BlockMeta & 15);
Pkt.WriteVarInt(Block);
- } // for itr - a_Changes[]
+ } // for itr - a_Changes[]*/
}
@@ -204,10 +557,10 @@ void cProtocol180::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum
{
ASSERT(m_State == 3); // In game mode?
- cPacketizer Pkt(*this, 0x04); // Entity Equipment packet
+ /*cPacketizer Pkt(*this, 0x04); // Entity Equipment packet
Pkt.WriteVarInt((UInt32)a_Entity.GetUniqueID());
Pkt.WriteShort(a_SlotNum);
- Pkt.WriteItem(a_Item);
+ Pkt.WriteItem(a_Item);*/
}
@@ -245,6 +598,50 @@ void cProtocol180::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
+void cProtocol180::HandlePacketClientStatus(cByteBuffer & a_ByteBuffer)
+{
+ HANDLE_READ(a_ByteBuffer, ReadChar, char, ActionID);
+ switch (ActionID)
+ {
+ case 0:
+ {
+ // Respawn
+ m_Client->HandleRespawn();
+ break;
+ }
+ case 1:
+ {
+ // Request stats
+ const cStatManager & Manager = m_Client->GetPlayer()->GetStatManager();
+ SendStatistics(Manager);
+
+ break;
+ }
+ case 2:
+ {
+ // Open Inventory achievement
+ m_Client->GetPlayer()->AwardAchievement(achOpenInv);
+ break;
+ }
+ }
+}
+
+
+
+
+
+void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer)
+{
+ HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel);
+ AString Data;
+ a_ByteBuffer.ReadAll(Data);
+ m_Client->HandlePluginMessage(Channel, Data);
+}
+
+
+
+
+
void cProtocol180::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer)
{
cServer * Server = cRoot::Get()->GetServer();
@@ -383,3 +780,119 @@ void cProtocol180::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffe
+
+void cProtocol180::HandlePacketSteerVehicle(cByteBuffer & a_ByteBuffer)
+{
+ HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Forward);
+ HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Sideways);
+ HANDLE_READ(a_ByteBuffer, ReadChar, char, Flags);
+
+ if ((Flags & 0x2) != 0)
+ {
+ m_Client->HandleUnmount();
+ }
+ else if ((Flags & 0x1) != 0)
+ {
+ m_Client->HandleSteerVehicle(Forward, Sideways);
+ }
+}
+
+
+
+
+
+void cProtocol180::HandlePacketEntityAction(cByteBuffer & a_ByteBuffer)
+{
+ HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, PlayerID);
+ HANDLE_READ(a_ByteBuffer, ReadChar, char, Action);
+ HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, JumpBoost);
+
+ switch (Action)
+ {
+ case 0: m_Client->HandleEntityCrouch(PlayerID, true); break; // Crouch
+ case 1: m_Client->HandleEntityCrouch(PlayerID, false); break; // Uncrouch
+ case 2: m_Client->HandleEntityLeaveBed(PlayerID); break; // Leave Bed
+ case 3: m_Client->HandleEntitySprinting(PlayerID, true); break; // Start sprinting
+ case 4: m_Client->HandleEntitySprinting(PlayerID, false); break; // Stop sprinting
+ }
+}
+
+
+
+
+
+void cProtocol180::HandlePacketUseEntity(cByteBuffer & a_ByteBuffer)
+{
+ HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, EntityID);
+ HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, Type);
+
+ switch (Type)
+ {
+ case 0:
+ {
+ m_Client->HandleUseEntity((int)EntityID, false);
+ break;
+ }
+ case 1:
+ {
+ m_Client->HandleUseEntity((int)EntityID, true);
+ break;
+ }
+ case 2:
+ {
+ HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, TargetX);
+ HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, TargetY);
+ HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, TargetZ);
+
+ // TODO: Do anything
+ break;
+ }
+ default:
+ {
+ ASSERT(!"Unhandled use entity type!");
+ return;
+ }
+ }
+}
+
+
+
+
+
+void cProtocol180::HandlePacketKeepAlive(cByteBuffer & a_ByteBuffer)
+{
+ HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, KeepAliveID);
+ m_Client->HandleKeepAlive((int)KeepAliveID);
+}
+
+
+
+
+
+void cProtocol180::HandlePacketPlayerPos(cByteBuffer & a_ByteBuffer)
+{
+ HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosX);
+ HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosY);
+ HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ);
+ HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround);
+ m_Client->HandlePlayerPos(PosX, PosY, PosZ, PosY + 1.62, IsOnGround);
+}
+
+
+
+
+
+void cProtocol180::HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer)
+{
+ HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosX);
+ HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosY);
+ HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ);
+ HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Yaw);
+ HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Pitch);
+ HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround);
+ m_Client->HandlePlayerMoveLook(PosX, PosY, PosZ, PosY + 1.62, Yaw, Pitch, IsOnGround);
+}
+
+
+
+
diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h
index 11a376b17..6604cbc3e 100644
--- a/src/Protocol/Protocol18x.h
+++ b/src/Protocol/Protocol18x.h
@@ -54,6 +54,32 @@ public:
cProtocol180(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State);
+ 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;
+ virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override;
+ virtual void SendEntityVelocity (const cEntity & a_Entity) override;
+ virtual void SendDestroyEntity (const cEntity & a_Entity) override;
+ virtual void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override;
+ virtual void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override;
+ virtual void SendEntityLook(const cEntity & a_Entity) override;
+ virtual void SendTeleportEntity(const cEntity & a_Entity) override;
+ virtual void SendEntityHeadLook(const cEntity & a_Entity) override;
+ virtual void SendEntityMetadata(const cEntity & a_Entity) override;
+ virtual void SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) override;
+ virtual void SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID) override;
+ virtual void SendEntityProperties(const cEntity & a_Entity) override;
+ virtual void SendKeepAlive(int a_PingID) override;
+ virtual void SendHealth(void) override;
+ virtual void SendExperience(void) override;
+ virtual void SendPaintingSpawn(const cPainting & a_Painting) override;
+ virtual void SendPluginMessage(const AString & a_Channel, const AString & a_Message) override;
+ virtual void SendUnloadChunk(int a_ChunkX, int a_ChunkZ) override;
+ virtual void SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
virtual void SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
virtual void SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override;
virtual void SendChat(const AString & a_Message) override;
@@ -69,6 +95,16 @@ protected:
// Packet handlers while in the Login state (m_State == 2):
virtual void HandlePacketLoginStart(cByteBuffer & a_ByteBuffer) override;
virtual void HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer) override;
+
+ // Packet handlers while in the Game state (m_State == 3):
+ virtual void HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) override;
+ virtual void HandlePacketClientStatus(cByteBuffer & a_ByteBuffer) override;
+ virtual void HandlePacketSteerVehicle(cByteBuffer & a_ByteBuffer) override;
+ virtual void HandlePacketEntityAction(cByteBuffer & a_ByteBuffer) override;
+ virtual void HandlePacketUseEntity(cByteBuffer & a_ByteBuffer) override;
+ virtual void HandlePacketKeepAlive(cByteBuffer & a_ByteBuffer) override;
+ virtual void HandlePacketPlayerPos(cByteBuffer & a_ByteBuffer) override;
+ virtual void HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer) override;
} ;