diff --git a/bukkit0/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_All.java b/bukkit0/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_All.java index 44c69866..0bc835cc 100644 --- a/bukkit0/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_All.java +++ b/bukkit0/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_All.java @@ -17,7 +17,6 @@ import org.bukkit.block.Block; public class BukkitQueue_All extends BukkitQueue_0 { public static int ALLOCATE; - public static double TPS_TARGET = 18.5; private static int LIGHT_MASK = 0x739C0; public BukkitQueue_All(com.sk89q.worldedit.world.World world) { diff --git a/core/src/main/java/com/boydti/fawe/Fawe.java b/core/src/main/java/com/boydti/fawe/Fawe.java index 19854fea..297b0eac 100644 --- a/core/src/main/java/com/boydti/fawe/Fawe.java +++ b/core/src/main/java/com/boydti/fawe/Fawe.java @@ -51,6 +51,7 @@ import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat; import com.sk89q.worldedit.extent.clipboard.io.SchematicReader; import com.sk89q.worldedit.extent.clipboard.io.SchematicWriter; +import com.sk89q.worldedit.extent.inventory.BlockBagExtent; import com.sk89q.worldedit.extent.transform.BlockTransformExtent; import com.sk89q.worldedit.function.entity.ExtentEntityCopy; import com.sk89q.worldedit.function.mask.BlockMask; @@ -389,6 +390,7 @@ public class Fawe { // Extents BlockTransformExtent.inject(); // Fix for cache not being mutable AbstractDelegateExtent.inject(); // Optimizations + BlockBagExtent.inject(); // Fixes + Optimizations // Vector Vector.inject(); // Optimizations // Pattern diff --git a/core/src/main/java/com/boydti/fawe/FaweCache.java b/core/src/main/java/com/boydti/fawe/FaweCache.java index 10511aa5..f203d404 100644 --- a/core/src/main/java/com/boydti/fawe/FaweCache.java +++ b/core/src/main/java/com/boydti/fawe/FaweCache.java @@ -16,6 +16,7 @@ import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.CuboidClipboard; import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.world.registry.BundledBlockData; import java.awt.Color; import java.lang.reflect.Field; @@ -65,6 +66,8 @@ public class FaweCache { */ public final static BaseBlock[] CACHE_BLOCK = new BaseBlock[Character.MAX_VALUE + 1]; + public final static BaseItem[] CACHE_ITEM = new BaseItem[Character.MAX_VALUE + 1]; + /** * Faster than java random (since it just needs to look random) */ @@ -83,6 +86,10 @@ public class FaweCache { return CACHE_BLOCK[(id << 4) + data]; } + public static final BaseItem getItem(int id, int data) { + return CACHE_ITEM[(id << 4) + data]; + } + /** * Get the combined data for a block * @param id @@ -174,6 +181,23 @@ public class FaweCache { return true; } }; + CACHE_ITEM[i] = new BaseItem(id, (short) data) { + + @Override + public void setData(short data) { + throw new IllegalStateException("Cannot set data"); + } + + @Override + public void setDamage(short data) { + throw new IllegalStateException("Cannot set data"); + } + + @Override + public void setType(int id) { + throw new IllegalStateException("Cannot set id"); + } + }; } CACHE_COLOR[getCombined(0, 0)] = new Color(128, 128, 128); //Air diff --git a/core/src/main/java/com/boydti/fawe/config/BBC.java b/core/src/main/java/com/boydti/fawe/config/BBC.java index 86dcb960..26272eff 100644 --- a/core/src/main/java/com/boydti/fawe/config/BBC.java +++ b/core/src/main/java/com/boydti/fawe/config/BBC.java @@ -169,6 +169,7 @@ public enum BBC { "Error"), WORLDEDIT_SOME_FAILS("&c%s0 blocks weren't placed because they were outside your allowed region.", "Error"), + WORLDEDIT_SOME_FAILS_BLOCKBAG("&cMissing blocks: %s0", "Error"), WORLDEDIT_CANCEL_COUNT("&cCancelled %s0 edits.", "Cancel"), WORLDEDIT_CANCEL_REASON("&cYour WorldEdit action was cancelled:&7 %s0&c.", "Cancel"), diff --git a/core/src/main/java/com/boydti/fawe/logging/LoggingChangeSet.java b/core/src/main/java/com/boydti/fawe/logging/LoggingChangeSet.java index 56c17b74..3f5c04b1 100644 --- a/core/src/main/java/com/boydti/fawe/logging/LoggingChangeSet.java +++ b/core/src/main/java/com/boydti/fawe/logging/LoggingChangeSet.java @@ -3,17 +3,14 @@ package com.boydti.fawe.logging; import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweCache; import com.boydti.fawe.object.FawePlayer; +import com.boydti.fawe.object.changeset.AbstractDelegateChangeSet; import com.boydti.fawe.object.changeset.FaweChangeSet; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.extent.inventory.BlockBag; -import com.sk89q.worldedit.history.change.Change; -import java.util.Iterator; import org.bukkit.entity.Player; import org.primesoft.blockshub.IBlocksHubApi; import org.primesoft.blockshub.api.IPlayer; import org.primesoft.blockshub.api.IWorld; -public class LoggingChangeSet extends FaweChangeSet { +public class LoggingChangeSet extends AbstractDelegateChangeSet { private static boolean initialized = false; @@ -30,8 +27,6 @@ public class LoggingChangeSet extends FaweChangeSet { public static IBlocksHubApi api; - private final FaweChangeSet parent; - private final MutableVector loc; private final IPlayer player; private final IWorld world; @@ -39,8 +34,7 @@ public class LoggingChangeSet extends FaweChangeSet { private final MutableBlockData newBlock; private LoggingChangeSet(FawePlayer player, FaweChangeSet parent) { - super(parent.getWorld()); - this.parent = parent; + super(parent); this.world = api.getWorld(player.getLocation().world); this.loc = new MutableVector(); this.oldBlock = new MutableBlockData(); @@ -48,11 +42,6 @@ public class LoggingChangeSet extends FaweChangeSet { this.player = api.getPlayer(player.getUUID()); } - @Override - public boolean flush() { - return parent.flush(); - } - @Override public void add(int x, int y, int z, int combinedId4DataFrom, int combinedId4DataTo) { // Mutable (avoids object creation) @@ -67,39 +56,4 @@ public class LoggingChangeSet extends FaweChangeSet { api.logBlock(loc, player, world, oldBlock, newBlock); parent.add(x, y, z, combinedId4DataFrom, combinedId4DataTo); } - - @Override - public void addTileCreate(CompoundTag tag) { - parent.addTileCreate(tag); - } - - @Override - public void addTileRemove(CompoundTag tag) { - parent.addTileRemove(tag); - } - - @Override - public void addEntityRemove(CompoundTag tag) { - parent.addEntityRemove(tag); - } - - @Override - public void addEntityCreate(CompoundTag tag) { - parent.addEntityCreate(tag); - } - - @Override - public Iterator getIterator(BlockBag blockBag, int mode, boolean redo) { - return parent.getIterator(blockBag, mode, redo); - } - - @Override - public Iterator getIterator(boolean undo) { - return parent.getIterator(undo); - } - - @Override - public int size() { - return parent.size(); - } } \ No newline at end of file diff --git a/core/src/main/java/com/boydti/fawe/object/HistoryExtent.java b/core/src/main/java/com/boydti/fawe/object/HistoryExtent.java index 7f3b779d..3d99da23 100644 --- a/core/src/main/java/com/boydti/fawe/object/HistoryExtent.java +++ b/core/src/main/java/com/boydti/fawe/object/HistoryExtent.java @@ -2,6 +2,7 @@ package com.boydti.fawe.object; import com.boydti.fawe.FaweCache; import com.boydti.fawe.object.changeset.FaweChangeSet; +import com.boydti.fawe.object.exception.FaweException; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.Vector; @@ -67,20 +68,24 @@ public class HistoryExtent extends AbstractDelegateExtent { return false; } } - if (!FaweCache.hasNBT(id)) { - if (FaweCache.hasNBT(block.getId())) { - this.changeSet.add(x, y, z, combined, block); + try { + if (!FaweCache.hasNBT(id)) { + if (FaweCache.hasNBT(block.getId())) { + this.changeSet.add(x, y, z, combined, block); + } else { + this.changeSet.add(x, y, z, combined, (block.getId() << 4) + block.getData()); + } } else { - this.changeSet.add(x, y, z, combined, (block.getId() << 4) + block.getData()); - } - } else { - try { - CompoundTag tag = queue.getTileEntity(x, y, z); - this.changeSet.add(x, y, z, new BaseBlock(id, combined & 0xF, tag), block); - } catch (Throwable e) { - e.printStackTrace(); - this.changeSet.add(x, y, z, combined, block); + try { + CompoundTag tag = queue.getTileEntity(x, y, z); + this.changeSet.add(x, y, z, new BaseBlock(id, combined & 0xF, tag), block); + } catch (Throwable e) { + e.printStackTrace(); + this.changeSet.add(x, y, z, combined, block); + } } + } catch (FaweException ignore) { + return false; } return extent.setBlock(x, y, z, block); } diff --git a/core/src/main/java/com/boydti/fawe/object/change/MutableFullBlockChange.java b/core/src/main/java/com/boydti/fawe/object/change/MutableFullBlockChange.java index a71842a4..bac5a1ac 100644 --- a/core/src/main/java/com/boydti/fawe/object/change/MutableFullBlockChange.java +++ b/core/src/main/java/com/boydti/fawe/object/change/MutableFullBlockChange.java @@ -60,24 +60,24 @@ public class MutableFullBlockChange implements Change { public void perform(FaweQueue queue) { int idFrom = FaweCache.getId(from); - int dataFrom = FaweCache.getData(from); if (blockBag != null) { - if (allowFetch && idFrom != 0) { - try { - blockBag.fetchPlacedBlock(idFrom, dataFrom); - } catch (BlockBagException e) { - return; - } - } int idTo = FaweCache.getId(to); - int dataTo = FaweCache.getData(to); - if (allowStore && idTo != 0) { - try { - blockBag.storeDroppedBlock(idTo, dataTo); - } catch (BlockBagException ignored) { + if (idFrom != idTo) { + if (allowFetch && from != 0) { + try { + blockBag.fetchPlacedBlock(idFrom, FaweCache.getData(from)); + } catch (BlockBagException e) { + return; + } + } + if (allowStore && to != 0) { + try { + blockBag.storeDroppedBlock(idTo, FaweCache.getData(to)); + } catch (BlockBagException ignored) { + } } } } - queue.setBlock(x, y, z, idFrom, dataFrom); + queue.setBlock(x, y, z, idFrom, FaweCache.getData(from)); } } diff --git a/core/src/main/java/com/boydti/fawe/object/changeset/AbstractDelegateChangeSet.java b/core/src/main/java/com/boydti/fawe/object/changeset/AbstractDelegateChangeSet.java new file mode 100644 index 00000000..70a6ab00 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/changeset/AbstractDelegateChangeSet.java @@ -0,0 +1,148 @@ +package com.boydti.fawe.object.changeset; + +import com.boydti.fawe.object.FawePlayer; +import com.boydti.fawe.object.FaweQueue; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.extent.inventory.BlockBag; +import com.sk89q.worldedit.history.change.BlockChange; +import com.sk89q.worldedit.history.change.Change; +import com.sk89q.worldedit.history.change.EntityCreate; +import com.sk89q.worldedit.history.change.EntityRemove; +import com.sk89q.worldedit.world.World; +import java.util.Iterator; +import java.util.UUID; + +public class AbstractDelegateChangeSet extends FaweChangeSet { + public final FaweChangeSet parent; + + public AbstractDelegateChangeSet(FaweChangeSet parent) { + super(parent.getWorld()); + this.parent = parent; + } + + public final FaweChangeSet getParent() { + return parent; + } + + public static FaweChangeSet getDefaultChangeSet(World world, UUID uuid) { + return FaweChangeSet.getDefaultChangeSet(world, uuid); + } + + @Override + public World getWorld() { + return parent.getWorld(); + } + + @Override + public boolean flushAsync() { + return parent.flushAsync(); + } + + @Override + public boolean flush() { + return parent.flush(); + } + + @Override + public void add(int x, int y, int z, int combinedFrom, int combinedTo) { + parent.add(x, y, z, combinedFrom, combinedTo); + } + + @Override + public Iterator backwardIterator() { + return parent.backwardIterator(); + } + + @Override + public Iterator forwardIterator() { + return parent.forwardIterator(); + } + + @Override + public int size() { + return parent.size(); + } + + @Override + public void addTileCreate(CompoundTag tag) { + parent.addTileCreate(tag); + } + + @Override + public void addTileRemove(CompoundTag tag) { + parent.addTileRemove(tag); + } + + @Override + public void addEntityRemove(CompoundTag tag) { + parent.addEntityRemove(tag); + } + + @Override + public void addEntityCreate(CompoundTag tag) { + parent.addEntityCreate(tag); + } + + @Override + public Iterator getIterator(BlockBag blockBag, int mode, boolean redo) { + return parent.getIterator(blockBag, mode, redo); + } + + @Override + public Iterator getIterator(boolean redo) { + return parent.getIterator(redo); + } + + @Override + public void delete() { + parent.delete(); + } + + @Override + public EditSession toEditSession(FawePlayer player) { + return parent.toEditSession(player); + } + + @Override + public void add(EntityCreate change) { + parent.add(change); + } + + @Override + public void add(EntityRemove change) { + parent.add(change); + } + + @Override + public void add(Change change) { + parent.add(change); + } + + @Override + public void add(BlockChange change) { + parent.add(change); + } + + @Override + public void add(Vector loc, BaseBlock from, BaseBlock to) { + parent.add(loc, from, to); + } + + @Override + public void add(int x, int y, int z, BaseBlock from, BaseBlock to) { + parent.add(x, y, z, from, to); + } + + @Override + public void add(int x, int y, int z, int combinedFrom, BaseBlock to) { + parent.add(x, y, z, combinedFrom, to); + } + + @Override + public void addChangeTask(FaweQueue queue) { + parent.addChangeTask(queue); + } +} diff --git a/core/src/main/java/com/boydti/fawe/object/changeset/BlockBagChangeSet.java b/core/src/main/java/com/boydti/fawe/object/changeset/BlockBagChangeSet.java new file mode 100644 index 00000000..21f54d87 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/changeset/BlockBagChangeSet.java @@ -0,0 +1,96 @@ +package com.boydti.fawe.object.changeset; + +import com.boydti.fawe.FaweCache; +import com.boydti.fawe.object.exception.FaweException; +import com.boydti.fawe.util.ReflectionUtils; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.extent.inventory.BlockBag; +import com.sk89q.worldedit.extent.inventory.BlockBagException; +import com.sk89q.worldedit.extent.inventory.UnplaceableBlockException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import javax.annotation.Nullable; + +public class BlockBagChangeSet extends AbstractDelegateChangeSet { + + private final boolean mine; + private int[] missingBlocks = new int[Character.MAX_VALUE + 1]; + private BlockBag blockBag; + + public BlockBagChangeSet(FaweChangeSet parent, BlockBag blockBag, boolean mine) { + super(parent); + this.blockBag = blockBag; + this.mine = mine; + } + + /** + * Get the block bag. + * + * @return a block bag, which may be null if none is used + */ + public @Nullable + BlockBag getBlockBag() { + return blockBag; + } + + /** + * Set the block bag. + * + * @param blockBag a block bag, which may be null if none is used + */ + public void setBlockBag(@Nullable BlockBag blockBag) { + this.blockBag = blockBag; + } + + + /** + * Gets the list of missing blocks and clears the list for the next + * operation. + * + * @return a map of missing blocks + */ + public Map popMissing() { + HashMap map = new HashMap<>(); + for (int i = 0; i < missingBlocks.length; i++) { + int count = missingBlocks[i]; + if (count > 0) { + map.put(i, count); + } + } + Arrays.fill(missingBlocks, 0); + return map; + } + + @Override + public void add(int x, int y, int z, int combinedFrom, int combinedTo) { + if (combinedTo != 0) { + try { + blockBag.fetchPlacedBlock(FaweCache.getId(combinedTo), FaweCache.getData(combinedTo)); + } catch (UnplaceableBlockException e) { + throw new FaweException.FaweBlockBagException(); + } catch (BlockBagException e) { + missingBlocks[combinedTo]++; + throw new FaweException.FaweBlockBagException(); + } + } + if (mine) { + if (combinedFrom != 0) { + try { + blockBag.storeDroppedBlock(FaweCache.getId(combinedFrom), FaweCache.getData(combinedFrom)); + } catch (BlockBagException ignored) {} + } + } + super.add(x, y, z, combinedFrom, combinedTo); + } + + @Override + public void addTileCreate(CompoundTag nbt) { + if (nbt.containsKey("items")) { + Map map = ReflectionUtils.getMap(nbt.getValue()); + map.remove("items"); + } + super.addTileCreate(nbt); + } +} diff --git a/core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java b/core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java index ef6a5f6a..24c9b64c 100644 --- a/core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java +++ b/core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java @@ -94,7 +94,9 @@ public abstract class FaweChangeSet implements ChangeSet { public abstract void addTileRemove(CompoundTag tag); public abstract void addEntityRemove(CompoundTag tag); public abstract void addEntityCreate(CompoundTag tag); - public abstract Iterator getIterator(BlockBag blockBag, int mode, boolean redo); + public Iterator getIterator(BlockBag blockBag, int mode, boolean redo) { + return getIterator(redo); + } public abstract Iterator getIterator(boolean redo); public void delete() {}; diff --git a/core/src/main/java/com/boydti/fawe/object/exception/FaweException.java b/core/src/main/java/com/boydti/fawe/object/exception/FaweException.java index df207c48..d04e1eb1 100644 --- a/core/src/main/java/com/boydti/fawe/object/exception/FaweException.java +++ b/core/src/main/java/com/boydti/fawe/object/exception/FaweException.java @@ -35,6 +35,12 @@ public class FaweException extends RuntimeException { } } + public static class FaweBlockBagException extends FaweException { + public FaweBlockBagException() { + super(BBC.WORLDEDIT_SOME_FAILS_BLOCKBAG); + } + } + /** * Faster exception throwing if you don't fill the stacktrace * @return diff --git a/core/src/main/java/com/boydti/fawe/object/io/FastByteArrayOutputStream.java b/core/src/main/java/com/boydti/fawe/object/io/FastByteArrayOutputStream.java index b2b918d3..ba60396f 100644 --- a/core/src/main/java/com/boydti/fawe/object/io/FastByteArrayOutputStream.java +++ b/core/src/main/java/com/boydti/fawe/object/io/FastByteArrayOutputStream.java @@ -5,9 +5,11 @@ import java.io.OutputStream; import java.io.RandomAccessFile; import java.io.Writer; import java.util.ArrayDeque; +import java.util.Arrays; import java.util.Iterator; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorCompletionService; +import java.util.concurrent.ForkJoinPool; /** @@ -101,44 +103,25 @@ public class FastByteArrayOutputStream extends OutputStream { return data; } - public byte[] toByteArray() { - byte[] data = new byte[getSize()]; - - // Check if we have a list of buffers - int pos = 0; - - if (buffers != null) { - for (byte[] bytes : buffers) { - System.arraycopy(bytes, 0, data, pos, bytes.length); - pos += bytes.length; - } - } - - // write the internal buffer directly - System.arraycopy(buffer, 0, data, pos, index); - - return data; - } - public String toString() { return new String(toByteArray()); } @Override - public void write(byte[] b) throws IOException { - if (b.length > blockSize) { - if (index > 0) { - byte[] buf2 = new byte[index]; - System.arraycopy(buffer, 0, buf2, 0, index); - buffer = buf2; - addBuffer(); + public void write(byte[] b) throws IOException { + if (b.length > blockSize) { + if (index > 0) { + byte[] buf2 = new byte[index]; + System.arraycopy(buffer, 0, buf2, 0, index); + buffer = buf2; + addBuffer(); + } + size += b.length; + buffers.addLast(b); + } else { + write(b, 0, b.length); } - size += b.length; - buffers.addLast(b); - } else { - write(b, 0, b.length); } - } public void write(int datum) { if (index == blockSize) { diff --git a/core/src/main/java/com/boydti/fawe/util/FaweTimer.java b/core/src/main/java/com/boydti/fawe/util/FaweTimer.java index 63215644..264d689b 100644 --- a/core/src/main/java/com/boydti/fawe/util/FaweTimer.java +++ b/core/src/main/java/com/boydti/fawe/util/FaweTimer.java @@ -61,6 +61,9 @@ public class FaweTimer implements Runnable { private long skipTick = 0; public boolean isAbove(double tps) { + if (tps <= 0) { + return true; + } if (skip > 0) { if (skipTick != tick) { skip--; diff --git a/core/src/main/java/com/boydti/fawe/util/SetQueue.java b/core/src/main/java/com/boydti/fawe/util/SetQueue.java index 6595fb93..767b1ca8 100644 --- a/core/src/main/java/com/boydti/fawe/util/SetQueue.java +++ b/core/src/main/java/com/boydti/fawe/util/SetQueue.java @@ -60,7 +60,8 @@ public class SetQueue { @Override public void run() { try { - while (!tasks.isEmpty() && Fawe.get().getTimer().isAbove(18.5)) { + double targetTPS = 18 - Math.max(Settings.QUEUE.EXTRA_TIME_MS * 0.05, 0); + while (!tasks.isEmpty() && Fawe.get().getTimer().isAbove(targetTPS)) { tasks.poll().run(); } if (inactiveQueues.isEmpty() && activeQueues.isEmpty()) { @@ -86,7 +87,7 @@ public class SetQueue { } } FaweQueue queue = getNextQueue(); - if (queue == null || !Fawe.get().getTimer().isAbove(18.5)) { + if (queue == null || !Fawe.get().getTimer().isAbove(targetTPS)) { return; } if (Thread.currentThread() != Fawe.get().getMainThread()) { diff --git a/core/src/main/java/com/sk89q/worldedit/EditSession.java b/core/src/main/java/com/sk89q/worldedit/EditSession.java index 3c046007..1b9594b3 100644 --- a/core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -36,6 +36,7 @@ import com.boydti.fawe.object.HistoryExtent; import com.boydti.fawe.object.NullChangeSet; import com.boydti.fawe.object.RegionWrapper; import com.boydti.fawe.object.RunnableVal; +import com.boydti.fawe.object.changeset.BlockBagChangeSet; import com.boydti.fawe.object.changeset.CPUOptimizedChangeSet; import com.boydti.fawe.object.changeset.DiskStorageHistory; import com.boydti.fawe.object.changeset.FaweChangeSet; @@ -70,7 +71,6 @@ import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.MaskingExtent; import com.sk89q.worldedit.extent.buffer.ForgetfulExtentBuffer; import com.sk89q.worldedit.extent.inventory.BlockBag; -import com.sk89q.worldedit.extent.inventory.BlockBagExtent; import com.sk89q.worldedit.extent.world.SurvivalModeExtent; import com.sk89q.worldedit.function.GroundFunction; import com.sk89q.worldedit.function.RegionMaskingFilter; @@ -285,9 +285,6 @@ public class EditSession extends AbstractWorld implements HasFaweQueue { this.bypassAll = wrapExtent(new FastWorldEditExtent(world, queue), bus, event, Stage.BEFORE_CHANGE); this.bypassHistory = (this.extent = wrapExtent(bypassAll, bus, event, Stage.BEFORE_REORDER)); if (!fastmode) { - if (this.blockBag != null && limit.INVENTORY_MODE > 0) { - this.bypassHistory = new BlockBagExtent(this.bypassHistory, this.blockBag, limit.INVENTORY_MODE == 1); - } if (limit.SPEED_REDUCTION > 0) { this.bypassHistory = new SlowExtent(this.bypassHistory, limit.SPEED_REDUCTION); } @@ -295,6 +292,9 @@ public class EditSession extends AbstractWorld implements HasFaweQueue { if (player != null && Fawe.imp().getBlocksHubApi() != null) { changeSet = LoggingChangeSet.wrap(player, changeSet); } + if (this.blockBag != null && limit.INVENTORY_MODE > 0) { + changeSet = new BlockBagChangeSet(changeSet, blockBag, limit.INVENTORY_MODE == 1); + } if (combineStages) { changeTask = changeSet; changeSet.addChangeTask(queue); @@ -728,6 +728,37 @@ public class EditSession extends AbstractWorld implements HasFaweQueue { * @return a map of missing blocks */ public Map popMissingBlocks() { + ChangeSet changeSet = getChangeSet(); + if (changeSet instanceof BlockBagChangeSet) { + BlockBagChangeSet bbcs = (BlockBagChangeSet) changeSet; + BlockBag bag = bbcs.getBlockBag(); + if (bag != null) { + bag.flushChanges(); + Map missingBlocks = ((BlockBagChangeSet) changeSet).popMissing(); + if (!missingBlocks.isEmpty()) { + StringBuilder str = new StringBuilder(); + int size = missingBlocks.size(); + int i = 0; + + for (Map.Entry entry : missingBlocks.entrySet()) { + int combined = entry.getKey(); + int id = FaweCache.getId(combined); + int data = FaweCache.getData(combined); + int amount = entry.getValue(); + BlockType type = BlockType.fromID(id); + str.append((type != null ? type.getName() : "" + id)) + .append((data != 0 ? ":" + data : "")) + .append((amount != 1 ? "x" + amount : "")); + ++i; + if (i != size) { + str.append(", "); + } + } + + BBC.WORLDEDIT_SOME_FAILS_BLOCKBAG.send(player, str.toString()); + } + } + } return new HashMap<>(); } diff --git a/core/src/main/java/com/sk89q/worldedit/extent/inventory/BlockBagExtent.java b/core/src/main/java/com/sk89q/worldedit/extent/inventory/BlockBagExtent.java index 785a0a55..bd5341c7 100644 --- a/core/src/main/java/com/sk89q/worldedit/extent/inventory/BlockBagExtent.java +++ b/core/src/main/java/com/sk89q/worldedit/extent/inventory/BlockBagExtent.java @@ -1,5 +1,6 @@ package com.sk89q.worldedit.extent.inventory; +import com.boydti.fawe.FaweCache; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEditException; @@ -108,4 +109,8 @@ public class BlockBagExtent extends AbstractDelegateExtent { } return super.setBlock(position, block); } + + public static Class inject() { + return BlockBagExtent.class; + } } \ No newline at end of file diff --git a/nukkit/src/main/java/com/boydti/fawe/nukkit/optimization/queue/NukkitQueue.java b/nukkit/src/main/java/com/boydti/fawe/nukkit/optimization/queue/NukkitQueue.java index 95b29707..100be89d 100644 --- a/nukkit/src/main/java/com/boydti/fawe/nukkit/optimization/queue/NukkitQueue.java +++ b/nukkit/src/main/java/com/boydti/fawe/nukkit/optimization/queue/NukkitQueue.java @@ -28,7 +28,6 @@ public class NukkitQueue extends NMSMappedFaweQueue