mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2024-12-22 17:27:38 +00:00
fix: allow use of quotes to allow spaces to be used as "and" (#2786)
* fix: allow use of quotes to allow spaces to be sued as "and" - e.g. `//set "#mask[grass_block&<air][green_concrete][red_concrete]"` - fixes #1883 * Remove static
This commit is contained in:
parent
4a5ff8e306
commit
8aba1e6c06
@ -21,22 +21,17 @@ import com.sk89q.worldedit.internal.registry.AbstractFactory;
|
|||||||
import com.sk89q.worldedit.internal.registry.InputParser;
|
import com.sk89q.worldedit.internal.registry.InputParser;
|
||||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class TransformFactory extends AbstractFactory<ResettableExtent> {
|
public class TransformFactory extends AbstractFactory<ResettableExtent> {
|
||||||
|
|
||||||
private final RichTransformParser richTransformParser;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new factory.
|
* Create a new factory.
|
||||||
*
|
*
|
||||||
* @param worldEdit the WorldEdit instance
|
* @param worldEdit the WorldEdit instance
|
||||||
*/
|
*/
|
||||||
public TransformFactory(WorldEdit worldEdit) {
|
public TransformFactory(WorldEdit worldEdit) {
|
||||||
super(worldEdit, new NullTransformParser(worldEdit));
|
super(worldEdit, new NullTransformParser(worldEdit), new RichTransformParser(worldEdit));
|
||||||
|
|
||||||
richTransformParser = new RichTransformParser(worldEdit);
|
|
||||||
|
|
||||||
// split and parse each sub-transform
|
// split and parse each sub-transform
|
||||||
register(new RandomTransformParser(worldEdit));
|
register(new RandomTransformParser(worldEdit));
|
||||||
@ -51,68 +46,7 @@ public class TransformFactory extends AbstractFactory<ResettableExtent> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResettableExtent parseFromInput(String input, ParserContext context) throws InputParseException {
|
protected ResettableExtent getParsed(final String input, final List<ResettableExtent> transforms) {
|
||||||
List<ResettableExtent> transforms = new ArrayList<>();
|
|
||||||
|
|
||||||
for (String component : input.split(" ")) {
|
|
||||||
if (component.isEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ResettableExtent match = richTransformParser.parseFromInput(component, context);
|
|
||||||
if (match != null) {
|
|
||||||
transforms.add(match);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
parseFromParsers(context, transforms, component);
|
|
||||||
}
|
|
||||||
|
|
||||||
return getResettableExtent(input, transforms);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void parseFromParsers(
|
|
||||||
final ParserContext context,
|
|
||||||
final List<ResettableExtent> transforms,
|
|
||||||
final String component
|
|
||||||
) {
|
|
||||||
ResettableExtent match = null;
|
|
||||||
for (InputParser<ResettableExtent> 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)));
|
|
||||||
}
|
|
||||||
transforms.add(match);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses a transform without considering parsing through the {@link RichTransformParser}, 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 ResettableExtent parseWithoutRich(String input, ParserContext context) throws InputParseException {
|
|
||||||
List<ResettableExtent> transforms = new ArrayList<>();
|
|
||||||
|
|
||||||
for (String component : input.split(" ")) {
|
|
||||||
if (component.isEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
parseFromParsers(context, transforms, component);
|
|
||||||
}
|
|
||||||
|
|
||||||
return getResettableExtent(input, transforms);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ResettableExtent getResettableExtent(final String input, final List<ResettableExtent> transforms) {
|
|
||||||
switch (transforms.size()) {
|
switch (transforms.size()) {
|
||||||
case 0:
|
case 0:
|
||||||
throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input)));
|
throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input)));
|
||||||
|
@ -37,14 +37,14 @@ public abstract class FaweParser<T> extends InputParser<T> implements AliasedPar
|
|||||||
for (int i = 0; i < toParse.length(); i++) {
|
for (int i = 0; i < toParse.length(); i++) {
|
||||||
char c = toParse.charAt(i);
|
char c = toParse.charAt(i);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case ',', '&' -> {
|
case ',', '&', ' ' -> {
|
||||||
if (expression) {
|
if (expression) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String result = toParse.substring(last, i);
|
String result = toParse.substring(last, i);
|
||||||
if (!result.isEmpty()) {
|
if (!result.isEmpty()) {
|
||||||
inputs.add(result);
|
inputs.add(result);
|
||||||
and.add(c == '&');
|
and.add(c == '&' || c == ' ');
|
||||||
} else {
|
} else {
|
||||||
throw new InputParseException(Caption.of("fawe.error.parse.invalid-dangling-character", c));
|
throw new InputParseException(Caption.of("fawe.error.parse.invalid-dangling-character", c));
|
||||||
}
|
}
|
||||||
|
@ -23,11 +23,16 @@ import com.sk89q.util.StringUtil;
|
|||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.extension.factory.parser.DefaultBlockParser;
|
import com.sk89q.worldedit.extension.factory.parser.DefaultBlockParser;
|
||||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
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.extension.input.ParserContext;
|
||||||
import com.sk89q.worldedit.internal.registry.AbstractFactory;
|
import com.sk89q.worldedit.internal.registry.AbstractFactory;
|
||||||
|
import com.sk89q.worldedit.internal.registry.InputParser;
|
||||||
|
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||||
|
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,4 +72,21 @@ public class BlockFactory extends AbstractFactory<BaseBlock> {
|
|||||||
return blocks;
|
return blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//FAWE start
|
||||||
|
@Override
|
||||||
|
public BaseBlock parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||||
|
BaseBlock match;
|
||||||
|
|
||||||
|
for (InputParser<BaseBlock> parser : parsers) {
|
||||||
|
match = parser.parseFromInput(input, context);
|
||||||
|
|
||||||
|
if (match != null) {
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new NoMatchException(TranslatableComponent.of("worldedit.error.no-match", TextComponent.of(input)));
|
||||||
|
}
|
||||||
|
//FAWE end
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,13 @@ package com.sk89q.worldedit.extension.factory;
|
|||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.blocks.BaseItem;
|
import com.sk89q.worldedit.blocks.BaseItem;
|
||||||
import com.sk89q.worldedit.extension.factory.parser.DefaultItemParser;
|
import com.sk89q.worldedit.extension.factory.parser.DefaultItemParser;
|
||||||
|
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.internal.registry.AbstractFactory;
|
import com.sk89q.worldedit.internal.registry.AbstractFactory;
|
||||||
|
import com.sk89q.worldedit.internal.registry.InputParser;
|
||||||
|
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||||
|
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
|
||||||
|
|
||||||
public class ItemFactory extends AbstractFactory<BaseItem> {
|
public class ItemFactory extends AbstractFactory<BaseItem> {
|
||||||
|
|
||||||
@ -35,4 +41,21 @@ public class ItemFactory extends AbstractFactory<BaseItem> {
|
|||||||
super(worldEdit, new DefaultItemParser(worldEdit));
|
super(worldEdit, new DefaultItemParser(worldEdit));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//FAWE start
|
||||||
|
@Override
|
||||||
|
public BaseItem parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||||
|
BaseItem match;
|
||||||
|
|
||||||
|
for (InputParser<BaseItem> parser : parsers) {
|
||||||
|
match = parser.parseFromInput(input, context);
|
||||||
|
|
||||||
|
if (match != null) {
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new NoMatchException(TranslatableComponent.of("worldedit.error.no-match", TextComponent.of(input)));
|
||||||
|
}
|
||||||
|
//FAWE end
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -53,16 +53,13 @@ import com.sk89q.worldedit.extension.factory.parser.mask.NoiseMaskParser;
|
|||||||
import com.sk89q.worldedit.extension.factory.parser.mask.OffsetMaskParser;
|
import com.sk89q.worldedit.extension.factory.parser.mask.OffsetMaskParser;
|
||||||
import com.sk89q.worldedit.extension.factory.parser.mask.RegionMaskParser;
|
import com.sk89q.worldedit.extension.factory.parser.mask.RegionMaskParser;
|
||||||
import com.sk89q.worldedit.extension.factory.parser.mask.SolidMaskParser;
|
import com.sk89q.worldedit.extension.factory.parser.mask.SolidMaskParser;
|
||||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
|
||||||
import com.sk89q.worldedit.extension.input.NoMatchException;
|
import com.sk89q.worldedit.extension.input.NoMatchException;
|
||||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import com.sk89q.worldedit.function.mask.MaskIntersection;
|
import com.sk89q.worldedit.function.mask.MaskIntersection;
|
||||||
import com.sk89q.worldedit.internal.registry.AbstractFactory;
|
import com.sk89q.worldedit.internal.registry.AbstractFactory;
|
||||||
import com.sk89q.worldedit.internal.registry.InputParser;
|
|
||||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -75,21 +72,13 @@ import java.util.stream.Collectors;
|
|||||||
*/
|
*/
|
||||||
public final class MaskFactory extends AbstractFactory<Mask> {
|
public final class MaskFactory extends AbstractFactory<Mask> {
|
||||||
|
|
||||||
//FAWE start - rich mask parsing
|
|
||||||
private final RichMaskParser richMaskParser;
|
|
||||||
//FAWE end
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new mask registry.
|
* Create a new mask registry.
|
||||||
*
|
*
|
||||||
* @param worldEdit the WorldEdit instance
|
* @param worldEdit the WorldEdit instance
|
||||||
*/
|
*/
|
||||||
public MaskFactory(WorldEdit worldEdit) {
|
public MaskFactory(WorldEdit worldEdit) {
|
||||||
super(worldEdit, new BlocksMaskParser(worldEdit));
|
super(worldEdit, new BlocksMaskParser(worldEdit), new RichMaskParser(worldEdit));
|
||||||
|
|
||||||
//FAWE start - rich mask parsing
|
|
||||||
richMaskParser = new RichMaskParser(worldEdit);
|
|
||||||
//FAWE end
|
|
||||||
|
|
||||||
register(new ExistingMaskParser(worldEdit));
|
register(new ExistingMaskParser(worldEdit));
|
||||||
register(new AirMaskParser(worldEdit));
|
register(new AirMaskParser(worldEdit));
|
||||||
@ -125,7 +114,6 @@ public final class MaskFactory extends AbstractFactory<Mask> {
|
|||||||
register(new ZAxisMaskParser(worldEdit));
|
register(new ZAxisMaskParser(worldEdit));
|
||||||
register(new SurfaceAngleMaskParser(worldEdit));
|
register(new SurfaceAngleMaskParser(worldEdit));
|
||||||
//FAWE end
|
//FAWE end
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -133,85 +121,24 @@ public final class MaskFactory extends AbstractFactory<Mask> {
|
|||||||
final String[] split = input.split(" ");
|
final String[] split = input.split(" ");
|
||||||
if (split.length > 1) {
|
if (split.length > 1) {
|
||||||
String prev = input.substring(0, input.lastIndexOf(" ")) + " ";
|
String prev = input.substring(0, input.lastIndexOf(" ")) + " ";
|
||||||
return super.getSuggestions(split[split.length - 1], parserContext).stream().map(s -> prev + s).collect(Collectors.toList());
|
return super
|
||||||
|
.getSuggestions(split[split.length - 1], parserContext)
|
||||||
|
.stream()
|
||||||
|
.map(s -> prev + s)
|
||||||
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
return super.getSuggestions(input, parserContext);
|
return super.getSuggestions(input, parserContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//FAWE start - rich mask parsing
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mask parseFromInput(String input, ParserContext context) throws InputParseException {
|
protected Mask getParsed(final String input, final List<Mask> masks) {
|
||||||
List<Mask> masks = new ArrayList<>();
|
return switch (masks.size()) {
|
||||||
|
case 0 -> throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input)));
|
||||||
for (String component : input.split(" ")) {
|
case 1 -> masks.get(0).optimize();
|
||||||
if (component.isEmpty()) {
|
default -> new MaskIntersection(masks).optimize();
|
||||||
continue;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
//FAWE start - rich mask parsing
|
|
||||||
Mask match = richMaskParser.parseFromInput(component, context);
|
|
||||||
if (match != null) {
|
|
||||||
masks.add(match);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
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)));
|
|
||||||
case 1:
|
|
||||||
return masks.get(0).optimize();
|
|
||||||
default:
|
|
||||||
return new MaskIntersection(masks).optimize();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//FAWE end
|
//FAWE end
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
package com.sk89q.worldedit.extension.factory;
|
package com.sk89q.worldedit.extension.factory;
|
||||||
|
|
||||||
import com.fastasyncworldedit.core.configuration.Caption;
|
import com.fastasyncworldedit.core.configuration.Caption;
|
||||||
import com.fastasyncworldedit.core.extension.factory.parser.mask.HotbarMaskParser;
|
|
||||||
import com.fastasyncworldedit.core.extension.factory.parser.pattern.AngleColorPatternParser;
|
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.AverageColorPatternParser;
|
||||||
import com.fastasyncworldedit.core.extension.factory.parser.pattern.BiomePatternParser;
|
import com.fastasyncworldedit.core.extension.factory.parser.pattern.BiomePatternParser;
|
||||||
@ -44,8 +43,6 @@ import com.fastasyncworldedit.core.extension.factory.parser.pattern.OffsetPatter
|
|||||||
import com.fastasyncworldedit.core.extension.factory.parser.pattern.PerlinPatternParser;
|
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.RandomFullClipboardPatternParser;
|
||||||
import com.fastasyncworldedit.core.extension.factory.parser.pattern.RandomOffsetPatternParser;
|
import com.fastasyncworldedit.core.extension.factory.parser.pattern.RandomOffsetPatternParser;
|
||||||
import com.fastasyncworldedit.core.extension.factory.parser.pattern.TypeSwapPatternParser;
|
|
||||||
import com.sk89q.worldedit.extension.factory.parser.pattern.RandomPatternParser;
|
|
||||||
import com.fastasyncworldedit.core.extension.factory.parser.pattern.RelativePatternParser;
|
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.RichPatternParser;
|
||||||
import com.fastasyncworldedit.core.extension.factory.parser.pattern.RidgedMultiFractalPatternParser;
|
import com.fastasyncworldedit.core.extension.factory.parser.pattern.RidgedMultiFractalPatternParser;
|
||||||
@ -53,24 +50,22 @@ import com.fastasyncworldedit.core.extension.factory.parser.pattern.SaturatePatt
|
|||||||
import com.fastasyncworldedit.core.extension.factory.parser.pattern.SimplexPatternParser;
|
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.SolidRandomOffsetPatternParser;
|
||||||
import com.fastasyncworldedit.core.extension.factory.parser.pattern.SurfaceRandomOffsetPatternParser;
|
import com.fastasyncworldedit.core.extension.factory.parser.pattern.SurfaceRandomOffsetPatternParser;
|
||||||
|
import com.fastasyncworldedit.core.extension.factory.parser.pattern.TypeSwapPatternParser;
|
||||||
import com.fastasyncworldedit.core.extension.factory.parser.pattern.VoronoiPatternParser;
|
import com.fastasyncworldedit.core.extension.factory.parser.pattern.VoronoiPatternParser;
|
||||||
import com.fastasyncworldedit.core.math.random.TrueRandom;
|
import com.fastasyncworldedit.core.math.random.TrueRandom;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.extension.factory.parser.pattern.BlockCategoryPatternParser;
|
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.ClipboardPatternParser;
|
||||||
|
import com.sk89q.worldedit.extension.factory.parser.pattern.RandomPatternParser;
|
||||||
import com.sk89q.worldedit.extension.factory.parser.pattern.RandomStatePatternParser;
|
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.SingleBlockPatternParser;
|
||||||
import com.sk89q.worldedit.extension.factory.parser.pattern.TypeOrStateApplyingPatternParser;
|
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.NoMatchException;
|
||||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.function.pattern.RandomPattern;
|
import com.sk89q.worldedit.function.pattern.RandomPattern;
|
||||||
import com.sk89q.worldedit.internal.registry.AbstractFactory;
|
import com.sk89q.worldedit.internal.registry.AbstractFactory;
|
||||||
import com.sk89q.worldedit.internal.registry.InputParser;
|
|
||||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,20 +77,14 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public final class PatternFactory extends AbstractFactory<Pattern> {
|
public final class PatternFactory extends AbstractFactory<Pattern> {
|
||||||
|
|
||||||
//FAWE start - rich pattern parsing
|
|
||||||
private final RichPatternParser richPatternParser;
|
|
||||||
//FAWE end
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance.
|
* Create a new instance.
|
||||||
*
|
*
|
||||||
* @param worldEdit the WorldEdit instance
|
* @param worldEdit the WorldEdit instance
|
||||||
*/
|
*/
|
||||||
public PatternFactory(WorldEdit worldEdit) {
|
public PatternFactory(WorldEdit worldEdit) {
|
||||||
super(worldEdit, new SingleBlockPatternParser(worldEdit));
|
|
||||||
|
|
||||||
//FAWE start - rich pattern parsing
|
//FAWE start - rich pattern parsing
|
||||||
richPatternParser = new RichPatternParser(worldEdit);
|
super(worldEdit, new SingleBlockPatternParser(worldEdit), new RichPatternParser(worldEdit));
|
||||||
//FAWE end
|
//FAWE end
|
||||||
|
|
||||||
// split and parse each sub-pattern
|
// split and parse each sub-pattern
|
||||||
@ -139,75 +128,10 @@ public final class PatternFactory extends AbstractFactory<Pattern> {
|
|||||||
register(new SurfaceRandomOffsetPatternParser(worldEdit));
|
register(new SurfaceRandomOffsetPatternParser(worldEdit));
|
||||||
register(new TypeSwapPatternParser(worldEdit));
|
register(new TypeSwapPatternParser(worldEdit));
|
||||||
register(new VoronoiPatternParser(worldEdit));
|
register(new VoronoiPatternParser(worldEdit));
|
||||||
//FAWE end
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException {
|
protected Pattern getParsed(final String input, final List<Pattern> patterns) {
|
||||||
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()) {
|
switch (patterns.size()) {
|
||||||
case 0:
|
case 0:
|
||||||
throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input)));
|
throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input)));
|
||||||
|
@ -21,6 +21,9 @@ package com.sk89q.worldedit.internal.registry;
|
|||||||
|
|
||||||
import com.fastasyncworldedit.core.configuration.Caption;
|
import com.fastasyncworldedit.core.configuration.Caption;
|
||||||
import com.fastasyncworldedit.core.extension.factory.parser.AliasedParser;
|
import com.fastasyncworldedit.core.extension.factory.parser.AliasedParser;
|
||||||
|
import com.fastasyncworldedit.core.extension.factory.parser.FaweParser;
|
||||||
|
import com.fastasyncworldedit.core.extension.factory.parser.pattern.RichPatternParser;
|
||||||
|
import com.sk89q.util.StringUtil;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||||
import com.sk89q.worldedit.extension.input.NoMatchException;
|
import com.sk89q.worldedit.extension.input.NoMatchException;
|
||||||
@ -43,7 +46,10 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
public abstract class AbstractFactory<E> {
|
public abstract class AbstractFactory<E> {
|
||||||
|
|
||||||
protected final WorldEdit worldEdit;
|
protected final WorldEdit worldEdit;
|
||||||
private final List<InputParser<E>> parsers = new ArrayList<>();
|
//FAWE start
|
||||||
|
protected final List<InputParser<E>> parsers = new ArrayList<>();
|
||||||
|
private final FaweParser<E> richParser;
|
||||||
|
//FWAE end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new factory.
|
* Create a new factory.
|
||||||
@ -52,11 +58,26 @@ public abstract class AbstractFactory<E> {
|
|||||||
* @param defaultParser the parser to fall back to
|
* @param defaultParser the parser to fall back to
|
||||||
*/
|
*/
|
||||||
protected AbstractFactory(WorldEdit worldEdit, InputParser<E> defaultParser) {
|
protected AbstractFactory(WorldEdit worldEdit, InputParser<E> defaultParser) {
|
||||||
|
//FAWE start
|
||||||
|
this(worldEdit, defaultParser, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new factory with a given rich parser for FAWE rich parsing
|
||||||
|
*
|
||||||
|
* @param worldEdit the WorldEdit instance
|
||||||
|
* @param defaultParser the parser to fall back to
|
||||||
|
* @param richParser the rich parser
|
||||||
|
* @since TODO
|
||||||
|
*/
|
||||||
|
protected AbstractFactory(WorldEdit worldEdit, InputParser<E> defaultParser, FaweParser<E> richParser) {
|
||||||
checkNotNull(worldEdit);
|
checkNotNull(worldEdit);
|
||||||
checkNotNull(defaultParser);
|
checkNotNull(defaultParser);
|
||||||
this.worldEdit = worldEdit;
|
this.worldEdit = worldEdit;
|
||||||
this.parsers.add(defaultParser);
|
this.parsers.add(defaultParser);
|
||||||
|
this.richParser = richParser;
|
||||||
}
|
}
|
||||||
|
//FAWE end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets an immutable list of parsers.
|
* Gets an immutable list of parsers.
|
||||||
@ -71,7 +92,7 @@ public abstract class AbstractFactory<E> {
|
|||||||
return Collections.unmodifiableList(parsers);
|
return Collections.unmodifiableList(parsers);
|
||||||
}
|
}
|
||||||
|
|
||||||
//FAWE start - javadoc
|
//FAWE start
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a string and context to each {@link InputParser} added to this factory. If no result found, throws {@link InputParseException}
|
* Parse a string and context to each {@link InputParser} added to this factory. If no result found, throws {@link InputParseException}
|
||||||
@ -81,20 +102,26 @@ public abstract class AbstractFactory<E> {
|
|||||||
* @return parsed result
|
* @return parsed result
|
||||||
* @throws InputParseException if no result found
|
* @throws InputParseException if no result found
|
||||||
*/
|
*/
|
||||||
//FAWE end
|
|
||||||
public E parseFromInput(String input, ParserContext context) throws InputParseException {
|
public E parseFromInput(String input, ParserContext context) throws InputParseException {
|
||||||
E match;
|
List<E> parsed = new ArrayList<>();
|
||||||
|
for (String component : StringUtil.split(input,' ', '[', ']')) {
|
||||||
for (InputParser<E> parser : parsers) {
|
if (component.isEmpty()) {
|
||||||
match = parser.parseFromInput(input, context);
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (richParser != null) {
|
||||||
|
E match = richParser.parseFromInput(component, context);
|
||||||
if (match != null) {
|
if (match != null) {
|
||||||
return match;
|
parsed.add(match);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
parseFromParsers(context, parsed, component);
|
||||||
|
}
|
||||||
|
|
||||||
throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input)));
|
return getParsed(input, parsed);
|
||||||
}
|
}
|
||||||
|
//FAWE end
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public List<String> getSuggestions(String input) {
|
public List<String> getSuggestions(String input) {
|
||||||
@ -133,4 +160,48 @@ public abstract class AbstractFactory<E> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//FAWE start
|
||||||
|
protected void parseFromParsers(final ParserContext context, final List<E> parsed, final String component) {
|
||||||
|
E match = null;
|
||||||
|
for (InputParser<E> 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)));
|
||||||
|
}
|
||||||
|
parsed.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 E parseWithoutRich(String input, ParserContext context) throws InputParseException {
|
||||||
|
List<E> parsed = new ArrayList<>();
|
||||||
|
|
||||||
|
for (String component : StringUtil.split(input, ' ', '[', ']')) {
|
||||||
|
if (component.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
parseFromParsers(context, parsed, component);
|
||||||
|
}
|
||||||
|
|
||||||
|
return getParsed(input, parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected E getParsed(final String input, final List<E> parsed) {
|
||||||
|
return parsed.isEmpty() ? null : parsed.get(0);
|
||||||
|
}
|
||||||
|
//FAWE end
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user