geforkt von Mirrors/Velocity
Ursprung
59ca9a534d
Commit
3b6b73f216
@ -64,7 +64,7 @@ dependencies {
|
||||
runtimeOnly 'org.jline:jline-terminal-jansi:3.16.0' // Needed for JLine
|
||||
runtimeOnly 'com.lmax:disruptor:3.4.2' // Async loggers
|
||||
|
||||
implementation 'it.unimi.dsi:fastutil:8.4.1'
|
||||
implementation 'it.unimi.dsi:fastutil-core:8.5.4'
|
||||
|
||||
implementation(platform("net.kyori:adventure-bom:${adventureVersion}"))
|
||||
implementation("net.kyori:adventure-nbt")
|
||||
@ -84,6 +84,7 @@ dependencies {
|
||||
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api:${junitVersion}"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-engine:${junitVersion}"
|
||||
testImplementation "org.mockito:mockito-core:3.+"
|
||||
}
|
||||
|
||||
test {
|
||||
@ -91,25 +92,35 @@ test {
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
// Exclude all the collection types we don't intend to use
|
||||
exclude 'it/unimi/dsi/fastutil/booleans/**'
|
||||
exclude 'it/unimi/dsi/fastutil/bytes/**'
|
||||
exclude 'it/unimi/dsi/fastutil/chars/**'
|
||||
exclude 'it/unimi/dsi/fastutil/doubles/**'
|
||||
exclude 'it/unimi/dsi/fastutil/floats/**'
|
||||
exclude 'it/unimi/dsi/fastutil/longs/**'
|
||||
exclude 'it/unimi/dsi/fastutil/shorts/**'
|
||||
|
||||
// Exclude the fastutil IO utilities - we don't use them.
|
||||
exclude 'it/unimi/dsi/fastutil/io/**'
|
||||
|
||||
// Exclude most of the int types - Object2IntMap have a values() method that returns an IntCollection
|
||||
exclude 'it/unimi/dsi/fastutil/ints/*Int2*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/IntAVL*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/IntArray*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/IntBi*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/*IntBi*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/Int*Pair'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/IntLinked*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/IntList*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/IntHeap*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/IntOpen*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/IntRB*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/IntSet*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/IntSorted*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/*Priority*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/*BigList*'
|
||||
exclude 'it/unimi/dsi/fastutil/io/**'
|
||||
exclude 'it/unimi/dsi/fastutil/longs/**'
|
||||
|
||||
// Try to exclude everything BUT Object2Int{LinkedOpen,Open,CustomOpen}HashMap
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*ObjectArray*'
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*ObjectAVL*'
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*Object*Big*'
|
||||
@ -127,7 +138,8 @@ shadowJar {
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*Object2Short*'
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*ObjectRB*'
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*Reference*'
|
||||
exclude 'it/unimi/dsi/fastutil/shorts/**'
|
||||
|
||||
// Exclude Checker Framework annotations
|
||||
exclude 'org/checkerframework/checker/**'
|
||||
|
||||
relocate 'org.bstats', 'com.velocitypowered.proxy.bstats'
|
||||
|
@ -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
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren