@@ -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());
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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");
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user