New Event System

Discussion in 'Resources' started by md_5, Jan 17, 2012.

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

    md_5

    Some of you may have noticed that we have introduced a new way of handling events in Bukkit. Those of you that haven't noticed sure will when you next open your IDE and find a bunch of big yellow deprecation warnings :p
    Anyway lets start with the old way of using listeners, or more specifically how I do it in all of my projects.
    Code:java
    1. package com.md_5.noclip.listeners;
    2.  
    3. import org.bukkit.Bukkit;
    4. import org.bukkit.event.Event;
    5. import org.bukkit.event.EventHandler;
    6. import org.bukkit.event.EventPriority;
    7. import org.bukkit.event.player.PlayerJoinEvent;
    8. import org.bukkit.event.player.PlayerListener;
    9.  
    10. public class NoClipPlayerListener extends PlayerListener{
    11.  
    12. public NoClipPlayerListener() {
    13. Bukkit.getServer().getPluginManager().registerEvent(Event.Type.PLAYER_JOIN, this, Event.Priority.Normal, plugin);
    14. }
    15. @Override
    16. public void onPlayerJoin(final PlayerJoinEvent event) {
    17. }
    18. }
    19.  

    Looking at the code we have a listening class that extends PlayerListener, we then have a constructor which registers the events and some methods to execute the events. The way I use this class is to simply call: new NoClipPlayerListener() : In my onEnable() method. But now how do we replace this with the new event system you ask? Well lets take a look at the same method again:

    Code:java
    1. package com.md_5.noclip.listeners;
    2.  
    3. import org.bukkit.Bukkit;
    4. import org.bukkit.event.EventHandler;
    5. import org.bukkit.event.EventPriority;
    6. import org.bukkit.event.Listener;
    7. import org.bukkit.event.player.PlayerJoinEvent;
    8.  
    9. public class NoClipPlayerListener implements Listener {
    10.  
    11. public NoClipPlayerListener() {
    12. Bukkit.getServer().getPluginManager().registerEvents(this, plugin);
    13. }
    14.  
    15. @EventHandler(priority = EventPriority.LOW)
    16. public void onPlayerJoin(final PlayerJoinEvent event) {
    17. }
    18. }
    19.  

    Well aside from the lack of big warnings several things have changed. The first being we no longer extend PlayerListener, instead all Listeners, no matter what their type implement Listener. Now instead of registering each event individually in the constructor we can simply call registerEvents() and get all the events we use registered for us. Another bonus of this system is you can name your methods anything you like. Now how do we actually go about registering these new events? Well instead of using the @Override tag to replace the listening methods you add a new tag:
    @EventHandler();
    The syntax goes like this:
    Code:
        @EventHandler(event = NAMEOFEVENT.class, priority = EventPriority.WHATPRIORITY)
    So say I wanted to add a new event, say playermove it is as simple as adding this method:
    Code:java
    1. @EventHandler(priority = EventPriority.LOW)
    2. public void whenThePlayerMoves(final PlayerMoveEvent event) {
    3. }
    4.  

    Notice here how I can call the method anything I like. Using these new listeners in your plugin is exactly the same as before: new MYListener();

    I hope this is a brief tutorial on how to upgrade your plugins to the new event system.
     
  2. Offline

    EdGruberman

    Did you ever actually accomplish setting priority with reflection? I'm stumped so far...

    Code:
            for (Method method : this.getClass().getDeclaredMethods()) {
                if (method.getParameterTypes().length != 1 || !(method.getParameterTypes()[0].isInstance(Event.class))) continue;
    
                // TODO something magical with the next line to change the annotation's priority
                method.getAnnotation(EventHandler.class).priority();
            }
     
  3. Offline

    xboxhacks

    Code:java
    1. pm.registerEvents(this.blockListener, this);
    2. pm.registerEvents(Event.Type.BLOCK_PLACE, this.blockListener, EventPriority.HIGHEST, this);
    3. pm.registerEvents(Event.Type.BLOCK_BREAK, this.blockListener, EventPriority.HIGHEST, this);
    4.  
    5. pm.registerEvents(Event.Type.EXPLOSION_PRIME, this.entityListener, EventPriority.HIGHEST, this);
    6.  
    7. this.logMessage("Enabled");

    I can't understand how I'm going to change this.

    Whole Main class (open)
    Code:java
    1.  
    2. package org;
    3.  
    4. import java.util.logging.Logger;
    5.  
    6. import org.bukkit.event.Event;
    7. import org.bukkit.event.EventPriority;
    8. import org.bukkit.permissions.Permission;
    9. import org.bukkit.plugin.PluginDescriptionFile;
    10. import org.bukkit.plugin.PluginManager;
    11. import org.bukkit.plugin.java.JavaPlugin;
    12.  
    13. public class TNTNotify extends JavaPlugin {
    14.  
    15. private Logger log = Logger.getLogger("Minecraft");
    16.  
    17. private TNTNotifyBlockListener blockListener = new TNTNotifyBlockListener(this);
    18. private TNTNotifyEntityListener entityListener = new TNTNotifyEntityListener(this);
    19.  
    20.  
    21. // Plugin Enable //
    22. public void onEnable(){
    23. PluginManager pm = this.getServer().getPluginManager();
    24. }
    25. {
    26. pm.registerEvents(this.blockListener, this);
    27. pm.registerEvents(Event.Type.BLOCK_PLACE, this.blockListener, EventPriority.HIGHEST, this);
    28. pm.registerEvents(Event.Type.BLOCK_BREAK, this.blockListener, EventPriority.HIGHEST, this);
    29.  
    30. pm.registerEvents(Event.Type.EXPLOSION_PRIME, this.entityListener, EventPriority.HIGHEST, this);
    31.  
    32. this.logMessage("Enabled");
    33. }
    34. {
    35. }
    36. // Plugin Disable //
    37. public void onDisable(){
    38. this.logMessage("Disabled");
    39.  
    40. }
    41.  
    42. protected void logMessage(String msg){
    43. PluginDescriptionFile pdFile = this.getDescription();
    44. this.log.info(pdFile.getName() + " " + pdFile.getVersion() + ": " + msg);
    45.  
    46. }
    47. }
    48.  

     
  4. xboxhacks
    You don't register specific events from the plugin manager anymore, you just register a class that has events in it.

    So, you just need registerEvents(class, plugin) and in the class you use @EventHandler on the events, it's too easy... you can set priority in that as well.
     
  5. Offline

    Zarius

    I'm keen on this too - I liked giving the server admins the option of changing priorities to avoid plugin conflicts (and this did need to be done a few times with OtherDrops conflicting with montoring plugins and mcMMO, etc).

    Would be nice to see an easy way to do this.
     
  6. Zarius

    You need to avoid plugin conflicts yourself by deciding how important your event is, be aware that server admins don't understand what the events are and what they do or what they trigger in your plugin so adding that option would verry much confuse them and leave it default either way... and as I said, you must decide how important your event is and you should set accordingly and fix any reported plugin conflicts separate, makes it alot easier for admins :p
     
  7. Offline

    Zarius

    Digi

    Of course I understand that I need to set a default (which I obviously had to do previously or the plugin just wouldn't work) and that most admins wouldn't understand what it's about (which is ok as they generally don't touch that config file anyway). Don't be too general with your statement though - there are many server admins who develop plugins that would know exactly what the setting is about.

    However did you not read my post? :D You pretty much tell me the feature is useless after I state that I've already used it. I found it very useful to be able to advise an admin to change the priority appropriately - much quicker and easier than rebuilding a new version, especially if I'm not around to do so (obviously if there's a long term issue I'd adjust the priority myself). Often this issue is specific to a particular server configuration and I'd rather not be pushing a special version to fix those.

    If there's great benefits gained from having the event priorities fixed/hard-coded then I understand however if it's possible to have the same benefits and still allow those that want customisable priorities I would rather that solution :)
     
  8. Well, suit yourself then :p
     
  9. Offline

    Colos22

  10. Colos22 read this thread about those errors.
     
  11. Offline

    Colos22

    Digi Can you help fix the error?
     
  12. I did, read the thread... or if it's too long, read the other thread you posted, another user simplified it.
     
  13. Offline

    Colos22

    Can you give a link?
     
  14. Offline

    sorklin

    Pm me if you need further explanation.
     
  15. Offline

    Colos22

    Yes should be! Od is skype?

    [​IMG]

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 23, 2016
  16. Sometimes a image is worth a milion words, sometimes it's worth zero... that one is near zero since we (or at least I) have no clue what your error is :}
    I only see some deprecated methods, but that's it.

    If you were able to make that plugin yourself you should be able to understand a simple error pointed by the IDE.

    Also, make your own thread, this thread is about the new event system.
     
  17. Offline

    obnoxint

    Digi , based on Colos posts I think he can barely speak a sentence in english.
     
  18. Offline

    Sage905

    With the help of some very nice folks on IRC, I came up with the following way of registering an event handler with a configurable priority. This event handler hooks in an action on a SignChangeEvent:

    Code:
    FilterSignListener.java
    -------------------------
    public class FilterSignListener implements Listener {
        private final Filter plugin;
        public FilterSignListener(Filter plugin) {
            this.plugin = plugin;
        }
        // This is the handler
        public void onSignChange(SignChangeEvent event) {
            plugin.filterSign(event);
        }
    }
     
    FilterPlugin.java
    -----------------
    public void onEnable {
    ... Stuff...
            /* Hook up the listener for onSignChange events, if configured */
            Boolean filterSigns = getConfig().getBoolean("signfilter");
            if (filterSigns) {
                EventPriority signFilterPriority = EventPriority.valueOf(getConfig().getString("signpriority").toUpperCase());           
                // Now register the listener with the appropriate priority
                PluginManager pm = this.getServer().getPluginManager();
                pm.registerEvent(SignChangeEvent.class, new FilterSignListener(this), signFilterPriority,
                new EventExecutor() {
                    public void execute(Listener l, Event e) { ((FilterSignListener)l).onSignChange((SignChangeEvent)e); }
                },
                this);
            }
    
     
    Comphenix likes this.
Thread Status:
Not open for further replies.

Share This Page