From 53308416ffcde97538dfcd471aa9907b8fb2a1bb Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Sun, 23 Dec 2018 18:56:26 +1000 Subject: [PATCH] Start work on modularising masks and patterns --- .../main/java/com/boydti/fawe/FaweAPI.java | 6 +- .../com/boydti/fawe/command/MaskBinding.java | 1 - .../worldedit/command/UtilityCommands.java | 7 +- .../extension/factory/BlockFactory.java | 3 +- .../extension/factory/ItemFactory.java | 3 +- .../extension/factory/MaskFactory.java | 53 ++++- .../extension/factory/PatternFactory.java | 9 +- .../{ => parser}/DefaultBlockParser.java | 2 +- .../{ => parser}/DefaultItemParser.java | 4 +- .../parser/mask/BlockCategoryMaskParser.java | 55 +++++ .../{ => parser/mask}/DefaultMaskParser.java | 89 +++----- .../parser/mask/ExistingMaskParser.java | 51 +++++ .../parser/mask/LazyRegionMaskParser.java | 48 ++++ .../factory/parser/mask/NegateMaskParser.java | 47 ++++ .../factory/parser/mask/NoiseMaskParser.java | 45 ++++ .../factory/parser/mask/RegionMaskParser.java | 52 +++++ .../factory/parser/mask/SolidMaskParser.java | 51 +++++ .../pattern/ClipboardPatternParser.java | 207 ++++++++++++++++++ .../pattern/DefaultPatternParser.java} | 33 ++- .../pattern}/RandomPatternParser.java | 7 +- .../pattern}/SingleBlockPatternParser.java | 6 +- .../internal/registry/AbstractFactory.java | 25 ++- .../internal/registry/InputParser.java | 13 +- .../internal/registry/SimpleInputParser.java | 71 ++++++ .../scripting/CommandScriptLoader.java | 7 +- 25 files changed, 808 insertions(+), 87 deletions(-) rename worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/{ => parser}/DefaultBlockParser.java (99%) rename worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/{ => parser}/DefaultItemParser.java (96%) create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/BlockCategoryMaskParser.java rename worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/{ => parser/mask}/DefaultMaskParser.java (79%) create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/ExistingMaskParser.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/LazyRegionMaskParser.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/NegateMaskParser.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/NoiseMaskParser.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/RegionMaskParser.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/SolidMaskParser.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/ClipboardPatternParser.java rename worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/{HashTagPatternParser.java => parser/pattern/DefaultPatternParser.java} (88%) rename worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/{ => parser/pattern}/RandomPatternParser.java (91%) rename worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/{ => parser/pattern}/SingleBlockPatternParser.java (89%) create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/SimpleInputParser.java diff --git a/worldedit-core/src/main/java/com/boydti/fawe/FaweAPI.java b/worldedit-core/src/main/java/com/boydti/fawe/FaweAPI.java index 9f90f2d70..f40085442 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/FaweAPI.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/FaweAPI.java @@ -22,9 +22,9 @@ import com.boydti.fawe.wrappers.WorldWrapper; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.extension.factory.DefaultMaskParser; import com.sk89q.worldedit.extension.factory.DefaultTransformParser; -import com.sk89q.worldedit.extension.factory.HashTagPatternParser; +import com.sk89q.worldedit.extension.factory.parser.mask.DefaultMaskParser; +import com.sk89q.worldedit.extension.factory.parser.pattern.DefaultPatternParser; import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extension.platform.CommandManager; import com.sk89q.worldedit.extension.platform.Platform; @@ -102,7 +102,7 @@ public class FaweAPI { * @see com.sk89q.worldedit.command.PatternCommands */ public static boolean registerPatterns(Object methods) { - HashTagPatternParser parser = getParser(HashTagPatternParser.class); + DefaultPatternParser parser = getParser(DefaultPatternParser.class); if (parser != null) parser.register(methods); return parser != null; } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/command/MaskBinding.java b/worldedit-core/src/main/java/com/boydti/fawe/command/MaskBinding.java index 2173aff6b..5711c43a4 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/command/MaskBinding.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/command/MaskBinding.java @@ -1,7 +1,6 @@ package com.boydti.fawe.command; import com.sk89q.worldedit.WorldEdit; -import com.sk89q.worldedit.extension.factory.DefaultMaskParser; import com.sk89q.worldedit.util.command.parametric.ParameterData; import com.sk89q.worldedit.world.block.BlockTypes; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index a846dd0f6..14b0cb68a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -59,9 +59,10 @@ import com.sk89q.worldedit.command.util.EntityRemover; import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.event.platform.CommandEvent; -import com.sk89q.worldedit.extension.factory.DefaultMaskParser; import com.sk89q.worldedit.extension.factory.DefaultTransformParser; -import com.sk89q.worldedit.extension.factory.HashTagPatternParser; +import com.sk89q.worldedit.extension.factory.parser.mask.DefaultMaskParser; +import com.sk89q.worldedit.extension.factory.parser.pattern.ClipboardPatternParser; +import com.sk89q.worldedit.extension.factory.parser.pattern.DefaultPatternParser; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extension.platform.CommandManager; @@ -128,7 +129,7 @@ public class UtilityCommands extends MethodCommands { queued = false ) public void patterns(Player player, LocalSession session, CommandContext args) throws WorldEditException { - displayModifierHelp(player, HashTagPatternParser.class, args); + displayModifierHelp(player, DefaultPatternParser.class, args); } @Command( diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/BlockFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/BlockFactory.java index 90cc333b7..9b97a175e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/BlockFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/BlockFactory.java @@ -22,6 +22,7 @@ package com.sk89q.worldedit.extension.factory; import com.sk89q.util.StringUtil; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.world.block.BlockStateHolder; +import com.sk89q.worldedit.extension.factory.parser.DefaultBlockParser; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.ParserContext; @@ -46,7 +47,7 @@ public class BlockFactory extends AbstractFactory { public BlockFactory(WorldEdit worldEdit) { super(worldEdit); - parsers.add(new DefaultBlockParser(worldEdit)); + register(new DefaultBlockParser(worldEdit)); } /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/ItemFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/ItemFactory.java index 321fc6280..e2a2bee29 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/ItemFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/ItemFactory.java @@ -21,6 +21,7 @@ package com.sk89q.worldedit.extension.factory; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.blocks.BaseItem; +import com.sk89q.worldedit.extension.factory.parser.DefaultItemParser; import com.sk89q.worldedit.internal.registry.AbstractFactory; public class ItemFactory extends AbstractFactory { @@ -33,7 +34,7 @@ public class ItemFactory extends AbstractFactory { public ItemFactory(WorldEdit worldEdit) { super(worldEdit); - parsers.add(new DefaultItemParser(worldEdit)); + register(new DefaultItemParser(worldEdit)); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java index 01fef9803..0f9f04fde 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java @@ -20,8 +20,24 @@ package com.sk89q.worldedit.extension.factory; import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.extension.factory.parser.mask.BlockCategoryMaskParser; +import com.sk89q.worldedit.extension.factory.parser.mask.DefaultMaskParser; +import com.sk89q.worldedit.extension.factory.parser.mask.ExistingMaskParser; +import com.sk89q.worldedit.extension.factory.parser.mask.LazyRegionMaskParser; +import com.sk89q.worldedit.extension.factory.parser.mask.NegateMaskParser; +import com.sk89q.worldedit.extension.factory.parser.mask.NoiseMaskParser; +import com.sk89q.worldedit.extension.factory.parser.mask.RegionMaskParser; +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.ParserContext; import com.sk89q.worldedit.function.mask.Mask; +import com.sk89q.worldedit.function.mask.MaskIntersection; import com.sk89q.worldedit.internal.registry.AbstractFactory; +import com.sk89q.worldedit.internal.registry.InputParser; + +import java.util.ArrayList; +import java.util.List; /** * A registry of known {@link Mask}s. Provides methods to instantiate @@ -40,7 +56,42 @@ public final class MaskFactory extends AbstractFactory { public MaskFactory(WorldEdit worldEdit) { super(worldEdit); - parsers.add(new DefaultMaskParser(worldEdit)); + register(new ExistingMaskParser(worldEdit)); + register(new SolidMaskParser(worldEdit)); + register(new LazyRegionMaskParser(worldEdit)); + register(new RegionMaskParser(worldEdit)); + register(new BlockCategoryMaskParser(worldEdit)); + register(new NoiseMaskParser(worldEdit)); + register(new NegateMaskParser(worldEdit)); + register(new DefaultMaskParser(worldEdit)); + } + + @Override + public Mask parseFromInput(String input, ParserContext context) throws InputParseException { + List masks = new ArrayList<>(); + + for (String component : input.split(" ")) { + if (component.isEmpty()) { + continue; + } + + for (InputParser parser : getParsers()) { + Mask match = parser.parseFromInput(component, context); + + if (match != null) { + masks.add(match); + } + } + } + + switch (masks.size()) { + case 0: + throw new NoMatchException("No match for '" + input + "'"); + case 1: + return masks.get(0); + default: + return new MaskIntersection(masks); + } } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java index dde70291e..5a24e5f79 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java @@ -20,6 +20,10 @@ package com.sk89q.worldedit.extension.factory; import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.extension.factory.parser.pattern.ClipboardPatternParser; +import com.sk89q.worldedit.extension.factory.parser.pattern.DefaultPatternParser; +import com.sk89q.worldedit.extension.factory.parser.pattern.RandomPatternParser; +import com.sk89q.worldedit.extension.factory.parser.pattern.SingleBlockPatternParser; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.internal.registry.AbstractFactory; @@ -40,7 +44,10 @@ public final class PatternFactory extends AbstractFactory { public PatternFactory(WorldEdit worldEdit) { super(worldEdit); - parsers.add(new HashTagPatternParser(worldEdit)); +// register(new ClipboardPatternParser(worldEdit)); +// register(new SingleBlockPatternParser(worldEdit)); +// register(new RandomPatternParser(worldEdit)); + register(new DefaultPatternParser(worldEdit)); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/DefaultBlockParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java similarity index 99% rename from worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/DefaultBlockParser.java rename to worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java index 9b61d3f31..3187d095a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/DefaultBlockParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.extension.factory; +package com.sk89q.worldedit.extension.factory.parser; import com.boydti.fawe.command.SuggestInputParseException; import com.boydti.fawe.jnbt.JSON2NBT; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/DefaultItemParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultItemParser.java similarity index 96% rename from worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/DefaultItemParser.java rename to worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultItemParser.java index 30022cfe9..8c087bfeb 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/DefaultItemParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultItemParser.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.extension.factory; +package com.sk89q.worldedit.extension.factory.parser; import com.boydti.fawe.util.MathMan; import com.sk89q.worldedit.WorldEdit; @@ -32,7 +32,7 @@ import com.sk89q.worldedit.world.registry.LegacyMapper; public class DefaultItemParser extends InputParser { - protected DefaultItemParser(WorldEdit worldEdit) { + public DefaultItemParser(WorldEdit worldEdit) { super(worldEdit); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/BlockCategoryMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/BlockCategoryMaskParser.java new file mode 100644 index 000000000..478ba22e6 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/BlockCategoryMaskParser.java @@ -0,0 +1,55 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +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.extent.Extent; +import com.sk89q.worldedit.function.mask.BlockCategoryMask; +import com.sk89q.worldedit.function.mask.Mask; +import com.sk89q.worldedit.internal.registry.InputParser; +import com.sk89q.worldedit.session.request.Request; +import com.sk89q.worldedit.world.block.BlockCategories; +import com.sk89q.worldedit.world.block.BlockCategory; + +public class BlockCategoryMaskParser extends InputParser { + + public BlockCategoryMaskParser(WorldEdit worldEdit) { + super(worldEdit); + } + + @Override + public Mask parseFromInput(String input, ParserContext context) throws InputParseException { + if (input.startsWith("##")) { + Extent extent = Request.request().getEditSession(); + + // This means it's a tag mask. + BlockCategory category = BlockCategories.get(input.substring(2).toLowerCase()); + if (category == null) { + throw new InputParseException("Unrecognised tag '" + input.substring(2) + '\''); + } else { + return new BlockCategoryMask(extent, category); + } + } + + return null; + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/DefaultMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/DefaultMaskParser.java similarity index 79% rename from worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/DefaultMaskParser.java rename to worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/DefaultMaskParser.java index 2f51cdda5..5e62e5656 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/DefaultMaskParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/DefaultMaskParser.java @@ -1,12 +1,30 @@ -package com.sk89q.worldedit.extension.factory; +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.extension.factory.parser.mask; import com.boydti.fawe.command.FaweParser; import com.boydti.fawe.command.SuggestInputParseException; import com.boydti.fawe.config.BBC; import com.boydti.fawe.util.StringMan; -import com.sk89q.minecraft.util.commands.CommandException; +import com.plotsquared.general.commands.Command.CommandException; import com.sk89q.minecraft.util.commands.CommandLocals; -import com.sk89q.worldedit.IncompleteRegionException; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.command.MaskCommands; import com.sk89q.worldedit.extension.input.InputParseException; @@ -15,22 +33,22 @@ import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.function.mask.BlockMaskBuilder; +import com.sk89q.worldedit.function.mask.BiomeMask2D; +import com.sk89q.worldedit.function.mask.BlockMask; +import com.sk89q.worldedit.function.mask.ExistingBlockMask; +import com.sk89q.worldedit.function.mask.ExpressionMask; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.MaskIntersection; import com.sk89q.worldedit.function.mask.MaskUnion; import com.sk89q.worldedit.internal.command.ActorAuthorizer; import com.sk89q.worldedit.internal.command.WorldEditBinding; import com.sk89q.worldedit.function.mask.Masks; -import com.sk89q.worldedit.function.mask.NoiseFilter; import com.sk89q.worldedit.function.mask.OffsetMask; -import com.sk89q.worldedit.function.mask.RegionMask; -import com.sk89q.worldedit.function.mask.SolidBlockMask; import com.sk89q.worldedit.internal.expression.Expression; import com.sk89q.worldedit.internal.expression.ExpressionException; import com.sk89q.worldedit.internal.registry.InputParser; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; -import com.sk89q.worldedit.math.noise.RandomNoise; import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment; import com.sk89q.worldedit.session.request.Request; import com.sk89q.worldedit.util.command.Dispatcher; @@ -40,6 +58,11 @@ import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockTypes; import java.util.ArrayList; +import com.sk89q.worldedit.world.biome.BaseBiome; +import com.sk89q.worldedit.world.biome.Biomes; +import com.sk89q.worldedit.world.registry.BiomeRegistry; + +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.regex.Pattern; @@ -49,7 +72,6 @@ import java.util.stream.Stream; public class DefaultMaskParser extends FaweParser { private final Dispatcher dispatcher; private final Pattern INTERSECTION_PATTERN = Pattern.compile("[&|;]+(?![^\\[]*\\])"); - public DefaultMaskParser(WorldEdit worldEdit) { super(worldEdit); this.dispatcher = new SimpleDispatcher(); @@ -163,7 +185,6 @@ public class DefaultMaskParser extends FaweParser { } } } else { -//<<<<<<< HEAD List args = entry.getValue(); String cmdArgs = ((args.isEmpty()) ? "" : " " + StringMan.join(args, " ")); try { @@ -192,57 +213,12 @@ public class DefaultMaskParser extends FaweParser { throw new InputParseException(e2.getMessage()); } }); -//======= -// throw new NoMatchException("Unrecognized mask '" + component + '\''); -// } -// -// case '>': -// case '<': -// Mask submask; -// if (component.length() > 1) { -// submask = getBlockMaskComponent(masks, component.substring(1), context); -// } else { -// submask = new ExistingBlockMask(extent); -// } -// OffsetMask offsetMask = new OffsetMask(submask, BlockVector3.at(0, firstChar == '>' ? -1 : 1, 0)); -// return new MaskIntersection(offsetMask, Masks.negate(submask)); -// -// case '$': -// Set biomes = new HashSet<>(); -// String[] biomesList = component.substring(1).split(","); -// BiomeRegistry biomeRegistry = WorldEdit.getInstance().getPlatformManager() -// .queryCapability(Capability.GAME_HOOKS).getRegistries().getBiomeRegistry(); -// List knownBiomes = biomeRegistry.getBiomes(); -// for (String biomeName : biomesList) { -// BaseBiome biome = Biomes.findBiomeByName(knownBiomes, biomeName, biomeRegistry); -// if (biome == null) { -// throw new InputParseException("Unknown biome '" + biomeName + '\''); -//>>>>>>> 2c8b2fe0... Move vectors to static creators, for caching - } } -//<<<<<<< HEAD if (pe.and) { masks.add(new ArrayList<>()); -//======= -// -// return Masks.asMask(new BiomeMask2D(context.requireExtent(), biomes)); -// -// case '%': -// int i = Integer.parseInt(component.substring(1)); -// return new NoiseFilter(new RandomNoise(), ((double) i) / 100); -// -// case '=': -// try { -// Expression exp = Expression.compile(component.substring(1), "x", "y", "z"); -// WorldEditExpressionEnvironment env = new WorldEditExpressionEnvironment( -// Request.request().getEditSession(), Vector3.ONE, Vector3.ZERO); -// exp.setEnvironment(env); -// return new ExpressionMask(exp); -// } catch (ExpressionException e) { -// throw new InputParseException("Invalid expression: " + e.getMessage()); -//>>>>>>> 399e0ad5... Refactor vector system to be cleaner } masks.get(masks.size() - 1).add(mask); + } } } catch (InputParseException rethrow) { throw rethrow; @@ -264,6 +240,7 @@ public class DefaultMaskParser extends FaweParser { return new MaskIntersection(maskUnions); } else { return null; - } + } + } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/ExistingMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/ExistingMaskParser.java new file mode 100644 index 000000000..a1dea6f48 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/ExistingMaskParser.java @@ -0,0 +1,51 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.extension.factory.parser.mask; + +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 com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.function.mask.ExistingBlockMask; +import com.sk89q.worldedit.function.mask.Mask; +import com.sk89q.worldedit.internal.registry.SimpleInputParser; +import com.sk89q.worldedit.session.request.Request; + +import java.util.List; + +public class ExistingMaskParser extends SimpleInputParser { + + public ExistingMaskParser(WorldEdit worldEdit) { + super(worldEdit); + } + + @Override + public List getMatchedAliases() { + return Lists.newArrayList("#existing"); + } + + @Override + public Mask parseFromSimpleInput(String input, ParserContext context) throws InputParseException { + Extent extent = Request.request().getEditSession(); + + return new ExistingBlockMask(extent); + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/LazyRegionMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/LazyRegionMaskParser.java new file mode 100644 index 000000000..82bc14d2b --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/LazyRegionMaskParser.java @@ -0,0 +1,48 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.extension.factory.parser.mask; + +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 com.sk89q.worldedit.function.mask.Mask; +import com.sk89q.worldedit.function.mask.RegionMask; +import com.sk89q.worldedit.internal.registry.SimpleInputParser; +import com.sk89q.worldedit.session.request.RequestSelection; + +import java.util.List; + +public class LazyRegionMaskParser extends SimpleInputParser { + + public LazyRegionMaskParser(WorldEdit worldEdit) { + super(worldEdit); + } + + @Override + public List getMatchedAliases() { + return Lists.newArrayList("#dregion", "#dselection", "#dsel"); + } + + @Override + public Mask parseFromSimpleInput(String input, ParserContext context) throws InputParseException { + return new RegionMask(new RequestSelection()); + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/NegateMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/NegateMaskParser.java new file mode 100644 index 000000000..9e1c2e9df --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/NegateMaskParser.java @@ -0,0 +1,47 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +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.Masks; +import com.sk89q.worldedit.internal.registry.InputParser; + +public class NegateMaskParser extends InputParser { + + public NegateMaskParser(WorldEdit worldEdit) { + super(worldEdit); + } + + @Override + public Mask parseFromInput(String input, ParserContext context) throws InputParseException { + if (!input.startsWith("!")) { + return null; + } + + if (input.length() > 1) { + return Masks.negate(worldEdit.getMaskFactory().parseFromInput(input.substring(1), context)); + } else { + throw new InputParseException("Can't negate nothing!"); + } + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/NoiseMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/NoiseMaskParser.java new file mode 100644 index 000000000..0cb1a85e8 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/NoiseMaskParser.java @@ -0,0 +1,45 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +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; + +public class NoiseMaskParser extends InputParser { + + public NoiseMaskParser(WorldEdit worldEdit) { + super(worldEdit); + } + + @Override + public Mask parseFromInput(String input, ParserContext context) throws InputParseException { + if (!input.startsWith("%")) { + return null; + } + + int i = Integer.parseInt(input.substring(1)); + return new NoiseFilter(new RandomNoise(), ((double) i) / 100); + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/RegionMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/RegionMaskParser.java new file mode 100644 index 000000000..21963835d --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/RegionMaskParser.java @@ -0,0 +1,52 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.extension.factory.parser.mask; + +import com.google.common.collect.Lists; +import com.sk89q.worldedit.IncompleteRegionException; +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; +import com.sk89q.worldedit.internal.registry.SimpleInputParser; + +import java.util.List; + +public class RegionMaskParser extends SimpleInputParser { + + public RegionMaskParser(WorldEdit worldEdit) { + super(worldEdit); + } + + @Override + public List getMatchedAliases() { + return Lists.newArrayList("#region", "#selection", "#sel"); + } + + @Override + public Mask parseFromSimpleInput(String input, ParserContext context) throws InputParseException { + try { + return new RegionMask(context.requireSession().getSelection(context.requireWorld()).clone()); + } catch (IncompleteRegionException e) { + throw new InputParseException("Please make a selection first."); + } + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/SolidMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/SolidMaskParser.java new file mode 100644 index 000000000..84df2fec8 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/SolidMaskParser.java @@ -0,0 +1,51 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.extension.factory.parser.mask; + +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 com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.function.mask.Mask; +import com.sk89q.worldedit.function.mask.SolidBlockMask; +import com.sk89q.worldedit.internal.registry.SimpleInputParser; +import com.sk89q.worldedit.session.request.Request; + +import java.util.List; + +public class SolidMaskParser extends SimpleInputParser { + + public SolidMaskParser(WorldEdit worldEdit) { + super(worldEdit); + } + + @Override + public List getMatchedAliases() { + return Lists.newArrayList("#solid"); + } + + @Override + public Mask parseFromSimpleInput(String input, ParserContext context) throws InputParseException { + Extent extent = Request.request().getEditSession(); + + return new SolidBlockMask(extent); + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/ClipboardPatternParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/ClipboardPatternParser.java new file mode 100644 index 000000000..720bf8956 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/ClipboardPatternParser.java @@ -0,0 +1,207 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.extension.factory.parser.pattern; + +import com.boydti.fawe.command.FaweParser; +import com.boydti.fawe.command.SuggestInputParseException; +import com.boydti.fawe.config.BBC; +import com.boydti.fawe.object.random.TrueRandom; +import com.boydti.fawe.util.StringMan; +import com.sk89q.minecraft.util.commands.CommandException; +import com.sk89q.minecraft.util.commands.CommandLocals; + +import com.google.common.collect.Lists; +import com.sk89q.worldedit.EmptyClipboardException; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.command.PatternCommands; +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.platform.Actor; +import com.sk89q.worldedit.function.pattern.Pattern; +import com.sk89q.worldedit.function.pattern.RandomPattern; +import com.sk89q.worldedit.internal.command.ActorAuthorizer; +import com.sk89q.worldedit.internal.command.WorldEditBinding; +import com.sk89q.worldedit.internal.expression.Expression; +import com.sk89q.worldedit.internal.expression.ExpressionException; +import com.sk89q.worldedit.util.command.Dispatcher; +import com.sk89q.worldedit.util.command.SimpleDispatcher; +import com.sk89q.worldedit.util.command.parametric.ParametricBuilder; +import com.sk89q.worldedit.world.block.BlockTypes; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class ClipboardPatternParser extends FaweParser { + private final Dispatcher dispatcher; + + public ClipboardPatternParser(WorldEdit worldEdit) { + super(worldEdit); + this.dispatcher = new SimpleDispatcher(); + this.register(new PatternCommands(worldEdit)); + } + + @Override + public Dispatcher getDispatcher() { + return dispatcher; + } + + public void register(Object clazz) { + ParametricBuilder builder = new ParametricBuilder(); + builder.setAuthorizer(new ActorAuthorizer()); + builder.addBinding(new WorldEditBinding(worldEdit)); + builder.registerMethodsAsCommands(dispatcher, clazz); + } + + @Override + public Pattern parseFromInput(String input, ParserContext context) throws InputParseException { + if (input.isEmpty()) { + throw new SuggestInputParseException("No input provided", "", () -> Stream.concat(Stream.of("#", ",", "&"), BlockTypes.getNameSpaces().stream().map(n -> n + ":")).collect(Collectors.toList())); + } + List chances = new ArrayList<>(); + List patterns = new ArrayList<>(); + final CommandLocals locals = new CommandLocals(); + Actor actor = context != null ? context.getActor() : null; + if (actor != null) { + locals.put(Actor.class, actor); + } + try { + for (Map.Entry> entry : parse(input)) { + ParseEntry pe = entry.getKey(); + final String command = pe.input; + String full = pe.full; + Pattern pattern = null; + double chance = 1; + if (command.isEmpty()) { + pattern = parseFromInput(StringMan.join(entry.getValue(), ','), context); + } else if (dispatcher.get(command) == null) { + // Legacy patterns + char char0 = command.charAt(0); + boolean charMask = input.length() > 1 && input.charAt(1) != '['; + if (charMask && input.charAt(0) == '=') { + return parseFromInput(char0 + "[" + input.substring(1) + "]", context); + } + if (char0 == '#') { + throw new SuggestInputParseException(new NoMatchException("Unknown pattern: " + full + ", See: //patterns"), full, + () -> { + if (full.length() == 1) return new ArrayList<>(dispatcher.getPrimaryAliases()); + return dispatcher.getAliases().stream().filter( + s -> s.startsWith(command.toLowerCase()) + ).collect(Collectors.toList()); + } + ); + } + + + if (charMask) { + switch (char0) { + case '$': { + String value = command.substring(1) + ((entry.getValue().isEmpty()) ? "" : "[" + StringMan.join(entry.getValue(), "][") + "]"); + if (value.contains(":")) { + if (value.charAt(0) == ':') value.replaceFirst(":", ""); + value = value.replaceAll(":", "]["); + } + pattern = parseFromInput(char0 + "[" + value + "]", context); + break; + } + } + } + if (pattern == null) { + if (command.startsWith("[")) { + int end = command.lastIndexOf(']'); + pattern = parseFromInput(command.substring(1, end == -1 ? command.length() : end), context); + } else { + int percentIndex = command.indexOf('%'); + if (percentIndex != -1) { // Legacy percent pattern + chance = Expression.compile(command.substring(0, percentIndex)).evaluate(); + String value = command.substring(percentIndex + 1); + if (!entry.getValue().isEmpty()) { + if (!value.isEmpty()) value += " "; + value += StringMan.join(entry.getValue(), " "); + } + pattern = parseFromInput(value, context); + } else { // legacy block pattern + try { + pattern = worldEdit.getBlockFactory().parseFromInput(pe.full, context); + } catch (NoMatchException e) { + throw new NoMatchException(e.getMessage() + " See: //patterns"); + } + } + } + } + } else { + List args = entry.getValue(); + String cmdArgs = ((args.isEmpty()) ? "" : " " + StringMan.join(args, " ")); + try { + pattern = (Pattern) dispatcher.call(command + cmdArgs, locals, new String[0]); + } catch (SuggestInputParseException rethrow) { + throw rethrow; + } catch (Throwable e) { + throw SuggestInputParseException.of(e, full, () -> { + try { + List suggestions = dispatcher.get(command).getCallable().getSuggestions(cmdArgs, locals); + if (suggestions.size() <= 2) { + for (int i = 0; i < suggestions.size(); i++) { + String suggestion = suggestions.get(i); + if (suggestion.indexOf(' ') != 0) { + String[] split = suggestion.split(" "); + suggestion = BBC.color("[" + StringMan.join(split, "][") + "]"); + suggestions.set(i, suggestion); + } + } + } + return suggestions; + } catch (CommandException e1) { + throw new InputParseException(e1.getMessage()); + } catch (Throwable e2) { + e2.printStackTrace(); + throw new InputParseException(e2.getMessage()); + } + }); + } + } + if (pattern != null) { + patterns.add(pattern); + chances.add(chance); + } + } + } catch (InputParseException rethrow) { + throw rethrow; + } catch (Throwable e) { + e.printStackTrace(); + throw new InputParseException(e.getMessage(), e); + } + if (patterns.isEmpty()) { + return null; + } else if (patterns.size() == 1) { + return patterns.get(0); + } else { + RandomPattern random = new RandomPattern(new TrueRandom()); + for (int i = 0; i < patterns.size(); i++) { + random.add(patterns.get(i), chances.get(i)); + } + return random; + } + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/HashTagPatternParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/DefaultPatternParser.java similarity index 88% rename from worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/HashTagPatternParser.java rename to worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/DefaultPatternParser.java index f32db3a77..bb5e353ae 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/HashTagPatternParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/DefaultPatternParser.java @@ -1,4 +1,23 @@ -package com.sk89q.worldedit.extension.factory; +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.extension.factory.parser.pattern; import com.boydti.fawe.command.FaweParser; import com.boydti.fawe.command.SuggestInputParseException; @@ -7,6 +26,10 @@ import com.boydti.fawe.object.random.TrueRandom; import com.boydti.fawe.util.StringMan; import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.minecraft.util.commands.CommandLocals; + +import com.google.common.collect.Lists; +import com.sk89q.worldedit.EmptyClipboardException; +import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.command.PatternCommands; import com.sk89q.worldedit.extension.input.InputParseException; @@ -30,10 +53,10 @@ import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; -public class HashTagPatternParser extends FaweParser { +public class DefaultPatternParser extends FaweParser { private final Dispatcher dispatcher; - public HashTagPatternParser(WorldEdit worldEdit) { + public DefaultPatternParser(WorldEdit worldEdit) { super(worldEdit); this.dispatcher = new SimpleDispatcher(); this.register(new PatternCommands(worldEdit)); @@ -179,8 +202,6 @@ public class HashTagPatternParser extends FaweParser { random.add(patterns.get(i), chances.get(i)); } return random; - } + } } - - } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/RandomPatternParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/RandomPatternParser.java similarity index 91% rename from worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/RandomPatternParser.java rename to worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/RandomPatternParser.java index 2cc9eae94..3afc9e81d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/RandomPatternParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/RandomPatternParser.java @@ -17,10 +17,11 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.extension.factory; +package com.sk89q.worldedit.extension.factory.parser.pattern; import com.sk89q.util.StringUtil; import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.extension.factory.BlockFactory; import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.function.pattern.BlockPattern; @@ -29,9 +30,9 @@ import com.sk89q.worldedit.function.pattern.RandomPattern; import com.sk89q.worldedit.internal.registry.InputParser; import com.sk89q.worldedit.world.block.BlockStateHolder; -class RandomPatternParser extends InputParser { +public class RandomPatternParser extends InputParser { - RandomPatternParser(WorldEdit worldEdit) { + public RandomPatternParser(WorldEdit worldEdit) { super(worldEdit); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/SingleBlockPatternParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/SingleBlockPatternParser.java similarity index 89% rename from worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/SingleBlockPatternParser.java rename to worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/SingleBlockPatternParser.java index cd3adb5e7..960983780 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/SingleBlockPatternParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/SingleBlockPatternParser.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.extension.factory; +package com.sk89q.worldedit.extension.factory.parser.pattern; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.extension.input.InputParseException; @@ -26,9 +26,9 @@ import com.sk89q.worldedit.function.pattern.BlockPattern; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.internal.registry.InputParser; -class SingleBlockPatternParser extends InputParser { +public class SingleBlockPatternParser extends InputParser { - SingleBlockPatternParser(WorldEdit worldEdit) { + public SingleBlockPatternParser(WorldEdit worldEdit) { super(worldEdit); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/AbstractFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/AbstractFactory.java index 506663a81..bdd40c104 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/AbstractFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/AbstractFactory.java @@ -21,12 +21,14 @@ package com.sk89q.worldedit.internal.registry; import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.collect.Lists; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.NoMatchException; import com.sk89q.worldedit.extension.input.ParserContext; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -38,7 +40,7 @@ import java.util.List; public abstract class AbstractFactory { protected final WorldEdit worldEdit; - protected final List> parsers = new ArrayList<>(); + private final List> parsers = new ArrayList<>(); /** * Create a new factory. @@ -50,6 +52,17 @@ public abstract class AbstractFactory { this.worldEdit = worldEdit; } + /** + * Gets an immutable list of parsers. + * + * To add parsers, use the register method. + * + * @return the parsers + */ + public List> getParsers() { + return Collections.unmodifiableList(parsers); + } + public E parseFromInput(String input, ParserContext context) throws InputParseException { E match; @@ -64,4 +77,14 @@ public abstract class AbstractFactory { throw new NoMatchException("No match for '" + input + "'"); } + /** + * Registers an InputParser to this factory + * + * @param inputParser The input parser + */ + public void register(InputParser inputParser) { + checkNotNull(inputParser); + + parsers.add(inputParser); + } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/InputParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/InputParser.java index 77c05c2e3..ee40fa3b9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/InputParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/InputParser.java @@ -19,10 +19,13 @@ 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; + /** * Input parser interface for {@link AbstractFactory}. * @@ -33,10 +36,18 @@ public abstract class InputParser { protected final WorldEdit worldEdit; - protected InputParser(WorldEdit worldEdit) { + public InputParser(WorldEdit worldEdit) { this.worldEdit = worldEdit; } public abstract E parseFromInput(String input, ParserContext context) throws InputParseException; + /** + * Gets a list of suggestions of input to this parser. + * + * @return a list of suggestions + */ + public List getSuggestions() { + return Lists.newArrayList(); + } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/SimpleInputParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/SimpleInputParser.java new file mode 100644 index 000000000..d0647f9cc --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/SimpleInputParser.java @@ -0,0 +1,71 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +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; + +/** + * An input parser that only performs a single function from aliases. + * + * @param the element + */ +public abstract class SimpleInputParser extends InputParser { + + public SimpleInputParser(WorldEdit worldEdit) { + super(worldEdit); + } + + /** + * The strings this parser matches + * + * @return the matching aliases + */ + public abstract List getMatchedAliases(); + + @Override + public E parseFromInput(String input, ParserContext context) throws InputParseException { + if (!getMatchedAliases().contains(input)) { + return null; + } + + return parseFromSimpleInput(input, context); + } + + public abstract E parseFromSimpleInput(String input, ParserContext context) throws InputParseException; + + /** + * Gets the primary name of this matcher + * + * @return the primary match + */ + public String getPrimaryMatcher() { + return getMatchedAliases().get(0); + } + + @Override + public List getSuggestions() { + return Lists.newArrayList(getPrimaryMatcher()); + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/CommandScriptLoader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/CommandScriptLoader.java index 9a69fd48c..8aca17dd3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/CommandScriptLoader.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/CommandScriptLoader.java @@ -9,8 +9,9 @@ import com.google.common.base.Charsets; import com.google.common.io.CharStreams; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.command.BrushProcessor; -import com.sk89q.worldedit.extension.factory.DefaultMaskParser; -import com.sk89q.worldedit.extension.factory.HashTagPatternParser; +import com.sk89q.worldedit.extension.factory.parser.mask.DefaultMaskParser; +import com.sk89q.worldedit.extension.factory.parser.pattern.ClipboardPatternParser; +import com.sk89q.worldedit.extension.factory.parser.pattern.DefaultPatternParser; import com.sk89q.worldedit.extension.platform.CommandManager; import com.sk89q.worldedit.util.command.ProcessedCallable; import com.sk89q.worldedit.util.command.parametric.FunctionParametricCallable; @@ -75,7 +76,7 @@ public class CommandScriptLoader { } return; case "patterns": - parser = FaweAPI.getParser(HashTagPatternParser.class); + parser = FaweAPI.getParser(DefaultPatternParser.class); break; case "masks": parser = FaweAPI.getParser(DefaultMaskParser.class);