PaperMC/patches/server/0296-Async-command-map-building.patch

66 lines
3.5 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Callahan <mr.callahhh@gmail.com>
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 7f561ab6e56cd1749da8eff950080d3ae3f5e028..286dab2ed3c6b962c9702b8b10105e1456b04f7b 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
@@ -396,6 +396,24 @@ public class Commands {
if ( org.spigotmc.SpigotConfig.tabComplete < 0 ) return; // Spigot
// CraftBukkit start
// Register Vanilla commands into builtRoot as before
+ // Paper start - 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 - Async command map building
Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> map = Maps.newIdentityHashMap(); // Use identity to prevent aliasing issues
RootCommandNode vanillaRoot = new RootCommandNode();
@@ -413,7 +431,14 @@ public class Commands {
for (CommandNode node : rootcommandnode.getChildren()) {
bukkit.add(node.getName());
}
+ // Paper start - Async command map building
+ net.minecraft.server.MinecraftServer.getServer().execute(() -> {
+ runSync(player, bukkit, rootcommandnode);
+ });
+ }
+ private void runSync(ServerPlayer player, Collection<String> bukkit, RootCommandNode<SharedSuggestionProvider> rootcommandnode) {
+ // Paper end - 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 d95a618dfdb50a6c6a5fc086cb5e88e0b0a91b71..d11ba8d081861b852bf74662d5e963ac89c226ca 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -900,6 +900,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
MinecraftServer.LOGGER.info("Stopping server");
+ Commands.COMMAND_SENDING_POOL.shutdownNow(); // Paper - Shutdown and don't bother finishing
MinecraftTimings.stopServer(); // Paper
// CraftBukkit start
if (this.server != null) {