|
|
|
@@ -14,17 +14,9 @@ completion, such as offline players.
|
|
|
|
|
Also adds isCommand and getLocation to the sync TabCompleteEvent
|
|
|
|
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
|
|
|
|
|
index 7270638f4a..3e8db87b88 100644
|
|
|
|
|
index 62b7f24b5a..d44ac990b4 100644
|
|
|
|
|
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
|
|
|
|
|
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
|
|
|
|
|
@@ -0,0 +0,0 @@ import io.netty.util.concurrent.Future;
|
|
|
|
|
import io.netty.util.concurrent.GenericFutureListener;
|
|
|
|
|
import java.util.Collections;
|
|
|
|
|
import java.util.Iterator;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
import java.util.Set;
|
|
|
|
|
import java.util.function.Consumer;
|
|
|
|
|
import javax.annotation.Nullable;
|
|
|
|
|
@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -42,8 +34,7 @@ index 7270638f4a..3e8db87b88 100644
|
|
|
|
|
stringreader.skip();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- ParseResults parseresults = this.minecraftServer.getCommandDispatcher().a().parse(stringreader, this.player.getCommandListener());
|
|
|
|
|
+ // Paper start
|
|
|
|
|
+ // Paper start - async tab completion
|
|
|
|
|
+ com.destroystokyo.paper.event.server.AsyncTabCompleteEvent event;
|
|
|
|
|
+ java.util.List<String> completions = new java.util.ArrayList<>();
|
|
|
|
|
+ String buffer = packetplayintabcomplete.c();
|
|
|
|
@@ -53,53 +44,29 @@ index 7270638f4a..3e8db87b88 100644
|
|
|
|
|
+ completions = event.isCancelled() ? com.google.common.collect.ImmutableList.of() : event.getCompletions();
|
|
|
|
|
+ // If the event isn't handled, we can assume that we have no completions, and so we'll ask the server
|
|
|
|
|
+ if (!event.isHandled()) {
|
|
|
|
|
+ if (!event.isCancelled() && org.bukkit.event.server.TabCompleteEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
|
|
|
|
+ java.util.List<String> finalCompletions = completions;
|
|
|
|
|
+ Waitable<java.util.List<String>> syncCompletions = new Waitable<java.util.List<String>>() {
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected java.util.List<String> evaluate() {
|
|
|
|
|
+ org.bukkit.event.server.TabCompleteEvent syncEvent = new org.bukkit.event.server.TabCompleteEvent(PlayerConnection.this.getPlayer(), buffer, finalCompletions, true, null);
|
|
|
|
|
+ return syncEvent.callEvent() ? syncEvent.getCompletions() : com.google.common.collect.ImmutableList.of();
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+ server.getServer().processQueue.add(syncCompletions);
|
|
|
|
|
+ try {
|
|
|
|
|
+ completions = syncCompletions.get();
|
|
|
|
|
+ } catch (InterruptedException | ExecutionException e1) {
|
|
|
|
|
+ e1.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!event.isCancelled()) {
|
|
|
|
|
+ // Paper end - async tab completion
|
|
|
|
|
ParseResults parseresults = this.minecraftServer.getCommandDispatcher().a().parse(stringreader, this.player.getCommandListener());
|
|
|
|
|
|
|
|
|
|
this.minecraftServer.getCommandDispatcher().a().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> {
|
|
|
|
|
if (((Suggestions) suggestions).isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [<args>] from showing for plugins with nothing more to offer
|
|
|
|
|
- this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), (Suggestions) suggestions)); // CraftBukkit - decompile error
|
|
|
|
|
- });
|
|
|
|
|
+ this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), (Suggestions) suggestions)); // CraftBukkit - decompile error
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ java.util.List<String> otherSuggestions = completions;
|
|
|
|
|
+ minecraftServer.postToMainThread(() -> sendSuggestions(packetplayintabcomplete, stringreader, otherSuggestions));
|
|
|
|
|
+ return;
|
|
|
|
|
+ // Paper start - async tab completion
|
|
|
|
|
+ } else if (!completions.isEmpty()) {
|
|
|
|
|
+ com.mojang.brigadier.suggestion.SuggestionsBuilder suggestionsBuilder = new com.mojang.brigadier.suggestion.SuggestionsBuilder(packetplayintabcomplete.c(), stringreader.getTotalLength());
|
|
|
|
|
+ completions.forEach(suggestionsBuilder::suggest);
|
|
|
|
|
+
|
|
|
|
|
+ player.playerConnection.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), suggestionsBuilder.build()));
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
- this.minecraftServer.getCommandDispatcher().a().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> {
|
|
|
|
|
- if (((Suggestions) suggestions).isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [<args>] from showing for plugins with nothing more to offer
|
|
|
|
|
- this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), (Suggestions) suggestions)); // CraftBukkit - decompile error
|
|
|
|
|
+ }
|
|
|
|
|
+ public void sendSuggestions(PacketPlayInTabComplete packetplayintabcomplete, StringReader reader, List<String> otherSuggestions) {
|
|
|
|
|
+ // Paper end - async tab completion
|
|
|
|
|
+
|
|
|
|
|
+ ParseResults parseresults = this.minecraftServer.getCommandDispatcher().a().parse(reader, this.player.getCommandListener());
|
|
|
|
|
+ //noinspection unchecked
|
|
|
|
|
+ java.util.concurrent.CompletableFuture<Suggestions> completionSuggestions = this.minecraftServer.getCommandDispatcher().a().getCompletionSuggestions(parseresults);
|
|
|
|
|
+ completionSuggestions.thenAccept((Suggestions suggestions) -> {
|
|
|
|
|
+ if (otherSuggestions != null && !otherSuggestions.isEmpty()) {
|
|
|
|
|
+ com.mojang.brigadier.suggestion.SuggestionsBuilder builder = new com.mojang.brigadier.suggestion.SuggestionsBuilder(packetplayintabcomplete.c(), reader.getTotalLength());
|
|
|
|
|
+ otherSuggestions.forEach(builder::suggest);
|
|
|
|
|
+ suggestions.getList().addAll(builder.build().getList());
|
|
|
|
|
+ }
|
|
|
|
|
+ // Paper end
|
|
|
|
|
+ if (suggestions.isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [<args>] from showing for plugins with nothing more to offer
|
|
|
|
|
+ this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), suggestions)); // CraftBukkit - decompile error
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void a(PacketPlayInSetCommandBlock packetplayinsetcommandblock) {
|
|
|
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
|
|
|
index 74e466d1f6..0e582e4e5c 100644
|
|
|
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
|
|
|