wip remove faweclipboard

This commit is contained in:
Jesse Boyd 2019-10-31 04:04:15 +01:00
parent e1b9b9e3e8
commit 0296d566ed
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
21 changed files with 844 additions and 787 deletions

View File

@ -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;
}

View File

@ -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 <B extends BlockStateHolder<B>> 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;
}

View File

@ -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 <B extends BlockStateHolder<B>> 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;

View File

@ -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 <B extends BlockStateHolder<B>> boolean setBlock(int x, int y, int z, B block) {
return parent.setBlock(x, y, z, block);
}
@Override
public <B extends BlockStateHolder<B>> 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<? extends Entity> 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<CompoundTag> getTileEntities() {
return parent.getTileEntities();
}
}

View File

@ -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<IntegerTrio, CompoundTag> nbtMapLoc;
private final HashMap<Integer, CompoundTag> nbtMapIndex;
private final HashSet<ClipboardEntity> entities;
private final HashSet<BlockArrayClipboard.ClipboardEntity> 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<String, Tag> 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 <B extends BlockStateHolder<B>> 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<BlockArrayClipboard.ClipboardEntity> 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;
}
}
}
}

View File

@ -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<? extends Entity> getEntities(Region region) {
return parent.getEntities(region);
}
@Override
public List<? extends Entity> 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 <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 position, T block) throws WorldEditException {
return parent.setBlock(position, block);
}
@Override
public <T extends BlockStateHolder<T>> 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);
}
}

View File

@ -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<IntegerTrio, CompoundTag> nbtMap;
private final HashSet<ClipboardEntity> entities;
private final HashSet<BlockArrayClipboard.ClipboardEntity> 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 <B extends BlockStateHolder<B>> 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 <B extends BlockStateHolder<B>> 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<BlockArrayClipboard.ClipboardEntity> 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;
}
}
}
}

View File

@ -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 <B extends BlockStateHolder<B>> boolean setBlock(int index, B block);
public abstract <B extends BlockStateHolder<B>> 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<? extends Entity> 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 {
<B extends BlockStateHolder<B>> 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 <B extends BlockStateHolder<B>> void run(int x, int y, int z, B block) {
task.run(index++, block.getInternalId());
}
}, true);
}
public List<CompoundTag> getTileEntities() {
final List<CompoundTag> tiles = new ArrayList<>();
forEach(new BlockReader() {
@Override
public <B extends BlockStateHolder<B>> 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<String, Tag> 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> T getFacet(Class<? extends T> 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;
}
}
}

View File

@ -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 <B extends BlockStateHolder<B>> 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 {
<B extends BlockStateHolder<B>> 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 <B extends BlockStateHolder<B>> void run(int x, int y, int z, B block) {
task.run(index++, block.getOrdinal());
}
}, true);
}
public List<CompoundTag> getTileEntities() {
final List<CompoundTag> tiles = new ArrayList<>();
forEach(new BlockReader() {
@Override
public <B extends BlockStateHolder<B>> 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<String, Tag> 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();
}
}

View File

@ -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<IntegerTrio, CompoundTag> nbtMapLoc;
private final HashMap<Integer, CompoundTag> nbtMapIndex;
private final HashSet<ClipboardEntity> entities;
private final HashSet<BlockArrayClipboard.ClipboardEntity> 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<String, Tag> 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<BlockArrayClipboard.ClipboardEntity> 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;
}
}
}
}

View File

@ -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();
}

View File

@ -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

View File

@ -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) {

View File

@ -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 <B extends BlockStateHolder<B>> void run(int x, int y, int z, B block) {
try {

View File

@ -211,7 +211,6 @@ public class ToolUtilCommands {
BBC.SUPERPICKAXE_DISABLED.send(player);
} else {
if ("off".equals(state)) {
BBC.SUPERPICKAXE_DISABLED.send(player);
return;
}

View File

@ -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<ClipboardEntity> 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<? extends Entity> getEntities(Region region) {
List<Entity> filtered = new ArrayList<>();
for (Entity entity : getEntities()) {
if (region.contains(entity.getLocation().toVector().toBlockPoint())) {
filtered.add(entity);
}
}
return Collections.unmodifiableList(filtered);
}
@Override
public List<? extends Entity> 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 <B extends BlockStateHolder<B>> 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<? extends Entity> 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> T getFacet(Class<? extends T> 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;
}
}
}

View File

@ -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);
}

View File

@ -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<BlockVector3, Clipboard>() {
@Override
public Clipboard apply(BlockVector3 dimensions) {
return new DiskOptimizedClipboard(dimensions);
}
});
}
default Clipboard read(UUID uuid, Function<BlockVector3, Clipboard> createOutput) throws IOException {
return read();
}
}

View File

@ -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<BlockVector3, Clipboard> 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));
}
}

View File

@ -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 <B extends BlockStateHolder<B>> void run(int x, int y, int z, B block) {
try {

View File

@ -60,6 +60,10 @@ public interface Region extends Iterable<BlockVector3>, 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