From 0b1a36bb7dbfd136fec82f68a7019a28f6bdd79b Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Sat, 16 Nov 2019 00:20:14 +0000 Subject: [PATCH] WIP VisualExtent --- .../sk89q/worldedit/bukkit/BukkitWorld.java | 4 + .../com/boydti/fawe/beta/CombinedBlocks.java | 135 ++++++++++++++++++ .../com/boydti/fawe/beta/IBatchProcessor.java | 2 + .../java/com/boydti/fawe/beta/IBlocks.java | 8 +- .../implementation/chunk/ChunkHolder.java | 2 + .../implementation/packet/ChunkPacket.java | 3 +- .../processors/BatchProcessorHolder.java | 5 + .../processors/ChunkSendProcessor.java | 35 ++++- .../processors/MultiBatchProcessor.java | 5 + .../PersistentChunkSendProcessor.java | 61 ++++++++ .../rollback/RollbackOptimizedHistory.java | 15 +- .../com/boydti/fawe/object/NullChangeSet.java | 4 +- .../changeset/AbstractDelegateChangeSet.java | 20 ++- .../fawe/object/changeset/CFIChangeSet.java | 8 +- .../object/changeset/DiskStorageHistory.java | 10 +- .../fawe/object/changeset/FaweChangeSet.java | 27 ++-- .../object/changeset/FaweStreamChangeSet.java | 2 +- .../changeset/MemoryOptimizedHistory.java | 8 +- .../java/com/sk89q/worldedit/EditSession.java | 8 +- .../com/sk89q/worldedit/LocalSession.java | 7 +- .../worldedit/command/BrushCommands.java | 8 +- .../worldedit/command/RegionCommands.java | 51 +++---- .../worldedit/command/tool/BrushTool.java | 6 +- 23 files changed, 339 insertions(+), 95 deletions(-) create mode 100644 worldedit-core/src/main/java/com/boydti/fawe/beta/CombinedBlocks.java create mode 100644 worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/processors/PersistentChunkSendProcessor.java diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index 7f48435dd..0fc65b847 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -22,7 +22,10 @@ package com.sk89q.worldedit.bukkit; import static com.google.common.base.Preconditions.checkNotNull; import com.boydti.fawe.Fawe; +import com.boydti.fawe.beta.IBlocks; +import com.boydti.fawe.beta.IChunk; import com.boydti.fawe.beta.IChunkGet; +import com.boydti.fawe.beta.IQueueExtent; import com.boydti.fawe.beta.implementation.packet.ChunkPacket; import com.boydti.fawe.bukkit.FaweBukkit; import com.boydti.fawe.bukkit.adapter.mc1_14.BukkitGetBlocks_1_14; @@ -55,6 +58,7 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.function.Supplier; import javax.annotation.Nullable; import io.papermc.lib.PaperLib; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/CombinedBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/CombinedBlocks.java new file mode 100644 index 000000000..95d4dfca1 --- /dev/null +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/CombinedBlocks.java @@ -0,0 +1,135 @@ +package com.boydti.fawe.beta; + +import com.boydti.fawe.FaweCache; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.world.biome.BiomeType; +import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockType; +import com.sk89q.worldedit.world.block.BlockTypes; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class CombinedBlocks implements IBlocks { + private final IBlocks secondary; + private final IBlocks primary; + private final int addMask; + + /** + * @param secondary + * @param primary + * @param addMask - bitMask for force sending sections, else 0 to send the primary ones + */ + public CombinedBlocks(IBlocks secondary, IBlocks primary, int addMask) { + this.secondary = secondary; + this.primary = primary; + this.addMask = addMask; + } + + @Override + public int getBitMask() { + int bitMask = addMask; + for (int layer = 0; layer < FaweCache.IMP.CHUNK_LAYERS; layer++) { + if (primary.hasSection(layer)) { + bitMask |= (1 << layer); + } + } + return bitMask; + } + + @Override + public boolean hasSection(int layer) { + return primary.hasSection(layer) || secondary.hasSection(layer); + } + + @Override + public char[] load(int layer) { + if (primary.hasSection(layer)) { + char[] blocks = primary.load(layer); + if (secondary.hasSection(layer)) { + int i = 0; + for (; i < 4096; i++) { + if (blocks[i] == 0) { + break; + } + } + if (i != 4096) { + char[] fallback = secondary.load(layer); + for (; i < 4096; i++) { + if (blocks[i] == 0) { + blocks[i] = fallback[i]; + } + } + } + } + return blocks; + } + return secondary.load(layer); + } + + @Override + public BlockState getBlock(int x, int y, int z) { + BlockState block = primary.getBlock(x, y, z); + if (block == null) { + return secondary.getBlock(x, y, z); + } + return BlockTypes.__RESERVED__.getDefaultState(); + } + + @Override + public Map getTiles() { + Map tiles = primary.getTiles(); + if (tiles.isEmpty()) { + return secondary.getTiles(); + } + Map otherTiles = secondary.getTiles(); + if (!otherTiles.isEmpty()) { + HashMap copy = null; + for (Map.Entry entry : otherTiles.entrySet()) { + BlockVector3 pos = entry.getKey(); + BlockState block = primary.getBlock(pos.getX(), pos.getY(), pos.getZ()); + if (block.getBlockType() == BlockTypes.__RESERVED__) { + if (copy == null) copy = new HashMap<>(tiles); + copy.put(pos, entry.getValue()); + } + } + if (copy != null) return copy; + } + return tiles; + } + + @Override + public Set getEntities() { + Set ents1 = primary.getEntities(); + Set ents2 = secondary.getEntities(); + if (ents1.isEmpty()) return ents2; + if (ents2.isEmpty()) return ents1; + HashSet joined = new HashSet<>(ents1); + joined.addAll(ents2); + return joined; + } + + @Override + public BiomeType getBiomeType(int x, int z) { + BiomeType biome = primary.getBiomeType(x, z); + if (biome == null) { + return secondary.getBiomeType(x, z); + } + return biome; + } + + @Override + public IBlocks reset() { + return null; + } + + @Override + public boolean trim(boolean aggressive) { + return false; + } +} diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/IBatchProcessor.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/IBatchProcessor.java index b584d2a40..910d286dc 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/IBatchProcessor.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/IBatchProcessor.java @@ -101,6 +101,8 @@ public interface IBatchProcessor { return MultiBatchProcessor.of(this, other); } + default void flush() {} + /** * Return a new processor after removing all are instances of a specified class * @param clazz diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/IBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/IBlocks.java index b7d6ee80b..0c242f620 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/IBlocks.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/IBlocks.java @@ -45,11 +45,11 @@ public interface IBlocks extends Trimable { IBlocks reset(); - default byte[] toByteArray(boolean writeBiomes) { - return toByteArray(null, writeBiomes); + default byte[] toByteArray(int bitMask) { + return toByteArray(null, bitMask); } - default byte[] toByteArray(byte[] buffer, boolean writeBiomes) { + default byte[] toByteArray(byte[] buffer, int bitMask) { if (buffer == null) { buffer = new byte[1024]; } @@ -138,7 +138,7 @@ public interface IBlocks extends Trimable { // } // } // } - if (writeBiomes) { + if (bitMask == Character.MAX_VALUE) { for (int z = 0; z < 16; z++) { for (int x = 0; x < 16; x++) { BiomeType biome = getBiomeType(x, z); diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/chunk/ChunkHolder.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/chunk/ChunkHolder.java index 5369b415f..05dc69ab1 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/chunk/ChunkHolder.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/chunk/ChunkHolder.java @@ -1,6 +1,8 @@ package com.boydti.fawe.beta.implementation.chunk; import com.boydti.fawe.FaweCache; +import com.boydti.fawe.beta.CombinedBlocks; +import com.boydti.fawe.beta.IBlocks; import com.boydti.fawe.beta.IQueueChunk; import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock; import com.boydti.fawe.beta.Filter; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/packet/ChunkPacket.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/packet/ChunkPacket.java index bc412cb1c..6fcfefa48 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/packet/ChunkPacket.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/packet/ChunkPacket.java @@ -62,7 +62,8 @@ public class ChunkPacket implements Function, Supplier { if (tmp == null) { synchronized (this) { if (sectionBytes == null) { - sectionBytes = getChunk().toByteArray(FaweCache.IMP.BYTE_BUFFER_8192.get(), this.full); + IBlocks tmpChunk = getChunk(); + sectionBytes = tmpChunk.toByteArray(FaweCache.IMP.BYTE_BUFFER_8192.get(), tmpChunk.getBitMask()); } tmp = sectionBytes; } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/processors/BatchProcessorHolder.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/processors/BatchProcessorHolder.java index b358cb638..be64c28ea 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/processors/BatchProcessorHolder.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/processors/BatchProcessorHolder.java @@ -19,6 +19,11 @@ public class BatchProcessorHolder implements IBatchProcessorHolder { return getProcessor().processSet(chunk, get, set); } + @Override + public void flush() { + getProcessor().flush(); + } + @Override public void setProcessor(IBatchProcessor set) { this.processor = set; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/processors/ChunkSendProcessor.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/processors/ChunkSendProcessor.java index 6c3d20371..687d358af 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/processors/ChunkSendProcessor.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/processors/ChunkSendProcessor.java @@ -1,6 +1,8 @@ package com.boydti.fawe.beta.implementation.processors; +import com.boydti.fawe.beta.CombinedBlocks; import com.boydti.fawe.beta.IBatchProcessor; +import com.boydti.fawe.beta.IBlocks; import com.boydti.fawe.beta.IChunk; import com.boydti.fawe.beta.IChunkGet; import com.boydti.fawe.beta.IChunkSet; @@ -16,18 +18,41 @@ import java.util.stream.Stream; public class ChunkSendProcessor implements IBatchProcessor { private final Supplier> players; private final World world; + private final boolean full; public ChunkSendProcessor(World world, Supplier> players) { + this(world, players, false); + } + + public ChunkSendProcessor(World world, Supplier> players, boolean full) { this.players = players; this.world = world; + this.full = full; + } + + public World getWorld() { + return world; + } + + public Supplier> getPlayers() { + return players; } @Override public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) { int chunkX = chunk.getX(); int chunkZ = chunk.getZ(); - boolean replaceAll = set.hasBiomes(); - ChunkPacket packet = new ChunkPacket(chunkX, chunkZ, () -> set, replaceAll); + IBlocks blocks; + boolean full = this.full; + if (full) { + blocks = set; + } else { + blocks = combine(chunk, get, set); + if (set.hasBiomes()) { + full = true; + } + } + ChunkPacket packet = new ChunkPacket(chunkX, chunkZ, () -> blocks, full); Stream stream = this.players.get(); if (stream == null) { world.sendFakeChunk(null, packet); @@ -38,8 +63,12 @@ public class ChunkSendProcessor implements IBatchProcessor { return set; } + public IBlocks combine(IChunk chunk, IChunkGet get, IChunkSet set) { + return new CombinedBlocks(get, set, 0); + } + @Override public Extent construct(Extent child) { - return null; + throw new UnsupportedOperationException("Processing only"); } } \ No newline at end of file diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/processors/MultiBatchProcessor.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/processors/MultiBatchProcessor.java index 5cb13fd8f..187ec7ecc 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/processors/MultiBatchProcessor.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/processors/MultiBatchProcessor.java @@ -106,6 +106,11 @@ public class MultiBatchProcessor implements IBatchProcessor { return this; } + @Override + public void flush() { + for (IBatchProcessor processor : this.processors) processor.flush(); + } + @Override public String toString() { return super.toString() + "{" + StringMan.join(processors, ",") + "}"; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/processors/PersistentChunkSendProcessor.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/processors/PersistentChunkSendProcessor.java new file mode 100644 index 000000000..112cf28ff --- /dev/null +++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/processors/PersistentChunkSendProcessor.java @@ -0,0 +1,61 @@ +package com.boydti.fawe.beta.implementation.processors; + +import com.boydti.fawe.Fawe; +import com.boydti.fawe.beta.CombinedBlocks; +import com.boydti.fawe.beta.IBlocks; +import com.boydti.fawe.beta.IChunk; +import com.boydti.fawe.beta.IChunkGet; +import com.boydti.fawe.beta.IChunkSet; +import com.boydti.fawe.beta.IQueueExtent; +import com.boydti.fawe.beta.implementation.packet.ChunkPacket; +import com.boydti.fawe.util.MathMan; +import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.math.BlockVector2; +import com.sk89q.worldedit.world.World; +import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; + +import java.util.function.Supplier; +import java.util.stream.Stream; + +public class PersistentChunkSendProcessor extends ChunkSendProcessor { + private Long2ObjectLinkedOpenHashMap current; + private Long2ObjectLinkedOpenHashMap previous; + + public PersistentChunkSendProcessor(World world, IQueueExtent queue, PersistentChunkSendProcessor previous, Supplier> players) { + super(world, players); + this.current = new Long2ObjectLinkedOpenHashMap<>(); + this.previous = previous.current; + } + + @Override + public IBlocks combine(IChunk chunk, IChunkGet get, IChunkSet set) { + int chunkX = chunk.getX(); + int chunkZ = chunk.getZ(); + long pair = MathMan.pairInt(chunkX, chunkZ); + Character bitMask = (char) (set.hasBiomes() ? Character.MAX_VALUE : set.getBitMask()); + current.put(pair, bitMask); + Character lastValue = previous.remove(pair); + return new CombinedBlocks(get, set, lastValue == null ? 0 : lastValue); + } + + public void flush(IQueueExtent extent) { + if (!previous.isEmpty()) { + Stream players = getPlayers().get(); + for (Long2ObjectMap.Entry entry : previous.long2ObjectEntrySet()) { + long pair = entry.getLongKey(); + int chunkX = MathMan.unpairIntX(pair); + int chunkZ = MathMan.unpairIntY(pair); + BlockVector2 pos = BlockVector2.at(chunkX, chunkZ); + Supplier chunk = () -> extent.getOrCreateChunk(pos.getX(), pos.getZ()); + ChunkPacket packet = new ChunkPacket(pos.getX(), pos.getZ(), chunk, true); + char bitMask = entry.getValue(); + if (players == null) { + getWorld().sendFakeChunk(null, packet); + } else { + players.forEach(player -> getWorld().sendFakeChunk(player, packet)); + } + } + } + } +} diff --git a/worldedit-core/src/main/java/com/boydti/fawe/logging/rollback/RollbackOptimizedHistory.java b/worldedit-core/src/main/java/com/boydti/fawe/logging/rollback/RollbackOptimizedHistory.java index 78351c6b7..17c5cddfe 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/logging/rollback/RollbackOptimizedHistory.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/logging/rollback/RollbackOptimizedHistory.java @@ -82,16 +82,13 @@ public class RollbackOptimizedHistory extends DiskStorageHistory { } @Override - public boolean close() { - if (super.close()) { - // Save to DB - RollbackDatabase db = DBHandler.IMP.getDatabase(getWorld()); - if (db != null) { - db.logEdit(this); - } - return true; + public void close() throws IOException { + super.close(); + // Save to DB + RollbackDatabase db = DBHandler.IMP.getDatabase(getWorld()); + if (db != null) { + db.logEdit(this); } - return false; } @Override diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/NullChangeSet.java b/worldedit-core/src/main/java/com/boydti/fawe/object/NullChangeSet.java index 2305da096..08316f554 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/NullChangeSet.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/NullChangeSet.java @@ -19,9 +19,7 @@ public class NullChangeSet extends FaweChangeSet { } @Override - public final boolean close() { - return false; - } + public final void close() {} @Override public final void add(int x, int y, int z, int combinedFrom, int combinedTo) { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractDelegateChangeSet.java b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractDelegateChangeSet.java index b65bb501d..51f557cf0 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractDelegateChangeSet.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/AbstractDelegateChangeSet.java @@ -13,6 +13,8 @@ import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; + +import java.io.IOException; import java.util.Iterator; import java.util.UUID; import java.util.concurrent.Future; @@ -32,18 +34,18 @@ public class AbstractDelegateChangeSet extends FaweChangeSet { } @Override - public boolean closeAsync() { - return parent.closeAsync(); + public void closeAsync() { + parent.closeAsync(); } @Override - public boolean flush() { - return parent.flush(); + public void flush() { + parent.flush(); } @Override - public boolean close() { - return super.close() && parent.close(); + public void close() throws IOException { + parent.close(); } public final FaweChangeSet getParent() { @@ -60,12 +62,6 @@ public class AbstractDelegateChangeSet extends FaweChangeSet { return parent.getWorld(); } - @Override - @Deprecated - public boolean flushAsync() { - return parent.flushAsync(); - } - @Override public void add(int x, int y, int z, int combinedFrom, int combinedTo) { parent.add(x, y, z, combinedFrom, combinedTo); diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/CFIChangeSet.java b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/CFIChangeSet.java index debca3057..cc71a6930 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/CFIChangeSet.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/CFIChangeSet.java @@ -30,14 +30,10 @@ public class CFIChangeSet extends FaweChangeSet { } @Override - public boolean close() { - return true; - } + public void close() {} @Override - public boolean closeAsync() { - return true; - } + public void closeAsync() {} @Override public void add(int x, int y, int z, int combinedFrom, int combinedTo) { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/DiskStorageHistory.java b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/DiskStorageHistory.java index d594d07d4..b16d36266 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/DiskStorageHistory.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/DiskStorageHistory.java @@ -173,10 +173,9 @@ public class DiskStorageHistory extends FaweStreamChangeSet { } @Override - public boolean flush() { + public void flush() { super.flush(); synchronized (this) { - boolean flushed = osBD != null || osBIO != null || osNBTF != null || osNBTT != null && osENTCF != null || osENTCT != null; try { if (osBD != null) osBD.flush(); if (osBIO != null) osBIO.flush(); @@ -187,12 +186,11 @@ public class DiskStorageHistory extends FaweStreamChangeSet { } catch (Exception e) { e.printStackTrace(); } - return flushed; } } @Override - public boolean close() { + public void close() throws IOException { super.close(); synchronized (this) { boolean flushed = osBD != null || osBIO != null || osNBTF != null || osNBTT != null && osENTCF != null || osENTCT != null; @@ -224,7 +222,9 @@ public class DiskStorageHistory extends FaweStreamChangeSet { } catch (Exception e) { e.printStackTrace(); } - return flushed; + if (!flushed) { + throw new IOException("Empty"); + } } } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java index a7e8400fa..cf92dfd38 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java @@ -33,6 +33,8 @@ import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; +import java.io.Closeable; +import java.io.IOException; import java.util.Iterator; import java.util.Map; import java.util.Set; @@ -40,7 +42,7 @@ import java.util.UUID; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicInteger; -public abstract class FaweChangeSet implements ChangeSet, IBatchProcessor { +public abstract class FaweChangeSet implements ChangeSet, IBatchProcessor, Closeable { private World world; private final String worldName; @@ -77,24 +79,23 @@ public abstract class FaweChangeSet implements ChangeSet, IBatchProcessor { return world; } - @Deprecated - public boolean flushAsync() { - return closeAsync(); - } - - public boolean closeAsync() { + public void closeAsync() { waitingAsync.incrementAndGet(); TaskManager.IMP.async(() -> { waitingAsync.decrementAndGet(); synchronized (waitingAsync) { waitingAsync.notifyAll(); } - close(); + try { + close(); + } catch (IOException e) { + e.printStackTrace(); + } }); - return true; } - public boolean flush() { + @Override + public void flush() { try { if (!Fawe.isMainThread()) { while (waitingAsync.get() > 0) { @@ -111,11 +112,11 @@ public abstract class FaweChangeSet implements ChangeSet, IBatchProcessor { } catch (InterruptedException e) { e.printStackTrace(); } - return true; } - public boolean close() { - return flush(); + @Override + public void close() throws IOException { + flush(); } public abstract void add(int x, int y, int z, int combinedFrom, int combinedTo); diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweStreamChangeSet.java b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweStreamChangeSet.java index 8c86f3d24..f9a940a40 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweStreamChangeSet.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweStreamChangeSet.java @@ -667,8 +667,8 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet { @Override public Iterator getIterator(final boolean dir) { - close(); try { + close(); final Iterator tileCreate = getTileIterator(getTileCreateIS(), true); final Iterator tileRemove = getTileIterator(getTileRemoveIS(), false); diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/MemoryOptimizedHistory.java b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/MemoryOptimizedHistory.java index b187ffc5f..76592adb1 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/MemoryOptimizedHistory.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/MemoryOptimizedHistory.java @@ -52,7 +52,7 @@ public class MemoryOptimizedHistory extends FaweStreamChangeSet { } @Override - public boolean flush() { + public void flush() { super.flush(); synchronized (this) { try { @@ -62,16 +62,14 @@ public class MemoryOptimizedHistory extends FaweStreamChangeSet { if (entRStream != null) entRStreamZip.flush(); if (tileCStream != null) tileCStreamZip.flush(); if (tileRStream != null) tileRStreamZip.flush(); - return true; } catch (IOException e) { e.printStackTrace(); } } - return false; } @Override - public boolean close() { + public void close() throws IOException { super.close(); synchronized (this) { try { @@ -111,12 +109,10 @@ public class MemoryOptimizedHistory extends FaweStreamChangeSet { tileRStream = null; tileRStreamZip = null; } - return true; } catch (IOException e) { e.printStackTrace(); } } - return false; } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java index 9359fab7c..605d6eee2 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -128,6 +128,8 @@ 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 java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -1008,7 +1010,11 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { if (Settings.IMP.HISTORY.COMBINE_STAGES) { ((FaweChangeSet) getChangeSet()).closeAsync(); } else { - ((FaweChangeSet) getChangeSet()).close(); + try { + ((FaweChangeSet) getChangeSet()).close(); + } catch (IOException e) { + throw new RuntimeException(e); + } } } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java index eb473dfc0..033fc604a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -399,7 +399,12 @@ public class LocalSession implements TextureHolder { private FaweChangeSet getChangeSet(Object o) { if (o instanceof FaweChangeSet) { FaweChangeSet cs = (FaweChangeSet) o; - cs.close(); + try { + cs.close(); + } catch (IOException e) { + e.printStackTrace(); + return null; + } return cs; } if (o instanceof Integer) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java index a03f89a21..48ef9f477 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java @@ -207,7 +207,7 @@ public class BrushCommands { ) @CommandPermissions("worldedit.brush.sphere") public void circleBrush(Player player, InjectedValueAccess context, - Pattern fill, + @Arg(desc = "Pattern") Pattern fill, @Arg(desc = "The radius to sample for blending", def = "5") Expression radius) throws WorldEditException { worldEdit.checkMaxBrushRadius(radius); @@ -223,7 +223,7 @@ public class BrushCommands { ) @CommandPermissions("worldedit.brush.recursive") public void recursiveBrush(InjectedValueAccess context, EditSession editSession, - Pattern fill, + @Arg(desc = "Pattern") Pattern fill, @Arg(desc = "The radius to sample for blending", def = "5") Expression radius, @Switch(name = 'd', desc = "Apply in depth first order") @@ -264,7 +264,7 @@ public class BrushCommands { ) @CommandPermissions("worldedit.brush.spline") public void splineBrush(Player player, InjectedValueAccess context, - Pattern fill, + @Arg(desc = "Pattern") Pattern fill, @Arg(desc = "The radius to sample for blending", def = "25") Expression radius) throws WorldEditException { worldEdit.checkMaxBrushRadius(radius); @@ -407,7 +407,7 @@ public class BrushCommands { ) @CommandPermissions("worldedit.brush.shatter") public void shatterBrush(EditSession editSession, InjectedValueAccess context, - Pattern fill, + @Arg(desc = "Pattern") Pattern fill, @Arg(desc = "The radius to sample for blending", def = "10") Expression radius, @Arg(desc = "Lines", def = "10") int count) throws WorldEditException { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java index bb48bc54b..8a0b91e87 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java @@ -19,24 +19,12 @@ package com.sk89q.worldedit.command; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.sk89q.worldedit.command.MethodCommands.getArguments; -import static com.sk89q.worldedit.command.util.Logging.LogMode.ALL; -import static com.sk89q.worldedit.command.util.Logging.LogMode.ORIENTATION_REGION; -import static com.sk89q.worldedit.command.util.Logging.LogMode.REGION; -import static com.sk89q.worldedit.internal.command.CommandUtil.checkCommandArgument; -import static com.sk89q.worldedit.regions.Regions.asFlatRegion; -import static com.sk89q.worldedit.regions.Regions.maximumBlockY; -import static com.sk89q.worldedit.regions.Regions.minimumBlockY; - -import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweAPI; import com.boydti.fawe.FaweCache; import com.boydti.fawe.beta.implementation.processors.ChunkSendProcessor; import com.boydti.fawe.beta.implementation.processors.NullProcessor; import com.boydti.fawe.config.BBC; import com.boydti.fawe.object.FaweLimit; -import com.boydti.fawe.util.TextureUtil; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalSession; @@ -47,7 +35,9 @@ import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator; import com.sk89q.worldedit.command.util.Logging; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.platform.Actor; +import com.sk89q.worldedit.function.FlatRegionFunction; import com.sk89q.worldedit.function.GroundFunction; +import com.sk89q.worldedit.function.biome.BiomeReplace; import com.sk89q.worldedit.function.generator.FloraGenerator; import com.sk89q.worldedit.function.mask.ExistingBlockMask; import com.sk89q.worldedit.function.mask.Mask; @@ -55,6 +45,7 @@ import com.sk89q.worldedit.function.mask.NoiseFilter2D; import com.sk89q.worldedit.function.mask.SolidBlockMask; import com.sk89q.worldedit.function.operation.Operations; import com.sk89q.worldedit.function.pattern.Pattern; +import com.sk89q.worldedit.function.visitor.FlatRegionVisitor; import com.sk89q.worldedit.function.visitor.LayerVisitor; import com.sk89q.worldedit.internal.annotation.Direction; import com.sk89q.worldedit.internal.annotation.Range; @@ -74,21 +65,9 @@ import com.sk89q.worldedit.regions.RegionOperationException; import com.sk89q.worldedit.regions.Regions; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.TreeGenerator.TreeType; -import com.sk89q.worldedit.util.formatting.component.TextComponentProducer; -import com.sk89q.worldedit.util.formatting.text.TextComponent; -import com.sk89q.worldedit.util.formatting.text.event.HoverEvent; -import com.sk89q.worldedit.util.formatting.text.serializer.legacy.LegacyComponentSerializer; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BlockStateHolder; - -import java.awt.Color; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.stream.Stream; - -import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; import org.enginehub.piston.annotation.Command; import org.enginehub.piston.annotation.CommandContainer; @@ -97,6 +76,21 @@ import org.enginehub.piston.annotation.param.ArgFlag; import org.enginehub.piston.annotation.param.Switch; import org.enginehub.piston.inject.InjectedValueAccess; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Stream; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.sk89q.worldedit.command.MethodCommands.getArguments; +import static com.sk89q.worldedit.command.util.Logging.LogMode.ALL; +import static com.sk89q.worldedit.command.util.Logging.LogMode.ORIENTATION_REGION; +import static com.sk89q.worldedit.command.util.Logging.LogMode.REGION; +import static com.sk89q.worldedit.internal.command.CommandUtil.checkCommandArgument; +import static com.sk89q.worldedit.regions.Regions.asFlatRegion; +import static com.sk89q.worldedit.regions.Regions.maximumBlockY; +import static com.sk89q.worldedit.regions.Regions.minimumBlockY; + /** * Commands that operate on regions. */ @@ -155,7 +149,14 @@ public class RegionCommands { ) @CommandPermissions("worldedit.region.test") @Logging(REGION) - public void test(Player player, @Arg(desc = "hello there")BlockType type) throws WorldEditException { + public void test(Player player, EditSession editSession, @Selection Region region, @Arg(desc = "hello there") BiomeType biome) throws WorldEditException { + System.out.println("Test start"); + editSession.addProcessor(new ChunkSendProcessor(editSession.getWorld(), () -> Stream.of(player))); + editSession.addProcessor(NullProcessor.INSTANCE); + FlatRegionFunction replace = new BiomeReplace(editSession, biome); + FlatRegionVisitor visitor = new FlatRegionVisitor(Regions.asFlatRegion(region), replace); + Operations.completeLegacy(visitor); + System.out.println("Test end"); } @Command( 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 4cb4188b9..7efbf26c6 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 @@ -23,6 +23,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import static org.slf4j.LoggerFactory.getLogger; import com.boydti.fawe.Fawe; +import com.boydti.fawe.beta.implementation.processors.PersistentChunkSendProcessor; import com.boydti.fawe.config.BBC; import com.boydti.fawe.object.RunnableVal; import com.boydti.fawe.object.brush.BrushSettings; @@ -644,8 +645,11 @@ public class BrushTool implements DoubleActionTraceTool, ScrollTool, MovableTool .autoQueue(false) .blockBag(null) .changeSetNull() - .combineStages(false); + .fastmode(true) + .combineStages(true); EditSession editSession = builder.build(); + +// processor = new PersistentChunkSendProcessor() VisualExtent newVisualExtent = new VisualExtent(editSession, player); BlockVector3 position = getPosition(editSession, player); if (position != null) {