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.config.Settings;
import com.boydti.fawe.object.clipboard.CPUOptimizedClipboard; import com.boydti.fawe.object.clipboard.CPUOptimizedClipboard;
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard; 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.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.extent.clipboard.Clipboard;
import com.sk89q.worldedit.math.BlockVector3; 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.BufferedInputStream;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.IOException; import java.io.IOException;
@ -29,7 +23,7 @@ public class CorruptSchematicStreamer {
private final InputStream stream; private final InputStream stream;
private final UUID uuid; private final UUID uuid;
private FaweClipboard fc; private LinearClipboard fc;
final AtomicInteger volume = new AtomicInteger(); final AtomicInteger volume = new AtomicInteger();
final AtomicInteger width = new AtomicInteger(); final AtomicInteger width = new AtomicInteger();
final AtomicInteger height = new AtomicInteger(); final AtomicInteger height = new AtomicInteger();
@ -78,7 +72,7 @@ public class CorruptSchematicStreamer {
} }
} }
public FaweClipboard setupClipboard() { public LinearClipboard setupClipboard() {
if (fc != null) { if (fc != null) {
return fc; return fc;
} }
@ -87,11 +81,11 @@ public class CorruptSchematicStreamer {
Fawe.debug("No dimensions found! Estimating based on factors:" + dimensions); Fawe.debug("No dimensions found! Estimating based on factors:" + dimensions);
} }
if (Settings.IMP.CLIPBOARD.USE_DISK) { 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) { } else if (Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL == 0) {
fc = new CPUOptimizedClipboard(dimensions.getBlockX(), dimensions.getBlockY(), dimensions.getBlockZ()); fc = new CPUOptimizedClipboard(dimensions);
} else { } else {
fc = new MemoryOptimizedClipboard(dimensions.getBlockX(), dimensions.getBlockY(), dimensions.getBlockZ()); fc = new MemoryOptimizedClipboard(dimensions);
} }
return fc; 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.FaweOutputStream;
import com.boydti.fawe.object.clipboard.CPUOptimizedClipboard; import com.boydti.fawe.object.clipboard.CPUOptimizedClipboard;
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard; 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.clipboard.MemoryOptimizedClipboard;
import com.boydti.fawe.object.io.FastByteArrayOutputStream; import com.boydti.fawe.object.io.FastByteArrayOutputStream;
import com.boydti.fawe.object.io.FastByteArraysInputStream; import com.boydti.fawe.object.io.FastByteArraysInputStream;
@ -200,7 +200,7 @@ public class SchematicStreamer extends NBTStreamer {
} }
private void fixStates() { private void fixStates() {
fc.forEach(new FaweClipboard.BlockReader() { fc.forEach(new LinearClipboard.BlockReader() {
@Override @Override
public <B extends BlockStateHolder<B>> void run(int x, int y, int z, B block) { public <B extends BlockStateHolder<B>> void run(int x, int y, int z, B block) {
BlockType type = block.getBlockType(); BlockType type = block.getBlockType();
@ -360,9 +360,9 @@ public class SchematicStreamer extends NBTStreamer {
private int offsetZ; private int offsetZ;
private BlockArrayClipboard clipboard; private BlockArrayClipboard clipboard;
private FaweClipboard fc; private LinearClipboard fc;
private FaweClipboard setupClipboard(int size) { private LinearClipboard setupClipboard(int size) {
if (fc != null) { if (fc != null) {
if (fc.getDimensions().getX() == 0) { if (fc.getDimensions().getX() == 0) {
fc.setDimensions(BlockVector3.at(size, 1, 1)); fc.setDimensions(BlockVector3.at(size, 1, 1));
@ -370,11 +370,11 @@ public class SchematicStreamer extends NBTStreamer {
return fc; return fc;
} }
if (Settings.IMP.CLIPBOARD.USE_DISK) { 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) { } 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 { } 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); return BlockVector3.at(width, height, length);
} }
public void setClipboard(FaweClipboard clipboard) { public void setClipboard(LinearClipboard clipboard) {
this.fc = clipboard; this.fc = clipboard;
} }

View File

@ -1,7 +1,7 @@
package com.boydti.fawe.object.brush; package com.boydti.fawe.object.brush;
import com.boydti.fawe.object.clipboard.CPUOptimizedClipboard; 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.boydti.fawe.object.clipboard.OffsetFaweClipboard;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.MaxChangedBlocksException;
@ -40,8 +40,8 @@ public class ErodeBrush implements Brush {
int brushSize = (int) size + 1; int brushSize = (int) size + 1;
int brushSizeSquared = (int) (size * size); int brushSizeSquared = (int) (size * size);
int dimension = brushSize * 2 + 1; int dimension = brushSize * 2 + 1;
FaweClipboard buffer1 = new OffsetFaweClipboard(new CPUOptimizedClipboard(dimension, dimension, dimension), brushSize); LinearClipboard buffer1 = new OffsetFaweClipboard(new CPUOptimizedClipboard(dimension, dimension, dimension), brushSize);
FaweClipboard buffer2 = 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 bx = target.getBlockX();
final int by = target.getBlockY(); 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); fillIteration(brushSize, brushSizeSquared, fillFaces, swap % 2 == 0 ? buffer1 : buffer2, swap % 2 == 1 ? buffer1 : buffer2);
swap++; 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 @Override
public <B extends BlockStateHolder<B>> void run(int x, int y, int z, B block) { public <B extends BlockStateHolder<B>> void run(int x, int y, int z, B block) {
es.setBlock(x + bx, y + by, z + bz, 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, private void fillIteration(int brushSize, int brushSizeSquared, int fillFaces,
FaweClipboard current, FaweClipboard target) { LinearClipboard current, LinearClipboard target) {
int[] frequency = null; int[] frequency = null;
for (int x = -brushSize; x <= brushSize; x++) { for (int x = -brushSize; x <= brushSize; x++) {
int x2 = x * x; int x2 = x * x;
@ -126,7 +126,7 @@ public class ErodeBrush implements Brush {
} }
private void erosionIteration(int brushSize, int brushSizeSquared, int erodeFaces, private void erosionIteration(int brushSize, int brushSizeSquared, int erodeFaces,
FaweClipboard current, FaweClipboard target) { LinearClipboard current, LinearClipboard target) {
int[] frequency = null; int[] frequency = null;
for (int x = -brushSize; x <= brushSize; x++) { for (int x = -brushSize; x <= brushSize; x++) {
int x2 = x * 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.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.math.BlockVector3; 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.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock; 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.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID;
public class CPUOptimizedClipboard extends FaweClipboard { public class CPUOptimizedClipboard extends LinearClipboard {
private int length;
private int height;
private int width;
private int area;
private int volume;
private BiomeType[] biomes = null; private BiomeType[] biomes = null;
private int[] states; private char[] states;
private final HashMap<IntegerTrio, CompoundTag> nbtMapLoc; private final HashMap<IntegerTrio, CompoundTag> nbtMapLoc;
private final HashMap<Integer, CompoundTag> nbtMapIndex; 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) { public CPUOptimizedClipboard(BlockVector3 dimensions) {
this.width = width; super(dimensions);
this.height = height; this.states = new char[getVolume()];
this.length = length;
this.area = width * length;
this.volume = area * height;
this.states = new int[volume];
nbtMapLoc = new HashMap<>(); nbtMapLoc = new HashMap<>();
nbtMapIndex = new HashMap<>(); nbtMapIndex = new HashMap<>();
entities = new HashSet<>(); entities = new HashSet<>();
@ -54,7 +52,7 @@ public class CPUOptimizedClipboard extends FaweClipboard {
} }
@Override @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); setBiome(getIndex(x, 0, z), biome);
return true; return true;
} }
@ -62,7 +60,7 @@ public class CPUOptimizedClipboard extends FaweClipboard {
@Override @Override
public void setBiome(int index, BiomeType biome) { public void setBiome(int index, BiomeType biome) {
if (biomes == null) { if (biomes == null) {
biomes = new BiomeType[area]; biomes = new BiomeType[getArea()];
} }
biomes[index] = biome; biomes[index] = biome;
} }
@ -71,8 +69,8 @@ public class CPUOptimizedClipboard extends FaweClipboard {
public void streamBiomes(NBTStreamer.ByteReader task) { public void streamBiomes(NBTStreamer.ByteReader task) {
if (!hasBiomes()) return; if (!hasBiomes()) return;
int index = 0; int index = 0;
for (int z = 0; z < length; z++) { for (int z = 0; z < getLength(); z++) {
for (int x = 0; x < width; x++, index++) { for (int x = 0; x < getWidth(); x++, index++) {
task.run(index, biomes[index].getInternalId()); task.run(index, biomes[index].getInternalId());
} }
} }
@ -87,7 +85,7 @@ public class CPUOptimizedClipboard extends FaweClipboard {
} }
@Override @Override
public BiomeType getBiome(int x, int z) { public BiomeType getBiomeType(int x, int z) {
return getBiome(getIndex(x, 0, z)); return getBiome(getIndex(x, 0, z));
} }
@ -107,70 +105,51 @@ public class CPUOptimizedClipboard extends FaweClipboard {
return nbtMapIndex.get(index); 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 yLast;
private int yLastI; private int yLastI;
private int zLast; private int zLast;
private int zLastI; private int zLastI;
public int getIndex(int x, int y, int z) { public int getIndex(int x, int y, int z) {
return x + ((yLast == y) ? yLastI : (yLastI = (yLast = y) * area)) + ((zLast == z) ? zLastI return x + ((yLast == y) ? yLastI : (yLastI = (yLast = y) * getArea())) + ((zLast == z) ? zLastI
: (zLastI = (zLast = z) * width)); : (zLastI = (zLast = z) * getWidth()));
} }
@Override @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); int index = getIndex(x, y, z);
return getBlock(index); return getFullBlock(index);
} }
@Override @Override
public BaseBlock getBlock(int index) { public BaseBlock getFullBlock(int index) {
int combinedId = states[index]; char ordinal = states[index];
BlockType type = BlockTypes.getFromStateId(combinedId); BlockState state = BlockState.getFromOrdinal(ordinal);
BaseBlock base = type.withStateId(combinedId).toBaseBlock(); if (state.getMaterial().hasContainer()) {
if (type.getMaterial().hasContainer()) {
CompoundTag nbt = getTag(index); CompoundTag nbt = getTag(index);
if (nbt != null) { if (nbt != null) {
return base.toBaseBlock(nbt); return state.toBaseBlock(nbt);
} }
} }
return base; return state.toBaseBlock();
} }
@Override @Override
public void forEach(final BlockReader task, boolean air) { public void forEach(final BlockReader task, boolean air) {
if (air) { if (air) {
for (int y = 0, index = 0; y < height; y++) { for (int y = 0, index = 0; y < getHeight(); y++) {
for (int z = 0; z < length; z++) { for (int z = 0; z < getLength(); z++) {
for (int x = 0; x < width; x++, index++) { for (int x = 0; x < getWidth(); x++, index++) {
BaseBlock block = getBlock(index); BaseBlock block = getFullBlock(index);
task.run(x, y, z, block); task.run(x, y, z, block);
} }
} }
} }
} else { } else {
for (int y = 0, index = 0; y < height; y++) { for (int y = 0, index = 0; y < getHeight(); y++) {
for (int z = 0; z < length; z++) { for (int z = 0; z < getLength(); z++) {
for (int x = 0; x < width; x++, index++) { for (int x = 0; x < getWidth(); x++, index++) {
BaseBlock block = getBlock(index); BaseBlock block = getFullBlock(index);
if (!block.getMaterial().isAir()) { if (!block.getMaterial().isAir()) {
task.run(x, y, z, block); task.run(x, y, z, block);
} }
@ -181,11 +160,11 @@ public class CPUOptimizedClipboard extends FaweClipboard {
} }
@Override @Override
public void streamCombinedIds(NBTStreamer.ByteReader task) { public void streamOrdinals(NBTStreamer.ByteReader task) {
int index = 0; int index = 0;
for (int y = 0; y < height; y++) { for (int y = 0; y < getHeight(); y++) {
for (int z = 0; z < length; z++) { for (int z = 0; z < getLength(); z++) {
for (int x = 0; x < width; x++) { for (int x = 0; x < getWidth(); x++) {
task.run(index, states[index++]); task.run(index, states[index++]);
} }
} }
@ -200,10 +179,10 @@ public class CPUOptimizedClipboard extends FaweClipboard {
CompoundTag tag = entry.getValue(); CompoundTag tag = entry.getValue();
Map<String, Tag> values = ReflectionUtils.getMap(tag.getValue()); Map<String, Tag> values = ReflectionUtils.getMap(tag.getValue());
if (!values.containsKey("x")) { if (!values.containsKey("x")) {
int y = index / area; int y = index / getArea();
index -= y * area; index -= y * getArea();
int z = index / width; int z = index / getWidth();
int x = index - (z * width); int x = index - (z * getWidth());
values.put("x", new IntTag(x)); values.put("x", new IntTag(x));
values.put("y", new IntTag(y)); values.put("y", new IntTag(y));
values.put("z", new IntTag(z)); values.put("z", new IntTag(z));
@ -234,7 +213,7 @@ public class CPUOptimizedClipboard extends FaweClipboard {
@Override @Override
public <B extends BlockStateHolder<B>> boolean setBlock(int index, B block) { 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(); boolean hasNbt = block instanceof BaseBlock && block.hasNbtData();
if (hasNbt) { if (hasNbt) {
setTile(index, block.getNbtData()); setTile(index, block.getNbtData());
@ -242,9 +221,10 @@ public class CPUOptimizedClipboard extends FaweClipboard {
return true; return true;
} }
@Nullable
@Override @Override
public Entity createEntity(Extent world, double x, double y, double z, float yaw, float pitch, BaseEntity entity) { public Entity createEntity(Location location, BaseEntity entity) {
FaweClipboard.ClipboardEntity ret = new ClipboardEntity(world, x, y, z, yaw, pitch, entity); BlockArrayClipboard.ClipboardEntity ret = new BlockArrayClipboard.ClipboardEntity(location, entity);
entities.add(ret); entities.add(ret);
return ret; return ret;
} }
@ -255,7 +235,21 @@ public class CPUOptimizedClipboard extends FaweClipboard {
} }
@Override @Override
public boolean remove(ClipboardEntity clipboardEntity) { public void removeEntity(Entity entity) {
return entities.remove(clipboardEntity); 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.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion; 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.BiomeType;
import com.sk89q.worldedit.world.biome.BiomeTypes; import com.sk89q.worldedit.world.biome.BiomeTypes;
import com.sk89q.worldedit.world.block.BaseBlock; 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.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import javax.annotation.Nullable;
import java.io.Closeable; import java.io.Closeable;
import java.io.DataInputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -34,6 +41,7 @@ import java.nio.channels.FileChannel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
@ -43,18 +51,12 @@ import java.util.UUID;
* - Uses an auto closable RandomAccessFile for getting / setting id / data * - 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. * - 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; 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 HashMap<IntegerTrio, CompoundTag> nbtMap;
private final HashSet<ClipboardEntity> entities; private final HashSet<BlockArrayClipboard.ClipboardEntity> entities;
private final File file; private final File file;
private RandomAccessFile braf; private RandomAccessFile braf;
@ -63,11 +65,60 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
private FileChannel fileChannel; private FileChannel fileChannel;
private boolean hasBiomes; private boolean hasBiomes;
public DiskOptimizedClipboard(int width, int height, int length, UUID uuid) { public DiskOptimizedClipboard(BlockVector3 dimensions, UUID uuid) {
this(width, height, length, MainUtil.getFile(Fawe.get() != null ? Fawe.imp().getDirectory() : new File("."), Settings.IMP.PATHS.CLIPBOARD + File.separator + uuid + ".bd")); 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) { public DiskOptimizedClipboard(File file) {
super(readSize(file));
try { try {
nbtMap = new HashMap<>(); nbtMap = new HashMap<>();
entities = new HashSet<>(); entities = new HashSet<>();
@ -75,13 +126,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
this.braf = new RandomAccessFile(file, "rw"); this.braf = new RandomAccessFile(file, "rw");
braf.setLength(file.length()); braf.setLength(file.length());
init(); init();
width = byteBuffer.getChar(2); if (braf.length() - HEADER_SIZE == (getVolume() << 1) + getArea()) {
height = byteBuffer.getChar(4);
length = byteBuffer.getChar(6);
area = width * length;
this.volume = length * width * height;
if (braf.length() - HEADER_SIZE == (volume << 2) + area) {
hasBiomes = true; hasBiomes = true;
} }
autoCloseTask(); autoCloseTask();
@ -107,7 +152,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
hasBiomes = true; hasBiomes = true;
close(); close();
this.braf = new RandomAccessFile(file, "rw"); this.braf = new RandomAccessFile(file, "rw");
this.braf.setLength(HEADER_SIZE + (volume << 2) + area); this.braf.setLength(HEADER_SIZE + (getVolume() << 1) + getArea());
init(); init();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
@ -123,7 +168,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
} }
@Override @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); setBiome(getIndex(x, 0, z), biome);
return true; return true;
} }
@ -131,7 +176,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
@Override @Override
public void setBiome(int index, BiomeType biome) { public void setBiome(int index, BiomeType biome) {
if (initBiome()) { 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()) { if (!hasBiomes()) {
return null; 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); return BiomeTypes.get(biomeId);
} }
@ -148,9 +193,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
public void streamBiomes(NBTStreamer.ByteReader task) { public void streamBiomes(NBTStreamer.ByteReader task) {
if (!hasBiomes()) return; if (!hasBiomes()) return;
int index = 0; int index = 0;
int mbbIndex = HEADER_SIZE + (volume << 2); int mbbIndex = HEADER_SIZE + (getVolume() << 1);
for (int z = 0; z < length; z++) { for (int z = 0; z < getLength(); z++) {
for (int x = 0; x < width; x++, index++, mbbIndex++) { for (int x = 0; x < getWidth(); x++, index++, mbbIndex++) {
int biome = byteBuffer.get(mbbIndex) & 0xFF; int biome = byteBuffer.get(mbbIndex) & 0xFF;
task.run(index, biome); task.run(index, biome);
} }
@ -158,18 +203,13 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
} }
@Override @Override
public BiomeType getBiome(int x, int z) { public BiomeType getBiomeType(int x, int z) {
return getBiome(getIndex(x, 0, z)); return getBiome(getIndex(x, 0, z));
} }
@Override
public BlockVector3 getDimensions() {
return BlockVector3.at(width, height, length);
}
public BlockArrayClipboard toClipboard() { public BlockArrayClipboard toClipboard() {
try { 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 ox = byteBuffer.getShort(8);
int oy = byteBuffer.getShort(10); int oy = byteBuffer.getShort(10);
int oz = byteBuffer.getShort(12); int oz = byteBuffer.getShort(12);
@ -182,45 +222,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
return null; 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 @Override
public void setOrigin(BlockVector3 offset) { public void setOrigin(BlockVector3 offset) {
super.setOrigin(offset);
try { try {
byteBuffer.putShort(8, (short) offset.getBlockX()); byteBuffer.putShort(8, (short) offset.getBlockX());
byteBuffer.putShort(10, (short) offset.getBlockY()); 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 @Override
public void flush() { public void flush() {
byteBuffer.force(); 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) { private void closeDirectBuffer(ByteBuffer cb) {
if (cb == null || !cb.isDirect()) return; if (cb == null || !cb.isDirect()) return;
// we could use this type cast and call functions without reflection code, // 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 @Override
public void close() { public void close() {
try { try {
@ -332,16 +304,16 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
private int zlasti; private int zlasti;
@Override @Override
public void streamCombinedIds(NBTStreamer.ByteReader task) { public void streamOrdinals(NBTStreamer.ByteReader task) {
try { try {
byteBuffer.force(); byteBuffer.force();
int pos = HEADER_SIZE; int pos = HEADER_SIZE;
int index = 0; int index = 0;
for (int y = 0; y < height; y++) { for (int y = 0; y < getHeight(); y++) {
for (int z = 0; z < length; z++) { for (int z = 0; z < getLength(); z++) {
for (int x = 0; x < width; x++, pos += 4) { for (int x = 0; x < getWidth(); x++, pos += 2) {
int combinedId = byteBuffer.getInt(pos); char ordinal = byteBuffer.getChar(pos);
task.run(index++, combinedId); task.run(index++, ordinal);
} }
} }
} }
@ -363,13 +335,12 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
final boolean hasTile = !nbtMap.isEmpty(); final boolean hasTile = !nbtMap.isEmpty();
if (air) { if (air) {
if (hasTile) { if (hasTile) {
for (int y = 0; y < height; y++) { for (int y = 0; y < getHeight(); y++) {
for (int z = 0; z < length; z++) { for (int z = 0; z < getLength(); z++) {
for (int x = 0; x < width; x++, pos += 4) { for (int x = 0; x < getWidth(); x++, pos += 2) {
int combinedId = byteBuffer.getInt(pos); int combinedId = byteBuffer.getChar(pos);
BlockType type = BlockTypes.getFromStateId(combinedId); BlockState state = BlockState.getFromOrdinal(combinedId);
BlockState state = type.withStateId(combinedId); if (state.getMaterial().hasContainer()) {
if (type.getMaterial().hasContainer()) {
trio.set(x, y, z); trio.set(x, y, z);
CompoundTag nbt = nbtMap.get(trio); CompoundTag nbt = nbtMap.get(trio);
if (nbt != null) { if (nbt != null) {
@ -382,31 +353,28 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
} }
} }
} else { } else {
for (int y = 0; y < height; y++) { for (int y = 0; y < getHeight(); y++) {
for (int z = 0; z < length; z++) { for (int z = 0; z < getLength(); z++) {
for (int x = 0; x < width; x++, pos += 4) { for (int x = 0; x < getWidth(); x++, pos += 2) {
int combinedId = byteBuffer.getInt(pos); int combinedId = byteBuffer.getChar(pos);
BlockState state = BlockState.getFromInternalId(combinedId); BlockState state = BlockState.getFromOrdinal(combinedId);
task.run(x, y, z, state); task.run(x, y, z, state);
} }
} }
} }
} }
} else { } else {
for (int y = 0; y < height; y++) { for (int y = 0; y < getHeight(); y++) {
for (int z = 0; z < length; z++) { for (int z = 0; z < getLength(); z++) {
for (int x = 0; x < width; x++, pos += 4) { for (int x = 0; x < getWidth(); x++, pos += 2) {
int combinedId = byteBuffer.getInt(pos); char combinedId = byteBuffer.getChar(pos);
BlockType type = BlockTypes.getFromStateId(combinedId); BlockState state = BlockState.getFromOrdinal(combinedId);
if (!type.getMaterial().isAir()) { if (state.getMaterial().hasContainer()) {
BlockState state = type.withStateId(combinedId); trio.set(x, y, z);
if (type.getMaterial().hasContainer()) { CompoundTag nbt = nbtMap.get(trio);
trio.set(x, y, z); if (nbt != null) {
CompoundTag nbt = nbtMap.get(trio); task.run(x, y, z, state.toBaseBlock(nbt));
if (nbt != null) { continue;
task.run(x, y, z, state.toBaseBlock(nbt));
continue;
}
} }
task.run(x, y, z, state); 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) { public int getIndex(int x, int y, int z) {
return x + (ylast == y ? ylasti : (ylasti = (ylast = y) * area)) + (zlast == z return x + (ylast == y ? ylasti : (ylasti = (ylast = y) * getArea())) + (zlast == z
? zlasti : (zlasti = (zlast = z) * width)); ? zlasti : (zlasti = (zlast = z) * getWidth()));
} }
@Override @Override
public BaseBlock getBlock(int x, int y, int z) { public BaseBlock getFullBlock(int x, int y, int z) {
try { try {
int index = HEADER_SIZE + (getIndex(x, y, z) << 2); int index = HEADER_SIZE + (getIndex(x, y, z) << 1);
int combinedId = byteBuffer.getInt(index); int combinedId = byteBuffer.getChar(index);
BlockType type = BlockTypes.getFromStateId(combinedId); BlockState state = BlockState.getFromOrdinal(combinedId);
BaseBlock base = type.withStateId(combinedId).toBaseBlock(); if (state.getMaterial().hasContainer() && !nbtMap.isEmpty()) {
if (type.getMaterial().hasContainer() && !nbtMap.isEmpty()) {
CompoundTag nbt = nbtMap.get(new IntegerTrio(x, y, z)); CompoundTag nbt = nbtMap.get(new IntegerTrio(x, y, z));
if (nbt != null) { return state.toBaseBlock(nbt);
return base.toBaseBlock(nbt);
}
} }
return base; return state.toBaseBlock();
} catch (IndexOutOfBoundsException ignore) { } catch (IndexOutOfBoundsException ignore) {
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -443,13 +408,12 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
} }
@Override @Override
public BaseBlock getBlock(int i) { public BaseBlock getFullBlock(int i) {
try { try {
int diskIndex = HEADER_SIZE + (i << 2); int diskIndex = HEADER_SIZE + (i << 1);
int combinedId = byteBuffer.getInt(diskIndex); char ordinal = byteBuffer.getChar(diskIndex);
BlockType type = BlockTypes.getFromStateId(combinedId); BlockState state = BlockState.getFromOrdinal(ordinal);
BaseBlock base = type.withStateId(combinedId).toBaseBlock(); if (state.getMaterial().hasContainer() && !nbtMap.isEmpty()) {
if (type.getMaterial().hasContainer() && !nbtMap.isEmpty()) {
CompoundTag nbt; CompoundTag nbt;
if (nbtMap.size() < 4) { if (nbtMap.size() < 4) {
nbt = null; nbt = null;
@ -462,18 +426,18 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
} }
} }
} else { } else {
// x + z * width + y * area; // x + z * getWidth() + y * area;
int y = i / area; int y = i / getArea();
int newI = i - y * area; int newI = i - y * getArea();
int z = newI / width; int z = newI / getWidth();
int x = newI - z * width; int x = newI - z * getWidth();
nbt = nbtMap.get(new IntegerTrio(x, y, z)); nbt = nbtMap.get(new IntegerTrio(x, y, z));
} }
if (nbt != null) { if (nbt != null) {
return base.toBaseBlock(nbt); return state.toBaseBlock(nbt);
} }
} }
return base; return state.toBaseBlock();
} catch (IndexOutOfBoundsException ignore) { } catch (IndexOutOfBoundsException ignore) {
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -494,9 +458,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
@Override @Override
public <B extends BlockStateHolder<B>> boolean setBlock(int x, int y, int z, B block) { public <B extends BlockStateHolder<B>> boolean setBlock(int x, int y, int z, B block) {
try { try {
int index = HEADER_SIZE + (getIndex(x, y, z) << 2); int index = HEADER_SIZE + (getIndex(x, y, z) << 1);
int combined = block.getInternalId(); char ordinal = block.getOrdinalChar();
byteBuffer.putInt(index, combined); byteBuffer.putChar(index, ordinal);
boolean hasNbt = block instanceof BaseBlock && block.hasNbtData(); boolean hasNbt = block instanceof BaseBlock && block.hasNbtData();
if (hasNbt) { if (hasNbt) {
setTile(x, y, z, block.getNbtData()); setTile(x, y, z, block.getNbtData());
@ -511,15 +475,15 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
@Override @Override
public <B extends BlockStateHolder<B>> boolean setBlock(int i, B block) { public <B extends BlockStateHolder<B>> boolean setBlock(int i, B block) {
try { try {
int combined = block.getInternalId(); char ordinal = block.getOrdinalChar();
int index = HEADER_SIZE + (i << 2); int index = HEADER_SIZE + (i << 1);
byteBuffer.putInt(index, combined); byteBuffer.putChar(index, ordinal);
boolean hasNbt = block instanceof BaseBlock && block.hasNbtData(); boolean hasNbt = block instanceof BaseBlock && block.hasNbtData();
if (hasNbt) { if (hasNbt) {
int y = i / area; int y = i / getArea();
int newI = i - y * area; int newI = i - y * getArea();
int z = newI / width; int z = newI / getWidth();
int x = newI - z * width; int x = newI - z * getWidth();
setTile(x, y, z, block.getNbtData()); setTile(x, y, z, block.getNbtData());
} }
return true; return true;
@ -529,9 +493,10 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
return false; return false;
} }
@Nullable
@Override @Override
public Entity createEntity(Extent world, double x, double y, double z, float yaw, float pitch, BaseEntity entity) { public Entity createEntity(Location location, BaseEntity entity) {
FaweClipboard.ClipboardEntity ret = new ClipboardEntity(world, x, y, z, yaw, pitch, entity); BlockArrayClipboard.ClipboardEntity ret = new BlockArrayClipboard.ClipboardEntity(location, entity);
entities.add(ret); entities.add(ret);
return ret; return ret;
} }
@ -542,7 +507,21 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
} }
@Override @Override
public boolean remove(ClipboardEntity clipboardEntity) { public void removeEntity(Entity entity) {
return entities.remove(clipboardEntity); 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.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
import com.sk89q.worldedit.math.BlockVector3; 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.BiomeType;
import com.sk89q.worldedit.world.biome.BiomeTypes; import com.sk89q.worldedit.world.biome.BiomeTypes;
import com.sk89q.worldedit.world.block.BaseBlock; 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.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID;
import net.jpountz.util.SafeUtils; 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_MASK = 1048575;
private static final int BLOCK_SHIFT = 20; 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[][] states;
private byte[] buffer = new byte[MainUtil.getMaxCompressedLength(BLOCK_SIZE)]; 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<IntegerTrio, CompoundTag> nbtMapLoc;
private final HashMap<Integer, CompoundTag> nbtMapIndex; private final HashMap<Integer, CompoundTag> nbtMapIndex;
private final HashSet<ClipboardEntity> entities; private final HashSet<BlockArrayClipboard.ClipboardEntity> entities;
private int lastCombinedIdsI = -1; private int lastCombinedIdsI = -1;
@ -55,17 +56,13 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
private int compressionLevel; private int compressionLevel;
public MemoryOptimizedClipboard(int width, int height, int length) { public MemoryOptimizedClipboard(BlockVector3 dimensions) {
this(width, height, length, Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL); this(dimensions, Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL);
} }
public MemoryOptimizedClipboard(int width, int height, int length, int compressionLevel) { public MemoryOptimizedClipboard(BlockVector3 dimensions, int compressionLevel) {
this.width = width; super(dimensions);
this.height = height; states = new byte[1 + (getVolume() >> BLOCK_SHIFT)][];
this.length = length;
this.area = width * length;
this.volume = area * height;
states = new byte[1 + (volume >> BLOCK_SHIFT)][];
nbtMapLoc = new HashMap<>(); nbtMapLoc = new HashMap<>();
nbtMapIndex = new HashMap<>(); nbtMapIndex = new HashMap<>();
entities = new HashSet<>(); entities = new HashSet<>();
@ -89,7 +86,7 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
} }
@Override @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); setBiome(getIndex(x, 0, z), biome);
return true; return true;
} }
@ -97,7 +94,7 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
@Override @Override
public void setBiome(int index, BiomeType biome) { public void setBiome(int index, BiomeType biome) {
if (biomes == null) { if (biomes == null) {
biomes = new byte[area]; biomes = new byte[getArea()];
} }
biomes[index] = (byte) biome.getInternalId(); biomes[index] = (byte) biome.getInternalId();
} }
@ -106,8 +103,8 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
public void streamBiomes(NBTStreamer.ByteReader task) { public void streamBiomes(NBTStreamer.ByteReader task) {
if (!hasBiomes()) return; if (!hasBiomes()) return;
int index = 0; int index = 0;
for (int z = 0; z < length; z++) { for (int z = 0; z < getLength(); z++) {
for (int x = 0; x < width; x++, index++) { for (int x = 0; x < getWidth(); x++, index++) {
task.run(index, biomes[index] & 0xFF); task.run(index, biomes[index] & 0xFF);
} }
} }
@ -122,7 +119,7 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
} }
@Override @Override
public BiomeType getBiome(int x, int z) { public BiomeType getBiomeType(int x, int z) {
return getBiome(getIndex(x, 0, z)); return getBiome(getIndex(x, 0, z));
} }
@ -131,22 +128,24 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
return nbtMapIndex.get(index); return nbtMapIndex.get(index);
} }
public int getCombinedId(int index) { public int getOrdinal(int index) {
int i = index >> BLOCK_SHIFT; int i = index >> BLOCK_SHIFT;
if (i == lastCombinedIdsI) { int li = (index & BLOCK_MASK) << 1;
if (lastCombinedIds == null) { 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 0;
} }
return lastCombinedIds[index & BLOCK_MASK] & 0xFF;
} }
saveCombinedIds(); if (lastCombinedIds == null) {
byte[] compressed = states[lastCombinedIdsI = i]; return 0;
if (compressed == null) {
lastCombinedIds = null;
return BlockTypes.AIR.getInternalId();
} }
lastCombinedIds = MainUtil.decompress(compressed, lastCombinedIds, BLOCK_SIZE, compressionLevel); int ordinal = ((lastCombinedIds[li] << 8) + lastCombinedIds[li + 1]);
return SafeUtils.readIntBE(lastCombinedIds, index & BLOCK_MASK); return ordinal;
} }
private void saveCombinedIds() { private void saveCombinedIds() {
@ -156,26 +155,6 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
saveCombinedIds = false; 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 lastI;
private int lastIMin; private int lastIMin;
private int lastIMax; private int lastIMax;
@ -207,22 +186,20 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
} }
lastCombinedIds = new byte[BLOCK_SIZE]; lastCombinedIds = new byte[BLOCK_SIZE];
} }
int li = (index & BLOCK_MASK) << 2; int li = (index & BLOCK_MASK) << 1;
lastCombinedIds[li] = (byte) ((v >>> 24) & 0xFF); lastCombinedIds[li] = (byte) ((v >>> 8) & 0xFF);
lastCombinedIds[li + 1] = (byte) ((v >>> 16) & 0xFF); lastCombinedIds[li + 1] = (byte) (v & 0xFF);
lastCombinedIds[li + 2] = (byte) ((v >>> 8) & 0xFF);
lastCombinedIds[li + 3] = (byte) ((v >>> 0) & 0xFF);
saveCombinedIds = true; saveCombinedIds = true;
} }
@Override @Override
public void streamCombinedIds(NBTStreamer.ByteReader task) { public void streamOrdinals(NBTStreamer.ByteReader task) {
int index = 0; int index = 0;
for (int y = 0; y < height; y++) { for (int y = 0; y < getHeight(); y++) {
for (int z = 0; z < length; z++) { for (int z = 0; z < getLength(); z++) {
for (int x = 0; x < width; x++) { for (int x = 0; x < getWidth(); x++, index++) {
int id = getCombinedId(index); int id = getOrdinal(index);
task.run(index++, id); task.run(index, id);
} }
} }
} }
@ -236,10 +213,10 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
CompoundTag tag = entry.getValue(); CompoundTag tag = entry.getValue();
Map<String, Tag> values = ReflectionUtils.getMap(tag.getValue()); Map<String, Tag> values = ReflectionUtils.getMap(tag.getValue());
if (!values.containsKey("x")) { if (!values.containsKey("x")) {
int y = index / area; int y = index / getArea();
index -= y * area; index -= y * getArea();
int z = index / width; int z = index / getWidth();
int x = index - (z * width); int x = index - (z * getWidth());
values.put("x", new IntTag(x)); values.put("x", new IntTag(x));
values.put("y", new IntTag(y)); values.put("y", new IntTag(y));
values.put("z", new IntTag(z)); values.put("z", new IntTag(z));
@ -254,18 +231,18 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
private int zlasti; private int zlasti;
public int getIndex(int x, int y, int z) { 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 @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); int index = getIndex(x, y, z);
return getBlock(index); return getFullBlock(index);
} }
@Override @Override
public BaseBlock getBlock(int index) { public BaseBlock getFullBlock(int index) {
int combinedId = getCombinedId(index); int combinedId = getOrdinal(index);
BlockType type = BlockTypes.getFromStateId(combinedId); BlockType type = BlockTypes.getFromStateId(combinedId);
BaseBlock base = type.withStateId(combinedId).toBaseBlock(); BaseBlock base = type.withStateId(combinedId).toBaseBlock();
if (type.getMaterial().hasContainer()) { if (type.getMaterial().hasContainer()) {
@ -280,19 +257,19 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
@Override @Override
public void forEach(final BlockReader task, final boolean air) { public void forEach(final BlockReader task, final boolean air) {
if (air) { if (air) {
for (int y = 0, index = 0; y < height; y++) { for (int y = 0, index = 0; y < getHeight(); y++) {
for (int z = 0; z < length; z++) { for (int z = 0; z < getLength(); z++) {
for (int x = 0; x < width; x++, index++) { for (int x = 0; x < getWidth(); x++, index++) {
BaseBlock block = getBlock(index); BaseBlock block = getFullBlock(index);
task.run(x, y, z, block); task.run(x, y, z, block);
} }
} }
} }
} else { } else {
for (int y = 0, index = 0; y < height; y++) { for (int y = 0, index = 0; y < getHeight(); y++) {
for (int z = 0; z < length; z++) { for (int z = 0; z < getLength(); z++) {
for (int x = 0; x < width; x++, index++) { for (int x = 0; x < getWidth(); x++, index++) {
BaseBlock block = getBlock(index); BaseBlock block = getFullBlock(index);
if (!block.getMaterial().isAir()) { if (!block.getMaterial().isAir()) {
task.run(x, y, z, block); task.run(x, y, z, block);
} }
@ -344,9 +321,10 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
return true; return true;
} }
@Nullable
@Override @Override
public Entity createEntity(Extent world, double x, double y, double z, float yaw, float pitch, BaseEntity entity) { public Entity createEntity(Location location, BaseEntity entity) {
FaweClipboard.ClipboardEntity ret = new ClipboardEntity(world, x, y, z, yaw, pitch, entity); BlockArrayClipboard.ClipboardEntity ret = new BlockArrayClipboard.ClipboardEntity(location, entity);
entities.add(ret); entities.add(ret);
return ret; return ret;
} }
@ -357,7 +335,21 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
} }
@Override @Override
public boolean remove(ClipboardEntity clipboardEntity) { public void removeEntity(Entity entity) {
return entities.remove(clipboardEntity); 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<>(); holders = new ArrayList<>();
URI uri = URI.create(""); URI uri = URI.create("");
if (clipboard instanceof BlockArrayClipboard) { if (clipboard instanceof BlockArrayClipboard) {
FaweClipboard fc = ((BlockArrayClipboard) clipboard).IMP; LinearClipboard fc = ((BlockArrayClipboard) clipboard).IMP;
if (fc instanceof DiskOptimizedClipboard) { if (fc instanceof DiskOptimizedClipboard) {
uri = ((DiskOptimizedClipboard) fc).getFile().toURI(); uri = ((DiskOptimizedClipboard) fc).getFile().toURI();
} }

View File

@ -1,22 +1,25 @@
package com.boydti.fawe.object.clipboard; package com.boydti.fawe.object.clipboard;
import com.sk89q.jnbt.CompoundTag; 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.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
public class OffsetFaweClipboard extends AbstractDelegateFaweClipboard { public class OffsetClipboard extends DelegateClipboard {
private final int ox, oy, oz; 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); super(parent);
this.ox = ox; this.ox = ox;
this.oy = oy; this.oy = oy;
this.oz = oz; this.oz = oz;
} }
public OffsetFaweClipboard(FaweClipboard parent, int offset) { @Override
this(parent, offset, offset, offset); public Region getRegion() {
return parent.getRegion();
} }
@Override @Override

View File

@ -12,7 +12,7 @@ import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import java.util.List; import java.util.List;
public abstract class ReadOnlyClipboard extends FaweClipboard { public abstract class ReadOnlyClipboard extends LinearClipboard {
public final Region region; public final Region region;
public ReadOnlyClipboard(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 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.object.clipboard.ReadOnlyClipboard;
import com.boydti.fawe.util.EditSessionBuilder; import com.boydti.fawe.util.EditSessionBuilder;
import com.boydti.fawe.util.MaskTraverser; import com.boydti.fawe.util.MaskTraverser;
@ -213,7 +213,7 @@ public class Schematic {
BlockArrayClipboard bac = (BlockArrayClipboard) clipboard; BlockArrayClipboard bac = (BlockArrayClipboard) clipboard;
if (copyBiomes) { if (copyBiomes) {
bac.IMP.forEach(new FaweClipboard.BlockReader() { bac.IMP.forEach(new LinearClipboard.BlockReader() {
MutableBlockVector2 mpos2d = new MutableBlockVector2(); MutableBlockVector2 mpos2d = new MutableBlockVector2();
{ {
@ -239,7 +239,7 @@ public class Schematic {
} }
}, true); }, true);
} else { } else {
bac.IMP.forEach(new FaweClipboard.BlockReader() { bac.IMP.forEach(new LinearClipboard.BlockReader() {
@Override @Override
public <B extends BlockStateHolder<B>> void run(int x, int y, int z, B block) { public <B extends BlockStateHolder<B>> void run(int x, int y, int z, B block) {
try { try {

View File

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

View File

@ -22,14 +22,15 @@ package com.sk89q.worldedit.extent.clipboard;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.config.Settings; 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.DiskOptimizedClipboard;
import com.boydti.fawe.object.clipboard.FaweClipboard; import com.boydti.fawe.object.clipboard.LinearClipboard;
import com.boydti.fawe.object.clipboard.FaweClipboard.ClipboardEntity;
import com.boydti.fawe.object.clipboard.MemoryOptimizedClipboard; import com.boydti.fawe.object.clipboard.MemoryOptimizedClipboard;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
@ -40,7 +41,10 @@ import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import jdk.vm.ci.meta.Local;
import java.io.Closeable; import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; 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 * Stores block data as a multi-dimensional array of {@link BlockState}s and
* other data as lists or maps. * other data as lists or maps.
*/ */
public class BlockArrayClipboard implements Clipboard, Closeable { public class BlockArrayClipboard extends DelegateClipboard implements Clipboard, Closeable {
private Region region; private Region region;
private BlockVector3 origin; 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) { public BlockArrayClipboard(Region region) {
checkNotNull(region); this(region, UUID.randomUUID());
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();
} }
/** /**
@ -81,48 +72,24 @@ public class BlockArrayClipboard implements Clipboard, Closeable {
* @param region the bounding region * @param region the bounding region
*/ */
public BlockArrayClipboard(Region region, UUID clipboardId) { public BlockArrayClipboard(Region region, UUID clipboardId) {
this(region, Clipboard.create(region.getDimensions(), clipboardId));
checkNotNull(region); checkNotNull(region);
this.region = region.clone(); 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.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); checkNotNull(region);
this.region = region.clone(); this.region = region.clone();
this.size = getDimensions();
this.origin = region.getMinimumPoint(); 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 @Override
protected void finalize() { public void close() throws IOException {
close(); if (getParent() instanceof Closeable) {
} ((Closeable) getParent()).close();
}
@Override
public void close() {
IMP.close();
} }
@Override @Override
@ -142,12 +109,7 @@ public class BlockArrayClipboard implements Clipboard, Closeable {
@Override @Override
public void setOrigin(BlockVector3 origin) { public void setOrigin(BlockVector3 origin) {
this.origin = origin; this.origin = origin;
IMP.setOrigin(origin.subtract(region.getMinimumPoint())); getParent().setOrigin(origin.subtract(region.getMinimumPoint()));
}
@Override
public BlockVector3 getDimensions() {
return region.getMaximumPoint().subtract(region.getMinimumPoint()).add(1, 1, 1);
} }
@Override @Override
@ -160,35 +122,13 @@ public class BlockArrayClipboard implements Clipboard, Closeable {
return region.getMaximumPoint(); 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 @Override
public BlockState getBlock(BlockVector3 position) { public BlockState getBlock(BlockVector3 position) {
if (region.contains(position)) { if (region.contains(position)) {
int x = position.getBlockX() - mx; int x = position.getBlockX()- origin.getX();
int y = position.getBlockY() - my; int y = position.getBlockY()- origin.getY();
int z = position.getBlockZ() - mz; int z = position.getBlockZ()- origin.getZ();
return IMP.getBlock(x, y, z).toImmutableState(); return getParent().getBlock(x, y, z);
} }
return BlockTypes.AIR.getDefaultState(); return BlockTypes.AIR.getDefaultState();
@ -197,10 +137,10 @@ public class BlockArrayClipboard implements Clipboard, Closeable {
@Override @Override
public BaseBlock getFullBlock(BlockVector3 position) { public BaseBlock getFullBlock(BlockVector3 position) {
if(region.contains(position)) { if(region.contains(position)) {
int x = position.getBlockX() - mx; int x = position.getBlockX()- origin.getX();
int y = position.getBlockY() - my; int y = position.getBlockY()- origin.getY();
int z = position.getBlockZ() - mz; int z = position.getBlockZ()- origin.getZ();
return IMP.getBlock(x, y, z); return getParent().getFullBlock(x, y, z);
} }
return BlockTypes.AIR.getDefaultState().toBaseBlock(); return BlockTypes.AIR.getDefaultState().toBaseBlock();
} }
@ -218,10 +158,10 @@ public class BlockArrayClipboard implements Clipboard, Closeable {
@Override @Override
public boolean setTile(int x, int y, int z, CompoundTag tag) { public boolean setTile(int x, int y, int z, CompoundTag tag) {
x -= mx; x -= origin.getX();
y -= my; y -= origin.getY();
z -= mz; z -= origin.getZ();
return IMP.setTile(x, y, z, tag); return getParent().setTile(x, y, z, tag);
} }
public boolean setTile(BlockVector3 position, CompoundTag tag) { public boolean setTile(BlockVector3 position, CompoundTag tag) {
@ -230,38 +170,133 @@ public class BlockArrayClipboard implements Clipboard, Closeable {
@Override @Override
public <B extends BlockStateHolder<B>> boolean setBlock(int x, int y, int z, B block) throws WorldEditException { public <B extends BlockStateHolder<B>> boolean setBlock(int x, int y, int z, B block) throws WorldEditException {
x -= mx; x -= origin.getX();
y -= my; y -= origin.getY();
z -= mz; z -= origin.getZ();
return IMP.setBlock(x, y, z, block); return getParent().setBlock(x, y, z, block);
} }
@Override @Override
public boolean hasBiomes() { public boolean hasBiomes() {
return IMP.hasBiomes(); return getParent().hasBiomes();
} }
@Override @Override
public BiomeType getBiome(BlockVector2 position) { public BiomeType getBiome(BlockVector2 position) {
BlockVector2 v = position.subtract(region.getMinimumPoint().toBlockVector2()); BlockVector2 v = position.subtract(region.getMinimumPoint().toBlockVector2());
return IMP.getBiome(v.getX(), v.getZ()); return getParent().getBiomeType(v.getX(), v.getZ());
} }
@Override @Override
public boolean setBiome(BlockVector2 position, BiomeType biome) { public boolean setBiome(BlockVector2 position, BiomeType biome) {
int x = position.getBlockX() - mx; int x = position.getBlockX()- origin.getX();
int z = position.getBlockZ() - mz; int z = position.getBlockZ()- origin.getZ();
return IMP.setBiome(x, z, biome); return getParent().setBiome(x, 0, z, biome);
} }
@Override @Override
public boolean setBiome(int x, int y, int z, BiomeType biome) { 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 @Override
public Operation commit() { public List<? extends Entity> getEntities(Region region) {
return null; 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; 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.extent.Extent;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region; 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." * Specifies an object that implements something suitable as a "clipboard."
*/ */
public interface Clipboard extends Extent { 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. * Get the bounding region of this extent.
@ -70,4 +88,10 @@ public interface Clipboard extends Extent {
default boolean hasBiomes() { default boolean hasBiomes() {
return false; 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; 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.extent.clipboard.Clipboard;
import com.sk89q.worldedit.math.BlockVector3;
import java.io.Closeable; import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.util.UUID; import java.util.UUID;
import java.util.function.Function;
/** /**
* Reads {@code Clipboard}s. * Reads {@code Clipboard}s.
@ -38,9 +43,20 @@ public interface ClipboardReader extends Closeable {
* @return the read clipboard * @return the read clipboard
* @throws IOException thrown on I/O error * @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 { 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(); 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.FaweOutputStream;
import com.boydti.fawe.object.clipboard.CPUOptimizedClipboard; import com.boydti.fawe.object.clipboard.CPUOptimizedClipboard;
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard; 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.clipboard.MemoryOptimizedClipboard;
import com.boydti.fawe.object.io.FastByteArrayOutputStream; import com.boydti.fawe.object.io.FastByteArrayOutputStream;
import com.boydti.fawe.object.io.FastByteArraysInputStream; 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.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.DataFixer;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.biome.BiomeTypes; 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.block.BlockTypes;
import com.sk89q.worldedit.world.entity.EntityType; import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.entity.EntityTypes; import com.sk89q.worldedit.world.entity.EntityTypes;
import com.sk89q.worldedit.world.storage.NBTConversions;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.UUID; import java.util.UUID;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Function;
import net.jpountz.lz4.LZ4BlockInputStream; import net.jpountz.lz4.LZ4BlockInputStream;
import net.jpountz.lz4.LZ4BlockOutputStream; import net.jpountz.lz4.LZ4BlockOutputStream;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -99,13 +99,18 @@ public class SpongeSchematicReader extends NBTSchematicReader {
return reader(uuid); return reader(uuid);
} }
@Override
public Clipboard read(UUID uuid, Function<BlockVector3, Clipboard> createOutput) {
return null;
}
private int width, height, length; private int width, height, length;
private int offsetX, offsetY, offsetZ; private int offsetX, offsetY, offsetZ;
private char[] palette; private char[] palette;
private BlockVector3 min; 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 != null) {
if (fc.getDimensions().getX() == 0) { if (fc.getDimensions().getX() == 0) {
fc.setDimensions(BlockVector3.at(size, 1, 1)); fc.setDimensions(BlockVector3.at(size, 1, 1));
@ -113,11 +118,11 @@ public class SpongeSchematicReader extends NBTSchematicReader {
return fc; return fc;
} }
if (Settings.IMP.CLIPBOARD.USE_DISK) { 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) { } 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 { } 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 static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.jnbt.NBTStreamer; 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.boydti.fawe.util.IOUtil;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
@ -146,7 +146,7 @@ public class SpongeSchematicWriter implements ClipboardWriter {
int[] numTiles = {0}; int[] numTiles = {0};
FaweClipboard.BlockReader reader = new FaweClipboard.BlockReader() { LinearClipboard.BlockReader reader = new LinearClipboard.BlockReader() {
@Override @Override
public <B extends BlockStateHolder<B>> void run(int x, int y, int z, B block) { public <B extends BlockStateHolder<B>> void run(int x, int y, int z, B block) {
try { try {

View File

@ -60,6 +60,10 @@ public interface Region extends Iterable<BlockVector3>, Cloneable, IBatchProcess
*/ */
BlockVector3 getMaximumPoint(); BlockVector3 getMaximumPoint();
default BlockVector3 getDimensions() {
return getMaximumPoint().subtract(getMinimumPoint()).add(1, 1, 1);
}
/** /**
* Get the center point of a region. * Get the center point of a region.
* Note: Coordinates will not be integers * Note: Coordinates will not be integers