diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java b/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java index b4cd1bf2..1a83647b 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java @@ -87,6 +87,8 @@ public class ProtocolLibrary extends JavaPlugin { // Worker that ensures that async packets are eventually sent createAsyncTask(server); + addDebugListener(); + // Try to enable statistics try { statistisc = new Statistics(this); @@ -97,6 +99,20 @@ public class ProtocolLibrary extends JavaPlugin { } } + private void addDebugListener() { + // DEBUG DEBUG + protocolManager.addPacketListener(new MonitorAdapter(this, ConnectionSide.BOTH, logger) { + @Override + public void onPacketReceiving(PacketEvent event) { + System.out.println("RECEIVING " + event.getPacketID() + " from " + event.getPlayer().getName()); + }; + @Override + public void onPacketSending(PacketEvent event) { + System.out.println("SENDING " + event.getPacketID() + " to " + event.getPlayer().getName()); + } + }); + } + private void createAsyncTask(Server server) { try { if (asyncPacketTask >= 0) diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetLoginInjector.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetLoginInjector.java index 91815304..8a9c221d 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetLoginInjector.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetLoginInjector.java @@ -47,6 +47,7 @@ class NetLoginInjector { try { Player fakePlayer = tempPlayerFactory.createTemporaryPlayer(server); PlayerInjector injector = injectionHandler.injectPlayer(fakePlayer, inserting, GamePhase.LOGIN); + injector.updateOnLogin = true; // Associate the injector too InjectContainer container = (InjectContainer) fakePlayer; diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjectionHandler.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjectionHandler.java index 1210329d..419ee54e 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjectionHandler.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjectionHandler.java @@ -239,10 +239,7 @@ public class PlayerInjectionHandler { // Close any previously associated hooks before we proceed if (previous != null) { uninjectPlayer(previous.getPlayer()); - - // Update the player object too - previous.setPlayer(player); - + // Remove the "hooked" network manager in our instance as well if (previous instanceof NetworkObjectInjector) { injector.setNetworkManager(previous.getNetworkManager(), true); 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 21f84c42..cef84410 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 @@ -34,6 +34,7 @@ import net.sf.cglib.proxy.Factory; import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.entity.Player; +import com.comphenix.protocol.Packets; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketEvent; import com.comphenix.protocol.events.PacketListener; @@ -63,6 +64,8 @@ abstract class PlayerInjector { protected static Field netHandlerField; protected static Field socketField; + private static Field entityPlayerField; + // Whether or not we're using a proxy type private static boolean hasProxyType; @@ -100,6 +103,10 @@ abstract class PlayerInjector { // Scheduled action on the next packet event protected Runnable scheduledAction; + + // Whether or not to update the current player on the first Packet1Login + boolean updateOnLogin; + Player updatedPlayer; public PlayerInjector(Logger logger, Player player, ListenerInvoker invoker) throws IllegalAccessException { this.logger = logger; @@ -362,6 +369,18 @@ abstract class PlayerInjector { return netHandler; } + /** + * Retrieve the stored entity player from a given NetHandler. + * @param netHandler - the nethandler to retrieve it from. + * @return The stored entity player. + * @throws IllegalAccessException If the reflection failed. + */ + private EntityPlayer getEntityPlayer(Object netHandler) throws IllegalAccessException { + if (entityPlayerField == null) + entityPlayerField = FuzzyReflection.fromObject(netHandler).getFieldByType(".*EntityPlayer"); + return (EntityPlayer) FieldUtils.readField(entityPlayerField, netHandler); + } + /** * Processes the given packet as if it was transmitted by the current player. * @param packet - packet to process. @@ -438,18 +457,33 @@ abstract class PlayerInjector { public Packet handlePacketSending(Packet packet) { // Get the packet ID too Integer id = invoker.getPacketID(packet); - - // Handle a single scheduled action + Player currentPlayer = player; + + // Hack #1: Handle a single scheduled action if (scheduledAction != null) { scheduledAction.run(); scheduledAction = null; } + // Hack #2 + if (updateOnLogin) { + if (id == Packets.Server.LOGIN) { + try { + updatedPlayer = getEntityPlayer(getNetHandler()).getBukkitEntity(); + } catch (IllegalAccessException e) { + logger.log(Level.WARNING, "Cannot update player in PlayerEvent.", e); + } + } + + // This will only occur in the NetLoginHandler injection + if (updatedPlayer != null) + currentPlayer = updatedPlayer; + } // Make sure we're listening if (id != null && hasListener(id)) { // A packet has been sent guys! PacketContainer container = new PacketContainer(id, packet); - PacketEvent event = PacketEvent.fromServer(invoker, container, player); + PacketEvent event = PacketEvent.fromServer(invoker, container, currentPlayer); invoker.invokePacketSending(event); // Cancelling is pretty simple. Just ignore the packet. diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/ReplacedArrayList.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/ReplacedArrayList.java index 2ee75461..6ebb9cb7 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/ReplacedArrayList.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/ReplacedArrayList.java @@ -154,6 +154,9 @@ class ReplacedArrayList extends ArrayList { @Override public void clear() { + for (TKey element : delegate()) + onRemoved(element); + delegate().clear(); }