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:
Ursprung
4c3d9de5fe
Commit
9c8c851d12
@ -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}.
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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) {
|
||||||
|
@ -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)));
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren