Fixed more 1.8 packets.
This commit is contained in:
parent
38124bcce3
commit
8f8693a71e
@ -489,6 +489,24 @@ bool cByteBuffer::ReadLEInt(int & a_Value)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cByteBuffer::ReadPosition(int & a_BlockX, int & a_BlockY, int & a_BlockZ)
|
||||||
|
{
|
||||||
|
Int64 Value;
|
||||||
|
if (!ReadBEInt64(Value))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
a_BlockX = Value >> 38;
|
||||||
|
a_BlockY = Value << 26 >> 52;
|
||||||
|
a_BlockZ = Value << 38 >> 38;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cByteBuffer::WriteChar(char a_Value)
|
bool cByteBuffer::WriteChar(char a_Value)
|
||||||
{
|
{
|
||||||
CHECK_THREAD;
|
CHECK_THREAD;
|
||||||
@ -661,6 +679,15 @@ bool cByteBuffer::WriteLEInt(int a_Value)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cByteBuffer::WritePosition(int a_BlockX, int a_BlockY, int a_BlockZ)
|
||||||
|
{
|
||||||
|
return WriteBEInt64(((Int64)a_BlockX & 0x3FFFFFF) << 38 | ((Int64)a_BlockY & 0xFFF) << 26 | ((Int64)a_BlockZ & 0x3FFFFFF));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cByteBuffer::ReadBuf(void * a_Buffer, size_t a_Count)
|
bool cByteBuffer::ReadBuf(void * a_Buffer, size_t a_Count)
|
||||||
{
|
{
|
||||||
CHECK_THREAD;
|
CHECK_THREAD;
|
||||||
@ -792,6 +819,23 @@ bool cByteBuffer::SkipRead(size_t a_Count)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cByteBuffer::ReverseRead(size_t a_Count)
|
||||||
|
{
|
||||||
|
CHECK_THREAD;
|
||||||
|
CheckValid();
|
||||||
|
if (m_ReadPos < a_Count)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_ReadPos -= a_Count;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cByteBuffer::ReadAll(AString & a_Data)
|
void cByteBuffer::ReadAll(AString & a_Data)
|
||||||
{
|
{
|
||||||
CHECK_THREAD;
|
CHECK_THREAD;
|
||||||
|
@ -64,6 +64,7 @@ public:
|
|||||||
bool ReadVarInt (UInt32 & a_Value);
|
bool ReadVarInt (UInt32 & a_Value);
|
||||||
bool ReadVarUTF8String (AString & a_Value); // string length as VarInt, then string as UTF-8
|
bool ReadVarUTF8String (AString & a_Value); // string length as VarInt, then string as UTF-8
|
||||||
bool ReadLEInt (int & a_Value);
|
bool ReadLEInt (int & a_Value);
|
||||||
|
bool ReadPosition (int & a_BlockX, int & a_BlockY, int & a_BlockZ);
|
||||||
|
|
||||||
/** Reads VarInt, assigns it to anything that can be assigned from an UInt32 (unsigned short, char, Byte, double, ...) */
|
/** Reads VarInt, assigns it to anything that can be assigned from an UInt32 (unsigned short, char, Byte, double, ...) */
|
||||||
template <typename T> bool ReadVarInt(T & a_Value)
|
template <typename T> bool ReadVarInt(T & a_Value)
|
||||||
@ -90,6 +91,7 @@ public:
|
|||||||
bool WriteVarInt (UInt32 a_Value);
|
bool WriteVarInt (UInt32 a_Value);
|
||||||
bool WriteVarUTF8String (const AString & a_Value); // string length as VarInt, then string as UTF-8
|
bool WriteVarUTF8String (const AString & a_Value); // string length as VarInt, then string as UTF-8
|
||||||
bool WriteLEInt (int a_Value);
|
bool WriteLEInt (int a_Value);
|
||||||
|
bool WritePosition (int a_BlockX, int a_BlockY, int a_BlockZ);
|
||||||
|
|
||||||
/** Reads a_Count bytes into a_Buffer; returns true if successful */
|
/** Reads a_Count bytes into a_Buffer; returns true if successful */
|
||||||
bool ReadBuf(void * a_Buffer, size_t a_Count);
|
bool ReadBuf(void * a_Buffer, size_t a_Count);
|
||||||
@ -105,6 +107,9 @@ public:
|
|||||||
|
|
||||||
/** Skips reading by a_Count bytes; returns false if not enough bytes in the ringbuffer */
|
/** Skips reading by a_Count bytes; returns false if not enough bytes in the ringbuffer */
|
||||||
bool SkipRead(size_t a_Count);
|
bool SkipRead(size_t a_Count);
|
||||||
|
|
||||||
|
/** Reverse reading by a_Count bytes; returns false if not enough readed bytes in the ringbuffer */
|
||||||
|
bool ReverseRead(size_t a_Count);
|
||||||
|
|
||||||
/** Reads all available data into a_Data */
|
/** Reads all available data into a_Data */
|
||||||
void ReadAll(AString & a_Data);
|
void ReadAll(AString & a_Data);
|
||||||
|
@ -1198,6 +1198,12 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
|
|||||||
|
|
||||||
cWorld * World = m_Player->GetWorld();
|
cWorld * World = m_Player->GetWorld();
|
||||||
|
|
||||||
|
// 1.8 protocol fix
|
||||||
|
if ((int)a_BlockFace == 255)
|
||||||
|
{
|
||||||
|
a_BlockFace = BLOCK_FACE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(a_BlockFace != BLOCK_FACE_NONE) && // The client is interacting with a specific block
|
(a_BlockFace != BLOCK_FACE_NONE) && // The client is interacting with a specific block
|
||||||
(
|
(
|
||||||
@ -1268,22 +1274,25 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BLOCKTYPE BlockType;
|
if ((Vector3d(a_BlockX, a_BlockY, a_BlockZ) - m_Player->GetPosition()).Length() <= 5)
|
||||||
NIBBLETYPE BlockMeta;
|
|
||||||
World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta);
|
|
||||||
cBlockHandler * BlockHandler = cBlockInfo::GetHandler(BlockType);
|
|
||||||
|
|
||||||
if (BlockHandler->IsUseable() && !m_Player->IsCrouched())
|
|
||||||
{
|
{
|
||||||
if (PlgMgr->CallHookPlayerUsingBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta))
|
BLOCKTYPE BlockType;
|
||||||
|
NIBBLETYPE BlockMeta;
|
||||||
|
World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, BlockType, BlockMeta);
|
||||||
|
cBlockHandler * BlockHandler = cBlockInfo::GetHandler(BlockType);
|
||||||
|
|
||||||
|
if (BlockHandler->IsUseable() && !m_Player->IsCrouched())
|
||||||
{
|
{
|
||||||
// A plugin doesn't agree with using the block, abort
|
if (PlgMgr->CallHookPlayerUsingBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta))
|
||||||
|
{
|
||||||
|
// A plugin doesn't agree with using the block, abort
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cChunkInterface ChunkInterface(World->GetChunkMap());
|
||||||
|
BlockHandler->OnUse(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ);
|
||||||
|
PlgMgr->CallHookPlayerUsedBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cChunkInterface ChunkInterface(World->GetChunkMap());
|
|
||||||
BlockHandler->OnUse(ChunkInterface, *World, m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ);
|
|
||||||
PlgMgr->CallHookPlayerUsedBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ, BlockType, BlockMeta);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
short EquippedDamage = Equipped.m_ItemDamage;
|
short EquippedDamage = Equipped.m_ItemDamage;
|
||||||
|
@ -1567,7 +1567,7 @@ void cProtocol172::AddReceivedData(const char * a_Data, size_t a_Size)
|
|||||||
PacketType, PacketType, PacketLen, PacketLen, m_State, PacketDataHex.c_str()
|
PacketType, PacketType, PacketLen, PacketLen, m_State, PacketDataHex.c_str()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!HandlePacket(bb, PacketType))
|
if (!HandlePacket(bb, PacketType))
|
||||||
{
|
{
|
||||||
// Unknown packet, already been reported, but without the length. Log the length here:
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bb.GetReadableSpace() != 1)
|
if (bb.GetReadableSpace() != 1)
|
||||||
{
|
{
|
||||||
// Read more or less than packet length, report as error
|
// 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);
|
m_Client->PacketError(PacketType);
|
||||||
}
|
}
|
||||||
} // for (ever)
|
} // for (ever)
|
||||||
|
|
||||||
// Log any leftover bytes into the logfile:
|
// Log any leftover bytes into the logfile:
|
||||||
if (g_ShouldLogCommIn && (m_ReceivedData.GetReadableSpace() > 0))
|
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 Metadata;
|
||||||
AString Uncompressed;
|
if (a_IsCompressed)
|
||||||
if (UncompressStringGZIP(a_Metadata.data(), a_Metadata.size(), Uncompressed) != Z_OK)
|
|
||||||
{
|
{
|
||||||
AString HexDump;
|
// Uncompress the GZIPped data:
|
||||||
CreateHexDump(HexDump, a_Metadata.data(), a_Metadata.size(), 16);
|
if (UncompressStringGZIP(a_Metadata.data(), a_Metadata.size(), Metadata) != Z_OK)
|
||||||
LOGWARNING("Cannot unGZIP item metadata (" SIZE_T_FMT " bytes):\n%s", a_Metadata.size(), HexDump.c_str());
|
{
|
||||||
return;
|
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:
|
// Parse into NBT:
|
||||||
cParsedNBT NBT(Uncompressed.data(), Uncompressed.size());
|
cParsedNBT NBT(Metadata.data(), Metadata.size());
|
||||||
if (!NBT.IsValid())
|
if (!NBT.IsValid())
|
||||||
{
|
{
|
||||||
AString HexDump;
|
AString HexDump;
|
||||||
CreateHexDump(HexDump, Uncompressed.data(), Uncompressed.size(), 16);
|
CreateHexDump(HexDump, Metadata.data(), Metadata.size(), 16);
|
||||||
LOGWARNING("Cannot parse NBT item metadata: (" SIZE_T_FMT " bytes)\n%s", Uncompressed.size(), HexDump.c_str());
|
LOGWARNING("Cannot parse NBT item metadata: (" SIZE_T_FMT " bytes)\n%s", Metadata.size(), HexDump.c_str());
|
||||||
return;
|
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))
|
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;
|
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);
|
cFireworkItem::WriteToNBTCompound(a_Item.m_FireworkItem, Writer, (ENUM_ITEM_ID)a_Item.m_ItemType);
|
||||||
}
|
}
|
||||||
Writer.Finish();
|
Writer.Finish();
|
||||||
AString Compressed;
|
|
||||||
CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed);
|
AString Result = Writer.GetResult();
|
||||||
WriteShort((short)Compressed.size());
|
if (m_Protocol.GetProtocolVersion() == cProtocolRecognizer::PROTO_VERSION_1_8_0)
|
||||||
WriteBuf(Compressed.data(), Compressed.size());
|
{
|
||||||
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -200,9 +200,9 @@ protected:
|
|||||||
m_Out.WriteVarUTF8String(a_Value);
|
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)
|
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):
|
// Packet handlers while in the Game state (m_State == 3):
|
||||||
void HandlePacketAnimation (cByteBuffer & a_ByteBuffer);
|
void HandlePacketAnimation (cByteBuffer & a_ByteBuffer);
|
||||||
void HandlePacketBlockDig (cByteBuffer & a_ByteBuffer);
|
virtual void HandlePacketBlockDig (cByteBuffer & a_ByteBuffer);
|
||||||
void HandlePacketBlockPlace (cByteBuffer & a_ByteBuffer);
|
virtual void HandlePacketBlockPlace (cByteBuffer & a_ByteBuffer);
|
||||||
void HandlePacketChatMessage (cByteBuffer & a_ByteBuffer);
|
void HandlePacketChatMessage (cByteBuffer & a_ByteBuffer);
|
||||||
virtual void HandlePacketClientSettings (cByteBuffer & a_ByteBuffer);
|
virtual void HandlePacketClientSettings (cByteBuffer & a_ByteBuffer);
|
||||||
virtual void HandlePacketClientStatus (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 HandlePacketEntityAction (cByteBuffer & a_ByteBuffer);
|
||||||
virtual void HandlePacketKeepAlive (cByteBuffer & a_ByteBuffer);
|
virtual void HandlePacketKeepAlive (cByteBuffer & a_ByteBuffer);
|
||||||
void HandlePacketPlayer (cByteBuffer & a_ByteBuffer);
|
void HandlePacketPlayer (cByteBuffer & a_ByteBuffer);
|
||||||
@ -306,10 +306,10 @@ protected:
|
|||||||
void SendCompass(const cWorld & a_World);
|
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 */
|
/** 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. */
|
/** 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);
|
void StartEncryption(const Byte * a_Key);
|
||||||
|
|
||||||
|
@ -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...
|
const int MAX_ENC_LEN = 512; // Maximum size of the encrypted message; should be 128, but who knows...
|
||||||
class cProtocol176;
|
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)
|
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?
|
ASSERT(m_State == 3); // In game mode?
|
||||||
|
|
||||||
cPacketizer Pkt(*this, 0x28); // Effect packet
|
cPacketizer Pkt(*this, 0x28); // Effect packet
|
||||||
Pkt.WriteInt(a_EffectID);
|
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.WriteInt(a_Data);
|
||||||
Pkt.WriteBool(false);
|
Pkt.WriteBool(false);
|
||||||
}
|
}
|
||||||
@ -144,7 +229,7 @@ void cProtocol180::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_Bloc
|
|||||||
|
|
||||||
cPacketizer Pkt(*this, 0x0a);
|
cPacketizer Pkt(*this, 0x0a);
|
||||||
Pkt.WriteVarInt(a_Entity.GetUniqueID());
|
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?
|
ASSERT(m_State == 3); // In game mode?
|
||||||
|
|
||||||
cPacketizer Pkt(*this, 0x23); // Block Change packet
|
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);
|
UInt32 Block = ((UInt32)a_BlockType << 4) | ((UInt32)a_BlockMeta & 15);
|
||||||
Pkt.WriteVarInt(Block);
|
Pkt.WriteVarInt(Block);
|
||||||
@ -624,8 +709,7 @@ void cProtocol180::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
|
|||||||
// Send the spawn position:
|
// Send the spawn position:
|
||||||
{
|
{
|
||||||
cPacketizer Pkt(*this, 0x05); // Spawn Position packet
|
cPacketizer Pkt(*this, 0x05); // Spawn Position packet
|
||||||
Vector3i Position(a_World.GetSpawnX(), a_World.GetSpawnY(), a_World.GetSpawnZ());
|
Pkt.WritePosition(a_World.GetSpawnX(), a_World.GetSpawnY(), a_World.GetSpawnZ());
|
||||||
Pkt.WritePosition(Position);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send player abilities:
|
// 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)
|
void cProtocol180::HandlePacketClientStatus(cByteBuffer & a_ByteBuffer)
|
||||||
{
|
{
|
||||||
HANDLE_READ(a_ByteBuffer, ReadChar, char, ActionID);
|
HANDLE_READ(a_ByteBuffer, ReadChar, char, ActionID);
|
||||||
@ -672,7 +811,10 @@ void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer)
|
|||||||
{
|
{
|
||||||
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel);
|
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel);
|
||||||
AString Data;
|
AString Data;
|
||||||
a_ByteBuffer.ReadAll(Data);
|
if (!a_ByteBuffer.ReadString(Data, a_ByteBuffer.GetReadableSpace() - 1))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
m_Client->HandlePluginMessage(Channel, Data);
|
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, ReadVarUTF8String, AString, Locale);
|
||||||
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ViewDistance);
|
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ViewDistance);
|
||||||
HANDLE_READ(a_ByteBuffer, ReadByte, Byte, ChatFlags);
|
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);
|
HANDLE_READ(a_ByteBuffer, ReadChar, char, SkinFlags);
|
||||||
|
|
||||||
m_Client->SetLocale(Locale);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,12 +54,12 @@ public:
|
|||||||
|
|
||||||
cProtocol180(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State);
|
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 SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override;
|
||||||
virtual void SendLoginSuccess (void) override;
|
virtual void SendLoginSuccess (void) override;
|
||||||
virtual void SendPickupSpawn (const cPickup & a_Pickup) 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 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 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 SendPlayerMoveLook (void) override;
|
||||||
virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override;
|
virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override;
|
||||||
@ -92,6 +92,8 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item) override;
|
||||||
|
|
||||||
virtual void HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) override;
|
virtual void HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) override;
|
||||||
|
|
||||||
// Packet handlers while in the Login state (m_State == 2):
|
// Packet handlers while in the Login state (m_State == 2):
|
||||||
@ -99,6 +101,7 @@ protected:
|
|||||||
virtual void HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer) override;
|
virtual void HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer) override;
|
||||||
|
|
||||||
// Packet handlers while in the Game state (m_State == 3):
|
// 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 HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) override;
|
||||||
virtual void HandlePacketClientStatus(cByteBuffer & a_ByteBuffer) override;
|
virtual void HandlePacketClientStatus(cByteBuffer & a_ByteBuffer) override;
|
||||||
virtual void HandlePacketSteerVehicle(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 HandlePacketPlayerPos(cByteBuffer & a_ByteBuffer) override;
|
||||||
virtual void HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer) override;
|
virtual void HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer) override;
|
||||||
virtual void HandlePacketClientSettings(cByteBuffer & a_ByteBuffer) override;
|
virtual void HandlePacketClientSettings(cByteBuffer & a_ByteBuffer) override;
|
||||||
|
virtual void HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer) override;
|
||||||
|
virtual void HandlePacketBlockDig(cByteBuffer & a_ByteBuffer);
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user