diff options
author | Nassim Jahnke <[email protected]> | 2024-11-29 17:04:32 +0100 |
---|---|---|
committer | Nassim Jahnke <[email protected]> | 2024-11-29 17:07:54 +0100 |
commit | 5ab678947fb620ff123865fc249831f68ff4d35d (patch) | |
tree | 61456e8be732cbedb56e04ecab6785d9687465b6 | |
parent | 64828f3a60d3efbe2e77665e0530d687a8408f56 (diff) | |
download | Paper-5ab678947fb620ff123865fc249831f68ff4d35d.tar.gz Paper-5ab678947fb620ff123865fc249831f68ff4d35d.zip |
Copy dispatcher root children before passing it into async tree building
4 files changed, 54 insertions, 23 deletions
diff --git a/patches/server/0273-Async-command-map-building.patch b/patches/server/0273-Async-command-map-building.patch index 2d9703c811..516cb43ecf 100644 --- a/patches/server/0273-Async-command-map-building.patch +++ b/patches/server/0273-Async-command-map-building.patch @@ -9,15 +9,17 @@ commands if the server is restarting. Using the default async pool caused issues 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 2008fd542eaf1c2fac776ae1751c227a3b6dde4b..34564f4118eab9e95176cb4ff4bc93fbe97d9b6b 100644 +index 2008fd542eaf1c2fac776ae1751c227a3b6dde4b..938db2436e0f099432263aba593e684eb89a44f9 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java -@@ -455,6 +455,19 @@ public class Commands { +@@ -455,6 +455,21 @@ 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)); ++ // Copy root children to avoid concurrent modification during building ++ final Collection<CommandNode<CommandSourceStack>> commandNodes = new java.util.ArrayList<>(this.dispatcher.getRoot().getChildren()); ++ COMMAND_SENDING_POOL.execute(() -> this.sendAsync(player, commandNodes)); + } + + public static final java.util.concurrent.ExecutorService COMMAND_SENDING_POOL = java.util.concurrent.Executors.newFixedThreadPool(2, @@ -27,12 +29,19 @@ index 2008fd542eaf1c2fac776ae1751c227a3b6dde4b..34564f4118eab9e95176cb4ff4bc93fb + .build() + ); + -+ private void sendAsync(ServerPlayer player) { ++ private void sendAsync(ServerPlayer player, Collection<CommandNode<CommandSourceStack>> dispatcherRootChildren) { + // Paper end - Perf: Async command map building Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> map = Maps.newIdentityHashMap(); // Use identity to prevent aliasing issues RootCommandNode vanillaRoot = new RootCommandNode(); -@@ -472,7 +485,14 @@ public class Commands { +@@ -466,13 +481,20 @@ public class Commands { + RootCommandNode<SharedSuggestionProvider> rootcommandnode = new RootCommandNode(); + + map.put(this.dispatcher.getRoot(), rootcommandnode); +- this.fillUsableCommands(this.dispatcher.getRoot(), rootcommandnode, player.createCommandSourceStack(), map); ++ this.fillUsableCommands(dispatcherRootChildren, rootcommandnode, player.createCommandSourceStack(), map); // Paper - Perf: Async command map building; pass copy of children + + Collection<String> bukkit = new LinkedHashSet<>(); for (CommandNode node : rootcommandnode.getChildren()) { bukkit.add(node.getName()); } @@ -47,6 +56,28 @@ index 2008fd542eaf1c2fac776ae1751c227a3b6dde4b..34564f4118eab9e95176cb4ff4bc93fb PlayerCommandSendEvent event = new PlayerCommandSendEvent(player.getBukkitEntity(), new LinkedHashSet<>(bukkit)); event.getPlayer().getServer().getPluginManager().callEvent(event); +@@ -486,8 +508,10 @@ public class Commands { + player.connection.send(new ClientboundCommandsPacket(rootcommandnode)); + } + +- private void fillUsableCommands(CommandNode<CommandSourceStack> tree, CommandNode<SharedSuggestionProvider> result, CommandSourceStack source, Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> resultNodes) { +- Iterator iterator = tree.getChildren().iterator(); ++ // Paper start - Perf: Async command map building; pass copy of children ++ private void fillUsableCommands(Collection<CommandNode<CommandSourceStack>> children, CommandNode<SharedSuggestionProvider> result, CommandSourceStack source, Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> resultNodes) { ++ Iterator iterator = children.iterator(); ++ // Paper end - Perf: Async command map building + + while (iterator.hasNext()) { + CommandNode<CommandSourceStack> commandnode2 = (CommandNode) iterator.next(); +@@ -522,7 +546,7 @@ public class Commands { + resultNodes.put(commandnode2, commandnode3); + result.addChild(commandnode3); + if (!commandnode2.getChildren().isEmpty()) { +- this.fillUsableCommands(commandnode2, commandnode3, source, resultNodes); ++ this.fillUsableCommands(commandnode2.getChildren(), commandnode3, source, resultNodes); // Paper - Perf: Async command map building; pass children directly + } + } + } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 9a9291282f7ec99be9badf8b32fab5f0ea0f1037..feb45369b41b597fd603c12f3da23759923b6a6d 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java diff --git a/patches/server/0274-Brigadier-Mojang-API.patch b/patches/server/0274-Brigadier-Mojang-API.patch index a6e586dce9..4c232b5a17 100644 --- a/patches/server/0274-Brigadier-Mojang-API.patch +++ b/patches/server/0274-Brigadier-Mojang-API.patch @@ -87,10 +87,10 @@ index 4d5f1dd1c3bd742b1bc5e3914101a699041caa7e..5316f148f3f9128690f019d544e462b0 public boolean hasPermission(int level) { // CraftBukkit start diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java -index 34564f4118eab9e95176cb4ff4bc93fbe97d9b6b..c2c8193a3b3f7a224b05a09cd65108860aaae814 100644 +index 938db2436e0f099432263aba593e684eb89a44f9..71c8692487c9c1c5b956b4356501d523368c0507 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java -@@ -486,6 +486,7 @@ public class Commands { +@@ -488,6 +488,7 @@ public class Commands { bukkit.add(node.getName()); } // Paper start - Perf: Async command map building @@ -98,7 +98,7 @@ index 34564f4118eab9e95176cb4ff4bc93fbe97d9b6b..c2c8193a3b3f7a224b05a09cd6510886 net.minecraft.server.MinecraftServer.getServer().execute(() -> { runSync(player, bukkit, rootcommandnode); }); -@@ -493,6 +494,7 @@ public class Commands { +@@ -495,6 +496,7 @@ public class Commands { private void runSync(ServerPlayer player, Collection<String> bukkit, RootCommandNode<SharedSuggestionProvider> rootcommandnode) { // Paper end - Perf: Async command map building @@ -106,7 +106,7 @@ index 34564f4118eab9e95176cb4ff4bc93fbe97d9b6b..c2c8193a3b3f7a224b05a09cd6510886 PlayerCommandSendEvent event = new PlayerCommandSendEvent(player.getBukkitEntity(), new LinkedHashSet<>(bukkit)); event.getPlayer().getServer().getPluginManager().callEvent(event); -@@ -511,6 +513,11 @@ public class Commands { +@@ -515,6 +517,11 @@ public class Commands { while (iterator.hasNext()) { CommandNode<CommandSourceStack> commandnode2 = (CommandNode) iterator.next(); diff --git a/patches/server/0953-Brigadier-based-command-API.patch b/patches/server/0953-Brigadier-based-command-API.patch index 0f4bec1390..30feff2e13 100644 --- a/patches/server/0953-Brigadier-based-command-API.patch +++ b/patches/server/0953-Brigadier-based-command-API.patch @@ -2068,7 +2068,7 @@ index fc0c60b22844ed010aede2fa125b9fa440d3de80..3549ffea451b932602efb113844ba21a public org.bukkit.command.CommandSender getBukkitSender() { return this.source.getBukkitSender(this); diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java -index 26bc8d7075f8a9c411776ab91aeddcd776d21348..2fc5651d1546fd4bb10b0617540e906f483cb36c 100644 +index f190a65ee2e091d4d5a1e114178eac42740075d4..622677fb281242681bf8ba39de34187bcc898a5f 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java @@ -159,7 +159,7 @@ public class Commands { @@ -2135,8 +2135,8 @@ index 26bc8d7075f8a9c411776ab91aeddcd776d21348..2fc5651d1546fd4bb10b0617540e906f StackTraceElement[] astacktraceelement = exception.getStackTrace(); for (int i = 0; i < Math.min(astacktraceelement.length, 3); ++i) { -@@ -473,13 +492,7 @@ public class Commands { - private void sendAsync(ServerPlayer player) { +@@ -475,13 +494,7 @@ public class Commands { + private void sendAsync(ServerPlayer player, Collection<CommandNode<CommandSourceStack>> dispatcherRootChildren) { // Paper end - Perf: Async command map building Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> map = Maps.newIdentityHashMap(); // Use identity to prevent aliasing issues - RootCommandNode vanillaRoot = new RootCommandNode(); @@ -2150,15 +2150,15 @@ index 26bc8d7075f8a9c411776ab91aeddcd776d21348..2fc5651d1546fd4bb10b0617540e906f RootCommandNode<SharedSuggestionProvider> rootcommandnode = new RootCommandNode(); map.put(this.dispatcher.getRoot(), rootcommandnode); -@@ -513,6 +526,7 @@ public class Commands { - } +@@ -516,6 +529,7 @@ public class Commands { - private void fillUsableCommands(CommandNode<CommandSourceStack> tree, CommandNode<SharedSuggestionProvider> result, CommandSourceStack source, Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> resultNodes) { + // Paper start - Perf: Async command map building; pass copy of children + private void fillUsableCommands(Collection<CommandNode<CommandSourceStack>> children, CommandNode<SharedSuggestionProvider> result, CommandSourceStack source, Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> resultNodes) { + resultNodes.keySet().removeIf((node) -> !org.spigotmc.SpigotConfig.sendNamespaced && node.getName().contains( ":" )); // Paper - Remove namedspaced from result nodes to prevent redirect trimming ~ see comment below - Iterator iterator = tree.getChildren().iterator(); + Iterator iterator = children.iterator(); + // Paper end - Perf: Async command map building - while (iterator.hasNext()) { -@@ -526,6 +540,42 @@ public class Commands { +@@ -530,6 +544,42 @@ public class Commands { if (commandnode2.canUse(source)) { ArgumentBuilder argumentbuilder = commandnode2.createBuilder(); // CraftBukkit - decompile error diff --git a/patches/server/0985-Fix-entity-type-tags-suggestions-in-selectors.patch b/patches/server/0985-Fix-entity-type-tags-suggestions-in-selectors.patch index 89a9da85e1..61b8db9955 100644 --- a/patches/server/0985-Fix-entity-type-tags-suggestions-in-selectors.patch +++ b/patches/server/0985-Fix-entity-type-tags-suggestions-in-selectors.patch @@ -37,18 +37,18 @@ index 3549ffea451b932602efb113844ba21a7bc72371..13bd145b1e8006a53c22f5dc0c78f29b + // Paper end - tell clients to ask server for suggestions for EntityArguments } diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java -index 2fc5651d1546fd4bb10b0617540e906f483cb36c..f58275101fd5671bab0aa66875c989e568384647 100644 +index 622677fb281242681bf8ba39de34187bcc898a5f..daca005854ae2bb68300b19bceedadcbbe1e06fd 100644 --- a/src/main/java/net/minecraft/commands/Commands.java +++ b/src/main/java/net/minecraft/commands/Commands.java -@@ -529,6 +529,7 @@ public class Commands { - resultNodes.keySet().removeIf((node) -> !org.spigotmc.SpigotConfig.sendNamespaced && node.getName().contains( ":" )); // Paper - Remove namedspaced from result nodes to prevent redirect trimming ~ see comment below - Iterator iterator = tree.getChildren().iterator(); +@@ -533,6 +533,7 @@ public class Commands { + Iterator iterator = children.iterator(); + // Paper end - Perf: Async command map building + boolean registeredAskServerSuggestionsForTree = false; // Paper - tell clients to ask server for suggestions for EntityArguments while (iterator.hasNext()) { CommandNode<CommandSourceStack> commandnode2 = (CommandNode) iterator.next(); // Paper start - Brigadier API -@@ -591,6 +592,12 @@ public class Commands { +@@ -595,6 +596,12 @@ public class Commands { if (requiredargumentbuilder.getSuggestionsProvider() != null) { requiredargumentbuilder.suggests(SuggestionProviders.safelySwap(requiredargumentbuilder.getSuggestionsProvider())); |