Re-implement richer mask and transform parsing (#1223)

Co-authored-by: dordsor21 <dordsor21@gmail.com>
Co-authored-by: Hannes Greule <SirYwell@users.noreply.github.com>
This commit is contained in:
dordsor21
2021-08-16 10:03:06 +01:00
committed by GitHub
parent 50137b31c4
commit d4d98708f9
109 changed files with 4068 additions and 2414 deletions

View File

@ -20,6 +20,7 @@
package com.sk89q.worldedit;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.google.common.base.Throwables;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
@ -37,6 +38,7 @@ import com.sk89q.worldedit.extension.factory.BlockFactory;
import com.sk89q.worldedit.extension.factory.ItemFactory;
import com.sk89q.worldedit.extension.factory.MaskFactory;
import com.sk89q.worldedit.extension.factory.PatternFactory;
import com.fastasyncworldedit.core.extension.factory.TransformFactory;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.Platform;
@ -138,6 +140,7 @@ public final class WorldEdit {
private final ItemFactory itemFactory = new ItemFactory(this);
private final MaskFactory maskFactory = new MaskFactory(this);
private final PatternFactory patternFactory = new PatternFactory(this);
private final TransformFactory transformFactory = new TransformFactory(this);
static {
getVersion();
@ -240,6 +243,16 @@ public final class WorldEdit {
return patternFactory;
}
/**
* Get the transform factory from which new {@link ResettableExtent}s
* can be constructed.
*
* @return the transform factory
*/
public TransformFactory getTransformFactory() {
return transformFactory;
}
/**
* Return the session manager.
*

View File

@ -86,6 +86,18 @@ import static com.google.common.base.Preconditions.checkNotNull;
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
public class GeneralCommands {
private final WorldEdit worldEdit;
/**
* Create a new instance.
*
* @param worldEdit reference to WorldEdit
*/
public GeneralCommands(WorldEdit worldEdit) {
checkNotNull(worldEdit);
this.worldEdit = worldEdit;
}
public static void register(
CommandRegistrationHandler registration,
CommandManager commandManager,
@ -149,18 +161,6 @@ public class GeneralCommands {
return CommandUtil.createNewCommandReplacementText("//perf " + flipped);
}
private final WorldEdit worldEdit;
/**
* Create a new instance.
*
* @param worldEdit reference to WorldEdit
*/
public GeneralCommands(WorldEdit worldEdit) {
checkNotNull(worldEdit);
this.worldEdit = worldEdit;
}
@Command(
name = "/limit",
desc = "Modify block change limit"
@ -451,50 +451,6 @@ public class GeneralCommands {
);
}
private static class ItemSearcher implements Callable<Component> {
private final boolean blocksOnly;
private final boolean itemsOnly;
private final String search;
private final int page;
ItemSearcher(String search, boolean blocksOnly, boolean itemsOnly, int page) {
this.blocksOnly = blocksOnly;
this.itemsOnly = itemsOnly;
this.search = search;
this.page = page;
}
@Override
public Component call() throws Exception {
String command = "/searchitem " + (blocksOnly ? "-b " : "") + (itemsOnly ? "-i " : "") + "-p %page% " + search;
Map<String, Component> results = new TreeMap<>();
String idMatch = search.replace(' ', '_');
String nameMatch = search.toLowerCase(Locale.ROOT);
for (ItemType searchType : ItemType.REGISTRY) {
if (blocksOnly && !searchType.hasBlockType()) {
continue;
}
if (itemsOnly && searchType.hasBlockType()) {
continue;
}
final String id = searchType.getId();
if (id.contains(idMatch)) {
Component name = searchType.getRichName();
results.put(id, TextComponent.builder()
.append(name)
.append(" (" + id + ")")
.build());
}
}
List<Component> list = new ArrayList<>(results.values());
return PaginationBox.fromComponents("Search results for '" + search + "'", command, list)
.create(page);
}
}
//FAWE start
@Command(
name = "/gtexture",
@ -592,15 +548,18 @@ public class GeneralCommands {
}
}
@Command(
name = "/gtransform",
aliases = {"gtransform"},
desc = "Set the global transform"
)
@CommandPermissions({"worldedit.global-transform", "worldedit.transform.global"})
public void gtransform(Player player, EditSession editSession, LocalSession session, ResettableExtent transform) throws
WorldEditException {
public void gtransform(
Player player,
EditSession editSession,
LocalSession session,
@Arg(desc = "The transform to set", def = "") ResettableExtent transform
) throws WorldEditException {
session.setTransform(transform);
if (transform == null) {
player.print(Caption.of("fawe.worldedit.general.transform.disabled"));
@ -648,5 +607,49 @@ public class GeneralCommands {
actor.print(Caption.of("worldedit.fast.enabled"));
}
}
private static class ItemSearcher implements Callable<Component> {
private final boolean blocksOnly;
private final boolean itemsOnly;
private final String search;
private final int page;
ItemSearcher(String search, boolean blocksOnly, boolean itemsOnly, int page) {
this.blocksOnly = blocksOnly;
this.itemsOnly = itemsOnly;
this.search = search;
this.page = page;
}
@Override
public Component call() throws Exception {
String command = "/searchitem " + (blocksOnly ? "-b " : "") + (itemsOnly ? "-i " : "") + "-p %page% " + search;
Map<String, Component> results = new TreeMap<>();
String idMatch = search.replace(' ', '_');
String nameMatch = search.toLowerCase(Locale.ROOT);
for (ItemType searchType : ItemType.REGISTRY) {
if (blocksOnly && !searchType.hasBlockType()) {
continue;
}
if (itemsOnly && searchType.hasBlockType()) {
continue;
}
final String id = searchType.getId();
if (id.contains(idMatch)) {
Component name = searchType.getRichName();
results.put(id, TextComponent.builder()
.append(name)
.append(" (" + id + ")")
.build());
}
}
List<Component> list = new ArrayList<>(results.values());
return PaginationBox.fromComponents("Search results for '" + search + "'", command, list)
.create(page);
}
}
//FAWE end
}

View File

@ -23,6 +23,7 @@ import com.fastasyncworldedit.core.command.tool.TargetMode;
import com.fastasyncworldedit.core.command.tool.brush.BrushSettings;
import com.fastasyncworldedit.core.command.tool.scroll.Scroll;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.fastasyncworldedit.core.util.MathMan;
import com.fastasyncworldedit.core.util.StringMan;
import com.google.common.collect.Iterables;
@ -360,33 +361,33 @@ public class ToolUtilCommands {
player.print(Caption.of("fawe.worldedit.brush.brush.source.mask"));
}
// TODO: Ping @MattBDev to reimplement 2020-02-04
// @Command(
// name = "transform",
// desc = "Set the brush transform"
// )
// @CommandPermissions({"worldedit.brush.options.transform", "worldedit.transform.brush"})
// public void transform(Player player, LocalSession session, EditSession editSession,
// @Arg(desc = "The transform", def = "") ResettableExtent transform,
// @Switch(name = 'h', desc = "Whether the offhand should be considered or not")
// boolean offHand,
// Arguments arguments) throws WorldEditException {
// BrushTool tool = session.getBrushTool(player, false);
// if (tool == null) {
// player.print(TranslatableComponent.of("fawe.worldedit.brush.brush.none"));
// return;
// }
// if (transform == null) {
// player.print(TranslatableComponent.of("fawe.worldedit.brush.brush.transform.disabled"));
// tool.setTransform(null);
// return;
// }
// BrushSettings settings = offHand ? tool.getOffHand() : tool.getContext();
// String lastArg = Iterables.getLast(CommandArgParser.spaceSplit(arguments.get())).getSubstring();
// settings.addSetting(BrushSettings.SettingType.TRANSFORM, lastArg);
// settings.setTransform(transform);
// tool.update();
// player.print(TranslatableComponent.of("fawe.worldedit.brush.brush.transform"));
// }
@Command(
name = "transform",
aliases = {"/transform"},
desc = "Set the brush transform"
)
@CommandPermissions({"worldedit.brush.options.transform", "worldedit.transform.brush"})
public void transform(Player player, LocalSession session, EditSession editSession,
@Arg(desc = "The transform", def = "") ResettableExtent transform,
@Switch(name = 'h', desc = "Whether the offhand should be considered or not")
boolean offHand,
Arguments arguments) throws WorldEditException {
BrushTool tool = session.getBrushTool(player, false);
if (tool == null) {
player.print(Caption.of("fawe.worldedit.brush.brush.none"));
return;
}
if (transform == null) {
player.print(Caption.of("fawe.worldedit.brush.brush.transform.disabled"));
tool.setTransform(null);
return;
}
BrushSettings settings = offHand ? tool.getOffHand() : tool.getContext();
String lastArg = Iterables.getLast(CommandArgParser.spaceSplit(arguments.get())).getSubstring();
settings.addSetting(BrushSettings.SettingType.TRANSFORM, lastArg);
settings.setTransform(transform);
tool.update();
player.print(Caption.of("fawe.worldedit.brush.brush.transform"));
}
//FAWE end
}

View File

@ -19,6 +19,7 @@
package com.sk89q.worldedit.command.argument;
import com.fastasyncworldedit.core.extent.ResettableExtent;
import com.fastasyncworldedit.core.extent.SupplyingExtent;
import com.sk89q.worldedit.EmptyClipboardException;
import com.sk89q.worldedit.LocalSession;
@ -54,6 +55,23 @@ import java.util.function.Function;
public class FactoryConverter<T> implements ArgumentConverter<T> {
private final WorldEdit worldEdit;
private final Function<WorldEdit, AbstractFactory<T>> factoryExtractor;
private final String description;
@Nullable
private final Consumer<ParserContext> contextTweaker;
private FactoryConverter(
WorldEdit worldEdit,
Function<WorldEdit, AbstractFactory<T>> factoryExtractor,
String description,
@Nullable Consumer<ParserContext> contextTweaker
) {
this.worldEdit = worldEdit;
this.factoryExtractor = factoryExtractor;
this.description = description;
this.contextTweaker = contextTweaker;
}
public static void register(WorldEdit worldEdit, CommandManager commandManager) {
commandManager.registerConverter(
Key.of(Pattern.class),
@ -67,6 +85,10 @@ public class FactoryConverter<T> implements ArgumentConverter<T> {
Key.of(BaseItem.class),
new FactoryConverter<>(worldEdit, WorldEdit::getItemFactory, "item", null)
);
commandManager.registerConverter(
Key.of(ResettableExtent.class),
new FactoryConverter<>(worldEdit, WorldEdit::getTransformFactory, "transform", null)
);
commandManager.registerConverter(
Key.of(Mask.class, ClipboardMask.class),
@ -90,24 +112,6 @@ public class FactoryConverter<T> implements ArgumentConverter<T> {
);
}
private final WorldEdit worldEdit;
private final Function<WorldEdit, AbstractFactory<T>> factoryExtractor;
private final String description;
@Nullable
private final Consumer<ParserContext> contextTweaker;
private FactoryConverter(
WorldEdit worldEdit,
Function<WorldEdit, AbstractFactory<T>> factoryExtractor,
String description,
@Nullable Consumer<ParserContext> contextTweaker
) {
this.worldEdit = worldEdit;
this.factoryExtractor = factoryExtractor;
this.description = description;
this.contextTweaker = contextTweaker;
}
@Override
public ConversionResult<T> convert(String argument, InjectedValueAccess context) {
Actor actor = context.injectedValue(Key.of(Actor.class))

View File

@ -234,6 +234,27 @@ public final class SuggestionHelper {
return Stream.empty();
}
//FAWE start
/**
* Returns a stream of suggestions for booleans.
*
* @param argumentInput the given input to filter with.
* @return a stream of suggestions.
*/
public static Stream<String> suggestBoolean(String argumentInput) {
if (argumentInput.isEmpty()) {
return Stream.of("true", "false");
}
if ("true".startsWith(argumentInput)) {
return Stream.of("true");
} else if ("false".startsWith(argumentInput)) {
return Stream.of("false");
}
// no valid input anymore
return Stream.empty();
}
//FAWE end
private static boolean isDouble(String input) {
boolean point = false;
for (char c : input.toCharArray()) {

View File

@ -22,6 +22,7 @@ package com.sk89q.worldedit.extension.factory;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.mask.AdjacentMaskParser;
import com.fastasyncworldedit.core.extension.factory.parser.mask.AngleMaskParser;
import com.fastasyncworldedit.core.extension.factory.parser.mask.RichMaskParser;
import com.fastasyncworldedit.core.extension.factory.parser.mask.ExtremaMaskParser;
import com.fastasyncworldedit.core.extension.factory.parser.mask.FalseMaskParser;
import com.fastasyncworldedit.core.extension.factory.parser.mask.LiquidMaskParser;
@ -71,6 +72,10 @@ import java.util.stream.Collectors;
*/
public final class MaskFactory extends AbstractFactory<Mask> {
//FAWE start - rich mask parsing
private final RichMaskParser richMaskParser;
//FAWE end
/**
* Create a new mask registry.
*
@ -79,6 +84,10 @@ public final class MaskFactory extends AbstractFactory<Mask> {
public MaskFactory(WorldEdit worldEdit) {
super(worldEdit, new BlocksMaskParser(worldEdit));
//FAWE start - rich mask parsing
richMaskParser = new RichMaskParser(worldEdit);
//FAWE end
register(new ExistingMaskParser(worldEdit));
register(new AirMaskParser(worldEdit));
register(new SolidMaskParser(worldEdit));
@ -133,20 +142,63 @@ public final class MaskFactory extends AbstractFactory<Mask> {
continue;
}
Mask match = null;
for (InputParser<Mask> parser : getParsers()) {
match = parser.parseFromInput(component, context);
if (match != null) {
break;
}
//FAWE start - rich mask parsing
Mask match = richMaskParser.parseFromInput(component, context);
if (match != null) {
masks.add(match);
continue;
}
if (match == null) {
throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(component)));
}
masks.add(match);
parseFromParsers(context, masks, component);
//FAWE end
}
return getMask(input, masks);
}
//FAWE start - rich mask parsing
private void parseFromParsers(
final ParserContext context,
final List<Mask> masks,
final String component
) {
Mask match = null;
for (InputParser<Mask> parser : getParsers()) {
match = parser.parseFromInput(component, context);
if (match != null) {
break;
}
}
if (match == null) {
throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(component)));
}
masks.add(match);
}
/**
* Parses a mask without considering parsing through the {@link RichMaskParser}, therefore not accepting
* "richer" parsing where & and , are used. Exists to prevent stack overflows.
*
* @param input input string
* @param context input context
* @return parsed result
* @throws InputParseException if no result found
*/
public Mask parseWithoutRich(String input, ParserContext context) throws InputParseException {
List<Mask> masks = new ArrayList<>();
for (String component : input.split(" ")) {
if (component.isEmpty()) {
continue;
}
parseFromParsers(context, masks, component);
}
return getMask(input, masks);
}
private Mask getMask(final String input, final List<Mask> masks) {
switch (masks.size()) {
case 0:
throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input)));
@ -156,5 +208,6 @@ public final class MaskFactory extends AbstractFactory<Mask> {
return new MaskIntersection(masks).optimize();
}
}
//FAWE end
}

View File

@ -19,24 +19,56 @@
package com.sk89q.worldedit.extension.factory;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.AngleColorPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.AverageColorPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.BiomePatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.BufferedPattern2DParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.BufferedPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.ColorPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.DarkenPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.DesaturatePatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.ExistingPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.ExpressionPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.LightenPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.Linear2DPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.Linear3DPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.LinearPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.MaskedPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.NoXPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.NoYPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.NoZPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.OffsetPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.PerlinPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.RandomFullClipboardPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.RandomOffsetPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.RandomPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.RelativePatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.RichPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.RidgedMultiFractalPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.SaturatePatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.SimplexPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.SolidRandomOffsetPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.SurfaceRandomOffsetPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.VoronoiPatternParser;
import com.fastasyncworldedit.core.math.random.TrueRandom;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.factory.parser.pattern.BlockCategoryPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.ClipboardPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.RandomStatePatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.SingleBlockPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.TypeOrStateApplyingPatternParser;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.NoMatchException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.RandomPattern;
import com.sk89q.worldedit.internal.registry.AbstractFactory;
import com.sk89q.worldedit.internal.registry.InputParser;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import java.util.ArrayList;
import java.util.List;
/**
* A registry of known {@link Pattern}s. Provides methods to instantiate
@ -47,6 +79,10 @@ import com.sk89q.worldedit.internal.registry.AbstractFactory;
*/
public final class PatternFactory extends AbstractFactory<Pattern> {
//FAWE start - rich pattern parsing
private final RichPatternParser richPatternParser;
//FAWE end
/**
* Create a new instance.
*
@ -55,6 +91,10 @@ public final class PatternFactory extends AbstractFactory<Pattern> {
public PatternFactory(WorldEdit worldEdit) {
super(worldEdit, new SingleBlockPatternParser(worldEdit));
//FAWE start - rich pattern parsing
richPatternParser = new RichPatternParser(worldEdit);
//FAWE end
// split and parse each sub-pattern
register(new RandomPatternParser(worldEdit));
@ -65,16 +105,117 @@ public final class PatternFactory extends AbstractFactory<Pattern> {
register(new BlockCategoryPatternParser(worldEdit));
//FAWE start
register(new SimplexPatternParser(worldEdit));
register(new VoronoiPatternParser(worldEdit));
register(new PerlinPatternParser(worldEdit));
register(new RidgedMultiFractalPatternParser(worldEdit));
register(new AngleColorPatternParser(worldEdit));
register(new AverageColorPatternParser(worldEdit));
register(new BiomePatternParser(worldEdit));
register(new BufferedPatternParser(worldEdit));
register(new BufferedPattern2DParser(worldEdit));
register(new ColorPatternParser(worldEdit));
register(new DarkenPatternParser(worldEdit));
register(new DesaturatePatternParser(worldEdit));
register(new ExistingPatternParser(worldEdit));
register(new ExpressionPatternParser(worldEdit));
register(new LightenPatternParser(worldEdit));
register(new Linear2DPatternParser(worldEdit));
register(new Linear3DPatternParser(worldEdit));
register(new BufferedPatternParser(worldEdit));
register(new ExistingPatternParser(worldEdit));
register(new LinearPatternParser(worldEdit));
register(new MaskedPatternParser(worldEdit));
register(new NoXPatternParser(worldEdit));
register(new NoYPatternParser(worldEdit));
register(new NoZPatternParser(worldEdit));
register(new OffsetPatternParser(worldEdit));
register(new PerlinPatternParser(worldEdit));
register(new RandomFullClipboardPatternParser(worldEdit));
register(new RandomOffsetPatternParser(worldEdit));
register(new RelativePatternParser(worldEdit));
register(new RidgedMultiFractalPatternParser(worldEdit));
register(new SaturatePatternParser(worldEdit));
register(new SimplexPatternParser(worldEdit));
register(new SolidRandomOffsetPatternParser(worldEdit));
register(new SurfaceRandomOffsetPatternParser(worldEdit));
register(new VoronoiPatternParser(worldEdit));
//FAWE end
}
@Override
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
List<Pattern> patterns = new ArrayList<>();
for (String component : input.split(" ")) {
if (component.isEmpty()) {
continue;
}
//FAWE start - rich pattern parsing
Pattern match = richPatternParser.parseFromInput(component, context);
if (match != null) {
patterns.add(match);
continue;
}
parseFromParsers(context, patterns, component);
//FAWE end
}
return getPattern(input, patterns);
}
//FAWE start - rich pattern parsing
private void parseFromParsers(
final ParserContext context,
final List<Pattern> patterns,
final String component
) {
Pattern match = null;
for (InputParser<Pattern> parser : getParsers()) {
match = parser.parseFromInput(component, context);
if (match != null) {
break;
}
}
if (match == null) {
throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(component)));
}
patterns.add(match);
}
/**
* Parses a pattern without considering parsing through the {@link RichPatternParser}, therefore not accepting
* "richer" parsing where & and , are used. Exists to prevent stack overflows.
*
* @param input input string
* @param context input context
* @return parsed result
* @throws InputParseException if no result found
*/
public Pattern parseWithoutRich(String input, ParserContext context) throws InputParseException {
List<Pattern> patterns = new ArrayList<>();
for (String component : input.split(" ")) {
if (component.isEmpty()) {
continue;
}
parseFromParsers(context, patterns, component);
}
return getPattern(input, patterns);
}
private Pattern getPattern(final String input, final List<Pattern> patterns) {
switch (patterns.size()) {
case 0:
throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input)));
case 1:
return patterns.get(0);
default:
RandomPattern randomPattern = new RandomPattern(new TrueRandom());
for (Pattern pattern : patterns) {
randomPattern.add(pattern, 1d);
}
return randomPattern;
}
}
//FAWE end
}

View File

@ -354,6 +354,7 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
throw new InputParseException(Caption.of("worldedit.error.incomplete-region"));
}
state = world.getBlock(primaryPosition);
nbt = state.getNbtData();
//FAWE start
} else if (typeString.matches("slot[0-9]+")) {
int slot = Integer.parseInt(typeString.substring(4)) - 1;
@ -384,9 +385,6 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
throw new NoMatchException(Caption.of("fawe.error.invalid-block-type", TextComponent.of(input)));
}
}
if (nbt == null) {
nbt = state.getNbtData();
}
//FAWE end
blockStates.putAll(parseProperties(state.getBlockType(), stateProperties, context));
@ -477,7 +475,17 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
return validate(context, new SkullBlock(state, type.replace(" ", "_"))); // valid MC usernames
} else {
return validate(context, state.toBaseBlock());
//FAWE start
nbt = state.getNbtData();
BaseBlock result;
if (nbt != null) {
WorldEdit.logger.info(blockStates.size());
result = blockStates.size() > 0 ? state.toBaseBlock(nbt) : new BlanketBaseBlock(state, nbt);
} else {
result = state.toBaseBlock();
}
return validate(context, result);
//FAWE end
}
}

View File

@ -20,6 +20,7 @@
package com.sk89q.worldedit.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.AliasedParser;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
import com.sk89q.worldedit.extension.input.InputParseException;
@ -31,11 +32,15 @@ import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.world.block.BlockCategory;
import com.sk89q.worldedit.world.block.BlockType;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Stream;
public class BlockCategoryPatternParser extends InputParser<Pattern> {
//FAWE start - aliased
public class BlockCategoryPatternParser extends InputParser<Pattern> implements AliasedParser {
//FAWE end
public BlockCategoryPatternParser(WorldEdit worldEdit) {
super(worldEdit);
@ -81,4 +86,11 @@ public class BlockCategoryPatternParser extends InputParser<Pattern> {
return randomPattern;
}
//FAWE start - aliased
@Override
public List<String> getMatchedAliases() {
return Collections.singletonList("##");
}
//FAWE end
}

View File

@ -19,6 +19,7 @@
package com.sk89q.worldedit.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.extension.factory.parser.AliasedParser;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.ParserContext;
@ -28,9 +29,13 @@ import com.sk89q.worldedit.internal.registry.InputParser;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.FuzzyBlockState;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;
public class RandomStatePatternParser extends InputParser<Pattern> {
//FAWE start - aliased
public class RandomStatePatternParser extends InputParser<Pattern> implements AliasedParser {
//FAWE end
public RandomStatePatternParser(WorldEdit worldEdit) {
super(worldEdit);
@ -68,4 +73,11 @@ public class RandomStatePatternParser extends InputParser<Pattern> {
}
}
//FAWE start - aliased
@Override
public List<String> getMatchedAliases() {
return Collections.singletonList("*");
}
//FAWE end
}

View File

@ -20,6 +20,7 @@
package com.sk89q.worldedit.extension.factory.parser.pattern;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.AliasedParser;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.SuggestionHelper;
import com.sk89q.worldedit.extension.input.InputParseException;
@ -33,12 +34,15 @@ import com.sk89q.worldedit.function.pattern.TypeApplyingPattern;
import com.sk89q.worldedit.internal.registry.InputParser;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
public class TypeOrStateApplyingPatternParser extends InputParser<Pattern> {
//FAWE start - aliased
public class TypeOrStateApplyingPatternParser extends InputParser<Pattern> implements AliasedParser {
//FAWE end
public TypeOrStateApplyingPatternParser(WorldEdit worldEdit) {
super(worldEdit);
@ -128,4 +132,11 @@ public class TypeOrStateApplyingPatternParser extends InputParser<Pattern> {
}
}
//FAWE start - aliased
@Override
public List<String> getMatchedAliases() {
return Collections.singletonList("^");
}
//FAWE end
}

View File

@ -839,8 +839,8 @@ public final class PlatformCommandManager {
}
//FAWE end
//FAWE start - Event & suggestions
private MemoizingValueAccess initializeInjectedValues(Arguments arguments, Actor actor, Event event, boolean isSuggestions) {
//FAWE start - Event & suggestions, make method public
public MemoizingValueAccess initializeInjectedValues(Arguments arguments, Actor actor, Event event, boolean isSuggestions) {
//FAWE end
InjectedValueStore store = MapBackedValueStore.create();
store.injectValue(Key.of(Actor.class), ValueProvider.constant(actor));

View File

@ -403,12 +403,34 @@ public interface Extent extends InputExtent, OutputExtent {
}
}
/**
* Returns true if the extent contains the given position
*
* @param pt position
* @return if position is contained
*/
default boolean contains(BlockVector3 pt) {
BlockVector3 min = getMinimumPoint();
BlockVector3 max = getMaximumPoint();
return pt.containedWithin(min, max);
}
/**
* Returns true if the extent contains the given position
*
* @param x position x
* @param y position y
* @param z position z
* @return if position is contained
*/
default boolean contains(int x, int y, int z) {
BlockVector3 min = getMinimumPoint();
BlockVector3 max = getMaximumPoint();
return min.getX() <= x && max.getX() >= x
&& min.getY() <= y && max.getY() >= y
&& min.getZ() <= z && max.getZ() >= z;
}
default void addOre(
Region region,
Mask mask,

View File

@ -20,6 +20,7 @@
package com.sk89q.worldedit.internal.registry;
import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.AliasedParser;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.NoMatchException;
@ -70,6 +71,17 @@ public abstract class AbstractFactory<E> {
return Collections.unmodifiableList(parsers);
}
//FAWE start - javadoc
/**
* Parse a string and context to each {@link InputParser} added to this factory. If no result found, throws {@link InputParseException}
*
* @param input input string
* @param context input context
* @return parsed result
* @throws InputParseException if no result found
*/
//FAWE end
public E parseFromInput(String input, ParserContext context) throws InputParseException {
E match;
@ -101,4 +113,19 @@ public abstract class AbstractFactory<E> {
parsers.add(parsers.size() - 1, inputParser);
}
/**
* Test all parsers to see if alias is contained by one of them
*
* @param alias alias to test
* @return if a parser contains the alias
*/
public boolean containsAlias(String alias) {
return parsers.stream().anyMatch(p -> {
if (!(p instanceof AliasedParser)) {
return false;
}
return ((AliasedParser) p).getMatchedAliases().contains(alias);
});
}
}

View File

@ -19,11 +19,11 @@
package com.sk89q.worldedit.internal.registry;
import com.fastasyncworldedit.core.extension.factory.parser.AliasedParser;
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;
@ -32,19 +32,14 @@ import java.util.stream.Stream;
*
* @param <E> the element
*/
public abstract class SimpleInputParser<E> extends InputParser<E> {
//FAWE start - AliasedParser interface, rather than method being here
public abstract class SimpleInputParser<E> extends InputParser<E> implements AliasedParser {
//FAWE end
protected SimpleInputParser(WorldEdit worldEdit) {
super(worldEdit);
}
/**
* The strings this parser matches.
*
* @return the matching aliases
*/
public abstract List<String> getMatchedAliases();
@Override
public E parseFromInput(String input, ParserContext context) throws InputParseException {
if (!getMatchedAliases().contains(input)) {