mirror of
https://github.com/PaperMC/Paper.git
synced 2025-05-18 21:20:24 -07:00
Improvements for Dump paper commands (#12512)
This commit is contained in:
parent
42a2a6c2b5
commit
753cff7c8a
@ -2,12 +2,13 @@ package io.papermc.paper.command.subcommands;
|
|||||||
|
|
||||||
import com.destroystokyo.paper.util.SneakyThrow;
|
import com.destroystokyo.paper.util.SneakyThrow;
|
||||||
import io.papermc.paper.command.PaperSubcommand;
|
import io.papermc.paper.command.PaperSubcommand;
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -16,6 +17,7 @@ import java.util.List;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
@ -23,6 +25,7 @@ import org.bukkit.event.HandlerList;
|
|||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.plugin.RegisteredListener;
|
import org.bukkit.plugin.RegisteredListener;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.checkerframework.framework.qual.DefaultQualifier;
|
import org.checkerframework.framework.qual.DefaultQualifier;
|
||||||
|
|
||||||
import static net.kyori.adventure.text.Component.newline;
|
import static net.kyori.adventure.text.Component.newline;
|
||||||
@ -35,6 +38,8 @@ import static net.kyori.adventure.text.format.NamedTextColor.WHITE;
|
|||||||
|
|
||||||
@DefaultQualifier(NonNull.class)
|
@DefaultQualifier(NonNull.class)
|
||||||
public final class DumpListenersCommand implements PaperSubcommand {
|
public final class DumpListenersCommand implements PaperSubcommand {
|
||||||
|
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss");
|
||||||
|
private static final String COMMAND_ARGUMENT_TO_FILE = "tofile";
|
||||||
private static final MethodHandle EVENT_TYPES_HANDLE;
|
private static final MethodHandle EVENT_TYPES_HANDLE;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@ -49,7 +54,7 @@ public final class DumpListenersCommand implements PaperSubcommand {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(final CommandSender sender, final String subCommand, final String[] args) {
|
public boolean execute(final CommandSender sender, final String subCommand, final String[] args) {
|
||||||
if (args.length >= 1 && args[0].equals("tofile")) {
|
if (args.length >= 1 && args[0].equals(COMMAND_ARGUMENT_TO_FILE)) {
|
||||||
this.dumpToFile(sender);
|
this.dumpToFile(sender);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -58,45 +63,69 @@ public final class DumpListenersCommand implements PaperSubcommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void dumpToFile(final CommandSender sender) {
|
private void dumpToFile(final CommandSender sender) {
|
||||||
final File file = new File("debug/listeners-"
|
Path parent = Path.of("debug");
|
||||||
+ DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(LocalDateTime.now()) + ".txt");
|
Path path = parent.resolve("listeners-" + FORMATTER.format(LocalDateTime.now()) + ".txt");
|
||||||
file.getParentFile().mkdirs();
|
sender.sendMessage(
|
||||||
try (final PrintWriter writer = new PrintWriter(file)) {
|
text("Writing listeners into directory", GREEN)
|
||||||
for (final String eventClass : eventClassNames()) {
|
.appendSpace()
|
||||||
final HandlerList handlers;
|
.append(
|
||||||
try {
|
text(parent.toString(), WHITE)
|
||||||
handlers = (HandlerList) findClass(eventClass).getMethod("getHandlerList").invoke(null);
|
.hoverEvent(text("Click to copy the full path of debug directory", WHITE))
|
||||||
} catch (final ReflectiveOperationException e) {
|
.clickEvent(ClickEvent.copyToClipboard(parent.toAbsolutePath().toString()))
|
||||||
continue;
|
)
|
||||||
}
|
);
|
||||||
if (handlers.getRegisteredListeners().length != 0) {
|
try {
|
||||||
writer.println(eventClass);
|
Files.createDirectories(parent);
|
||||||
}
|
Files.createFile(path);
|
||||||
for (final RegisteredListener registeredListener : handlers.getRegisteredListeners()) {
|
try (final PrintWriter writer = new PrintWriter(path.toFile())){
|
||||||
writer.println(" - " + registeredListener);
|
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) {
|
} catch (final IOException ex) {
|
||||||
throw new RuntimeException(ex);
|
sender.sendMessage(text("Failed to write dumped listener! See the console for more info.", RED));
|
||||||
|
MinecraftServer.LOGGER.warn("Error occurred while dumping listeners", ex);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
sender.sendMessage(text("Dumped listeners to " + file, GREEN));
|
sender.sendMessage(
|
||||||
|
text("Successfully written listeners into", GREEN)
|
||||||
|
.appendSpace()
|
||||||
|
.append(
|
||||||
|
text(path.toString(), WHITE)
|
||||||
|
.hoverEvent(text("Click to copy the full path of the file", WHITE))
|
||||||
|
.clickEvent(ClickEvent.copyToClipboard(path.toAbsolutePath().toString()))
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doDumpListeners(final CommandSender sender, final String[] args) {
|
private void doDumpListeners(final CommandSender sender, final String[] args) {
|
||||||
if (args.length == 0) {
|
if (args.length == 0) {
|
||||||
sender.sendMessage(text("Usage: /paper dumplisteners tofile|<className>", RED));
|
sender.sendMessage(text("Usage: /paper dumplisteners " + COMMAND_ARGUMENT_TO_FILE + "|<className>", RED));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final String className = args[0];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final HandlerList handlers = (HandlerList) findClass(args[0]).getMethod("getHandlerList").invoke(null);
|
final HandlerList handlers = (HandlerList) findClass(className).getMethod("getHandlerList").invoke(null);
|
||||||
|
|
||||||
if (handlers.getRegisteredListeners().length == 0) {
|
if (handlers.getRegisteredListeners().length == 0) {
|
||||||
sender.sendMessage(text(args[0] + " does not have any registered listeners."));
|
sender.sendMessage(text(className + " does not have any registered listeners."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sender.sendMessage(text("Listeners for " + args[0] + ":"));
|
sender.sendMessage(text("Listeners for " + className + ":"));
|
||||||
|
|
||||||
for (final RegisteredListener listener : handlers.getRegisteredListeners()) {
|
for (final RegisteredListener listener : handlers.getRegisteredListeners()) {
|
||||||
final Component hoverText = text("Priority: " + listener.getPriority().name() + " (" + listener.getPriority().getSlot() + ")", WHITE)
|
final Component hoverText = text("Priority: " + listener.getPriority().name() + " (" + listener.getPriority().getSlot() + ")", WHITE)
|
||||||
@ -115,12 +144,12 @@ public final class DumpListenersCommand implements PaperSubcommand {
|
|||||||
sender.sendMessage(text("Total listeners: " + handlers.getRegisteredListeners().length));
|
sender.sendMessage(text("Total listeners: " + handlers.getRegisteredListeners().length));
|
||||||
|
|
||||||
} catch (final ClassNotFoundException e) {
|
} catch (final ClassNotFoundException e) {
|
||||||
sender.sendMessage(text("Unable to find a class named '" + args[0] + "'. Make sure to use the fully qualified name.", RED));
|
sender.sendMessage(text("Unable to find a class named '" + className + "'. Make sure to use the fully qualified name.", RED));
|
||||||
} catch (final NoSuchMethodException e) {
|
} catch (final NoSuchMethodException e) {
|
||||||
sender.sendMessage(text("Class '" + args[0] + "' does not have a valid getHandlerList method.", RED));
|
sender.sendMessage(text("Class '" + className + "' does not have a valid getHandlerList method.", RED));
|
||||||
} catch (final ReflectiveOperationException e) {
|
} catch (final ReflectiveOperationException e) {
|
||||||
sender.sendMessage(text("Something went wrong, see the console for more details.", RED));
|
sender.sendMessage(text("Something went wrong, see the console for more details.", RED));
|
||||||
MinecraftServer.LOGGER.warn("Error occurred while dumping listeners for class " + args[0], e);
|
MinecraftServer.LOGGER.warn("Error occurred while dumping listeners for class {}", className, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,7 +166,7 @@ public final class DumpListenersCommand implements PaperSubcommand {
|
|||||||
|
|
||||||
private static List<String> suggestions() {
|
private static List<String> suggestions() {
|
||||||
final List<String> ret = new ArrayList<>();
|
final List<String> ret = new ArrayList<>();
|
||||||
ret.add("tofile");
|
ret.add(COMMAND_ARGUMENT_TO_FILE);
|
||||||
ret.addAll(eventClassNames());
|
ret.addAll(eventClassNames());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import com.google.gson.JsonArray;
|
|||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonPrimitive;
|
import com.google.gson.JsonPrimitive;
|
||||||
|
import com.google.gson.Strictness;
|
||||||
import com.google.gson.internal.Streams;
|
import com.google.gson.internal.Streams;
|
||||||
import com.google.gson.stream.JsonWriter;
|
import com.google.gson.stream.JsonWriter;
|
||||||
import io.papermc.paper.command.PaperSubcommand;
|
import io.papermc.paper.command.PaperSubcommand;
|
||||||
@ -15,7 +16,6 @@ import io.papermc.paper.plugin.entrypoint.classloader.group.PaperPluginClassLoad
|
|||||||
import io.papermc.paper.plugin.entrypoint.classloader.group.SimpleListPluginClassLoaderGroup;
|
import io.papermc.paper.plugin.entrypoint.classloader.group.SimpleListPluginClassLoaderGroup;
|
||||||
import io.papermc.paper.plugin.entrypoint.classloader.group.SpigotPluginClassLoaderGroup;
|
import io.papermc.paper.plugin.entrypoint.classloader.group.SpigotPluginClassLoaderGroup;
|
||||||
import io.papermc.paper.plugin.entrypoint.classloader.group.StaticPluginClassLoaderGroup;
|
import io.papermc.paper.plugin.entrypoint.classloader.group.StaticPluginClassLoaderGroup;
|
||||||
import io.papermc.paper.plugin.entrypoint.dependency.GraphDependencyContext;
|
|
||||||
import io.papermc.paper.plugin.entrypoint.dependency.SimpleMetaDependencyTree;
|
import io.papermc.paper.plugin.entrypoint.dependency.SimpleMetaDependencyTree;
|
||||||
import io.papermc.paper.plugin.provider.entrypoint.DependencyContext;
|
import io.papermc.paper.plugin.provider.entrypoint.DependencyContext;
|
||||||
import io.papermc.paper.plugin.entrypoint.strategy.modern.ModernPluginLoadingStrategy;
|
import io.papermc.paper.plugin.entrypoint.strategy.modern.ModernPluginLoadingStrategy;
|
||||||
@ -27,12 +27,14 @@ import io.papermc.paper.plugin.provider.classloader.PaperClassLoaderStorage;
|
|||||||
import io.papermc.paper.plugin.provider.classloader.PluginClassLoaderGroup;
|
import io.papermc.paper.plugin.provider.classloader.PluginClassLoaderGroup;
|
||||||
import io.papermc.paper.plugin.storage.ConfiguredProviderStorage;
|
import io.papermc.paper.plugin.storage.ConfiguredProviderStorage;
|
||||||
import io.papermc.paper.plugin.storage.ProviderStorage;
|
import io.papermc.paper.plugin.storage.ProviderStorage;
|
||||||
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.checkerframework.framework.qual.DefaultQualifier;
|
import org.checkerframework.framework.qual.DefaultQualifier;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
@ -47,6 +49,7 @@ import java.util.Map;
|
|||||||
import static net.kyori.adventure.text.Component.text;
|
import static net.kyori.adventure.text.Component.text;
|
||||||
import static net.kyori.adventure.text.format.NamedTextColor.GREEN;
|
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.RED;
|
||||||
|
import static net.kyori.adventure.text.format.NamedTextColor.WHITE;
|
||||||
|
|
||||||
@DefaultQualifier(NonNull.class)
|
@DefaultQualifier(NonNull.class)
|
||||||
public final class DumpPluginsCommand implements PaperSubcommand {
|
public final class DumpPluginsCommand implements PaperSubcommand {
|
||||||
@ -60,24 +63,40 @@ public final class DumpPluginsCommand implements PaperSubcommand {
|
|||||||
|
|
||||||
private void dumpPlugins(final CommandSender sender, final String[] args) {
|
private void dumpPlugins(final CommandSender sender, final String[] args) {
|
||||||
Path parent = Path.of("debug");
|
Path parent = Path.of("debug");
|
||||||
Path path = parent.resolve("plugin-info-" + FORMATTER.format(LocalDateTime.now()) + ".txt");
|
Path path = parent.resolve("plugin-info-" + FORMATTER.format(LocalDateTime.now()) + ".json");
|
||||||
try {
|
try {
|
||||||
Files.createDirectories(parent);
|
Files.createDirectories(parent);
|
||||||
Files.createFile(path);
|
Files.createFile(path);
|
||||||
sender.sendMessage(text("Writing plugin information to " + path, GREEN));
|
sender.sendMessage(
|
||||||
|
text("Writing plugin information into directory", GREEN)
|
||||||
|
.appendSpace()
|
||||||
|
.append(
|
||||||
|
text(parent.toString(), WHITE)
|
||||||
|
.hoverEvent(text("Click to copy the full path of debug directory", WHITE))
|
||||||
|
.clickEvent(ClickEvent.copyToClipboard(parent.toAbsolutePath().toString()))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
final JsonObject data = this.writeDebug();
|
final JsonObject data = this.writeDebug();
|
||||||
|
|
||||||
StringWriter stringWriter = new StringWriter();
|
StringWriter stringWriter = new StringWriter();
|
||||||
JsonWriter jsonWriter = new JsonWriter(stringWriter);
|
JsonWriter jsonWriter = new JsonWriter(stringWriter);
|
||||||
jsonWriter.setIndent(" ");
|
jsonWriter.setIndent(" ");
|
||||||
jsonWriter.setLenient(false);
|
jsonWriter.setStrictness(Strictness.STRICT);
|
||||||
Streams.write(data, jsonWriter);
|
Streams.write(data, jsonWriter);
|
||||||
|
|
||||||
try (PrintStream out = new PrintStream(Files.newOutputStream(path), false, StandardCharsets.UTF_8)) {
|
try (PrintStream out = new PrintStream(Files.newOutputStream(path), false, StandardCharsets.UTF_8)) {
|
||||||
out.print(stringWriter);
|
out.print(stringWriter);
|
||||||
}
|
}
|
||||||
sender.sendMessage(text("Successfully written plugin debug information!", GREEN));
|
sender.sendMessage(
|
||||||
|
text("Successfully written plugin debug information into", GREEN)
|
||||||
|
.appendSpace()
|
||||||
|
.append(
|
||||||
|
text(path.toString(), WHITE)
|
||||||
|
.hoverEvent(text("Click to copy the full path of the file", WHITE))
|
||||||
|
.clickEvent(ClickEvent.copyToClipboard(path.toAbsolutePath().toString()))
|
||||||
|
)
|
||||||
|
);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
sender.sendMessage(text("Failed to write plugin information! See the console for more info.", RED));
|
sender.sendMessage(text("Failed to write plugin information! See the console for more info.", RED));
|
||||||
MinecraftServer.LOGGER.warn("Error occurred while dumping plugin info", e);
|
MinecraftServer.LOGGER.warn("Error occurred while dumping plugin info", e);
|
||||||
@ -97,6 +116,7 @@ public final class DumpPluginsCommand implements PaperSubcommand {
|
|||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
private void writeProviders(JsonObject root) {
|
private void writeProviders(JsonObject root) {
|
||||||
JsonObject rootProviders = new JsonObject();
|
JsonObject rootProviders = new JsonObject();
|
||||||
root.add("providers", rootProviders);
|
root.add("providers", rootProviders);
|
||||||
@ -116,7 +136,6 @@ public final class DumpPluginsCommand implements PaperSubcommand {
|
|||||||
providerObj.addProperty("soft-dependencies", provider.getMeta().getPluginSoftDependencies().toString());
|
providerObj.addProperty("soft-dependencies", provider.getMeta().getPluginSoftDependencies().toString());
|
||||||
providerObj.addProperty("load-before", provider.getMeta().getLoadBeforePlugins().toString());
|
providerObj.addProperty("load-before", provider.getMeta().getLoadBeforePlugins().toString());
|
||||||
|
|
||||||
|
|
||||||
providers.add(providerObj);
|
providers.add(providerObj);
|
||||||
pluginProviders.add((PluginProvider<Object>) provider);
|
pluginProviders.add((PluginProvider<Object>) provider);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user