Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-12-24 15:20:35 +01:00
Add async command suggestions
Dieser Commit ist enthalten in:
Ursprung
4c3d9de5fe
Commit
9c8c851d12
@ -2,6 +2,7 @@ package com.velocitypowered.api.command;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
/**
|
||||
@ -29,6 +30,18 @@ public interface Command {
|
||||
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
|
||||
* {@code args}.
|
||||
|
@ -2,6 +2,7 @@ package com.velocitypowered.api.command;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
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
|
||||
* @return tab complete suggestions
|
||||
*/
|
||||
default List<String> suggest(CommandSource source, String currentLine) {
|
||||
return ImmutableList.of();
|
||||
default CompletableFuture<List<String>> suggest(CommandSource source, String currentLine) {
|
||||
return CompletableFuture.completedFuture(ImmutableList.of());
|
||||
}
|
||||
|
||||
@Override
|
||||
default CompletableFuture<List<String>> suggestAsync(CommandSource source,
|
||||
String @NonNull [] currentArgs) {
|
||||
return suggest(source, String.join(" ", currentArgs));
|
||||
}
|
||||
|
||||
@Override
|
||||
default List<String> suggest(CommandSource source, String @NonNull [] currentArgs) {
|
||||
return suggest(source, String.join(" ", currentArgs));
|
||||
return suggestAsync(source, currentArgs).join();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -157,9 +157,9 @@ public class VelocityCommandManager implements CommandManager {
|
||||
* Offer suggestions to fill in the command.
|
||||
* @param source the source for the 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(cmdLine, "cmdLine");
|
||||
|
||||
@ -173,7 +173,7 @@ public class VelocityCommandManager implements CommandManager {
|
||||
availableCommands.add("/" + entry.getKey());
|
||||
}
|
||||
}
|
||||
return availableCommands.build();
|
||||
return CompletableFuture.completedFuture(availableCommands.build());
|
||||
}
|
||||
|
||||
String alias = cmdLine.substring(0, firstSpace);
|
||||
@ -181,14 +181,15 @@ public class VelocityCommandManager implements CommandManager {
|
||||
RawCommand command = commands.get(alias.toLowerCase(Locale.ENGLISH));
|
||||
if (command == null) {
|
||||
// No such command, so we can't offer any tab complete suggestions.
|
||||
return ImmutableList.of();
|
||||
return CompletableFuture.completedFuture(ImmutableList.of());
|
||||
}
|
||||
|
||||
try {
|
||||
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) {
|
||||
throw new RuntimeException(
|
||||
"Unable to invoke suggestions for command " + cmdLine + " for " + source, e);
|
||||
@ -253,8 +254,8 @@ public class VelocityCommandManager implements CommandManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> suggest(CommandSource source, String currentLine) {
|
||||
return delegate.suggest(source, split(currentLine));
|
||||
public CompletableFuture<List<String>> suggest(CommandSource source, String currentLine) {
|
||||
return delegate.suggestAsync(source, split(currentLine));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -397,26 +397,28 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<String> suggestions = server.getCommandManager().offerSuggestions(player, command);
|
||||
if (suggestions.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
server.getCommandManager().offerSuggestions(player, command)
|
||||
.thenAcceptAsync(suggestions -> {
|
||||
if (suggestions.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<Offer> offers = new ArrayList<>();
|
||||
for (String suggestion : suggestions) {
|
||||
offers.add(new Offer(suggestion));
|
||||
}
|
||||
List<Offer> offers = new ArrayList<>();
|
||||
for (String suggestion : suggestions) {
|
||||
offers.add(new Offer(suggestion));
|
||||
}
|
||||
|
||||
int startPos = packet.getCommand().lastIndexOf(' ') + 1;
|
||||
if (startPos > 0) {
|
||||
TabCompleteResponse resp = new TabCompleteResponse();
|
||||
resp.setTransactionId(packet.getTransactionId());
|
||||
resp.setStart(startPos);
|
||||
resp.setLength(packet.getCommand().length() - startPos);
|
||||
resp.getOffers().addAll(offers);
|
||||
player.getConnection().write(resp);
|
||||
}
|
||||
return true;
|
||||
int startPos = packet.getCommand().lastIndexOf(' ') + 1;
|
||||
if (startPos > 0) {
|
||||
TabCompleteResponse resp = new TabCompleteResponse();
|
||||
resp.setTransactionId(packet.getTransactionId());
|
||||
resp.setStart(startPos);
|
||||
resp.setLength(packet.getCommand().length() - startPos);
|
||||
resp.getOffers().addAll(offers);
|
||||
player.getConnection().write(resp);
|
||||
}
|
||||
}, player.getConnection().eventLoop());
|
||||
return true; // Sorry, handler; we're just gonna have to lie to you here.
|
||||
}
|
||||
|
||||
private boolean handleRegularTabComplete(TabCompleteRequest packet) {
|
||||
@ -449,18 +451,20 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
|
||||
private void finishCommandTabComplete(TabCompleteRequest request, TabCompleteResponse response) {
|
||||
String command = request.getCommand().substring(1);
|
||||
try {
|
||||
List<String> offers = server.getCommandManager().offerSuggestions(player, command);
|
||||
for (String offer : offers) {
|
||||
response.getOffers().add(new Offer(offer, null));
|
||||
}
|
||||
response.getOffers().sort(null);
|
||||
player.getConnection().write(response);
|
||||
} catch (Exception e) {
|
||||
logger.error("Unable to provide tab list completions for {} for command '{}'",
|
||||
player.getUsername(),
|
||||
command, e);
|
||||
}
|
||||
server.getCommandManager().offerSuggestions(player, command)
|
||||
.thenAcceptAsync(offers -> {
|
||||
try {
|
||||
for (String offer : offers) {
|
||||
response.getOffers().add(new Offer(offer, null));
|
||||
}
|
||||
response.getOffers().sort(null);
|
||||
player.getConnection().write(response);
|
||||
} catch (Exception e) {
|
||||
logger.error("Unable to provide tab list completions for {} for command '{}'",
|
||||
player.getUsername(),
|
||||
command, e);
|
||||
}
|
||||
}, player.getConnection().eventLoop());
|
||||
}
|
||||
|
||||
private void finishRegularTabComplete(TabCompleteRequest request, TabCompleteResponse response) {
|
||||
|
@ -73,7 +73,8 @@ public final class VelocityConsole extends SimpleTerminalConsole implements Cons
|
||||
try {
|
||||
boolean isCommand = parsedLine.line().indexOf(' ') == -1;
|
||||
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) {
|
||||
if (isCommand) {
|
||||
list.add(new Candidate(offer.substring(1)));
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren