From b4f9c501b3dd33ff740b917c6ba83cfb99977e61 Mon Sep 17 00:00:00 2001 From: Dan Mulloy Date: Sun, 14 May 2017 21:37:36 -0400 Subject: [PATCH] 1.12 hotfix: delay injection for network manager Fixes #332, fixes #330 --- .../injector/netty/ProtocolInjector.java | 46 +++++++++++++------ 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/modules/ProtocolLib/src/main/java/com/comphenix/protocol/injector/netty/ProtocolInjector.java b/modules/ProtocolLib/src/main/java/com/comphenix/protocol/injector/netty/ProtocolInjector.java index e0a349c4..ea75052b 100644 --- a/modules/ProtocolLib/src/main/java/com/comphenix/protocol/injector/netty/ProtocolInjector.java +++ b/modules/ProtocolLib/src/main/java/com/comphenix/protocol/injector/netty/ProtocolInjector.java @@ -16,18 +16,11 @@ */ package com.comphenix.protocol.injector.netty; -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandler; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.channel.ChannelInitializer; - import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; import java.net.InetSocketAddress; import java.util.List; import java.util.Set; @@ -57,6 +50,14 @@ import com.comphenix.protocol.reflect.VolatileField; import com.comphenix.protocol.utility.MinecraftReflection; import com.google.common.collect.Lists; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandler; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.ChannelInitializer; + public class ProtocolInjector implements ChannelListener { public static final ReportType REPORT_CANNOT_INJECT_INCOMING_CHANNEL = new ReportType("Unable to inject incoming channel %s."); @@ -139,11 +140,12 @@ public class ProtocolInjector implements ChannelListener { // Handle connected channels final ChannelInboundHandler endInitProtocol = new ChannelInitializer() { @Override - protected void initChannel(Channel channel) throws Exception { + protected void initChannel(final Channel channel) throws Exception { try { - // This can take a while, so we need to stop the main thread from interfering + // TODO I don't like this synchronized (networkManagers) { - injectionFactory.fromChannel(channel, ProtocolInjector.this, playerFactory).inject(); + channel.eventLoop().submit(() -> + injectionFactory.fromChannel(channel, ProtocolInjector.this, playerFactory).inject()); } } catch (Exception e) { reporter.reportDetailed(ProtocolInjector.this, Report.newBuilder(REPORT_CANNOT_INJECT_INCOMING_CHANNEL).messageParam(channel).error(e)); @@ -171,9 +173,26 @@ public class ProtocolInjector implements ChannelListener { ctx.fireChannelRead(msg); } }; + + FuzzyReflection fuzzy = FuzzyReflection.fromObject(serverConnection, true); - // Get the current NetworkMananger list - networkManagers = (List) FuzzyReflection.fromObject(serverConnection, true).invokeMethod(null, "getNetworkManagers", List.class, serverConnection); + try { + List fields = fuzzy.getFieldListByType(List.class); + for (Field field : fields) { + ParameterizedType param = (ParameterizedType) field.getGenericType(); + if (param.getActualTypeArguments()[0].equals(MinecraftReflection.getNetworkManagerClass())) { + field.setAccessible(true); + networkManagers = (List) field.get(serverConnection); + } + } + } catch (Exception ex) { + networkManagers = (List) fuzzy.getMethodByParameters("getNetworkManagers", List.class, serverConnection.getClass()) + .invoke(null, serverConnection); + } + + if (networkManagers == null) { + throw new RuntimeException("Failed to obtain list of network managers."); + } // Insert ProtocolLib's connection interceptor bootstrapFields = getBootstrapFields(serverConnection); @@ -191,7 +210,6 @@ public class ProtocolInjector implements ChannelListener { } injected = true; - } catch (Exception e) { throw new RuntimeException("Unable to inject channel futures.", e); }