From c89b20695df7d2a7afc85806d147e0b9ab1a23d1 Mon Sep 17 00:00:00 2001 From: mathiascode Date: Tue, 21 Feb 2017 17:11:28 +0200 Subject: [PATCH] Add 1.11.1/1.11.2 protocol (#3575) --- CONTRIBUTORS | 2 +- README.md | 2 +- Server/README.txt | 2 +- src/Protocol/ProtocolRecognizer.cpp | 6 +++ src/Protocol/ProtocolRecognizer.h | 5 ++- src/Protocol/Protocol_1_10.cpp | 2 +- src/Protocol/Protocol_1_11.cpp | 65 +++++++++++++++++++++++++---- src/Protocol/Protocol_1_11.h | 15 +++++++ src/Protocol/Protocol_1_9.cpp | 6 +-- 9 files changed, 89 insertions(+), 16 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 2bbee0d32..0f7ff964c 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -24,7 +24,7 @@ Luksor M10360 marmot21 Masy98 -mathias-github +mathiascode mborland mgueydan MikeHunsinger diff --git a/README.md b/README.md index 21ffaf9b9..b0b85feee 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Cuberite is a Minecraft-compatible multiplayer game server that is written in C+ Cuberite can run on Windows, *nix and Android operating systems. This includes Android phones and tablets as well as Raspberry Pis. -We currently support Release 1.8 - 1.10 Minecraft protocol versions. +We currently support Release 1.8 - 1.11 Minecraft protocol versions. Subscribe to [the newsletter](https://cuberite.org/news/#subscribe) for important updates and project news. diff --git a/Server/README.txt b/Server/README.txt index 88d60fae8..8cca1315c 100644 --- a/Server/README.txt +++ b/Server/README.txt @@ -1,5 +1,5 @@ -------------------------------------------------------------------------------- - Welcome to your new Cuberite server, compatible with Minecraft 1.8 - 1.10! + Welcome to your new Cuberite server, compatible with Minecraft 1.8 - 1.11! -------------------------------------------------------------------------------- - To get started with your server, read the user's manual at diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 04ac1bb2b..79270644f 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -56,6 +56,7 @@ AString cProtocolRecognizer::GetVersionTextFromInt(int a_ProtocolVersion) case PROTO_VERSION_1_9_4: return "1.9.4"; case PROTO_VERSION_1_10_0: return "1.10"; case PROTO_VERSION_1_11_0: return "1.11"; + case PROTO_VERSION_1_11_1: return "1.11.1"; } ASSERT(!"Unknown protocol version"); return Printf("Unknown protocol (%d)", a_ProtocolVersion); @@ -1079,6 +1080,11 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema m_Protocol = new cProtocol_1_11_0(m_Client, ServerAddress, ServerPort, NextState); return true; } + case PROTO_VERSION_1_11_1: + { + m_Protocol = new cProtocol_1_11_1(m_Client, ServerAddress, ServerPort, NextState); + return true; + } default: { LOGD("Client \"%s\" uses an unsupported protocol (lengthed, version %u (0x%x))", diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index 081b2136e..b48717563 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -18,8 +18,8 @@ // Adjust these if a new protocol is added or an old one is removed: -#define MCS_CLIENT_VERSIONS "1.8.x, 1.9.x, 1.10.x, 1.11" -#define MCS_PROTOCOL_VERSIONS "47, 107, 108, 109, 110, 210, 315" +#define MCS_CLIENT_VERSIONS "1.8.x, 1.9.x, 1.10.x, 1.11.x" +#define MCS_PROTOCOL_VERSIONS "47, 107, 108, 109, 110, 210, 315, 316" @@ -40,6 +40,7 @@ public: PROTO_VERSION_1_9_4 = 110, PROTO_VERSION_1_10_0 = 210, PROTO_VERSION_1_11_0 = 315, + PROTO_VERSION_1_11_1 = 316, } ; cProtocolRecognizer(cClientHandle * a_Client); diff --git a/src/Protocol/Protocol_1_10.cpp b/src/Protocol/Protocol_1_10.cpp index 1cd7153a7..5ecd2743b 100644 --- a/src/Protocol/Protocol_1_10.cpp +++ b/src/Protocol/Protocol_1_10.cpp @@ -282,7 +282,7 @@ namespace Metadata -cProtocol_1_10_0::cProtocol_1_10_0(cClientHandle * a_Client, const AString &a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : +cProtocol_1_10_0::cProtocol_1_10_0(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : super(a_Client, a_ServerAddress, a_ServerPort, a_State) { } diff --git a/src/Protocol/Protocol_1_11.cpp b/src/Protocol/Protocol_1_11.cpp index 5d6eca508..6b5c207d3 100644 --- a/src/Protocol/Protocol_1_11.cpp +++ b/src/Protocol/Protocol_1_11.cpp @@ -36,7 +36,7 @@ Implements the 1.11 protocol classes: -cProtocol_1_11_0::cProtocol_1_11_0(cClientHandle * a_Client, const AString &a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : +cProtocol_1_11_0::cProtocol_1_11_0(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : super(a_Client, a_ServerAddress, a_ServerPort, a_State) { } @@ -49,7 +49,7 @@ void cProtocol_1_11_0::SendCollectEntity(const cEntity & a_Entity, const cPlayer { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x0d); // Collect Item packet + cPacketizer Pkt(*this, 0x48); // Collect Item packet Pkt.WriteVarInt32(a_Entity.GetUniqueID()); Pkt.WriteVarInt32(a_Player.GetUniqueID()); Pkt.WriteVarInt32(static_cast(a_Count)); @@ -87,12 +87,15 @@ void cProtocol_1_11_0::SendSpawnMob(const cMonster & a_Mob) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, 0x0f); // Spawn Mob packet + cPacketizer Pkt(*this, 0x03); // Spawn Mob packet Pkt.WriteVarInt32(a_Mob.GetUniqueID()); + // TODO: Bad way to write a UUID, and it's not a true UUID, but this is functional for now. + Pkt.WriteBEUInt64(0); + Pkt.WriteBEUInt64(a_Mob.GetUniqueID()); Pkt.WriteVarInt32(static_cast(a_Mob.GetMobType())); - Pkt.WriteFPInt(a_Mob.GetPosX()); - Pkt.WriteFPInt(a_Mob.GetPosY()); - Pkt.WriteFPInt(a_Mob.GetPosZ()); + Pkt.WriteBEDouble(a_Mob.GetPosX()); + Pkt.WriteBEDouble(a_Mob.GetPosY()); + Pkt.WriteBEDouble(a_Mob.GetPosZ()); Pkt.WriteByteAngle(a_Mob.GetPitch()); Pkt.WriteByteAngle(a_Mob.GetHeadYaw()); Pkt.WriteByteAngle(a_Mob.GetYaw()); @@ -100,7 +103,7 @@ void cProtocol_1_11_0::SendSpawnMob(const cMonster & a_Mob) Pkt.WriteBEInt16(static_cast(a_Mob.GetSpeedY() * 400)); Pkt.WriteBEInt16(static_cast(a_Mob.GetSpeedZ() * 400)); WriteEntityMetadata(Pkt, a_Mob); - Pkt.WriteBEUInt8(0x7f); // Metadata terminator + Pkt.WriteBEUInt8(0xff); // Metadata terminator } @@ -187,3 +190,51 @@ void cProtocol_1_11_0::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) +cProtocol_1_11_1::cProtocol_1_11_1(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : + super(a_Client, a_ServerAddress, a_ServerPort, a_State) +{ +} + + + + + +void cProtocol_1_11_1::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) +{ + cServer * Server = cRoot::Get()->GetServer(); + AString ServerDescription = Server->GetDescription(); + int NumPlayers = Server->GetNumPlayers(); + int MaxPlayers = Server->GetMaxPlayers(); + AString Favicon = Server->GetFaviconData(); + cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, ServerDescription, NumPlayers, MaxPlayers, Favicon); + + // Version: + Json::Value Version; + Version["name"] = "Cuberite 1.11.1"; + Version["protocol"] = cProtocolRecognizer::PROTO_VERSION_1_11_1; + + // Players: + Json::Value Players; + Players["online"] = NumPlayers; + Players["max"] = MaxPlayers; + // TODO: Add "sample" + + // Description: + Json::Value Description; + Description["text"] = ServerDescription.c_str(); + + // Create the response: + Json::Value ResponseValue; + ResponseValue["version"] = Version; + ResponseValue["players"] = Players; + ResponseValue["description"] = Description; + if (!Favicon.empty()) + { + ResponseValue["favicon"] = Printf("data:image/png;base64,%s", Favicon.c_str()); + } + + // Serialize the response into a packet: + Json::FastWriter Writer; + cPacketizer Pkt(*this, 0x00); // Response packet + Pkt.WriteString(Writer.write(ResponseValue)); +} diff --git a/src/Protocol/Protocol_1_11.h b/src/Protocol/Protocol_1_11.h index a3c7c4d58..8131a5b35 100644 --- a/src/Protocol/Protocol_1_11.h +++ b/src/Protocol/Protocol_1_11.h @@ -39,3 +39,18 @@ protected: virtual void HandlePacketBlockPlace (cByteBuffer & a_ByteBuffer) override; virtual void HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) override; }; + + + + + +class cProtocol_1_11_1 : + public cProtocol_1_11_0 +{ + typedef cProtocol_1_11_0 super; + +public: + cProtocol_1_11_1(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State); + + virtual void HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) override; +}; diff --git a/src/Protocol/Protocol_1_9.cpp b/src/Protocol/Protocol_1_9.cpp index 19a00ce37..5b1b4472b 100644 --- a/src/Protocol/Protocol_1_9.cpp +++ b/src/Protocol/Protocol_1_9.cpp @@ -4082,7 +4082,7 @@ void cProtocol_1_9_0::WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & //////////////////////////////////////////////////////////////////////////////// // cProtocol_1_9_1: -cProtocol_1_9_1::cProtocol_1_9_1(cClientHandle * a_Client, const AString &a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : +cProtocol_1_9_1::cProtocol_1_9_1(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : super(a_Client, a_ServerAddress, a_ServerPort, a_State) { } @@ -4174,7 +4174,7 @@ void cProtocol_1_9_1::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) //////////////////////////////////////////////////////////////////////////////// // cProtocol_1_9_2: -cProtocol_1_9_2::cProtocol_1_9_2(cClientHandle * a_Client, const AString &a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : +cProtocol_1_9_2::cProtocol_1_9_2(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : super(a_Client, a_ServerAddress, a_ServerPort, a_State) { } @@ -4231,7 +4231,7 @@ void cProtocol_1_9_2::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) //////////////////////////////////////////////////////////////////////////////// // cProtocol_1_9_4: -cProtocol_1_9_4::cProtocol_1_9_4(cClientHandle * a_Client, const AString &a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : +cProtocol_1_9_4::cProtocol_1_9_4(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : super(a_Client, a_ServerAddress, a_ServerPort, a_State) { }