I saw getServer().getPluginManager().registerEvent. Do that means that we can register custom events? Is there any documentation about that?
There is a slight inefficiency in that you will receive all custom events and can't register for specific ones. You must check the event name I added a pull that allows you to register for specific events, but it hasn't been pulled yet. --- merged: Feb 22, 2011 11:25 AM --- Hmm, auto-merge ate my previous post. This is an example of a custom event: Code: public class RunnableEvent extends Event { Runnable runnable; public RunnableEvent(final Runnable runnable) { super("ServerPortRunnableEvent"); this.runnable = runnable; } } This is an example of the listener: Code: public class ServerPortCustomListener extends CustomEventListener implements Listener { JavaPlugin serverPort = null; ServerPortListenerCommon serverPortListenerCommon; ServerPortCustomListener( ServerPortBukkit serverPort ) { this.serverPort = serverPort; this.serverPortListenerCommon = serverPort.serverPortListenerCommon; } public void onCustomEvent(Event event) { if( !event.getType().equals(Type.CUSTOM_EVENT) ) { return; } if( !event.getEventName().equals("ServerPortRunnableEvent")) { return; } ((RunnableEvent)event).runnable.run(); } }
Those 2 pieces of code are the class files. The only thing missing is how to trigger the event You do that with Code: RunnableEvent runnableEvent = new RunnableEvent(runnable) getServer().getPluginManager().callEvent(runnableEvent); In this case, you pass a Runnable to the constructor, but in practice, you can create the custom event so that it does whatever you want.
Listener: Code: import org.bukkit.event.CustomEventListener; import org.bukkit.event.Event; public class CustomListener extends CustomEventListener{ public void onCustomEvent(CustomEvent event){ onCustomEvent(event); } public void onCustomEvent(Event ev){ CustomEvent event = (CustomEvent)ev; CustomEvent.Reason Reason = event.getReason(); if(Reason == CustomEvent.Reason.RIGHTCLICK){ //TO-DO when you right clicked something } else if(Reason == CustomEvent.Reason.OTHER_REASON){ //TO-DO when ... something else? } } } The Event: Code: import org.bukkit.event.Event; import org.bukkit.event.Cancellable; @SuppressWarnings("serial") public class CustomEvent extends Event implements Cancellable{ private Reason reason; private boolean isCancelled = false; protected CustomEvent(Reason reason) { super(Event.Type.CUSTOM_EVENT); this.reason = reason; } @Override public boolean isCancelled() { return isCancelled; } @Override public void setCancelled(boolean arg0){ isCancelled = arg0; } public Reason getReason(){ return this.reason; } public enum Reason{ RIGHTCLICK, OTHER_REASON } } To call the event Code: CustomEvent event = new CustomEvent(CustomEvent.Reason.RIGHTCLICK); CustomListener.onCustomEvent(event); Haven't tested it, but you all know what I mean with it right?? --- merged: Mar 5, 2011 5:33 PM --- I tought it would work if you extended the Event class but the onCustomEvent can only call the Event class --- merged: Mar 5, 2011 5:34 PM --- BTW: I know it isn't working with the getServer().getPluginManager().callEvent(runnableEvent); But who cares?
Thank you, now i just need to sort out what is what --- merged: Mar 5, 2011 5:47 PM --- Will this work for others plugin trying to catch the event ? I need a way to call all the plugins listening to my event
That sends the event to all plugins that are listening to the custom event type. (This is in fact, pretty inefficient, ideally they should be able to register for specific custom events).
Hmm, getting an error Code: java.lang.IllegalArgumentException: use Event(String) to make custom events Error located at my CustomEvent constructor, error on this line: Code: super(Event.Type.CUSTOM_EVENT); And also, how can i trigger the event in another plugin ?
I´m sorry, to be honest I have no idea. Never really worked with the custom event. Sorry BTW: Try to rename "Event.Type.CUSTOM_EVENT" to a String type ("Custom Event" or something)
A custom event is created using the String type constructor. You would use super("The name of the custom event");
Imma test it out, hold yer thumbs fer me will ye ? Edit: It dosen't give out errors anymore Thanks! --- merged: Mar 6, 2011 12:14 PM --- Eh, one more thing, now that i have a working Event. Do I really need to have the Listener in my plugin? I just want to give other plugins the event. --- merged: Mar 6, 2011 12:39 PM --- Calling onCustomEvent(CustomEvent event) will get you stuck in a loop, as it calls itself Im still confused about triggering the event, as i think this way will only call my Event ? In a static way too... Correct me if I'm wrong
You call events using getServer().getPluginManager().callEvent(event); Note: this doesn't do resyncing to the main thread, if you call an event from another thread, it could cause problems. Also, if you are only sending custom events, then you don't need the listener.
Fantastic! Off to test this now! --- merged: Mar 6, 2011 1:52 PM --- Hmm, the listener don't seem to get the event being triggered, i know that the event is sent but its not recived, sending my event to lets say the playerListerner gives me errors as i expected, sending it to the customListerner wont do a thing... Probably something wrong in CustomListener.java Code: public class CustomListener extends CustomEventListener { public void onCustomEvent(RoomyEvent event) { onCustomEvent(event); System.out.println("Event was done!"); } public void onCustomEvent(Event ev) { System.out.println("Event was done!"); RoomyEvent event = (RoomyEvent)ev; RoomyEvent.Reason Reason = event.getReason(); if(Reason == RoomyEvent.Reason.ROOM_CHANGE) { //Player entered the room event.getPlayer().sendMessage("Entered/Left a room! :)"); } } } Edit: the sender and the listeners are in different .JAR files, but ive included the Event Jar file into the other Listener.
Normally the way to include the other classes is to specify that include the other .jar file like you include the bukkit jar file. Have you registered the event in the receiver plugin? getServer().getPluginManager().registerEvent(Type.CUSTOM_EVENT, customEventListener, Priority.Normal, this) Also, you might have an infinite loop there. If you pass a RoomyEvent, then it will call the first function over and over. --- merged: Mar 6, 2011 4:19 PM --- Also, it might be worth using the @Override to make sure it is working properly.
Yes i know about the infinite loop, i comented it away when i ran the code Code: // Changing this public class CustomListener extends CustomEventListener { // To this public class CustomListener extends CustomEventListener implemets listener { Forgot to tell that it worked like 10 minutes after my last post.
Not always useful, but in my case I was able to use an abstract class to start out the sorting process, and create methods that would seem more useful: Code: /** * abstract because it should not be instanciated. * methods are not abstract because overriding event methods should be optional. * This allows you to choose which to respond to. * @author Aaron * */ public abstract class PermsReceptacleEventListener extends CustomEventListener { /** * main event handler. filter out non-PermsReceptacleEvent events * return unhandled for filtered events. */ @Override public void onCustomEvent(Event event) { if (event instanceof PermsReceptacleEvent) { onPermsReceptacleEvent((PermsReceptacleEvent) event); } } /** * sort by event reason. * override to handle non-sorted events (optional) * @param event */ public void onPermsReceptacleEvent(PermsReceptacleEvent event) { switch (event.getReason()) { case ALLOW: onPermsReceptacleAllowEvent(event); break; case DENY: onPermsReceptacleDenyEvent(event); break; case DEFAULT: onPermsReceptacleDefaultEvent(event); } } /** * named event handler for extended listener * @param event */ public void onPermsReceptacleDefaultEvent(PermsReceptacleEvent event) { // place holder for override -- do nothing } /** * named event handler for extended listener * @param event */ public void onPermsReceptacleDenyEvent(PermsReceptacleEvent event) { // place holder for override -- do nothing } /** * named event handler for extended listener * @param event */ public void onPermsReceptacleAllowEvent(PermsReceptacleEvent event) { // place holder for override -- do nothing } } } After, I extent this base class for use in my plugin: Code: public class ShirtsAndSkinsPermissionListener extends PermsReceptacleEventListener { @SuppressWarnings("unused") private final ShirtsAndSkins plugin; public ShirtsAndSkinsPermissionListener(ShirtsAndSkins plugin) { this.plugin = plugin; } @Override public void onPermsReceptacleDenyEvent(PermsReceptacleEvent event) { Player player = (Player) event.getSender(); String eventName = event.getLockName().toPermissionString(); ShirtsAndSkins.log(Level.INFO, "Permission was denied: " + player.getName() + " : " + eventName); } @Override public void onPermsReceptacleAllowEvent(PermsReceptacleEvent event) { String permissionString = event.getLockName().toPermissionString(); CommandSender sender = event.getSender(); String playerName = null; if (sender instanceof Player){ playerName = ((Player) event.getSender()).getName(); } else if (sender instanceof ConsoleCommandSender){ playerName = "Console"; } else { playerName = "Unkown Sender"; } ShirtsAndSkins.log(Level.INFO, "Permission was allowed: " + playerName + " : " + permissionString); } } If you supply a non-generic listener class for extension then your custom event can act like a non-custom event. A question arises, however... Is it possible to assign several CustomEventListeners to a single plugin and have it work? Or would it only push the event to one of my listeners? (does that make sense?) Anyway... Thanks all for this thread as it helped me understand how to use the custom events. Hope my input helps someone else...