geforkt von Mirrors/FastAsyncWorldEdit
comments / minor compiling
Dieser Commit ist enthalten in:
Ursprung
3c626ef25a
Commit
ee59dec3d8
@ -60,6 +60,7 @@ public final class FaweCache implements Trimable {
|
|||||||
|
|
||||||
MUTABLE_VECTOR3.clean();
|
MUTABLE_VECTOR3.clean();
|
||||||
MUTABLE_BLOCKVECTOR3.clean();
|
MUTABLE_BLOCKVECTOR3.clean();
|
||||||
|
SECTION_BITS_TO_CHAR.clean();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,6 +73,14 @@ public final class FaweCache implements Trimable {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static final IterableThreadLocal<char[]> SECTION_BITS_TO_CHAR = new IterableThreadLocal<char[]>() {
|
||||||
|
@Override
|
||||||
|
public char[] init() {
|
||||||
|
char[] result = new char[4096];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public static final IterableThreadLocal<int[]> PALETTE_TO_BLOCK = new IterableThreadLocal<int[]>() {
|
public static final IterableThreadLocal<int[]> PALETTE_TO_BLOCK = new IterableThreadLocal<int[]>() {
|
||||||
@Override
|
@Override
|
||||||
public int[] init() {
|
public int[] init() {
|
||||||
|
@ -19,17 +19,30 @@ public interface IChunk<T extends Future<T>> extends Trimable, Callable<T>, IChu
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize at the location
|
* Initialize at the location
|
||||||
*
|
* (allows for reuse)
|
||||||
|
* - It's expected initialization will clear any set fields
|
||||||
* @param extent
|
* @param extent
|
||||||
* @param x
|
* @param x
|
||||||
* @param z
|
* @param z
|
||||||
*/
|
*/
|
||||||
void init(IQueueExtent extent, int x, int z);
|
void init(IQueueExtent extent, int x, int z);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the queue
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
IQueueExtent getQueue();
|
IQueueExtent getQueue();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get chunkX
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
int getX();
|
int getX();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get chunkZ
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
int getZ();
|
int getZ();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -53,14 +66,14 @@ public interface IChunk<T extends Future<T>> extends Trimable, Callable<T>, IChu
|
|||||||
* <p>The future returned may return another future. To ensure completion keep calling {@link
|
* <p>The future returned may return another future. To ensure completion keep calling {@link
|
||||||
* Future#get()} on each result.</p>
|
* Future#get()} on each result.</p>
|
||||||
*
|
*
|
||||||
* @return Futures
|
* @return Future
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
T call();
|
T call();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call and join
|
* Call and join
|
||||||
*
|
* - Should be done async, if at all
|
||||||
* @throws ExecutionException
|
* @throws ExecutionException
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
@ -73,7 +86,7 @@ public interface IChunk<T extends Future<T>> extends Trimable, Callable<T>, IChu
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter
|
* Filter through all the blocks in the chunk
|
||||||
*
|
*
|
||||||
* @param filter the filter
|
* @param filter the filter
|
||||||
* @param block The filter block
|
* @param block The filter block
|
||||||
@ -81,6 +94,13 @@ public interface IChunk<T extends Future<T>> extends Trimable, Callable<T>, IChu
|
|||||||
*/
|
*/
|
||||||
void filterBlocks(Filter filter, ChunkFilterBlock block, @Nullable Region region);
|
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);
|
void flood(Flood flood, FilterBlockMask mask, ChunkFilterBlock block);
|
||||||
|
|
||||||
/* set - queues a change */
|
/* set - queues a change */
|
||||||
@ -100,6 +120,10 @@ public interface IChunk<T extends Future<T>> extends Trimable, Callable<T>, IChu
|
|||||||
@Override
|
@Override
|
||||||
CompoundTag getTag(int x, int y, int z);
|
CompoundTag getTag(int x, int y, int z);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset (defaults to just calling init)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
default IBlocks reset() {
|
default IBlocks reset() {
|
||||||
init(getQueue(), getX(), getZ());
|
init(getQueue(), getX(), getZ());
|
||||||
|
@ -2,6 +2,7 @@ package com.boydti.fawe.beta;
|
|||||||
|
|
||||||
import com.boydti.fawe.FaweCache;
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.beta.implementation.WorldChunkCache;
|
import com.boydti.fawe.beta.implementation.WorldChunkCache;
|
||||||
|
import com.sk89q.worldedit.entity.Player;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
@ -23,6 +24,22 @@ public interface IQueueExtent extends Flushable, Trimable, Extent {
|
|||||||
return true;
|
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
|
* Must ensure that it is enqueued with QueueHandler
|
||||||
*/
|
*/
|
||||||
@ -30,20 +47,33 @@ public interface IQueueExtent extends Flushable, Trimable, Extent {
|
|||||||
void enableQueue();
|
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
|
@Override
|
||||||
void disableQueue();
|
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
|
* @return
|
||||||
*/
|
*/
|
||||||
IChunkGet getCachedGet(int x, int z, Supplier<IChunkGet> supplier);
|
IChunkGet getCachedGet(int x, int z, Supplier<IChunkGet> supplier);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the cached chunk set object
|
||||||
|
* @param x
|
||||||
|
* @param z
|
||||||
|
* @param supplier
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
IChunkSet getCachedSet(int x, int z, Supplier<IChunkSet> supplier);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the IChunk at a position (and cache it if it's not already)
|
* 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 extends Future<T>> T submit(IChunk<T> chunk);
|
<T extends Future<T>> T submit(IChunk<T> chunk);
|
||||||
|
|
||||||
|
// standard get / set
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default boolean setBlock(int x, int y, int z, BlockStateHolder state) {
|
default boolean setBlock(int x, int y, int z, BlockStateHolder state) {
|
||||||
final IChunk chunk = getCachedChunk(x >> 4, z >> 4);
|
final IChunk chunk = getCachedChunk(x >> 4, z >> 4);
|
||||||
@ -126,11 +158,31 @@ public interface IQueueExtent extends Flushable, Trimable, Extent {
|
|||||||
@Override
|
@Override
|
||||||
void flush();
|
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();
|
ChunkFilterBlock initFilterBlock();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of chunks in queue
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
int size();
|
int size();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return If queue is empty
|
||||||
|
*/
|
||||||
boolean isEmpty();
|
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);
|
void sendChunk(int chunkX, int chunkZ, int bitMask);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.boydti.fawe.beta.implementation.blocks;
|
package com.boydti.fawe.beta.implementation.blocks;
|
||||||
|
|
||||||
|
import com.boydti.fawe.FaweCache;
|
||||||
import com.boydti.fawe.beta.IChunkSet;
|
import com.boydti.fawe.beta.IChunkSet;
|
||||||
import com.boydti.fawe.object.collection.MemBlockSet;
|
import com.boydti.fawe.object.collection.MemBlockSet;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
@ -59,6 +60,7 @@ public class BitSetBlocks implements IChunkSet {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public char[] getArray(int layer) {
|
public char[] getArray(int layer) {
|
||||||
|
char[] arr = FaweCache.SECTION_BITS_TO_CHAR.get();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ import javax.annotation.Nullable;
|
|||||||
/**
|
/**
|
||||||
* An abstract {@link IChunk} class that implements basic get/set blocks
|
* An abstract {@link IChunk} class that implements basic get/set blocks
|
||||||
*/
|
*/
|
||||||
public abstract class ChunkHolder implements IChunk, Supplier<IChunkGet> {
|
public abstract class ChunkHolder implements IChunk {
|
||||||
|
|
||||||
public static final IBlockDelegate BOTH = new IBlockDelegate() {
|
public static final IBlockDelegate BOTH = new IBlockDelegate() {
|
||||||
@Override
|
@Override
|
||||||
@ -242,27 +242,61 @@ public abstract class ChunkHolder implements IChunk, Supplier<IChunkGet> {
|
|||||||
return set == null || set.isEmpty();
|
return set == null || set.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get or create the settable part of this chunk
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public final IChunkGet getOrCreateGet() {
|
public final IChunkGet getOrCreateGet() {
|
||||||
if (get == null) {
|
if (get == null) {
|
||||||
get = newGet();
|
get = newWrappedGet();
|
||||||
}
|
}
|
||||||
return get;
|
return get;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get or create the settable part of this chunk
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public final IChunkSet getOrCreateSet() {
|
public final IChunkSet getOrCreateSet() {
|
||||||
if (set == null) {
|
if (set == null) {
|
||||||
set = set();
|
set = newWrappedSet();
|
||||||
}
|
}
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IChunkSet set() {
|
/**
|
||||||
|
* Create the settable part of this chunk (defaults to a char array)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public IChunkSet createSet() {
|
||||||
return new CharSetBlocks();
|
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) {
|
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) {
|
if (newGet != null) {
|
||||||
return newGet;
|
return newGet;
|
||||||
}
|
}
|
||||||
@ -270,6 +304,8 @@ public abstract class ChunkHolder implements IChunk, Supplier<IChunkGet> {
|
|||||||
return get();
|
return get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract IChunkGet get();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(IQueueExtent extent, int chunkX, int chunkZ) {
|
public void init(IQueueExtent extent, int chunkX, int chunkZ) {
|
||||||
this.extent = extent;
|
this.extent = extent;
|
||||||
|
@ -12,17 +12,15 @@ import com.sk89q.worldedit.internal.registry.InputParser;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public abstract class FaweParser<T> extends InputParser<T> {
|
public abstract class FaweParser<T> extends InputParser<T> {
|
||||||
private final PlatformCommandManager platform;
|
|
||||||
private final Class<T> type;
|
private final Class<T> type;
|
||||||
|
|
||||||
protected FaweParser(WorldEdit worldEdit, PlatformCommandManager commandManager, Class<T> type) {
|
protected FaweParser(WorldEdit worldEdit, Class<T> type) {
|
||||||
super(worldEdit);
|
super(worldEdit);
|
||||||
this.platform = commandManager;
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlatformCommandManager getPlatform() {
|
public PlatformCommandManager getPlatform() {
|
||||||
return platform;
|
return PlatformCommandManager.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class<T> getType() {
|
public Class<T> getType() {
|
||||||
|
@ -15,7 +15,6 @@ import java.util.concurrent.Future;
|
|||||||
* - Using a non transparent block can cause FPS lag
|
* - Using a non transparent block can cause FPS lag
|
||||||
*/
|
*/
|
||||||
public class VisualChunk extends ChunkHolder {
|
public class VisualChunk extends ChunkHolder {
|
||||||
public static BlockState VISUALIZE_BLOCK = BlockTypes.BLACK_STAINED_GLASS.getDefaultState();
|
|
||||||
private final IChunk parent;
|
private final IChunk parent;
|
||||||
private final VisualExtent extent;
|
private final VisualExtent extent;
|
||||||
|
|
||||||
@ -42,7 +41,7 @@ public class VisualChunk extends ChunkHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IChunkSet set() {
|
public IChunkSet createSet() {
|
||||||
return new BitSetBlocks(VISUALIZE_BLOCK);
|
return new BitSetBlocks(VISUALIZE_BLOCK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,30 +5,38 @@ import com.boydti.fawe.object.FawePlayer;
|
|||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
|
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
|
import com.sk89q.worldedit.entity.Player;
|
||||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
import com.sk89q.worldedit.extent.PassthroughExtent;
|
import com.sk89q.worldedit.extent.PassthroughExtent;
|
||||||
|
import com.sk89q.worldedit.function.operation.Operation;
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
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.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.Long2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
public class VisualExtent extends AbstractDelegateExtent {
|
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;
|
public VisualExtent(IQueueExtent parent, Player player) {
|
||||||
private Long2ObjectMap<VisualChunk> chunks = new Long2ObjectOpenHashMap<>();
|
this(parent, player, VISUALIZE_BLOCK_DEFAULT);
|
||||||
|
|
||||||
public VisualExtent(Extent parent, IQueueExtent queue) {
|
|
||||||
super(parent);
|
|
||||||
this.queue = queue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public VisualChunk getChunk(int cx, int cz) {
|
public VisualExtent(IQueueExtent parent, Player player, BlockType visualizeBlock) {
|
||||||
return chunks.get(MathMan.pairInt(cx, cz));
|
super(parent);
|
||||||
|
this.visualizeBlock = visualizeBlock;
|
||||||
|
this.player = player;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -38,24 +46,19 @@ public class VisualExtent extends AbstractDelegateExtent {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBlock(int x, int y, int z, BlockStateHolder block) throws WorldEditException {
|
public boolean setBlock(int x, int y, int z, BlockStateHolder block) throws WorldEditException {
|
||||||
BlockStateHolder previous = super.getBlock(x, y, z);
|
if (block.getMaterial().isAir()) {
|
||||||
int cx = x >> 4;
|
return super.setBlock(x, y, z, block);
|
||||||
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;
|
|
||||||
} else {
|
} else {
|
||||||
if (chunk == null) {
|
return super.setBlock(x, y, z, visualizeBlock.getDefaultState());
|
||||||
chunk = new VisualChunk(cx, cz);
|
|
||||||
chunks.put(chunkPair, chunk);
|
|
||||||
}
|
}
|
||||||
chunk.setBlock(x, y, z, block.getInternalId());
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Operation commit() {
|
||||||
|
IQueueExtent queue = (IQueueExtent) getExtent();
|
||||||
|
queue.sendBlockUpdates(this.player);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -64,42 +67,9 @@ public class VisualExtent extends AbstractDelegateExtent {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear(VisualExtent other, FawePlayer... players) {
|
public void clear() {
|
||||||
for (Long2ObjectMap.Entry<VisualChunk> entry : chunks.long2ObjectEntrySet()) {
|
IQueueExtent queue = (IQueueExtent) getExtent();
|
||||||
long pair = entry.getLongKey();
|
queue.clearBlockUpdates(player);
|
||||||
int cx = MathMan.unpairIntX(pair);
|
queue.cancel();
|
||||||
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 visualize(FawePlayer players) {
|
|
||||||
for (VisualChunk chunk : chunks.values()) {
|
|
||||||
queue.sendBlockUpdate(chunk, players);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Future sendChunkUpdate(VisualChunk visualChunk) {
|
|
||||||
return null; // TODO NOT IMPLEMENTED
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -652,14 +652,13 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool
|
|||||||
.changeSetNull()
|
.changeSetNull()
|
||||||
.combineStages(false);
|
.combineStages(false);
|
||||||
EditSession editSession = builder.build();
|
EditSession editSession = builder.build();
|
||||||
|
VisualExtent newVisualExtent = new VisualExtent(editSession, player);
|
||||||
VisualExtent newVisualExtent = new VisualExtent(builder.getExtent(), builder.getQueue());
|
|
||||||
BlockVector3 position = getPosition(editSession, player);
|
BlockVector3 position = getPosition(editSession, player);
|
||||||
if (position != null) {
|
if (position != null) {
|
||||||
editSession.setExtent(newVisualExtent);
|
editSession.setExtent(newVisualExtent);
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case POINT:
|
case POINT:
|
||||||
editSession.setBlock(position, VisualChunk.VISUALIZE_BLOCK);
|
editSession.setBlock(position, VisualExtent.VISUALIZE_BLOCK_DEFAULT);
|
||||||
break;
|
break;
|
||||||
case OUTLINE: {
|
case OUTLINE: {
|
||||||
new PatternTraverser(current).reset(editSession);
|
new PatternTraverser(current).reset(editSession);
|
||||||
@ -670,7 +669,7 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool
|
|||||||
}
|
}
|
||||||
if (visualExtent != null) {
|
if (visualExtent != null) {
|
||||||
// clear old data
|
// clear old data
|
||||||
visualExtent.clear(newVisualExtent, fp);
|
visualExtent.clear(newVisualExtent, player);
|
||||||
}
|
}
|
||||||
visualExtent = newVisualExtent;
|
visualExtent = newVisualExtent;
|
||||||
newVisualExtent.visualize(fp);
|
newVisualExtent.visualize(fp);
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package com.sk89q.worldedit.extension.factory;
|
package com.sk89q.worldedit.extension.factory;
|
||||||
|
|
||||||
import com.boydti.fawe.command.FaweParser;
|
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.MultiTransform;
|
||||||
import com.boydti.fawe.object.extent.RandomTransform;
|
import com.boydti.fawe.object.extent.RandomTransform;
|
||||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||||
import com.boydti.fawe.object.random.TrueRandom;
|
import com.boydti.fawe.object.random.TrueRandom;
|
||||||
import com.boydti.fawe.util.StringMan;
|
import com.boydti.fawe.util.StringMan;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
import com.sk89q.minecraft.util.commands.CommandLocals;
|
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.command.TransformCommands;
|
import com.sk89q.worldedit.command.TransformCommands;
|
||||||
@ -22,16 +24,7 @@ import java.util.Map;
|
|||||||
public class DefaultTransformParser extends FaweParser<ResettableExtent> {
|
public class DefaultTransformParser extends FaweParser<ResettableExtent> {
|
||||||
|
|
||||||
public DefaultTransformParser(WorldEdit worldEdit) {
|
public DefaultTransformParser(WorldEdit worldEdit) {
|
||||||
super(worldEdit);
|
super(worldEdit, ResettableExtent.class);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -57,7 +50,17 @@ public class DefaultTransformParser extends FaweParser<ResettableExtent> {
|
|||||||
double chance = 1;
|
double chance = 1;
|
||||||
if (command.isEmpty()) {
|
if (command.isEmpty()) {
|
||||||
transform = parseFromInput(StringMan.join(entry.getValue(), ','), context);
|
transform = parseFromInput(StringMan.join(entry.getValue(), ','), context);
|
||||||
} else if (dispatcher.get(command) == null) {
|
} else {
|
||||||
|
List<String> args = entry.getValue();
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
if (transform == null) {
|
||||||
// Legacy syntax
|
// Legacy syntax
|
||||||
int percentIndex = command.indexOf('%');
|
int percentIndex = command.indexOf('%');
|
||||||
if (percentIndex != -1) { // Legacy percent pattern
|
if (percentIndex != -1) { // Legacy percent pattern
|
||||||
@ -71,12 +74,6 @@ public class DefaultTransformParser extends FaweParser<ResettableExtent> {
|
|||||||
} else {
|
} else {
|
||||||
throw new NoMatchException("See: //transforms");
|
throw new NoMatchException("See: //transforms");
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
List<String> args = entry.getValue();
|
|
||||||
if (!args.isEmpty()) {
|
|
||||||
command += " " + StringMan.join(args, " ");
|
|
||||||
}
|
|
||||||
transform = (ResettableExtent) dispatcher.call(command, locals, new String[0]);
|
|
||||||
}
|
}
|
||||||
if (pe.and) { // &
|
if (pe.and) { // &
|
||||||
intersectionChances.add(chance);
|
intersectionChances.add(chance);
|
||||||
@ -102,6 +99,7 @@ public class DefaultTransformParser extends FaweParser<ResettableExtent> {
|
|||||||
union.add(transform);
|
union.add(transform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
throw new InputParseException(e.getMessage(), e);
|
throw new InputParseException(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
@ -48,8 +48,8 @@ import java.util.stream.Collectors;
|
|||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class DefaultMaskParser extends FaweParser<Mask> {
|
public class DefaultMaskParser extends FaweParser<Mask> {
|
||||||
public DefaultMaskParser(WorldEdit worldEdit, PlatformCommandManager manager) {
|
public DefaultMaskParser(WorldEdit worldEdit) {
|
||||||
super(worldEdit, manager, Mask.class);
|
super(worldEdit, Mask.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -73,12 +73,40 @@ public class DefaultMaskParser extends FaweParser<Mask> {
|
|||||||
ParseEntry pe = entry.getKey();
|
ParseEntry pe = entry.getKey();
|
||||||
final String command = pe.input;
|
final String command = pe.input;
|
||||||
String full = pe.full;
|
String full = pe.full;
|
||||||
Mask mask;
|
Mask mask = null;
|
||||||
if (command.isEmpty()) {
|
if (command.isEmpty()) {
|
||||||
mask = parseFromInput(StringMan.join(entry.getValue(), ','), context);
|
mask = parseFromInput(StringMan.join(entry.getValue(), ','), context);
|
||||||
} else {
|
} else {
|
||||||
mask = Iterables.getFirst(parse(input, actor), null);
|
List<String> args = entry.getValue();
|
||||||
SuggestInputParseException suggestion = null; // TODO NOT IMPLEMENTED suggestion
|
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<String> 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) {
|
if (mask == null) {
|
||||||
// Legacy patterns
|
// Legacy patterns
|
||||||
char char0 = command.charAt(0);
|
char char0 = command.charAt(0);
|
||||||
@ -87,7 +115,7 @@ public class DefaultMaskParser extends FaweParser<Mask> {
|
|||||||
return parseFromInput(char0 + "[" + input.substring(1) + "]", context);
|
return parseFromInput(char0 + "[" + input.substring(1) + "]", context);
|
||||||
}
|
}
|
||||||
if (char0 == '#' || char0 == '?') {
|
if (char0 == '#' || char0 == '?') {
|
||||||
throw suggestion;
|
// TODO NOT IMPLEMENTED
|
||||||
// throw new SuggestInputParseException(new NoMatchException("Unknown mask: " + full + ", See: //masks"), full,
|
// throw new SuggestInputParseException(new NoMatchException("Unknown mask: " + full + ", See: //masks"), full,
|
||||||
// () -> {
|
// () -> {
|
||||||
// if (full.length() == 1) return new ArrayList<>(dispatcher.getPrimaryAliases());
|
// if (full.length() == 1) return new ArrayList<>(dispatcher.getPrimaryAliases());
|
||||||
@ -150,37 +178,6 @@ public class DefaultMaskParser extends FaweParser<Mask> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// else {
|
|
||||||
// List<String> 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<String> 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) {
|
if (pe.and) {
|
||||||
masks.add(new ArrayList<>());
|
masks.add(new ArrayList<>());
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import com.boydti.fawe.command.SuggestInputParseException;
|
|||||||
import com.boydti.fawe.config.BBC;
|
import com.boydti.fawe.config.BBC;
|
||||||
import com.boydti.fawe.object.random.TrueRandom;
|
import com.boydti.fawe.object.random.TrueRandom;
|
||||||
import com.boydti.fawe.util.StringMan;
|
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.CommandException;
|
||||||
import com.sk89q.minecraft.util.commands.CommandLocals;
|
import com.sk89q.minecraft.util.commands.CommandLocals;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
@ -47,8 +48,8 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
public class DefaultPatternParser extends FaweParser<Pattern> {
|
public class DefaultPatternParser extends FaweParser<Pattern> {
|
||||||
|
|
||||||
public DefaultPatternParser(WorldEdit worldEdit, PlatformCommandManager commandManager) {
|
public DefaultPatternParser(WorldEdit worldEdit) {
|
||||||
super(worldEdit, commandManager, Pattern.class);
|
super(worldEdit, Pattern.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -72,7 +73,38 @@ public class DefaultPatternParser extends FaweParser<Pattern> {
|
|||||||
double chance = 1;
|
double chance = 1;
|
||||||
if (command.isEmpty()) {
|
if (command.isEmpty()) {
|
||||||
pattern = parseFromInput(StringMan.join(entry.getValue(), ','), context);
|
pattern = parseFromInput(StringMan.join(entry.getValue(), ','), context);
|
||||||
} else if (dispatcher.get(command) == null) {
|
} else {
|
||||||
|
List<String> args = entry.getValue();
|
||||||
|
String cmdArgs = ((args.isEmpty()) ? "" : " " + StringMan.join(args, " "));
|
||||||
|
try {
|
||||||
|
pattern = Iterables.getFirst(parse(cmdArgs, actor), null);
|
||||||
|
} catch (SuggestInputParseException rethrow) {
|
||||||
|
throw rethrow;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
// TODO NOT IMPLEMENTED
|
||||||
|
// throw SuggestInputParseException.of(e, full, () -> {
|
||||||
|
// try {
|
||||||
|
// List<String> 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
|
// Legacy patterns
|
||||||
char char0 = command.charAt(0);
|
char char0 = command.charAt(0);
|
||||||
boolean charMask = input.length() > 1 && input.charAt(1) != '[';
|
boolean charMask = input.length() > 1 && input.charAt(1) != '[';
|
||||||
@ -80,14 +112,15 @@ public class DefaultPatternParser extends FaweParser<Pattern> {
|
|||||||
return parseFromInput(char0 + "[" + input.substring(1) + "]", context);
|
return parseFromInput(char0 + "[" + input.substring(1) + "]", context);
|
||||||
}
|
}
|
||||||
if (char0 == '#') {
|
if (char0 == '#') {
|
||||||
throw new SuggestInputParseException(new NoMatchException("Unknown pattern: " + full + ", See: //patterns"), full,
|
// 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(
|
// if (full.length() == 1) return new ArrayList<>(dispatcher.getPrimaryAliases());
|
||||||
s -> s.startsWith(command.toLowerCase(Locale.ROOT))
|
// return dispatcher.getAliases().stream().filter(
|
||||||
).collect(Collectors.toList());
|
// s -> s.startsWith(command.toLowerCase(Locale.ROOT))
|
||||||
}
|
// ).collect(Collectors.toList());
|
||||||
);
|
// }
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -127,35 +160,6 @@ public class DefaultPatternParser extends FaweParser<Pattern> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
List<String> 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<String> 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) {
|
if (pattern != null) {
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren