299 lines
10 KiB
Java
299 lines
10 KiB
Java
package net.minecraft.commands;
|
|
|
|
import com.google.common.base.CharMatcher;
|
|
import com.google.common.base.Strings;
|
|
import com.google.common.collect.Lists;
|
|
import com.mojang.brigadier.Message;
|
|
import com.mojang.brigadier.context.CommandContext;
|
|
import com.mojang.brigadier.suggestion.Suggestions;
|
|
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
import java.util.Locale;
|
|
import java.util.Set;
|
|
import java.util.concurrent.CompletableFuture;
|
|
import java.util.function.Consumer;
|
|
import java.util.function.Function;
|
|
import java.util.function.Predicate;
|
|
import java.util.stream.Stream;
|
|
import net.minecraft.core.Registry;
|
|
import net.minecraft.core.RegistryAccess;
|
|
import net.minecraft.resources.ResourceKey;
|
|
import net.minecraft.resources.ResourceLocation;
|
|
import net.minecraft.world.flag.FeatureFlagSet;
|
|
import net.minecraft.world.level.Level;
|
|
|
|
public interface SharedSuggestionProvider {
|
|
CharMatcher MATCH_SPLITTER = CharMatcher.anyOf("._/");
|
|
|
|
Collection<String> getOnlinePlayerNames();
|
|
|
|
default Collection<String> getCustomTabSugggestions() {
|
|
return this.getOnlinePlayerNames();
|
|
}
|
|
|
|
default Collection<String> getSelectedEntities() {
|
|
return Collections.emptyList();
|
|
}
|
|
|
|
Collection<String> getAllTeams();
|
|
|
|
Stream<ResourceLocation> getAvailableSounds();
|
|
|
|
CompletableFuture<Suggestions> customSuggestion(CommandContext<?> context);
|
|
|
|
default Collection<SharedSuggestionProvider.TextCoordinates> getRelevantCoordinates() {
|
|
return Collections.singleton(SharedSuggestionProvider.TextCoordinates.DEFAULT_GLOBAL);
|
|
}
|
|
|
|
default Collection<SharedSuggestionProvider.TextCoordinates> getAbsoluteCoordinates() {
|
|
return Collections.singleton(SharedSuggestionProvider.TextCoordinates.DEFAULT_GLOBAL);
|
|
}
|
|
|
|
Set<ResourceKey<Level>> levels();
|
|
|
|
RegistryAccess registryAccess();
|
|
|
|
FeatureFlagSet enabledFeatures();
|
|
|
|
default void suggestRegistryElements(Registry<?> registry, SharedSuggestionProvider.ElementSuggestionType type, SuggestionsBuilder builder) {
|
|
if (type.shouldSuggestTags()) {
|
|
suggestResource(registry.getTags().map(named -> named.key().location()), builder, "#");
|
|
}
|
|
|
|
if (type.shouldSuggestElements()) {
|
|
suggestResource(registry.keySet(), builder);
|
|
}
|
|
}
|
|
|
|
CompletableFuture<Suggestions> suggestRegistryElements(
|
|
ResourceKey<? extends Registry<?>> resourceKey,
|
|
SharedSuggestionProvider.ElementSuggestionType registryKey,
|
|
SuggestionsBuilder builder,
|
|
CommandContext<?> context
|
|
);
|
|
|
|
boolean hasPermission(int permissionLevel);
|
|
|
|
static <T> void filterResources(Iterable<T> resources, String input, Function<T, ResourceLocation> locationFunction, Consumer<T> resourceConsumer) {
|
|
boolean bl = input.indexOf(58) > -1;
|
|
|
|
for (T object : resources) {
|
|
ResourceLocation resourceLocation = (ResourceLocation)locationFunction.apply(object);
|
|
if (bl) {
|
|
String string = resourceLocation.toString();
|
|
if (matchesSubStr(input, string)) {
|
|
resourceConsumer.accept(object);
|
|
}
|
|
} else if (matchesSubStr(input, resourceLocation.getNamespace())
|
|
|| resourceLocation.getNamespace().equals("minecraft") && matchesSubStr(input, resourceLocation.getPath())) {
|
|
resourceConsumer.accept(object);
|
|
}
|
|
}
|
|
}
|
|
|
|
static <T> void filterResources(
|
|
Iterable<T> resources, String remaining, String prefix, Function<T, ResourceLocation> locationFunction, Consumer<T> resourceConsumer
|
|
) {
|
|
if (remaining.isEmpty()) {
|
|
resources.forEach(resourceConsumer);
|
|
} else {
|
|
String string = Strings.commonPrefix(remaining, prefix);
|
|
if (!string.isEmpty()) {
|
|
String string2 = remaining.substring(string.length());
|
|
filterResources(resources, string2, locationFunction, resourceConsumer);
|
|
}
|
|
}
|
|
}
|
|
|
|
static CompletableFuture<Suggestions> suggestResource(Iterable<ResourceLocation> resources, SuggestionsBuilder builder, String prefix) {
|
|
String string = builder.getRemaining().toLowerCase(Locale.ROOT);
|
|
filterResources(resources, string, prefix, resourceLocation -> resourceLocation, resourceLocation -> builder.suggest(prefix + resourceLocation));
|
|
return builder.buildFuture();
|
|
}
|
|
|
|
static CompletableFuture<Suggestions> suggestResource(Stream<ResourceLocation> resources, SuggestionsBuilder builder, String prefix) {
|
|
return suggestResource(resources::iterator, builder, prefix);
|
|
}
|
|
|
|
static CompletableFuture<Suggestions> suggestResource(Iterable<ResourceLocation> resources, SuggestionsBuilder builder) {
|
|
String string = builder.getRemaining().toLowerCase(Locale.ROOT);
|
|
filterResources(resources, string, resourceLocation -> resourceLocation, resourceLocation -> builder.suggest(resourceLocation.toString()));
|
|
return builder.buildFuture();
|
|
}
|
|
|
|
static <T> CompletableFuture<Suggestions> suggestResource(
|
|
Iterable<T> resources, SuggestionsBuilder builder, Function<T, ResourceLocation> locationFunction, Function<T, Message> suggestionFunction
|
|
) {
|
|
String string = builder.getRemaining().toLowerCase(Locale.ROOT);
|
|
filterResources(
|
|
resources,
|
|
string,
|
|
locationFunction,
|
|
object -> builder.suggest(((ResourceLocation)locationFunction.apply(object)).toString(), (Message)suggestionFunction.apply(object))
|
|
);
|
|
return builder.buildFuture();
|
|
}
|
|
|
|
static CompletableFuture<Suggestions> suggestResource(Stream<ResourceLocation> resourceLocations, SuggestionsBuilder builder) {
|
|
return suggestResource(resourceLocations::iterator, builder);
|
|
}
|
|
|
|
static <T> CompletableFuture<Suggestions> suggestResource(
|
|
Stream<T> resources, SuggestionsBuilder builder, Function<T, ResourceLocation> locationFunction, Function<T, Message> suggestionFunction
|
|
) {
|
|
return suggestResource(resources::iterator, builder, locationFunction, suggestionFunction);
|
|
}
|
|
|
|
static CompletableFuture<Suggestions> suggestCoordinates(
|
|
String remaining, Collection<SharedSuggestionProvider.TextCoordinates> coordinates, SuggestionsBuilder builder, Predicate<String> validator
|
|
) {
|
|
List<String> list = Lists.<String>newArrayList();
|
|
if (Strings.isNullOrEmpty(remaining)) {
|
|
for (SharedSuggestionProvider.TextCoordinates textCoordinates : coordinates) {
|
|
String string = textCoordinates.x + " " + textCoordinates.y + " " + textCoordinates.z;
|
|
if (validator.test(string)) {
|
|
list.add(textCoordinates.x);
|
|
list.add(textCoordinates.x + " " + textCoordinates.y);
|
|
list.add(string);
|
|
}
|
|
}
|
|
} else {
|
|
String[] strings = remaining.split(" ");
|
|
if (strings.length == 1) {
|
|
for (SharedSuggestionProvider.TextCoordinates textCoordinates2 : coordinates) {
|
|
String string2 = strings[0] + " " + textCoordinates2.y + " " + textCoordinates2.z;
|
|
if (validator.test(string2)) {
|
|
list.add(strings[0] + " " + textCoordinates2.y);
|
|
list.add(string2);
|
|
}
|
|
}
|
|
} else if (strings.length == 2) {
|
|
for (SharedSuggestionProvider.TextCoordinates textCoordinates2x : coordinates) {
|
|
String string2 = strings[0] + " " + strings[1] + " " + textCoordinates2x.z;
|
|
if (validator.test(string2)) {
|
|
list.add(string2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return suggest(list, builder);
|
|
}
|
|
|
|
static CompletableFuture<Suggestions> suggest2DCoordinates(
|
|
String remaining, Collection<SharedSuggestionProvider.TextCoordinates> coordinates, SuggestionsBuilder builder, Predicate<String> validator
|
|
) {
|
|
List<String> list = Lists.<String>newArrayList();
|
|
if (Strings.isNullOrEmpty(remaining)) {
|
|
for (SharedSuggestionProvider.TextCoordinates textCoordinates : coordinates) {
|
|
String string = textCoordinates.x + " " + textCoordinates.z;
|
|
if (validator.test(string)) {
|
|
list.add(textCoordinates.x);
|
|
list.add(string);
|
|
}
|
|
}
|
|
} else {
|
|
String[] strings = remaining.split(" ");
|
|
if (strings.length == 1) {
|
|
for (SharedSuggestionProvider.TextCoordinates textCoordinates2 : coordinates) {
|
|
String string2 = strings[0] + " " + textCoordinates2.z;
|
|
if (validator.test(string2)) {
|
|
list.add(string2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return suggest(list, builder);
|
|
}
|
|
|
|
static CompletableFuture<Suggestions> suggest(Iterable<String> strings, SuggestionsBuilder builder) {
|
|
String string = builder.getRemaining().toLowerCase(Locale.ROOT);
|
|
|
|
for (String string2 : strings) {
|
|
if (matchesSubStr(string, string2.toLowerCase(Locale.ROOT))) {
|
|
builder.suggest(string2);
|
|
}
|
|
}
|
|
|
|
return builder.buildFuture();
|
|
}
|
|
|
|
static CompletableFuture<Suggestions> suggest(Stream<String> strings, SuggestionsBuilder builder) {
|
|
String string = builder.getRemaining().toLowerCase(Locale.ROOT);
|
|
strings.filter(string2 -> matchesSubStr(string, string2.toLowerCase(Locale.ROOT))).forEach(builder::suggest);
|
|
return builder.buildFuture();
|
|
}
|
|
|
|
static CompletableFuture<Suggestions> suggest(String[] strings, SuggestionsBuilder builder) {
|
|
String string = builder.getRemaining().toLowerCase(Locale.ROOT);
|
|
|
|
for (String string2 : strings) {
|
|
if (matchesSubStr(string, string2.toLowerCase(Locale.ROOT))) {
|
|
builder.suggest(string2);
|
|
}
|
|
}
|
|
|
|
return builder.buildFuture();
|
|
}
|
|
|
|
static <T> CompletableFuture<Suggestions> suggest(
|
|
Iterable<T> resources, SuggestionsBuilder builder, Function<T, String> stringFunction, Function<T, Message> suggestionFunction
|
|
) {
|
|
String string = builder.getRemaining().toLowerCase(Locale.ROOT);
|
|
|
|
for (T object : resources) {
|
|
String string2 = (String)stringFunction.apply(object);
|
|
if (matchesSubStr(string, string2.toLowerCase(Locale.ROOT))) {
|
|
builder.suggest(string2, (Message)suggestionFunction.apply(object));
|
|
}
|
|
}
|
|
|
|
return builder.buildFuture();
|
|
}
|
|
|
|
static boolean matchesSubStr(String input, String substring) {
|
|
int i = 0;
|
|
|
|
while (!substring.startsWith(input, i)) {
|
|
int j = MATCH_SPLITTER.indexIn(substring, i);
|
|
if (j < 0) {
|
|
return false;
|
|
}
|
|
|
|
i = j + 1;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public static enum ElementSuggestionType {
|
|
TAGS,
|
|
ELEMENTS,
|
|
ALL;
|
|
|
|
public boolean shouldSuggestTags() {
|
|
return this == TAGS || this == ALL;
|
|
}
|
|
|
|
public boolean shouldSuggestElements() {
|
|
return this == ELEMENTS || this == ALL;
|
|
}
|
|
}
|
|
|
|
public static class TextCoordinates {
|
|
public static final SharedSuggestionProvider.TextCoordinates DEFAULT_LOCAL = new SharedSuggestionProvider.TextCoordinates("^", "^", "^");
|
|
public static final SharedSuggestionProvider.TextCoordinates DEFAULT_GLOBAL = new SharedSuggestionProvider.TextCoordinates("~", "~", "~");
|
|
public final String x;
|
|
public final String y;
|
|
public final String z;
|
|
|
|
public TextCoordinates(String x, String y, String z) {
|
|
this.x = x;
|
|
this.y = y;
|
|
this.z = z;
|
|
}
|
|
}
|
|
}
|