Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-12-26 02:50:06 +01:00
Started refactoring Clipboards
Dieser Commit ist enthalten in:
Ursprung
fb45fd51fb
Commit
0bf0848758
@ -1,312 +0,0 @@
|
|||||||
package com.boydti.fawe.jnbt;
|
|
||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
|
||||||
import com.boydti.fawe.config.Settings;
|
|
||||||
import com.boydti.fawe.object.clipboard.CPUOptimizedClipboard;
|
|
||||||
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
|
||||||
import com.boydti.fawe.object.clipboard.LinearClipboard;
|
|
||||||
import com.boydti.fawe.object.clipboard.MemoryOptimizedClipboard;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
public class CorruptSchematicStreamer {
|
|
||||||
|
|
||||||
private final Logger log = LoggerFactory.getLogger(CorruptSchematicStreamer.class);
|
|
||||||
private final InputStream stream;
|
|
||||||
private final UUID uuid;
|
|
||||||
private LinearClipboard fc;
|
|
||||||
final AtomicInteger volume = new AtomicInteger();
|
|
||||||
final AtomicInteger width = new AtomicInteger();
|
|
||||||
final AtomicInteger height = new AtomicInteger();
|
|
||||||
final AtomicInteger length = new AtomicInteger();
|
|
||||||
final AtomicInteger offsetX = new AtomicInteger();
|
|
||||||
final AtomicInteger offsetY = new AtomicInteger();
|
|
||||||
final AtomicInteger offsetZ = new AtomicInteger();
|
|
||||||
final AtomicInteger originX = new AtomicInteger();
|
|
||||||
final AtomicInteger originY = new AtomicInteger();
|
|
||||||
final AtomicInteger originZ = new AtomicInteger();
|
|
||||||
|
|
||||||
public CorruptSchematicStreamer(InputStream rootStream, UUID uuid) {
|
|
||||||
this.stream = rootStream;
|
|
||||||
this.uuid = uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void match(String matchTag, CorruptReader reader) {
|
|
||||||
try {
|
|
||||||
stream.reset();
|
|
||||||
stream.mark(Integer.MAX_VALUE);
|
|
||||||
DataInputStream dataInput = new DataInputStream(new BufferedInputStream(new GZIPInputStream(stream)));
|
|
||||||
byte[] match = matchTag.getBytes();
|
|
||||||
int[] matchValue = new int[match.length];
|
|
||||||
int matchIndex = 0;
|
|
||||||
int read;
|
|
||||||
while ((read = dataInput.read()) != -1) {
|
|
||||||
int expected = match[matchIndex];
|
|
||||||
if (expected == -1) {
|
|
||||||
if (++matchIndex == match.length) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (read == expected) {
|
|
||||||
if (++matchIndex == match.length) {
|
|
||||||
reader.run(dataInput);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (matchIndex == 2)
|
|
||||||
matchIndex = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.debug(" - Recover " + matchTag + " = success");
|
|
||||||
} catch (Throwable e) {
|
|
||||||
log.error(" - Recover " + matchTag + " = partial failure", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public LinearClipboard setupClipboard() {
|
|
||||||
if (fc != null) {
|
|
||||||
return fc;
|
|
||||||
}
|
|
||||||
BlockVector3 dimensions = guessDimensions(volume.get(), width.get(), height.get(), length.get());
|
|
||||||
if (width.get() == 0 || height.get() == 0 || length.get() == 0) {
|
|
||||||
log.debug("No dimensions found! Estimating based on factors:" + dimensions);
|
|
||||||
}
|
|
||||||
if (Settings.IMP.CLIPBOARD.USE_DISK) {
|
|
||||||
fc = new DiskOptimizedClipboard(dimensions, uuid);
|
|
||||||
} else if (Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL == 0) {
|
|
||||||
fc = new CPUOptimizedClipboard(dimensions);
|
|
||||||
} else {
|
|
||||||
fc = new MemoryOptimizedClipboard(dimensions);
|
|
||||||
}
|
|
||||||
return fc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Clipboard recover() {
|
|
||||||
// TODO FIXME
|
|
||||||
throw new UnsupportedOperationException("TODO FIXME");
|
|
||||||
// try {
|
|
||||||
// if (stream == null || !stream.markSupported()) {
|
|
||||||
// throw new IllegalArgumentException("Can only recover from a marked and resettable stream!");
|
|
||||||
// }
|
|
||||||
// match("Width", new CorruptSchematicStreamer.CorruptReader() {
|
|
||||||
// @Override
|
|
||||||
// public void run(DataInputStream in) throws IOException {
|
|
||||||
// width.set(in.readShort());
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// match("Height", new CorruptSchematicStreamer.CorruptReader() {
|
|
||||||
// @Override
|
|
||||||
// public void run(DataInputStream in) throws IOException {
|
|
||||||
// height.set(in.readShort());
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// match("Length", new CorruptSchematicStreamer.CorruptReader() {
|
|
||||||
// @Override
|
|
||||||
// public void run(DataInputStream in) throws IOException {
|
|
||||||
// length.set(in.readShort());
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// match("WEOffsetX", new CorruptSchematicStreamer.CorruptReader() {
|
|
||||||
// @Override
|
|
||||||
// public void run(DataInputStream in) throws IOException {
|
|
||||||
// offsetX.set(in.readInt());
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// match("WEOffsetY", new CorruptSchematicStreamer.CorruptReader() {
|
|
||||||
// @Override
|
|
||||||
// public void run(DataInputStream in) throws IOException {
|
|
||||||
// offsetY.set(in.readInt());
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// match("WEOffsetZ", new CorruptSchematicStreamer.CorruptReader() {
|
|
||||||
// @Override
|
|
||||||
// public void run(DataInputStream in) throws IOException {
|
|
||||||
// offsetZ.set(in.readInt());
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// match("WEOriginX", new CorruptSchematicStreamer.CorruptReader() {
|
|
||||||
// @Override
|
|
||||||
// public void run(DataInputStream in) throws IOException {
|
|
||||||
// originX.set(in.readInt());
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// match("WEOriginY", new CorruptSchematicStreamer.CorruptReader() {
|
|
||||||
// @Override
|
|
||||||
// public void run(DataInputStream in) throws IOException {
|
|
||||||
// originY.set(in.readInt());
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// match("WEOriginZ", new CorruptSchematicStreamer.CorruptReader() {
|
|
||||||
// @Override
|
|
||||||
// public void run(DataInputStream in) throws IOException {
|
|
||||||
// originZ.set(in.readInt());
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// match("Blocks", new CorruptSchematicStreamer.CorruptReader() {
|
|
||||||
// @Override
|
|
||||||
// public void run(DataInputStream in) throws IOException {
|
|
||||||
// int length = in.readInt();
|
|
||||||
// volume.set(length);
|
|
||||||
// setupClipboard();
|
|
||||||
// for (int i = 0; i < length; i++) {
|
|
||||||
// fc.setId(i, in.read());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// match("Data", new CorruptSchematicStreamer.CorruptReader() {
|
|
||||||
// @Override
|
|
||||||
// public void run(DataInputStream in) throws IOException {
|
|
||||||
// int length = in.readInt();
|
|
||||||
// volume.set(length);
|
|
||||||
// setupClipboard();
|
|
||||||
// for (int i = 0; i < length; i++) {
|
|
||||||
// fc.setData(i, in.read());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// match("AddBlocks", new CorruptSchematicStreamer.CorruptReader() {
|
|
||||||
// @Override
|
|
||||||
// public void run(DataInputStream in) throws IOException {
|
|
||||||
// int length = in.readInt();
|
|
||||||
// int expected = volume.get();
|
|
||||||
// if (expected == 0) {
|
|
||||||
// expected = length * 2;
|
|
||||||
// volume.set(expected);
|
|
||||||
// }
|
|
||||||
// setupClipboard();
|
|
||||||
// if (expected == length * 2) {
|
|
||||||
// for (int i = 0; i < length; i++) {
|
|
||||||
// int value = in.read();
|
|
||||||
// int first = value & 0x0F;
|
|
||||||
// int second = (value & 0xF0) >> 4;
|
|
||||||
// int gIndex = i << 1;
|
|
||||||
// if (first != 0) fc.setAdd(gIndex, first);
|
|
||||||
// if (second != 0) fc.setAdd(gIndex + 1, second);
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// for (int i = 0; i < length; i++) {
|
|
||||||
// int value = in.read();
|
|
||||||
// if (value != 0) fc.setAdd(i, value);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// match("Biomes", new CorruptSchematicStreamer.CorruptReader() {
|
|
||||||
// @Override
|
|
||||||
// public void run(DataInputStream in) throws IOException {
|
|
||||||
// int length = in.readInt();
|
|
||||||
// for (int i = 0; i < length; i++) {
|
|
||||||
// fc.setBiome(i, in.read());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// Vector dimensions = guessDimensions(volume.get(), width.get(), height.get(), length.get());
|
|
||||||
// Vector min = new Vector(originX.get(), originY.get(), originZ.get());
|
|
||||||
// Vector offset = new Vector(offsetX.get(), offsetY.get(), offsetZ.get());
|
|
||||||
// Vector origin = min.subtract(offset);
|
|
||||||
// CuboidRegion region = new CuboidRegion(min, min.add(dimensions.getBlockX(), dimensions.getBlockY(), dimensions.getBlockZ()).subtract(Vector.ONE));
|
|
||||||
// fc.setOrigin(offset);
|
|
||||||
// final BlockArrayClipboard clipboard = new BlockArrayClipboard(region, fc);
|
|
||||||
// match("TileEntities", new CorruptSchematicStreamer.CorruptReader() {
|
|
||||||
// @Override
|
|
||||||
// public void run(DataInputStream in) throws IOException {
|
|
||||||
// int childType = in.readByte();
|
|
||||||
// int length = in.readInt();
|
|
||||||
// NBTInputStream nis = new NBTInputStream(in);
|
|
||||||
// for (int i = 0; i < length; ++i) {
|
|
||||||
// CompoundTag tag = (CompoundTag) nis.readTagPayload(childType, 1);
|
|
||||||
// int x = tag.getInt("x");
|
|
||||||
// int y = tag.getInt("y");
|
|
||||||
// int z = tag.getInt("z");
|
|
||||||
// fc.setTile(x, y, z, tag);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// match("Entities", new CorruptSchematicStreamer.CorruptReader() {
|
|
||||||
// @Override
|
|
||||||
// public void run(DataInputStream in) throws IOException {
|
|
||||||
// int childType = in.readByte();
|
|
||||||
// int length = in.readInt();
|
|
||||||
// NBTInputStream nis = new NBTInputStream(in);
|
|
||||||
// for (int i = 0; i < length; ++i) {
|
|
||||||
// CompoundTag tag = (CompoundTag) nis.readTagPayload(childType, 1);
|
|
||||||
// int x = tag.getInt("x");
|
|
||||||
// int y = tag.getInt("y");
|
|
||||||
// int z = tag.getInt("z");
|
|
||||||
// String id = tag.getString("id");
|
|
||||||
// if (id.isEmpty()) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// ListTag positionTag = tag.getListTag("Pos");
|
|
||||||
// ListTag directionTag = tag.getListTag("Rotation");
|
|
||||||
// BaseEntity state = new BaseEntity(id, tag);
|
|
||||||
// fc.createEntity(clipboard, positionTag.asDouble(0), positionTag.asDouble(1), positionTag.asDouble(2), (float) directionTag.asDouble(0), (float) directionTag.asDouble(1), state);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// return clipboard;
|
|
||||||
// } catch (Throwable e) {
|
|
||||||
// if (fc != null) fc.close();
|
|
||||||
// throw e;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
private BlockVector3 guessDimensions(int volume, int width, int height, int length) {
|
|
||||||
if (volume == 0) {
|
|
||||||
return BlockVector3.at(width, height, length);
|
|
||||||
}
|
|
||||||
if (volume == width * height * length) {
|
|
||||||
return BlockVector3.at(width, height, length);
|
|
||||||
}
|
|
||||||
if (width == 0 && height != 0 && length != 0 && volume % (height * length) == 0 && height * length <= volume) {
|
|
||||||
return BlockVector3.at(volume / (height * length), height, length);
|
|
||||||
}
|
|
||||||
if (height == 0 && width != 0 && length != 0 && volume % (width * length) == 0 && width * length <= volume) {
|
|
||||||
return BlockVector3.at(width, volume / (width * length), length);
|
|
||||||
}
|
|
||||||
if (length == 0 && height != 0 && width != 0 && volume % (height * width) == 0 && height * width <= volume) {
|
|
||||||
return BlockVector3.at(width, height, volume / (width * height));
|
|
||||||
}
|
|
||||||
List<Integer> factors = new ArrayList<>();
|
|
||||||
for (int i = (int) Math.sqrt(volume); i > 0; i--) {
|
|
||||||
if (volume % i == 0) {
|
|
||||||
factors.add(i);
|
|
||||||
factors.add(volume / i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int min = Integer.MAX_VALUE;
|
|
||||||
int vx = 0, vy = 0, vz = 0;
|
|
||||||
for (int x = 0; x < factors.size(); x++) {
|
|
||||||
int xValue = factors.get(x);
|
|
||||||
for (int yValue : factors) {
|
|
||||||
long area = xValue * yValue;
|
|
||||||
if (volume % area == 0) {
|
|
||||||
int z = (int) (volume / area);
|
|
||||||
int max = Math.max(Math.max(xValue, yValue), z);
|
|
||||||
if (max < min) {
|
|
||||||
min = max;
|
|
||||||
vx = xValue;
|
|
||||||
vz = z;
|
|
||||||
vy = yValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return BlockVector3.at(vx, vz, vy);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface CorruptReader {
|
|
||||||
void run(DataInputStream in) throws IOException;
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,6 +10,7 @@ import com.sk89q.worldedit.entity.BaseEntity;
|
|||||||
import com.sk89q.worldedit.entity.Entity;
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
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.Region;
|
||||||
import com.sk89q.worldedit.util.Location;
|
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;
|
||||||
@ -43,6 +44,10 @@ public class CPUOptimizedClipboard extends LinearClipboard {
|
|||||||
nbtMapIndex = new HashMap<>();
|
nbtMapIndex = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CPUOptimizedClipboard(Region region) {
|
||||||
|
this(region.getDimensions());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasBiomes() {
|
public boolean hasBiomes() {
|
||||||
return biomes != null;
|
return biomes != null;
|
||||||
|
@ -14,6 +14,7 @@ import com.sk89q.worldedit.entity.Entity;
|
|||||||
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.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;
|
||||||
@ -50,6 +51,7 @@ import javax.annotation.Nullable;
|
|||||||
public class DiskOptimizedClipboard extends LinearClipboard implements Closeable {
|
public class DiskOptimizedClipboard extends LinearClipboard implements Closeable {
|
||||||
|
|
||||||
private static int HEADER_SIZE = 14;
|
private static int HEADER_SIZE = 14;
|
||||||
|
private static final int MAX_SIZE = Short.MAX_VALUE - Short.MIN_VALUE;
|
||||||
|
|
||||||
private final HashMap<IntegerTrio, CompoundTag> nbtMap;
|
private final HashMap<IntegerTrio, CompoundTag> nbtMap;
|
||||||
private final File file;
|
private final File file;
|
||||||
@ -70,8 +72,14 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable
|
|||||||
|
|
||||||
public DiskOptimizedClipboard(BlockVector3 dimensions, File file) {
|
public DiskOptimizedClipboard(BlockVector3 dimensions, File file) {
|
||||||
super(dimensions);
|
super(dimensions);
|
||||||
if (getWidth() > Character.MAX_VALUE || getHeight() > Character.MAX_VALUE || getLength() > Character.MAX_VALUE) {
|
if (getWidth() > MAX_SIZE) {
|
||||||
throw new IllegalArgumentException("Too large");
|
throw new IllegalArgumentException("Width of region too large");
|
||||||
|
}
|
||||||
|
if (getHeight() > MAX_SIZE) {
|
||||||
|
throw new IllegalArgumentException("Height of region too large");
|
||||||
|
}
|
||||||
|
if (getLength() > MAX_SIZE) {
|
||||||
|
throw new IllegalArgumentException("Length of region too large");
|
||||||
}
|
}
|
||||||
nbtMap = new HashMap<>();
|
nbtMap = new HashMap<>();
|
||||||
try {
|
try {
|
||||||
@ -101,6 +109,10 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DiskOptimizedClipboard(Region region, UUID uuid) {
|
||||||
|
this(region.getDimensions(), uuid);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public URI getURI() {
|
public URI getURI() {
|
||||||
return file.toURI();
|
return file.toURI();
|
||||||
@ -166,7 +178,7 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
public boolean setBiome(int x, int y, int z, BiomeType biome) {
|
||||||
setBiome(getIndex(x, 0, z), biome);
|
setBiome(getIndex(x, y, z), biome);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import com.sk89q.worldedit.entity.Entity;
|
|||||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard.ClipboardEntity;
|
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard.ClipboardEntity;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.util.Location;
|
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;
|
||||||
@ -52,12 +53,12 @@ public class MemoryOptimizedClipboard extends LinearClipboard {
|
|||||||
|
|
||||||
private int compressionLevel;
|
private int compressionLevel;
|
||||||
|
|
||||||
public MemoryOptimizedClipboard(BlockVector3 dimensions) {
|
public MemoryOptimizedClipboard(Region region) {
|
||||||
this(dimensions, Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL);
|
this(region, Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MemoryOptimizedClipboard(BlockVector3 dimensions, int compressionLevel) {
|
public MemoryOptimizedClipboard(Region region, int compressionLevel) {
|
||||||
super(dimensions);
|
super(region.getDimensions());
|
||||||
states = new byte[1 + (getVolume() >> BLOCK_SHIFT)][];
|
states = new byte[1 + (getVolume() >> BLOCK_SHIFT)][];
|
||||||
nbtMapLoc = new HashMap<>();
|
nbtMapLoc = new HashMap<>();
|
||||||
nbtMapIndex = new HashMap<>();
|
nbtMapIndex = new HashMap<>();
|
||||||
@ -97,8 +98,8 @@ public class MemoryOptimizedClipboard extends LinearClipboard {
|
|||||||
@Override
|
@Override
|
||||||
public void streamBiomes(IntValueReader task) {
|
public void streamBiomes(IntValueReader task) {
|
||||||
if (!hasBiomes()) return;
|
if (!hasBiomes()) return;
|
||||||
int index = 0;
|
|
||||||
try {
|
try {
|
||||||
|
int index = 0;
|
||||||
for (int z = 0; z < getLength(); z++) {
|
for (int z = 0; z < getLength(); z++) {
|
||||||
for (int x = 0; x < getWidth(); x++, index++) {
|
for (int x = 0; x < getWidth(); x++, index++) {
|
||||||
task.applyInt(index, biomes[index] & 0xFF);
|
task.applyInt(index, biomes[index] & 0xFF);
|
||||||
|
@ -19,7 +19,7 @@ public abstract class ReadOnlyClipboard extends SimpleClipboard {
|
|||||||
public final Region region;
|
public final Region region;
|
||||||
|
|
||||||
public ReadOnlyClipboard(Region region) {
|
public ReadOnlyClipboard(Region region) {
|
||||||
super(region.getDimensions());
|
super(region);
|
||||||
this.region = region;
|
this.region = region;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ public abstract class SimpleClipboard implements Clipboard {
|
|||||||
private final int volume;
|
private final int volume;
|
||||||
private BlockVector3 origin;
|
private BlockVector3 origin;
|
||||||
|
|
||||||
public SimpleClipboard(BlockVector3 dimensions) {
|
SimpleClipboard(BlockVector3 dimensions) {
|
||||||
this.size = dimensions;
|
this.size = dimensions;
|
||||||
long longVolume = (long) getWidth() * (long) getHeight() * (long) getLength();
|
long longVolume = (long) getWidth() * (long) getHeight() * (long) getLength();
|
||||||
if (longVolume >= Integer.MAX_VALUE >> 2) {
|
if (longVolume >= Integer.MAX_VALUE >> 2) {
|
||||||
@ -22,6 +22,10 @@ public abstract class SimpleClipboard implements Clipboard {
|
|||||||
this.origin = BlockVector3.ZERO;
|
this.origin = BlockVector3.ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SimpleClipboard(Region region) {
|
||||||
|
this(region.getDimensions());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setOrigin(BlockVector3 offset) {
|
public void setOrigin(BlockVector3 offset) {
|
||||||
this.origin = offset;
|
this.origin = offset;
|
||||||
@ -44,7 +48,7 @@ public abstract class SimpleClipboard implements Clipboard {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Region getRegion() {
|
public Region getRegion() {
|
||||||
return new CuboidRegion(BlockVector3.at(0, 0, 0), BlockVector3.at(getWidth() - 1, getHeight() - 1, getLength() - 1));
|
return new CuboidRegion(BlockVector3.ZERO, BlockVector3.at(getWidth() - 1, getHeight() - 1, getLength() - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -76,13 +76,13 @@ public class BlockArrayClipboard implements Clipboard {
|
|||||||
* @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));
|
this(region, Clipboard.create(region, clipboardId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockArrayClipboard(Region region, Clipboard clipboard) {
|
public BlockArrayClipboard(Region region, Clipboard parent) {
|
||||||
checkNotNull(clipboard);
|
checkNotNull(parent);
|
||||||
checkNotNull(region);
|
checkNotNull(region);
|
||||||
this.parent = clipboard;
|
this.parent = parent;
|
||||||
this.region = region;
|
this.region = region;
|
||||||
this.origin = region.getMinimumPoint();
|
this.origin = region.getMinimumPoint();
|
||||||
}
|
}
|
||||||
|
@ -75,13 +75,13 @@ public interface Clipboard extends Extent, Iterable<BlockVector3>, Closeable {
|
|||||||
return ReadOnlyClipboard.of(session, region);
|
return ReadOnlyClipboard.of(session, region);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Clipboard create(BlockVector3 size, UUID uuid) {
|
static Clipboard create(Region region, UUID uuid) {
|
||||||
if (Settings.IMP.CLIPBOARD.USE_DISK) {
|
if (Settings.IMP.CLIPBOARD.USE_DISK) {
|
||||||
return new DiskOptimizedClipboard(size, uuid);
|
return new DiskOptimizedClipboard(region, uuid);
|
||||||
} else if (Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL == 0) {
|
} else if (Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL == 0) {
|
||||||
return new CPUOptimizedClipboard(size);
|
return new CPUOptimizedClipboard(region);
|
||||||
} else {
|
} else {
|
||||||
return new MemoryOptimizedClipboard(size);
|
return new MemoryOptimizedClipboard(region);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,8 +443,8 @@ public class SchematicReader implements ClipboardReader {
|
|||||||
if (set.getState(PropertyKey.WEST) == Boolean.FALSE && merge(fc, group, x - 1, y, z)) set = set.with(PropertyKey.WEST, true);
|
if (set.getState(PropertyKey.WEST) == Boolean.FALSE && merge(fc, group, x - 1, y, z)) set = set.with(PropertyKey.WEST, true);
|
||||||
|
|
||||||
if (group == 2) {
|
if (group == 2) {
|
||||||
int ns = ((Boolean) set.getState(PropertyKey.NORTH) ? 1 : 0) + ((Boolean) set.getState(PropertyKey.SOUTH) ? 1 : 0);
|
int ns = (set.getState(PropertyKey.NORTH) ? 1 : 0) + ((Boolean) set.getState(PropertyKey.SOUTH) ? 1 : 0);
|
||||||
int ew = ((Boolean) set.getState(PropertyKey.EAST) ? 1 : 0) + ((Boolean) set.getState(PropertyKey.WEST) ? 1 : 0);
|
int ew = (set.getState(PropertyKey.EAST) ? 1 : 0) + ((Boolean) set.getState(PropertyKey.WEST) ? 1 : 0);
|
||||||
if (Math.abs(ns - ew) != 2 || fc.getBlock(x, y + 1, z).getBlockType().getMaterial().isSolid()) {
|
if (Math.abs(ns - ew) != 2 || fc.getBlock(x, y + 1, z).getBlockType().getMaterial().isSolid()) {
|
||||||
set = set.with(PropertyKey.UP, true);
|
set = set.with(PropertyKey.UP, true);
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,6 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private BlockArrayClipboard readVersion1(CompoundTag schematicTag) throws IOException {
|
private BlockArrayClipboard readVersion1(CompoundTag schematicTag) throws IOException {
|
||||||
BlockVector3 origin;
|
|
||||||
Region region;
|
Region region;
|
||||||
Map<String, Tag> schematic = schematicTag.getValue();
|
Map<String, Tag> schematic = schematicTag.getValue();
|
||||||
|
|
||||||
@ -172,22 +171,8 @@ public class SpongeSchematicReader extends NBTSchematicReader {
|
|||||||
offsetParts = new int[] {0, 0, 0};
|
offsetParts = new int[] {0, 0, 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockVector3 min = BlockVector3.at(offsetParts[0], offsetParts[1], offsetParts[2]);
|
BlockVector3 origin = BlockVector3.at(offsetParts[0], offsetParts[1], offsetParts[2]);
|
||||||
|
region = new CuboidRegion(origin, BlockVector3.ZERO.add(width, height, length).subtract(BlockVector3.ONE));
|
||||||
CompoundTag metadataTag = getTag(schematic, "Metadata", CompoundTag.class);
|
|
||||||
if (metadataTag != null && metadataTag.containsKey("WEOffsetX")) {
|
|
||||||
// We appear to have WorldEdit Metadata
|
|
||||||
Map<String, Tag> metadata = metadataTag.getValue();
|
|
||||||
int offsetX = requireTag(metadata, "WEOffsetX", IntTag.class).getValue();
|
|
||||||
int offsetY = requireTag(metadata, "WEOffsetY", IntTag.class).getValue();
|
|
||||||
int offsetZ = requireTag(metadata, "WEOffsetZ", IntTag.class).getValue();
|
|
||||||
BlockVector3 offset = BlockVector3.at(offsetX, offsetY, offsetZ);
|
|
||||||
origin = min.subtract(offset);
|
|
||||||
region = new CuboidRegion(min, min.add(width, height, length).subtract(BlockVector3.ONE));
|
|
||||||
} else {
|
|
||||||
origin = min;
|
|
||||||
region = new CuboidRegion(origin, origin.add(width, height, length).subtract(BlockVector3.ONE));
|
|
||||||
}
|
|
||||||
|
|
||||||
IntTag paletteMaxTag = getTag(schematic, "PaletteMax", IntTag.class);
|
IntTag paletteMaxTag = getTag(schematic, "PaletteMax", IntTag.class);
|
||||||
Map<String, Tag> paletteObject = requireTag(schematic, "Palette", CompoundTag.class).getValue();
|
Map<String, Tag> paletteObject = requireTag(schematic, "Palette", CompoundTag.class).getValue();
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren