Added event exception handler
This commit is contained in:
parent
b012956afa
commit
e892d60564
3 changed files with 174 additions and 13 deletions
9
pom.xml
9
pom.xml
|
@ -1,9 +1,9 @@
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>buttondevteam</groupId>
|
<groupId>com.github.TBMCPlugins.ButtonCore</groupId>
|
||||||
<artifactId>ButtonCore</artifactId>
|
<artifactId>ButtonCore</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>master-SNAPSHOT</version>
|
||||||
<name>ButtonCore</name>
|
<name>ButtonCore</name>
|
||||||
<description>ButtonCore</description>
|
<description>ButtonCore</description>
|
||||||
<build>
|
<build>
|
||||||
|
@ -99,6 +99,11 @@
|
||||||
<artifactId>Towny</artifactId>
|
<artifactId>Towny</artifactId>
|
||||||
<version>master-SNAPSHOT</version>
|
<version>master-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.TBMCPlugins</groupId>
|
||||||
|
<artifactId>DiscordPlugin</artifactId>
|
||||||
|
<version>master-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<organization>
|
<organization>
|
||||||
<name>TBMCPlugins</name>
|
<name>TBMCPlugins</name>
|
||||||
|
|
154
src/main/java/buttondevteam/core/EventExceptionHandler.java
Normal file
154
src/main/java/buttondevteam/core/EventExceptionHandler.java
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
package buttondevteam.core;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.Validate;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.EventException;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.plugin.EventExecutor;
|
||||||
|
import org.bukkit.plugin.IllegalPluginAccessException;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.bukkit.plugin.PluginManager;
|
||||||
|
import org.bukkit.plugin.RegisteredListener;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
public abstract class EventExceptionHandler { // https://gist.github.com/aadnk/5430459
|
||||||
|
// For wrapping a registered listener
|
||||||
|
private static class ExceptionRegisteredListener extends RegisteredListener {
|
||||||
|
/**
|
||||||
|
* Represents an event executor that does nothing. This is not really necessary in the current
|
||||||
|
* implementation of CraftBukkit, but we will take no chances.
|
||||||
|
*/
|
||||||
|
private static EventExecutor NULL_EXECUTOR = new EventExecutor() {
|
||||||
|
@Override
|
||||||
|
public void execute(Listener listener, Event event) throws EventException {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final RegisteredListener delegate;
|
||||||
|
private final EventExceptionHandler handler;
|
||||||
|
|
||||||
|
public ExceptionRegisteredListener(RegisteredListener delegate, EventExceptionHandler handler) {
|
||||||
|
super(delegate.getListener(), NULL_EXECUTOR, delegate.getPriority(),
|
||||||
|
delegate.getPlugin(), delegate.isIgnoringCancelled());
|
||||||
|
this.delegate = delegate;
|
||||||
|
this.handler = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void callEvent(Event event) throws EventException {
|
||||||
|
try {
|
||||||
|
delegate.callEvent(event);
|
||||||
|
} catch (EventException e) {
|
||||||
|
if (!handler.handle(e.getCause(), event)) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
if (!handler.handle(e, event)) {
|
||||||
|
doThrow(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WARNING: HORRIBLE, HORRIBLE HACK to get around checked exceptions
|
||||||
|
private static void doThrow(Throwable e) {
|
||||||
|
ExceptionRegisteredListener.<RuntimeException> doThrowInner(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static <E extends Throwable> void doThrowInner(Throwable e) throws E {
|
||||||
|
throw (E) e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register Bukkit event handlers with a given exception handler.
|
||||||
|
* @param listener - a class of event handlers.
|
||||||
|
* @param plugin - the current plugin.
|
||||||
|
* @param handler - exception handler.
|
||||||
|
*/
|
||||||
|
public static void registerEvents(Listener listener, Plugin plugin, EventExceptionHandler handler) {
|
||||||
|
Validate.notNull(plugin, "Plugin cannot be NULL.");
|
||||||
|
|
||||||
|
registerEvents(plugin.getServer().getPluginManager(), listener, plugin, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register Bukkit event handlers with a given exception handler.
|
||||||
|
* @param manager - the current plugin manager.
|
||||||
|
* @param listener - a class of event handlers.
|
||||||
|
* @param plugin - the current plugin.
|
||||||
|
* @param handler - exception handler.
|
||||||
|
*/
|
||||||
|
public static void registerEvents(PluginManager manager, Listener listener, Plugin plugin, EventExceptionHandler handler) {
|
||||||
|
Validate.notNull(manager, "Manager cannot be NULL.");
|
||||||
|
Validate.notNull(listener, "Listener cannot be NULL.");
|
||||||
|
Validate.notNull(plugin, "Plugin cannot be NULL.");
|
||||||
|
Validate.notNull(handler, "Handler cannot be NULL.");
|
||||||
|
|
||||||
|
if (!plugin.isEnabled()) {
|
||||||
|
throw new IllegalPluginAccessException("Plugin attempted to register " + listener + " while not enabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create normal listeners
|
||||||
|
for (Map.Entry<Class<? extends Event>, Set<RegisteredListener>> entry :
|
||||||
|
plugin.getPluginLoader().createRegisteredListeners(listener, plugin).entrySet()) {
|
||||||
|
|
||||||
|
// Wrap these listeners in our exception handler
|
||||||
|
getHandlerList(entry.getKey()).registerAll(wrapAll(entry.getValue(), handler));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap every listener in the given collection around an exception handler.
|
||||||
|
* @param listeners - the listeners to wrap.
|
||||||
|
* @param handler - the exception handler to add.
|
||||||
|
* @return The wrapped listeners.
|
||||||
|
*/
|
||||||
|
private static Collection<RegisteredListener> wrapAll(Collection<RegisteredListener> listeners, EventExceptionHandler handler) {
|
||||||
|
List<RegisteredListener> output = Lists.newArrayList();
|
||||||
|
|
||||||
|
for (RegisteredListener listener : listeners) {
|
||||||
|
output.add(new ExceptionRegisteredListener(listener, handler));
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the handler list associated with the given class.
|
||||||
|
* @param clazz - given event class.
|
||||||
|
* @return Associated handler list.
|
||||||
|
*/
|
||||||
|
private static HandlerList getHandlerList(Class<? extends Event> clazz) {
|
||||||
|
// Class must have Event as its superclass
|
||||||
|
while (clazz.getSuperclass() != null && Event.class.isAssignableFrom(clazz.getSuperclass())) {
|
||||||
|
try {
|
||||||
|
Method method = clazz.getDeclaredMethod("getHandlerList");
|
||||||
|
method.setAccessible(true);
|
||||||
|
return (HandlerList) method.invoke(null);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
// Keep on searching
|
||||||
|
clazz = clazz.getSuperclass().asSubclass(Event.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalPluginAccessException(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalPluginAccessException("Unable to find handler list for event " + clazz.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a given exception.
|
||||||
|
* @param ex - the exception to handle.
|
||||||
|
* @param event - the event that was being handled.
|
||||||
|
* @return TRUE to indicate that the exception has been handled, FALSE to rethrow it.
|
||||||
|
*/
|
||||||
|
public abstract boolean handle(Throwable ex, Event event);
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package buttondevteam.core;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
import org.bukkit.plugin.PluginDescriptionFile;
|
import org.bukkit.plugin.PluginDescriptionFile;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
@ -19,7 +20,8 @@ public class MainPlugin extends JavaPlugin {
|
||||||
logger = getLogger();
|
logger = getLogger();
|
||||||
|
|
||||||
logger.info(pdfFile.getName() + " has been Enabled (V." + pdfFile.getVersion() + ").");
|
logger.info(pdfFile.getName() + " has been Enabled (V." + pdfFile.getVersion() + ").");
|
||||||
Bukkit.getPluginManager().registerEvents(new PlayerListener(), this);
|
EventExceptionHandler.registerEvents(new PlayerListener(), this, new EventExceptionDiscordSender() {
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue