geforkt von Mirrors/FastAsyncWorldEdit
Add comprehensive suggestions to many commands.
All patterns now have suggestions, including recursive patterns. Suggestions will suggest blocks and block states. All masks now have suggestions, though mask intersections are not yet supported due to issues with quotes strings. EntityRemover and ItemFactory now also have completions, as well as all RegistryConverters (though I am unsure how many are actually used). Also use paper's AsyncTabComplete event, if available.
Dieser Commit ist enthalten in:
Ursprung
871c25e1cd
Commit
6962b2e7b6
@ -44,7 +44,7 @@
|
||||
<subpackage name="bukkit">
|
||||
<allow pkg="org.bukkit"/>
|
||||
<allow pkg="org.bstats.bukkit"/>
|
||||
<allow pkg="net.minecraft.server"/>
|
||||
<allow pkg="io.papermc.lib"/>
|
||||
</subpackage>
|
||||
|
||||
<subpackage name="forge">
|
||||
|
@ -19,7 +19,8 @@ dependencies {
|
||||
compile project(':worldedit-libs:bukkit')
|
||||
compile 'com.sk89q:dummypermscompat:1.10'
|
||||
compile 'org.bukkit:bukkit:1.13.2-R0.1-SNAPSHOT' // zzz
|
||||
compile "io.papermc:paperlib:1.0.1"
|
||||
compile 'com.destroystokyo.paper:paper-api:1.13.2-R0.1-SNAPSHOT'
|
||||
compile "io.papermc:paperlib:1.0.2"
|
||||
compile 'org.apache.logging.log4j:log4j-slf4j-impl:2.8.1'
|
||||
compile 'org.bstats:bstats-bukkit:1.4'
|
||||
testCompile 'org.mockito:mockito-core:1.9.0-rc1'
|
||||
@ -53,7 +54,7 @@ shadowJar {
|
||||
include(dependency("org.bstats:bstats-bukkit:1.4"))
|
||||
}
|
||||
relocate ("io.papermc.lib", "com.sk89q.worldedit.bukkit.paperlib") {
|
||||
include(dependency("io.papermc:paperlib:1.0.1"))
|
||||
include(dependency("io.papermc:paperlib:1.0.2"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ public class BukkitAdapter {
|
||||
if (match != null) {
|
||||
return match;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Can't find a Bukkit world for " + world);
|
||||
throw new IllegalArgumentException("Can't find a Bukkit world for " + world.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ import com.sk89q.worldedit.world.gamemode.GameModes;
|
||||
import com.sk89q.worldedit.world.item.ItemCategory;
|
||||
import com.sk89q.worldedit.world.item.ItemType;
|
||||
import com.sk89q.worldedit.world.weather.WeatherTypes;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
@ -75,6 +76,7 @@ import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.ZipEntry;
|
||||
@ -122,6 +124,10 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter {
|
||||
|
||||
// Now we can register events
|
||||
getServer().getPluginManager().registerEvents(new WorldEditListener(this), this);
|
||||
// register async tab complete, if available
|
||||
if (PaperLib.isPaper()) {
|
||||
getServer().getPluginManager().registerEvents(new AsyncTabCompleteListener(), this);
|
||||
}
|
||||
|
||||
// register this so we can load world-dependent data right as the first world is loading
|
||||
if (worldInitListener != null) {
|
||||
@ -138,6 +144,7 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter {
|
||||
|
||||
// Enable metrics
|
||||
new Metrics(this);
|
||||
PaperLib.suggestPaper(this);
|
||||
}
|
||||
|
||||
private void setupWorldData() {
|
||||
@ -171,11 +178,12 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter {
|
||||
).toImmutableState();
|
||||
BlockState defaultState = blockState.getBlockType().getAllStates().get(0);
|
||||
for (Map.Entry<Property<?>, Object> propertyObjectEntry : state.getStates().entrySet()) {
|
||||
defaultState = defaultState.with((Property) propertyObjectEntry.getKey(), propertyObjectEntry.getValue());
|
||||
//noinspection unchecked
|
||||
defaultState = defaultState.with((Property<Object>) propertyObjectEntry.getKey(), propertyObjectEntry.getValue());
|
||||
}
|
||||
return defaultState;
|
||||
} catch (InputParseException e) {
|
||||
e.printStackTrace();
|
||||
getLogger().log(Level.WARNING, "Error loading block state for " + material.getKey(), e);
|
||||
return blockState;
|
||||
}
|
||||
}));
|
||||
@ -206,7 +214,7 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter {
|
||||
for (Tag<Material> itemTag : Bukkit.getTags(Tag.REGISTRY_ITEMS, Material.class)) {
|
||||
ItemCategory.REGISTRY.register(itemTag.getKey().toString(), new ItemCategory(itemTag.getKey().toString()));
|
||||
}
|
||||
} catch (NoSuchMethodError e) {
|
||||
} catch (NoSuchMethodError ignored) {
|
||||
getLogger().warning("The version of Spigot/Paper you are using doesn't support Tags. The usage of tags with WorldEdit will not work until you update.");
|
||||
}
|
||||
}
|
||||
@ -458,4 +466,29 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter {
|
||||
setupWorldData();
|
||||
}
|
||||
}
|
||||
|
||||
private class AsyncTabCompleteListener implements Listener {
|
||||
AsyncTabCompleteListener() {
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnnecessaryFullyQualifiedName")
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onAsyncTabComplete(com.destroystokyo.paper.event.server.AsyncTabCompleteEvent event) {
|
||||
if (!event.isCommand()) return;
|
||||
|
||||
String buffer = event.getBuffer();
|
||||
final String[] parts = buffer.split(" ");
|
||||
if (parts.length < 1) return;
|
||||
final String label = parts[0];
|
||||
final Optional<org.enginehub.piston.Command> command
|
||||
= WorldEdit.getInstance().getPlatformManager().getPlatformCommandManager().getCommandManager().getCommand(label);
|
||||
if (!command.isPresent()) return;
|
||||
|
||||
CommandSuggestionEvent suggestEvent = new CommandSuggestionEvent(wrapCommandSender(event.getSender()), event.getBuffer());
|
||||
getWorldEdit().getEventBus().post(suggestEvent);
|
||||
|
||||
event.setCompletions(CommandUtil.fixSuggestions(event.getBuffer(), suggestEvent.getSuggestions()));
|
||||
event.setHandled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -306,6 +306,10 @@ public final class StringUtil {
|
||||
}
|
||||
|
||||
public static List<String> parseListInQuotes(String[] input, char delimiter, char quoteOpen, char quoteClose) {
|
||||
return parseListInQuotes(input, delimiter, quoteOpen, quoteClose, false);
|
||||
}
|
||||
|
||||
public static List<String> parseListInQuotes(String[] input, char delimiter, char quoteOpen, char quoteClose, boolean appendLeftover) {
|
||||
List<String> parsableBlocks = new ArrayList<>();
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
for (String split : input) {
|
||||
@ -321,6 +325,9 @@ public final class StringUtil {
|
||||
buffer.append(split).append(delimiter);
|
||||
}
|
||||
}
|
||||
if (appendLeftover && buffer.length() != 0) {
|
||||
parsableBlocks.add(buffer.delete(buffer.length() - 1, buffer.length()).toString());
|
||||
}
|
||||
|
||||
return parsableBlocks;
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ public class RegionCommands {
|
||||
@Logging(REGION)
|
||||
public int set(Player player, EditSession editSession,
|
||||
@Selection Region region,
|
||||
@Arg(desc = "The patter of blocks to set")
|
||||
@Arg(desc = "The pattern of blocks to set")
|
||||
Pattern pattern) {
|
||||
RegionFunction set = new BlockReplace(editSession, pattern);
|
||||
RegionVisitor visitor = new RegionVisitor(region, set);
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.command.argument;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.worldedit.command.util.EntityRemover;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
@ -30,12 +31,19 @@ import org.enginehub.piston.converter.SuccessfulConversion;
|
||||
import org.enginehub.piston.inject.InjectedValueAccess;
|
||||
import org.enginehub.piston.inject.Key;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.enginehub.piston.converter.SuggestionHelper.limitByPrefix;
|
||||
|
||||
public class EntityRemoverConverter implements ArgumentConverter<EntityRemover> {
|
||||
|
||||
public static void register(CommandManager commandManager) {
|
||||
commandManager.registerConverter(Key.of(EntityRemover.class), new EntityRemoverConverter());
|
||||
}
|
||||
|
||||
private final List<String> suggestions
|
||||
= ImmutableList.of("projectiles", "items", "paintings", "itemframes", "boats", "minecarts", "tnt", "xp", "all");
|
||||
|
||||
private EntityRemoverConverter() {
|
||||
}
|
||||
|
||||
@ -46,6 +54,11 @@ public class EntityRemoverConverter implements ArgumentConverter<EntityRemover>
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getSuggestions(String input) {
|
||||
return limitByPrefix(suggestions.stream(), input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversionResult<EntityRemover> convert(String argument, InjectedValueAccess context) {
|
||||
try {
|
||||
|
@ -19,8 +19,6 @@
|
||||
|
||||
package com.sk89q.worldedit.command.argument;
|
||||
|
||||
import static org.enginehub.piston.converter.SuggestionHelper.limitByPrefix;
|
||||
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.blocks.BaseItem;
|
||||
|
@ -21,6 +21,7 @@ package com.sk89q.worldedit.command.argument;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.worldedit.registry.Keyed;
|
||||
import com.sk89q.worldedit.registry.NamespacedRegistry;
|
||||
import com.sk89q.worldedit.registry.Registry;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
@ -84,10 +85,12 @@ public final class RegistryConverter<V extends Keyed> implements ArgumentConvert
|
||||
|
||||
private final Registry<V> registry;
|
||||
private final TextComponent choices;
|
||||
private final boolean namespaced;
|
||||
|
||||
private RegistryConverter(Registry<V> registry) {
|
||||
this.registry = registry;
|
||||
this.choices = TextComponent.of("any " + registry.getName());
|
||||
this.namespaced = registry instanceof NamespacedRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -106,6 +109,9 @@ public final class RegistryConverter<V extends Keyed> implements ArgumentConvert
|
||||
|
||||
@Override
|
||||
public List<String> getSuggestions(String input) {
|
||||
if (namespaced && input.indexOf(':') < 0) {
|
||||
input = "minecraft:" + input;
|
||||
}
|
||||
return limitByPrefix(registry.keySet().stream(), input);
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,6 @@ public final class ItemUseFactory implements Contextual<RegionFunction> {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "application of the item " + item.getType() + ":" + item.getNbtData();
|
||||
return "application of the item " + item.getType();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.command.util;
|
||||
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.world.block.BlockCategory;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public final class SuggestionHelper {
|
||||
private SuggestionHelper() {
|
||||
}
|
||||
|
||||
public static Stream<String> getBlockCategorySuggestions(String tag, boolean allowRandom) {
|
||||
final Stream<String> allTags = BlockCategory.REGISTRY.keySet().stream().map(str -> "##" + str);
|
||||
if (tag.isEmpty()) {
|
||||
return allTags;
|
||||
}
|
||||
if (tag.startsWith("#")) {
|
||||
String key;
|
||||
if (tag.startsWith("##")) {
|
||||
key = tag.substring(2);
|
||||
if (key.isEmpty()) {
|
||||
return allTags;
|
||||
}
|
||||
boolean anyState = false;
|
||||
if (allowRandom && key.charAt(0) == '*') {
|
||||
key = key.substring(1);
|
||||
anyState = true;
|
||||
}
|
||||
if (key.indexOf(':') < 0) {
|
||||
key = "minecraft:" + key;
|
||||
}
|
||||
String finalTag = key.toLowerCase(Locale.ROOT);
|
||||
final Stream<String> stream = BlockCategory.REGISTRY.keySet().stream().filter(s ->
|
||||
s.startsWith(finalTag));
|
||||
return anyState ? stream.map(s -> "##*" + s) : stream.map(s -> "##" + s);
|
||||
} else if (tag.length() == 1) {
|
||||
return allTags;
|
||||
}
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
public static Stream<String> getBlockPropertySuggestions(String blockType, String props) {
|
||||
BlockType type = BlockTypes.get(blockType.toLowerCase(Locale.ROOT));
|
||||
if (type == null) {
|
||||
return Stream.empty();
|
||||
}
|
||||
final Map<String, ? extends Property<?>> propertyMap = type.getPropertyMap();
|
||||
Set<String> matchedProperties = new HashSet<>();
|
||||
String[] propParts = props.split(",", -1);
|
||||
for (int i = 0; i < propParts.length; i++) {
|
||||
String[] propVal = propParts[i].split("=");
|
||||
final String matchProp = propVal[0].toLowerCase(Locale.ROOT);
|
||||
if (i == propParts.length - 1) {
|
||||
// suggest for next property
|
||||
String previous = Arrays.stream(propParts, 0, propParts.length - 1).collect(Collectors.joining(","))
|
||||
+ (propParts.length == 1 ? "" : ",");
|
||||
String lastValidInput = (blockType + "[" + previous).toLowerCase(Locale.ROOT);
|
||||
if (propVal.length == 1) {
|
||||
// only property, no value yet
|
||||
final List<? extends Property<?>> matchingProps = propertyMap.entrySet().stream()
|
||||
.filter(p -> !matchedProperties.contains(p.getKey()) && p.getKey().startsWith(matchProp))
|
||||
.map(Map.Entry::getValue).collect(Collectors.toList());
|
||||
switch (matchingProps.size()) {
|
||||
case 0:
|
||||
return propertyMap.keySet().stream().filter(p -> !matchedProperties.contains(p)).map(prop ->
|
||||
lastValidInput + prop + "=");
|
||||
case 1:
|
||||
return matchingProps.get(0).getValues().stream().map(val ->
|
||||
lastValidInput + matchingProps.get(0).getName() + "="
|
||||
+ val.toString().toLowerCase(Locale.ROOT));
|
||||
default:
|
||||
return matchingProps.stream().map(p -> lastValidInput + p.getName() + "=");
|
||||
}
|
||||
} else {
|
||||
Property<?> prop = propertyMap.get(matchProp);
|
||||
if (prop == null) {
|
||||
return Stream.empty();
|
||||
}
|
||||
final List<String> values = prop.getValues().stream().map(v -> v.toString().toLowerCase(Locale.ROOT)).collect(Collectors.toList());
|
||||
String matchVal = propVal[1].toLowerCase(Locale.ROOT);
|
||||
List<String> matchingVals = values.stream().filter(val -> val.startsWith(matchVal)).collect(Collectors.toList());
|
||||
if (matchingVals.isEmpty()) {
|
||||
return values.stream().map(val -> lastValidInput + prop.getName() + "=" + val);
|
||||
} else {
|
||||
if (matchingVals.size() == 1 && matchingVals.get(0).equals(matchVal)) {
|
||||
String currProp = lastValidInput + prop.getName() + "=" + matchVal;
|
||||
if (matchingVals.size() < values.size()) {
|
||||
return Stream.of(currProp + "] ", currProp + ",");
|
||||
}
|
||||
return Stream.of(currProp + "] ");
|
||||
}
|
||||
return matchingVals.stream().map(val -> lastValidInput + prop.getName() + "=" + val);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// validate previous properties
|
||||
if (propVal.length != 2) {
|
||||
return Stream.empty();
|
||||
}
|
||||
Property<?> prop = propertyMap.get(matchProp);
|
||||
if (prop == null) {
|
||||
return Stream.empty();
|
||||
}
|
||||
try {
|
||||
prop.getValueFor(propVal[1]);
|
||||
matchedProperties.add(prop.getName());
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
return Stream.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
}
|
@ -61,7 +61,7 @@ public class BlockFactory extends AbstractFactory<BaseBlock> {
|
||||
public Set<BaseBlock> parseFromListInput(String input, ParserContext context) throws InputParseException {
|
||||
Set<BaseBlock> blocks = new HashSet<>();
|
||||
String[] splits = input.split(",");
|
||||
for (String token : StringUtil.parseListInQuotes(splits, ',', '[', ']')) {
|
||||
for (String token : StringUtil.parseListInQuotes(splits, ',', '[', ']', true)) {
|
||||
blocks.add(parseFromInput(token, context));
|
||||
}
|
||||
return blocks;
|
||||
|
@ -64,13 +64,15 @@ public final class MaskFactory extends AbstractFactory<Mask> {
|
||||
register(new SolidMaskParser(worldEdit));
|
||||
register(new LazyRegionMaskParser(worldEdit));
|
||||
register(new RegionMaskParser(worldEdit));
|
||||
register(new BlockCategoryMaskParser(worldEdit));
|
||||
register(new OffsetMaskParser(worldEdit));
|
||||
register(new BiomeMaskParser(worldEdit));
|
||||
register(new NoiseMaskParser(worldEdit));
|
||||
register(new BlockStateMaskParser(worldEdit));
|
||||
register(new NegateMaskParser(worldEdit));
|
||||
register(new ExpressionMaskParser(worldEdit));
|
||||
|
||||
register(new BlockCategoryMaskParser(worldEdit));
|
||||
register(new BiomeMaskParser(worldEdit));
|
||||
|
||||
register(new BlocksMaskParser(worldEdit));
|
||||
}
|
||||
|
||||
|
@ -50,10 +50,10 @@ public final class PatternFactory extends AbstractFactory<Pattern> {
|
||||
register(new RandomPatternParser(worldEdit));
|
||||
|
||||
// individual patterns
|
||||
register(new BlockCategoryPatternParser(worldEdit));
|
||||
register(new ClipboardPatternParser(worldEdit));
|
||||
register(new TypeOrStateApplyingPatternParser(worldEdit));
|
||||
register(new RandomStatePatternParser(worldEdit));
|
||||
register(new BlockCategoryPatternParser(worldEdit));
|
||||
|
||||
// inner-most pattern: just one block - must be last
|
||||
register(new SingleBlockPatternParser(worldEdit));
|
||||
|
@ -27,6 +27,7 @@ import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.MobSpawnerBlock;
|
||||
import com.sk89q.worldedit.blocks.SignBlock;
|
||||
import com.sk89q.worldedit.blocks.SkullBlock;
|
||||
import com.sk89q.worldedit.command.util.SuggestionHelper;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.input.DisallowedUsageException;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
@ -38,7 +39,6 @@ import com.sk89q.worldedit.internal.registry.InputParser;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.util.HandSide;
|
||||
import com.sk89q.worldedit.util.formatting.component.ErrorFormat;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
@ -101,7 +101,7 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
|
||||
}
|
||||
}
|
||||
|
||||
private static String[] EMPTY_STRING_ARRAY = new String[]{};
|
||||
private static String[] EMPTY_STRING_ARRAY = {};
|
||||
|
||||
/**
|
||||
* Backwards compatibility for wool colours in block syntax.
|
||||
@ -169,11 +169,9 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
|
||||
Property<Object> propertyKey = (Property<Object>) type.getPropertyMap().get(parts[0]);
|
||||
if (propertyKey == null) {
|
||||
if (context.getActor() != null) {
|
||||
context.getActor().print(ErrorFormat.wrap("Unknown property ", parts[0], " for block ", type.getName(),
|
||||
". Defaulting to base."));
|
||||
throw new NoMatchException("Unknown property " + parts[0] + " for block " + type.getName());
|
||||
} else {
|
||||
WorldEdit.logger.warn("Unknown property " + parts[0] + " for block " + type.getName());
|
||||
// throw new NoMatchException("Unknown property " + parts[0] + " for block " + type.getName());
|
||||
}
|
||||
return Maps.newHashMap();
|
||||
}
|
||||
@ -202,9 +200,30 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String input) {
|
||||
// TODO Include states
|
||||
final int idx = input.lastIndexOf('[');
|
||||
if (idx < 0) {
|
||||
if (input.indexOf(':') == -1) {
|
||||
String key = ("minecraft:" + input).toLowerCase(Locale.ROOT);
|
||||
return BlockType.REGISTRY.keySet().stream().filter(s -> s.startsWith(key));
|
||||
}
|
||||
if (input.contains(",")) {
|
||||
return Stream.empty();
|
||||
}
|
||||
return BlockType.REGISTRY.keySet().stream();
|
||||
}
|
||||
String blockType = input.substring(0, idx);
|
||||
BlockType type = BlockTypes.get(blockType.toLowerCase(Locale.ROOT));
|
||||
if (type == null) {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
String props = input.substring(idx + 1);
|
||||
if (props.isEmpty()) {
|
||||
return type.getProperties().stream().map(p -> input + p.getName() + "=");
|
||||
}
|
||||
|
||||
return SuggestionHelper.getBlockPropertySuggestions(blockType, props);
|
||||
}
|
||||
|
||||
private BaseBlock parseLogic(String input, ParserContext context) throws InputParseException {
|
||||
BlockType blockType = null;
|
||||
@ -238,6 +257,13 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
|
||||
typeString = blockAndExtraData[0];
|
||||
} else {
|
||||
typeString = blockAndExtraData[0].substring(0, stateStart);
|
||||
if (stateStart + 1 >= blockAndExtraData[0].length()) {
|
||||
throw new InputParseException("Invalid format. Hanging bracket @ " + stateStart + ".");
|
||||
}
|
||||
int stateEnd = blockAndExtraData[0].lastIndexOf(']');
|
||||
if (stateEnd < 0) {
|
||||
throw new InputParseException("Invalid format. Unclosed property.");
|
||||
}
|
||||
stateString = blockAndExtraData[0].substring(stateStart + 1, blockAndExtraData[0].length() - 1);
|
||||
}
|
||||
if (typeString.isEmpty()) {
|
||||
|
@ -28,10 +28,7 @@ import com.sk89q.worldedit.world.item.ItemType;
|
||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class DefaultItemParser extends InputParser<BaseItem> {
|
||||
@ -42,7 +39,11 @@ public class DefaultItemParser extends InputParser<BaseItem> {
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String input) {
|
||||
return ItemType.REGISTRY.keySet().stream();
|
||||
if (input.indexOf(':') == -1) {
|
||||
input = "minecraft:" + input;
|
||||
}
|
||||
String key = input;
|
||||
return ItemType.REGISTRY.keySet().stream().filter(s -> s.startsWith(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -58,8 +59,10 @@ public class DefaultItemParser extends InputParser<BaseItem> {
|
||||
} else {
|
||||
type = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
|
||||
}
|
||||
if (type != null) {
|
||||
item = new BaseItem(type);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ import com.sk89q.worldedit.world.registry.BiomeRegistry;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@ -46,7 +47,22 @@ public class BiomeMaskParser extends InputParser<Mask> {
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String input) {
|
||||
return BiomeType.REGISTRY.keySet().stream().map(biomeType -> "$" + biomeType);
|
||||
final Stream<String> allBiomes = BiomeType.REGISTRY.keySet().stream().map(biomeType -> "$" + biomeType);
|
||||
if (input.isEmpty()) {
|
||||
return allBiomes;
|
||||
}
|
||||
if (input.charAt(0) == '$') {
|
||||
String key = input.substring(1);
|
||||
if (key.isEmpty()) {
|
||||
return allBiomes;
|
||||
}
|
||||
if (key.indexOf(':') < 0) {
|
||||
key = "minecraft:" + key;
|
||||
}
|
||||
String biomeId = key.toLowerCase(Locale.ROOT);
|
||||
return BiomeType.REGISTRY.keySet().stream().filter(s -> s.startsWith(biomeId)).map(s -> "$" + s);
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -20,6 +20,7 @@
|
||||
package com.sk89q.worldedit.extension.factory.parser.mask;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.util.SuggestionHelper;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.BlockCategoryMask;
|
||||
@ -39,7 +40,7 @@ public class BlockCategoryMaskParser extends InputParser<Mask> {
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String input) {
|
||||
return BlockCategory.REGISTRY.keySet().stream().map(str -> "##" + str);
|
||||
return SuggestionHelper.getBlockCategorySuggestions(input, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -28,12 +28,22 @@ import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.internal.registry.InputParser;
|
||||
import com.sk89q.worldedit.session.request.RequestExtent;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class BlockStateMaskParser extends InputParser<Mask> {
|
||||
|
||||
public BlockStateMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String input) {
|
||||
if (input.isEmpty()) {
|
||||
return Stream.of("^[", "^=[");
|
||||
}
|
||||
return Stream.of("^[", "^=[").filter(s -> s.startsWith(input)); // no block type, can't suggest states
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||
if (!(input.startsWith("^[") || input.startsWith("^=[")) || !input.endsWith("]")) {
|
||||
|
@ -28,7 +28,6 @@ import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.internal.registry.InputParser;
|
||||
import com.sk89q.worldedit.session.request.RequestExtent;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockCategory;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.extension.factory.parser.mask;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
|
||||
@ -31,13 +31,15 @@ import java.util.List;
|
||||
|
||||
public class ExistingMaskParser extends SimpleInputParser<Mask> {
|
||||
|
||||
private final List<String> aliases = ImmutableList.of("#existing");
|
||||
|
||||
public ExistingMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMatchedAliases() {
|
||||
return Lists.newArrayList("#existing");
|
||||
return aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -30,10 +30,10 @@ import com.sk89q.worldedit.internal.registry.InputParser;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment;
|
||||
import com.sk89q.worldedit.session.SessionOwner;
|
||||
import com.sk89q.worldedit.session.request.Request;
|
||||
import com.sk89q.worldedit.session.request.RequestExtent;
|
||||
|
||||
import java.util.function.IntSupplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ExpressionMaskParser extends InputParser<Mask> {
|
||||
|
||||
@ -41,6 +41,14 @@ public class ExpressionMaskParser extends InputParser<Mask> {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String input) {
|
||||
if (input.isEmpty()) {
|
||||
return Stream.of("=");
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||
if (!input.startsWith("=")) {
|
||||
|
@ -19,9 +19,8 @@
|
||||
|
||||
package com.sk89q.worldedit.extension.factory.parser.mask;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.RegionMask;
|
||||
@ -32,17 +31,19 @@ import java.util.List;
|
||||
|
||||
public class LazyRegionMaskParser extends SimpleInputParser<Mask> {
|
||||
|
||||
private final List<String> aliases = ImmutableList.of("#dregion", "#dselection", "#dsel");
|
||||
|
||||
public LazyRegionMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMatchedAliases() {
|
||||
return Lists.newArrayList("#dregion", "#dselection", "#dsel");
|
||||
return aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask parseFromSimpleInput(String input, ParserContext context) throws InputParseException {
|
||||
public Mask parseFromSimpleInput(String input, ParserContext context) {
|
||||
return new RegionMask(new RequestSelection());
|
||||
}
|
||||
}
|
||||
|
@ -26,12 +26,25 @@ import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.Masks;
|
||||
import com.sk89q.worldedit.internal.registry.InputParser;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class NegateMaskParser extends InputParser<Mask> {
|
||||
|
||||
public NegateMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String input) {
|
||||
if (input.isEmpty()) {
|
||||
return Stream.of("!");
|
||||
}
|
||||
if (input.charAt(0) != '!') {
|
||||
return Stream.empty();
|
||||
}
|
||||
return worldEdit.getMaskFactory().getSuggestions(input.substring(1)).stream().map(s -> "!" + s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||
if (!input.startsWith("!")) {
|
||||
|
@ -20,13 +20,14 @@
|
||||
package com.sk89q.worldedit.extension.factory.parser.mask;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.NoiseFilter;
|
||||
import com.sk89q.worldedit.internal.registry.InputParser;
|
||||
import com.sk89q.worldedit.math.noise.RandomNoise;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class NoiseMaskParser extends InputParser<Mask> {
|
||||
|
||||
public NoiseMaskParser(WorldEdit worldEdit) {
|
||||
@ -34,7 +35,18 @@ public class NoiseMaskParser extends InputParser<Mask> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||
public Stream<String> getSuggestions(String input) {
|
||||
if (input.isEmpty()) {
|
||||
return Stream.of("%");
|
||||
}
|
||||
if (input.charAt(0) != '%') {
|
||||
return Stream.empty();
|
||||
}
|
||||
return Stream.of("%10", "%25", "%50", "%75").filter(s -> s.startsWith(input));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask parseFromInput(String input, ParserContext context) {
|
||||
if (!input.startsWith("%")) {
|
||||
return null;
|
||||
}
|
||||
|
@ -31,12 +31,26 @@ import com.sk89q.worldedit.internal.registry.InputParser;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.session.request.RequestExtent;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class OffsetMaskParser extends InputParser<Mask> {
|
||||
|
||||
public OffsetMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String input) {
|
||||
if (input.isEmpty()) {
|
||||
return Stream.of(">", "<");
|
||||
}
|
||||
final char firstChar = input.charAt(0);
|
||||
if (firstChar != '>' && firstChar != '<') {
|
||||
return Stream.empty();
|
||||
}
|
||||
return worldEdit.getMaskFactory().getSuggestions(input.substring(1)).stream().map(s -> firstChar + s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||
final char firstChar = input.charAt(0);
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.extension.factory.parser.mask;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.worldedit.IncompleteRegionException;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
@ -32,13 +32,15 @@ import java.util.List;
|
||||
|
||||
public class RegionMaskParser extends SimpleInputParser<Mask> {
|
||||
|
||||
private final List<String> aliases = ImmutableList.of("#region", "#selection", "#sel");
|
||||
|
||||
public RegionMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMatchedAliases() {
|
||||
return Lists.newArrayList("#region", "#selection", "#sel");
|
||||
return aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.extension.factory.parser.mask;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
@ -31,13 +31,15 @@ import java.util.List;
|
||||
|
||||
public class SolidMaskParser extends SimpleInputParser<Mask> {
|
||||
|
||||
private final List<String> aliases = ImmutableList.of("#solid");
|
||||
|
||||
public SolidMaskParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getMatchedAliases() {
|
||||
return Lists.newArrayList("#solid");
|
||||
return aliases;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -20,6 +20,7 @@
|
||||
package com.sk89q.worldedit.extension.factory.parser.pattern;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.util.SuggestionHelper;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.pattern.BlockPattern;
|
||||
@ -41,7 +42,7 @@ public class BlockCategoryPatternParser extends InputParser<Pattern> {
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String input) {
|
||||
return BlockCategory.REGISTRY.keySet().stream().map(str -> "##" + str);
|
||||
return SuggestionHelper.getBlockCategorySuggestions(input, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -31,6 +31,7 @@ import com.sk89q.worldedit.internal.registry.InputParser;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ClipboardPatternParser extends InputParser<Pattern> {
|
||||
@ -41,7 +42,27 @@ public class ClipboardPatternParser extends InputParser<Pattern> {
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String input) {
|
||||
return Stream.of("#clipboard", "#copy");
|
||||
if (input.isEmpty()) {
|
||||
return Stream.of("#clipoard");
|
||||
}
|
||||
String[] offsetParts = input.split("@", 2);
|
||||
String firstLower = offsetParts[0].toLowerCase(Locale.ROOT);
|
||||
final boolean isClip = "#clipboard".startsWith(firstLower);
|
||||
final boolean isCopy = "#copy".startsWith(firstLower);
|
||||
if (isClip || isCopy) {
|
||||
if (offsetParts.length == 2) {
|
||||
String coords = offsetParts[1];
|
||||
if (coords.isEmpty()) {
|
||||
return Stream.of(input + "[x,y,z]");
|
||||
}
|
||||
} else {
|
||||
if (isClip) {
|
||||
return Stream.of("#clipboard", "#clipboard@[x,y,z]");
|
||||
}
|
||||
return Stream.of("#copy", "#copy@[x,y,z]");
|
||||
}
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -28,6 +28,7 @@ import com.sk89q.worldedit.function.pattern.RandomPattern;
|
||||
import com.sk89q.worldedit.internal.registry.InputParser;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class RandomPatternParser extends InputParser<Pattern> {
|
||||
|
||||
@ -35,12 +36,35 @@ public class RandomPatternParser extends InputParser<Pattern> {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String input) {
|
||||
String[] splits = input.split(",", -1);
|
||||
List<String> patterns = StringUtil.parseListInQuotes(splits, ',', '[', ']', true);
|
||||
if (patterns.size() == 1) {
|
||||
return Stream.empty();
|
||||
}
|
||||
// get suggestions for the last token only
|
||||
String token = patterns.get(patterns.size() - 1);
|
||||
String previous = String.join(",", patterns.subList(0, patterns.size() - 1));
|
||||
if (token.matches("[0-9]+(\\.[0-9]*)?%.*")) {
|
||||
String[] p = token.split("%");
|
||||
|
||||
if (p.length < 2) {
|
||||
return Stream.empty();
|
||||
} else {
|
||||
token = p[1];
|
||||
}
|
||||
}
|
||||
final List<String> innerSuggestions = worldEdit.getPatternFactory().getSuggestions(token);
|
||||
return innerSuggestions.stream().map(s -> previous + "," + s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||
RandomPattern randomPattern = new RandomPattern();
|
||||
|
||||
String[] splits = input.split(",");
|
||||
List<String> patterns = StringUtil.parseListInQuotes(splits, ',', '[', ']');
|
||||
String[] splits = input.split(",", -1);
|
||||
List<String> patterns = StringUtil.parseListInQuotes(splits, ',', '[', ']', true);
|
||||
if (patterns.size() == 1) {
|
||||
return null; // let a 'single'-pattern parser handle it
|
||||
}
|
||||
|
@ -29,11 +29,25 @@ import com.sk89q.worldedit.internal.registry.InputParser;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.FuzzyBlockState;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class RandomStatePatternParser extends InputParser<Pattern> {
|
||||
public RandomStatePatternParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String input) {
|
||||
if (input.isEmpty()) {
|
||||
return Stream.of("*");
|
||||
}
|
||||
if (!input.startsWith("*")) {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
return worldEdit.getBlockFactory().getSuggestions(input.substring(1)).stream().map(s -> "*" + s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||
if (!input.startsWith("*")) {
|
||||
|
@ -25,7 +25,6 @@ import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.function.pattern.BlockPattern;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.internal.registry.InputParser;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
@ -20,9 +20,8 @@
|
||||
package com.sk89q.worldedit.extension.factory.parser.pattern;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.command.util.SuggestionHelper;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
@ -32,10 +31,9 @@ import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.function.pattern.StateApplyingPattern;
|
||||
import com.sk89q.worldedit.function.pattern.TypeApplyingPattern;
|
||||
import com.sk89q.worldedit.internal.registry.InputParser;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
||||
public class TypeOrStateApplyingPatternParser extends InputParser<Pattern> {
|
||||
@ -44,6 +42,30 @@ public class TypeOrStateApplyingPatternParser extends InputParser<Pattern> {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String input) {
|
||||
if (input.isEmpty()) {
|
||||
return Stream.of("^");
|
||||
}
|
||||
if (!input.startsWith("^")) {
|
||||
return Stream.empty();
|
||||
}
|
||||
input = input.substring(1);
|
||||
|
||||
String[] parts = input.split("\\[", 2);
|
||||
String type = parts[0];
|
||||
|
||||
if (parts.length == 1) {
|
||||
return worldEdit.getBlockFactory().getSuggestions(input).stream().map(s -> "^" + s);
|
||||
} else {
|
||||
if (type.isEmpty()) {
|
||||
return Stream.empty(); // without knowing a type, we can't really suggest states
|
||||
} else {
|
||||
return SuggestionHelper.getBlockPropertySuggestions(type, parts[1]).map(s -> "^" + s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||
if (!input.startsWith("^")) {
|
||||
|
@ -20,7 +20,6 @@
|
||||
package com.sk89q.worldedit.internal.registry;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.enginehub.piston.converter.SuggestionHelper.limitByPrefix;
|
||||
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
@ -28,11 +27,9 @@ import com.sk89q.worldedit.extension.input.NoMatchException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* An abstract implementation of a factory for internal usage.
|
||||
@ -81,7 +78,9 @@ public abstract class AbstractFactory<E> {
|
||||
}
|
||||
|
||||
public List<String> getSuggestions(String input) {
|
||||
return limitByPrefix(parsers.stream().flatMap(parser -> parser.getSuggestions(input)), input);
|
||||
return parsers.stream().flatMap(
|
||||
p -> p.getSuggestions(input)
|
||||
).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -23,8 +23,6 @@ import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
@ -37,7 +35,7 @@ public abstract class InputParser<E> {
|
||||
|
||||
protected final WorldEdit worldEdit;
|
||||
|
||||
public InputParser(WorldEdit worldEdit) {
|
||||
protected InputParser(WorldEdit worldEdit) {
|
||||
this.worldEdit = worldEdit;
|
||||
}
|
||||
|
||||
|
@ -19,12 +19,12 @@
|
||||
|
||||
package com.sk89q.worldedit.internal.registry;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
@ -34,7 +34,7 @@ import java.util.stream.Stream;
|
||||
*/
|
||||
public abstract class SimpleInputParser<E> extends InputParser<E> {
|
||||
|
||||
public SimpleInputParser(WorldEdit worldEdit) {
|
||||
protected SimpleInputParser(WorldEdit worldEdit) {
|
||||
super(worldEdit);
|
||||
}
|
||||
|
||||
@ -67,6 +67,15 @@ public abstract class SimpleInputParser<E> extends InputParser<E> {
|
||||
|
||||
@Override
|
||||
public Stream<String> getSuggestions(String input) {
|
||||
if (input.isEmpty()) {
|
||||
return Stream.of(getPrimaryMatcher());
|
||||
}
|
||||
final String prefix = input.toLowerCase(Locale.ROOT);
|
||||
for (String alias : getMatchedAliases()) {
|
||||
if (alias.startsWith(prefix)) {
|
||||
return Stream.of(alias);
|
||||
}
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
}
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren