Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-11-02 17:40:09 +01:00
wip remove faweclipboard
Dieser Commit ist enthalten in:
Ursprung
e1b9b9e3e8
Commit
0296d566ed
@ -4,17 +4,11 @@ import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.clipboard.CPUOptimizedClipboard;
|
||||
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
||||
import com.boydti.fawe.object.clipboard.FaweClipboard;
|
||||
import com.boydti.fawe.object.clipboard.LinearClipboard;
|
||||
import com.boydti.fawe.object.clipboard.MemoryOptimizedClipboard;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
@ -29,7 +23,7 @@ public class CorruptSchematicStreamer {
|
||||
|
||||
private final InputStream stream;
|
||||
private final UUID uuid;
|
||||
private FaweClipboard fc;
|
||||
private LinearClipboard fc;
|
||||
final AtomicInteger volume = new AtomicInteger();
|
||||
final AtomicInteger width = new AtomicInteger();
|
||||
final AtomicInteger height = new AtomicInteger();
|
||||
@ -78,7 +72,7 @@ public class CorruptSchematicStreamer {
|
||||
}
|
||||
}
|
||||
|
||||
public FaweClipboard setupClipboard() {
|
||||
public LinearClipboard setupClipboard() {
|
||||
if (fc != null) {
|
||||
return fc;
|
||||
}
|
||||
@ -87,11 +81,11 @@ public class CorruptSchematicStreamer {
|
||||
Fawe.debug("No dimensions found! Estimating based on factors:" + dimensions);
|
||||
}
|
||||
if (Settings.IMP.CLIPBOARD.USE_DISK) {
|
||||
fc = new DiskOptimizedClipboard(dimensions.getBlockX(), dimensions.getBlockY(), dimensions.getBlockZ(), uuid);
|
||||
fc = new DiskOptimizedClipboard(dimensions, uuid);
|
||||
} else if (Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL == 0) {
|
||||
fc = new CPUOptimizedClipboard(dimensions.getBlockX(), dimensions.getBlockY(), dimensions.getBlockZ());
|
||||
fc = new CPUOptimizedClipboard(dimensions);
|
||||
} else {
|
||||
fc = new MemoryOptimizedClipboard(dimensions.getBlockX(), dimensions.getBlockY(), dimensions.getBlockZ());
|
||||
fc = new MemoryOptimizedClipboard(dimensions);
|
||||
}
|
||||
return fc;
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import com.boydti.fawe.object.FaweInputStream;
|
||||
import com.boydti.fawe.object.FaweOutputStream;
|
||||
import com.boydti.fawe.object.clipboard.CPUOptimizedClipboard;
|
||||
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
||||
import com.boydti.fawe.object.clipboard.FaweClipboard;
|
||||
import com.boydti.fawe.object.clipboard.LinearClipboard;
|
||||
import com.boydti.fawe.object.clipboard.MemoryOptimizedClipboard;
|
||||
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
||||
import com.boydti.fawe.object.io.FastByteArraysInputStream;
|
||||
@ -200,7 +200,7 @@ public class SchematicStreamer extends NBTStreamer {
|
||||
}
|
||||
|
||||
private void fixStates() {
|
||||
fc.forEach(new FaweClipboard.BlockReader() {
|
||||
fc.forEach(new LinearClipboard.BlockReader() {
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> void run(int x, int y, int z, B block) {
|
||||
BlockType type = block.getBlockType();
|
||||
@ -360,9 +360,9 @@ public class SchematicStreamer extends NBTStreamer {
|
||||
private int offsetZ;
|
||||
|
||||
private BlockArrayClipboard clipboard;
|
||||
private FaweClipboard fc;
|
||||
private LinearClipboard fc;
|
||||
|
||||
private FaweClipboard setupClipboard(int size) {
|
||||
private LinearClipboard setupClipboard(int size) {
|
||||
if (fc != null) {
|
||||
if (fc.getDimensions().getX() == 0) {
|
||||
fc.setDimensions(BlockVector3.at(size, 1, 1));
|
||||
@ -370,11 +370,11 @@ public class SchematicStreamer extends NBTStreamer {
|
||||
return fc;
|
||||
}
|
||||
if (Settings.IMP.CLIPBOARD.USE_DISK) {
|
||||
return fc = new DiskOptimizedClipboard(size, 1, 1, uuid);
|
||||
return fc = new DiskOptimizedClipboard(BlockVector3.at(size, 1, 1), uuid);
|
||||
} else if (Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL == 0) {
|
||||
return fc = new CPUOptimizedClipboard(size, 1, 1);
|
||||
return fc = new CPUOptimizedClipboard(BlockVector3.at(size, 1, 1));
|
||||
} else {
|
||||
return fc = new MemoryOptimizedClipboard(size, 1, 1);
|
||||
return fc = new MemoryOptimizedClipboard(BlockVector3.at(size, 1, 1));
|
||||
}
|
||||
}
|
||||
|
||||
@ -390,7 +390,7 @@ public class SchematicStreamer extends NBTStreamer {
|
||||
return BlockVector3.at(width, height, length);
|
||||
}
|
||||
|
||||
public void setClipboard(FaweClipboard clipboard) {
|
||||
public void setClipboard(LinearClipboard clipboard) {
|
||||
this.fc = clipboard;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.boydti.fawe.object.brush;
|
||||
|
||||
import com.boydti.fawe.object.clipboard.CPUOptimizedClipboard;
|
||||
import com.boydti.fawe.object.clipboard.FaweClipboard;
|
||||
import com.boydti.fawe.object.clipboard.LinearClipboard;
|
||||
import com.boydti.fawe.object.clipboard.OffsetFaweClipboard;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
@ -40,8 +40,8 @@ public class ErodeBrush implements Brush {
|
||||
int brushSize = (int) size + 1;
|
||||
int brushSizeSquared = (int) (size * size);
|
||||
int dimension = brushSize * 2 + 1;
|
||||
FaweClipboard buffer1 = new OffsetFaweClipboard(new CPUOptimizedClipboard(dimension, dimension, dimension), brushSize);
|
||||
FaweClipboard buffer2 = new OffsetFaweClipboard(new CPUOptimizedClipboard(dimension, dimension, dimension), brushSize);
|
||||
LinearClipboard buffer1 = new OffsetFaweClipboard(new CPUOptimizedClipboard(dimension, dimension, dimension), brushSize);
|
||||
LinearClipboard buffer2 = new OffsetFaweClipboard(new CPUOptimizedClipboard(dimension, dimension, dimension), brushSize);
|
||||
|
||||
final int bx = target.getBlockX();
|
||||
final int by = target.getBlockY();
|
||||
@ -70,9 +70,9 @@ public class ErodeBrush implements Brush {
|
||||
fillIteration(brushSize, brushSizeSquared, fillFaces, swap % 2 == 0 ? buffer1 : buffer2, swap % 2 == 1 ? buffer1 : buffer2);
|
||||
swap++;
|
||||
}
|
||||
FaweClipboard finalBuffer = swap % 2 == 0 ? buffer1 : buffer2;
|
||||
LinearClipboard finalBuffer = swap % 2 == 0 ? buffer1 : buffer2;
|
||||
|
||||
finalBuffer.forEach(new FaweClipboard.BlockReader() {
|
||||
finalBuffer.forEach(new LinearClipboard.BlockReader() {
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> void run(int x, int y, int z, B block) {
|
||||
es.setBlock(x + bx, y + by, z + bz, block);
|
||||
@ -81,7 +81,7 @@ public class ErodeBrush implements Brush {
|
||||
}
|
||||
|
||||
private void fillIteration(int brushSize, int brushSizeSquared, int fillFaces,
|
||||
FaweClipboard current, FaweClipboard target) {
|
||||
LinearClipboard current, LinearClipboard target) {
|
||||
int[] frequency = null;
|
||||
for (int x = -brushSize; x <= brushSize; x++) {
|
||||
int x2 = x * x;
|
||||
@ -126,7 +126,7 @@ public class ErodeBrush implements Brush {
|
||||
}
|
||||
|
||||
private void erosionIteration(int brushSize, int brushSizeSquared, int erodeFaces,
|
||||
FaweClipboard current, FaweClipboard target) {
|
||||
LinearClipboard current, LinearClipboard target) {
|
||||
int[] frequency = null;
|
||||
for (int x = -brushSize; x <= brushSize; x++) {
|
||||
int x2 = x * x;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -9,40 +9,38 @@ import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class CPUOptimizedClipboard extends FaweClipboard {
|
||||
private int length;
|
||||
private int height;
|
||||
private int width;
|
||||
private int area;
|
||||
private int volume;
|
||||
public class CPUOptimizedClipboard extends LinearClipboard {
|
||||
|
||||
private BiomeType[] biomes = null;
|
||||
private int[] states;
|
||||
private char[] states;
|
||||
|
||||
private final HashMap<IntegerTrio, CompoundTag> nbtMapLoc;
|
||||
private final HashMap<Integer, CompoundTag> nbtMapIndex;
|
||||
|
||||
private final HashSet<ClipboardEntity> entities;
|
||||
private final HashSet<BlockArrayClipboard.ClipboardEntity> entities;
|
||||
|
||||
public CPUOptimizedClipboard(int width, int height, int length) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.length = length;
|
||||
this.area = width * length;
|
||||
this.volume = area * height;
|
||||
this.states = new int[volume];
|
||||
public CPUOptimizedClipboard(BlockVector3 dimensions) {
|
||||
super(dimensions);
|
||||
this.states = new char[getVolume()];
|
||||
nbtMapLoc = new HashMap<>();
|
||||
nbtMapIndex = new HashMap<>();
|
||||
entities = new HashSet<>();
|
||||
@ -54,7 +52,7 @@ public class CPUOptimizedClipboard extends FaweClipboard {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(int x, int z, BiomeType biome) {
|
||||
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||
setBiome(getIndex(x, 0, z), biome);
|
||||
return true;
|
||||
}
|
||||
@ -62,7 +60,7 @@ public class CPUOptimizedClipboard extends FaweClipboard {
|
||||
@Override
|
||||
public void setBiome(int index, BiomeType biome) {
|
||||
if (biomes == null) {
|
||||
biomes = new BiomeType[area];
|
||||
biomes = new BiomeType[getArea()];
|
||||
}
|
||||
biomes[index] = biome;
|
||||
}
|
||||
@ -71,8 +69,8 @@ public class CPUOptimizedClipboard extends FaweClipboard {
|
||||
public void streamBiomes(NBTStreamer.ByteReader task) {
|
||||
if (!hasBiomes()) return;
|
||||
int index = 0;
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++, index++) {
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
for (int x = 0; x < getWidth(); x++, index++) {
|
||||
task.run(index, biomes[index].getInternalId());
|
||||
}
|
||||
}
|
||||
@ -87,7 +85,7 @@ public class CPUOptimizedClipboard extends FaweClipboard {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeType getBiome(int x, int z) {
|
||||
public BiomeType getBiomeType(int x, int z) {
|
||||
return getBiome(getIndex(x, 0, z));
|
||||
}
|
||||
|
||||
@ -107,70 +105,51 @@ public class CPUOptimizedClipboard extends FaweClipboard {
|
||||
return nbtMapIndex.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDimensions(BlockVector3 dimensions) {
|
||||
width = dimensions.getBlockX();
|
||||
height = dimensions.getBlockY();
|
||||
length = dimensions.getBlockZ();
|
||||
area = width * length;
|
||||
int newVolume = area * height;
|
||||
if (newVolume != volume) {
|
||||
volume = newVolume;
|
||||
states = new int[volume];
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockVector3 getDimensions() {
|
||||
return BlockVector3.at(width, height, length);
|
||||
}
|
||||
|
||||
private int yLast;
|
||||
private int yLastI;
|
||||
private int zLast;
|
||||
private int zLastI;
|
||||
|
||||
public int getIndex(int x, int y, int z) {
|
||||
return x + ((yLast == y) ? yLastI : (yLastI = (yLast = y) * area)) + ((zLast == z) ? zLastI
|
||||
: (zLastI = (zLast = z) * width));
|
||||
return x + ((yLast == y) ? yLastI : (yLastI = (yLast = y) * getArea())) + ((zLast == z) ? zLastI
|
||||
: (zLastI = (zLast = z) * getWidth()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getBlock(int x, int y, int z) {
|
||||
public BaseBlock getFullBlock(int x, int y, int z) {
|
||||
int index = getIndex(x, y, z);
|
||||
return getBlock(index);
|
||||
return getFullBlock(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getBlock(int index) {
|
||||
int combinedId = states[index];
|
||||
BlockType type = BlockTypes.getFromStateId(combinedId);
|
||||
BaseBlock base = type.withStateId(combinedId).toBaseBlock();
|
||||
if (type.getMaterial().hasContainer()) {
|
||||
public BaseBlock getFullBlock(int index) {
|
||||
char ordinal = states[index];
|
||||
BlockState state = BlockState.getFromOrdinal(ordinal);
|
||||
if (state.getMaterial().hasContainer()) {
|
||||
CompoundTag nbt = getTag(index);
|
||||
if (nbt != null) {
|
||||
return base.toBaseBlock(nbt);
|
||||
return state.toBaseBlock(nbt);
|
||||
}
|
||||
}
|
||||
return base;
|
||||
return state.toBaseBlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(final BlockReader task, boolean air) {
|
||||
if (air) {
|
||||
for (int y = 0, index = 0; y < height; y++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++, index++) {
|
||||
BaseBlock block = getBlock(index);
|
||||
for (int y = 0, index = 0; y < getHeight(); y++) {
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
for (int x = 0; x < getWidth(); x++, index++) {
|
||||
BaseBlock block = getFullBlock(index);
|
||||
task.run(x, y, z, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int y = 0, index = 0; y < height; y++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++, index++) {
|
||||
BaseBlock block = getBlock(index);
|
||||
for (int y = 0, index = 0; y < getHeight(); y++) {
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
for (int x = 0; x < getWidth(); x++, index++) {
|
||||
BaseBlock block = getFullBlock(index);
|
||||
if (!block.getMaterial().isAir()) {
|
||||
task.run(x, y, z, block);
|
||||
}
|
||||
@ -181,11 +160,11 @@ public class CPUOptimizedClipboard extends FaweClipboard {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void streamCombinedIds(NBTStreamer.ByteReader task) {
|
||||
public void streamOrdinals(NBTStreamer.ByteReader task) {
|
||||
int index = 0;
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int y = 0; y < getHeight(); y++) {
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
for (int x = 0; x < getWidth(); x++) {
|
||||
task.run(index, states[index++]);
|
||||
}
|
||||
}
|
||||
@ -200,10 +179,10 @@ public class CPUOptimizedClipboard extends FaweClipboard {
|
||||
CompoundTag tag = entry.getValue();
|
||||
Map<String, Tag> values = ReflectionUtils.getMap(tag.getValue());
|
||||
if (!values.containsKey("x")) {
|
||||
int y = index / area;
|
||||
index -= y * area;
|
||||
int z = index / width;
|
||||
int x = index - (z * width);
|
||||
int y = index / getArea();
|
||||
index -= y * getArea();
|
||||
int z = index / getWidth();
|
||||
int x = index - (z * getWidth());
|
||||
values.put("x", new IntTag(x));
|
||||
values.put("y", new IntTag(y));
|
||||
values.put("z", new IntTag(z));
|
||||
@ -234,7 +213,7 @@ public class CPUOptimizedClipboard extends FaweClipboard {
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(int index, B block) {
|
||||
states[index] = block.getInternalId();
|
||||
states[index] = block.getOrdinalChar();
|
||||
boolean hasNbt = block instanceof BaseBlock && block.hasNbtData();
|
||||
if (hasNbt) {
|
||||
setTile(index, block.getNbtData());
|
||||
@ -242,9 +221,10 @@ public class CPUOptimizedClipboard extends FaweClipboard {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Entity createEntity(Extent world, double x, double y, double z, float yaw, float pitch, BaseEntity entity) {
|
||||
FaweClipboard.ClipboardEntity ret = new ClipboardEntity(world, x, y, z, yaw, pitch, entity);
|
||||
public Entity createEntity(Location location, BaseEntity entity) {
|
||||
BlockArrayClipboard.ClipboardEntity ret = new BlockArrayClipboard.ClipboardEntity(location, entity);
|
||||
entities.add(ret);
|
||||
return ret;
|
||||
}
|
||||
@ -255,7 +235,21 @@ public class CPUOptimizedClipboard extends FaweClipboard {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(ClipboardEntity clipboardEntity) {
|
||||
return entities.remove(clipboardEntity);
|
||||
public void removeEntity(Entity entity) {
|
||||
this.entities.remove(entity);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public void removeEntity(int x, int y, int z, UUID uuid) {
|
||||
Iterator<BlockArrayClipboard.ClipboardEntity> iter = this.entities.iterator();
|
||||
while (iter.hasNext()) {
|
||||
BlockArrayClipboard.ClipboardEntity entity = iter.next();
|
||||
UUID entUUID = entity.getState().getNbtData().getUUID();
|
||||
if (uuid.equals(entUUID)) {
|
||||
iter.remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -15,6 +15,8 @@ import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
@ -22,8 +24,13 @@ import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.Closeable;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.lang.reflect.Field;
|
||||
@ -34,6 +41,7 @@ import java.nio.channels.FileChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
@ -43,18 +51,12 @@ import java.util.UUID;
|
||||
* - Uses an auto closable RandomAccessFile for getting / setting id / data
|
||||
* - I don't know how to reduce nbt / entities to O(2) complexity, so it is stored in memory.
|
||||
*/
|
||||
public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
public class DiskOptimizedClipboard extends LinearClipboard implements Closeable {
|
||||
|
||||
private static int HEADER_SIZE = 14;
|
||||
|
||||
protected int length;
|
||||
protected int height;
|
||||
protected int width;
|
||||
protected int area;
|
||||
protected int volume;
|
||||
|
||||
private final HashMap<IntegerTrio, CompoundTag> nbtMap;
|
||||
private final HashSet<ClipboardEntity> entities;
|
||||
private final HashSet<BlockArrayClipboard.ClipboardEntity> entities;
|
||||
private final File file;
|
||||
|
||||
private RandomAccessFile braf;
|
||||
@ -63,11 +65,60 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
private FileChannel fileChannel;
|
||||
private boolean hasBiomes;
|
||||
|
||||
public DiskOptimizedClipboard(int width, int height, int length, UUID uuid) {
|
||||
this(width, height, length, MainUtil.getFile(Fawe.get() != null ? Fawe.imp().getDirectory() : new File("."), Settings.IMP.PATHS.CLIPBOARD + File.separator + uuid + ".bd"));
|
||||
public DiskOptimizedClipboard(BlockVector3 dimensions, UUID uuid) {
|
||||
this(dimensions, MainUtil.getFile(Fawe.get() != null ? Fawe.imp().getDirectory() : new File("."), Settings.IMP.PATHS.CLIPBOARD + File.separator + uuid + ".bd"));
|
||||
}
|
||||
|
||||
public DiskOptimizedClipboard(BlockVector3 dimensions) {
|
||||
this(dimensions, MainUtil.getFile(Fawe.imp() != null ? Fawe.imp().getDirectory() : new File("."), Settings.IMP.PATHS.CLIPBOARD + File.separator + UUID.randomUUID() + ".bd"));
|
||||
}
|
||||
|
||||
public DiskOptimizedClipboard(BlockVector3 dimensions, File file) {
|
||||
super(dimensions);
|
||||
if (getWidth() > Character.MAX_VALUE || getHeight() > Character.MAX_VALUE || getLength() > Character.MAX_VALUE) {
|
||||
throw new IllegalArgumentException("Too large");
|
||||
}
|
||||
try {
|
||||
nbtMap = new HashMap<>();
|
||||
entities = new HashSet<>();
|
||||
this.file = file;
|
||||
try {
|
||||
if (!file.exists()) {
|
||||
File parent = file.getParentFile();
|
||||
if (parent != null) {
|
||||
file.getParentFile().mkdirs();
|
||||
}
|
||||
file.createNewFile();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.braf = new RandomAccessFile(file, "rw");
|
||||
long volume = (long) getArea() * 2L + (long) HEADER_SIZE;
|
||||
braf.setLength(0);
|
||||
braf.setLength(volume);
|
||||
init();
|
||||
// write getLength() etc
|
||||
byteBuffer.putChar(2, (char) getWidth());
|
||||
byteBuffer.putChar(4, (char) getHeight());
|
||||
byteBuffer.putChar(6, (char) getLength());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static BlockVector3 readSize(File file) {
|
||||
try (DataInputStream is = new DataInputStream(new FileInputStream(file))) {
|
||||
is.skipBytes(2);
|
||||
return BlockVector3.at(is.readChar(), is.readChar(), is.readChar());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public DiskOptimizedClipboard(File file) {
|
||||
super(readSize(file));
|
||||
try {
|
||||
nbtMap = new HashMap<>();
|
||||
entities = new HashSet<>();
|
||||
@ -75,13 +126,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
this.braf = new RandomAccessFile(file, "rw");
|
||||
braf.setLength(file.length());
|
||||
init();
|
||||
width = byteBuffer.getChar(2);
|
||||
height = byteBuffer.getChar(4);
|
||||
length = byteBuffer.getChar(6);
|
||||
area = width * length;
|
||||
this.volume = length * width * height;
|
||||
|
||||
if (braf.length() - HEADER_SIZE == (volume << 2) + area) {
|
||||
if (braf.length() - HEADER_SIZE == (getVolume() << 1) + getArea()) {
|
||||
hasBiomes = true;
|
||||
}
|
||||
autoCloseTask();
|
||||
@ -107,7 +152,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
hasBiomes = true;
|
||||
close();
|
||||
this.braf = new RandomAccessFile(file, "rw");
|
||||
this.braf.setLength(HEADER_SIZE + (volume << 2) + area);
|
||||
this.braf.setLength(HEADER_SIZE + (getVolume() << 1) + getArea());
|
||||
init();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@ -123,7 +168,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(int x, int z, BiomeType biome) {
|
||||
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||
setBiome(getIndex(x, 0, z), biome);
|
||||
return true;
|
||||
}
|
||||
@ -131,7 +176,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
@Override
|
||||
public void setBiome(int index, BiomeType biome) {
|
||||
if (initBiome()) {
|
||||
byteBuffer.put(HEADER_SIZE + (volume << 2) + index, (byte) biome.getInternalId());
|
||||
byteBuffer.put(HEADER_SIZE + (getVolume() << 1) + index, (byte) biome.getInternalId());
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,7 +185,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
if (!hasBiomes()) {
|
||||
return null;
|
||||
}
|
||||
int biomeId = byteBuffer.get(HEADER_SIZE + (volume << 2) + index) & 0xFF;
|
||||
int biomeId = byteBuffer.get(HEADER_SIZE + (getVolume() << 1) + index) & 0xFF;
|
||||
return BiomeTypes.get(biomeId);
|
||||
}
|
||||
|
||||
@ -148,9 +193,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
public void streamBiomes(NBTStreamer.ByteReader task) {
|
||||
if (!hasBiomes()) return;
|
||||
int index = 0;
|
||||
int mbbIndex = HEADER_SIZE + (volume << 2);
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++, index++, mbbIndex++) {
|
||||
int mbbIndex = HEADER_SIZE + (getVolume() << 1);
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
for (int x = 0; x < getWidth(); x++, index++, mbbIndex++) {
|
||||
int biome = byteBuffer.get(mbbIndex) & 0xFF;
|
||||
task.run(index, biome);
|
||||
}
|
||||
@ -158,18 +203,13 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeType getBiome(int x, int z) {
|
||||
public BiomeType getBiomeType(int x, int z) {
|
||||
return getBiome(getIndex(x, 0, z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockVector3 getDimensions() {
|
||||
return BlockVector3.at(width, height, length);
|
||||
}
|
||||
|
||||
public BlockArrayClipboard toClipboard() {
|
||||
try {
|
||||
CuboidRegion region = new CuboidRegion(BlockVector3.at(0, 0, 0), BlockVector3.at(width - 1, height - 1, length - 1));
|
||||
CuboidRegion region = new CuboidRegion(BlockVector3.at(0, 0, 0), BlockVector3.at(getWidth() - 1, getHeight() - 1, getLength() - 1));
|
||||
int ox = byteBuffer.getShort(8);
|
||||
int oy = byteBuffer.getShort(10);
|
||||
int oz = byteBuffer.getShort(12);
|
||||
@ -182,45 +222,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
return null;
|
||||
}
|
||||
|
||||
public DiskOptimizedClipboard(int width, int height, int length, File file) {
|
||||
try {
|
||||
nbtMap = new HashMap<>();
|
||||
entities = new HashSet<>();
|
||||
this.file = file;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.length = length;
|
||||
this.area = width * length;
|
||||
this.volume = width * length * height;
|
||||
try {
|
||||
if (!file.exists()) {
|
||||
File parent = file.getParentFile();
|
||||
if (parent != null) {
|
||||
file.getParentFile().mkdirs();
|
||||
}
|
||||
file.createNewFile();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
this.braf = new RandomAccessFile(file, "rw");
|
||||
long volume = (long) width * (long) height * (long) length * 4L + (long) HEADER_SIZE;
|
||||
braf.setLength(0);
|
||||
braf.setLength(volume);
|
||||
if (width * height * length != 0) {
|
||||
init();
|
||||
// write length etc
|
||||
byteBuffer.putChar(2, (char) width);
|
||||
byteBuffer.putChar(4, (char) height);
|
||||
byteBuffer.putChar(6, (char) length);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOrigin(BlockVector3 offset) {
|
||||
super.setOrigin(offset);
|
||||
try {
|
||||
byteBuffer.putShort(8, (short) offset.getBlockX());
|
||||
byteBuffer.putShort(10, (short) offset.getBlockY());
|
||||
@ -230,38 +234,11 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDimensions(BlockVector3 dimensions) {
|
||||
try {
|
||||
width = dimensions.getBlockX();
|
||||
height = dimensions.getBlockY();
|
||||
length = dimensions.getBlockZ();
|
||||
area = width * length;
|
||||
volume = width * length * height;
|
||||
long size = width * height * length * 4L + HEADER_SIZE + (hasBiomes() ? area : 0);
|
||||
if (braf.length() < size) {
|
||||
close();
|
||||
this.braf = new RandomAccessFile(file, "rw");
|
||||
braf.setLength(size);
|
||||
init();
|
||||
}
|
||||
byteBuffer.putChar(2, (char) width);
|
||||
byteBuffer.putChar(4, (char) height);
|
||||
byteBuffer.putChar(6, (char) length);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
byteBuffer.force();
|
||||
}
|
||||
|
||||
public DiskOptimizedClipboard(int width, int height, int length) {
|
||||
this(width, height, length, MainUtil.getFile(Fawe.imp() != null ? Fawe.imp().getDirectory() : new File("."), Settings.IMP.PATHS.CLIPBOARD + File.separator + UUID.randomUUID() + ".bd"));
|
||||
}
|
||||
|
||||
private void closeDirectBuffer(ByteBuffer cb) {
|
||||
if (cb == null || !cb.isDirect()) return;
|
||||
// we could use this type cast and call functions without reflection code,
|
||||
@ -287,11 +264,6 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
@ -332,16 +304,16 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
private int zlasti;
|
||||
|
||||
@Override
|
||||
public void streamCombinedIds(NBTStreamer.ByteReader task) {
|
||||
public void streamOrdinals(NBTStreamer.ByteReader task) {
|
||||
try {
|
||||
byteBuffer.force();
|
||||
int pos = HEADER_SIZE;
|
||||
int index = 0;
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++, pos += 4) {
|
||||
int combinedId = byteBuffer.getInt(pos);
|
||||
task.run(index++, combinedId);
|
||||
for (int y = 0; y < getHeight(); y++) {
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
for (int x = 0; x < getWidth(); x++, pos += 2) {
|
||||
char ordinal = byteBuffer.getChar(pos);
|
||||
task.run(index++, ordinal);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -363,13 +335,12 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
final boolean hasTile = !nbtMap.isEmpty();
|
||||
if (air) {
|
||||
if (hasTile) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++, pos += 4) {
|
||||
int combinedId = byteBuffer.getInt(pos);
|
||||
BlockType type = BlockTypes.getFromStateId(combinedId);
|
||||
BlockState state = type.withStateId(combinedId);
|
||||
if (type.getMaterial().hasContainer()) {
|
||||
for (int y = 0; y < getHeight(); y++) {
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
for (int x = 0; x < getWidth(); x++, pos += 2) {
|
||||
int combinedId = byteBuffer.getChar(pos);
|
||||
BlockState state = BlockState.getFromOrdinal(combinedId);
|
||||
if (state.getMaterial().hasContainer()) {
|
||||
trio.set(x, y, z);
|
||||
CompoundTag nbt = nbtMap.get(trio);
|
||||
if (nbt != null) {
|
||||
@ -382,32 +353,29 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++, pos += 4) {
|
||||
int combinedId = byteBuffer.getInt(pos);
|
||||
BlockState state = BlockState.getFromInternalId(combinedId);
|
||||
for (int y = 0; y < getHeight(); y++) {
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
for (int x = 0; x < getWidth(); x++, pos += 2) {
|
||||
int combinedId = byteBuffer.getChar(pos);
|
||||
BlockState state = BlockState.getFromOrdinal(combinedId);
|
||||
task.run(x, y, z, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++, pos += 4) {
|
||||
int combinedId = byteBuffer.getInt(pos);
|
||||
BlockType type = BlockTypes.getFromStateId(combinedId);
|
||||
if (!type.getMaterial().isAir()) {
|
||||
BlockState state = type.withStateId(combinedId);
|
||||
if (type.getMaterial().hasContainer()) {
|
||||
for (int y = 0; y < getHeight(); y++) {
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
for (int x = 0; x < getWidth(); x++, pos += 2) {
|
||||
char combinedId = byteBuffer.getChar(pos);
|
||||
BlockState state = BlockState.getFromOrdinal(combinedId);
|
||||
if (state.getMaterial().hasContainer()) {
|
||||
trio.set(x, y, z);
|
||||
CompoundTag nbt = nbtMap.get(trio);
|
||||
if (nbt != null) {
|
||||
task.run(x, y, z, state.toBaseBlock(nbt));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
task.run(x, y, z, state);
|
||||
}
|
||||
}
|
||||
@ -417,24 +385,21 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
}
|
||||
|
||||
public int getIndex(int x, int y, int z) {
|
||||
return x + (ylast == y ? ylasti : (ylasti = (ylast = y) * area)) + (zlast == z
|
||||
? zlasti : (zlasti = (zlast = z) * width));
|
||||
return x + (ylast == y ? ylasti : (ylasti = (ylast = y) * getArea())) + (zlast == z
|
||||
? zlasti : (zlasti = (zlast = z) * getWidth()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getBlock(int x, int y, int z) {
|
||||
public BaseBlock getFullBlock(int x, int y, int z) {
|
||||
try {
|
||||
int index = HEADER_SIZE + (getIndex(x, y, z) << 2);
|
||||
int combinedId = byteBuffer.getInt(index);
|
||||
BlockType type = BlockTypes.getFromStateId(combinedId);
|
||||
BaseBlock base = type.withStateId(combinedId).toBaseBlock();
|
||||
if (type.getMaterial().hasContainer() && !nbtMap.isEmpty()) {
|
||||
int index = HEADER_SIZE + (getIndex(x, y, z) << 1);
|
||||
int combinedId = byteBuffer.getChar(index);
|
||||
BlockState state = BlockState.getFromOrdinal(combinedId);
|
||||
if (state.getMaterial().hasContainer() && !nbtMap.isEmpty()) {
|
||||
CompoundTag nbt = nbtMap.get(new IntegerTrio(x, y, z));
|
||||
if (nbt != null) {
|
||||
return base.toBaseBlock(nbt);
|
||||
return state.toBaseBlock(nbt);
|
||||
}
|
||||
}
|
||||
return base;
|
||||
return state.toBaseBlock();
|
||||
} catch (IndexOutOfBoundsException ignore) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@ -443,13 +408,12 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getBlock(int i) {
|
||||
public BaseBlock getFullBlock(int i) {
|
||||
try {
|
||||
int diskIndex = HEADER_SIZE + (i << 2);
|
||||
int combinedId = byteBuffer.getInt(diskIndex);
|
||||
BlockType type = BlockTypes.getFromStateId(combinedId);
|
||||
BaseBlock base = type.withStateId(combinedId).toBaseBlock();
|
||||
if (type.getMaterial().hasContainer() && !nbtMap.isEmpty()) {
|
||||
int diskIndex = HEADER_SIZE + (i << 1);
|
||||
char ordinal = byteBuffer.getChar(diskIndex);
|
||||
BlockState state = BlockState.getFromOrdinal(ordinal);
|
||||
if (state.getMaterial().hasContainer() && !nbtMap.isEmpty()) {
|
||||
CompoundTag nbt;
|
||||
if (nbtMap.size() < 4) {
|
||||
nbt = null;
|
||||
@ -462,18 +426,18 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// x + z * width + y * area;
|
||||
int y = i / area;
|
||||
int newI = i - y * area;
|
||||
int z = newI / width;
|
||||
int x = newI - z * width;
|
||||
// x + z * getWidth() + y * area;
|
||||
int y = i / getArea();
|
||||
int newI = i - y * getArea();
|
||||
int z = newI / getWidth();
|
||||
int x = newI - z * getWidth();
|
||||
nbt = nbtMap.get(new IntegerTrio(x, y, z));
|
||||
}
|
||||
if (nbt != null) {
|
||||
return base.toBaseBlock(nbt);
|
||||
return state.toBaseBlock(nbt);
|
||||
}
|
||||
}
|
||||
return base;
|
||||
return state.toBaseBlock();
|
||||
} catch (IndexOutOfBoundsException ignore) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@ -494,9 +458,9 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(int x, int y, int z, B block) {
|
||||
try {
|
||||
int index = HEADER_SIZE + (getIndex(x, y, z) << 2);
|
||||
int combined = block.getInternalId();
|
||||
byteBuffer.putInt(index, combined);
|
||||
int index = HEADER_SIZE + (getIndex(x, y, z) << 1);
|
||||
char ordinal = block.getOrdinalChar();
|
||||
byteBuffer.putChar(index, ordinal);
|
||||
boolean hasNbt = block instanceof BaseBlock && block.hasNbtData();
|
||||
if (hasNbt) {
|
||||
setTile(x, y, z, block.getNbtData());
|
||||
@ -511,15 +475,15 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(int i, B block) {
|
||||
try {
|
||||
int combined = block.getInternalId();
|
||||
int index = HEADER_SIZE + (i << 2);
|
||||
byteBuffer.putInt(index, combined);
|
||||
char ordinal = block.getOrdinalChar();
|
||||
int index = HEADER_SIZE + (i << 1);
|
||||
byteBuffer.putChar(index, ordinal);
|
||||
boolean hasNbt = block instanceof BaseBlock && block.hasNbtData();
|
||||
if (hasNbt) {
|
||||
int y = i / area;
|
||||
int newI = i - y * area;
|
||||
int z = newI / width;
|
||||
int x = newI - z * width;
|
||||
int y = i / getArea();
|
||||
int newI = i - y * getArea();
|
||||
int z = newI / getWidth();
|
||||
int x = newI - z * getWidth();
|
||||
setTile(x, y, z, block.getNbtData());
|
||||
}
|
||||
return true;
|
||||
@ -529,9 +493,10 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Entity createEntity(Extent world, double x, double y, double z, float yaw, float pitch, BaseEntity entity) {
|
||||
FaweClipboard.ClipboardEntity ret = new ClipboardEntity(world, x, y, z, yaw, pitch, entity);
|
||||
public Entity createEntity(Location location, BaseEntity entity) {
|
||||
BlockArrayClipboard.ClipboardEntity ret = new BlockArrayClipboard.ClipboardEntity(location, entity);
|
||||
entities.add(ret);
|
||||
return ret;
|
||||
}
|
||||
@ -542,7 +507,21 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(ClipboardEntity clipboardEntity) {
|
||||
return entities.remove(clipboardEntity);
|
||||
public void removeEntity(Entity entity) {
|
||||
this.entities.remove(entity);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public void removeEntity(int x, int y, int z, UUID uuid) {
|
||||
Iterator<BlockArrayClipboard.ClipboardEntity> iter = this.entities.iterator();
|
||||
while (iter.hasNext()) {
|
||||
BlockArrayClipboard.ClipboardEntity entity = iter.next();
|
||||
UUID entUUID = entity.getState().getNbtData().getUUID();
|
||||
if (uuid.equals(entUUID)) {
|
||||
iter.remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -11,7 +11,9 @@ import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
@ -21,22 +23,21 @@ import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import net.jpountz.util.SafeUtils;
|
||||
|
||||
public class MemoryOptimizedClipboard extends FaweClipboard {
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
private static final int BLOCK_SIZE = 1048576 * 4;
|
||||
public class MemoryOptimizedClipboard extends LinearClipboard {
|
||||
|
||||
private static final int BLOCK_SIZE = 1048576 * 2;
|
||||
private static final int BLOCK_MASK = 1048575;
|
||||
private static final int BLOCK_SHIFT = 20;
|
||||
|
||||
private int length;
|
||||
private int height;
|
||||
private int width;
|
||||
private int area;
|
||||
private int volume;
|
||||
|
||||
private byte[][] states;
|
||||
|
||||
private byte[] buffer = new byte[MainUtil.getMaxCompressedLength(BLOCK_SIZE)];
|
||||
@ -45,7 +46,7 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
|
||||
private final HashMap<IntegerTrio, CompoundTag> nbtMapLoc;
|
||||
private final HashMap<Integer, CompoundTag> nbtMapIndex;
|
||||
|
||||
private final HashSet<ClipboardEntity> entities;
|
||||
private final HashSet<BlockArrayClipboard.ClipboardEntity> entities;
|
||||
|
||||
private int lastCombinedIdsI = -1;
|
||||
|
||||
@ -55,17 +56,13 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
|
||||
|
||||
private int compressionLevel;
|
||||
|
||||
public MemoryOptimizedClipboard(int width, int height, int length) {
|
||||
this(width, height, length, Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL);
|
||||
public MemoryOptimizedClipboard(BlockVector3 dimensions) {
|
||||
this(dimensions, Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL);
|
||||
}
|
||||
|
||||
public MemoryOptimizedClipboard(int width, int height, int length, int compressionLevel) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.length = length;
|
||||
this.area = width * length;
|
||||
this.volume = area * height;
|
||||
states = new byte[1 + (volume >> BLOCK_SHIFT)][];
|
||||
public MemoryOptimizedClipboard(BlockVector3 dimensions, int compressionLevel) {
|
||||
super(dimensions);
|
||||
states = new byte[1 + (getVolume() >> BLOCK_SHIFT)][];
|
||||
nbtMapLoc = new HashMap<>();
|
||||
nbtMapIndex = new HashMap<>();
|
||||
entities = new HashSet<>();
|
||||
@ -89,7 +86,7 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(int x, int z, BiomeType biome) {
|
||||
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||
setBiome(getIndex(x, 0, z), biome);
|
||||
return true;
|
||||
}
|
||||
@ -97,7 +94,7 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
|
||||
@Override
|
||||
public void setBiome(int index, BiomeType biome) {
|
||||
if (biomes == null) {
|
||||
biomes = new byte[area];
|
||||
biomes = new byte[getArea()];
|
||||
}
|
||||
biomes[index] = (byte) biome.getInternalId();
|
||||
}
|
||||
@ -106,8 +103,8 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
|
||||
public void streamBiomes(NBTStreamer.ByteReader task) {
|
||||
if (!hasBiomes()) return;
|
||||
int index = 0;
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++, index++) {
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
for (int x = 0; x < getWidth(); x++, index++) {
|
||||
task.run(index, biomes[index] & 0xFF);
|
||||
}
|
||||
}
|
||||
@ -122,7 +119,7 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeType getBiome(int x, int z) {
|
||||
public BiomeType getBiomeType(int x, int z) {
|
||||
return getBiome(getIndex(x, 0, z));
|
||||
}
|
||||
|
||||
@ -131,22 +128,24 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
|
||||
return nbtMapIndex.get(index);
|
||||
}
|
||||
|
||||
public int getCombinedId(int index) {
|
||||
public int getOrdinal(int index) {
|
||||
int i = index >> BLOCK_SHIFT;
|
||||
if (i == lastCombinedIdsI) {
|
||||
int li = (index & BLOCK_MASK) << 1;
|
||||
if (i != lastCombinedIdsI) {
|
||||
saveCombinedIds();
|
||||
byte[] compressed = states[lastCombinedIdsI = i];
|
||||
if (compressed != null) {
|
||||
lastCombinedIds = MainUtil.decompress(compressed, lastCombinedIds, BLOCK_SIZE, compressionLevel);
|
||||
} else {
|
||||
lastCombinedIds = null;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (lastCombinedIds == null) {
|
||||
return 0;
|
||||
}
|
||||
return lastCombinedIds[index & BLOCK_MASK] & 0xFF;
|
||||
}
|
||||
saveCombinedIds();
|
||||
byte[] compressed = states[lastCombinedIdsI = i];
|
||||
if (compressed == null) {
|
||||
lastCombinedIds = null;
|
||||
return BlockTypes.AIR.getInternalId();
|
||||
}
|
||||
lastCombinedIds = MainUtil.decompress(compressed, lastCombinedIds, BLOCK_SIZE, compressionLevel);
|
||||
return SafeUtils.readIntBE(lastCombinedIds, index & BLOCK_MASK);
|
||||
int ordinal = ((lastCombinedIds[li] << 8) + lastCombinedIds[li + 1]);
|
||||
return ordinal;
|
||||
}
|
||||
|
||||
private void saveCombinedIds() {
|
||||
@ -156,26 +155,6 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
|
||||
saveCombinedIds = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDimensions(BlockVector3 dimensions) {
|
||||
width = dimensions.getBlockX();
|
||||
height = dimensions.getBlockY();
|
||||
length = dimensions.getBlockZ();
|
||||
area = width * length;
|
||||
int newVolume = area * height;
|
||||
if (newVolume != volume) {
|
||||
volume = newVolume;
|
||||
states = new byte[1 + (volume >> BLOCK_SHIFT)][];
|
||||
lastCombinedIdsI = -1;
|
||||
saveCombinedIds = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockVector3 getDimensions() {
|
||||
return BlockVector3.at(width, height, length);
|
||||
}
|
||||
|
||||
private int lastI;
|
||||
private int lastIMin;
|
||||
private int lastIMax;
|
||||
@ -207,22 +186,20 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
|
||||
}
|
||||
lastCombinedIds = new byte[BLOCK_SIZE];
|
||||
}
|
||||
int li = (index & BLOCK_MASK) << 2;
|
||||
lastCombinedIds[li] = (byte) ((v >>> 24) & 0xFF);
|
||||
lastCombinedIds[li + 1] = (byte) ((v >>> 16) & 0xFF);
|
||||
lastCombinedIds[li + 2] = (byte) ((v >>> 8) & 0xFF);
|
||||
lastCombinedIds[li + 3] = (byte) ((v >>> 0) & 0xFF);
|
||||
int li = (index & BLOCK_MASK) << 1;
|
||||
lastCombinedIds[li] = (byte) ((v >>> 8) & 0xFF);
|
||||
lastCombinedIds[li + 1] = (byte) (v & 0xFF);
|
||||
saveCombinedIds = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void streamCombinedIds(NBTStreamer.ByteReader task) {
|
||||
public void streamOrdinals(NBTStreamer.ByteReader task) {
|
||||
int index = 0;
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
int id = getCombinedId(index);
|
||||
task.run(index++, id);
|
||||
for (int y = 0; y < getHeight(); y++) {
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
for (int x = 0; x < getWidth(); x++, index++) {
|
||||
int id = getOrdinal(index);
|
||||
task.run(index, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -236,10 +213,10 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
|
||||
CompoundTag tag = entry.getValue();
|
||||
Map<String, Tag> values = ReflectionUtils.getMap(tag.getValue());
|
||||
if (!values.containsKey("x")) {
|
||||
int y = index / area;
|
||||
index -= y * area;
|
||||
int z = index / width;
|
||||
int x = index - (z * width);
|
||||
int y = index / getArea();
|
||||
index -= y * getArea();
|
||||
int z = index / getWidth();
|
||||
int x = index - (z * getWidth());
|
||||
values.put("x", new IntTag(x));
|
||||
values.put("y", new IntTag(y));
|
||||
values.put("z", new IntTag(z));
|
||||
@ -254,18 +231,18 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
|
||||
private int zlasti;
|
||||
|
||||
public int getIndex(int x, int y, int z) {
|
||||
return x + ((ylast == y) ? ylasti : (ylasti = (ylast = y) * area)) + ((zlast == z) ? zlasti : (zlasti = (zlast = z) * width));
|
||||
return x + ((ylast == y) ? ylasti : (ylasti = (ylast = y) * getArea())) + ((zlast == z) ? zlasti : (zlasti = (zlast = z) * getWidth()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getBlock(int x, int y, int z) {
|
||||
public BaseBlock getFullBlock(int x, int y, int z) {
|
||||
int index = getIndex(x, y, z);
|
||||
return getBlock(index);
|
||||
return getFullBlock(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getBlock(int index) {
|
||||
int combinedId = getCombinedId(index);
|
||||
public BaseBlock getFullBlock(int index) {
|
||||
int combinedId = getOrdinal(index);
|
||||
BlockType type = BlockTypes.getFromStateId(combinedId);
|
||||
BaseBlock base = type.withStateId(combinedId).toBaseBlock();
|
||||
if (type.getMaterial().hasContainer()) {
|
||||
@ -280,19 +257,19 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
|
||||
@Override
|
||||
public void forEach(final BlockReader task, final boolean air) {
|
||||
if (air) {
|
||||
for (int y = 0, index = 0; y < height; y++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++, index++) {
|
||||
BaseBlock block = getBlock(index);
|
||||
for (int y = 0, index = 0; y < getHeight(); y++) {
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
for (int x = 0; x < getWidth(); x++, index++) {
|
||||
BaseBlock block = getFullBlock(index);
|
||||
task.run(x, y, z, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int y = 0, index = 0; y < height; y++) {
|
||||
for (int z = 0; z < length; z++) {
|
||||
for (int x = 0; x < width; x++, index++) {
|
||||
BaseBlock block = getBlock(index);
|
||||
for (int y = 0, index = 0; y < getHeight(); y++) {
|
||||
for (int z = 0; z < getLength(); z++) {
|
||||
for (int x = 0; x < getWidth(); x++, index++) {
|
||||
BaseBlock block = getFullBlock(index);
|
||||
if (!block.getMaterial().isAir()) {
|
||||
task.run(x, y, z, block);
|
||||
}
|
||||
@ -344,9 +321,10 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Entity createEntity(Extent world, double x, double y, double z, float yaw, float pitch, BaseEntity entity) {
|
||||
FaweClipboard.ClipboardEntity ret = new ClipboardEntity(world, x, y, z, yaw, pitch, entity);
|
||||
public Entity createEntity(Location location, BaseEntity entity) {
|
||||
BlockArrayClipboard.ClipboardEntity ret = new BlockArrayClipboard.ClipboardEntity(location, entity);
|
||||
entities.add(ret);
|
||||
return ret;
|
||||
}
|
||||
@ -357,7 +335,21 @@ public class MemoryOptimizedClipboard extends FaweClipboard {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(ClipboardEntity clipboardEntity) {
|
||||
return entities.remove(clipboardEntity);
|
||||
public void removeEntity(Entity entity) {
|
||||
this.entities.remove(entity);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public void removeEntity(int x, int y, int z, UUID uuid) {
|
||||
Iterator<BlockArrayClipboard.ClipboardEntity> iter = this.entities.iterator();
|
||||
while (iter.hasNext()) {
|
||||
BlockArrayClipboard.ClipboardEntity entity = iter.next();
|
||||
UUID entUUID = entity.getState().getNbtData().getUUID();
|
||||
if (uuid.equals(entUUID)) {
|
||||
iter.remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ public class MultiClipboardHolder extends URIClipboardHolder {
|
||||
holders = new ArrayList<>();
|
||||
URI uri = URI.create("");
|
||||
if (clipboard instanceof BlockArrayClipboard) {
|
||||
FaweClipboard fc = ((BlockArrayClipboard) clipboard).IMP;
|
||||
LinearClipboard fc = ((BlockArrayClipboard) clipboard).IMP;
|
||||
if (fc instanceof DiskOptimizedClipboard) {
|
||||
uri = ((DiskOptimizedClipboard) fc).getFile().toURI();
|
||||
}
|
||||
|
@ -1,22 +1,25 @@
|
||||
package com.boydti.fawe.object.clipboard;
|
||||
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
|
||||
public class OffsetFaweClipboard extends AbstractDelegateFaweClipboard {
|
||||
public class OffsetClipboard extends DelegateClipboard {
|
||||
private final int ox, oy, oz;
|
||||
|
||||
public OffsetFaweClipboard(FaweClipboard parent, int ox, int oy, int oz) {
|
||||
public OffsetClipboard(Clipboard parent, int ox, int oy, int oz) {
|
||||
super(parent);
|
||||
this.ox = ox;
|
||||
this.oy = oy;
|
||||
this.oz = oz;
|
||||
}
|
||||
|
||||
public OffsetFaweClipboard(FaweClipboard parent, int offset) {
|
||||
this(parent, offset, offset, offset);
|
||||
@Override
|
||||
public Region getRegion() {
|
||||
return parent.getRegion();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -12,7 +12,7 @@ import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class ReadOnlyClipboard extends FaweClipboard {
|
||||
public abstract class ReadOnlyClipboard extends LinearClipboard {
|
||||
public final Region region;
|
||||
|
||||
public ReadOnlyClipboard(Region region) {
|
||||
|
@ -2,7 +2,7 @@ package com.boydti.fawe.object.schematic;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.boydti.fawe.object.clipboard.FaweClipboard;
|
||||
import com.boydti.fawe.object.clipboard.LinearClipboard;
|
||||
import com.boydti.fawe.object.clipboard.ReadOnlyClipboard;
|
||||
import com.boydti.fawe.util.EditSessionBuilder;
|
||||
import com.boydti.fawe.util.MaskTraverser;
|
||||
@ -213,7 +213,7 @@ public class Schematic {
|
||||
|
||||
BlockArrayClipboard bac = (BlockArrayClipboard) clipboard;
|
||||
if (copyBiomes) {
|
||||
bac.IMP.forEach(new FaweClipboard.BlockReader() {
|
||||
bac.IMP.forEach(new LinearClipboard.BlockReader() {
|
||||
MutableBlockVector2 mpos2d = new MutableBlockVector2();
|
||||
|
||||
{
|
||||
@ -239,7 +239,7 @@ public class Schematic {
|
||||
}
|
||||
}, true);
|
||||
} else {
|
||||
bac.IMP.forEach(new FaweClipboard.BlockReader() {
|
||||
bac.IMP.forEach(new LinearClipboard.BlockReader() {
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> void run(int x, int y, int z, B block) {
|
||||
try {
|
||||
|
@ -211,7 +211,6 @@ public class ToolUtilCommands {
|
||||
BBC.SUPERPICKAXE_DISABLED.send(player);
|
||||
} else {
|
||||
if ("off".equals(state)) {
|
||||
|
||||
BBC.SUPERPICKAXE_DISABLED.send(player);
|
||||
return;
|
||||
}
|
||||
|
@ -22,14 +22,15 @@ package com.sk89q.worldedit.extent.clipboard;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.clipboard.DelegateClipboard;
|
||||
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
||||
import com.boydti.fawe.object.clipboard.FaweClipboard;
|
||||
import com.boydti.fawe.object.clipboard.FaweClipboard.ClipboardEntity;
|
||||
import com.boydti.fawe.object.clipboard.LinearClipboard;
|
||||
import com.boydti.fawe.object.clipboard.MemoryOptimizedClipboard;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.operation.Operation;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
@ -40,7 +41,10 @@ import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import jdk.vm.ci.meta.Local;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@ -51,26 +55,13 @@ import javax.annotation.Nullable;
|
||||
* Stores block data as a multi-dimensional array of {@link BlockState}s and
|
||||
* other data as lists or maps.
|
||||
*/
|
||||
public class BlockArrayClipboard implements Clipboard, Closeable {
|
||||
public class BlockArrayClipboard extends DelegateClipboard implements Clipboard, Closeable {
|
||||
|
||||
private Region region;
|
||||
private BlockVector3 origin;
|
||||
public FaweClipboard IMP;
|
||||
private BlockVector3 size;
|
||||
private int mx;
|
||||
private int my;
|
||||
private int mz;
|
||||
private final List<ClipboardEntity> entities = new ArrayList<>();
|
||||
|
||||
public BlockArrayClipboard(Region region) {
|
||||
checkNotNull(region);
|
||||
this.region = region.clone();
|
||||
this.size = getDimensions();
|
||||
this.IMP = Settings.IMP.CLIPBOARD.USE_DISK ? new DiskOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ()) : new MemoryOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ());
|
||||
this.origin = region.getMinimumPoint();
|
||||
this.mx = origin.getBlockX();
|
||||
this.my = origin.getBlockY();
|
||||
this.mz = origin.getBlockZ();
|
||||
this(region, UUID.randomUUID());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -81,48 +72,24 @@ public class BlockArrayClipboard implements Clipboard, Closeable {
|
||||
* @param region the bounding region
|
||||
*/
|
||||
public BlockArrayClipboard(Region region, UUID clipboardId) {
|
||||
this(region, Clipboard.create(region.getDimensions(), clipboardId));
|
||||
checkNotNull(region);
|
||||
this.region = region.clone();
|
||||
this.size = getDimensions();
|
||||
this.IMP = Settings.IMP.CLIPBOARD.USE_DISK ? new DiskOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ(), clipboardId) : new MemoryOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ());
|
||||
this.origin = region.getMinimumPoint();
|
||||
this.mx = origin.getBlockX();
|
||||
this.my = origin.getBlockY();
|
||||
this.mz = origin.getBlockZ();
|
||||
}
|
||||
|
||||
public BlockArrayClipboard(Region region, FaweClipboard clipboard) {
|
||||
public BlockArrayClipboard(Region region, Clipboard clipboard) {
|
||||
super(clipboard);
|
||||
checkNotNull(region);
|
||||
this.region = region.clone();
|
||||
this.size = getDimensions();
|
||||
this.origin = region.getMinimumPoint();
|
||||
this.IMP = clipboard;
|
||||
this.mx = origin.getBlockX();
|
||||
this.my = origin.getBlockY();
|
||||
this.mz = origin.getBlockZ();
|
||||
}
|
||||
|
||||
public void init(Region region, FaweClipboard fc) {
|
||||
checkNotNull(region);
|
||||
checkNotNull(fc);
|
||||
this.region = region.clone();
|
||||
this.size = getDimensions();
|
||||
this.IMP = fc;
|
||||
this.origin = region.getMinimumPoint();
|
||||
this.mx = origin.getBlockX();
|
||||
this.my = origin.getBlockY();
|
||||
this.mz = origin.getBlockZ();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() {
|
||||
close();
|
||||
public void close() throws IOException {
|
||||
if (getParent() instanceof Closeable) {
|
||||
((Closeable) getParent()).close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
IMP.close();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -142,12 +109,7 @@ public class BlockArrayClipboard implements Clipboard, Closeable {
|
||||
@Override
|
||||
public void setOrigin(BlockVector3 origin) {
|
||||
this.origin = origin;
|
||||
IMP.setOrigin(origin.subtract(region.getMinimumPoint()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockVector3 getDimensions() {
|
||||
return region.getMaximumPoint().subtract(region.getMinimumPoint()).add(1, 1, 1);
|
||||
getParent().setOrigin(origin.subtract(region.getMinimumPoint()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -160,35 +122,13 @@ public class BlockArrayClipboard implements Clipboard, Closeable {
|
||||
return region.getMaximumPoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Entity> getEntities(Region region) {
|
||||
List<Entity> filtered = new ArrayList<>();
|
||||
for (Entity entity : getEntities()) {
|
||||
if (region.contains(entity.getLocation().toVector().toBlockPoint())) {
|
||||
filtered.add(entity);
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableList(filtered);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Entity> getEntities() {
|
||||
return IMP.getEntities();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Entity createEntity(Location location, BaseEntity entity) {
|
||||
return IMP.createEntity(location.getExtent(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch(), entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlock(BlockVector3 position) {
|
||||
if (region.contains(position)) {
|
||||
int x = position.getBlockX() - mx;
|
||||
int y = position.getBlockY() - my;
|
||||
int z = position.getBlockZ() - mz;
|
||||
return IMP.getBlock(x, y, z).toImmutableState();
|
||||
int x = position.getBlockX()- origin.getX();
|
||||
int y = position.getBlockY()- origin.getY();
|
||||
int z = position.getBlockZ()- origin.getZ();
|
||||
return getParent().getBlock(x, y, z);
|
||||
}
|
||||
|
||||
return BlockTypes.AIR.getDefaultState();
|
||||
@ -197,10 +137,10 @@ public class BlockArrayClipboard implements Clipboard, Closeable {
|
||||
@Override
|
||||
public BaseBlock getFullBlock(BlockVector3 position) {
|
||||
if(region.contains(position)) {
|
||||
int x = position.getBlockX() - mx;
|
||||
int y = position.getBlockY() - my;
|
||||
int z = position.getBlockZ() - mz;
|
||||
return IMP.getBlock(x, y, z);
|
||||
int x = position.getBlockX()- origin.getX();
|
||||
int y = position.getBlockY()- origin.getY();
|
||||
int z = position.getBlockZ()- origin.getZ();
|
||||
return getParent().getFullBlock(x, y, z);
|
||||
}
|
||||
return BlockTypes.AIR.getDefaultState().toBaseBlock();
|
||||
}
|
||||
@ -218,10 +158,10 @@ public class BlockArrayClipboard implements Clipboard, Closeable {
|
||||
|
||||
@Override
|
||||
public boolean setTile(int x, int y, int z, CompoundTag tag) {
|
||||
x -= mx;
|
||||
y -= my;
|
||||
z -= mz;
|
||||
return IMP.setTile(x, y, z, tag);
|
||||
x -= origin.getX();
|
||||
y -= origin.getY();
|
||||
z -= origin.getZ();
|
||||
return getParent().setTile(x, y, z, tag);
|
||||
}
|
||||
|
||||
public boolean setTile(BlockVector3 position, CompoundTag tag) {
|
||||
@ -230,38 +170,133 @@ public class BlockArrayClipboard implements Clipboard, Closeable {
|
||||
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(int x, int y, int z, B block) throws WorldEditException {
|
||||
x -= mx;
|
||||
y -= my;
|
||||
z -= mz;
|
||||
return IMP.setBlock(x, y, z, block);
|
||||
x -= origin.getX();
|
||||
y -= origin.getY();
|
||||
z -= origin.getZ();
|
||||
return getParent().setBlock(x, y, z, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBiomes() {
|
||||
return IMP.hasBiomes();
|
||||
return getParent().hasBiomes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeType getBiome(BlockVector2 position) {
|
||||
BlockVector2 v = position.subtract(region.getMinimumPoint().toBlockVector2());
|
||||
return IMP.getBiome(v.getX(), v.getZ());
|
||||
return getParent().getBiomeType(v.getX(), v.getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(BlockVector2 position, BiomeType biome) {
|
||||
int x = position.getBlockX() - mx;
|
||||
int z = position.getBlockZ() - mz;
|
||||
return IMP.setBiome(x, z, biome);
|
||||
int x = position.getBlockX()- origin.getX();
|
||||
int z = position.getBlockZ()- origin.getZ();
|
||||
return getParent().setBiome(x, 0, z, biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||
return IMP.setBiome(x, z, biome);
|
||||
return parent.setBiome(x, y, z, biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Entity> getEntities(Region region) {
|
||||
return parent.getEntities(region);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Entity createEntity(Location location, BaseEntity entity) {
|
||||
return parent.createEntity(location, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public void removeEntity(int x, int y, int z, UUID uuid) {
|
||||
parent.removeEntity(x, y, z, uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlock(int x, int y, int z) {
|
||||
return parent.getBlock(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getFullBlock(int x, int y, int z) {
|
||||
return parent.getFullBlock(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeType getBiomeType(int x, int z) {
|
||||
return parent.getBiomeType(x, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores entity data.
|
||||
*/
|
||||
public static class ClipboardEntity implements Entity {
|
||||
private final BaseEntity entity;
|
||||
private final Clipboard clipboard;
|
||||
private final double x, y, z;
|
||||
private final float yaw, pitch;
|
||||
|
||||
public ClipboardEntity(Location loc, BaseEntity entity) {
|
||||
this((Clipboard) loc.getExtent(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), loc.getYaw(), loc.getPitch(), entity);
|
||||
}
|
||||
|
||||
public ClipboardEntity(Clipboard clipboard, double x, double y, double z, float yaw, float pitch, BaseEntity entity) {
|
||||
checkNotNull(entity);
|
||||
checkNotNull(clipboard);
|
||||
this.clipboard = clipboard;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.yaw = yaw;
|
||||
this.pitch = pitch;
|
||||
this.entity = new BaseEntity(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove() {
|
||||
clipboard.removeEntity(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Operation commit() {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,15 +19,33 @@
|
||||
|
||||
package com.sk89q.worldedit.extent.clipboard;
|
||||
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.clipboard.CPUOptimizedClipboard;
|
||||
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
||||
import com.boydti.fawe.object.clipboard.MemoryOptimizedClipboard;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Specifies an object that implements something suitable as a "clipboard."
|
||||
*/
|
||||
public interface Clipboard extends Extent {
|
||||
static Clipboard create(BlockVector3 size, UUID uuid) {
|
||||
if (Settings.IMP.CLIPBOARD.USE_DISK) {
|
||||
return new DiskOptimizedClipboard(size, uuid);
|
||||
} else if (Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL == 0) {
|
||||
return new CPUOptimizedClipboard(size);
|
||||
} else {
|
||||
return new MemoryOptimizedClipboard(size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bounding region of this extent.
|
||||
@ -70,4 +88,10 @@ public interface Clipboard extends Extent {
|
||||
default boolean hasBiomes() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove entity from clipboard
|
||||
* @param entity
|
||||
*/
|
||||
void removeEntity(Entity entity);
|
||||
}
|
||||
|
@ -19,11 +19,16 @@
|
||||
|
||||
package com.sk89q.worldedit.extent.clipboard.io;
|
||||
|
||||
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Reads {@code Clipboard}s.
|
||||
@ -38,9 +43,20 @@ public interface ClipboardReader extends Closeable {
|
||||
* @return the read clipboard
|
||||
* @throws IOException thrown on I/O error
|
||||
*/
|
||||
Clipboard read() throws IOException;
|
||||
default Clipboard read() throws IOException {
|
||||
return read(UUID.randomUUID());
|
||||
}
|
||||
|
||||
default Clipboard read(UUID uuid) throws IOException {
|
||||
return read(uuid, new Function<BlockVector3, Clipboard>() {
|
||||
@Override
|
||||
public Clipboard apply(BlockVector3 dimensions) {
|
||||
return new DiskOptimizedClipboard(dimensions);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
default Clipboard read(UUID uuid, Function<BlockVector3, Clipboard> createOutput) throws IOException {
|
||||
return read();
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ import com.boydti.fawe.object.FaweInputStream;
|
||||
import com.boydti.fawe.object.FaweOutputStream;
|
||||
import com.boydti.fawe.object.clipboard.CPUOptimizedClipboard;
|
||||
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
||||
import com.boydti.fawe.object.clipboard.FaweClipboard;
|
||||
import com.boydti.fawe.object.clipboard.LinearClipboard;
|
||||
import com.boydti.fawe.object.clipboard.MemoryOptimizedClipboard;
|
||||
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
|
||||
import com.boydti.fawe.object.io.FastByteArraysInputStream;
|
||||
@ -48,7 +48,6 @@ import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.DataFixer;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||
@ -56,14 +55,15 @@ import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.entity.EntityType;
|
||||
import com.sk89q.worldedit.world.entity.EntityTypes;
|
||||
import com.sk89q.worldedit.world.storage.NBTConversions;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||
import net.jpountz.lz4.LZ4BlockOutputStream;
|
||||
import org.slf4j.Logger;
|
||||
@ -99,13 +99,18 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
return reader(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Clipboard read(UUID uuid, Function<BlockVector3, Clipboard> createOutput) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private int width, height, length;
|
||||
private int offsetX, offsetY, offsetZ;
|
||||
private char[] palette;
|
||||
private BlockVector3 min;
|
||||
private FaweClipboard fc;
|
||||
private LinearClipboard fc;
|
||||
|
||||
private FaweClipboard setupClipboard(int size, UUID uuid) {
|
||||
private LinearClipboard setupClipboard(int size, UUID uuid) {
|
||||
if (fc != null) {
|
||||
if (fc.getDimensions().getX() == 0) {
|
||||
fc.setDimensions(BlockVector3.at(size, 1, 1));
|
||||
@ -113,11 +118,11 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
||||
return fc;
|
||||
}
|
||||
if (Settings.IMP.CLIPBOARD.USE_DISK) {
|
||||
return fc = new DiskOptimizedClipboard(size, 1, 1, uuid);
|
||||
return fc = new DiskOptimizedClipboard(BlockVector3.at(size, 1, 1), uuid);
|
||||
} else if (Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL == 0) {
|
||||
return fc = new CPUOptimizedClipboard(size, 1, 1);
|
||||
return fc = new CPUOptimizedClipboard(BlockVector3.at(size, 1, 1));
|
||||
} else {
|
||||
return fc = new MemoryOptimizedClipboard(size, 1, 1);
|
||||
return fc = new MemoryOptimizedClipboard(BlockVector3.at(size, 1, 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ package com.sk89q.worldedit.extent.clipboard.io;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.boydti.fawe.jnbt.NBTStreamer;
|
||||
import com.boydti.fawe.object.clipboard.FaweClipboard;
|
||||
import com.boydti.fawe.object.clipboard.LinearClipboard;
|
||||
import com.boydti.fawe.util.IOUtil;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
@ -146,7 +146,7 @@ public class SpongeSchematicWriter implements ClipboardWriter {
|
||||
|
||||
|
||||
int[] numTiles = {0};
|
||||
FaweClipboard.BlockReader reader = new FaweClipboard.BlockReader() {
|
||||
LinearClipboard.BlockReader reader = new LinearClipboard.BlockReader() {
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> void run(int x, int y, int z, B block) {
|
||||
try {
|
||||
|
@ -60,6 +60,10 @@ public interface Region extends Iterable<BlockVector3>, Cloneable, IBatchProcess
|
||||
*/
|
||||
BlockVector3 getMaximumPoint();
|
||||
|
||||
default BlockVector3 getDimensions() {
|
||||
return getMaximumPoint().subtract(getMinimumPoint()).add(1, 1, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the center point of a region.
|
||||
* Note: Coordinates will not be integers
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren