@Override public void channelRead(final ChannelHandlerContext ctx, final Object inputObj) throws Exception { try { final ByteBuf input = (ByteBuf) inputObj; if (!input.isReadable()) { return; } final Channel channel = ctx.channel(); receivedData.writeBytes(input); ProtocolVersion handshakeversion = ProtocolVersion.NOT_SET; receivedData.readerIndex(0); int firstbyte = receivedData.readUnsignedByte(); switch (firstbyte) { case 0xFE: { // old ping try { if (receivedData.readableBytes() == 0) { // really old protocol probably scheduleTask(ctx, new Ping11ResponseTask(channel), 1000, TimeUnit.MILLISECONDS); } else if (receivedData.readUnsignedByte() == 1) { if (receivedData.readableBytes() == 0) { // 1.5.2 probably scheduleTask( ctx, new Ping152ResponseTask(this, channel), 500, TimeUnit.MILLISECONDS); } else if ((receivedData.readUnsignedByte() == 0xFA) && "MC|PingHost" .equals( new String( Utils.toArray( receivedData.readBytes(receivedData.readUnsignedShort() * 2)), StandardCharsets.UTF_16BE))) { // 1.6.* receivedData.readUnsignedShort(); handshakeversion = ProtocolVersion.fromId(receivedData.readUnsignedByte()); } } } catch (IndexOutOfBoundsException ex) { } break; } case 0x02: { // 1.6 or 1.5.2 handshake try { handshakeversion = ProtocolVersion.fromId(receivedData.readUnsignedByte()); } catch (IndexOutOfBoundsException ex) { } break; } default: { // 1.7 or 1.8 handshake receivedData.readerIndex(0); ByteBuf data = getVarIntPrefixedData(receivedData); if (data != null) { handshakeversion = readNPHandshake(data); } break; } } // if we detected the protocol than we save it and process data if (handshakeversion != ProtocolVersion.NOT_SET) { setProtocol(channel, receivedData, handshakeversion); } } catch (Throwable t) { ctx.channel().close(); } finally { ReferenceCountUtil.release(inputObj); } }
private ProtocolVersion readNPHandshake(ByteBuf data) { if (readVarInt(data) == 0x00) { return ProtocolVersion.fromId(readVarInt(data)); } return ProtocolVersion.UNKNOWN; }