diff --git a/ProtocolLib/src/com/comphenix/protocol/ProtocolLibrary.java b/ProtocolLib/src/com/comphenix/protocol/ProtocolLibrary.java index bb01a1b2..b2af48cc 100644 --- a/ProtocolLib/src/com/comphenix/protocol/ProtocolLibrary.java +++ b/ProtocolLib/src/com/comphenix/protocol/ProtocolLibrary.java @@ -81,6 +81,8 @@ public class ProtocolLibrary extends JavaPlugin { /** * Retrieve the metrics instance used to measure users of this library. + *

+ * Note that this method may return NULL when the server is reloading or shutting down. * @return Metrics instance container. */ public Statistics getStatistics() { diff --git a/ProtocolLib/src/com/comphenix/protocol/ProtocolManager.java b/ProtocolLib/src/com/comphenix/protocol/ProtocolManager.java index f2735874..c492e235 100644 --- a/ProtocolLib/src/com/comphenix/protocol/ProtocolManager.java +++ b/ProtocolLib/src/com/comphenix/protocol/ProtocolManager.java @@ -40,13 +40,19 @@ public interface ProtocolManager { public ImmutableSet getPacketListeners(); /** - * Adds a packet listener. + * Adds a packet listener. + *

+ * Adding an already registered listener has no effect. If you need to change the packets + * the current listener is observing, you must first remove the packet listener before you + * can register it again. * @param listener - new packet listener. */ public void addPacketListener(PacketListener listener); /** - * Removes a given packet listener. + * Removes a given packet listener. + *

+ * Attempting to remove a listener that doesn't exist has no effect. * @param listener - the packet listener to remove. */ public void removePacketListener(PacketListener listener); @@ -107,16 +113,16 @@ public interface ProtocolManager { /** * Constructs a new encapsulated Minecraft packet with the given ID. *

- * If set to true, the skip default option will prevent the system from assigning - * non-primitive fields in the packet to a new default instance. For instance, certain + * If set to true, the forceDefaults option will force the system to automatically + * give non-primitive fields in the packet sensible default values. For instance, certain * packets - like Packet60Explosion - require a List or Set to be non-null. If the - * skipDefaults option is false, the List or Set will be automatically created. + * forceDefaults option is true, the List or Set will be automatically created. * * @param id - packet ID. - * @param skipDefaults - TRUE to skip setting default values, FALSE otherwise. + * @param forceDefaults - TRUE to use sensible defaults in most fields, FALSE otherwise. * @return New encapsulated Minecraft packet. */ - public PacketContainer createPacket(int id, boolean skipDefaults); + public PacketContainer createPacket(int id, boolean forceDefaults); /** * Retrieves a immutable set containing the ID of the sent server packets that will be observed by listeners. diff --git a/ProtocolLib/src/com/comphenix/protocol/events/PacketAdapter.java b/ProtocolLib/src/com/comphenix/protocol/events/PacketAdapter.java index 9a1dc40d..58845e87 100644 --- a/ProtocolLib/src/com/comphenix/protocol/events/PacketAdapter.java +++ b/ProtocolLib/src/com/comphenix/protocol/events/PacketAdapter.java @@ -19,7 +19,6 @@ package com.comphenix.protocol.events; import org.bukkit.plugin.Plugin; - /** * Represents a packet listener with useful constructors. * @@ -33,7 +32,7 @@ public abstract class PacketAdapter implements PacketListener { protected ListeningWhitelist sendingWhitelist = ListeningWhitelist.EMPTY_WHITELIST; /** - * Initialize a packet listener. + * Initialize a packet listener with default priority. * @param plugin - the plugin that spawned this listener. * @param connectionSide - the packet type the listener is looking for. * @param packets - the packet IDs the listener is looking for. @@ -43,7 +42,7 @@ public abstract class PacketAdapter implements PacketListener { } /** - * Initialize a packet listener. + * Initialize a packet listener for a single connection side. * @param plugin - the plugin that spawned this listener. * @param connectionSide - the packet type the listener is looking for. * @param listenerPriority - the event priority. diff --git a/ProtocolLib/src/com/comphenix/protocol/events/PacketListener.java b/ProtocolLib/src/com/comphenix/protocol/events/PacketListener.java index aab19240..7594686b 100644 --- a/ProtocolLib/src/com/comphenix/protocol/events/PacketListener.java +++ b/ProtocolLib/src/com/comphenix/protocol/events/PacketListener.java @@ -21,6 +21,8 @@ import org.bukkit.plugin.Plugin; /** * Represents a listener that recieves notifications when packets are sent or recieved. + *

+ * Use {@link PacketAdapter} for a simple wrapper around this interface. * @author Kristian */ public interface PacketListener { diff --git a/ProtocolLib/src/com/comphenix/protocol/injector/ConcurrentListenerMultimap.java b/ProtocolLib/src/com/comphenix/protocol/injector/ConcurrentListenerMultimap.java index 845b3866..ec4542e6 100644 --- a/ProtocolLib/src/com/comphenix/protocol/injector/ConcurrentListenerMultimap.java +++ b/ProtocolLib/src/com/comphenix/protocol/injector/ConcurrentListenerMultimap.java @@ -29,6 +29,7 @@ public class ConcurrentListenerMultimap { /** * Adds a listener to its requested list of packet recievers. * @param listener - listener with a list of packets to recieve notifcations for. + * @param whitelist - the packet whitelist to use. */ public void addListener(PacketListener listener, ListeningWhitelist whitelist) { @@ -66,6 +67,7 @@ public class ConcurrentListenerMultimap { /** * Removes the given listener from the packet event list. * @param listener - listener to remove. + * @param whitelist - the packet whitelist that was used. * @return Every packet ID that was removed due to no listeners. */ public List removeListener(PacketListener listener, ListeningWhitelist whitelist) { @@ -113,7 +115,7 @@ public class ConcurrentListenerMultimap { for (PrioritizedListener element : list) { try { element.getListener().onPacketReceiving(event); - } catch (Exception e) { + } catch (Throwable e) { // Minecraft doesn't want your Exception. logger.log(Level.SEVERE, "Exception occured in onPacketReceiving() for " + @@ -138,7 +140,7 @@ public class ConcurrentListenerMultimap { for (PrioritizedListener element : list) { try { element.getListener().onPacketSending(event); - } catch (Exception e) { + } catch (Throwable e) { // Minecraft doesn't want your Exception. logger.log(Level.SEVERE, "Exception occured in onPacketReceiving() for " + diff --git a/ProtocolLib/src/com/comphenix/protocol/injector/PacketFilterManager.java b/ProtocolLib/src/com/comphenix/protocol/injector/PacketFilterManager.java index f79a88d3..2a697290 100644 --- a/ProtocolLib/src/com/comphenix/protocol/injector/PacketFilterManager.java +++ b/ProtocolLib/src/com/comphenix/protocol/injector/PacketFilterManager.java @@ -40,6 +40,7 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.server.PluginDisableEvent; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; @@ -270,15 +271,15 @@ public final class PacketFilterManager implements ProtocolManager { @Override public PacketContainer createPacket(int id) { - return createPacket(id, false); + return createPacket(id, true); } @Override - public PacketContainer createPacket(int id, boolean skipDefaults) { + public PacketContainer createPacket(int id, boolean forceDefaults) { PacketContainer packet = new PacketContainer(id); // Use any default values if possible - if (!skipDefaults) { + if (forceDefaults) { try { packet.getModifier().writeDefaults(); } catch (FieldAccessException e) { @@ -331,7 +332,7 @@ public final class PacketFilterManager implements ProtocolManager { * @param manager - Bukkit plugin manager that provides player join/leave events. * @param plugin - the parent plugin. */ - public void registerEvents(PluginManager manager, Plugin plugin) { + public void registerEvents(PluginManager manager, final Plugin plugin) { try { manager.registerEvents(new Listener() { @@ -345,6 +346,15 @@ public final class PacketFilterManager implements ProtocolManager { public void onPlayerQuit(PlayerQuitEvent event) { uninjectPlayer(event.getPlayer()); } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onPluginDisabled(PluginDisableEvent event) { + // Clean up in case the plugin forgets + if (event.getPlugin() != plugin) { + removePacketListeners(event.getPlugin()); + } + } + }, plugin); } catch (NoSuchMethodError e) { @@ -370,6 +380,7 @@ public final class PacketFilterManager implements ProtocolManager { // Get event types Object playerJoinType = Enum.valueOf(eventTypes, "PLAYER_JOIN"); Object playerQuitType = Enum.valueOf(eventTypes, "PLAYER_QUIT"); + Object pluginDisabledType = Enum.valueOf(eventTypes, "PLUGIN_DISABLE"); // The player listener! Good times. Class playerListener = loader.loadClass("org.bukkit.event.player.PlayerListener"); @@ -394,6 +405,8 @@ public final class PacketFilterManager implements ProtocolManager { injectPlayer(((PlayerJoinEvent) event).getPlayer()); else if (event instanceof PlayerQuitEvent) injectPlayer(((PlayerQuitEvent) event).getPlayer()); + else if (event instanceof PluginDisableEvent) + removePacketListeners(((PluginDisableEvent) event).getPlugin()); } return null; @@ -405,6 +418,7 @@ public final class PacketFilterManager implements ProtocolManager { registerEvent.invoke(manager, playerJoinType, proxy, priorityNormal, plugin); registerEvent.invoke(manager, playerQuitType, proxy, priorityNormal, plugin); + registerEvent.invoke(manager, pluginDisabledType, proxy, priorityNormal, plugin); // A lot can go wrong } catch (ClassNotFoundException e1) {