Skip to content

Instantly share code, notes, and snippets.

@Mindgamesnl
Last active May 17, 2020 22:13
Show Gist options
  • Save Mindgamesnl/b74ce2dae7f3c5f5054f518f9b04f4e4 to your computer and use it in GitHub Desktop.
Save Mindgamesnl/b74ce2dae7f3c5f5054f518f9b04f4e4 to your computer and use it in GitHub Desktop.
Event interceptor
import org.bukkit.Bukkit;
import org.bukkit.event.*;
import org.bukkit.plugin.EventExecutor;
import org.bukkit.plugin.RegisteredListener;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
public class EventInterceptor<E extends Event> extends HandlerList {
private List<Consumer<E>> preExecutors = new ArrayList<>();
public static EventInterceptor create(Class<? extends Event> event) throws NoSuchFieldException, IllegalAccessException {
// get the current handler list, maybe it already is intercepted, then we can just use that one
Field field = null;
for (Field declaredField : event.getDeclaredFields()) {
if (declaredField.getType() == EventInterceptor.class) return (EventInterceptor) declaredField.get(null);
if (declaredField.getType() == HandlerList.class) field = declaredField;
}
if (field == null) {
throw new IllegalStateException("Handler not found");
}
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
EventInterceptor interceptor = new EventInterceptor();
field.set(null, interceptor);
return interceptor;
}
public void addPreExecutor(Consumer<E> preExecutor) {
this.preExecutors.add(preExecutor);
}
@Override
public RegisteredListener[] getRegisteredListeners() {
RegisteredListener fakeListener = new RegisteredListener(null, new EventExecutor() {
@Override
public void execute(Listener listener, Event event) throws EventException {
for (Consumer<E> preExecutor : preExecutors) {
preExecutor.accept((E) event);
}
}
}, EventPriority.LOWEST, Treadful.getInstance(), true);
return pushToBeginning(super.getRegisteredListeners(), fakeListener);
}
private RegisteredListener[] pushToBeginning(RegisteredListener[] elements, RegisteredListener element) {
RegisteredListener[] newArray = Arrays.copyOf(elements, elements.length + 1);
newArray[0] = element;
System.arraycopy(elements, 0, newArray, 1, elements.length);
return newArray;
}
}
// Register the interceptor
EventInterceptor interceptor = EventInterceptor.create(WorldLoadEvent.class);
// catch events before they are passed on to the handlers and possibly cancel them here
interceptor.addPreExecutor((event) -> {
// intercepted world load event
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment