From 07fba5c98ec94f98b742e8aa76dcec5572bfcecb Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 4 Sep 2014 03:22:35 +0200 Subject: Added more 1.8 protocol things. --- src/Protocol/ChunkDataSerializer.cpp | 64 +++++ src/Protocol/ChunkDataSerializer.h | 4 +- src/Protocol/Protocol17x.cpp | 1 + src/Protocol/Protocol17x.h | 18 +- src/Protocol/Protocol18x.cpp | 523 ++++++++++++++++++++++++++++++++++- src/Protocol/Protocol18x.h | 36 +++ 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; } ; -- cgit v1.2.3