From ee59dec3d8cb4d78be0525531c0a93f3d02f19bf Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Wed, 7 Aug 2019 10:13:07 +1000 Subject: [PATCH] comments / minor compiling --- .../main/java/com/boydti/fawe/FaweCache.java | 9 + .../java/com/boydti/fawe/beta/IChunk.java | 32 +++- .../com/boydti/fawe/beta/IQueueExtent.java | 60 ++++++- .../implementation/blocks/BitSetBlocks.java | 4 +- .../implementation/holder/ChunkHolder.java | 48 +++++- .../com/boydti/fawe/command/FaweParser.java | 6 +- .../brush/visualization/VisualChunk.java | 3 +- .../brush/visualization/VisualExtent.java | 94 ++++------- .../worldedit/command/tool/BrushTool.java | 7 +- .../factory/DefaultTransformParser.java | 94 ++++++----- .../parser/mask/DefaultMaskParser.java | 71 ++++---- .../parser/pattern/DefaultPatternParser.java | 156 +++++++++--------- 12 files changed, 336 insertions(+), 248 deletions(-) diff --git a/worldedit-core/src/main/java/com/boydti/fawe/FaweCache.java b/worldedit-core/src/main/java/com/boydti/fawe/FaweCache.java index 7742f5dda..0e2606fe9 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/FaweCache.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/FaweCache.java @@ -60,6 +60,7 @@ public final class FaweCache implements Trimable { MUTABLE_VECTOR3.clean(); MUTABLE_BLOCKVECTOR3.clean(); + SECTION_BITS_TO_CHAR.clean(); return false; } @@ -72,6 +73,14 @@ public final class FaweCache implements Trimable { } }; + public static final IterableThreadLocal SECTION_BITS_TO_CHAR = new IterableThreadLocal() { + @Override + public char[] init() { + char[] result = new char[4096]; + return result; + } + }; + public static final IterableThreadLocal PALETTE_TO_BLOCK = new IterableThreadLocal() { @Override public int[] init() { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/IChunk.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/IChunk.java index 0d6f4e211..f2af58deb 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/IChunk.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/IChunk.java @@ -19,17 +19,30 @@ public interface IChunk> extends Trimable, Callable, IChu /** * Initialize at the location - * + * (allows for reuse) + * - It's expected initialization will clear any set fields * @param extent * @param x * @param z */ void init(IQueueExtent extent, int x, int z); + /** + * Get the queue + * @return + */ IQueueExtent getQueue(); + /** + * Get chunkX + * @return + */ int getX(); + /** + * Get chunkZ + * @return + */ int getZ(); /** @@ -53,14 +66,14 @@ public interface IChunk> extends Trimable, Callable, IChu *

The future returned may return another future. To ensure completion keep calling {@link * Future#get()} on each result.

* - * @return Futures + * @return Future */ @Override T call(); /** * Call and join - * + * - Should be done async, if at all * @throws ExecutionException * @throws InterruptedException */ @@ -73,7 +86,7 @@ public interface IChunk> extends Trimable, Callable, IChu } /** - * Filter + * Filter through all the blocks in the chunk * * @param filter the filter * @param block The filter block @@ -81,6 +94,13 @@ public interface IChunk> extends Trimable, Callable, IChu */ void filterBlocks(Filter filter, ChunkFilterBlock block, @Nullable Region region); + /** + * Flood through all the blocks in the chunk + * TODO not implemented + * @param flood + * @param mask + * @param block + */ void flood(Flood flood, FilterBlockMask mask, ChunkFilterBlock block); /* set - queues a change */ @@ -100,6 +120,10 @@ public interface IChunk> extends Trimable, Callable, IChu @Override CompoundTag getTag(int x, int y, int z); + /** + * Reset (defaults to just calling init) + * @return + */ @Override default IBlocks reset() { init(getQueue(), getX(), getZ()); diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/IQueueExtent.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/IQueueExtent.java index 38392ef74..d892d47f1 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/IQueueExtent.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/IQueueExtent.java @@ -2,6 +2,7 @@ package com.boydti.fawe.beta; import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.implementation.WorldChunkCache; +import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.biome.BiomeType; @@ -23,6 +24,22 @@ public interface IQueueExtent extends Flushable, Trimable, Extent { return true; } + /** + * Clear any block updates + * @param players + */ + default void clearBlockUpdates(Player... players) { + throw new UnsupportedOperationException("TODO NOT IMPLEMENTED"); + } + + /** + * Send all the chunks as block updates + * @param players + */ + default void sendBlockUpdates(Player... players) { + throw new UnsupportedOperationException("TODO NOT IMPLEMENTED"); + } + /** * Must ensure that it is enqueued with QueueHandler */ @@ -30,20 +47,33 @@ public interface IQueueExtent extends Flushable, Trimable, Extent { void enableQueue(); /** - * Must ensure it is not in the queue handler + * Must ensure it is not in the queue handler (i.e. does not change blocks in the world) */ @Override void disableQueue(); - void init(WorldChunkCache world); + + void init(WorldChunkCache world); // TODO NOT IMPLEMENTED replace with supplier /** - * Get the {@link WorldChunkCache} - * + * Get the cached get object + * - Faster than getting it using NMS and allows for wrapping + * @param x + * @param z + * @param supplier * @return */ IChunkGet getCachedGet(int x, int z, Supplier supplier); + /** + * Get the cached chunk set object + * @param x + * @param z + * @param supplier + * @return + */ + IChunkSet getCachedSet(int x, int z, Supplier supplier); + /** * Get the IChunk at a position (and cache it if it's not already) * @@ -61,6 +91,8 @@ public interface IQueueExtent extends Flushable, Trimable, Extent { */ > T submit(IChunk chunk); + // standard get / set + @Override default boolean setBlock(int x, int y, int z, BlockStateHolder state) { final IChunk chunk = getCachedChunk(x >> 4, z >> 4); @@ -126,11 +158,31 @@ public interface IQueueExtent extends Flushable, Trimable, Extent { @Override void flush(); + /** + * A filter block is used to iterate over blocks / positions + * - Essentially combines BlockVector3, Extent and BlockState functions in a way that avoids lookups + * @return + */ ChunkFilterBlock initFilterBlock(); + /** + * Number of chunks in queue + * @return + */ int size(); + /** + * @return If queue is empty + */ boolean isEmpty(); + /** + * Refresh a specific chunk with a bitMask (0 = default, 65535 = all block sections) + * Note: only 0 is guaranteed to send all tiles / entities + * Note: Only 65535 is guaranteed to send all blocks + * @param chunkX + * @param chunkZ + * @param bitMask + */ void sendChunk(int chunkX, int chunkZ, int bitMask); } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/BitSetBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/BitSetBlocks.java index 9303b4a44..eeb5412e0 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/BitSetBlocks.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/BitSetBlocks.java @@ -1,5 +1,6 @@ package com.boydti.fawe.beta.implementation.blocks; +import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.IChunkSet; import com.boydti.fawe.object.collection.MemBlockSet; import com.sk89q.jnbt.CompoundTag; @@ -59,7 +60,8 @@ public class BitSetBlocks implements IChunkSet { @Override public char[] getArray(int layer) { - + char[] arr = FaweCache.SECTION_BITS_TO_CHAR.get(); + } @Override diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/holder/ChunkHolder.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/holder/ChunkHolder.java index c966df483..a8a08c5d4 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/holder/ChunkHolder.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/holder/ChunkHolder.java @@ -22,7 +22,7 @@ import javax.annotation.Nullable; /** * An abstract {@link IChunk} class that implements basic get/set blocks */ -public abstract class ChunkHolder implements IChunk, Supplier { +public abstract class ChunkHolder implements IChunk { public static final IBlockDelegate BOTH = new IBlockDelegate() { @Override @@ -242,27 +242,61 @@ public abstract class ChunkHolder implements IChunk, Supplier { return set == null || set.isEmpty(); } + /** + * Get or create the settable part of this chunk + * @return + */ public final IChunkGet getOrCreateGet() { if (get == null) { - get = newGet(); + get = newWrappedGet(); } return get; } + /** + * Get or create the settable part of this chunk + * @return + */ public final IChunkSet getOrCreateSet() { if (set == null) { - set = set(); + set = newWrappedSet(); } return set; } - public IChunkSet set() { + /** + * Create the settable part of this chunk (defaults to a char array) + * @return + */ + public IChunkSet createSet() { return new CharSetBlocks(); } - private IChunkGet newGet() { + /** + * Create a wrapped set object + * - The purpose of wrapping is to allow different extents to intercept / alter behavior + * - E.g. caching, optimizations, filtering + * @return + */ + private IChunkSet newWrappedSet() { if (extent instanceof SingleThreadQueueExtent) { - IChunkGet newGet = extent.getCachedGet(chunkX, chunkZ, this); + IChunkSet newSet = extent.getCachedSet(chunkX, chunkZ, this::createSet); + if (newSet != null) { + return newSet; + } + } + return createSet(); + } + + /** + * Create a wrapped get object + * - The purpose of wrapping is to allow different extents to intercept / alter behavior + * - E.g. caching, optimizations, filtering + * @return + */ + private IChunkGet newWrappedGet() { + if (extent instanceof SingleThreadQueueExtent) { + IChunkGet newGet = extent.getCachedGet(chunkX, chunkZ, this::get); if (newGet != null) { return newGet; } @@ -270,6 +304,8 @@ public abstract class ChunkHolder implements IChunk, Supplier { return get(); } + public abstract IChunkGet get(); + @Override public void init(IQueueExtent extent, int chunkX, int chunkZ) { this.extent = extent; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/command/FaweParser.java b/worldedit-core/src/main/java/com/boydti/fawe/command/FaweParser.java index 0a81466a7..3c13b2b55 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/command/FaweParser.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/command/FaweParser.java @@ -12,17 +12,15 @@ import com.sk89q.worldedit.internal.registry.InputParser; import java.util.*; public abstract class FaweParser extends InputParser { - private final PlatformCommandManager platform; private final Class type; - protected FaweParser(WorldEdit worldEdit, PlatformCommandManager commandManager, Class type) { + protected FaweParser(WorldEdit worldEdit, Class type) { super(worldEdit); - this.platform = commandManager; this.type = type; } public PlatformCommandManager getPlatform() { - return platform; + return PlatformCommandManager.getInstance(); } public Class getType() { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualChunk.java b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualChunk.java index 0cdacbeca..3d0664404 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualChunk.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualChunk.java @@ -15,7 +15,6 @@ import java.util.concurrent.Future; * - Using a non transparent block can cause FPS lag */ public class VisualChunk extends ChunkHolder { - public static BlockState VISUALIZE_BLOCK = BlockTypes.BLACK_STAINED_GLASS.getDefaultState(); private final IChunk parent; private final VisualExtent extent; @@ -42,7 +41,7 @@ public class VisualChunk extends ChunkHolder { } @Override - public IChunkSet set() { + public IChunkSet createSet() { return new BitSetBlocks(VISUALIZE_BLOCK); } } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualExtent.java b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualExtent.java index 6c58fca9a..e133fec90 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualExtent.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualExtent.java @@ -5,30 +5,38 @@ import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.util.MathMan; import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.PassthroughExtent; +import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.biome.BiomeType; +import com.sk89q.worldedit.world.block.BlockID; +import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; +import com.sk89q.worldedit.world.block.BlockType; +import com.sk89q.worldedit.world.block.BlockTypes; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import javax.annotation.Nullable; import java.util.concurrent.Future; public class VisualExtent extends AbstractDelegateExtent { + public static final BlockType VISUALIZE_BLOCK_DEFAULT = BlockTypes.BLACK_STAINED_GLASS; + private final BlockType visualizeBlock; + private final Player player; - private final IQueueExtent queue; - private Long2ObjectMap chunks = new Long2ObjectOpenHashMap<>(); - - public VisualExtent(Extent parent, IQueueExtent queue) { - super(parent); - this.queue = queue; + public VisualExtent(IQueueExtent parent, Player player) { + this(parent, player, VISUALIZE_BLOCK_DEFAULT); } - public VisualChunk getChunk(int cx, int cz) { - return chunks.get(MathMan.pairInt(cx, cz)); + public VisualExtent(IQueueExtent parent, Player player, BlockType visualizeBlock) { + super(parent); + this.visualizeBlock = visualizeBlock; + this.player = player; } @Override @@ -38,68 +46,30 @@ public class VisualExtent extends AbstractDelegateExtent { @Override public boolean setBlock(int x, int y, int z, BlockStateHolder block) throws WorldEditException { - BlockStateHolder previous = super.getBlock(x, y, z); - int cx = x >> 4; - int cz = z >> 4; - long chunkPair = MathMan.pairInt(cx, cz); - VisualChunk chunk = chunks.get(chunkPair); - if (previous.equals(block)) { - if (chunk != null) { - chunk.unset(x, y, z); - } - return false; + if (block.getMaterial().isAir()) { + return super.setBlock(x, y, z, block); } else { - if (chunk == null) { - chunk = new VisualChunk(cx, cz); - chunks.put(chunkPair, chunk); - } - chunk.setBlock(x, y, z, block.getInternalId()); - return true; + return super.setBlock(x, y, z, visualizeBlock.getDefaultState()); } } + @Nullable + @Override + public Operation commit() { + IQueueExtent queue = (IQueueExtent) getExtent(); + queue.sendBlockUpdates(this.player); + return null; + } + @Override public boolean setBiome(BlockVector2 position, BiomeType biome) { // Do nothing return false; } - public void clear(VisualExtent other, FawePlayer... players) { - for (Long2ObjectMap.Entry entry : chunks.long2ObjectEntrySet()) { - long pair = entry.getLongKey(); - int cx = MathMan.unpairIntX(pair); - int cz = MathMan.unpairIntY(pair); - VisualChunk chunk = entry.getValue(); - final VisualChunk otherChunk = other != null ? other.getChunk(cx, cz) : null; - final IntFaweChunk newChunk = new NullQueueIntFaweChunk(cx, cz); - final int bx = cx << 4; - final int bz = cz << 4; - if (otherChunk == null) { - chunk.forEachQueuedBlock((localX, y, localZ, combined) -> { - combined = queue.getCombinedId4Data(bx + localX, y, bz + localZ, 0); - newChunk.setBlock(localX, y, localZ, combined); - }); - } else { - chunk.forEachQueuedBlock((localX, y, localZ, combined) -> { - if (combined != otherChunk.getBlockCombinedId(localX, y, localZ)) { - combined = queue.getCombinedId4Data(bx + localX, y, bz + localZ, 0); - newChunk.setBlock(localX, y, localZ, combined); - } - }); - } - if (newChunk.getTotalCount() != 0) { - queue.sendBlockUpdate(newChunk, players); - } - } + public void clear() { + IQueueExtent queue = (IQueueExtent) getExtent(); + queue.clearBlockUpdates(player); + queue.cancel(); } - - public void visualize(FawePlayer players) { - for (VisualChunk chunk : chunks.values()) { - queue.sendBlockUpdate(chunk, players); - } - } - - public Future sendChunkUpdate(VisualChunk visualChunk) { - return null; // TODO NOT IMPLEMENTED - } -} +} \ No newline at end of file diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java index dff89da9d..21cb2136c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java @@ -652,14 +652,13 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool .changeSetNull() .combineStages(false); EditSession editSession = builder.build(); - - VisualExtent newVisualExtent = new VisualExtent(builder.getExtent(), builder.getQueue()); + VisualExtent newVisualExtent = new VisualExtent(editSession, player); BlockVector3 position = getPosition(editSession, player); if (position != null) { editSession.setExtent(newVisualExtent); switch (mode) { case POINT: - editSession.setBlock(position, VisualChunk.VISUALIZE_BLOCK); + editSession.setBlock(position, VisualExtent.VISUALIZE_BLOCK_DEFAULT); break; case OUTLINE: { new PatternTraverser(current).reset(editSession); @@ -670,7 +669,7 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool } if (visualExtent != null) { // clear old data - visualExtent.clear(newVisualExtent, fp); + visualExtent.clear(newVisualExtent, player); } visualExtent = newVisualExtent; newVisualExtent.visualize(fp); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/DefaultTransformParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/DefaultTransformParser.java index 6bb6cd222..0626d4a33 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/DefaultTransformParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/DefaultTransformParser.java @@ -1,11 +1,13 @@ package com.sk89q.worldedit.extension.factory; import com.boydti.fawe.command.FaweParser; +import com.boydti.fawe.command.SuggestInputParseException; import com.boydti.fawe.object.extent.MultiTransform; import com.boydti.fawe.object.extent.RandomTransform; import com.boydti.fawe.object.extent.ResettableExtent; import com.boydti.fawe.object.random.TrueRandom; import com.boydti.fawe.util.StringMan; +import com.google.common.collect.Iterables; import com.sk89q.minecraft.util.commands.CommandLocals; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.command.TransformCommands; @@ -22,16 +24,7 @@ import java.util.Map; public class DefaultTransformParser extends FaweParser { public DefaultTransformParser(WorldEdit worldEdit) { - super(worldEdit); - this.register(new TransformCommands()); - } - - - public void register(Object clazz) { - ParametricBuilder builder = new ParametricBuilder(); - builder.setAuthorizer(new ActorAuthorizer()); - builder.addBinding(new WorldEditBinding(worldEdit)); - builder.registerMethodsAsCommands(dispatcher, clazz); + super(worldEdit, ResettableExtent.class); } @Override @@ -57,49 +50,54 @@ public class DefaultTransformParser extends FaweParser { double chance = 1; if (command.isEmpty()) { transform = parseFromInput(StringMan.join(entry.getValue(), ','), context); - } else if (dispatcher.get(command) == null) { - // Legacy syntax - int percentIndex = command.indexOf('%'); - if (percentIndex != -1) { // Legacy percent pattern - chance = Expression.compile(command.substring(0, percentIndex)).evaluate(); - command = command.substring(percentIndex + 1); - if (!entry.getValue().isEmpty()) { - if (!command.isEmpty()) command += " "; - command += StringMan.join(entry.getValue(), " "); - } - transform = parseFromInput(command, context); - } else { - throw new NoMatchException("See: //transforms"); - } } else { List args = entry.getValue(); - if (!args.isEmpty()) { - command += " " + StringMan.join(args, " "); + String cmdArgs = ((args.isEmpty()) ? "" : " " + StringMan.join(args, " ")); + try { + transform = Iterables.getFirst(parse(cmdArgs, actor), null); + } catch (SuggestInputParseException rethrow) { + throw rethrow; + } catch (Throwable e) { + throw new NoMatchException("See: //transforms"); } - transform = (ResettableExtent) dispatcher.call(command, locals, new String[0]); - } - if (pe.and) { // & - intersectionChances.add(chance); - intersection.add(transform); - } else { - if (!intersection.isEmpty()) { - if (intersection.size() == 1) { - throw new InputParseException("Error, floating &"); + if (transform == null) { + // Legacy syntax + int percentIndex = command.indexOf('%'); + if (percentIndex != -1) { // Legacy percent pattern + chance = Expression.compile(command.substring(0, percentIndex)).evaluate(); + command = command.substring(percentIndex + 1); + if (!entry.getValue().isEmpty()) { + if (!command.isEmpty()) command += " "; + command += StringMan.join(entry.getValue(), " "); + } + transform = parseFromInput(command, context); + } else { + throw new NoMatchException("See: //transforms"); } - MultiTransform multi = new MultiTransform(); - double total = 0; - for (int i = 0; i < intersection.size(); i++) { - Double value = intersectionChances.get(i); - total += value; - multi.add(intersection.get(i), value); - } - union.add(multi); - unionChances.add(total); - intersection.clear(); - intersectionChances.clear(); } - unionChances.add(chance); - union.add(transform); + if (pe.and) { // & + intersectionChances.add(chance); + intersection.add(transform); + } else { + if (!intersection.isEmpty()) { + if (intersection.size() == 1) { + throw new InputParseException("Error, floating &"); + } + MultiTransform multi = new MultiTransform(); + double total = 0; + for (int i = 0; i < intersection.size(); i++) { + Double value = intersectionChances.get(i); + total += value; + multi.add(intersection.get(i), value); + } + union.add(multi); + unionChances.add(total); + intersection.clear(); + intersectionChances.clear(); + } + unionChances.add(chance); + union.add(transform); + } } } } catch (Throwable e) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/DefaultMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/DefaultMaskParser.java index 33b4b3db4..dd005f6b5 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/DefaultMaskParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/DefaultMaskParser.java @@ -48,8 +48,8 @@ import java.util.stream.Collectors; import java.util.stream.Stream; public class DefaultMaskParser extends FaweParser { - public DefaultMaskParser(WorldEdit worldEdit, PlatformCommandManager manager) { - super(worldEdit, manager, Mask.class); + public DefaultMaskParser(WorldEdit worldEdit) { + super(worldEdit, Mask.class); } @Override @@ -73,12 +73,40 @@ public class DefaultMaskParser extends FaweParser { ParseEntry pe = entry.getKey(); final String command = pe.input; String full = pe.full; - Mask mask; + Mask mask = null; if (command.isEmpty()) { mask = parseFromInput(StringMan.join(entry.getValue(), ','), context); } else { - mask = Iterables.getFirst(parse(input, actor), null); - SuggestInputParseException suggestion = null; // TODO NOT IMPLEMENTED suggestion + List args = entry.getValue(); + String cmdArgs = ((args.isEmpty()) ? "" : " " + StringMan.join(args, " ")); + try { + mask = Iterables.getFirst(parse(cmdArgs, actor), null); + } catch (SuggestInputParseException rethrow) { + throw rethrow; + } catch (Throwable e) { + // TODO NOT IMPLEMENTED +// 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 = "[" + 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 (mask == null) { // Legacy patterns char char0 = command.charAt(0); @@ -87,7 +115,7 @@ public class DefaultMaskParser extends FaweParser { return parseFromInput(char0 + "[" + input.substring(1) + "]", context); } if (char0 == '#' || char0 == '?') { - throw suggestion; + // TODO NOT IMPLEMENTED // throw new SuggestInputParseException(new NoMatchException("Unknown mask: " + full + ", See: //masks"), full, // () -> { // if (full.length() == 1) return new ArrayList<>(dispatcher.getPrimaryAliases()); @@ -150,37 +178,6 @@ public class DefaultMaskParser extends FaweParser { } } } -// else { -// List args = entry.getValue(); -// String cmdArgs = ((args.isEmpty()) ? "" : " " + StringMan.join(args, " ")); -// try { -// mask = (Mask) 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 = "[" + 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 (pe.and) { masks.add(new ArrayList<>()); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/DefaultPatternParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/DefaultPatternParser.java index fe17e5c1a..1c828ab9e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/DefaultPatternParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/DefaultPatternParser.java @@ -24,6 +24,7 @@ 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.google.common.collect.Iterables; import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.minecraft.util.commands.CommandLocals; import com.sk89q.worldedit.WorldEdit; @@ -47,8 +48,8 @@ import java.util.stream.Stream; public class DefaultPatternParser extends FaweParser { - public DefaultPatternParser(WorldEdit worldEdit, PlatformCommandManager commandManager) { - super(worldEdit, commandManager, Pattern.class); + public DefaultPatternParser(WorldEdit worldEdit) { + super(worldEdit, Pattern.class); } @Override @@ -72,90 +73,93 @@ public class DefaultPatternParser extends FaweParser { 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(Locale.ROOT)) - ).collect(Collectors.toList()); - } - ); - } - - - if (charMask) { - if (char0 == '$') { - 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); - } - } - 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]); + pattern = Iterables.getFirst(parse(cmdArgs, actor), null); } 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 = "[" + StringMan.join(split, "][") + "]"; - suggestions.set(i, suggestion); - } + // TODO NOT IMPLEMENTED +// 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 = "[" + 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) { + // 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 == '#') { + // TODO NOT IMPLEMENTED +// 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(Locale.ROOT)) +// ).collect(Collectors.toList()); +// } +// ); + } + + + if (charMask) { + if (char0 == '$') { + 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); + } + } + 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"); } } - return suggestions; - } catch (CommandException e1) { - throw new InputParseException(e1.getMessage()); - } catch (Throwable e2) { - e2.printStackTrace(); - throw new InputParseException(e2.getMessage()); } - }); + } } } if (pattern != null) {