From e883aa828c304600fcd707b50df9515011311db8 Mon Sep 17 00:00:00 2001 From: peterbell10 Date: Thu, 21 Sep 2017 14:12:43 +0100 Subject: [PATCH] Add support for release 1.12.2 (#4041) --- README.md | 2 +- src/Protocol/ProtocolRecognizer.cpp | 5 ++ src/Protocol/ProtocolRecognizer.h | 7 +-- src/Protocol/Protocol_1_12.cpp | 76 +++++++++++++++++++++++++++++ src/Protocol/Protocol_1_12.h | 23 +++++++++ 5 files changed, 109 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f72a22f94..cda5aa295 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,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.12.1 Minecraft protocol versions. +We currently support Release 1.8 - 1.12.2 Minecraft protocol versions. Subscribe to [the newsletter][1] for important updates and project news. diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index cb2a4fc9d..912091acc 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -1133,6 +1133,11 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema m_Protocol = new cProtocol_1_12_1(m_Client, ServerAddress, ServerPort, NextState); return true; } + case PROTO_VERSION_1_12_2: + { + m_Protocol = new cProtocol_1_12_2(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 6d75b0f2e..a29daad94 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -19,8 +19,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.x, 1.12.x" -#define MCS_PROTOCOL_VERSIONS "47, 107, 108, 109, 110, 210, 315, 316, 335, 338" -#define MCS_LATEST_PROTOCOL_VERSION 338 +#define MCS_PROTOCOL_VERSIONS "47, 107, 108, 109, 110, 210, 315, 316, 335, 338, 340" +#define MCS_LATEST_PROTOCOL_VERSION 340 @@ -44,7 +44,8 @@ public: PROTO_VERSION_1_11_1 = 316, PROTO_VERSION_1_12 = 335, PROTO_VERSION_1_12_1 = 338, - } ; + PROTO_VERSION_1_12_2 = 340, + }; cProtocolRecognizer(cClientHandle * a_Client); virtual ~cProtocolRecognizer() override; diff --git a/src/Protocol/Protocol_1_12.cpp b/src/Protocol/Protocol_1_12.cpp index 627131576..b804dd351 100644 --- a/src/Protocol/Protocol_1_12.cpp +++ b/src/Protocol/Protocol_1_12.cpp @@ -1332,3 +1332,79 @@ bool cProtocol_1_12_1::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketT +//////////////////////////////////////////////////////////////////////////////// +// cProtocol_1_12_2: + +void cProtocol_1_12_2::HandlePacketKeepAlive(cByteBuffer & a_ByteBuffer) +{ + HANDLE_READ(a_ByteBuffer, ReadBEInt64, Int64, KeepAliveID); + if ( + (KeepAliveID <= std::numeric_limits::max()) && + (KeepAliveID >= 0) + ) + { + // The server will only send a UInt32 so any value out of that range shouldn't keep the client alive. + m_Client->HandleKeepAlive(static_cast(KeepAliveID)); + } +} + + + + + +void cProtocol_1_12_2::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) +{ + cServer * Server = cRoot::Get()->GetServer(); + AString ServerDescription = Server->GetDescription(); + auto NumPlayers = static_cast(Server->GetNumPlayers()); + auto MaxPlayers = static_cast(Server->GetMaxPlayers()); + AString Favicon = Server->GetFaviconData(); + cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, ServerDescription, NumPlayers, MaxPlayers, Favicon); + + // Version: + Json::Value Version; + Version["name"] = "Cuberite 1.12.2"; + Version["protocol"] = cProtocolRecognizer::PROTO_VERSION_1_12_2; + + // 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)); +} + + + + + +void cProtocol_1_12_2::SendKeepAlive(UInt32 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, GetPacketId(sendKeepAlive)); // Keep Alive packet + Pkt.WriteBEInt64(a_PingID); +} diff --git a/src/Protocol/Protocol_1_12.h b/src/Protocol/Protocol_1_12.h index 9b87494a6..fe518fdbd 100644 --- a/src/Protocol/Protocol_1_12.h +++ b/src/Protocol/Protocol_1_12.h @@ -7,6 +7,8 @@ Declares the 1.12 protocol classes: - release 1.12 protocol (#335) - cProtocol_1_12_1 - 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) */ @@ -71,3 +73,24 @@ protected: + +class cProtocol_1_12_2: + public cProtocol_1_12_1 +{ + typedef cProtocol_1_12_1 Super; + +public: + cProtocol_1_12_2(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State): + Super(a_Client, a_ServerAddress, a_ServerPort, a_State) + { + } + +protected: + virtual void HandlePacketKeepAlive(cByteBuffer & a_ByteBuffer) override; + virtual void HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) override; + virtual void SendKeepAlive(UInt32 a_PingID) override; +}; + + + +