diff options
author | Tiger Wang <ziwei.tiger@outlook.com> | 2020-07-20 10:56:27 +0200 |
---|---|---|
committer | Tiger Wang <ziwei.tiger@outlook.com> | 2020-07-26 19:55:16 +0200 |
commit | 99f8c4434246c3483436b1abac917cf3f23ddbc2 (patch) | |
tree | 866c1ad86ac7fc8ca243f5261fca47e6f737e792 /src/Protocol | |
parent | Remove redundant ErasePowerData call (diff) | |
download | cuberite-99f8c4434246c3483436b1abac917cf3f23ddbc2.tar cuberite-99f8c4434246c3483436b1abac917cf3f23ddbc2.tar.gz cuberite-99f8c4434246c3483436b1abac917cf3f23ddbc2.tar.bz2 cuberite-99f8c4434246c3483436b1abac917cf3f23ddbc2.tar.lz cuberite-99f8c4434246c3483436b1abac917cf3f23ddbc2.tar.xz cuberite-99f8c4434246c3483436b1abac917cf3f23ddbc2.tar.zst cuberite-99f8c4434246c3483436b1abac917cf3f23ddbc2.zip |
Diffstat (limited to '')
-rw-r--r-- | src/Protocol/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/Protocol/ChunkDataSerializer.cpp | 118 | ||||
-rw-r--r-- | src/Protocol/ChunkDataSerializer.h | 7 | ||||
-rw-r--r-- | src/Protocol/Packetizer.h | 14 | ||||
-rw-r--r-- | src/Protocol/Protocol.h | 3 | ||||
-rw-r--r-- | src/Protocol/ProtocolRecognizer.cpp | 18 | ||||
-rw-r--r-- | src/Protocol/Protocol_1_11.cpp | 2 | ||||
-rw-r--r-- | src/Protocol/Protocol_1_12.cpp | 2 | ||||
-rw-r--r-- | src/Protocol/Protocol_1_12.h | 1 | ||||
-rw-r--r-- | src/Protocol/Protocol_1_13.cpp | 27 | ||||
-rw-r--r-- | src/Protocol/Protocol_1_13.h | 26 | ||||
-rw-r--r-- | src/Protocol/Protocol_1_14.cpp | 305 | ||||
-rw-r--r-- | src/Protocol/Protocol_1_14.h | 59 | ||||
-rw-r--r-- | src/Protocol/Protocol_1_8.cpp | 26 | ||||
-rw-r--r-- | src/Protocol/Protocol_1_8.h | 2 | ||||
-rw-r--r-- | src/Protocol/Protocol_1_9.cpp | 12 |
16 files changed, 560 insertions, 64 deletions
diff --git a/src/Protocol/CMakeLists.txt b/src/Protocol/CMakeLists.txt index f3d0e1901..fc7366efc 100644 --- a/src/Protocol/CMakeLists.txt +++ b/src/Protocol/CMakeLists.txt @@ -12,6 +12,7 @@ target_sources( Protocol_1_11.cpp Protocol_1_12.cpp Protocol_1_13.cpp + Protocol_1_14.cpp ProtocolRecognizer.cpp RecipeMapper.cpp @@ -27,6 +28,7 @@ target_sources( Protocol_1_11.h Protocol_1_12.h Protocol_1_13.h + Protocol_1_14.h ProtocolRecognizer.h RecipeMapper.h ) diff --git a/src/Protocol/ChunkDataSerializer.cpp b/src/Protocol/ChunkDataSerializer.cpp index 6577aaedd..d4e23f11f 100644 --- a/src/Protocol/ChunkDataSerializer.cpp +++ b/src/Protocol/ChunkDataSerializer.cpp @@ -5,10 +5,12 @@ #include "Protocol_1_9.h" #include "../ByteBuffer.h" #include "../ClientHandle.h" +#include "../WorldStorage/FastNBT.h" #include "Palettes/Upgrade.h" #include "Palettes/Palette_1_13.h" #include "Palettes/Palette_1_13_1.h" +#include "Palettes/Palette_1_14.h" @@ -102,6 +104,11 @@ void cChunkDataSerializer::SendToClients(const std::unordered_set<cClientHandle Serialize393<&Palette_1_13_1::FromBlock>(Entry.second); continue; } + case cProtocol::Version::Version_1_14: + { + Serialize477(Entry.second); + continue; + } } LOGERROR("cChunkDataSerializer::Serialize(): Unknown version: %d", Entry.first); @@ -497,6 +504,117 @@ void cChunkDataSerializer::Serialize393(const std::vector<cClientHandle *> & a_S +void cChunkDataSerializer::Serialize477(const std::vector<cClientHandle *> & a_SendTo) +{ + // This function returns the fully compressed packet (including packet size), not the raw packet! + + // Create the packet: + cByteBuffer Packet(512 KiB); + Packet.WriteVarInt32(0x21); // Packet id (Chunk Data packet) + Packet.WriteBEInt32(m_ChunkX); + Packet.WriteBEInt32(m_ChunkZ); + Packet.WriteBool(true); // "Ground-up continuous", or rather, "biome data present" flag + Packet.WriteVarInt32(m_Data.GetSectionBitmask()); + + { + cFastNBTWriter Writer; + // TODO: client works fine without? + // std::array<Int64, 36> Longz = {}; + // Writer.AddLongArray("MOTION_BLOCKING", Longz.data(), Longz.size()); + Writer.Finish(); + Packet.Write(Writer.GetResult().data(), Writer.GetResult().size()); + } + + // Write the chunk size in bytes: + const UInt8 BitsPerEntry = 14; + const size_t Mask = (1 << BitsPerEntry) - 1; + const size_t ChunkSectionDataArraySize = (cChunkData::SectionBlockCount * BitsPerEntry) / 8 / 8; + const size_t ChunkSectionSize = ( + 2 + // Block count, BEInt16, 2 bytes + 1 + // Bits per entry, BEUInt8, 1 byte + Packet.GetVarIntSize(static_cast<UInt32>(ChunkSectionDataArraySize)) + // Field containing "size of whole section", VarInt32, variable size + ChunkSectionDataArraySize * 8 // Actual section data, lots of bytes (multiplier 1 long = 8 bytes) + ); + + const size_t BiomeDataSize = cChunkDef::Width * cChunkDef::Width; + const size_t ChunkSize = ( + ChunkSectionSize * m_Data.NumPresentSections() + + BiomeDataSize * 4 // Biome data now BE ints + ); + Packet.WriteVarInt32(static_cast<UInt32>(ChunkSize)); + + // Write each chunk section... + ForEachSection(m_Data, [&](const cChunkData::sChunkSection & a_Section) + { + Packet.WriteBEInt16(-1); + Packet.WriteBEUInt8(BitsPerEntry); + Packet.WriteVarInt32(static_cast<UInt32>(ChunkSectionDataArraySize)); + WriteSectionDataSeamless(Packet, a_Section, BitsPerEntry); + } + ); + + // Write the biome data + for (size_t i = 0; i != BiomeDataSize; i++) + { + Packet.WriteBEUInt32(static_cast<UInt32>(m_BiomeData[i]) & 0xff); + } + + // Identify 1.9.4's tile entity list as empty + Packet.WriteVarInt32(0); + + CompressAndSend(Packet, a_SendTo); +} + + + + + +void cChunkDataSerializer::WriteSectionDataSeamless(cByteBuffer & a_Packet, const cChunkData::sChunkSection & a_Section, const UInt8 a_BitsPerEntry) +{ + // https://wiki.vg/Chunk_Format#Data_structure + + // We shift a UInt64 by a_BitsPerEntry, the latter cannot be too big: + ASSERT(a_BitsPerEntry < 64); + + UInt64 Buffer = 0; // A buffer to compose multiple smaller bitsizes into one 64-bit number + unsigned char BitIndex = 0; // The bit-position in Buffer that represents where to write next + + for (size_t Index = 0; Index != cChunkData::SectionBlockCount; Index++) + { + const UInt32 BlockType = a_Section.m_BlockTypes[Index]; + const UInt32 BlockMeta = (a_Section.m_BlockMetas[Index / 2] >> ((Index % 2) * 4)) & 0x0f; + const UInt32 Value = Palette_1_14::FromBlock(PaletteUpgrade::FromBlock(BlockType, BlockMeta)); + + // Write as much as possible of Value, starting from BitIndex, into Buffer: + Buffer |= static_cast<UInt64>(Value) << BitIndex; + + // The _signed_ count of bits in Value left to write + const char Remaining = a_BitsPerEntry - (64 - BitIndex); + if (Remaining >= 0) + { + // There were some bits remaining: we've filled the buffer. Flush it: + a_Packet.WriteBEUInt64(Buffer); + + // And write the remaining bits, setting the new BitIndex: + Buffer = Value >> (a_BitsPerEntry - Remaining); + BitIndex = Remaining; + } + else + { + // It fit, sexcellent. + BitIndex += a_BitsPerEntry; + } + } + + static_assert((cChunkData::SectionBlockCount % 64) == 0, "Section must fit wholly into a 64-bit long array"); + ASSERT(BitIndex == 0); + ASSERT(Buffer == 0); +} + + + + + void cChunkDataSerializer::CompressAndSend(cByteBuffer & a_Packet, const std::vector<cClientHandle *> & a_SendTo) { AString PacketData; diff --git a/src/Protocol/ChunkDataSerializer.h b/src/Protocol/ChunkDataSerializer.h index ed3e5c8b1..ce80cc481 100644 --- a/src/Protocol/ChunkDataSerializer.h +++ b/src/Protocol/ChunkDataSerializer.h @@ -36,9 +36,12 @@ protected: void Serialize47 (const std::vector<cClientHandle *> & a_SendTo); // Release 1.8 void Serialize107(const std::vector<cClientHandle *> & a_SendTo); // Release 1.9 void Serialize110(const std::vector<cClientHandle *> & a_SendTo); // Release 1.9.4 + template <auto Palette> void Serialize393(const std::vector<cClientHandle *> & a_SendTo); // Release 1.13 - 1.13.1 + void Serialize477(const std::vector<cClientHandle *> & a_SendTo); // Release 1.13 - 1.13.1 - template <auto Palette> - void Serialize393(const std::vector<cClientHandle *> & a_SendTo); // Release 1.13 - 1.13.1 + /** Writes all blocks in a chunk section into a series of Int64. + Writes start from the bit directly subsequent to the previous write's end, possibly crossing over to the next Int64. */ + inline void WriteSectionDataSeamless(cByteBuffer & a_Packet, const cChunkData::sChunkSection & a_Section, const UInt8 a_BitsPerEntry); /** Finalises the data, compresses it if required, and delivers it to all clients. */ void CompressAndSend(cByteBuffer & a_Packet, const std::vector<cClientHandle *> & a_SendTo); diff --git a/src/Protocol/Packetizer.h b/src/Protocol/Packetizer.h index e3a409cf0..22ef01ed9 100644 --- a/src/Protocol/Packetizer.h +++ b/src/Protocol/Packetizer.h @@ -125,10 +125,18 @@ public: } - /** Writes the specified block position as a single encoded 64-bit BigEndian integer. */ - inline void WritePosition64(int a_BlockX, int a_BlockY, int a_BlockZ) + /** Writes the specified block position as a single encoded 64-bit BigEndian integer. + The three coordinates are written in XYZ order. */ + inline void WriteXYZPosition64(int a_BlockX, int a_BlockY, int a_BlockZ) { - VERIFY(m_Out.WritePosition64(a_BlockX, a_BlockY, a_BlockZ)); + VERIFY(m_Out.WriteXYZPosition64(a_BlockX, a_BlockY, a_BlockZ)); + } + + /** Writes the specified block position as a single encoded 64-bit BigEndian integer. + The three coordinates are written in XZY order, in 1.14+. */ + inline void WriteXZYPosition64(int a_BlockX, int a_BlockY, int a_BlockZ) + { + VERIFY(m_Out.WriteXZYPosition64(a_BlockX, a_BlockY, a_BlockZ)); } /** Writes the specified angle using a single byte. */ diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index 8636c350f..1b2e74d7c 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -341,7 +341,8 @@ public: Version_1_12_2 = 340, Version_1_13 = 393, Version_1_13_1 = 401, - Version_1_13_2 = 404 // TODO: this constant should be in WebServer + Version_1_13_2 = 404, // TODO: this constant should be in WebServer + Version_1_14 = 477 }; /** Called when client sends some data */ diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index a6aa901c9..813791485 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -13,6 +13,7 @@ #include "Protocol_1_11.h" #include "Protocol_1_12.h" #include "Protocol_1_13.h" +#include "Protocol_1_14.h" #include "../ClientHandle.h" #include "../Root.h" #include "../Server.h" @@ -76,7 +77,9 @@ AString cMultiVersionProtocol::GetVersionTextFromInt(cProtocol::Version a_Protoc case cProtocol::Version::Version_1_13: return "1.13"; case cProtocol::Version::Version_1_13_1: return "1.13.1"; case cProtocol::Version::Version_1_13_2: return "1.13.2"; + case cProtocol::Version::Version_1_14: return "1.14"; } + ASSERT(!"Unknown protocol version"); return Printf("Unknown protocol (%d)", a_ProtocolVersion); } @@ -285,20 +288,21 @@ std::unique_ptr<cProtocol> cMultiVersionProtocol::TryRecognizeLengthedProtocol(c switch (static_cast<cProtocol::Version>(ProtocolVersion)) { - case cProtocol::Version::Version_1_8_0: return std::make_unique<cProtocol_1_8_0>(&a_Client, ServerAddress, ServerPort, NextState); - case cProtocol::Version::Version_1_9_0: return std::make_unique<cProtocol_1_9_0>(&a_Client, ServerAddress, ServerPort, NextState); - case cProtocol::Version::Version_1_9_1: return std::make_unique<cProtocol_1_9_1>(&a_Client, ServerAddress, ServerPort, NextState); - case cProtocol::Version::Version_1_9_2: return std::make_unique<cProtocol_1_9_2>(&a_Client, ServerAddress, ServerPort, NextState); - case cProtocol::Version::Version_1_9_4: return std::make_unique<cProtocol_1_9_4>(&a_Client, ServerAddress, ServerPort, NextState); + case cProtocol::Version::Version_1_8_0: return std::make_unique<cProtocol_1_8_0> (&a_Client, ServerAddress, ServerPort, NextState); + case cProtocol::Version::Version_1_9_0: return std::make_unique<cProtocol_1_9_0> (&a_Client, ServerAddress, ServerPort, NextState); + case cProtocol::Version::Version_1_9_1: return std::make_unique<cProtocol_1_9_1> (&a_Client, ServerAddress, ServerPort, NextState); + case cProtocol::Version::Version_1_9_2: return std::make_unique<cProtocol_1_9_2> (&a_Client, ServerAddress, ServerPort, NextState); + case cProtocol::Version::Version_1_9_4: return std::make_unique<cProtocol_1_9_4> (&a_Client, ServerAddress, ServerPort, NextState); case cProtocol::Version::Version_1_10_0: return std::make_unique<cProtocol_1_10_0>(&a_Client, ServerAddress, ServerPort, NextState); case cProtocol::Version::Version_1_11_0: return std::make_unique<cProtocol_1_11_0>(&a_Client, ServerAddress, ServerPort, NextState); case cProtocol::Version::Version_1_11_1: return std::make_unique<cProtocol_1_11_1>(&a_Client, ServerAddress, ServerPort, NextState); - case cProtocol::Version::Version_1_12: return std::make_unique<cProtocol_1_12>(&a_Client, ServerAddress, ServerPort, NextState); + case cProtocol::Version::Version_1_12: return std::make_unique<cProtocol_1_12> (&a_Client, ServerAddress, ServerPort, NextState); case cProtocol::Version::Version_1_12_1: return std::make_unique<cProtocol_1_12_1>(&a_Client, ServerAddress, ServerPort, NextState); case cProtocol::Version::Version_1_12_2: return std::make_unique<cProtocol_1_12_2>(&a_Client, ServerAddress, ServerPort, NextState); - case cProtocol::Version::Version_1_13: return std::make_unique<cProtocol_1_13>(&a_Client, ServerAddress, ServerPort, NextState); + case cProtocol::Version::Version_1_13: return std::make_unique<cProtocol_1_13> (&a_Client, ServerAddress, ServerPort, NextState); case cProtocol::Version::Version_1_13_1: return std::make_unique<cProtocol_1_13_1>(&a_Client, ServerAddress, ServerPort, NextState); case cProtocol::Version::Version_1_13_2: return std::make_unique<cProtocol_1_13_2>(&a_Client, ServerAddress, ServerPort, NextState); + case cProtocol::Version::Version_1_14: return std::make_unique<cProtocol_1_14> (&a_Client, ServerAddress, ServerPort, NextState); default: { LOGD("Client \"%s\" uses an unsupported protocol (lengthed, version %u (0x%x))", diff --git a/src/Protocol/Protocol_1_11.cpp b/src/Protocol/Protocol_1_11.cpp index 385dcb34a..dcb1e98fc 100644 --- a/src/Protocol/Protocol_1_11.cpp +++ b/src/Protocol/Protocol_1_11.cpp @@ -592,7 +592,7 @@ UInt32 cProtocol_1_11_0::GetProtocolMobType(eMonsterType a_MobType) void cProtocol_1_11_0::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer) { int BlockX, BlockY, BlockZ; - if (!a_ByteBuffer.ReadPosition64(BlockX, BlockY, BlockZ)) + if (!a_ByteBuffer.ReadXYZPosition64(BlockX, BlockY, BlockZ)) { return; } diff --git a/src/Protocol/Protocol_1_12.cpp b/src/Protocol/Protocol_1_12.cpp index 3be1fe672..a67a82eaf 100644 --- a/src/Protocol/Protocol_1_12.cpp +++ b/src/Protocol/Protocol_1_12.cpp @@ -4,6 +4,8 @@ /* Implements the 1.12 protocol classes: - release 1.12 protocol (#335) +- release 1.12.1 protocol (#338) +- release 1.12.2 protocol (#340) */ #include "Globals.h" diff --git a/src/Protocol/Protocol_1_12.h b/src/Protocol/Protocol_1_12.h index 42c8483c4..80f0b4680 100644 --- a/src/Protocol/Protocol_1_12.h +++ b/src/Protocol/Protocol_1_12.h @@ -9,7 +9,6 @@ Declares the 1.12 protocol classes: - release 1.12.1 protocol (#338) - cProtocol_1_12_2 - release 1.12.2 protocol (#340) -(others may be added later in the future for the 1.12 release series) */ diff --git a/src/Protocol/Protocol_1_13.cpp b/src/Protocol/Protocol_1_13.cpp index c8c2e7383..3ca1cc3a8 100644 --- a/src/Protocol/Protocol_1_13.cpp +++ b/src/Protocol/Protocol_1_13.cpp @@ -4,11 +4,12 @@ /* Implements the 1.13 protocol classes: - release 1.13 protocol (#393) +- release 1.13.1 protocol (#401) +- release 1.13.2 protocol (#404) */ #include "Globals.h" #include "Protocol_1_13.h" -#include "Packetizer.h" #include "../Entities/Boat.h" #include "../Entities/Minecart.h" @@ -29,7 +30,6 @@ Implements the 1.13 protocol classes: #include "../Bindings/PluginManager.h" -#include "Palettes/Upgrade.h" #include "Palettes/Palette_1_13.h" #include "Palettes/Palette_1_13_1.h" @@ -85,7 +85,7 @@ void cProtocol_1_13::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, B ASSERT(m_State == 3); // In game mode? cPacketizer Pkt(*this, pktBlockChange); - Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); + Pkt.WriteXYZPosition64(a_BlockX, a_BlockY, a_BlockZ); Pkt.WriteVarInt32(Palette(PaletteUpgrade::FromBlock(a_BlockType, a_BlockMeta))); } @@ -102,27 +102,6 @@ void cProtocol_1_13::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBloc -template <auto Palette> -void cProtocol_1_13::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) -{ - ASSERT(m_State == 3); // In game mode? - - cPacketizer Pkt(*this, pktBlockChanges); - Pkt.WriteBEInt32(a_ChunkX); - Pkt.WriteBEInt32(a_ChunkZ); - Pkt.WriteVarInt32(static_cast<UInt32>(a_Changes.size())); - for (const auto & Change : a_Changes) - { - Int16 Coords = static_cast<Int16>(Change.m_RelY | (Change.m_RelZ << 8) | (Change.m_RelX << 12)); - Pkt.WriteBEInt16(Coords); - Pkt.WriteVarInt32(Palette(PaletteUpgrade::FromBlock(Change.m_BlockType, Change.m_BlockMeta))); - } // for itr - a_Changes[] -} - - - - - void cProtocol_1_13::SendMapData(const cMap & a_Map, int a_DataStartX, int a_DataStartY) { // TODO diff --git a/src/Protocol/Protocol_1_13.h b/src/Protocol/Protocol_1_13.h index fa4625f7e..bdc8bb33a 100644 --- a/src/Protocol/Protocol_1_13.h +++ b/src/Protocol/Protocol_1_13.h @@ -9,7 +9,6 @@ Declares the 1.13 protocol classes: - release 1.13.1 protocol (#401) - cProtocol_1_13_2 - release 1.13.2 protocol (#404) -(others may be added later in the future for the 1.13 release series) */ @@ -19,6 +18,8 @@ Declares the 1.13 protocol classes: #pragma once #include "Protocol_1_12.h" +#include "Packetizer.h" +#include "Palettes/Upgrade.h" @@ -35,11 +36,27 @@ public: protected: - // Packet sending: virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; template <auto Palette> void SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); // Template to avoid virtual calls in tight loops virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override; - template <auto Palette>void SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes); // Template to avoid virtual calls in tight loops + + /** Common implementation of multiblock change sending, templated to avoid virtual calls in tight loops. */ + template <auto Palette>void SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) + { + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, pktBlockChanges); + Pkt.WriteBEInt32(a_ChunkX); + Pkt.WriteBEInt32(a_ChunkZ); + Pkt.WriteVarInt32(static_cast<UInt32>(a_Changes.size())); + for (const auto & Change : a_Changes) + { + Int16 Coords = static_cast<Int16>(Change.m_RelY | (Change.m_RelZ << 8) | (Change.m_RelX << 12)); + Pkt.WriteBEInt16(Coords); + Pkt.WriteVarInt32(Palette(PaletteUpgrade::FromBlock(Change.m_BlockType, Change.m_BlockMeta))); + } // for itr - a_Changes[] + } + virtual void SendMapData (const cMap & a_Map, int a_DataStartX, int a_DataStartY) override; virtual void SendPaintingSpawn (const cPainting & a_Painting) override; virtual void SendParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data) override; @@ -49,7 +66,7 @@ protected: virtual void SendTabCompletionResults (const AStringVector & a_Results) override; virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override; - // Outgoing packet type translation: + /** Translates outgoing packet types. */ virtual UInt32 GetPacketID(ePacketType a_PacketType) override; /** Returns 1.13. */ @@ -63,7 +80,6 @@ protected: virtual std::pair<short, short> GetItemFromProtocolID(UInt32 a_ProtocolID); virtual UInt32 GetProtocolIDFromItem(short a_ItemID, short a_ItemDamage); - // Packet receiving: virtual bool HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) override; virtual void HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) override; diff --git a/src/Protocol/Protocol_1_14.cpp b/src/Protocol/Protocol_1_14.cpp new file mode 100644 index 000000000..d6751c6b1 --- /dev/null +++ b/src/Protocol/Protocol_1_14.cpp @@ -0,0 +1,305 @@ + +// Protocol_1_14.cpp + +/* +Implements the 1.14 protocol classes: +- release 1.14 protocol (#477) +*/ + +#include "Globals.h" +#include "Protocol_1_14.h" +#include "Packetizer.h" +#include "../Entities/Player.h" +#include "../Root.h" +#include "../Server.h" +#include "../World.h" + +#include "Palettes/Upgrade.h" +#include "Palettes/Palette_1_14.h" + + + + + +#define HANDLE_READ(ByteBuf, Proc, Type, Var) \ + Type Var; \ + do { \ + if (!ByteBuf.Proc(Var))\ + {\ + return;\ + } \ + } while (false) + + + + + +#define HANDLE_PACKET_READ(ByteBuf, Proc, Type, Var) \ + Type Var; \ + do { \ + { \ + if (!ByteBuf.Proc(Var)) \ + { \ + ByteBuf.CheckValid(); \ + return false; \ + } \ + ByteBuf.CheckValid(); \ + } \ + } while (false) + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cProtocol_1_14: + +void cProtocol_1_14::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) +{ +} + + + + + +void cProtocol_1_14::SendBlockBreakAnim(UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) +{ +} + + + + + +void cProtocol_1_14::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +{ + SendBlockChange<&Palette_1_14::FromBlock>(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); +} + + + + + +template <auto Palette> +void cProtocol_1_14::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) +{ + ASSERT(m_State == 3); // In game mode? + + cPacketizer Pkt(*this, pktBlockChange); + Pkt.WriteXZYPosition64(a_BlockX, a_BlockY, a_BlockZ); + Pkt.WriteVarInt32(Palette(PaletteUpgrade::FromBlock(a_BlockType, a_BlockMeta))); +} + + + + + +void cProtocol_1_14::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) +{ + cProtocol_1_13::SendBlockChanges<&Palette_1_14::FromBlock>(a_ChunkX, a_ChunkZ, a_Changes); +} + + + + + +void cProtocol_1_14::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ) +{ +} + + + + + +void cProtocol_1_14::SendLogin(const cPlayer & a_Player, const cWorld & a_World) +{ + // Send the Join Game packet: + { + cServer * Server = cRoot::Get()->GetServer(); + cPacketizer Pkt(*this, pktJoinGame); + Pkt.WriteBEUInt32(a_Player.GetUniqueID()); + Pkt.WriteBEUInt8(static_cast<UInt8>(a_Player.GetEffectiveGameMode()) | (Server->IsHardcore() ? 0x08 : 0)); + Pkt.WriteBEInt32(static_cast<Int32>(a_World.GetDimension())); + Pkt.WriteBEUInt8(static_cast<UInt8>(Clamp<size_t>(Server->GetMaxPlayers(), 0, 255))); + Pkt.WriteString("default"); + Pkt.WriteVarInt32(a_World.GetMaxViewDistance()); + Pkt.WriteBool(false); + } + + // Send the spawn position: + { + cPacketizer Pkt(*this, pktSpawnPosition); + Pkt.WriteXZYPosition64(FloorC(a_World.GetSpawnX()), FloorC(a_World.GetSpawnY()), FloorC(a_World.GetSpawnZ())); + } + + // Send the server difficulty: + { + // cPacketizer Pkt(*this, pktDifficulty); + // Pkt.WriteBEInt8(1); + } + + // Send player abilities: + SendPlayerAbilities(); +} + + + + + +void cProtocol_1_14::SendPaintingSpawn(const cPainting & a_Painting) +{ +} + + + + + +void cProtocol_1_14::SendSoundParticleEffect(const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) +{ +} + + + + + +void cProtocol_1_14::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity) +{ +} + + + + + +void cProtocol_1_14::SendUpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) +{ +} + + + + + +void cProtocol_1_14::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) +{ +} + + + + + +UInt32 cProtocol_1_14::GetPacketID(ePacketType a_PacketType) +{ + switch (a_PacketType) + { + case cProtocol::pktAttachEntity: return 0x4A; + case cProtocol::pktCameraSetTo: return 0x3E; + case cProtocol::pktCollectEntity: return 0x55; + case cProtocol::pktDestroyEntity: return 0x37; + case cProtocol::pktDisconnectDuringGame: return 0x1A; + case cProtocol::pktEntityEffect: return 0x59; + case cProtocol::pktEntityEquipment: return 0x46; + case cProtocol::pktEntityHeadLook: return 0x3B; + case cProtocol::pktEntityMeta: return 0x43; + case cProtocol::pktEntityProperties: return 0x58; + case cProtocol::pktEntityStatus: return 0x1B; + case cProtocol::pktEntityVelocity: return 0x45; + case cProtocol::pktExperience: return 0x47; + case cProtocol::pktExplosion: return 0x1C; + case cProtocol::pktGameMode: return 0x1E; + case cProtocol::pktHeldItemChange: return 0x3F; + case cProtocol::pktInventorySlot: return 0x16; + case cProtocol::pktKeepAlive: return 0x20; + case cProtocol::pktParticleEffect: return 0x23; + case cProtocol::pktPlayerAbilities: return 0x31; + case cProtocol::pktPlayerList: return 0x33; + case cProtocol::pktPlayerMoveLook: return 0x35; + case cProtocol::pktPluginMessage: return 0x18; + case cProtocol::pktRemoveEntityEffect: return 0x38; + case cProtocol::pktResourcePack: return 0x39; + case cProtocol::pktRespawn: return 0x3A; + case cProtocol::pktScoreboardObjective: return 0x49; + case cProtocol::pktSoundEffect: return 0x19; + case cProtocol::pktSoundParticleEffect: return 0x22; + case cProtocol::pktSpawnPosition: return 0x4D; + case cProtocol::pktTeleportEntity: return 0x56; + case cProtocol::pktTimeUpdate: return 0x4E; + case cProtocol::pktTitle: return 0x4F; + case cProtocol::pktUnloadChunk: return 0x1D; + case cProtocol::pktUnlockRecipe: return 0x36; + case cProtocol::pktUpdateHealth: return 0x48; + case cProtocol::pktUpdateScore: return 0x4C; + case cProtocol::pktUpdateSign: return 0x2F; + case cProtocol::pktWindowItems: return 0x14; + case cProtocol::pktWindowOpen: return 0x2E; + case cProtocol::pktWindowProperty: return 0x15; + default: return Super::GetPacketID(a_PacketType); + } +} + + + + + +cProtocol::Version cProtocol_1_14::GetProtocolVersion() +{ + return Version::Version_1_14; +} + + + + + +bool cProtocol_1_14::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) +{ + if (m_State != 3) + { + return Super::HandlePacket(a_ByteBuffer, a_PacketType); + } + + // Game + switch (a_PacketType) + { + default: AString dum; a_ByteBuffer.ReadAll(dum); a_ByteBuffer.CommitRead(); a_ByteBuffer.Write(" ", 1); + return true; + } +} + + + + + +void cProtocol_1_14::HandlePacketBlockDig(cByteBuffer & a_ByteBuffer) +{ +} + + + + + +void cProtocol_1_14::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer) +{ +} + + + + + +void cProtocol_1_14::HandlePacketUpdateSign(cByteBuffer & a_ByteBuffer) +{ +} + + + + + +std::pair<short, short> cProtocol_1_14::GetItemFromProtocolID(UInt32 a_ProtocolID) +{ + return PaletteUpgrade::ToItem(Palette_1_14::ToItem(a_ProtocolID)); +} + + + + + +UInt32 cProtocol_1_14::GetProtocolIDFromItem(short a_ItemID, short a_ItemDamage) +{ + return Palette_1_14::FromItem(PaletteUpgrade::FromItem(a_ItemID, a_ItemDamage)); +} diff --git a/src/Protocol/Protocol_1_14.h b/src/Protocol/Protocol_1_14.h new file mode 100644 index 000000000..2b21246e5 --- /dev/null +++ b/src/Protocol/Protocol_1_14.h @@ -0,0 +1,59 @@ + +// Protocol_1_14.h + +/* +Declares the 1.14 protocol classes: + - cProtocol_1_14 + - release 1.14 protocol (#477) +*/ + + + + + +#pragma once + +#include "Protocol_1_13.h" + + + + + +class cProtocol_1_14: + public cProtocol_1_13_2 +{ + using Super = cProtocol_1_13_2; + +public: + + using Super::cProtocol_1_13_2; + +protected: + + virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override; + virtual void SendBlockBreakAnim (UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override; + virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; + template <auto Palette> void SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); + virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override; + virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+) + virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override; + virtual void SendPaintingSpawn (const cPainting & a_Painting) override; + virtual void SendSoundParticleEffect (const EffectID a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; + virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override; + virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; + virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override; + + virtual UInt32 GetPacketID(ePacketType a_PacketType) override; + virtual Version GetProtocolVersion() override; + + virtual bool HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) override; + virtual void HandlePacketBlockDig(cByteBuffer & a_ByteBuffer) override; + virtual void HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer) override; + virtual void HandlePacketUpdateSign(cByteBuffer & a_ByteBuffer) override; + + virtual std::pair<short, short> GetItemFromProtocolID(UInt32 a_ProtocolID) override; + virtual UInt32 GetProtocolIDFromItem(short a_ItemID, short a_ItemDamage) override; + + virtual void WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) override {} + virtual void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) override {} +}; diff --git a/src/Protocol/Protocol_1_8.cpp b/src/Protocol/Protocol_1_8.cpp index 50c70ef09..e865725ea 100644 --- a/src/Protocol/Protocol_1_8.cpp +++ b/src/Protocol/Protocol_1_8.cpp @@ -224,7 +224,7 @@ void cProtocol_1_8_0::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, ASSERT(m_State == 3); // In game mode? cPacketizer Pkt(*this, pktBlockAction); - Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); + Pkt.WriteXYZPosition64(a_BlockX, a_BlockY, a_BlockZ); Pkt.WriteBEInt8(a_Byte1); Pkt.WriteBEInt8(a_Byte2); Pkt.WriteVarInt32(a_BlockType); @@ -240,7 +240,7 @@ void cProtocol_1_8_0::SendBlockBreakAnim(UInt32 a_EntityID, int a_BlockX, int a_ cPacketizer Pkt(*this, pktBlockBreakAnim); Pkt.WriteVarInt32(a_EntityID); - Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); + Pkt.WriteXYZPosition64(a_BlockX, a_BlockY, a_BlockZ); Pkt.WriteBEInt8(a_Stage); } @@ -253,7 +253,7 @@ void cProtocol_1_8_0::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, ASSERT(m_State == 3); // In game mode? cPacketizer Pkt(*this, pktBlockChange); - Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); + Pkt.WriteXYZPosition64(a_BlockX, a_BlockY, a_BlockZ); Pkt.WriteVarInt32((static_cast<UInt32>(a_BlockType) << 4) | (static_cast<UInt32>(a_BlockMeta) & 15)); } @@ -410,7 +410,7 @@ void cProtocol_1_8_0::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ) ASSERT(m_State == 3); // In game mode? cPacketizer Pkt(*this, pktEditSign); - Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); + Pkt.WriteXYZPosition64(a_BlockX, a_BlockY, a_BlockZ); } @@ -776,7 +776,7 @@ void cProtocol_1_8_0::SendLogin(const cPlayer & a_Player, const cWorld & a_World // Send the spawn position: { cPacketizer Pkt(*this, pktSpawnPosition); - Pkt.WritePosition64(FloorC(a_World.GetSpawnX()), FloorC(a_World.GetSpawnY()), FloorC(a_World.GetSpawnZ())); + Pkt.WriteXYZPosition64(FloorC(a_World.GetSpawnX()), FloorC(a_World.GetSpawnY()), FloorC(a_World.GetSpawnZ())); } // Send the server difficulty: @@ -826,7 +826,7 @@ void cProtocol_1_8_0::SendPaintingSpawn(const cPainting & a_Painting) cPacketizer Pkt(*this, pktSpawnPainting); Pkt.WriteVarInt32(a_Painting.GetUniqueID()); Pkt.WriteString(a_Painting.GetName()); - Pkt.WritePosition64(static_cast<Int32>(PosX), static_cast<Int32>(PosY), static_cast<Int32>(PosZ)); + Pkt.WriteXYZPosition64(static_cast<Int32>(PosX), static_cast<Int32>(PosY), static_cast<Int32>(PosZ)); Pkt.WriteBEInt8(static_cast<Int8>(a_Painting.GetProtocolFacing())); } @@ -1339,7 +1339,7 @@ void cProtocol_1_8_0::SendSoundParticleEffect(const EffectID a_EffectID, int a_S cPacketizer Pkt(*this, pktSoundParticleEffect); Pkt.WriteBEInt32(static_cast<int>(a_EffectID)); - Pkt.WritePosition64(a_SrcX, a_SrcY, a_SrcZ); + Pkt.WriteXYZPosition64(a_SrcX, a_SrcY, a_SrcZ); Pkt.WriteBEInt32(a_Data); Pkt.WriteBool(false); } @@ -1526,7 +1526,7 @@ void cProtocol_1_8_0::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity) ASSERT(m_State == 3); // In game mode? cPacketizer Pkt(*this, pktUpdateBlockEntity); - Pkt.WritePosition64(a_BlockEntity.GetPosX(), a_BlockEntity.GetPosY(), a_BlockEntity.GetPosZ()); + Pkt.WriteXYZPosition64(a_BlockEntity.GetPosX(), a_BlockEntity.GetPosY(), a_BlockEntity.GetPosZ()); Byte Action = 0; switch (a_BlockEntity.GetBlockType()) @@ -1553,7 +1553,7 @@ void cProtocol_1_8_0::SendUpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, c ASSERT(m_State == 3); // In game mode? cPacketizer Pkt(*this, pktUpdateSign); - Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); + Pkt.WriteXYZPosition64(a_BlockX, a_BlockY, a_BlockZ); AString Lines[] = { a_Line1, a_Line2, a_Line3, a_Line4 }; for (size_t i = 0; i < ARRAYCOUNT(Lines); i++) @@ -1574,7 +1574,7 @@ void cProtocol_1_8_0::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_B cPacketizer Pkt(*this, pktUseBed); Pkt.WriteVarInt32(a_Entity.GetUniqueID()); - Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); + Pkt.WriteXYZPosition64(a_BlockX, a_BlockY, a_BlockZ); } @@ -2471,7 +2471,7 @@ void cProtocol_1_8_0::HandlePacketBlockDig(cByteBuffer & a_ByteBuffer) HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Status); int BlockX, BlockY, BlockZ; - if (!a_ByteBuffer.ReadPosition64(BlockX, BlockY, BlockZ)) + if (!a_ByteBuffer.ReadXYZPosition64(BlockX, BlockY, BlockZ)) { return; } @@ -2487,7 +2487,7 @@ void cProtocol_1_8_0::HandlePacketBlockDig(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer) { int BlockX, BlockY, BlockZ; - if (!a_ByteBuffer.ReadPosition64(BlockX, BlockY, BlockZ)) + if (!a_ByteBuffer.ReadXYZPosition64(BlockX, BlockY, BlockZ)) { return; } @@ -2805,7 +2805,7 @@ void cProtocol_1_8_0::HandlePacketTabComplete(cByteBuffer & a_ByteBuffer) void cProtocol_1_8_0::HandlePacketUpdateSign(cByteBuffer & a_ByteBuffer) { int BlockX, BlockY, BlockZ; - if (!a_ByteBuffer.ReadPosition64(BlockX, BlockY, BlockZ)) + if (!a_ByteBuffer.ReadXYZPosition64(BlockX, BlockY, BlockZ)) { return; } diff --git a/src/Protocol/Protocol_1_8.h b/src/Protocol/Protocol_1_8.h index cd9e2f095..aec9e2e57 100644 --- a/src/Protocol/Protocol_1_8.h +++ b/src/Protocol/Protocol_1_8.h @@ -4,7 +4,7 @@ /* Declares the 1.8 protocol classes: - cProtocol_1_8_0 - - release 1.8 protocol (#47) + - release 1.8 protocol (#47), also used by 1.8.1 to 1.8.9 */ diff --git a/src/Protocol/Protocol_1_9.cpp b/src/Protocol/Protocol_1_9.cpp index 9bb0b7d08..5c5227b5f 100644 --- a/src/Protocol/Protocol_1_9.cpp +++ b/src/Protocol/Protocol_1_9.cpp @@ -285,7 +285,7 @@ void cProtocol_1_9_0::SendPaintingSpawn(const cPainting & a_Painting) Pkt.WriteBEUInt64(0); Pkt.WriteBEUInt64(a_Painting.GetUniqueID()); Pkt.WriteString(a_Painting.GetName()); - Pkt.WritePosition64(static_cast<Int32>(PosX), static_cast<Int32>(PosY), static_cast<Int32>(PosZ)); + Pkt.WriteXYZPosition64(static_cast<Int32>(PosX), static_cast<Int32>(PosY), static_cast<Int32>(PosZ)); Pkt.WriteBEInt8(static_cast<Int8>(a_Painting.GetProtocolFacing())); } @@ -680,7 +680,7 @@ void cProtocol_1_9_0::HandlePacketBlockDig(cByteBuffer & a_ByteBuffer) HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Status); int BlockX, BlockY, BlockZ; - if (!a_ByteBuffer.ReadPosition64(BlockX, BlockY, BlockZ)) + if (!a_ByteBuffer.ReadXYZPosition64(BlockX, BlockY, BlockZ)) { return; } @@ -696,7 +696,7 @@ void cProtocol_1_9_0::HandlePacketBlockDig(cByteBuffer & a_ByteBuffer) void cProtocol_1_9_0::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer) { int BlockX, BlockY, BlockZ; - if (!a_ByteBuffer.ReadPosition64(BlockX, BlockY, BlockZ)) + if (!a_ByteBuffer.ReadXYZPosition64(BlockX, BlockY, BlockZ)) { return; } @@ -873,7 +873,7 @@ void cProtocol_1_9_0::HandlePacketTabComplete(cByteBuffer & a_ByteBuffer) void cProtocol_1_9_0::HandlePacketUpdateSign(cByteBuffer & a_ByteBuffer) { int BlockX, BlockY, BlockZ; - if (!a_ByteBuffer.ReadPosition64(BlockX, BlockY, BlockZ)) + if (!a_ByteBuffer.ReadXYZPosition64(BlockX, BlockY, BlockZ)) { return; } @@ -2171,7 +2171,7 @@ void cProtocol_1_9_1::SendLogin(const cPlayer & a_Player, const cWorld & a_World // Send the spawn position: { cPacketizer Pkt(*this, pktSpawnPosition); - Pkt.WritePosition64(FloorC(a_World.GetSpawnX()), FloorC(a_World.GetSpawnY()), FloorC(a_World.GetSpawnZ())); + Pkt.WriteXYZPosition64(FloorC(a_World.GetSpawnX()), FloorC(a_World.GetSpawnY()), FloorC(a_World.GetSpawnZ())); } // Send the server difficulty: @@ -2218,7 +2218,7 @@ void cProtocol_1_9_4::SendUpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, c // 1.9.4 removed the update sign packet and now uses Update Block Entity cPacketizer Pkt(*this, pktUpdateBlockEntity); - Pkt.WritePosition64(a_BlockX, a_BlockY, a_BlockZ); + Pkt.WriteXYZPosition64(a_BlockX, a_BlockY, a_BlockZ); Pkt.WriteBEUInt8(9); // Action 9 - update sign cFastNBTWriter Writer; |