From bdcd7f1f545dc70b1e05acde029d3c872525fb2f Mon Sep 17 00:00:00 2001 From: "Kristian S. Stangeland" Date: Tue, 5 Feb 2013 16:06:49 +0100 Subject: [PATCH] Ensure that ProtocolLib works with VanishNoPacket and Spigot --- .../injector/player/PlayerInjector.java | 15 ++++++++---- .../injector/spigot/SpigotPacketInjector.java | 23 +++++++++++++++++-- .../protocol/utility/MinecraftReflection.java | 13 ++++++++++- 3 files changed, 44 insertions(+), 7 deletions(-) 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 d3f0109a..8f84cdd0 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 @@ -135,7 +135,7 @@ abstract class PlayerInjector { //Dispatch to the correct injection method if (injectionSource instanceof Player) - initializePlayer(injectionSource); + initializePlayer((Player) injectionSource); else if (MinecraftReflection.isLoginHandler(injectionSource)) initializeLogin(injectionSource); else @@ -146,10 +146,12 @@ abstract class PlayerInjector { * Initialize the player injector using an actual player instance. * @param player - the player to hook. */ - public void initializePlayer(Object player) { - + public void initializePlayer(Player player) { Object notchEntity = getEntityPlayer((Player) player); + // Save the player too + this.player = player; + if (!hasInitialized) { // Do this first, in case we encounter an exception hasInitialized = true; @@ -174,11 +176,16 @@ abstract class PlayerInjector { } /** - * Initialize the player injector for a NetLoginHandler instead. + * Initialize the player injector from a NetLoginHandler. * @param netLoginHandler - the net login handler to inject. */ public void initializeLogin(Object netLoginHandler) { if (!hasInitialized) { + // Just in case + if (!MinecraftReflection.isLoginHandler(netLoginHandler)) + throw new IllegalArgumentException("netLoginHandler (" + netLoginHandler + ") is not a " + + MinecraftReflection.getNetLoginHandlerName()); + hasInitialized = true; loginHandler = netLoginHandler; diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/spigot/SpigotPacketInjector.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/spigot/SpigotPacketInjector.java index 1ff5ca62..e52bd2e4 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/spigot/SpigotPacketInjector.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/spigot/SpigotPacketInjector.java @@ -1,5 +1,6 @@ package com.comphenix.protocol.injector.spigot; +import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Collections; @@ -29,6 +30,7 @@ import com.comphenix.protocol.injector.PlayerLoggedOutException; import com.comphenix.protocol.injector.packet.PacketInjector; import com.comphenix.protocol.injector.player.NetworkObjectInjector; import com.comphenix.protocol.injector.player.PlayerInjectionHandler; +import com.comphenix.protocol.reflect.FuzzyReflection; import com.comphenix.protocol.reflect.MethodInfo; import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract; import com.comphenix.protocol.utility.MinecraftReflection; @@ -44,6 +46,9 @@ public class SpigotPacketInjector implements SpigotPacketListener { private static volatile Class spigotListenerClass; private static volatile boolean classChecked; + // Retrieve the entity player from a PlayerConnection + private static Field playerConnectionPlayer; + // Packets that are not to be processed by the filters private Set ignoredPackets = Collections.newSetFromMap(new MapMaker().weakKeys().makeMap()); @@ -255,8 +260,22 @@ public class SpigotPacketInjector implements SpigotPacketListener { try { NetworkObjectInjector created = new NetworkObjectInjector(classLoader, reporter, null, invoker, null); - created.initializeLogin(connection); - created.setPlayer(created.createTemporaryPlayer(server)); + if (MinecraftReflection.isLoginHandler(connection)) { + created.initialize(connection); + created.setPlayer(created.createTemporaryPlayer(server)); + } else if (MinecraftReflection.isServerHandler(connection)) { + // Get the player instead + if (playerConnectionPlayer == null) + playerConnectionPlayer = FuzzyReflection.fromObject(connection). + getFieldByType("player", MinecraftReflection.getEntityPlayerClass()); + Object entityPlayer = playerConnectionPlayer.get(connection); + + created.initialize(MinecraftReflection.getBukkitEntity(entityPlayer)); + + } else { + throw new IllegalArgumentException("Unregonized connection in NetworkManager."); + } + dummyInjector = saveInjector(networkManager, created); } catch (IllegalAccessException e) { 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 cd18d71d..3717fe1d 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java @@ -289,7 +289,7 @@ public class MinecraftReflection { } /** - * Determine if the given object is a NetLoginHandler. + * Determine if the given object is a NetLoginHandler (PendingConnection) * @param obj - the given object. * @return TRUE if it is, FALSE otherwise. */ @@ -297,6 +297,15 @@ public class MinecraftReflection { return getNetLoginHandlerClass().isAssignableFrom(obj.getClass()); } + /** + * Determine if the given object is assignable to a NetServerHandler (PlayerConnection) + * @param obj - the given object. + * @return TRUE if it is, FALSE otherwise. + */ + public static boolean isServerHandler(Object obj) { + return getNetServerHandlerClass().isAssignableFrom(obj.getClass()); + } + /** * Determine if the given object is actually a Minecraft packet. * @param obj - the given object. @@ -1102,4 +1111,6 @@ public class MinecraftReflection { public static String getNetLoginHandlerName() { return getNetLoginHandlerClass().getSimpleName(); } + + }