1.12 hotfix: delay injection for network manager
Fixes #332, fixes #330
Dieser Commit ist enthalten in:
Ursprung
1738c6f243
Commit
b4f9c501b3
@ -16,18 +16,11 @@
|
|||||||
*/
|
*/
|
||||||
package com.comphenix.protocol.injector.netty;
|
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.io.InputStream;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -57,6 +50,14 @@ import com.comphenix.protocol.reflect.VolatileField;
|
|||||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||||
import com.google.common.collect.Lists;
|
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 class ProtocolInjector implements ChannelListener {
|
||||||
public static final ReportType REPORT_CANNOT_INJECT_INCOMING_CHANNEL = new ReportType("Unable to inject incoming channel %s.");
|
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
|
// Handle connected channels
|
||||||
final ChannelInboundHandler endInitProtocol = new ChannelInitializer<Channel>() {
|
final ChannelInboundHandler endInitProtocol = new ChannelInitializer<Channel>() {
|
||||||
@Override
|
@Override
|
||||||
protected void initChannel(Channel channel) throws Exception {
|
protected void initChannel(final Channel channel) throws Exception {
|
||||||
try {
|
try {
|
||||||
// This can take a while, so we need to stop the main thread from interfering
|
// TODO I don't like this
|
||||||
synchronized (networkManagers) {
|
synchronized (networkManagers) {
|
||||||
injectionFactory.fromChannel(channel, ProtocolInjector.this, playerFactory).inject();
|
channel.eventLoop().submit(() ->
|
||||||
|
injectionFactory.fromChannel(channel, ProtocolInjector.this, playerFactory).inject());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
reporter.reportDetailed(ProtocolInjector.this, Report.newBuilder(REPORT_CANNOT_INJECT_INCOMING_CHANNEL).messageParam(channel).error(e));
|
reporter.reportDetailed(ProtocolInjector.this, Report.newBuilder(REPORT_CANNOT_INJECT_INCOMING_CHANNEL).messageParam(channel).error(e));
|
||||||
@ -172,8 +174,25 @@ public class ProtocolInjector implements ChannelListener {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get the current NetworkMananger list
|
FuzzyReflection fuzzy = FuzzyReflection.fromObject(serverConnection, true);
|
||||||
networkManagers = (List<Object>) FuzzyReflection.fromObject(serverConnection, true).invokeMethod(null, "getNetworkManagers", List.class, serverConnection);
|
|
||||||
|
try {
|
||||||
|
List<Field> 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<Object>) field.get(serverConnection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
networkManagers = (List<Object>) 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
|
// Insert ProtocolLib's connection interceptor
|
||||||
bootstrapFields = getBootstrapFields(serverConnection);
|
bootstrapFields = getBootstrapFields(serverConnection);
|
||||||
@ -191,7 +210,6 @@ public class ProtocolInjector implements ChannelListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
injected = true;
|
injected = true;
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Unable to inject channel futures.", e);
|
throw new RuntimeException("Unable to inject channel futures.", e);
|
||||||
}
|
}
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren