Created
June 18, 2020 06:25
-
-
Save aikar/1f37e6d7c56541948d6d9adbf0939a6a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/main/java/net/minecraft/server/CommandDispatcher.java b/src/main/java/net/minecraft/server/CommandDispatcher.java | |
index 2d512aa4f9a..34454a8efa6 100644 | |
--- a/src/main/java/net/minecraft/server/CommandDispatcher.java | |
+++ b/src/main/java/net/minecraft/server/CommandDispatcher.java | |
@@ -1,5 +1,6 @@ | |
package net.minecraft.server; | |
+import com.google.common.collect.ArrayListMultimap; | |
import com.google.common.collect.Maps; | |
import com.mojang.brigadier.ParseResults; | |
import com.mojang.brigadier.StringReader; | |
@@ -13,6 +14,7 @@ import com.mojang.brigadier.tree.CommandNode; | |
import com.mojang.brigadier.tree.RootCommandNode; | |
import java.util.Collection; | |
import java.util.Iterator; | |
+import java.util.List; | |
import java.util.Map; | |
import java.util.function.Predicate; | |
import javax.annotation.Nullable; | |
@@ -250,17 +252,18 @@ public class CommandDispatcher { | |
private void sendAsync(EntityPlayer entityplayer) { | |
// Paper end - Async command map building | |
Map<CommandNode<CommandListenerWrapper>, CommandNode<ICompletionProvider>> map = Maps.newIdentityHashMap(); // Use identity to prevent aliasing issues | |
+ ArrayListMultimap<CommandNode, Runnable> pendingInit = ArrayListMultimap.create(); // CraftBukkit | |
RootCommandNode vanillaRoot = new RootCommandNode(); | |
RootCommandNode<CommandListenerWrapper> vanilla = entityplayer.server.vanillaCommandDispatcher.a().getRoot(); | |
map.put(vanilla, vanillaRoot); | |
- this.a(vanilla, vanillaRoot, entityplayer.getCommandListener(), (Map) map); | |
+ this.a(vanilla, vanillaRoot, entityplayer.getCommandListener(), (Map) map, pendingInit); // CraftBukkit | |
// Now build the global commands in a second pass | |
RootCommandNode<ICompletionProvider> rootcommandnode = new RootCommandNode(); | |
map.put(this.b.getRoot(), rootcommandnode); | |
- this.a(this.b.getRoot(), rootcommandnode, entityplayer.getCommandListener(), (Map) map); | |
+ this.a(this.b.getRoot(), rootcommandnode, entityplayer.getCommandListener(), (Map) map, pendingInit); // CraftBukkit | |
Collection<String> bukkit = new LinkedHashSet<>(); | |
for (CommandNode node : rootcommandnode.getChildren()) { | |
@@ -289,7 +292,7 @@ public class CommandDispatcher { | |
entityplayer.playerConnection.sendPacket(new PacketPlayOutCommands(rootcommandnode)); | |
} | |
- private void a(CommandNode<CommandListenerWrapper> commandnode, CommandNode<ICompletionProvider> commandnode1, CommandListenerWrapper commandlistenerwrapper, Map<CommandNode<CommandListenerWrapper>, CommandNode<ICompletionProvider>> map) { | |
+ private void a(CommandNode<CommandListenerWrapper> commandnode, CommandNode<ICompletionProvider> commandnode1, CommandListenerWrapper commandlistenerwrapper, Map<CommandNode<CommandListenerWrapper>, CommandNode<ICompletionProvider>> map, ArrayListMultimap<CommandNode, Runnable> pendingInit) { // CraftBukkit | |
Iterator iterator = commandnode.getChildren().iterator(); | |
while (iterator.hasNext()) { | |
@@ -316,22 +319,39 @@ public class CommandDispatcher { | |
} | |
} | |
- if (argumentbuilder.getRedirect() != null) { | |
- argumentbuilder.redirect((CommandNode) map.get(argumentbuilder.getRedirect())); | |
- } | |
- | |
- CommandNode commandnode3 = argumentbuilder.build(); // CraftBukkit - decompile error | |
- | |
- map.put(commandnode2, commandnode3); | |
- commandnode1.addChild(commandnode3); | |
- if (!commandnode2.getChildren().isEmpty()) { | |
- this.a(commandnode2, commandnode3, commandlistenerwrapper, map); | |
+ // CraftBukkit start | |
+ CommandNode target = argumentbuilder.getRedirect(); | |
+ if (target != null) { | |
+ CommandNode clonedRef = map.get(target); | |
+ if (clonedRef == null) { | |
+ pendingInit.put(target, () -> { | |
+ // Should be set now | |
+ argumentbuilder.redirect(map.get(target)); | |
+ addBuilder(commandnode1, commandlistenerwrapper, map, commandnode2, argumentbuilder, pendingInit); | |
+ }); | |
+ continue; | |
+ } | |
+ argumentbuilder.redirect(clonedRef); | |
} | |
+ addBuilder(commandnode1, commandlistenerwrapper, map, commandnode2, argumentbuilder, pendingInit); | |
} | |
} | |
} | |
+ private void addBuilder(CommandNode<ICompletionProvider> commandnode1, CommandListenerWrapper commandlistenerwrapper, Map<CommandNode<CommandListenerWrapper>, CommandNode<ICompletionProvider>> map, CommandNode<CommandListenerWrapper> commandnode2, ArgumentBuilder argumentbuilder, ArrayListMultimap<CommandNode, Runnable> pendingInit) { | |
+ CommandNode commandnode3 = argumentbuilder.build(); // CraftBukkit - decompile error | |
+ | |
+ map.put(commandnode2, commandnode3); | |
+ commandnode1.addChild(commandnode3); | |
+ if (!commandnode2.getChildren().isEmpty()) { | |
+ this.a(commandnode2, commandnode3, commandlistenerwrapper, map, pendingInit); | |
+ } | |
+ List<Runnable> pending = pendingInit.removeAll(commandnode2); | |
+ pending.forEach(Runnable::run); | |
+ } | |
+ // CraftBukkit end | |
+ | |
public static LiteralArgumentBuilder<CommandListenerWrapper> a(String s) { | |
return LiteralArgumentBuilder.literal(s); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment