From 50186579737c12f11bea815d5fb8db732c6ff3c6 Mon Sep 17 00:00:00 2001 From: tycho Date: Sun, 27 Sep 2015 15:18:31 +0100 Subject: Broken3 --- src/ClientAction.h | 3 +- src/ClientHandle.cpp | 6 +- src/Protocol/LengthenedProtocol.h | 4 ++ src/Protocol/Protocol.h | 6 +- src/Protocol/Protocol17x.cpp | 17 +++--- src/Protocol/Protocol17x.h | 5 +- src/Protocol/Protocol18x.cpp | 13 ++-- src/Protocol/Protocol18x.h | 4 +- src/Protocol/ProtocolRecognizer.cpp | 119 +++++++++++++++++------------------- src/Protocol/ProtocolRecognizer.h | 13 ++-- 10 files changed, 97 insertions(+), 93 deletions(-) diff --git a/src/ClientAction.h b/src/ClientAction.h index d07d9a07b..1844d14c6 100644 --- a/src/ClientAction.h +++ b/src/ClientAction.h @@ -19,7 +19,8 @@ public: Respawn, StatsRequest, Achivement, - CreativeInventory + CreativeInventory, + SetProtocolVersion }; cClientAction(Type a_Type) : m_Type(a_Type) {} diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index e54b73db3..41b7f1fbc 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -90,7 +90,7 @@ cClientHandle::cClientHandle(const AString & a_IPString, int a_ViewDistance) : m_LastPlacedSign(0, -1, 0), m_ProtocolVersion(0) { - m_Protocol = new cProtocolRecognizer(this); + m_Protocol = new cProtocolRecognizer(GetIPString()); s_ClientCount++; // Not protected by CS because clients are always constructed from the same thread m_UniqueID = s_ClientCount; @@ -3002,7 +3002,7 @@ void cClientHandle::PacketError(UInt32 a_PacketType) SendDisconnect("Protocol error"); } - +#endif @@ -3039,7 +3039,6 @@ void cClientHandle::SetSelf(cClientHandlePtr a_Self) - void cClientHandle::OnLinkCreated(cTCPLinkPtr a_Link) { m_Link = a_Link; @@ -3087,7 +3086,6 @@ void cClientHandle::OnError(int a_ErrorCode, const AString & a_ErrorMsg) } SocketClosed(); } -#endif diff --git a/src/Protocol/LengthenedProtocol.h b/src/Protocol/LengthenedProtocol.h index 88550989d..4394614ce 100644 --- a/src/Protocol/LengthenedProtocol.h +++ b/src/Protocol/LengthenedProtocol.h @@ -11,6 +11,10 @@ public: { } + virtual ~cLengthenedProtocol() = default; + + cProtocolError HandleHandshake(cByteBuffer & a_ByteBuffer, std::vector> & a_Actions) override WARN_UNUSED; + protected: virtual cProtocolError DataReceived(const char * a_Data, size_t a_Size, std::vector> & a_Actions) override WARN_UNUSED; /** This method should append the actions from incoming packets to a_Action */ diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index 675302c1d..b3335b6b8 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -71,7 +71,9 @@ public: PacketReadError, // One of the values read out of the packet was invalid. // We send a kick packet in response to a process error - PacketProcessError + PacketProcessError, + NotCompleted, + UnsupportedProtocol }; cProtocol(AString a_LogID) : @@ -179,6 +181,8 @@ public: /** Returns the ServerID used for authentication through session.minecraft.net */ virtual AString GetAuthServerID(void) = 0; + virtual cProtocolError HandleHandshake(cByteBuffer & a_ByteBuffer, std::vector> & a_Actions) WARN_UNUSED = 0; + protected: friend class cPacketizer; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 873efa075..4e3b985e1 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -88,14 +88,12 @@ extern bool g_ShouldLogCommIn, g_ShouldLogCommOut; //////////////////////////////////////////////////////////////////////////////// // cProtocol172: -/* -cProtocol172::cProtocol172(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : - super(a_Client->GetIPString()), - m_ServerAddress(a_ServerAddress), - m_ServerPort(a_ServerPort), - m_State(a_State), + +cProtocol172::cProtocol172(const AString a_LogID) : + super(a_LogID), m_LastSentDimension(dimNotSet) { +/* // BungeeCord handling: // If BC is setup with ip_forward == true, it sends additional data in the login packet's ServerAddress field: // hostname\00ip-address\00uuid\00profile-properties-as-json @@ -108,8 +106,9 @@ cProtocol172::cProtocol172(cClientHandle * a_Client, const AString & a_ServerAdd a_Client->SetUUID(cMojangAPI::MakeUUIDShort(Params[2])); a_Client->SetProperties(Params[3]); } -} */ +} + @@ -3123,8 +3122,8 @@ void cProtocol172::WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_ //////////////////////////////////////////////////////////////////////////////// // cProtocol176: -cProtocol176::cProtocol176(cClientHandle * a_Client, const AString &a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) : - super(a_Client, a_ServerAddress, a_ServerPort, a_State) +cProtocol176::cProtocol176(const AString a_LogID) : + super(a_LogID) { } diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 16a4e972e..a98910bc3 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -53,7 +53,7 @@ class cProtocol172 : public: - cProtocol172(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State); + cProtocol172(const AString a_LogID); /** Sending stuff to clients (alphabetically sorted): */ virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override; @@ -139,6 +139,7 @@ public: virtual AString GetAuthServerID(void) override { return m_AuthServerID; } + protected: typedef std::vector> ActionList; @@ -247,7 +248,7 @@ class cProtocol176 : typedef cProtocol172 super; public: - cProtocol176(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State); + cProtocol176(const AString a_LogID); // cProtocol172 overrides: virtual void SendPlayerSpawn(const cPlayer & a_Player) override; diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index d40fd97d6..8867ba21e 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -1,5 +1,4 @@ -#if 0 // Protocol18x.cpp @@ -12,7 +11,9 @@ Implements the 1.8.x protocol classes: #include "Globals.h" #include "json/json.h" +#include "zlib/zlib.h" #include "Protocol18x.h" +#if 0 #include "ChunkDataSerializer.h" #include "PolarSSL++/Sha1Checksum.h" #include "Packetizer.h" @@ -85,10 +86,10 @@ static const Int16 SLOT_NUM_OUTSIDE = -999; - const int MAX_ENC_LEN = 512; // Maximum size of the encrypted message; should be 128, but who knows... +#endif const uLongf MAX_COMPRESSED_PACKET_LEN = 200 KiB; // Maximum size of compressed packets. - +#if 0 @@ -1636,7 +1637,7 @@ void cProtocol180::SendWindowProperty(const cWindow & a_Window, short a_Property } - +#endif bool cProtocol180::CompressPacket(const AString & a_Packet, AString & a_CompressedData) @@ -1680,7 +1681,7 @@ bool cProtocol180::CompressPacket(const AString & a_Packet, AString & a_Compress - +#if 0 int cProtocol180::GetParticleID(const AString & a_ParticleName) { @@ -2918,8 +2919,6 @@ void cProtocol180::SendPacket(cPacketizer & a_Pkt) if ((m_State == 3) && (PacketLen >= 256)) { - // Compress the packet payload: - if (!cProtocol180::CompressPacket(PacketData, CompressedPacket)) { return; } diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h index 97169ec90..51d591e68 100644 --- a/src/Protocol/Protocol18x.h +++ b/src/Protocol/Protocol18x.h @@ -55,7 +55,7 @@ class cProtocol180 : public: - cProtocol180(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State); + cProtocol180(const AString a_LogID); /** Sending stuff to clients (alphabetically sorted): */ virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override; @@ -257,6 +257,8 @@ protected: /** Writes the block entity data for the specified block entity into the packet. */ void WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity & a_BlockEntity); + + virtual cProtocolError OnDataAddedToBuffer(cByteBuffer & a_ByteBuffer, std::vector> & a_Actions) override WARN_UNUSED; } ; diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index c8e1cba1b..40d4222fe 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -18,10 +18,9 @@ -#if 0 -cProtocolRecognizer::cProtocolRecognizer(cClientHandle * a_Client) : - super(a_Client), +cProtocolRecognizer::cProtocolRecognizer(AString a_LogID) : + super(a_LogID), m_Protocol(nullptr), m_Buffer(8192) // We need a larger buffer to support BungeeCord - it sends one huge packet at the start { @@ -31,16 +30,6 @@ cProtocolRecognizer::cProtocolRecognizer(cClientHandle * a_Client) : -cProtocolRecognizer::~cProtocolRecognizer() -{ - delete m_Protocol; - m_Protocol = nullptr; -} - - - - - AString cProtocolRecognizer::GetVersionTextFromInt(int a_ProtocolVersion) { switch (a_ProtocolVersion) @@ -57,30 +46,30 @@ AString cProtocolRecognizer::GetVersionTextFromInt(int a_ProtocolVersion) -void cProtocolRecognizer::DataReceived(const char * a_Data, size_t a_Size) +cProtocol::cProtocolError cProtocolRecognizer::DataReceived(const char * a_Data, size_t a_Size, std::vector> & a_Actions) { if (m_Protocol == nullptr) { if (!m_Buffer.Write(a_Data, a_Size)) { - m_Client->Kick("Unsupported protocol version"); - return; + return cProtocolError::PacketReadError; } - - if (!TryRecognizeProtocol()) + + auto recognized = TryRecognizeProtocol(a_Actions); + if (recognized != cProtocolError::Success) { - return; + return recognized; } // The protocol has just been recognized, dump the whole m_Buffer contents into it for parsing: AString Dump; m_Buffer.ResetRead(); m_Buffer.ReadAll(Dump); - m_Protocol->DataReceived(Dump.data(), Dump.size()); + return m_Protocol->DataReceived(Dump.data(), Dump.size(), a_Actions); } else { - m_Protocol->DataReceived(a_Data, a_Size); + return m_Protocol->DataReceived(a_Data, a_Size, a_Actions); } } @@ -340,10 +329,10 @@ void cProtocolRecognizer::SendGameMode(eGameMode a_GameMode) -void cProtocolRecognizer::SendHealth(void) +void cProtocolRecognizer::SendHealth(int a_Health, int a_FoodLevel, double a_FoodSaturationLevel) { ASSERT(m_Protocol != nullptr); - m_Protocol->SendHealth(); + m_Protocol->SendHealth(a_Health, a_FoodLevel, a_FoodSaturationLevel); } @@ -400,10 +389,10 @@ void cProtocolRecognizer::SendLogin(const cPlayer & a_Player, const cWorld & a_W -void cProtocolRecognizer::SendLoginSuccess(void) +void cProtocolRecognizer::SendLoginSuccess(const AString & a_UUID, const AString & a_Username) { ASSERT(m_Protocol != nullptr); - m_Protocol->SendLoginSuccess(); + m_Protocol->SendLoginSuccess(a_UUID, a_Username); } @@ -459,10 +448,10 @@ void cProtocolRecognizer::SendPickupSpawn(const cPickup & a_Pickup) -void cProtocolRecognizer::SendPlayerAbilities(void) +void cProtocolRecognizer::SendPlayerAbilities(const cPlayer & a_Player) { ASSERT(m_Protocol != nullptr); - m_Protocol->SendPlayerAbilities(); + m_Protocol->SendPlayerAbilities(a_Player); } @@ -529,30 +518,30 @@ void cProtocolRecognizer::SendPlayerListUpdateDisplayName(const cPlayer & a_Play -void cProtocolRecognizer::SendPlayerMaxSpeed(void) +void cProtocolRecognizer::SendPlayerMaxSpeed(const cPlayer & a_Player) { ASSERT(m_Protocol != nullptr); - m_Protocol->SendPlayerMaxSpeed(); + m_Protocol->SendPlayerMaxSpeed(a_Player); } -void cProtocolRecognizer::SendPlayerMoveLook(void) +void cProtocolRecognizer::SendPlayerMoveLook(const cPlayer & a_Player) { ASSERT(m_Protocol != nullptr); - m_Protocol->SendPlayerMoveLook(); + m_Protocol->SendPlayerMoveLook(a_Player); } -void cProtocolRecognizer::SendPlayerPosition(void) +void cProtocolRecognizer::SendPlayerPosition(const cPlayer & a_Player) { ASSERT(m_Protocol != nullptr); - m_Protocol->SendPlayerPosition(); + m_Protocol->SendPlayerPosition(a_Player); } @@ -599,20 +588,20 @@ void cProtocolRecognizer::SendResetTitle(void) -void cProtocolRecognizer::SendRespawn(eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) +void cProtocolRecognizer::SendRespawn(eGameMode a_GameMode, eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) { ASSERT(m_Protocol != nullptr); - m_Protocol->SendRespawn(a_Dimension, a_ShouldIgnoreDimensionChecks); + m_Protocol->SendRespawn(a_GameMode, a_Dimension, a_ShouldIgnoreDimensionChecks); } -void cProtocolRecognizer::SendExperience(void) +void cProtocolRecognizer::SendExperience(const cPlayer & a_Player) { ASSERT(m_Protocol != nullptr); - m_Protocol->SendExperience(); + m_Protocol->SendExperience(a_Player); } @@ -869,10 +858,10 @@ void cProtocolRecognizer::SendWeather(eWeather a_Weather) -void cProtocolRecognizer::SendWholeInventory(const cWindow & a_Window) +void cProtocolRecognizer::SendWholeInventory(const cPlayer & a_Player, const cWindow & a_Window) { ASSERT(m_Protocol != nullptr); - m_Protocol->SendWholeInventory(a_Window); + m_Protocol->SendWholeInventory(a_Player, a_Window); } @@ -908,18 +897,18 @@ AString cProtocolRecognizer::GetAuthServerID(void) - +#if 0 void cProtocolRecognizer::SendData(const char * a_Data, size_t a_Size) { // This is used only when handling the server ping m_Client->SendData(a_Data, a_Size); } +#endif - -bool cProtocolRecognizer::TryRecognizeProtocol(void) +cProtocol::cProtocolError cProtocolRecognizer::TryRecognizeProtocol(std::vector> & a_Actions) { // NOTE: If a new protocol is added or an old one is removed, adjust MCS_CLIENT_VERSIONS and // MCS_PROTOCOL_VERSIONS macros in the header file, as well as PROTO_VERSION_LATEST macro @@ -930,47 +919,48 @@ bool cProtocolRecognizer::TryRecognizeProtocol(void) if (!m_Buffer.ReadVarInt(PacketLen)) { // Not enough bytes for the packet length, keep waiting - return false; + return cProtocolError::NotCompleted; } ReadSoFar -= static_cast(m_Buffer.GetReadableSpace()); if (!m_Buffer.CanReadBytes(PacketLen)) { // Not enough bytes for the packet, keep waiting - return false; + return cProtocolError::NotCompleted; } - return TryRecognizeLengthedProtocol(PacketLen - ReadSoFar); + return TryRecognizeLengthedProtocol(PacketLen - ReadSoFar, a_Actions); } -bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRemaining) +cProtocol::cProtocolError cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRemaining, std::vector> & a_Actions) { UInt32 PacketType; if (!m_Buffer.ReadVarInt(PacketType)) { - return false; + return cProtocolError::NotCompleted; } if (PacketType != 0x00) { // Not an initial handshake packet, we don't know how to talk to them LOGINFO("Client \"%s\" uses an unsupported protocol (lengthed, initial packet %u)", - m_Client->GetIPString().c_str(), PacketType + m_LogID.c_str(), PacketType ); - m_Client->Kick("Unsupported protocol version"); - return false; + return cProtocolError::UnsupportedProtocol; } UInt32 ProtocolVersion; if (!m_Buffer.ReadVarInt(ProtocolVersion)) { - return false; + return cProtocolError::NotCompleted; } - m_Client->SetProtocolVersion(ProtocolVersion); + a_Actions.push_back(cpp14::make_unique(cClientAction::Type::SetProtocolVersion)); switch (ProtocolVersion) { case PROTO_VERSION_1_7_2: { + m_Buffer.ResetRead(); + /* AString ServerAddress; UInt16 ServerPort; UInt32 NextState; @@ -987,11 +977,14 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema break; } m_Buffer.CommitRead(); - m_Protocol = new cProtocol172(m_Client, ServerAddress, ServerPort, NextState); - return true; + */ + m_Protocol = cpp14::make_unique(m_LogID); + return m_Protocol->HandleHandshake(m_Buffer, a_Actions); } case PROTO_VERSION_1_7_6: { + m_Buffer.ResetRead(); + /* AString ServerAddress; UInt16 ServerPort; UInt32 NextState; @@ -1008,11 +1001,13 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema break; } m_Buffer.CommitRead(); - m_Protocol = new cProtocol176(m_Client, ServerAddress, ServerPort, NextState); - return true; + */ + m_Protocol = cpp14::make_unique(m_LogID); + return m_Protocol->HandleHandshake(m_Buffer, a_Actions); } case PROTO_VERSION_1_8_0: { + /* AString ServerAddress; UInt16 ServerPort; UInt32 NextState; @@ -1029,15 +1024,15 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema break; } m_Buffer.CommitRead(); - m_Protocol = new cProtocol180(m_Client, ServerAddress, ServerPort, NextState); - return true; + */ + m_Protocol = cpp14::make_unique(m_LogID); + return m_Protocol->HandleHandshake(m_Buffer, a_Actions); } } LOGINFO("Client \"%s\" uses an unsupported protocol (lengthed, version %u (0x%x))", - m_Client->GetIPString().c_str(), ProtocolVersion, ProtocolVersion + m_LogID.c_str(), ProtocolVersion, ProtocolVersion ); - m_Client->Kick("Unsupported protocol version"); - return false; + return cProtocolError::UnsupportedProtocol; } @@ -1051,7 +1046,5 @@ void cProtocolRecognizer::SendPacket(cPacketizer & a_Pkt) ASSERT(!"Function not to be called"); } -#endif - diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index 98dd95b17..5cbe8f2c3 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -38,8 +38,7 @@ public: PROTO_VERSION_1_8_0 = 47, } ; - cProtocolRecognizer(cClientHandle * a_Client); - virtual ~cProtocolRecognizer(); + cProtocolRecognizer(AString a_LogID); /** Translates protocol version number into protocol version text: 49 -> "1.4.4" */ static AString GetVersionTextFromInt(int a_ProtocolVersion); @@ -133,21 +132,25 @@ public: virtual void SendData(const char * a_Data, size_t a_Size) override; + cProtocolError HandleHandshake(cByteBuffer & a_ByteBuffer, std::vector> & a_Actions) override WARN_UNUSED; + protected: /** The recognized protocol */ - cProtocol * m_Protocol; + std::unique_ptr m_Protocol; /** Buffer for the incoming data until we recognize the protocol */ cByteBuffer m_Buffer; + + AString m_LogID; /** Tries to recognize protocol based on m_Buffer contents; returns true if recognized */ - bool TryRecognizeProtocol(void); + cProtocolError TryRecognizeProtocol(std::vector> & a_Actions); /** Tries to recognize a protocol in the lengthed family (1.7+), based on m_Buffer; returns true if recognized. The packet length and type have already been read, type is 0 The number of bytes remaining in the packet is passed as a_PacketLengthRemaining. */ - bool TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRemaining); + cProtocolError TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRemaining, std::vector> & a_Actions); /** Sends a single packet contained within the cPacketizer class. The cPacketizer's destructor calls this to send the contained packet; protocol may transform the data (compression in 1.8 etc). */ -- cgit v1.2.3