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