From 0296d566ed6033510e3e67093cad170be4e333be Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Thu, 31 Oct 2019 04:04:15 +0100 Subject: [PATCH] wip remove faweclipboard --- .../fawe/jnbt/CorruptSchematicStreamer.java | 20 +- .../boydti/fawe/jnbt/SchematicStreamer.java | 16 +- .../boydti/fawe/object/brush/ErodeBrush.java | 14 +- .../AbstractDelegateFaweClipboard.java | 130 ------- .../clipboard/CPUOptimizedClipboard.java | 134 ++++---- .../object/clipboard/DelegateClipboard.java | 169 +++++++++ .../clipboard/DiskOptimizedClipboard.java | 321 ++++++++---------- .../fawe/object/clipboard/FaweClipboard.java | 179 ---------- .../object/clipboard/LinearClipboard.java | 152 +++++++++ .../clipboard/MemoryOptimizedClipboard.java | 164 +++++---- .../clipboard/MultiClipboardHolder.java | 2 +- .../object/clipboard/OffsetFaweClipboard.java | 11 +- .../object/clipboard/ReadOnlyClipboard.java | 2 +- .../fawe/object/schematic/Schematic.java | 6 +- .../worldedit/command/ToolUtilCommands.java | 1 - .../extent/clipboard/BlockArrayClipboard.java | 237 +++++++------ .../worldedit/extent/clipboard/Clipboard.java | 24 ++ .../extent/clipboard/io/ClipboardReader.java | 18 +- .../clipboard/io/SpongeSchematicReader.java | 23 +- .../clipboard/io/SpongeSchematicWriter.java | 4 +- .../com/sk89q/worldedit/regions/Region.java | 4 + 21 files changed, 844 insertions(+), 787 deletions(-) delete mode 100644 worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/AbstractDelegateFaweClipboard.java create mode 100644 worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/DelegateClipboard.java delete mode 100644 worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/FaweClipboard.java create mode 100644 worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/LinearClipboard.java diff --git a/worldedit-core/src/main/java/com/boydti/fawe/jnbt/CorruptSchematicStreamer.java b/worldedit-core/src/main/java/com/boydti/fawe/jnbt/CorruptSchematicStreamer.java index 6d46542f3..f20d9e8a8 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/jnbt/CorruptSchematicStreamer.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/jnbt/CorruptSchematicStreamer.java @@ -4,17 +4,11 @@ import com.boydti.fawe.Fawe; import com.boydti.fawe.config.Settings; import com.boydti.fawe.object.clipboard.CPUOptimizedClipboard; import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard; -import com.boydti.fawe.object.clipboard.FaweClipboard; +import com.boydti.fawe.object.clipboard.LinearClipboard; import com.boydti.fawe.object.clipboard.MemoryOptimizedClipboard; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.ListTag; -import com.sk89q.jnbt.NBTInputStream; -import com.sk89q.worldedit.entity.BaseEntity; -import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.math.Vector3; -import com.sk89q.worldedit.regions.CuboidRegion; + import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.IOException; @@ -29,7 +23,7 @@ public class CorruptSchematicStreamer { private final InputStream stream; private final UUID uuid; - private FaweClipboard fc; + private LinearClipboard fc; final AtomicInteger volume = new AtomicInteger(); final AtomicInteger width = new AtomicInteger(); final AtomicInteger height = new AtomicInteger(); @@ -78,7 +72,7 @@ public class CorruptSchematicStreamer { } } - public FaweClipboard setupClipboard() { + public LinearClipboard setupClipboard() { if (fc != null) { return fc; } @@ -87,11 +81,11 @@ public class CorruptSchematicStreamer { Fawe.debug("No dimensions found! Estimating based on factors:" + dimensions); } if (Settings.IMP.CLIPBOARD.USE_DISK) { - fc = new DiskOptimizedClipboard(dimensions.getBlockX(), dimensions.getBlockY(), dimensions.getBlockZ(), uuid); + fc = new DiskOptimizedClipboard(dimensions, uuid); } else if (Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL == 0) { - fc = new CPUOptimizedClipboard(dimensions.getBlockX(), dimensions.getBlockY(), dimensions.getBlockZ()); + fc = new CPUOptimizedClipboard(dimensions); } else { - fc = new MemoryOptimizedClipboard(dimensions.getBlockX(), dimensions.getBlockY(), dimensions.getBlockZ()); + fc = new MemoryOptimizedClipboard(dimensions); } return fc; } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/jnbt/SchematicStreamer.java b/worldedit-core/src/main/java/com/boydti/fawe/jnbt/SchematicStreamer.java index 93ba38f0b..b94f414e2 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/jnbt/SchematicStreamer.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/jnbt/SchematicStreamer.java @@ -6,7 +6,7 @@ import com.boydti.fawe.object.FaweInputStream; import com.boydti.fawe.object.FaweOutputStream; import com.boydti.fawe.object.clipboard.CPUOptimizedClipboard; import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard; -import com.boydti.fawe.object.clipboard.FaweClipboard; +import com.boydti.fawe.object.clipboard.LinearClipboard; import com.boydti.fawe.object.clipboard.MemoryOptimizedClipboard; import com.boydti.fawe.object.io.FastByteArrayOutputStream; import com.boydti.fawe.object.io.FastByteArraysInputStream; @@ -200,7 +200,7 @@ public class SchematicStreamer extends NBTStreamer { } private void fixStates() { - fc.forEach(new FaweClipboard.BlockReader() { + fc.forEach(new LinearClipboard.BlockReader() { @Override public > void run(int x, int y, int z, B block) { BlockType type = block.getBlockType(); @@ -360,9 +360,9 @@ public class SchematicStreamer extends NBTStreamer { private int offsetZ; private BlockArrayClipboard clipboard; - private FaweClipboard fc; + private LinearClipboard fc; - private FaweClipboard setupClipboard(int size) { + private LinearClipboard setupClipboard(int size) { if (fc != null) { if (fc.getDimensions().getX() == 0) { fc.setDimensions(BlockVector3.at(size, 1, 1)); @@ -370,11 +370,11 @@ public class SchematicStreamer extends NBTStreamer { return fc; } if (Settings.IMP.CLIPBOARD.USE_DISK) { - return fc = new DiskOptimizedClipboard(size, 1, 1, uuid); + return fc = new DiskOptimizedClipboard(BlockVector3.at(size, 1, 1), uuid); } else if (Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL == 0) { - return fc = new CPUOptimizedClipboard(size, 1, 1); + return fc = new CPUOptimizedClipboard(BlockVector3.at(size, 1, 1)); } else { - return fc = new MemoryOptimizedClipboard(size, 1, 1); + return fc = new MemoryOptimizedClipboard(BlockVector3.at(size, 1, 1)); } } @@ -390,7 +390,7 @@ public class SchematicStreamer extends NBTStreamer { return BlockVector3.at(width, height, length); } - public void setClipboard(FaweClipboard clipboard) { + public void setClipboard(LinearClipboard clipboard) { this.fc = clipboard; } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/ErodeBrush.java b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/ErodeBrush.java index 0b70366cd..d52a9c674 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/ErodeBrush.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/ErodeBrush.java @@ -1,7 +1,7 @@ package com.boydti.fawe.object.brush; import com.boydti.fawe.object.clipboard.CPUOptimizedClipboard; -import com.boydti.fawe.object.clipboard.FaweClipboard; +import com.boydti.fawe.object.clipboard.LinearClipboard; import com.boydti.fawe.object.clipboard.OffsetFaweClipboard; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.MaxChangedBlocksException; @@ -40,8 +40,8 @@ public class ErodeBrush implements Brush { int brushSize = (int) size + 1; int brushSizeSquared = (int) (size * size); int dimension = brushSize * 2 + 1; - FaweClipboard buffer1 = new OffsetFaweClipboard(new CPUOptimizedClipboard(dimension, dimension, dimension), brushSize); - FaweClipboard buffer2 = new OffsetFaweClipboard(new CPUOptimizedClipboard(dimension, dimension, dimension), brushSize); + LinearClipboard buffer1 = new OffsetFaweClipboard(new CPUOptimizedClipboard(dimension, dimension, dimension), brushSize); + LinearClipboard buffer2 = new OffsetFaweClipboard(new CPUOptimizedClipboard(dimension, dimension, dimension), brushSize); final int bx = target.getBlockX(); final int by = target.getBlockY(); @@ -70,9 +70,9 @@ public class ErodeBrush implements Brush { fillIteration(brushSize, brushSizeSquared, fillFaces, swap % 2 == 0 ? buffer1 : buffer2, swap % 2 == 1 ? buffer1 : buffer2); swap++; } - FaweClipboard finalBuffer = swap % 2 == 0 ? buffer1 : buffer2; + LinearClipboard finalBuffer = swap % 2 == 0 ? buffer1 : buffer2; - finalBuffer.forEach(new FaweClipboard.BlockReader() { + finalBuffer.forEach(new LinearClipboard.BlockReader() { @Override public > void run(int x, int y, int z, B block) { es.setBlock(x + bx, y + by, z + bz, block); @@ -81,7 +81,7 @@ public class ErodeBrush implements Brush { } private void fillIteration(int brushSize, int brushSizeSquared, int fillFaces, - FaweClipboard current, FaweClipboard target) { + LinearClipboard current, LinearClipboard target) { int[] frequency = null; for (int x = -brushSize; x <= brushSize; x++) { int x2 = x * x; @@ -126,7 +126,7 @@ public class ErodeBrush implements Brush { } private void erosionIteration(int brushSize, int brushSizeSquared, int erodeFaces, - FaweClipboard current, FaweClipboard target) { + LinearClipboard current, LinearClipboard target) { int[] frequency = null; for (int x = -brushSize; x <= brushSize; x++) { int x2 = x * x; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/AbstractDelegateFaweClipboard.java b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/AbstractDelegateFaweClipboard.java deleted file mode 100644 index 6d9bd9b52..000000000 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/AbstractDelegateFaweClipboard.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.boydti.fawe.object.clipboard; - -import com.boydti.fawe.jnbt.NBTStreamer; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.entity.BaseEntity; -import com.sk89q.worldedit.entity.Entity; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.block.BaseBlock; -import com.sk89q.worldedit.world.block.BlockStateHolder; -import java.util.List; - -public class AbstractDelegateFaweClipboard extends FaweClipboard { - private final FaweClipboard parent; - - public AbstractDelegateFaweClipboard(FaweClipboard parent) { - this.parent = parent; - } - - @Override - public BaseBlock getBlock(int x, int y, int z) { - return parent.getBlock(x, y, z); - } - - @Override - public > boolean setBlock(int x, int y, int z, B block) { - return parent.setBlock(x, y, z, block); - } - - @Override - public > boolean setBlock(int index, B block) { - return parent.setBlock(index, block); - } - - @Override - public boolean hasBiomes() { - return parent.hasBiomes(); - } - - @Override - public boolean setBiome(int x, int z, BiomeType biome) { - return parent.setBiome(x, z, biome); - } - - @Override - public BiomeType getBiome(int x, int z) { - return parent.getBiome(x, z); - } - - @Override - public BiomeType getBiome(int index) { - return parent.getBiome(index); - } - - @Override - public BaseBlock getBlock(int index) { - return parent.getBlock(index); - } - - @Override - public void setBiome(int index, BiomeType biome) { - parent.setBiome(index, biome); - } - - @Override - public boolean setTile(int x, int y, int z, CompoundTag tag) { - return parent.setTile(x, y, z, tag); - } - - @Override - public Entity createEntity(Extent world, double x, double y, double z, float yaw, float pitch, BaseEntity entity) { - return parent.createEntity(world, x, y, z, yaw, pitch, entity); - } - - @Override - public List getEntities() { - return parent.getEntities(); - } - - @Override - public boolean remove(ClipboardEntity clipboardEntity) { - return parent.remove(clipboardEntity); - } - - @Override - public void setOrigin(BlockVector3 offset) { - parent.setOrigin(offset); - } - - @Override - public void setDimensions(BlockVector3 dimensions) { - parent.setDimensions(dimensions); - } - - @Override - public void flush() { - parent.flush(); - } - - @Override - public void close() { - parent.close(); - } - - @Override - public BlockVector3 getDimensions() { - return parent.getDimensions(); - } - - @Override - public void forEach(BlockReader task, boolean air) { - parent.forEach(task, air); - } - - @Override - public void streamBiomes(NBTStreamer.ByteReader task) { - parent.streamBiomes(task); - } - - @Override - public void streamCombinedIds(NBTStreamer.ByteReader task) { - parent.streamCombinedIds(task); - } - - @Override - public List getTileEntities() { - return parent.getTileEntities(); - } -} diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/CPUOptimizedClipboard.java b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/CPUOptimizedClipboard.java index 3eaab8e9d..2d19b80fe 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/CPUOptimizedClipboard.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/CPUOptimizedClipboard.java @@ -9,40 +9,38 @@ import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; +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 javax.annotation.Nullable; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.UUID; -public class CPUOptimizedClipboard extends FaweClipboard { - private int length; - private int height; - private int width; - private int area; - private int volume; +public class CPUOptimizedClipboard extends LinearClipboard { private BiomeType[] biomes = null; - private int[] states; + private char[] states; private final HashMap nbtMapLoc; private final HashMap nbtMapIndex; - private final HashSet entities; + private final HashSet entities; - public CPUOptimizedClipboard(int width, int height, int length) { - this.width = width; - this.height = height; - this.length = length; - this.area = width * length; - this.volume = area * height; - this.states = new int[volume]; + public CPUOptimizedClipboard(BlockVector3 dimensions) { + super(dimensions); + this.states = new char[getVolume()]; nbtMapLoc = new HashMap<>(); nbtMapIndex = new HashMap<>(); entities = new HashSet<>(); @@ -54,7 +52,7 @@ public class CPUOptimizedClipboard extends FaweClipboard { } @Override - public boolean setBiome(int x, int z, BiomeType biome) { + public boolean setBiome(int x, int y, int z, BiomeType biome) { setBiome(getIndex(x, 0, z), biome); return true; } @@ -62,7 +60,7 @@ public class CPUOptimizedClipboard extends FaweClipboard { @Override public void setBiome(int index, BiomeType biome) { if (biomes == null) { - biomes = new BiomeType[area]; + biomes = new BiomeType[getArea()]; } biomes[index] = biome; } @@ -71,8 +69,8 @@ public class CPUOptimizedClipboard extends FaweClipboard { public void streamBiomes(NBTStreamer.ByteReader task) { if (!hasBiomes()) return; int index = 0; - for (int z = 0; z < length; z++) { - for (int x = 0; x < width; x++, index++) { + for (int z = 0; z < getLength(); z++) { + for (int x = 0; x < getWidth(); x++, index++) { task.run(index, biomes[index].getInternalId()); } } @@ -87,7 +85,7 @@ public class CPUOptimizedClipboard extends FaweClipboard { } @Override - public BiomeType getBiome(int x, int z) { + public BiomeType getBiomeType(int x, int z) { return getBiome(getIndex(x, 0, z)); } @@ -107,70 +105,51 @@ public class CPUOptimizedClipboard extends FaweClipboard { return nbtMapIndex.get(index); } - @Override - public void setDimensions(BlockVector3 dimensions) { - width = dimensions.getBlockX(); - height = dimensions.getBlockY(); - length = dimensions.getBlockZ(); - area = width * length; - int newVolume = area * height; - if (newVolume != volume) { - volume = newVolume; - states = new int[volume]; - } - } - - @Override - public BlockVector3 getDimensions() { - return BlockVector3.at(width, height, length); - } - private int yLast; private int yLastI; private int zLast; private int zLastI; public int getIndex(int x, int y, int z) { - return x + ((yLast == y) ? yLastI : (yLastI = (yLast = y) * area)) + ((zLast == z) ? zLastI - : (zLastI = (zLast = z) * width)); + return x + ((yLast == y) ? yLastI : (yLastI = (yLast = y) * getArea())) + ((zLast == z) ? zLastI + : (zLastI = (zLast = z) * getWidth())); } @Override - public BaseBlock getBlock(int x, int y, int z) { + public BaseBlock getFullBlock(int x, int y, int z) { int index = getIndex(x, y, z); - return getBlock(index); + return getFullBlock(index); } @Override - public BaseBlock getBlock(int index) { - int combinedId = states[index]; - BlockType type = BlockTypes.getFromStateId(combinedId); - BaseBlock base = type.withStateId(combinedId).toBaseBlock(); - if (type.getMaterial().hasContainer()) { + public BaseBlock getFullBlock(int index) { + char ordinal = states[index]; + BlockState state = BlockState.getFromOrdinal(ordinal); + if (state.getMaterial().hasContainer()) { CompoundTag nbt = getTag(index); if (nbt != null) { - return base.toBaseBlock(nbt); + return state.toBaseBlock(nbt); } } - return base; + return state.toBaseBlock(); } @Override public void forEach(final BlockReader task, boolean air) { if (air) { - for (int y = 0, index = 0; y < height; y++) { - for (int z = 0; z < length; z++) { - for (int x = 0; x < width; x++, index++) { - BaseBlock block = getBlock(index); + for (int y = 0, index = 0; y < getHeight(); y++) { + for (int z = 0; z < getLength(); z++) { + for (int x = 0; x < getWidth(); x++, index++) { + BaseBlock block = getFullBlock(index); task.run(x, y, z, block); } } } } else { - for (int y = 0, index = 0; y < height; y++) { - for (int z = 0; z < length; z++) { - for (int x = 0; x < width; x++, index++) { - BaseBlock block = getBlock(index); + for (int y = 0, index = 0; y < getHeight(); y++) { + for (int z = 0; z < getLength(); z++) { + for (int x = 0; x < getWidth(); x++, index++) { + BaseBlock block = getFullBlock(index); if (!block.getMaterial().isAir()) { task.run(x, y, z, block); } @@ -181,11 +160,11 @@ public class CPUOptimizedClipboard extends FaweClipboard { } @Override - public void streamCombinedIds(NBTStreamer.ByteReader task) { + public void streamOrdinals(NBTStreamer.ByteReader task) { int index = 0; - for (int y = 0; y < height; y++) { - for (int z = 0; z < length; z++) { - for (int x = 0; x < width; x++) { + for (int y = 0; y < getHeight(); y++) { + for (int z = 0; z < getLength(); z++) { + for (int x = 0; x < getWidth(); x++) { task.run(index, states[index++]); } } @@ -200,10 +179,10 @@ public class CPUOptimizedClipboard extends FaweClipboard { CompoundTag tag = entry.getValue(); Map values = ReflectionUtils.getMap(tag.getValue()); if (!values.containsKey("x")) { - int y = index / area; - index -= y * area; - int z = index / width; - int x = index - (z * width); + int y = index / getArea(); + index -= y * getArea(); + int z = index / getWidth(); + int x = index - (z * getWidth()); values.put("x", new IntTag(x)); values.put("y", new IntTag(y)); values.put("z", new IntTag(z)); @@ -234,7 +213,7 @@ public class CPUOptimizedClipboard extends FaweClipboard { @Override public > boolean setBlock(int index, B block) { - states[index] = block.getInternalId(); + states[index] = block.getOrdinalChar(); boolean hasNbt = block instanceof BaseBlock && block.hasNbtData(); if (hasNbt) { setTile(index, block.getNbtData()); @@ -242,9 +221,10 @@ public class CPUOptimizedClipboard extends FaweClipboard { return true; } + @Nullable @Override - public Entity createEntity(Extent world, double x, double y, double z, float yaw, float pitch, BaseEntity entity) { - FaweClipboard.ClipboardEntity ret = new ClipboardEntity(world, x, y, z, yaw, pitch, entity); + public Entity createEntity(Location location, BaseEntity entity) { + BlockArrayClipboard.ClipboardEntity ret = new BlockArrayClipboard.ClipboardEntity(location, entity); entities.add(ret); return ret; } @@ -255,7 +235,21 @@ public class CPUOptimizedClipboard extends FaweClipboard { } @Override - public boolean remove(ClipboardEntity clipboardEntity) { - return entities.remove(clipboardEntity); + public void removeEntity(Entity entity) { + this.entities.remove(entity); + } + + @Nullable + @Override + public void removeEntity(int x, int y, int z, UUID uuid) { + Iterator iter = this.entities.iterator(); + while (iter.hasNext()) { + BlockArrayClipboard.ClipboardEntity entity = iter.next(); + UUID entUUID = entity.getState().getNbtData().getUUID(); + if (uuid.equals(entUUID)) { + iter.remove(); + return; + } + } } } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/DelegateClipboard.java b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/DelegateClipboard.java new file mode 100644 index 000000000..84ad50923 --- /dev/null +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/DelegateClipboard.java @@ -0,0 +1,169 @@ +package com.boydti.fawe.object.clipboard; + +import com.boydti.fawe.beta.IBatchProcessor; +import com.boydti.fawe.jnbt.NBTStreamer; +import com.boydti.fawe.object.changeset.FaweChangeSet; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.function.generator.GenBase; +import com.sk89q.worldedit.function.generator.Resource; +import com.sk89q.worldedit.function.mask.Mask; +import com.sk89q.worldedit.function.operation.Operation; +import com.sk89q.worldedit.function.pattern.Pattern; +import com.sk89q.worldedit.math.BlockVector2; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.session.ClipboardHolder; +import com.sk89q.worldedit.util.Countable; +import com.sk89q.worldedit.util.Location; +import com.sk89q.worldedit.world.biome.BiomeType; +import com.sk89q.worldedit.world.block.BaseBlock; +import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockStateHolder; +import com.sk89q.worldedit.world.block.BlockType; + +import javax.annotation.Nullable; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +public class DelegateClipboard implements Clipboard { + private final Clipboard parent; + + public DelegateClipboard(Clipboard parent) { + this.parent = parent; + } + + public Clipboard getParent() { + return parent; + } + + @Override + public void setOrigin(BlockVector3 offset) { + parent.setOrigin(offset); + } + + @Override + public BlockVector3 getDimensions() { + return parent.getDimensions(); + } + + @Override + public Region getRegion() { + return parent.getRegion(); + } + + @Override + public BlockVector3 getOrigin() { + return parent.getOrigin(); + } + + @Override + public boolean hasBiomes() { + return parent.hasBiomes(); + } + + @Override + public void removeEntity(Entity entity) { + parent.removeEntity(entity); + } + + @Override + public BlockVector3 getMinimumPoint() { + return parent.getMinimumPoint(); + } + + @Override + public BlockVector3 getMaximumPoint() { + return parent.getMaximumPoint(); + } + + @Override + public List getEntities(Region region) { + return parent.getEntities(region); + } + + @Override + public List getEntities() { + return parent.getEntities(); + } + + @Override + @Nullable + public Entity createEntity(Location location, BaseEntity entity) { + return parent.createEntity(location, entity); + } + + @Override + @Nullable + public void removeEntity(int x, int y, int z, UUID uuid) { + parent.removeEntity(x, y, z, uuid); + } + + @Override + public boolean isWorld() { + return parent.isWorld(); + } + + @Override + public BlockState getBlock(BlockVector3 position) { + return parent.getBlock(position); + } + + @Override + public BlockState getBlock(int x, int y, int z) { + return parent.getBlock(x, y, z); + } + + @Override + public BaseBlock getFullBlock(BlockVector3 position) { + return parent.getFullBlock(position); + } + + @Override + public BaseBlock getFullBlock(int x, int y, int z) { + return parent.getFullBlock(x, y, z); + } + + @Override + public BiomeType getBiome(BlockVector2 position) { + return parent.getBiome(position); + } + + @Override + public BiomeType getBiomeType(int x, int z) { + return parent.getBiomeType(x, z); + } + + @Override + @Deprecated + public > boolean setBlock(BlockVector3 position, T block) throws WorldEditException { + return parent.setBlock(position, block); + } + + @Override + public > boolean setBlock(int x, int y, int z, T block) throws WorldEditException { + return parent.setBlock(x, y, z, block); + } + + @Override + public boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException { + return parent.setTile(x, y, z, tile); + } + + @Override + public boolean setBiome(BlockVector2 position, BiomeType biome) { + return parent.setBiome(position, biome); + } + + @Override + public boolean setBiome(int x, int y, int z, BiomeType biome) { + return parent.setBiome(x, y, z, biome); + } +} diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/DiskOptimizedClipboard.java b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/DiskOptimizedClipboard.java index 7f581f4e1..6bf6fd00c 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/DiskOptimizedClipboard.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/DiskOptimizedClipboard.java @@ -15,6 +15,8 @@ import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeTypes; import com.sk89q.worldedit.world.block.BaseBlock; @@ -22,8 +24,13 @@ 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 javax.annotation.Nullable; import java.io.Closeable; +import java.io.DataInputStream; import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.lang.reflect.Field; @@ -34,6 +41,7 @@ import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.UUID; @@ -43,18 +51,12 @@ import java.util.UUID; * - Uses an auto closable RandomAccessFile for getting / setting id / data * - I don't know how to reduce nbt / entities to O(2) complexity, so it is stored in memory. */ -public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { +public class DiskOptimizedClipboard extends LinearClipboard implements Closeable { private static int HEADER_SIZE = 14; - protected int length; - protected int height; - protected int width; - protected int area; - protected int volume; - private final HashMap nbtMap; - private final HashSet entities; + private final HashSet entities; private final File file; private RandomAccessFile braf; @@ -63,11 +65,60 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { private FileChannel fileChannel; private boolean hasBiomes; - public DiskOptimizedClipboard(int width, int height, int length, UUID uuid) { - this(width, height, length, MainUtil.getFile(Fawe.get() != null ? Fawe.imp().getDirectory() : new File("."), Settings.IMP.PATHS.CLIPBOARD + File.separator + uuid + ".bd")); + public DiskOptimizedClipboard(BlockVector3 dimensions, UUID uuid) { + this(dimensions, MainUtil.getFile(Fawe.get() != null ? Fawe.imp().getDirectory() : new File("."), Settings.IMP.PATHS.CLIPBOARD + File.separator + uuid + ".bd")); + } + + public DiskOptimizedClipboard(BlockVector3 dimensions) { + this(dimensions, MainUtil.getFile(Fawe.imp() != null ? Fawe.imp().getDirectory() : new File("."), Settings.IMP.PATHS.CLIPBOARD + File.separator + UUID.randomUUID() + ".bd")); + } + + public DiskOptimizedClipboard(BlockVector3 dimensions, File file) { + super(dimensions); + if (getWidth() > Character.MAX_VALUE || getHeight() > Character.MAX_VALUE || getLength() > Character.MAX_VALUE) { + throw new IllegalArgumentException("Too large"); + } + try { + nbtMap = new HashMap<>(); + entities = new HashSet<>(); + this.file = file; + try { + if (!file.exists()) { + File parent = file.getParentFile(); + if (parent != null) { + file.getParentFile().mkdirs(); + } + file.createNewFile(); + } + } catch (Exception e) { + e.printStackTrace(); + } + this.braf = new RandomAccessFile(file, "rw"); + long volume = (long) getArea() * 2L + (long) HEADER_SIZE; + braf.setLength(0); + braf.setLength(volume); + init(); + // write getLength() etc + byteBuffer.putChar(2, (char) getWidth()); + byteBuffer.putChar(4, (char) getHeight()); + byteBuffer.putChar(6, (char) getLength()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static BlockVector3 readSize(File file) { + try (DataInputStream is = new DataInputStream(new FileInputStream(file))) { + is.skipBytes(2); + return BlockVector3.at(is.readChar(), is.readChar(), is.readChar()); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } } public DiskOptimizedClipboard(File file) { + super(readSize(file)); try { nbtMap = new HashMap<>(); entities = new HashSet<>(); @@ -75,13 +126,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { this.braf = new RandomAccessFile(file, "rw"); braf.setLength(file.length()); init(); - width = byteBuffer.getChar(2); - height = byteBuffer.getChar(4); - length = byteBuffer.getChar(6); - area = width * length; - this.volume = length * width * height; - - if (braf.length() - HEADER_SIZE == (volume << 2) + area) { + if (braf.length() - HEADER_SIZE == (getVolume() << 1) + getArea()) { hasBiomes = true; } autoCloseTask(); @@ -107,7 +152,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { hasBiomes = true; close(); this.braf = new RandomAccessFile(file, "rw"); - this.braf.setLength(HEADER_SIZE + (volume << 2) + area); + this.braf.setLength(HEADER_SIZE + (getVolume() << 1) + getArea()); init(); } catch (IOException e) { e.printStackTrace(); @@ -123,7 +168,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { } @Override - public boolean setBiome(int x, int z, BiomeType biome) { + public boolean setBiome(int x, int y, int z, BiomeType biome) { setBiome(getIndex(x, 0, z), biome); return true; } @@ -131,7 +176,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { @Override public void setBiome(int index, BiomeType biome) { if (initBiome()) { - byteBuffer.put(HEADER_SIZE + (volume << 2) + index, (byte) biome.getInternalId()); + byteBuffer.put(HEADER_SIZE + (getVolume() << 1) + index, (byte) biome.getInternalId()); } } @@ -140,7 +185,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { if (!hasBiomes()) { return null; } - int biomeId = byteBuffer.get(HEADER_SIZE + (volume << 2) + index) & 0xFF; + int biomeId = byteBuffer.get(HEADER_SIZE + (getVolume() << 1) + index) & 0xFF; return BiomeTypes.get(biomeId); } @@ -148,9 +193,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { public void streamBiomes(NBTStreamer.ByteReader task) { if (!hasBiomes()) return; int index = 0; - int mbbIndex = HEADER_SIZE + (volume << 2); - for (int z = 0; z < length; z++) { - for (int x = 0; x < width; x++, index++, mbbIndex++) { + int mbbIndex = HEADER_SIZE + (getVolume() << 1); + for (int z = 0; z < getLength(); z++) { + for (int x = 0; x < getWidth(); x++, index++, mbbIndex++) { int biome = byteBuffer.get(mbbIndex) & 0xFF; task.run(index, biome); } @@ -158,18 +203,13 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { } @Override - public BiomeType getBiome(int x, int z) { + public BiomeType getBiomeType(int x, int z) { return getBiome(getIndex(x, 0, z)); } - @Override - public BlockVector3 getDimensions() { - return BlockVector3.at(width, height, length); - } - public BlockArrayClipboard toClipboard() { try { - CuboidRegion region = new CuboidRegion(BlockVector3.at(0, 0, 0), BlockVector3.at(width - 1, height - 1, length - 1)); + CuboidRegion region = new CuboidRegion(BlockVector3.at(0, 0, 0), BlockVector3.at(getWidth() - 1, getHeight() - 1, getLength() - 1)); int ox = byteBuffer.getShort(8); int oy = byteBuffer.getShort(10); int oz = byteBuffer.getShort(12); @@ -182,45 +222,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { return null; } - public DiskOptimizedClipboard(int width, int height, int length, File file) { - try { - nbtMap = new HashMap<>(); - entities = new HashSet<>(); - this.file = file; - this.width = width; - this.height = height; - this.length = length; - this.area = width * length; - this.volume = width * length * height; - try { - if (!file.exists()) { - File parent = file.getParentFile(); - if (parent != null) { - file.getParentFile().mkdirs(); - } - file.createNewFile(); - } - } catch (Exception e) { - e.printStackTrace(); - } - this.braf = new RandomAccessFile(file, "rw"); - long volume = (long) width * (long) height * (long) length * 4L + (long) HEADER_SIZE; - braf.setLength(0); - braf.setLength(volume); - if (width * height * length != 0) { - init(); - // write length etc - byteBuffer.putChar(2, (char) width); - byteBuffer.putChar(4, (char) height); - byteBuffer.putChar(6, (char) length); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - @Override public void setOrigin(BlockVector3 offset) { + super.setOrigin(offset); try { byteBuffer.putShort(8, (short) offset.getBlockX()); byteBuffer.putShort(10, (short) offset.getBlockY()); @@ -230,38 +234,11 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { } } - @Override - public void setDimensions(BlockVector3 dimensions) { - try { - width = dimensions.getBlockX(); - height = dimensions.getBlockY(); - length = dimensions.getBlockZ(); - area = width * length; - volume = width * length * height; - long size = width * height * length * 4L + HEADER_SIZE + (hasBiomes() ? area : 0); - if (braf.length() < size) { - close(); - this.braf = new RandomAccessFile(file, "rw"); - braf.setLength(size); - init(); - } - byteBuffer.putChar(2, (char) width); - byteBuffer.putChar(4, (char) height); - byteBuffer.putChar(6, (char) length); - } catch (IOException e) { - e.printStackTrace(); - } - } - @Override public void flush() { byteBuffer.force(); } - public DiskOptimizedClipboard(int width, int height, int length) { - this(width, height, length, MainUtil.getFile(Fawe.imp() != null ? Fawe.imp().getDirectory() : new File("."), Settings.IMP.PATHS.CLIPBOARD + File.separator + UUID.randomUUID() + ".bd")); - } - private void closeDirectBuffer(ByteBuffer cb) { if (cb == null || !cb.isDirect()) return; // we could use this type cast and call functions without reflection code, @@ -287,11 +264,6 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { } } - @Override - protected void finalize() throws Throwable { - close(); - } - @Override public void close() { try { @@ -332,16 +304,16 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { private int zlasti; @Override - public void streamCombinedIds(NBTStreamer.ByteReader task) { + public void streamOrdinals(NBTStreamer.ByteReader task) { try { byteBuffer.force(); int pos = HEADER_SIZE; int index = 0; - for (int y = 0; y < height; y++) { - for (int z = 0; z < length; z++) { - for (int x = 0; x < width; x++, pos += 4) { - int combinedId = byteBuffer.getInt(pos); - task.run(index++, combinedId); + for (int y = 0; y < getHeight(); y++) { + for (int z = 0; z < getLength(); z++) { + for (int x = 0; x < getWidth(); x++, pos += 2) { + char ordinal = byteBuffer.getChar(pos); + task.run(index++, ordinal); } } } @@ -363,13 +335,12 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { final boolean hasTile = !nbtMap.isEmpty(); if (air) { if (hasTile) { - for (int y = 0; y < height; y++) { - for (int z = 0; z < length; z++) { - for (int x = 0; x < width; x++, pos += 4) { - int combinedId = byteBuffer.getInt(pos); - BlockType type = BlockTypes.getFromStateId(combinedId); - BlockState state = type.withStateId(combinedId); - if (type.getMaterial().hasContainer()) { + for (int y = 0; y < getHeight(); y++) { + for (int z = 0; z < getLength(); z++) { + for (int x = 0; x < getWidth(); x++, pos += 2) { + int combinedId = byteBuffer.getChar(pos); + BlockState state = BlockState.getFromOrdinal(combinedId); + if (state.getMaterial().hasContainer()) { trio.set(x, y, z); CompoundTag nbt = nbtMap.get(trio); if (nbt != null) { @@ -382,31 +353,28 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { } } } else { - for (int y = 0; y < height; y++) { - for (int z = 0; z < length; z++) { - for (int x = 0; x < width; x++, pos += 4) { - int combinedId = byteBuffer.getInt(pos); - BlockState state = BlockState.getFromInternalId(combinedId); + for (int y = 0; y < getHeight(); y++) { + for (int z = 0; z < getLength(); z++) { + for (int x = 0; x < getWidth(); x++, pos += 2) { + int combinedId = byteBuffer.getChar(pos); + BlockState state = BlockState.getFromOrdinal(combinedId); task.run(x, y, z, state); } } } } } else { - for (int y = 0; y < height; y++) { - for (int z = 0; z < length; z++) { - for (int x = 0; x < width; x++, pos += 4) { - int combinedId = byteBuffer.getInt(pos); - BlockType type = BlockTypes.getFromStateId(combinedId); - if (!type.getMaterial().isAir()) { - BlockState state = type.withStateId(combinedId); - if (type.getMaterial().hasContainer()) { - trio.set(x, y, z); - CompoundTag nbt = nbtMap.get(trio); - if (nbt != null) { - task.run(x, y, z, state.toBaseBlock(nbt)); - continue; - } + for (int y = 0; y < getHeight(); y++) { + for (int z = 0; z < getLength(); z++) { + for (int x = 0; x < getWidth(); x++, pos += 2) { + char combinedId = byteBuffer.getChar(pos); + BlockState state = BlockState.getFromOrdinal(combinedId); + if (state.getMaterial().hasContainer()) { + trio.set(x, y, z); + CompoundTag nbt = nbtMap.get(trio); + if (nbt != null) { + task.run(x, y, z, state.toBaseBlock(nbt)); + continue; } task.run(x, y, z, state); } @@ -417,24 +385,21 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { } public int getIndex(int x, int y, int z) { - return x + (ylast == y ? ylasti : (ylasti = (ylast = y) * area)) + (zlast == z - ? zlasti : (zlasti = (zlast = z) * width)); + return x + (ylast == y ? ylasti : (ylasti = (ylast = y) * getArea())) + (zlast == z + ? zlasti : (zlasti = (zlast = z) * getWidth())); } @Override - public BaseBlock getBlock(int x, int y, int z) { + public BaseBlock getFullBlock(int x, int y, int z) { try { - int index = HEADER_SIZE + (getIndex(x, y, z) << 2); - int combinedId = byteBuffer.getInt(index); - BlockType type = BlockTypes.getFromStateId(combinedId); - BaseBlock base = type.withStateId(combinedId).toBaseBlock(); - if (type.getMaterial().hasContainer() && !nbtMap.isEmpty()) { + int index = HEADER_SIZE + (getIndex(x, y, z) << 1); + int combinedId = byteBuffer.getChar(index); + BlockState state = BlockState.getFromOrdinal(combinedId); + if (state.getMaterial().hasContainer() && !nbtMap.isEmpty()) { CompoundTag nbt = nbtMap.get(new IntegerTrio(x, y, z)); - if (nbt != null) { - return base.toBaseBlock(nbt); - } + return state.toBaseBlock(nbt); } - return base; + return state.toBaseBlock(); } catch (IndexOutOfBoundsException ignore) { } catch (Exception e) { e.printStackTrace(); @@ -443,13 +408,12 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { } @Override - public BaseBlock getBlock(int i) { + public BaseBlock getFullBlock(int i) { try { - int diskIndex = HEADER_SIZE + (i << 2); - int combinedId = byteBuffer.getInt(diskIndex); - BlockType type = BlockTypes.getFromStateId(combinedId); - BaseBlock base = type.withStateId(combinedId).toBaseBlock(); - if (type.getMaterial().hasContainer() && !nbtMap.isEmpty()) { + int diskIndex = HEADER_SIZE + (i << 1); + char ordinal = byteBuffer.getChar(diskIndex); + BlockState state = BlockState.getFromOrdinal(ordinal); + if (state.getMaterial().hasContainer() && !nbtMap.isEmpty()) { CompoundTag nbt; if (nbtMap.size() < 4) { nbt = null; @@ -462,18 +426,18 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { } } } else { - // x + z * width + y * area; - int y = i / area; - int newI = i - y * area; - int z = newI / width; - int x = newI - z * width; + // x + z * getWidth() + y * area; + int y = i / getArea(); + int newI = i - y * getArea(); + int z = newI / getWidth(); + int x = newI - z * getWidth(); nbt = nbtMap.get(new IntegerTrio(x, y, z)); } if (nbt != null) { - return base.toBaseBlock(nbt); + return state.toBaseBlock(nbt); } } - return base; + return state.toBaseBlock(); } catch (IndexOutOfBoundsException ignore) { } catch (Exception e) { e.printStackTrace(); @@ -494,9 +458,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { @Override public > boolean setBlock(int x, int y, int z, B block) { try { - int index = HEADER_SIZE + (getIndex(x, y, z) << 2); - int combined = block.getInternalId(); - byteBuffer.putInt(index, combined); + int index = HEADER_SIZE + (getIndex(x, y, z) << 1); + char ordinal = block.getOrdinalChar(); + byteBuffer.putChar(index, ordinal); boolean hasNbt = block instanceof BaseBlock && block.hasNbtData(); if (hasNbt) { setTile(x, y, z, block.getNbtData()); @@ -511,15 +475,15 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { @Override public > boolean setBlock(int i, B block) { try { - int combined = block.getInternalId(); - int index = HEADER_SIZE + (i << 2); - byteBuffer.putInt(index, combined); + char ordinal = block.getOrdinalChar(); + int index = HEADER_SIZE + (i << 1); + byteBuffer.putChar(index, ordinal); boolean hasNbt = block instanceof BaseBlock && block.hasNbtData(); if (hasNbt) { - int y = i / area; - int newI = i - y * area; - int z = newI / width; - int x = newI - z * width; + int y = i / getArea(); + int newI = i - y * getArea(); + int z = newI / getWidth(); + int x = newI - z * getWidth(); setTile(x, y, z, block.getNbtData()); } return true; @@ -529,9 +493,10 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { return false; } + @Nullable @Override - public Entity createEntity(Extent world, double x, double y, double z, float yaw, float pitch, BaseEntity entity) { - FaweClipboard.ClipboardEntity ret = new ClipboardEntity(world, x, y, z, yaw, pitch, entity); + public Entity createEntity(Location location, BaseEntity entity) { + BlockArrayClipboard.ClipboardEntity ret = new BlockArrayClipboard.ClipboardEntity(location, entity); entities.add(ret); return ret; } @@ -542,7 +507,21 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable { } @Override - public boolean remove(ClipboardEntity clipboardEntity) { - return entities.remove(clipboardEntity); + public void removeEntity(Entity entity) { + this.entities.remove(entity); + } + + @Nullable + @Override + public void removeEntity(int x, int y, int z, UUID uuid) { + Iterator iter = this.entities.iterator(); + while (iter.hasNext()) { + BlockArrayClipboard.ClipboardEntity entity = iter.next(); + UUID entUUID = entity.getState().getNbtData().getUUID(); + if (uuid.equals(entUUID)) { + iter.remove(); + return; + } + } } } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/FaweClipboard.java b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/FaweClipboard.java deleted file mode 100644 index 75011e299..000000000 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/FaweClipboard.java +++ /dev/null @@ -1,179 +0,0 @@ -package com.boydti.fawe.object.clipboard; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.boydti.fawe.jnbt.NBTStreamer; -import com.boydti.fawe.util.ReflectionUtils; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.IntTag; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.entity.BaseEntity; -import com.sk89q.worldedit.entity.Entity; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.util.Location; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.block.BaseBlock; -import com.sk89q.worldedit.world.block.BlockStateHolder; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import javax.annotation.Nullable; - -public abstract class FaweClipboard { - public abstract BaseBlock getBlock(int x, int y, int z); - - public abstract > boolean setBlock(int index, B block); - - public abstract > boolean setBlock(int x, int y, int z, B block); - - /** - * Returns true if the clipboard has biome data. This can be checked since {@link Extent#getBiome(BlockVector2)} - * strongly suggests returning {@link com.sk89q.worldedit.world.biome.BiomeTypes#OCEAN} instead of {@code null} - * if biomes aren't present. However, it might not be desired to set areas to ocean if the clipboard is defaulting - * to ocean, instead of having biomes explicitly set. - * - * @return true if the clipboard has biome data set - */ - public boolean hasBiomes() { - return false; - } - - public abstract boolean setBiome(int x, int z, BiomeType biome); - - public abstract BiomeType getBiome(int x, int z); - - public abstract BiomeType getBiome(int index); - - public abstract BaseBlock getBlock(int index); - - public abstract void setBiome(int index, BiomeType biome); - - public abstract boolean setTile(int x, int y, int z, CompoundTag tag); - - public abstract Entity createEntity(Extent world, double x, double y, double z, float yaw, float pitch, BaseEntity entity); - - public abstract List getEntities(); - - public abstract boolean remove(ClipboardEntity clipboardEntity); - - public void setOrigin(BlockVector3 offset) { - } // Do nothing - - public abstract void setDimensions(BlockVector3 dimensions); - - public abstract BlockVector3 getDimensions(); - - /** - * The locations provided are relative to the clipboard min - * - * @param task - * @param air - */ - public abstract void forEach(BlockReader task, boolean air); - - public interface BlockReader { - > void run(int x, int y, int z, B block); - } - - public abstract void streamBiomes(NBTStreamer.ByteReader task); - - public void streamCombinedIds(NBTStreamer.ByteReader task) { - forEach(new BlockReader() { - private int index; - - @Override - public > void run(int x, int y, int z, B block) { - task.run(index++, block.getInternalId()); - } - }, true); - } - - public List getTileEntities() { - final List tiles = new ArrayList<>(); - forEach(new BlockReader() { - - @Override - public > void run(int x, int y, int z, B block) { - if(!(block instanceof BaseBlock)) return; - BaseBlock base = (BaseBlock)block; - CompoundTag tag = base.getNbtData(); - if (tag != null) { - Map values = ReflectionUtils.getMap(tag.getValue()); - values.put("x", new IntTag(x)); - values.put("y", new IntTag(y)); - values.put("z", new IntTag(z)); - tiles.add(tag); - } - } - }, false); - return tiles; - } - - public void close() {} - - public void flush() {} - - /** - * Stores entity data. - */ - public class ClipboardEntity implements Entity { - private final BaseEntity entity; - private final Extent world; - private final double x, y, z; - private final float yaw, pitch; - - public ClipboardEntity(Extent world, double x, double y, double z, float yaw, float pitch, BaseEntity entity) { - checkNotNull(entity); - checkNotNull(world); - this.world = world; - this.x = x; - this.y = y; - this.z = z; - this.yaw = yaw; - this.pitch = pitch; - this.entity = new BaseEntity(entity); - } - - @Override - public boolean remove() { - return FaweClipboard.this.remove(this); - } - - @Nullable - @Override - public T getFacet(Class cls) { - return null; - } - - /** - * Get the entity state. This is not a copy. - * - * @return the entity - */ - BaseEntity getEntity() { - return entity; - } - - @Override - public BaseEntity getState() { - return new BaseEntity(entity); - } - - @Override - public Location getLocation() { - return new Location(world, x, y, z, yaw, pitch); - } - - @Override - public Extent getExtent() { - return world; - } - - @Override - public boolean setLocation(Location location) { - //Should not be teleporting this entity - return false; - } - } -} diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/LinearClipboard.java b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/LinearClipboard.java new file mode 100644 index 000000000..f136981da --- /dev/null +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/LinearClipboard.java @@ -0,0 +1,152 @@ +package com.boydti.fawe.object.clipboard; + +import com.boydti.fawe.jnbt.NBTStreamer; +import com.boydti.fawe.util.ReflectionUtils; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.IntTag; +import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.world.biome.BiomeType; +import com.sk89q.worldedit.world.block.BaseBlock; +import com.sk89q.worldedit.world.block.BlockStateHolder; + +import java.io.Closeable; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Best used when clipboard selections are small, or using legacy formats + * (Small being < Integer.MAX_VALUE/BLOCK_SIZE_BYTES blocks) + */ +public abstract class LinearClipboard implements Clipboard, Closeable { + private final BlockVector3 size; + private final int area; + private final int volume; + private BlockVector3 origin; + + public LinearClipboard(BlockVector3 dimensions) { + this.size = dimensions; + long longVolume = (long) getWidth() * (long) getHeight() * (long) getLength(); + if (longVolume >= Integer.MAX_VALUE >> 2) { + throw new IllegalArgumentException("Dimensions are too large for this clipboard format."); + } + this.area = getWidth() * getLength(); + this.volume = (int) longVolume; + this.origin = BlockVector3.ZERO; + } + + public abstract > boolean setBlock(int i, B block); + + public abstract BaseBlock getFullBlock(int i); + + public abstract void setBiome(int index, BiomeType biome); + + public abstract BiomeType getBiome(int index); + + public void setOrigin(BlockVector3 offset) { + this.origin = offset; + } + + @Override + public BlockVector3 getOrigin() { + return origin; + } + + @Override + public BlockVector3 getMinimumPoint() { + return BlockVector3.ZERO; + } + + @Override + public BlockVector3 getMaximumPoint() { + return size.subtract(BlockVector3.ONE); + } + + @Override + public Region getRegion() { + return new CuboidRegion(BlockVector3.at(0, 0, 0), BlockVector3.at(getWidth() - 1, getHeight() - 1, getLength() - 1)); + } + + public final BlockVector3 getDimensions() { + return size; + } + + public final int getWidth() { + return size.getBlockX(); + } + + public final int getHeight() { + return size.getBlockY(); + } + + public final int getLength() { + return size.getBlockZ(); + } + + public int getArea() { + return area; + } + + public int getVolume() { + return volume; + } + + /** + * The locations provided are relative to the clipboard min + * + * @param task + * @param air + */ + public abstract void forEach(BlockReader task, boolean air); + + public interface BlockReader { + > void run(int x, int y, int z, B block); + } + + public abstract void streamBiomes(NBTStreamer.ByteReader task); + + public void streamOrdinals(NBTStreamer.ByteReader task) { + forEach(new BlockReader() { + private int index; + + @Override + public > void run(int x, int y, int z, B block) { + task.run(index++, block.getOrdinal()); + } + }, true); + } + + public List getTileEntities() { + final List tiles = new ArrayList<>(); + forEach(new BlockReader() { + + @Override + public > void run(int x, int y, int z, B block) { + if(!(block instanceof BaseBlock)) return; + BaseBlock base = (BaseBlock)block; + CompoundTag tag = base.getNbtData(); + if (tag != null) { + Map values = ReflectionUtils.getMap(tag.getValue()); + values.put("x", new IntTag(x)); + values.put("y", new IntTag(y)); + values.put("z", new IntTag(z)); + tiles.add(tag); + } + } + }, false); + return tiles; + } + + public void close() {} + + public void flush() {} + + @Override + protected void finalize() { + close(); + } +} diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/MemoryOptimizedClipboard.java b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/MemoryOptimizedClipboard.java index 7d36969d6..9338079e2 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/MemoryOptimizedClipboard.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/MemoryOptimizedClipboard.java @@ -11,7 +11,9 @@ import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeTypes; import com.sk89q.worldedit.world.block.BaseBlock; @@ -21,22 +23,21 @@ import com.sk89q.worldedit.world.block.BlockTypes; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.UUID; + import net.jpountz.util.SafeUtils; -public class MemoryOptimizedClipboard extends FaweClipboard { +import javax.annotation.Nullable; - private static final int BLOCK_SIZE = 1048576 * 4; +public class MemoryOptimizedClipboard extends LinearClipboard { + + private static final int BLOCK_SIZE = 1048576 * 2; private static final int BLOCK_MASK = 1048575; private static final int BLOCK_SHIFT = 20; - private int length; - private int height; - private int width; - private int area; - private int volume; - private byte[][] states; private byte[] buffer = new byte[MainUtil.getMaxCompressedLength(BLOCK_SIZE)]; @@ -45,7 +46,7 @@ public class MemoryOptimizedClipboard extends FaweClipboard { private final HashMap nbtMapLoc; private final HashMap nbtMapIndex; - private final HashSet entities; + private final HashSet entities; private int lastCombinedIdsI = -1; @@ -55,17 +56,13 @@ public class MemoryOptimizedClipboard extends FaweClipboard { private int compressionLevel; - public MemoryOptimizedClipboard(int width, int height, int length) { - this(width, height, length, Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL); + public MemoryOptimizedClipboard(BlockVector3 dimensions) { + this(dimensions, Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL); } - public MemoryOptimizedClipboard(int width, int height, int length, int compressionLevel) { - this.width = width; - this.height = height; - this.length = length; - this.area = width * length; - this.volume = area * height; - states = new byte[1 + (volume >> BLOCK_SHIFT)][]; + public MemoryOptimizedClipboard(BlockVector3 dimensions, int compressionLevel) { + super(dimensions); + states = new byte[1 + (getVolume() >> BLOCK_SHIFT)][]; nbtMapLoc = new HashMap<>(); nbtMapIndex = new HashMap<>(); entities = new HashSet<>(); @@ -89,7 +86,7 @@ public class MemoryOptimizedClipboard extends FaweClipboard { } @Override - public boolean setBiome(int x, int z, BiomeType biome) { + public boolean setBiome(int x, int y, int z, BiomeType biome) { setBiome(getIndex(x, 0, z), biome); return true; } @@ -97,7 +94,7 @@ public class MemoryOptimizedClipboard extends FaweClipboard { @Override public void setBiome(int index, BiomeType biome) { if (biomes == null) { - biomes = new byte[area]; + biomes = new byte[getArea()]; } biomes[index] = (byte) biome.getInternalId(); } @@ -106,8 +103,8 @@ public class MemoryOptimizedClipboard extends FaweClipboard { public void streamBiomes(NBTStreamer.ByteReader task) { if (!hasBiomes()) return; int index = 0; - for (int z = 0; z < length; z++) { - for (int x = 0; x < width; x++, index++) { + for (int z = 0; z < getLength(); z++) { + for (int x = 0; x < getWidth(); x++, index++) { task.run(index, biomes[index] & 0xFF); } } @@ -122,7 +119,7 @@ public class MemoryOptimizedClipboard extends FaweClipboard { } @Override - public BiomeType getBiome(int x, int z) { + public BiomeType getBiomeType(int x, int z) { return getBiome(getIndex(x, 0, z)); } @@ -131,22 +128,24 @@ public class MemoryOptimizedClipboard extends FaweClipboard { return nbtMapIndex.get(index); } - public int getCombinedId(int index) { + public int getOrdinal(int index) { int i = index >> BLOCK_SHIFT; - if (i == lastCombinedIdsI) { - if (lastCombinedIds == null) { + int li = (index & BLOCK_MASK) << 1; + if (i != lastCombinedIdsI) { + saveCombinedIds(); + byte[] compressed = states[lastCombinedIdsI = i]; + if (compressed != null) { + lastCombinedIds = MainUtil.decompress(compressed, lastCombinedIds, BLOCK_SIZE, compressionLevel); + } else { + lastCombinedIds = null; return 0; } - return lastCombinedIds[index & BLOCK_MASK] & 0xFF; } - saveCombinedIds(); - byte[] compressed = states[lastCombinedIdsI = i]; - if (compressed == null) { - lastCombinedIds = null; - return BlockTypes.AIR.getInternalId(); + if (lastCombinedIds == null) { + return 0; } - lastCombinedIds = MainUtil.decompress(compressed, lastCombinedIds, BLOCK_SIZE, compressionLevel); - return SafeUtils.readIntBE(lastCombinedIds, index & BLOCK_MASK); + int ordinal = ((lastCombinedIds[li] << 8) + lastCombinedIds[li + 1]); + return ordinal; } private void saveCombinedIds() { @@ -156,26 +155,6 @@ public class MemoryOptimizedClipboard extends FaweClipboard { saveCombinedIds = false; } - @Override - public void setDimensions(BlockVector3 dimensions) { - width = dimensions.getBlockX(); - height = dimensions.getBlockY(); - length = dimensions.getBlockZ(); - area = width * length; - int newVolume = area * height; - if (newVolume != volume) { - volume = newVolume; - states = new byte[1 + (volume >> BLOCK_SHIFT)][]; - lastCombinedIdsI = -1; - saveCombinedIds = false; - } - } - - @Override - public BlockVector3 getDimensions() { - return BlockVector3.at(width, height, length); - } - private int lastI; private int lastIMin; private int lastIMax; @@ -207,22 +186,20 @@ public class MemoryOptimizedClipboard extends FaweClipboard { } lastCombinedIds = new byte[BLOCK_SIZE]; } - int li = (index & BLOCK_MASK) << 2; - lastCombinedIds[li] = (byte) ((v >>> 24) & 0xFF); - lastCombinedIds[li + 1] = (byte) ((v >>> 16) & 0xFF); - lastCombinedIds[li + 2] = (byte) ((v >>> 8) & 0xFF); - lastCombinedIds[li + 3] = (byte) ((v >>> 0) & 0xFF); + int li = (index & BLOCK_MASK) << 1; + lastCombinedIds[li] = (byte) ((v >>> 8) & 0xFF); + lastCombinedIds[li + 1] = (byte) (v & 0xFF); saveCombinedIds = true; } @Override - public void streamCombinedIds(NBTStreamer.ByteReader task) { + public void streamOrdinals(NBTStreamer.ByteReader task) { int index = 0; - for (int y = 0; y < height; y++) { - for (int z = 0; z < length; z++) { - for (int x = 0; x < width; x++) { - int id = getCombinedId(index); - task.run(index++, id); + for (int y = 0; y < getHeight(); y++) { + for (int z = 0; z < getLength(); z++) { + for (int x = 0; x < getWidth(); x++, index++) { + int id = getOrdinal(index); + task.run(index, id); } } } @@ -236,10 +213,10 @@ public class MemoryOptimizedClipboard extends FaweClipboard { CompoundTag tag = entry.getValue(); Map values = ReflectionUtils.getMap(tag.getValue()); if (!values.containsKey("x")) { - int y = index / area; - index -= y * area; - int z = index / width; - int x = index - (z * width); + int y = index / getArea(); + index -= y * getArea(); + int z = index / getWidth(); + int x = index - (z * getWidth()); values.put("x", new IntTag(x)); values.put("y", new IntTag(y)); values.put("z", new IntTag(z)); @@ -254,18 +231,18 @@ public class MemoryOptimizedClipboard extends FaweClipboard { private int zlasti; public int getIndex(int x, int y, int z) { - return x + ((ylast == y) ? ylasti : (ylasti = (ylast = y) * area)) + ((zlast == z) ? zlasti : (zlasti = (zlast = z) * width)); + return x + ((ylast == y) ? ylasti : (ylasti = (ylast = y) * getArea())) + ((zlast == z) ? zlasti : (zlasti = (zlast = z) * getWidth())); } @Override - public BaseBlock getBlock(int x, int y, int z) { + public BaseBlock getFullBlock(int x, int y, int z) { int index = getIndex(x, y, z); - return getBlock(index); + return getFullBlock(index); } @Override - public BaseBlock getBlock(int index) { - int combinedId = getCombinedId(index); + public BaseBlock getFullBlock(int index) { + int combinedId = getOrdinal(index); BlockType type = BlockTypes.getFromStateId(combinedId); BaseBlock base = type.withStateId(combinedId).toBaseBlock(); if (type.getMaterial().hasContainer()) { @@ -280,19 +257,19 @@ public class MemoryOptimizedClipboard extends FaweClipboard { @Override public void forEach(final BlockReader task, final boolean air) { if (air) { - for (int y = 0, index = 0; y < height; y++) { - for (int z = 0; z < length; z++) { - for (int x = 0; x < width; x++, index++) { - BaseBlock block = getBlock(index); + for (int y = 0, index = 0; y < getHeight(); y++) { + for (int z = 0; z < getLength(); z++) { + for (int x = 0; x < getWidth(); x++, index++) { + BaseBlock block = getFullBlock(index); task.run(x, y, z, block); } } } } else { - for (int y = 0, index = 0; y < height; y++) { - for (int z = 0; z < length; z++) { - for (int x = 0; x < width; x++, index++) { - BaseBlock block = getBlock(index); + for (int y = 0, index = 0; y < getHeight(); y++) { + for (int z = 0; z < getLength(); z++) { + for (int x = 0; x < getWidth(); x++, index++) { + BaseBlock block = getFullBlock(index); if (!block.getMaterial().isAir()) { task.run(x, y, z, block); } @@ -344,9 +321,10 @@ public class MemoryOptimizedClipboard extends FaweClipboard { return true; } + @Nullable @Override - public Entity createEntity(Extent world, double x, double y, double z, float yaw, float pitch, BaseEntity entity) { - FaweClipboard.ClipboardEntity ret = new ClipboardEntity(world, x, y, z, yaw, pitch, entity); + public Entity createEntity(Location location, BaseEntity entity) { + BlockArrayClipboard.ClipboardEntity ret = new BlockArrayClipboard.ClipboardEntity(location, entity); entities.add(ret); return ret; } @@ -357,7 +335,21 @@ public class MemoryOptimizedClipboard extends FaweClipboard { } @Override - public boolean remove(ClipboardEntity clipboardEntity) { - return entities.remove(clipboardEntity); + public void removeEntity(Entity entity) { + this.entities.remove(entity); + } + + @Nullable + @Override + public void removeEntity(int x, int y, int z, UUID uuid) { + Iterator iter = this.entities.iterator(); + while (iter.hasNext()) { + BlockArrayClipboard.ClipboardEntity entity = iter.next(); + UUID entUUID = entity.getState().getNbtData().getUUID(); + if (uuid.equals(entUUID)) { + iter.remove(); + return; + } + } } } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/MultiClipboardHolder.java b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/MultiClipboardHolder.java index b9e3ad59d..a26c12700 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/MultiClipboardHolder.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/MultiClipboardHolder.java @@ -36,7 +36,7 @@ public class MultiClipboardHolder extends URIClipboardHolder { holders = new ArrayList<>(); URI uri = URI.create(""); if (clipboard instanceof BlockArrayClipboard) { - FaweClipboard fc = ((BlockArrayClipboard) clipboard).IMP; + LinearClipboard fc = ((BlockArrayClipboard) clipboard).IMP; if (fc instanceof DiskOptimizedClipboard) { uri = ((DiskOptimizedClipboard) fc).getFile().toURI(); } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/OffsetFaweClipboard.java b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/OffsetFaweClipboard.java index 3982df681..dbc63b777 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/OffsetFaweClipboard.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/OffsetFaweClipboard.java @@ -1,22 +1,25 @@ package com.boydti.fawe.object.clipboard; import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockStateHolder; -public class OffsetFaweClipboard extends AbstractDelegateFaweClipboard { +public class OffsetClipboard extends DelegateClipboard { private final int ox, oy, oz; - public OffsetFaweClipboard(FaweClipboard parent, int ox, int oy, int oz) { + public OffsetClipboard(Clipboard parent, int ox, int oy, int oz) { super(parent); this.ox = ox; this.oy = oy; this.oz = oz; } - public OffsetFaweClipboard(FaweClipboard parent, int offset) { - this(parent, offset, offset, offset); + @Override + public Region getRegion() { + return parent.getRegion(); } @Override diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/ReadOnlyClipboard.java b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/ReadOnlyClipboard.java index 7ad3a4fdc..f72afb758 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/ReadOnlyClipboard.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/ReadOnlyClipboard.java @@ -12,7 +12,7 @@ import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockStateHolder; import java.util.List; -public abstract class ReadOnlyClipboard extends FaweClipboard { +public abstract class ReadOnlyClipboard extends LinearClipboard { public final Region region; public ReadOnlyClipboard(Region region) { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/schematic/Schematic.java b/worldedit-core/src/main/java/com/boydti/fawe/object/schematic/Schematic.java index 3365342c1..54cc248a8 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/schematic/Schematic.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/schematic/Schematic.java @@ -2,7 +2,7 @@ package com.boydti.fawe.object.schematic; import static com.google.common.base.Preconditions.checkNotNull; -import com.boydti.fawe.object.clipboard.FaweClipboard; +import com.boydti.fawe.object.clipboard.LinearClipboard; import com.boydti.fawe.object.clipboard.ReadOnlyClipboard; import com.boydti.fawe.util.EditSessionBuilder; import com.boydti.fawe.util.MaskTraverser; @@ -213,7 +213,7 @@ public class Schematic { BlockArrayClipboard bac = (BlockArrayClipboard) clipboard; if (copyBiomes) { - bac.IMP.forEach(new FaweClipboard.BlockReader() { + bac.IMP.forEach(new LinearClipboard.BlockReader() { MutableBlockVector2 mpos2d = new MutableBlockVector2(); { @@ -239,7 +239,7 @@ public class Schematic { } }, true); } else { - bac.IMP.forEach(new FaweClipboard.BlockReader() { + bac.IMP.forEach(new LinearClipboard.BlockReader() { @Override public > void run(int x, int y, int z, B block) { try { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolUtilCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolUtilCommands.java index 20cb49152..dcbc68abf 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolUtilCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolUtilCommands.java @@ -211,7 +211,6 @@ public class ToolUtilCommands { BBC.SUPERPICKAXE_DISABLED.send(player); } else { if ("off".equals(state)) { - BBC.SUPERPICKAXE_DISABLED.send(player); return; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java index 97d722462..04b3bb590 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java @@ -22,14 +22,15 @@ package com.sk89q.worldedit.extent.clipboard; import static com.google.common.base.Preconditions.checkNotNull; import com.boydti.fawe.config.Settings; +import com.boydti.fawe.object.clipboard.DelegateClipboard; import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard; -import com.boydti.fawe.object.clipboard.FaweClipboard; -import com.boydti.fawe.object.clipboard.FaweClipboard.ClipboardEntity; +import com.boydti.fawe.object.clipboard.LinearClipboard; import com.boydti.fawe.object.clipboard.MemoryOptimizedClipboard; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; @@ -40,7 +41,10 @@ import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockTypes; +import jdk.vm.ci.meta.Local; + import java.io.Closeable; +import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -51,26 +55,13 @@ import javax.annotation.Nullable; * Stores block data as a multi-dimensional array of {@link BlockState}s and * other data as lists or maps. */ -public class BlockArrayClipboard implements Clipboard, Closeable { +public class BlockArrayClipboard extends DelegateClipboard implements Clipboard, Closeable { private Region region; private BlockVector3 origin; - public FaweClipboard IMP; - private BlockVector3 size; - private int mx; - private int my; - private int mz; - private final List entities = new ArrayList<>(); public BlockArrayClipboard(Region region) { - checkNotNull(region); - this.region = region.clone(); - this.size = getDimensions(); - this.IMP = Settings.IMP.CLIPBOARD.USE_DISK ? new DiskOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ()) : new MemoryOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ()); - this.origin = region.getMinimumPoint(); - this.mx = origin.getBlockX(); - this.my = origin.getBlockY(); - this.mz = origin.getBlockZ(); + this(region, UUID.randomUUID()); } /** @@ -81,48 +72,24 @@ public class BlockArrayClipboard implements Clipboard, Closeable { * @param region the bounding region */ public BlockArrayClipboard(Region region, UUID clipboardId) { + this(region, Clipboard.create(region.getDimensions(), clipboardId)); checkNotNull(region); this.region = region.clone(); - this.size = getDimensions(); - this.IMP = Settings.IMP.CLIPBOARD.USE_DISK ? new DiskOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ(), clipboardId) : new MemoryOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ()); this.origin = region.getMinimumPoint(); - this.mx = origin.getBlockX(); - this.my = origin.getBlockY(); - this.mz = origin.getBlockZ(); } - public BlockArrayClipboard(Region region, FaweClipboard clipboard) { + public BlockArrayClipboard(Region region, Clipboard clipboard) { + super(clipboard); checkNotNull(region); this.region = region.clone(); - this.size = getDimensions(); this.origin = region.getMinimumPoint(); - this.IMP = clipboard; - this.mx = origin.getBlockX(); - this.my = origin.getBlockY(); - this.mz = origin.getBlockZ(); - } - - public void init(Region region, FaweClipboard fc) { - checkNotNull(region); - checkNotNull(fc); - this.region = region.clone(); - this.size = getDimensions(); - this.IMP = fc; - this.origin = region.getMinimumPoint(); - this.mx = origin.getBlockX(); - this.my = origin.getBlockY(); - this.mz = origin.getBlockZ(); } @Override - protected void finalize() { - close(); - } - - @Override - public void close() { - IMP.close(); - + public void close() throws IOException { + if (getParent() instanceof Closeable) { + ((Closeable) getParent()).close(); + } } @Override @@ -142,12 +109,7 @@ public class BlockArrayClipboard implements Clipboard, Closeable { @Override public void setOrigin(BlockVector3 origin) { this.origin = origin; - IMP.setOrigin(origin.subtract(region.getMinimumPoint())); - } - - @Override - public BlockVector3 getDimensions() { - return region.getMaximumPoint().subtract(region.getMinimumPoint()).add(1, 1, 1); + getParent().setOrigin(origin.subtract(region.getMinimumPoint())); } @Override @@ -160,35 +122,13 @@ public class BlockArrayClipboard implements Clipboard, Closeable { return region.getMaximumPoint(); } - @Override - public List getEntities(Region region) { - List filtered = new ArrayList<>(); - for (Entity entity : getEntities()) { - if (region.contains(entity.getLocation().toVector().toBlockPoint())) { - filtered.add(entity); - } - } - return Collections.unmodifiableList(filtered); - } - - @Override - public List getEntities() { - return IMP.getEntities(); - } - - @Nullable - @Override - public Entity createEntity(Location location, BaseEntity entity) { - return IMP.createEntity(location.getExtent(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch(), entity); - } - @Override public BlockState getBlock(BlockVector3 position) { if (region.contains(position)) { - int x = position.getBlockX() - mx; - int y = position.getBlockY() - my; - int z = position.getBlockZ() - mz; - return IMP.getBlock(x, y, z).toImmutableState(); + int x = position.getBlockX()- origin.getX(); + int y = position.getBlockY()- origin.getY(); + int z = position.getBlockZ()- origin.getZ(); + return getParent().getBlock(x, y, z); } return BlockTypes.AIR.getDefaultState(); @@ -197,10 +137,10 @@ public class BlockArrayClipboard implements Clipboard, Closeable { @Override public BaseBlock getFullBlock(BlockVector3 position) { if(region.contains(position)) { - int x = position.getBlockX() - mx; - int y = position.getBlockY() - my; - int z = position.getBlockZ() - mz; - return IMP.getBlock(x, y, z); + int x = position.getBlockX()- origin.getX(); + int y = position.getBlockY()- origin.getY(); + int z = position.getBlockZ()- origin.getZ(); + return getParent().getFullBlock(x, y, z); } return BlockTypes.AIR.getDefaultState().toBaseBlock(); } @@ -218,10 +158,10 @@ public class BlockArrayClipboard implements Clipboard, Closeable { @Override public boolean setTile(int x, int y, int z, CompoundTag tag) { - x -= mx; - y -= my; - z -= mz; - return IMP.setTile(x, y, z, tag); + x -= origin.getX(); + y -= origin.getY(); + z -= origin.getZ(); + return getParent().setTile(x, y, z, tag); } public boolean setTile(BlockVector3 position, CompoundTag tag) { @@ -230,38 +170,133 @@ public class BlockArrayClipboard implements Clipboard, Closeable { @Override public > boolean setBlock(int x, int y, int z, B block) throws WorldEditException { - x -= mx; - y -= my; - z -= mz; - return IMP.setBlock(x, y, z, block); + x -= origin.getX(); + y -= origin.getY(); + z -= origin.getZ(); + return getParent().setBlock(x, y, z, block); } @Override public boolean hasBiomes() { - return IMP.hasBiomes(); + return getParent().hasBiomes(); } @Override public BiomeType getBiome(BlockVector2 position) { BlockVector2 v = position.subtract(region.getMinimumPoint().toBlockVector2()); - return IMP.getBiome(v.getX(), v.getZ()); + return getParent().getBiomeType(v.getX(), v.getZ()); } @Override public boolean setBiome(BlockVector2 position, BiomeType biome) { - int x = position.getBlockX() - mx; - int z = position.getBlockZ() - mz; - return IMP.setBiome(x, z, biome); + int x = position.getBlockX()- origin.getX(); + int z = position.getBlockZ()- origin.getZ(); + return getParent().setBiome(x, 0, z, biome); } @Override public boolean setBiome(int x, int y, int z, BiomeType biome) { - return IMP.setBiome(x, z, biome); + return parent.setBiome(x, y, z, biome); } - @Nullable @Override - public Operation commit() { - return null; + public List getEntities(Region region) { + return parent.getEntities(region); + } + + @Override + @Nullable + public Entity createEntity(Location location, BaseEntity entity) { + return parent.createEntity(location, entity); + } + + @Override + @Nullable + public void removeEntity(int x, int y, int z, UUID uuid) { + parent.removeEntity(x, y, z, uuid); + } + + @Override + public BlockState getBlock(int x, int y, int z) { + return parent.getBlock(x, y, z); + } + + @Override + public BaseBlock getFullBlock(int x, int y, int z) { + return parent.getFullBlock(x, y, z); + } + + @Override + public BiomeType getBiomeType(int x, int z) { + return parent.getBiomeType(x, z); + } + + /** + * Stores entity data. + */ + public static class ClipboardEntity implements Entity { + private final BaseEntity entity; + private final Clipboard clipboard; + private final double x, y, z; + private final float yaw, pitch; + + public ClipboardEntity(Location loc, BaseEntity entity) { + this((Clipboard) loc.getExtent(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), loc.getYaw(), loc.getPitch(), entity); + } + + public ClipboardEntity(Clipboard clipboard, double x, double y, double z, float yaw, float pitch, BaseEntity entity) { + checkNotNull(entity); + checkNotNull(clipboard); + this.clipboard = clipboard; + this.x = x; + this.y = y; + this.z = z; + this.yaw = yaw; + this.pitch = pitch; + this.entity = new BaseEntity(entity); + } + + @Override + public boolean remove() { + clipboard.removeEntity(this); + return true; + } + + @Nullable + @Override + public T getFacet(Class cls) { + return null; + } + + /** + * Get the entity state. This is not a copy. + * + * @return the entity + */ + BaseEntity getEntity() { + return entity; + } + + @Override + public BaseEntity getState() { + return new BaseEntity(entity); + } + + @Override + public Location getLocation() { + return new Location(clipboard, x, y, z, yaw, pitch); + } + + @Override + public Extent getExtent() { + return clipboard; + } + + @Override + public boolean setLocation(Location loc) { + clipboard.removeEntity(this); + Entity result = clipboard.createEntity(loc, entity); + return result != null; + } } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java index 6994442fe..610d49791 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java @@ -19,15 +19,33 @@ package com.sk89q.worldedit.extent.clipboard; +import com.boydti.fawe.config.Settings; +import com.boydti.fawe.object.clipboard.CPUOptimizedClipboard; +import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard; +import com.boydti.fawe.object.clipboard.MemoryOptimizedClipboard; +import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.util.Location; + +import javax.annotation.Nullable; +import java.util.UUID; /** * Specifies an object that implements something suitable as a "clipboard." */ public interface Clipboard extends Extent { + static Clipboard create(BlockVector3 size, UUID uuid) { + if (Settings.IMP.CLIPBOARD.USE_DISK) { + return new DiskOptimizedClipboard(size, uuid); + } else if (Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL == 0) { + return new CPUOptimizedClipboard(size); + } else { + return new MemoryOptimizedClipboard(size); + } + } /** * Get the bounding region of this extent. @@ -70,4 +88,10 @@ public interface Clipboard extends Extent { default boolean hasBiomes() { return false; } + + /** + * Remove entity from clipboard + * @param entity + */ + void removeEntity(Entity entity); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardReader.java index 07ff96593..a1b893890 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardReader.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardReader.java @@ -19,11 +19,16 @@ package com.sk89q.worldedit.extent.clipboard.io; +import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.math.BlockVector3; import java.io.Closeable; import java.io.IOException; import java.util.UUID; +import java.util.function.Function; /** * Reads {@code Clipboard}s. @@ -38,9 +43,20 @@ public interface ClipboardReader extends Closeable { * @return the read clipboard * @throws IOException thrown on I/O error */ - Clipboard read() throws IOException; + default Clipboard read() throws IOException { + return read(UUID.randomUUID()); + } default Clipboard read(UUID uuid) throws IOException { + return read(uuid, new Function() { + @Override + public Clipboard apply(BlockVector3 dimensions) { + return new DiskOptimizedClipboard(dimensions); + } + }); + } + + default Clipboard read(UUID uuid, Function createOutput) throws IOException { return read(); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java index 64085e274..edc33dcd0 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java @@ -29,7 +29,7 @@ import com.boydti.fawe.object.FaweInputStream; import com.boydti.fawe.object.FaweOutputStream; import com.boydti.fawe.object.clipboard.CPUOptimizedClipboard; import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard; -import com.boydti.fawe.object.clipboard.FaweClipboard; +import com.boydti.fawe.object.clipboard.LinearClipboard; import com.boydti.fawe.object.clipboard.MemoryOptimizedClipboard; import com.boydti.fawe.object.io.FastByteArrayOutputStream; import com.boydti.fawe.object.io.FastByteArraysInputStream; @@ -48,7 +48,6 @@ import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; -import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeTypes; @@ -56,14 +55,15 @@ import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.entity.EntityType; import com.sk89q.worldedit.world.entity.EntityTypes; -import com.sk89q.worldedit.world.storage.NBTConversions; + import java.io.IOException; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.UUID; import java.util.function.BiConsumer; +import java.util.function.Function; + import net.jpountz.lz4.LZ4BlockInputStream; import net.jpountz.lz4.LZ4BlockOutputStream; import org.slf4j.Logger; @@ -99,13 +99,18 @@ public class SpongeSchematicReader extends NBTSchematicReader { return reader(uuid); } + @Override + public Clipboard read(UUID uuid, Function createOutput) { + return null; + } + private int width, height, length; private int offsetX, offsetY, offsetZ; private char[] palette; private BlockVector3 min; - private FaweClipboard fc; + private LinearClipboard fc; - private FaweClipboard setupClipboard(int size, UUID uuid) { + private LinearClipboard setupClipboard(int size, UUID uuid) { if (fc != null) { if (fc.getDimensions().getX() == 0) { fc.setDimensions(BlockVector3.at(size, 1, 1)); @@ -113,11 +118,11 @@ public class SpongeSchematicReader extends NBTSchematicReader { return fc; } if (Settings.IMP.CLIPBOARD.USE_DISK) { - return fc = new DiskOptimizedClipboard(size, 1, 1, uuid); + return fc = new DiskOptimizedClipboard(BlockVector3.at(size, 1, 1), uuid); } else if (Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL == 0) { - return fc = new CPUOptimizedClipboard(size, 1, 1); + return fc = new CPUOptimizedClipboard(BlockVector3.at(size, 1, 1)); } else { - return fc = new MemoryOptimizedClipboard(size, 1, 1); + return fc = new MemoryOptimizedClipboard(BlockVector3.at(size, 1, 1)); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java index 67bc219d6..f57758c01 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java @@ -22,7 +22,7 @@ package com.sk89q.worldedit.extent.clipboard.io; import static com.google.common.base.Preconditions.checkNotNull; import com.boydti.fawe.jnbt.NBTStreamer; -import com.boydti.fawe.object.clipboard.FaweClipboard; +import com.boydti.fawe.object.clipboard.LinearClipboard; import com.boydti.fawe.util.IOUtil; import com.google.common.collect.Maps; import com.sk89q.jnbt.CompoundTag; @@ -146,7 +146,7 @@ public class SpongeSchematicWriter implements ClipboardWriter { int[] numTiles = {0}; - FaweClipboard.BlockReader reader = new FaweClipboard.BlockReader() { + LinearClipboard.BlockReader reader = new LinearClipboard.BlockReader() { @Override public > void run(int x, int y, int z, B block) { try { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java index 025428172..29c399199 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java @@ -60,6 +60,10 @@ public interface Region extends Iterable, Cloneable, IBatchProcess */ BlockVector3 getMaximumPoint(); + default BlockVector3 getDimensions() { + return getMaximumPoint().subtract(getMinimumPoint()).add(1, 1, 1); + } + /** * Get the center point of a region. * Note: Coordinates will not be integers