bool cProtocolRecognizer::TryRecognizeProtocol(void) { // 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 // Lengthed protocol, try if it has the entire initial handshake packet: UInt32 PacketLen; UInt32 ReadSoFar = static_cast<UInt32>(m_Buffer.GetReadableSpace()); if (!m_Buffer.ReadVarInt(PacketLen)) { // Not enough bytes for the packet length, keep waiting return false; } ReadSoFar -= static_cast<UInt32>(m_Buffer.GetReadableSpace()); if (!m_Buffer.CanReadBytes(PacketLen)) { // Not enough bytes for the packet, keep waiting return false; } return TryRecognizeLengthedProtocol(PacketLen - ReadSoFar); }
bool cProtocolRecognizer::TryRecognizeProtocol(void) { // 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 // The first packet should be a Handshake, 0x02: unsigned char PacketType; if (!m_Buffer.ReadByte(PacketType)) { return false; } switch (PacketType) { case 0x02: return TryRecognizeLengthlessProtocol(); // Handshake, continue recognizing case 0xfe: { // This may be either a packet length or the length-less Ping packet Byte NextByte; if (!m_Buffer.ReadByte(NextByte)) { // Not enough data for either protocol // This could actually happen with the 1.2 / 1.3 client, but their support is fading out anyway return false; } if (NextByte != 0x01) { // This is definitely NOT a length-less Ping packet, handle as lengthed protocol: break; } if (!m_Buffer.ReadByte(NextByte)) { // There is no more data. Although this *could* mean TCP fragmentation, it is highly unlikely // and rather this is a 1.4 client sending a regular Ping packet (without the following Plugin message) SendLengthlessServerPing(); return false; } if (NextByte == 0xfa) { // Definitely a length-less Ping followed by a Plugin message SendLengthlessServerPing(); return false; } // Definitely a lengthed Initial handshake, handle below: break; } } // switch (PacketType) // This must be a lengthed protocol, try if it has the entire initial handshake packet: m_Buffer.ResetRead(); UInt32 PacketLen; UInt32 ReadSoFar = (UInt32)m_Buffer.GetReadableSpace(); if (!m_Buffer.ReadVarInt(PacketLen)) { // Not enough bytes for the packet length, keep waiting return false; } ReadSoFar -= (UInt32)m_Buffer.GetReadableSpace(); if (!m_Buffer.CanReadBytes(PacketLen)) { // Not enough bytes for the packet, keep waiting return false; } return TryRecognizeLengthedProtocol(PacketLen - ReadSoFar); }