Make announce-player-commands not suggest aliases

Fixes #533
This commit is contained in:
Andrew Steinborn
2021-06-24 10:10:34 -04:00
parent 59ca9a534d
commit 3b6b73f216
7 changed files with 81 additions and 6 deletions

View File

@@ -247,6 +247,8 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
LogManager.shutdown();
System.exit(1);
}
commandManager.setAnnounceProxyCommands(configuration.isAnnounceProxyCommands());
} catch (Exception e) {
logger.error("Unable to read/load/save your velocity.toml. The server will shut down.", e);
LogManager.shutdown();
@@ -384,6 +386,7 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
newConfiguration.getQueryPort());
}
commandManager.setAnnounceProxyCommands(newConfiguration.isAnnounceProxyCommands());
ipAttemptLimiter = Ratelimiters.createWithMilliseconds(newConfiguration.getLoginRatelimit());
this.configuration = newConfiguration;
eventManager.fireAndForget(new ProxyReloadEvent());

View File

@@ -33,6 +33,7 @@ import com.spotify.futures.CompletableFutures;
import com.velocitypowered.api.command.Command;
import com.velocitypowered.api.command.CommandMeta;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.proxy.command.brigadier.VelocityArgumentCommandNode;
import java.util.ArrayList;
import java.util.Collection;
@@ -62,10 +63,12 @@ final class SuggestionsProvider<S> {
private final @GuardedBy("lock") CommandDispatcher<S> dispatcher;
private final Lock lock;
private boolean announceProxyCommands;
SuggestionsProvider(final CommandDispatcher<S> dispatcher, final Lock lock) {
this.dispatcher = Preconditions.checkNotNull(dispatcher, "dispatcher");
this.lock = Preconditions.checkNotNull(lock, "lock");
this.announceProxyCommands = true;
}
/**
@@ -149,6 +152,10 @@ final class SuggestionsProvider<S> {
// TODO Is this actually faster? It may incur an allocation
final String input = reader.getRead().toLowerCase(Locale.ENGLISH);
if (source instanceof Player && !this.announceProxyCommands) {
return new SuggestionsBuilder(input, 0).buildFuture();
}
final Collection<CommandNode<S>> aliases = contextSoFar.getRootNode().getChildren();
@SuppressWarnings("unchecked")
final CompletableFuture<Suggestions>[] futures = new CompletableFuture[aliases.size()];
@@ -368,4 +375,13 @@ final class SuggestionsProvider<S> {
return Suggestions.merge(fullInput, suggestions);
});
}
/**
* Sets a flag indicating whether or not alias suggestions shall be returned to the user.
*
* @param announceProxyCommands whether alias suggestions can be returned
*/
public void setAnnounceProxyCommands(boolean announceProxyCommands) {
this.announceProxyCommands = announceProxyCommands;
}
}

View File

@@ -77,6 +77,10 @@ public class VelocityCommandManager implements CommandManager {
this.injector = new CommandGraphInjector<>(this.dispatcher, this.lock.readLock());
}
public void setAnnounceProxyCommands(boolean announceProxyCommands) {
this.suggestionsProvider.setAnnounceProxyCommands(announceProxyCommands);
}
@Override
public CommandMeta.Builder metaBuilder(final String alias) {
Preconditions.checkNotNull(alias, "alias");

View File

@@ -43,7 +43,6 @@ import com.velocitypowered.proxy.protocol.packet.brigadier.ArgumentPropertyRegis
import com.velocitypowered.proxy.util.collect.IdentityHashStrategy;
import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenCustomHashMap;
import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import java.util.ArrayDeque;
import java.util.Arrays;

View File

@@ -20,8 +20,13 @@ package com.velocitypowered.proxy.command;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.permission.Tristate;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.proxy.event.MockEventManager;
import com.velocitypowered.proxy.event.VelocityEventManager;
import java.util.Arrays;
@@ -68,4 +73,11 @@ abstract class CommandTestSuite {
final var actual = manager.offerSuggestions(source, input).join();
assertEquals(Arrays.asList(expectedSuggestions), actual);
}
final void assertPlayerSuggestions(final String input, final String... expectedSuggestions) {
final var player = mock(Player.class);
when(player.getPermissionValue(any())).thenReturn(Tristate.UNDEFINED);
final var actual = manager.offerSuggestions(player, input).join();
assertEquals(Arrays.asList(expectedSuggestions), actual);
}
}

View File

@@ -45,6 +45,17 @@ public class SuggestionsProviderTests extends CommandTestSuite {
assertSuggestions("", "bar", "baz", "foo"); // in alphabetical order
}
@Test
void willNotSuggestAliasesIfNotAnnouncingForPlayer() {
manager.setAnnounceProxyCommands(false);
manager.register(manager.metaBuilder("foo").build(), NoSuggestionsCommand.INSTANCE);
manager.register(manager.metaBuilder("bar").build(), NoSuggestionsCommand.INSTANCE);
manager.register(manager.metaBuilder("baz").build(), NoSuggestionsCommand.INSTANCE);
assertPlayerSuggestions(""); // for a fake player
assertSuggestions("", "bar", "baz", "foo"); // for non-players
}
@Test
void testDoesNotSuggestForLeadingWhitespace() {
final var meta = manager.metaBuilder("hello").build();
@@ -210,6 +221,24 @@ public class SuggestionsProviderTests extends CommandTestSuite {
assertSuggestions("hello ", "suggestion");
}
// Hints and argument suggestions should still be sent even when aliases are not being suggested.
@Test
void testSuggestWillSuggestArgumentsEvenWhenAliasesAreNot() {
final var hint = RequiredArgumentBuilder
.<CommandSource, String>argument("hint", word())
.suggests((context, builder) -> builder.suggest("suggestion").buildFuture())
.build();
final var meta = manager.metaBuilder("hello")
.hint(hint)
.build();
manager.setAnnounceProxyCommands(false);
manager.register(meta, NoSuggestionsCommand.INSTANCE);
assertSuggestions("hello ", "suggestion");
assertPlayerSuggestions("hello ", "suggestion");
}
@Test
void testDoesNotSuggestHintIfHintSuggestionProviderFutureCompletesExceptionally() {
final var hint = RequiredArgumentBuilder