geforkt von Mirrors/Paper
Add /paper dumplisteners tofile
and increase detail of command output (#8592)
Dieser Commit ist enthalten in:
Ursprung
25196237b1
Commit
59d8df6cba
@ -4,6 +4,88 @@ Date: Sat, 19 Nov 2022 19:46:44 +0100
|
||||
Subject: [PATCH] Add /paper dumplisteners command
|
||||
|
||||
|
||||
diff --git a/src/main/java/co/aikar/timings/TimedEventExecutor.java b/src/main/java/co/aikar/timings/TimedEventExecutor.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/co/aikar/timings/TimedEventExecutor.java
|
||||
+++ b/src/main/java/co/aikar/timings/TimedEventExecutor.java
|
||||
@@ -0,0 +0,0 @@ public class TimedEventExecutor implements EventExecutor {
|
||||
executor.execute(listener, event);
|
||||
}
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ @NotNull
|
||||
+ public String toString() {
|
||||
+ return "TimedEventExecutor['" + this.executor.toString() + "']";
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/executor/MethodHandleEventExecutor.java b/src/main/java/com/destroystokyo/paper/event/executor/MethodHandleEventExecutor.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/event/executor/MethodHandleEventExecutor.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/executor/MethodHandleEventExecutor.java
|
||||
@@ -0,0 +0,0 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class MethodHandleEventExecutor implements EventExecutor {
|
||||
private final Class<? extends Event> eventClass;
|
||||
private final MethodHandle handle;
|
||||
+ private final Method method;
|
||||
|
||||
public MethodHandleEventExecutor(@NotNull Class<? extends Event> eventClass, @NotNull MethodHandle handle) {
|
||||
this.eventClass = eventClass;
|
||||
this.handle = handle;
|
||||
+ this.method = null;
|
||||
}
|
||||
|
||||
public MethodHandleEventExecutor(@NotNull Class<? extends Event> eventClass, @NotNull Method m) {
|
||||
@@ -0,0 +0,0 @@ public class MethodHandleEventExecutor implements EventExecutor {
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new AssertionError("Unable to set accessible", e);
|
||||
}
|
||||
+ this.method = m;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class MethodHandleEventExecutor implements EventExecutor {
|
||||
SneakyThrow.sneaky(t);
|
||||
}
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ @NotNull
|
||||
+ public String toString() {
|
||||
+ return "MethodHandleEventExecutor['" + this.method + "']";
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java b/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java
|
||||
@@ -0,0 +0,0 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class StaticMethodHandleEventExecutor implements EventExecutor {
|
||||
private final Class<? extends Event> eventClass;
|
||||
private final MethodHandle handle;
|
||||
+ private final Method method;
|
||||
|
||||
public StaticMethodHandleEventExecutor(@NotNull Class<? extends Event> eventClass, @NotNull Method m) {
|
||||
Preconditions.checkArgument(Modifier.isStatic(m.getModifiers()), "Not a static method: %s", m);
|
||||
@@ -0,0 +0,0 @@ public class StaticMethodHandleEventExecutor implements EventExecutor {
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new AssertionError("Unable to set accessible", e);
|
||||
}
|
||||
+ this.method = m;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class StaticMethodHandleEventExecutor implements EventExecutor {
|
||||
SneakyThrow.sneaky(throwable);
|
||||
}
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ @NotNull
|
||||
+ public String toString() {
|
||||
+ return "StaticMethodHandleEventExecutor['" + this.method + "']";
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/event/HandlerList.java b/src/main/java/org/bukkit/event/HandlerList.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/event/HandlerList.java
|
||||
@ -35,3 +117,61 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
handlerslots = new EnumMap<EventPriority, ArrayList<RegisteredListener>>(EventPriority.class);
|
||||
for (EventPriority o : EventPriority.values()) {
|
||||
handlerslots.put(o, new ArrayList<RegisteredListener>());
|
||||
diff --git a/src/main/java/org/bukkit/plugin/EventExecutor.java b/src/main/java/org/bukkit/plugin/EventExecutor.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/EventExecutor.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/EventExecutor.java
|
||||
@@ -0,0 +0,0 @@ public interface EventExecutor {
|
||||
try {
|
||||
EventExecutor asmExecutor = executorClass.newInstance();
|
||||
// Define a wrapper to conform to bukkit stupidity (passing in events that don't match and wrapper exception)
|
||||
- return (listener, event) -> {
|
||||
- if (!eventClass.isInstance(event)) return;
|
||||
- asmExecutor.execute(listener, event);
|
||||
+ return new EventExecutor() {
|
||||
+ @Override
|
||||
+ public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException {
|
||||
+ if (!eventClass.isInstance(event)) return;
|
||||
+ asmExecutor.execute(listener, event);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ @NotNull
|
||||
+ public String toString() {
|
||||
+ return "ASMEventExecutor['" + m + "']";
|
||||
+ }
|
||||
};
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
throw new AssertionError("Unable to initialize generated event executor", e);
|
||||
diff --git a/src/main/java/org/bukkit/plugin/RegisteredListener.java b/src/main/java/org/bukkit/plugin/RegisteredListener.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/RegisteredListener.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/RegisteredListener.java
|
||||
@@ -0,0 +0,0 @@ public class RegisteredListener {
|
||||
public boolean isIgnoringCancelled() {
|
||||
return ignoreCancelled;
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Get the executor for this registration.
|
||||
+ *
|
||||
+ * @return executor
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public EventExecutor getExecutor() {
|
||||
+ return this.executor;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String toString() {
|
||||
+ return "RegisteredListener{"
|
||||
+ + "plugin=\"" + this.plugin.getName()
|
||||
+ + "\", listener=\"" + this.listener
|
||||
+ + "\", executor=\"" + this.executor
|
||||
+ + "\", priority=\"" + this.priority.name() + " (" + this.priority.getSlot() + ")"
|
||||
+ + "\", ignoringCancelled=" + this.ignoreCancelled
|
||||
+ + "}";
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
@ -35,27 +35,36 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+
|
||||
+import com.destroystokyo.paper.util.SneakyThrow;
|
||||
+import io.papermc.paper.command.PaperSubcommand;
|
||||
+import java.io.File;
|
||||
+import java.io.IOException;
|
||||
+import java.io.PrintWriter;
|
||||
+import java.lang.invoke.MethodHandle;
|
||||
+import java.lang.invoke.MethodHandles;
|
||||
+import java.lang.reflect.Field;
|
||||
+import java.time.LocalDateTime;
|
||||
+import java.time.format.DateTimeFormatter;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.Collections;
|
||||
+import java.util.List;
|
||||
+import java.util.Locale;
|
||||
+import java.util.Set;
|
||||
+import java.util.stream.Stream;
|
||||
+import net.kyori.adventure.text.Component;
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.plugin.Plugin;
|
||||
+import org.bukkit.plugin.RegisteredListener;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+import static net.kyori.adventure.text.Component.newline;
|
||||
+import static net.kyori.adventure.text.Component.space;
|
||||
+import static net.kyori.adventure.text.Component.text;
|
||||
+import static net.kyori.adventure.text.format.NamedTextColor.GRAY;
|
||||
+import static net.kyori.adventure.text.format.NamedTextColor.GREEN;
|
||||
+import static net.kyori.adventure.text.format.NamedTextColor.RED;
|
||||
+import static net.kyori.adventure.text.format.NamedTextColor.WHITE;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public final class DumpListenersCommand implements PaperSubcommand {
|
||||
@ -73,13 +82,41 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean execute(final CommandSender sender, final String subCommand, final String[] args) {
|
||||
+ if (args.length >= 1 && args[0].equals("tofile")) {
|
||||
+ this.dumpToFile(sender);
|
||||
+ return true;
|
||||
+ }
|
||||
+ this.doDumpListeners(sender, args);
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ private void dumpToFile(final CommandSender sender) {
|
||||
+ final File file = new File("debug/listeners-"
|
||||
+ + DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(LocalDateTime.now()) + ".txt");
|
||||
+ try (final PrintWriter writer = new PrintWriter(file)) {
|
||||
+ for (final String eventClass : eventClassNames()) {
|
||||
+ final HandlerList handlers;
|
||||
+ try {
|
||||
+ handlers = (HandlerList) findClass(eventClass).getMethod("getHandlerList").invoke(null);
|
||||
+ } catch (final ReflectiveOperationException e) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (handlers.getRegisteredListeners().length != 0) {
|
||||
+ writer.println(eventClass);
|
||||
+ }
|
||||
+ for (final RegisteredListener registeredListener : handlers.getRegisteredListeners()) {
|
||||
+ writer.println(" - " + registeredListener);
|
||||
+ }
|
||||
+ }
|
||||
+ } catch (final IOException ex) {
|
||||
+ throw new RuntimeException(ex);
|
||||
+ }
|
||||
+ sender.sendMessage(text("Dumped listeners to " + file, GREEN));
|
||||
+ }
|
||||
+
|
||||
+ private void doDumpListeners(final CommandSender sender, final String[] args) {
|
||||
+ if (args.length == 0) {
|
||||
+ sender.sendMessage(text("Usage: /paper dumplisteners [className]", RED));
|
||||
+ sender.sendMessage(text("Usage: /paper dumplisteners tofile|<className>", RED));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
@ -93,12 +130,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+
|
||||
+ sender.sendMessage(text("Listeners for " + args[0] + ":"));
|
||||
+
|
||||
+ Stream.of(handlers.getRegisteredListeners())
|
||||
+ .map(listener -> text(listener.getPlugin().getName(), GREEN)
|
||||
+ for (final RegisteredListener listener : handlers.getRegisteredListeners()) {
|
||||
+ final Component hoverText = text("Priority: " + listener.getPriority().name() + " (" + listener.getPriority().getSlot() + ")", WHITE)
|
||||
+ .append(newline())
|
||||
+ .append(text("Listener: " + listener.getListener()))
|
||||
+ .append(newline())
|
||||
+ .append(text("Executor: " + listener.getExecutor()))
|
||||
+ .append(newline())
|
||||
+ .append(text("Ignoring cancelled: " + listener.isIgnoringCancelled()));
|
||||
+
|
||||
+ sender.sendMessage(text(listener.getPlugin().getName(), GREEN)
|
||||
+ .append(space())
|
||||
+ .append(text("(" + listener.getListener().getClass().getName() + ")", GRAY)
|
||||
+ .hoverEvent(text("Priority: " + listener.getPriority().name() + " (" + listener.getPriority().getSlot() + ")", GRAY))))
|
||||
+ .forEach(sender::sendMessage);
|
||||
+ .append(text("(" + listener.getListener().getClass().getName() + ")", GRAY).hoverEvent(hoverText)));
|
||||
+ }
|
||||
+
|
||||
+ sender.sendMessage(text("Total listeners: " + handlers.getRegisteredListeners().length));
|
||||
+
|
||||
@ -115,16 +159,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||
+ @Override
|
||||
+ public List<String> tabComplete(final CommandSender sender, final String subCommand, final String[] args) {
|
||||
+ return switch (args.length) {
|
||||
+ case 0 -> List.copyOf(getEventClasses());
|
||||
+ case 1 -> getEventClasses().stream()
|
||||
+ case 0 -> suggestions();
|
||||
+ case 1 -> suggestions().stream()
|
||||
+ .filter(clazz -> clazz.toLowerCase(Locale.ROOT).contains(args[0].toLowerCase(Locale.ROOT)))
|
||||
+ .toList();
|
||||
+ default -> Collections.emptyList();
|
||||
+ };
|
||||
+ }
|
||||
+
|
||||
+ private static List<String> suggestions() {
|
||||
+ final List<String> ret = new ArrayList<>();
|
||||
+ ret.add("tofile");
|
||||
+ ret.addAll(eventClassNames());
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ @SuppressWarnings("unchecked")
|
||||
+ private static Set<String> getEventClasses() {
|
||||
+ private static Set<String> eventClassNames() {
|
||||
+ try {
|
||||
+ return (Set<String>) EVENT_TYPES_HANDLE.invokeExact();
|
||||
+ } catch (final Throwable e) {
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren