online suggestions via suggester
This commit is contained in:
1 parent
5f9df1239a
commit
bc99b081ca
2 files changed
+72
-34
No files matched your search
@@ -215,7 +215,7 @@ public class CarpetScriptHost extends ScriptHost
|
||||
Value spec = typeData.getValue();
|
||||
if (!(spec instanceof MapValue)) throw new InternalExpressionException("Spec for '"+argument+"' should be a map");
|
||||
Map<String, Value> specData = ((MapValue) spec).getMap().entrySet().stream().collect(Collectors.toMap(e -> e.getKey().getString(), Map.Entry::getValue));
|
||||
appArgTypes.put(argument, CommandArgument.buildFromConfig(argument, specData));
|
||||
appArgTypes.put(argument, CommandArgument.buildFromConfig(argument, specData, this));
|
||||
}
|
||||
}
|
||||
appConfig = config;
|
||||
|
||||
@@ -2,11 +2,13 @@ package carpet.script.command;
|
||||
|
||||
import carpet.fakes.BlockStateArgumentInterface;
|
||||
import carpet.script.CarpetScriptHost;
|
||||
import carpet.script.argument.FunctionArgument;
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import carpet.script.value.BlockValue;
|
||||
import carpet.script.value.EntityValue;
|
||||
import carpet.script.value.FormattedTextValue;
|
||||
import carpet.script.value.ListValue;
|
||||
import carpet.script.value.MapValue;
|
||||
import carpet.script.value.NBTSerializableValue;
|
||||
import carpet.script.value.NumericValue;
|
||||
import carpet.script.value.StringValue;
|
||||
@@ -22,11 +24,14 @@ import com.mojang.brigadier.arguments.LongArgumentType;
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.context.ParsedCommandNode;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
||||
import com.mojang.brigadier.suggestion.SuggestionProvider;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
import com.mojang.brigadier.tree.ArgumentCommandNode;
|
||||
import com.mojang.brigadier.tree.CommandNode;
|
||||
import net.minecraft.advancement.Advancement;
|
||||
import net.minecraft.command.CommandSource;
|
||||
import net.minecraft.command.argument.AngleArgumentType;
|
||||
@@ -74,8 +79,10 @@ import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Vec2f;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -259,13 +266,15 @@ public abstract class CommandArgument
|
||||
{
|
||||
CommandArgument arg = getTypeForArgument(param, host);
|
||||
if (arg.suggestionProvider != null) return argument(param, arg.getArgumentType()).suggests(arg.suggestionProvider);
|
||||
return arg.needsMatching? argument(param, arg.getArgumentType()).suggests(arg::suggest) : argument(param, arg.getArgumentType());
|
||||
return arg.needsMatching? argument(param, arg.getArgumentType()).suggests((c, b) -> arg.suggest(c, b, host)) : argument(param, arg.getArgumentType());
|
||||
}
|
||||
|
||||
protected String suffix;
|
||||
protected Collection<String> examples;
|
||||
protected boolean needsMatching = false;
|
||||
protected SuggestionProvider<ServerCommandSource> suggestionProvider;
|
||||
protected FunctionArgument<Value> customSuggester;
|
||||
|
||||
|
||||
protected CommandArgument(
|
||||
String suffix,
|
||||
@@ -292,7 +301,7 @@ public abstract class CommandArgument
|
||||
return suffix;
|
||||
}
|
||||
|
||||
public static CommandArgument buildFromConfig(String suffix, Map<String, Value> config)
|
||||
public static CommandArgument buildFromConfig(String suffix, Map<String, Value> config, CarpetScriptHost host)
|
||||
{
|
||||
if (!config.containsKey("type"))
|
||||
throw new InternalExpressionException("Custom types should at least specify the type");
|
||||
@@ -300,15 +309,20 @@ public abstract class CommandArgument
|
||||
if (!builtIns.containsKey(baseType))
|
||||
throw new InternalExpressionException("Unknown base type: "+baseType);
|
||||
CommandArgument variant = builtIns.get(baseType).builder().get();
|
||||
variant.configure(config);
|
||||
variant.configure(config, host);
|
||||
variant.suffix = suffix;
|
||||
return variant;
|
||||
}
|
||||
|
||||
protected void configure(Map<String, Value> config)
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host)
|
||||
{
|
||||
if (config.containsKey("suggester"))
|
||||
{
|
||||
customSuggester = FunctionArgument.fromCommandSpec(host, config.get("suggester"));
|
||||
}
|
||||
if (config.containsKey("suggest"))
|
||||
{
|
||||
if (config.containsKey("suggester")) throw new InternalExpressionException("Attempted to provide 'suggest' list while 'suggester' is present");
|
||||
Value suggestionValue = config.get("suggest");
|
||||
if (!(suggestionValue instanceof ListValue)) throw new InternalExpressionException("Argument suggestions needs to be a list");
|
||||
examples = ((ListValue) suggestionValue).getItems().stream()
|
||||
@@ -316,34 +330,55 @@ public abstract class CommandArgument
|
||||
.collect(Collectors.toSet());
|
||||
if (!examples.isEmpty()) needsMatching = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public CompletableFuture<Suggestions> suggest(
|
||||
CommandContext<ServerCommandSource> context,
|
||||
SuggestionsBuilder suggestionsBuilder
|
||||
)
|
||||
SuggestionsBuilder suggestionsBuilder,
|
||||
CarpetScriptHost host
|
||||
) throws CommandSyntaxException
|
||||
{
|
||||
String prefix = suggestionsBuilder.getRemaining().toLowerCase(Locale.ROOT);
|
||||
suggestFor(prefix).forEach(suggestionsBuilder::suggest);
|
||||
suggestFor(context, prefix, host).forEach(suggestionsBuilder::suggest);
|
||||
return suggestionsBuilder.buildFuture();
|
||||
}
|
||||
|
||||
protected List<String> suggestFor(String prefix)
|
||||
protected List<String> suggestFor(CommandContext<ServerCommandSource> context, String prefix, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
return getOptions().stream().filter(s -> optionMatchesPrefix(prefix, s)).collect(Collectors.toList());
|
||||
return getOptions(context, host).stream().filter(s -> optionMatchesPrefix(prefix, s)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
protected Collection<String> getOptions()
|
||||
protected Collection<String> getOptions(CommandContext<ServerCommandSource> context, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
if (customSuggester != null)
|
||||
{
|
||||
Map<Value, Value> params = new HashMap<>();
|
||||
for(ParsedCommandNode<ServerCommandSource> pnode : context.getNodes())
|
||||
{
|
||||
CommandNode<ServerCommandSource> node = pnode.getNode();
|
||||
if (node instanceof ArgumentCommandNode)
|
||||
{
|
||||
params.put(StringValue.of(node.getName()), CommandArgument.getValue(context, node.getName(), host));
|
||||
}
|
||||
}
|
||||
List<Value> args = new ArrayList<>(customSuggester.args.size()+1);
|
||||
args.add(MapValue.wrap(params));
|
||||
args.addAll(customSuggester.args);
|
||||
Value response = host.handleCommand(context.getSource(), customSuggester.function, args);
|
||||
if (!(response instanceof ListValue)) throw error("Custom suggester should return a list of options");
|
||||
return ((ListValue) response).getItems().stream().map(Value::getString).collect(Collectors.toList());
|
||||
}
|
||||
if (needsMatching) return examples;
|
||||
//return Lists.newArrayList("");
|
||||
// better than nothing I guess
|
||||
// nothing is such a bad default.
|
||||
if (needsMatching) return examples;
|
||||
return Collections.singletonList("... "+getTypeSuffix());
|
||||
}
|
||||
|
||||
protected boolean optionMatchesPrefix(String prefix, String option)
|
||||
{
|
||||
//prefix = prefix.toLowerCase(Locale.ROOT);
|
||||
//option = option.toLowerCase(Locale.ROOT);
|
||||
for(int i = 0; !option.startsWith(prefix, i); ++i)
|
||||
{
|
||||
i = option.indexOf('_', i);
|
||||
@@ -382,9 +417,9 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(Map<String, Value> config)
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host)
|
||||
{
|
||||
super.configure(config);
|
||||
super.configure(config, host);
|
||||
caseSensitive = config.getOrDefault("case_sensitive", Value.FALSE).getBoolean();
|
||||
if (config.containsKey("options"))
|
||||
{
|
||||
@@ -397,7 +432,10 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<String> getOptions() { return validOptions.isEmpty()?super.getOptions():validOptions; }
|
||||
protected Collection<String> getOptions(CommandContext<ServerCommandSource> context, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
return validOptions.isEmpty()?super.getOptions(context, host):validOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Supplier<CommandArgument> builder() { return WordArgument::new; }
|
||||
@@ -446,9 +484,9 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(Map<String, Value> config)
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host)
|
||||
{
|
||||
super.configure(config);
|
||||
super.configure(config, host);
|
||||
mustBeLoaded = config.getOrDefault("loaded", Value.FALSE).getBoolean();
|
||||
}
|
||||
|
||||
@@ -481,9 +519,9 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(Map<String, Value> config)
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host)
|
||||
{
|
||||
super.configure(config);
|
||||
super.configure(config, host);
|
||||
blockCentered = config.getOrDefault("block_centered", Value.TRUE).getBoolean();
|
||||
}
|
||||
|
||||
@@ -529,9 +567,9 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(Map<String, Value> config)
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host)
|
||||
{
|
||||
super.configure(config);
|
||||
super.configure(config, host);
|
||||
onlyFans = config.getOrDefault("players", Value.FALSE).getBoolean();
|
||||
single = config.getOrDefault("single", Value.FALSE).getBoolean();
|
||||
}
|
||||
@@ -570,9 +608,9 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(Map<String, Value> config)
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host)
|
||||
{
|
||||
super.configure(config);
|
||||
super.configure(config, host);
|
||||
single = config.getOrDefault("single", Value.FALSE).getBoolean();
|
||||
}
|
||||
|
||||
@@ -611,9 +649,9 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(Map<String, Value> config)
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host)
|
||||
{
|
||||
super.configure(config);
|
||||
super.configure(config, host);
|
||||
single = config.getOrDefault("single", Value.FALSE).getBoolean();
|
||||
}
|
||||
|
||||
@@ -648,9 +686,9 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(Map<String, Value> config)
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host)
|
||||
{
|
||||
super.configure(config);
|
||||
super.configure(config, host);
|
||||
mapRequired = !config.getOrDefault("allow_element", Value.FALSE).getBoolean();
|
||||
}
|
||||
|
||||
@@ -694,9 +732,9 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(Map<String, Value> config)
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host)
|
||||
{
|
||||
super.configure(config);
|
||||
super.configure(config, host);
|
||||
if (config.containsKey("options"))
|
||||
{
|
||||
Value optionsValue = config.get("options");
|
||||
@@ -736,9 +774,9 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(Map<String, Value> config)
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host)
|
||||
{
|
||||
super.configure(config);
|
||||
super.configure(config, host);
|
||||
if (config.containsKey("min"))
|
||||
{
|
||||
min = NumericValue.asNumber(config.get("min"), "min").getDouble();
|
||||
@@ -787,9 +825,9 @@ public abstract class CommandArgument
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(Map<String, Value> config)
|
||||
protected void configure(Map<String, Value> config, CarpetScriptHost host)
|
||||
{
|
||||
super.configure(config);
|
||||
super.configure(config, host);
|
||||
if (config.containsKey("min"))
|
||||
{
|
||||
min = NumericValue.asNumber(config.get("min"), "min").getLong();
|
||||
|
||||
Reference in new issue
Block a user