protected void setProtocol(final Channel channel, final ByteBuf input, ProtocolVersion version) throws Exception { if (protocolSet) { return; } protocolSet = true; ProtocolStorage.setProtocolVersion(Utils.getNetworkManagerSocketAddress(channel), version); channel.pipeline().remove(ChannelHandlers.INITIAL_DECODER); pipelineBuilders.get(version).buildPipeLine(channel, version); input.readerIndex(0); channel.pipeline().firstContext().fireChannelRead(input); }
@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); } }
public class AsyncErrorLogger { private static final boolean enabled = Utils.getJavaPropertyValue( "protocolsupport.errlog.errlog", true, Converter.STRING_TO_BOOLEAN); private static final long maxFileSize = Utils.getJavaPropertyValue( "protocolsupport.errlog.maxsize", 1024L * 1024L * 20L, Converter.STRING_TO_LONG); private static final String filePath = Utils.getJavaPropertyValue( "protocolsupport.errlog.path", JavaPlugin.getPlugin(ProtocolSupport.class).getName() + "-errlog", Converter.NONE); public static final AsyncErrorLogger INSTANCE = new AsyncErrorLogger(); private final ExecutorService executor = Executors.newSingleThreadExecutor( new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r, JavaPlugin.getPlugin(ProtocolSupport.class) + "-errlog-thread"); } }); public void start() {} public void stop() { executor.shutdown(); try { executor.awaitTermination(10, TimeUnit.SECONDS); } catch (InterruptedException e) { } synchronized (writer) { if (writer != null) { writer.close(); } } } private PrintWriter writer; private AsyncErrorLogger() { if (!enabled) { stop(); return; } try { File logfile = new File(filePath); if (logfile.length() > maxFileSize) { logfile.delete(); } logfile.createNewFile(); writer = new PrintWriter(new FileOutputStream(logfile, true)); } catch (Exception e) { ProtocolSupport.logWarning("Unable to create error log"); stop(); } } public void log(final Throwable t, final Object... info) { if (executor.isShutdown()) { return; } try { executor.submit( new Runnable() { @Override public void run() { synchronized (writer) { writer.println( "Error occured at " + new SimpleDateFormat("yyyy-MM-dd-HH-mm", Locale.ROOT).format(new Date())); writer.println("Additional info: " + StringUtils.join(info, ", ")); writer.println("Exception class: " + t.getClass().getName()); writer.println("Exception message: " + t.getMessage()); writer.println("Exception log:"); t.printStackTrace(writer); writer.println(); } } }); } catch (RejectedExecutionException e) { } } }