Plugin Disable/Listener Removal

Discussion in 'Plugin Development' started by EdGruberman, Oct 8, 2011.

Thread Status:
Not open for further replies.
  1. Offline

    EdGruberman

    To date, I've just assumed listeners were removed by Bukkit when the plugin was disabled. I have since learned this to not be the case. Events still get sent to disabled plugins and disabled plugin listeners still react to those events.

    Is there a "best practice" design pattern I should be employing to manage plugin disablement properly?

    I'm thinking two things at least here...

    1 - Instantiate listeners in the plugin's onLoad event to avoid creating additional listeners in each onEnable event that might be called more than once.

    2 - Each event method of a listener should have checks upfront to determine if it should continue:
    if (event.isCancelled() || plugin.isDisabled()) return;

    Is there any way to disable a listener that I'm overlooking? Or are we stuck with managing this all ourselves in the plugin itself?
     
  2. Manually disabling plugins (meaning, outside of a /reload-process, where everything gets cleared) does not do what it should do at the moment. That's a design issue of bukkit and was discussed dozens of times by now.

    It's not only listeners that are completely ignored, commands will also stay registered (but the onCommand-block won't be executed, they just don't do anything but are still there ...). Same stuff with permissions and whatnot.

    I don't think it's up to the plugin to check if it is disabled, that just doesn't make sense.
     
  3. Offline

    EdGruberman

    Okay, this is "better". So this means I should not work too hard to compensate for this in my plugins, but expect Bukkit to handle plugin disablement more properly in the future and just hope people understand a /reload or complete server restart is the proper work-around for now?
     
  4. Yes, that should generally be enough. Almost none of the plugins care about that, and it's not their business.
    Also, single plugins never get manually disabled on a plain bukkit server. And any developer using the disablePlugin() method should be aware of the issue with it and handle it properly.
     
  5. Offline

    bergerkiller

    Why not use reflection to remove listeners? Surely this is stored somewhere...

    Code:
        private final Map<Event.Type, SortedSet<RegisteredListener>> listeners = new EnumMap<Event.Type, SortedSet<RegisteredListener>>(Event.Type.class);
    Located in the:
    Simply get the field using reflection, get it and store it in an instance
    Code:
    Map<Event.Type, SortedSet<RegisteredListener>> listeners = field.get(<need var name here>)
    And then simply remove one listener.
     
Thread Status:
Not open for further replies.

Share This Page