diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/netty/ChannelInjector.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/netty/ChannelInjector.java index e6434a4c..f552ac30 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/netty/ChannelInjector.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/netty/ChannelInjector.java @@ -64,6 +64,7 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector { public static final ReportType REPORT_CANNOT_INTERCEPT_CLIENT_PACKET = new ReportType("Unable to intercept a read client packet."); public static final ReportType REPORT_CANNOT_EXECUTE_IN_CHANNEL_THREAD = new ReportType("Cannot execute code in channel thread."); public static final ReportType REPORT_CANNOT_FIND_GET_VERSION = new ReportType("Cannot find getVersion() in NetworkMananger"); + public static final ReportType REPORT_CANNOT_SEND_PACKET = new ReportType("Unable to send packet %s to %s"); /** * Indicates that a packet has bypassed packet listeners. @@ -668,8 +669,9 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector { } else { MinecraftMethods.getSendPacketMethod().invoke(getPlayerConnection(), packet); } - } catch (Exception e) { - throw new RuntimeException("Unable to send server packet " + packet, e); + } catch (Throwable ex) { + ProtocolLibrary.getErrorReporter().reportWarning(factory.getPlugin(), + Report.newBuilder(REPORT_CANNOT_SEND_PACKET).messageParam(packet, playerName).error(ex).build()); } } diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkServerInjector.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkServerInjector.java index cbdaa0e8..17e2513c 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkServerInjector.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkServerInjector.java @@ -126,7 +126,7 @@ class NetworkServerInjector extends PlayerInjector { return; if (!tryInjectManager()) { - Class serverHandlerClass = MinecraftReflection.getNetServerHandlerClass(); + Class serverHandlerClass = MinecraftReflection.getPlayerConnectionClass(); // Try to override the proxied object if (proxyServerField != null) { diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjector.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjector.java index c74b5f6d..62683c6e 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjector.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjector.java @@ -188,7 +188,7 @@ public abstract class PlayerInjector implements SocketInjector { // Retrieve the server handler if (serverHandlerField == null) { serverHandlerField = FuzzyReflection.fromObject(notchEntity).getFieldByType( - "NetServerHandler", MinecraftReflection.getNetServerHandlerClass()); + "NetServerHandler", MinecraftReflection.getPlayerConnectionClass()); proxyServerField = getProxyField(notchEntity, serverHandlerField); } @@ -402,7 +402,7 @@ public abstract class PlayerInjector implements SocketInjector { FuzzyReflection reflection = FuzzyReflection.fromObject(currentHandler, true); // It might be - return reflection.getFieldByType("NetServerHandler", MinecraftReflection.getNetServerHandlerClass()); + return reflection.getFieldByType("NetServerHandler", MinecraftReflection.getPlayerConnectionClass()); } catch (RuntimeException e) { // Damn @@ -428,7 +428,7 @@ public abstract class PlayerInjector implements SocketInjector { Class clazz = obj.getClass(); return MinecraftReflection.getNetLoginHandlerClass().equals(clazz) || - MinecraftReflection.getNetServerHandlerClass().equals(clazz); + MinecraftReflection.getPlayerConnectionClass().equals(clazz); } /** @@ -601,7 +601,7 @@ public abstract class PlayerInjector implements SocketInjector { final Object handler = getNetHandler(true); // Is this a net server class? - if (MinecraftReflection.getNetServerHandlerClass().isAssignableFrom(handler.getClass())) { + if (MinecraftReflection.getPlayerConnectionClass().isAssignableFrom(handler.getClass())) { setUpdatedPlayer( (Player) MinecraftReflection.getBukkitEntity(getEntityPlayer(handler)) ); diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftFields.java b/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftFields.java index 428fbcd3..88353730 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftFields.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftFields.java @@ -5,6 +5,7 @@ import org.bukkit.entity.Player; import com.comphenix.protocol.injector.BukkitUnwrapper; import com.comphenix.protocol.reflect.accessors.Accessors; import com.comphenix.protocol.reflect.accessors.FieldAccessor; +import com.google.common.base.Preconditions; /** * Retrieve the content of well-known fields in Minecraft. @@ -29,7 +30,7 @@ public class MinecraftFields { if (NETWORK_ACCESSOR == null) { Class networkClass = MinecraftReflection.getNetworkManagerClass(); - Class connectionClass = MinecraftReflection.getNetServerHandlerClass(); + Class connectionClass = MinecraftReflection.getPlayerConnectionClass(); NETWORK_ACCESSOR = Accessors.getFieldAccessor(connectionClass, networkClass, true); } // Retrieve the network manager @@ -41,7 +42,7 @@ public class MinecraftFields { } /** - * Retrieve the player connection (or NetServerHandler) associated with a player. + * Retrieve the PlayerConnection (or NetServerHandler) associated with a player. * @param player - the player. * @return The player connection. */ @@ -51,8 +52,10 @@ public class MinecraftFields { // Retrieve player connection from a native instance private static Object getPlayerConnection(Object nmsPlayer) { + Preconditions.checkNotNull(nmsPlayer, "nmsPlayer cannot be null!"); + if (CONNECTION_ACCESSOR == null) { - Class connectionClass = MinecraftReflection.getNetServerHandlerClass(); + Class connectionClass = MinecraftReflection.getPlayerConnectionClass(); CONNECTION_ACCESSOR = Accessors.getFieldAccessor(nmsPlayer.getClass(), connectionClass, true); } return CONNECTION_ACCESSOR.get(nmsPlayer); diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftMethods.java b/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftMethods.java index 810b23fb..3a4845e7 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftMethods.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftMethods.java @@ -41,7 +41,7 @@ public class MinecraftMethods { */ public static Method getSendPacketMethod() { if (sendPacketMethod == null) { - Class serverHandlerClass = MinecraftReflection.getNetServerHandlerClass(); + Class serverHandlerClass = MinecraftReflection.getPlayerConnectionClass(); try { sendPacketMethod = FuzzyReflection.fromClass(serverHandlerClass).getMethodByName("sendPacket.*"); diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java b/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java index e0a7675d..ba016e42 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java @@ -463,7 +463,7 @@ public class MinecraftReflection { * @return TRUE if it is, FALSE otherwise. */ public static boolean isServerHandler(Object obj) { - return obj != null && getNetServerHandlerClass().isAssignableFrom(obj.getClass()); + return obj != null && getPlayerConnectionClass().isAssignableFrom(obj.getClass()); } /** @@ -685,7 +685,7 @@ public class MinecraftReflection { } // Select a method with one Minecraft object parameter - Method selected = FuzzyReflection.fromClass(getNetServerHandlerClass()). + Method selected = FuzzyReflection.fromClass(getPlayerConnectionClass()). getMethod(FuzzyMethodContract.newBuilder(). parameterMatches(paketContract, 0). parameterCount(1). @@ -974,16 +974,16 @@ public class MinecraftReflection { } /** - * Retrieve the NetServerHandler class (or PlayerConnection) - * @return The NetServerHandler class. + * Retrieve the PlayerConnection class (or NetServerHandler) + * @return The PlayerConnection class. */ - public static Class getNetServerHandlerClass() { + public static Class getPlayerConnectionClass() { try { - return getMinecraftClass("NetServerHandler", "PlayerConnection"); + return getMinecraftClass("PlayerConnection", "NetServerHandler"); } catch (RuntimeException e) { try { // Use the player connection field - return setMinecraftClass("NetServerHandler", + return setMinecraftClass("PlayerConnection", FuzzyReflection.fromClass(getEntityPlayerClass()). getFieldByType("playerConnection", getNetHandlerClass()).getType() ); @@ -1012,7 +1012,7 @@ public class MinecraftReflection { FuzzyFieldContract.newBuilder().typeMatches(playerConnection).build() ).getType(); - return setMinecraftClass("NetServerHandler", fieldType); + return setMinecraftClass("PlayerConnection", fieldType); } } } @@ -1025,7 +1025,7 @@ public class MinecraftReflection { try { return getMinecraftClass("INetworkManager", "NetworkManager"); } catch (RuntimeException e) { - Constructor selected = FuzzyReflection.fromClass(getNetServerHandlerClass()). + Constructor selected = FuzzyReflection.fromClass(getPlayerConnectionClass()). getConstructor(FuzzyMethodContract.newBuilder(). parameterSuperOf(getMinecraftServerClass(), 0). parameterSuperOf(getEntityPlayerClass(), 2). @@ -1304,7 +1304,7 @@ public class MinecraftReflection { } else { serverConnectionContract. method(FuzzyMethodContract.newBuilder(). - parameterExactType(getNetServerHandlerClass())); + parameterExactType(getPlayerConnectionClass())); selected = FuzzyReflection.fromClass(getMinecraftServerClass()). getMethod(FuzzyMethodContract.newBuilder(). @@ -1454,7 +1454,7 @@ public class MinecraftReflection { field(FuzzyFieldContract.newBuilder(). typeDerivedOf(List.class)). method(FuzzyMethodContract.newBuilder(). - parameterExactType(getNetServerHandlerClass())). + parameterExactType(getPlayerConnectionClass())). build(); Field selected = FuzzyReflection.fromClass(MinecraftReflection.getMinecraftServerClass(), true). diff --git a/ProtocolLib/src/test/java/com/comphenix/protocol/utility/MinecraftReflectionTest.java b/ProtocolLib/src/test/java/com/comphenix/protocol/utility/MinecraftReflectionTest.java index 5f5bb311..1b6f08e7 100644 --- a/ProtocolLib/src/test/java/com/comphenix/protocol/utility/MinecraftReflectionTest.java +++ b/ProtocolLib/src/test/java/com/comphenix/protocol/utility/MinecraftReflectionTest.java @@ -11,6 +11,7 @@ import net.minecraft.server.v1_8_R3.IChatBaseComponent; import net.minecraft.server.v1_8_R3.IChatBaseComponent.ChatSerializer; import net.minecraft.server.v1_8_R3.NBTCompressedStreamTools; import net.minecraft.server.v1_8_R3.PacketPlayOutUpdateAttributes.AttributeSnapshot; +import net.minecraft.server.v1_8_R3.PlayerConnection; import net.minecraft.server.v1_8_R3.ServerPing; import net.minecraft.server.v1_8_R3.ServerPing.ServerData; import net.minecraft.server.v1_8_R3.ServerPing.ServerPingPlayerSample; @@ -94,6 +95,11 @@ public class MinecraftReflectionTest { assertEquals(ChunkCoordIntPair.class, MinecraftReflection.getChunkCoordIntPair()); } + @Test + public void testPlayerConnection() { + assertEquals(PlayerConnection.class, MinecraftReflection.getPlayerConnectionClass()); + } + @Test public void testServerPing() { assertEquals(ServerPing.class, MinecraftReflection.getServerPingClass());