Last active
May 17, 2020 22:13
-
-
Save Mindgamesnl/b74ce2dae7f3c5f5054f518f9b04f4e4 to your computer and use it in GitHub Desktop.
Event interceptor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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