From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Thu, 1 Apr 2021 00:34:02 -0700 Subject: [PATCH] Allow for Component suggestion tooltips in AsyncTabCompleteEvent diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java index 36df32ae2edef09e6c544c4e93ef3e262aee5566..7f73b6b63edefcf7fd4f5c7f15558af8b926f24e 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java @@ -771,12 +771,11 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser // Paper start - async tab completion com.destroystokyo.paper.event.server.AsyncTabCompleteEvent event; - java.util.List completions = new java.util.ArrayList<>(); String buffer = packet.getCommand(); - event = new com.destroystokyo.paper.event.server.AsyncTabCompleteEvent(this.getCraftPlayer(), completions, + event = new com.destroystokyo.paper.event.server.AsyncTabCompleteEvent(this.getCraftPlayer(), buffer, true, null); event.callEvent(); - completions = event.isCancelled() ? com.google.common.collect.ImmutableList.of() : event.getCompletions(); + java.util.List completions = event.isCancelled() ? com.google.common.collect.ImmutableList.of() : event.completions(); // 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()) { @@ -795,10 +794,17 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser }); } } else if (!completions.isEmpty()) { - com.mojang.brigadier.suggestion.SuggestionsBuilder builder = new com.mojang.brigadier.suggestion.SuggestionsBuilder(packet.getCommand(), stringreader.getTotalLength()); + com.mojang.brigadier.suggestion.SuggestionsBuilder builder0 = new com.mojang.brigadier.suggestion.SuggestionsBuilder(packet.getCommand(), stringreader.getTotalLength()); - builder = builder.createOffset(builder.getInput().lastIndexOf(' ') + 1); - completions.forEach(builder::suggest); + final com.mojang.brigadier.suggestion.SuggestionsBuilder builder = builder0.createOffset(builder0.getInput().lastIndexOf(' ') + 1); + completions.forEach(completion -> { + final Integer intSuggestion = com.google.common.primitives.Ints.tryParse(completion.suggestion()); + if (intSuggestion != null) { + builder.suggest(intSuggestion, PaperAdventure.asVanilla(completion.tooltip())); + } else { + builder.suggest(completion.suggestion(), PaperAdventure.asVanilla(completion.tooltip())); + } + }); com.mojang.brigadier.suggestion.Suggestions suggestions = builder.buildFuture().join(); com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getCraftPlayer(), suggestions, buffer); suggestEvent.setCancelled(suggestions.isEmpty()); diff --git a/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java b/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java index e5af155d75f717d33c23e22ff8b96bb3ff87844d..14cd8ae69d9b25dc5edad4ff96ff4a9acb1f22cb 100644 --- a/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java +++ b/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java @@ -29,34 +29,56 @@ public class ConsoleCommandCompleter implements Completer { final CraftServer server = this.server.server; final String buffer = line.line(); // Async Tab Complete - com.destroystokyo.paper.event.server.AsyncTabCompleteEvent event; - java.util.List completions = new java.util.ArrayList<>(); - event = new com.destroystokyo.paper.event.server.AsyncTabCompleteEvent(server.getConsoleSender(), completions, - buffer, true, null); + final com.destroystokyo.paper.event.server.AsyncTabCompleteEvent event = + new com.destroystokyo.paper.event.server.AsyncTabCompleteEvent(server.getConsoleSender(), buffer, true, null); event.callEvent(); - completions = event.isCancelled() ? com.google.common.collect.ImmutableList.of() : event.getCompletions(); + final List completions = event.isCancelled() ? com.google.common.collect.ImmutableList.of() : event.completions(); if (event.isCancelled() || event.isHandled()) { // Still fire sync event with the provided completions, if someone is listening if (!event.isCancelled() && TabCompleteEvent.getHandlerList().getRegisteredListeners().length > 0) { - List finalCompletions = completions; + List finalCompletions = new java.util.ArrayList<>(completions); Waitable> syncCompletions = new Waitable>() { @Override protected List evaluate() { - org.bukkit.event.server.TabCompleteEvent syncEvent = new org.bukkit.event.server.TabCompleteEvent(server.getConsoleSender(), buffer, finalCompletions); + org.bukkit.event.server.TabCompleteEvent syncEvent = new org.bukkit.event.server.TabCompleteEvent(server.getConsoleSender(), buffer, + finalCompletions.stream() + .map(com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion::suggestion) + .collect(java.util.stream.Collectors.toList())); return syncEvent.callEvent() ? syncEvent.getCompletions() : com.google.common.collect.ImmutableList.of(); } }; server.getServer().processQueue.add(syncCompletions); try { - completions = syncCompletions.get(); + final List legacyCompletions = syncCompletions.get(); + completions.removeIf(it -> !legacyCompletions.contains(it.suggestion())); // remove any suggestions that were removed + // add any new suggestions + for (final String completion : legacyCompletions) { + if (notNewSuggestion(completions, completion)) { + continue; + } + completions.add(com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion.completion(completion)); + } } catch (InterruptedException | ExecutionException e1) { e1.printStackTrace(); } } if (!completions.isEmpty()) { - candidates.addAll(completions.stream().map(Candidate::new).collect(java.util.stream.Collectors.toList())); + for (final com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion completion : completions) { + if (completion.suggestion().isEmpty()) { + continue; + } + candidates.add(new Candidate( + completion.suggestion(), + completion.suggestion(), + null, + io.papermc.paper.adventure.PaperAdventure.PLAIN.serializeOr(completion.tooltip(), null), + null, + null, + false + )); + } } return; } @@ -106,4 +128,15 @@ public class ConsoleCommandCompleter implements Completer { Thread.currentThread().interrupt(); } } + + // Paper start + private boolean notNewSuggestion(final List completions, final String completion) { + for (final com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion it : completions) { + if (it.suggestion().equals(completion)) { + return true; + } + } + return false; + } + // Paper end }