From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Callahan Date: Wed, 8 Apr 2020 02:42:14 -0500 Subject: [PATCH] Async command map building This adds a custom pool inorder to make sure that they are closed without much though, as it doesn't matter if the client is not sent commands if the server is restarting. Using the default async pool caused issues to arise due to the shutdown logic generally being much later. diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java index 03966f447354fb16a01442ff6c6257fa19461bcd..6383cdfe3e2b61314fee7f7236dc7df1c1e8bfb6 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java @@ -460,6 +460,24 @@ public class Commands { if ( org.spigotmc.SpigotConfig.tabComplete < 0 ) return; // Spigot // CraftBukkit start // Register Vanilla commands into builtRoot as before + // Paper start - Perf: Async command map building + COMMAND_SENDING_POOL.execute(() -> { + this.sendAsync(player); + }); + } + + public static final java.util.concurrent.ThreadPoolExecutor COMMAND_SENDING_POOL = new java.util.concurrent.ThreadPoolExecutor( + 0, 2, 60L, java.util.concurrent.TimeUnit.SECONDS, + new java.util.concurrent.LinkedBlockingQueue<>(), + new com.google.common.util.concurrent.ThreadFactoryBuilder() + .setNameFormat("Paper Async Command Builder Thread Pool - %1$d") + .setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(net.minecraft.server.MinecraftServer.LOGGER)) + .build(), + new java.util.concurrent.ThreadPoolExecutor.DiscardPolicy() + ); + + private void sendAsync(ServerPlayer player) { + // Paper end - Perf: Async command map building Map, CommandNode> map = Maps.newIdentityHashMap(); // Use identity to prevent aliasing issues RootCommandNode vanillaRoot = new RootCommandNode(); @@ -477,7 +495,14 @@ public class Commands { for (CommandNode node : rootcommandnode.getChildren()) { bukkit.add(node.getName()); } + // Paper start - Perf: Async command map building + net.minecraft.server.MinecraftServer.getServer().execute(() -> { + runSync(player, bukkit, rootcommandnode); + }); + } + private void runSync(ServerPlayer player, Collection bukkit, RootCommandNode rootcommandnode) { + // Paper end - Perf: Async command map building PlayerCommandSendEvent event = new PlayerCommandSendEvent(player.getBukkitEntity(), new LinkedHashSet<>(bukkit)); event.getPlayer().getServer().getPluginManager().callEvent(event); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 65e9ac5ba7237e97e286953568f28db86d244d1e..4f4e662e8f21e92b49c3d3811a24f9acedde9fff 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -927,6 +927,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop