3
0
Mirror von https://github.com/PaperMC/Velocity.git synchronisiert 2024-11-16 21:10:30 +01:00

Add async command suggestions

Dieser Commit ist enthalten in:
Mariell Hoversholm 2020-07-14 23:55:34 +02:00
Ursprung 4c3d9de5fe
Commit 9c8c851d12
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 7E8663CA3C537F64
5 geänderte Dateien mit 68 neuen und 42 gelöschten Zeilen

Datei anzeigen

@ -2,6 +2,7 @@ package com.velocitypowered.api.command;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import java.util.List; import java.util.List;
import java.util.concurrent.CompletableFuture;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
/** /**
@ -29,6 +30,18 @@ public interface Command {
return ImmutableList.of(); return ImmutableList.of();
} }
/**
* Provides tab complete suggestions for a command for a specified {@link CommandSource}.
*
* @param source the source to run the command for
* @param currentArgs the current, partial arguments for this command
* @return tab complete suggestions
*/
default CompletableFuture<List<String>> suggestAsync(CommandSource source,
String @NonNull [] currentArgs) {
return CompletableFuture.completedFuture(suggest(source, currentArgs));
}
/** /**
* Tests to check if the {@code source} has permission to use this command with the provided * Tests to check if the {@code source} has permission to use this command with the provided
* {@code args}. * {@code args}.

Datei anzeigen

@ -2,6 +2,7 @@ package com.velocitypowered.api.command;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import java.util.List; import java.util.List;
import java.util.concurrent.CompletableFuture;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
/** /**
@ -29,13 +30,19 @@ public interface RawCommand extends Command {
* @param currentLine the current, partial command line for this command * @param currentLine the current, partial command line for this command
* @return tab complete suggestions * @return tab complete suggestions
*/ */
default List<String> suggest(CommandSource source, String currentLine) { default CompletableFuture<List<String>> suggest(CommandSource source, String currentLine) {
return ImmutableList.of(); return CompletableFuture.completedFuture(ImmutableList.of());
}
@Override
default CompletableFuture<List<String>> suggestAsync(CommandSource source,
String @NonNull [] currentArgs) {
return suggest(source, String.join(" ", currentArgs));
} }
@Override @Override
default List<String> suggest(CommandSource source, String @NonNull [] currentArgs) { default List<String> suggest(CommandSource source, String @NonNull [] currentArgs) {
return suggest(source, String.join(" ", currentArgs)); return suggestAsync(source, currentArgs).join();
} }
@Override @Override

Datei anzeigen

@ -157,9 +157,9 @@ public class VelocityCommandManager implements CommandManager {
* Offer suggestions to fill in the command. * Offer suggestions to fill in the command.
* @param source the source for the command * @param source the source for the command
* @param cmdLine the partially completed command * @param cmdLine the partially completed command
* @return a {@link List}, possibly empty * @return a {@link CompletableFuture} eventually completed with a {@link List}, possibly empty
*/ */
public List<String> offerSuggestions(CommandSource source, String cmdLine) { public CompletableFuture<List<String>> offerSuggestions(CommandSource source, String cmdLine) {
Preconditions.checkNotNull(source, "source"); Preconditions.checkNotNull(source, "source");
Preconditions.checkNotNull(cmdLine, "cmdLine"); Preconditions.checkNotNull(cmdLine, "cmdLine");
@ -173,7 +173,7 @@ public class VelocityCommandManager implements CommandManager {
availableCommands.add("/" + entry.getKey()); availableCommands.add("/" + entry.getKey());
} }
} }
return availableCommands.build(); return CompletableFuture.completedFuture(availableCommands.build());
} }
String alias = cmdLine.substring(0, firstSpace); String alias = cmdLine.substring(0, firstSpace);
@ -181,14 +181,15 @@ public class VelocityCommandManager implements CommandManager {
RawCommand command = commands.get(alias.toLowerCase(Locale.ENGLISH)); RawCommand command = commands.get(alias.toLowerCase(Locale.ENGLISH));
if (command == null) { if (command == null) {
// No such command, so we can't offer any tab complete suggestions. // No such command, so we can't offer any tab complete suggestions.
return ImmutableList.of(); return CompletableFuture.completedFuture(ImmutableList.of());
} }
try { try {
if (!command.hasPermission(source, args)) { if (!command.hasPermission(source, args)) {
return ImmutableList.of(); return CompletableFuture.completedFuture(ImmutableList.of());
} }
return ImmutableList.copyOf(command.suggest(source, args)); return command.suggest(source, args)
.thenApply(ImmutableList::copyOf);
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException( throw new RuntimeException(
"Unable to invoke suggestions for command " + cmdLine + " for " + source, e); "Unable to invoke suggestions for command " + cmdLine + " for " + source, e);
@ -253,8 +254,8 @@ public class VelocityCommandManager implements CommandManager {
} }
@Override @Override
public List<String> suggest(CommandSource source, String currentLine) { public CompletableFuture<List<String>> suggest(CommandSource source, String currentLine) {
return delegate.suggest(source, split(currentLine)); return delegate.suggestAsync(source, split(currentLine));
} }
@Override @Override

Datei anzeigen

@ -397,26 +397,28 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
return false; return false;
} }
List<String> suggestions = server.getCommandManager().offerSuggestions(player, command); server.getCommandManager().offerSuggestions(player, command)
if (suggestions.isEmpty()) { .thenAcceptAsync(suggestions -> {
return false; if (suggestions.isEmpty()) {
} return;
}
List<Offer> offers = new ArrayList<>(); List<Offer> offers = new ArrayList<>();
for (String suggestion : suggestions) { for (String suggestion : suggestions) {
offers.add(new Offer(suggestion)); offers.add(new Offer(suggestion));
} }
int startPos = packet.getCommand().lastIndexOf(' ') + 1; int startPos = packet.getCommand().lastIndexOf(' ') + 1;
if (startPos > 0) { if (startPos > 0) {
TabCompleteResponse resp = new TabCompleteResponse(); TabCompleteResponse resp = new TabCompleteResponse();
resp.setTransactionId(packet.getTransactionId()); resp.setTransactionId(packet.getTransactionId());
resp.setStart(startPos); resp.setStart(startPos);
resp.setLength(packet.getCommand().length() - startPos); resp.setLength(packet.getCommand().length() - startPos);
resp.getOffers().addAll(offers); resp.getOffers().addAll(offers);
player.getConnection().write(resp); player.getConnection().write(resp);
} }
return true; }, player.getConnection().eventLoop());
return true; // Sorry, handler; we're just gonna have to lie to you here.
} }
private boolean handleRegularTabComplete(TabCompleteRequest packet) { private boolean handleRegularTabComplete(TabCompleteRequest packet) {
@ -449,18 +451,20 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
private void finishCommandTabComplete(TabCompleteRequest request, TabCompleteResponse response) { private void finishCommandTabComplete(TabCompleteRequest request, TabCompleteResponse response) {
String command = request.getCommand().substring(1); String command = request.getCommand().substring(1);
try { server.getCommandManager().offerSuggestions(player, command)
List<String> offers = server.getCommandManager().offerSuggestions(player, command); .thenAcceptAsync(offers -> {
for (String offer : offers) { try {
response.getOffers().add(new Offer(offer, null)); for (String offer : offers) {
} response.getOffers().add(new Offer(offer, null));
response.getOffers().sort(null); }
player.getConnection().write(response); response.getOffers().sort(null);
} catch (Exception e) { player.getConnection().write(response);
logger.error("Unable to provide tab list completions for {} for command '{}'", } catch (Exception e) {
player.getUsername(), logger.error("Unable to provide tab list completions for {} for command '{}'",
command, e); player.getUsername(),
} command, e);
}
}, player.getConnection().eventLoop());
} }
private void finishRegularTabComplete(TabCompleteRequest request, TabCompleteResponse response) { private void finishRegularTabComplete(TabCompleteRequest request, TabCompleteResponse response) {

Datei anzeigen

@ -73,7 +73,8 @@ public final class VelocityConsole extends SimpleTerminalConsole implements Cons
try { try {
boolean isCommand = parsedLine.line().indexOf(' ') == -1; boolean isCommand = parsedLine.line().indexOf(' ') == -1;
List<String> offers = this.server.getCommandManager() List<String> offers = this.server.getCommandManager()
.offerSuggestions(this, parsedLine.line()); .offerSuggestions(this, parsedLine.line())
.join(); // Console doesn't get harmed much by this...
for (String offer : offers) { for (String offer : offers) {
if (isCommand) { if (isCommand) {
list.add(new Candidate(offer.substring(1))); list.add(new Candidate(offer.substring(1)));