geforkt von Mirrors/FastAsyncWorldEdit
Fix fast schematic reader/writer
- Have both sponge and fast r/w available but default to "fast" - Correctly "offset" entities in the schematic, and add a legacy mode for loading old FAWE schematics with entities required. - Lazily reading means it's read in order of appearance in the inputstream so we need to read schematic version first (skip past everything) and then reset the stream. Fixes #740 - Add an FAWEVersion to the metadata - Correctly actually return a BlockArrayClipboard when required. Fixes #454
Dieser Commit ist enthalten in:
Ursprung
82f640d132
Commit
fbfe3221d7
@ -200,7 +200,7 @@ public class StreamDelegate {
|
||||
Object raw = is.readTagPayloadRaw(type, depth);
|
||||
valueReader.apply(0, raw);
|
||||
} else {
|
||||
is.readTagPaylodLazy(type, depth + 1, this);
|
||||
is.readTagPayloadLazy(type, depth + 1, this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,14 @@ public final class NBTInputStream implements Closeable {
|
||||
this.is = dis;
|
||||
}
|
||||
|
||||
public void mark(int mark) {
|
||||
is.mark(mark);
|
||||
}
|
||||
|
||||
public void reset() throws IOException {
|
||||
is.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an NBT tag from the stream.
|
||||
*
|
||||
@ -99,7 +107,7 @@ public final class NBTInputStream implements Closeable {
|
||||
if (child != null) {
|
||||
child.acceptRoot(this, type, 0);
|
||||
} else {
|
||||
readTagPaylodLazy(type, 0);
|
||||
readTagPayloadLazy(type, 0);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
@ -119,7 +127,7 @@ public final class NBTInputStream implements Closeable {
|
||||
|
||||
private byte[] buf;
|
||||
|
||||
public void readTagPaylodLazy(int type, int depth) throws IOException {
|
||||
public void readTagPayloadLazy(int type, int depth) throws IOException {
|
||||
switch (type) {
|
||||
case NBTConstants.TYPE_END:
|
||||
return;
|
||||
@ -152,7 +160,7 @@ public final class NBTInputStream implements Closeable {
|
||||
int childType = is.readByte();
|
||||
length = is.readInt();
|
||||
for (int i = 0; i < length; ++i) {
|
||||
readTagPaylodLazy(childType, depth + 1);
|
||||
readTagPayloadLazy(childType, depth + 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -165,7 +173,7 @@ public final class NBTInputStream implements Closeable {
|
||||
return;
|
||||
}
|
||||
is.skipBytes(is.readShort() & 0xFFFF);
|
||||
readTagPaylodLazy(childType, depth + 1);
|
||||
readTagPayloadLazy(childType, depth + 1);
|
||||
}
|
||||
}
|
||||
case NBTConstants.TYPE_INT_ARRAY: {
|
||||
@ -181,7 +189,7 @@ public final class NBTInputStream implements Closeable {
|
||||
}
|
||||
}
|
||||
|
||||
public void readTagPaylodLazy(int type, int depth, StreamDelegate scope) throws IOException {
|
||||
public void readTagPayloadLazy(int type, int depth, StreamDelegate scope) throws IOException {
|
||||
switch (type) {
|
||||
case NBTConstants.TYPE_END:
|
||||
return;
|
||||
@ -293,11 +301,11 @@ public final class NBTInputStream implements Closeable {
|
||||
child = scope.get0();
|
||||
if (child == null) {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
readTagPaylodLazy(childType, depth + 1);
|
||||
readTagPayloadLazy(childType, depth + 1);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
readTagPaylodLazy(childType, depth + 1, child);
|
||||
readTagPayloadLazy(childType, depth + 1, child);
|
||||
}
|
||||
}
|
||||
return;
|
||||
@ -330,9 +338,9 @@ public final class NBTInputStream implements Closeable {
|
||||
}
|
||||
StreamDelegate child = scope.get(is);
|
||||
if (child == null) {
|
||||
readTagPaylodLazy(childType, depth + 1);
|
||||
readTagPayloadLazy(childType, depth + 1);
|
||||
} else {
|
||||
readTagPaylodLazy(childType, depth + 1, child);
|
||||
readTagPayloadLazy(childType, depth + 1, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -147,7 +147,7 @@ public class SchematicCommands {
|
||||
@Deprecated
|
||||
@CommandPermissions({"worldedit.clipboard.load", "worldedit.schematic.load", "worldedit.schematic.load.web", "worldedit.schematic.load.asset"})
|
||||
public void loadall(Player player, LocalSession session,
|
||||
@Arg(desc = "Format name.", def = "schematic")
|
||||
@Arg(desc = "Format name.", def = "fast")
|
||||
String formatName,
|
||||
@Arg(desc = "File name.")
|
||||
String filename,
|
||||
@ -223,7 +223,7 @@ public class SchematicCommands {
|
||||
public void load(Actor actor, LocalSession session,
|
||||
@Arg(desc = "File name.")
|
||||
String filename,
|
||||
@Arg(desc = "Format name.", def = "sponge")
|
||||
@Arg(desc = "Format name.", def = "fast")
|
||||
String formatName) throws FilenameException {
|
||||
LocalConfiguration config = worldEdit.getConfiguration();
|
||||
|
||||
@ -323,7 +323,7 @@ public class SchematicCommands {
|
||||
public void save(Actor actor, LocalSession session,
|
||||
@Arg(desc = "File name.")
|
||||
String filename,
|
||||
@Arg(desc = "Format name.", def = "sponge")
|
||||
@Arg(desc = "Format name.", def = "fast")
|
||||
String formatName,
|
||||
@Switch(name = 'f', desc = "Overwrite an existing file.")
|
||||
boolean allowOverwrite,
|
||||
|
@ -24,8 +24,11 @@ import com.boydti.fawe.object.io.ResettableFileInputStream;
|
||||
import com.boydti.fawe.object.schematic.MinecraftStructure;
|
||||
import com.boydti.fawe.object.schematic.PNGWriter;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.NBTOutputStream;
|
||||
import com.sk89q.jnbt.NamedTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
@ -35,6 +38,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
@ -44,6 +48,44 @@ import java.util.zip.GZIPOutputStream;
|
||||
*/
|
||||
public enum BuiltInClipboardFormat implements ClipboardFormat {
|
||||
|
||||
FAST("fast", "fawe") {
|
||||
|
||||
@Override
|
||||
public String getPrimaryFileExtension() {
|
||||
return "schem";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClipboardReader getReader(InputStream inputStream) throws IOException {
|
||||
if (inputStream instanceof FileInputStream) {
|
||||
inputStream = new ResettableFileInputStream((FileInputStream) inputStream);
|
||||
}
|
||||
BufferedInputStream buffered = new BufferedInputStream(inputStream);
|
||||
NBTInputStream nbtStream = new NBTInputStream(new BufferedInputStream(new GZIPInputStream(buffered)));
|
||||
return new FastSchematicReader(nbtStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||
OutputStream gzip;
|
||||
if (outputStream instanceof PGZIPOutputStream || outputStream instanceof GZIPOutputStream) {
|
||||
gzip = outputStream;
|
||||
} else {
|
||||
outputStream = new BufferedOutputStream(outputStream);
|
||||
gzip = new PGZIPOutputStream(outputStream);
|
||||
}
|
||||
NBTOutputStream nbtStream = new NBTOutputStream(new BufferedOutputStream(gzip));
|
||||
return new FastSchematicWriter(nbtStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFormat(File file) {
|
||||
String name = file.getName().toLowerCase(Locale.ROOT);
|
||||
return name.endsWith(".schem") || name.endsWith(".sponge");
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* The Schematic format used by MCEdit.
|
||||
*/
|
||||
@ -77,8 +119,49 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
|
||||
return name.endsWith(".schematic") || name.endsWith(".mcedit") || name.endsWith(".mce");
|
||||
}
|
||||
},
|
||||
|
||||
SPONGE_SCHEMATIC("sponge", "schem") {
|
||||
|
||||
@Override
|
||||
public String getPrimaryFileExtension() {
|
||||
return "schem";
|
||||
}
|
||||
@Override
|
||||
public ClipboardReader getReader(InputStream inputStream) throws IOException {
|
||||
NBTInputStream nbtStream = new NBTInputStream(new GZIPInputStream(inputStream));
|
||||
return new SpongeSchematicReader(nbtStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClipboardWriter getWriter(OutputStream outputStream) throws IOException {
|
||||
NBTOutputStream nbtStream = new NBTOutputStream(new GZIPOutputStream(outputStream));
|
||||
return new SpongeSchematicWriter(nbtStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFormat(File file) {
|
||||
try (NBTInputStream str = new NBTInputStream(new GZIPInputStream(new FileInputStream(file)))) {
|
||||
NamedTag rootTag = str.readNamedTag();
|
||||
if (!rootTag.getName().equals("Schematic")) {
|
||||
return false;
|
||||
}
|
||||
CompoundTag schematicTag = (CompoundTag) rootTag.getTag();
|
||||
|
||||
// Check
|
||||
Map<String, Tag> schematic = schematicTag.getValue();
|
||||
if (!schematic.containsKey("Version")) {
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
BROKENENTITY("brokenentity", "legacyentity", "le", "be", "brokenentities", "legacyentities") {
|
||||
|
||||
@Override
|
||||
public String getPrimaryFileExtension() {
|
||||
return "schem";
|
||||
@ -91,7 +174,9 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
|
||||
}
|
||||
BufferedInputStream buffered = new BufferedInputStream(inputStream);
|
||||
NBTInputStream nbtStream = new NBTInputStream(new BufferedInputStream(new GZIPInputStream(buffered)));
|
||||
return new FastSchematicReader(nbtStream);
|
||||
FastSchematicReader reader = new FastSchematicReader(nbtStream);
|
||||
reader.setBrokenEntities(true);
|
||||
return reader;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -104,13 +189,14 @@ public enum BuiltInClipboardFormat implements ClipboardFormat {
|
||||
gzip = new PGZIPOutputStream(outputStream);
|
||||
}
|
||||
NBTOutputStream nbtStream = new NBTOutputStream(new BufferedOutputStream(gzip));
|
||||
return new FastSchematicWriter(nbtStream);
|
||||
FastSchematicWriter writer = new FastSchematicWriter(nbtStream);
|
||||
writer.setBrokenEntities(true);
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFormat(File file) {
|
||||
String name = file.getName().toLowerCase(Locale.ROOT);
|
||||
return name.endsWith(".schem") || name.endsWith(".sponge");
|
||||
return false;
|
||||
}
|
||||
|
||||
},
|
||||
|
@ -30,10 +30,12 @@ import com.boydti.fawe.object.io.FastByteArraysInputStream;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.IntTag;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.NamedTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.extension.input.InputParseException;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
@ -45,6 +47,7 @@ import com.sk89q.worldedit.world.DataFixer;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||
import com.sk89q.worldedit.world.entity.EntityType;
|
||||
import com.sk89q.worldedit.world.entity.EntityTypes;
|
||||
@ -58,6 +61,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
|
||||
@ -70,9 +74,10 @@ public class FastSchematicReader extends NBTSchematicReader {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(FastSchematicReader.class);
|
||||
private final NBTInputStream inputStream;
|
||||
private DataFixer fixer = null;
|
||||
private DataFixer fixer;
|
||||
private int dataVersion = -1;
|
||||
private int version = -1;
|
||||
private int faweWritten = -1;
|
||||
|
||||
private FastByteArrayOutputStream blocksOut;
|
||||
private FaweOutputStream blocks;
|
||||
@ -92,6 +97,7 @@ public class FastSchematicReader extends NBTSchematicReader {
|
||||
private char[] palette;
|
||||
private char[] biomePalette;
|
||||
private BlockVector3 min = BlockVector3.ZERO;
|
||||
private boolean brokenEntities = false;
|
||||
|
||||
|
||||
/**
|
||||
@ -105,6 +111,10 @@ public class FastSchematicReader extends NBTSchematicReader {
|
||||
this.fixer = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataFixer();
|
||||
}
|
||||
|
||||
public void setBrokenEntities(boolean brokenEntities) {
|
||||
this.brokenEntities = brokenEntities;
|
||||
}
|
||||
|
||||
private String fix(String palettePart) {
|
||||
if (fixer == null || dataVersion == -1) {
|
||||
return palettePart;
|
||||
@ -133,7 +143,7 @@ public class FastSchematicReader extends NBTSchematicReader {
|
||||
return fixer.fixUp(DataFixer.FixTypes.BIOME, biomePalettePart, dataVersion);
|
||||
}
|
||||
|
||||
public StreamDelegate createDelegate() {
|
||||
public StreamDelegate createVersionDelegate() {
|
||||
StreamDelegate root = new StreamDelegate();
|
||||
StreamDelegate schematic = root.add("Schematic");
|
||||
schematic.add("DataVersion").withInt((i, v) -> dataVersion = v);
|
||||
@ -143,6 +153,12 @@ public class FastSchematicReader extends NBTSchematicReader {
|
||||
dataVersion = Constants.DATA_VERSION_MC_1_13_2;
|
||||
}
|
||||
});
|
||||
return root;
|
||||
}
|
||||
|
||||
public StreamDelegate createDelegate() {
|
||||
StreamDelegate root = new StreamDelegate();
|
||||
StreamDelegate schematic = root.add("Schematic");
|
||||
schematic.add("Width").withInt((i, v) -> width = v);
|
||||
schematic.add("Height").withInt((i, v) -> height = v);
|
||||
schematic.add("Length").withInt((i, v) -> length = v);
|
||||
@ -152,17 +168,19 @@ public class FastSchematicReader extends NBTSchematicReader {
|
||||
metadata.add("WEOffsetX").withInt((i, v) -> offsetX = v);
|
||||
metadata.add("WEOffsetY").withInt((i, v) -> offsetY = v);
|
||||
metadata.add("WEOffsetZ").withInt((i, v) -> offsetZ = v);
|
||||
metadata.add("FAWEVersion").withInt((i, v) -> faweWritten = v);
|
||||
|
||||
StreamDelegate paletteDelegate = schematic.add("Palette");
|
||||
paletteDelegate.withValue((ValueReader<Map<String, Object>>) (ignore, v) -> {
|
||||
palette = new char[v.size()];
|
||||
for (Entry<String, Object> entry : v.entrySet()) {
|
||||
BlockState state = null;
|
||||
BlockState state;
|
||||
String palettePart = fix(entry.getKey());
|
||||
try {
|
||||
String palettePart = fix(entry.getKey());
|
||||
state = BlockState.get(palettePart);
|
||||
} catch (InputParseException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InputParseException ignored) {
|
||||
log.warn("Invalid BlockState in palette: " + palettePart + ". Block will be replaced with air.");
|
||||
state = BlockTypes.AIR.getDefaultState();
|
||||
}
|
||||
int index = (int) entry.getValue();
|
||||
palette[index] = (char) state.getOrdinal();
|
||||
@ -224,10 +242,14 @@ public class FastSchematicReader extends NBTSchematicReader {
|
||||
@Override
|
||||
public Clipboard read(UUID uuid, Function<BlockVector3, Clipboard> createOutput) throws IOException {
|
||||
StreamDelegate root = createDelegate();
|
||||
StreamDelegate versions = createVersionDelegate();
|
||||
inputStream.mark(Integer.MAX_VALUE);
|
||||
inputStream.readNamedTagLazy(versions);
|
||||
inputStream.reset();
|
||||
inputStream.readNamedTagLazy(root);
|
||||
|
||||
if (version != 1 && version != 2) {
|
||||
throw new IOException("This schematic version is currently not supported");
|
||||
throw new IOException("This schematic version is currently not supported (" + version + ")");
|
||||
}
|
||||
|
||||
if (blocks != null) {
|
||||
@ -240,9 +262,11 @@ public class FastSchematicReader extends NBTSchematicReader {
|
||||
biomes = null;
|
||||
|
||||
BlockVector3 dimensions = BlockVector3.at(width, height, length);
|
||||
BlockVector3 origin = BlockVector3.ZERO;
|
||||
BlockVector3 origin;
|
||||
if (offsetX != Integer.MIN_VALUE && offsetY != Integer.MIN_VALUE && offsetZ != Integer.MIN_VALUE) {
|
||||
origin = BlockVector3.at(-offsetX, -offsetY, -offsetZ);
|
||||
} else {
|
||||
origin = BlockVector3.ZERO;
|
||||
}
|
||||
|
||||
Clipboard clipboard = createOutput.apply(dimensions);
|
||||
@ -352,7 +376,7 @@ public class FastSchematicReader extends NBTSchematicReader {
|
||||
if (id == null) {
|
||||
id = (StringTag) value.get("id");
|
||||
if (id == null) {
|
||||
return null;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
value.put("id", id);
|
||||
@ -363,7 +387,26 @@ public class FastSchematicReader extends NBTSchematicReader {
|
||||
ent = fixEntity(ent);
|
||||
BaseEntity state = new BaseEntity(type, ent);
|
||||
Location loc = ent.getEntityLocation(clipboard);
|
||||
clipboard.createEntity(loc, state);
|
||||
if (brokenEntities) {
|
||||
clipboard.createEntity(loc, state);
|
||||
continue;
|
||||
}
|
||||
if (faweWritten == -1) {
|
||||
int locX = loc.getBlockX();
|
||||
int locY = loc.getBlockY();
|
||||
int locZ = loc.getBlockZ();
|
||||
BlockVector3 max = min.add(dimensions).subtract(BlockVector3.ONE);
|
||||
if (locX < min.getX() || locY < min.getY() || locZ < min.getZ()
|
||||
|| locX > max.getX() || locY > max.getY() || locZ > max.getZ()) {
|
||||
for (Entity e : clipboard.getEntities()) {
|
||||
clipboard.removeEntity(e);
|
||||
}
|
||||
log.error("Detected schematic entity outside clipboard region. FAWE will not load entities. "
|
||||
+ "Please try loading the schematic with the format \"legacyentity\"");
|
||||
break;
|
||||
}
|
||||
}
|
||||
clipboard.createEntity(loc.setPosition(loc.subtract(min.toVector3())), state);
|
||||
} else {
|
||||
log.debug("Invalid entity: " + id);
|
||||
}
|
||||
@ -372,7 +415,7 @@ public class FastSchematicReader extends NBTSchematicReader {
|
||||
clipboard.setOrigin(origin);
|
||||
|
||||
if (!min.equals(BlockVector3.ZERO)) {
|
||||
new BlockArrayClipboard(clipboard, min);
|
||||
clipboard = new BlockArrayClipboard(clipboard, min);
|
||||
}
|
||||
|
||||
return clipboard;
|
||||
|
@ -19,10 +19,10 @@
|
||||
|
||||
package com.sk89q.worldedit.extent.clipboard.io;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.jnbt.streamer.IntValueReader;
|
||||
import com.boydti.fawe.object.FaweOutputStream;
|
||||
import com.boydti.fawe.util.IOUtil;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.IntArrayTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
@ -39,6 +39,7 @@ import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.function.visitor.Order;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
@ -58,8 +59,6 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
@ -72,6 +71,7 @@ public class FastSchematicWriter implements ClipboardWriter {
|
||||
|
||||
private static final int MAX_SIZE = Short.MAX_VALUE - Short.MIN_VALUE;
|
||||
private final NBTOutputStream outputStream;
|
||||
private boolean brokenEntities = false;
|
||||
|
||||
/**
|
||||
* Create a new schematic writer.
|
||||
@ -83,6 +83,10 @@ public class FastSchematicWriter implements ClipboardWriter {
|
||||
this.outputStream = outputStream;
|
||||
}
|
||||
|
||||
public void setBrokenEntities(boolean brokenEntities) {
|
||||
this.brokenEntities = brokenEntities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(Clipboard clipboard) throws IOException {
|
||||
// For now always write the latest version. Maybe provide support for earlier if more appear.
|
||||
@ -132,6 +136,7 @@ public class FastSchematicWriter implements ClipboardWriter {
|
||||
out1.writeNamedTag("WEOffsetX", offset.getBlockX());
|
||||
out1.writeNamedTag("WEOffsetY", offset.getBlockY());
|
||||
out1.writeNamedTag("WEOffsetZ", offset.getBlockZ());
|
||||
out1.writeNamedTag("FAWEVersion", Fawe.get().getVersion().build);
|
||||
});
|
||||
|
||||
ByteArrayOutputStream blocksCompressed = new ByteArrayOutputStream();
|
||||
@ -240,8 +245,12 @@ public class FastSchematicWriter implements ClipboardWriter {
|
||||
|
||||
// Store our location data, overwriting any
|
||||
values.remove("id");
|
||||
Location loc = entity.getLocation();
|
||||
if (!brokenEntities) {
|
||||
loc = loc.setPosition(loc.add(min.toVector3()));
|
||||
}
|
||||
values.put("Id", new StringTag(state.getType().getId()));
|
||||
values.put("Pos", writeVector(entity.getLocation()));
|
||||
values.put("Pos", writeVector(loc));
|
||||
values.put("Rotation", writeRotation(entity.getLocation()));
|
||||
|
||||
CompoundTag entityTag = new CompoundTag(values);
|
||||
@ -311,30 +320,6 @@ public class FastSchematicWriter implements ClipboardWriter {
|
||||
}
|
||||
}
|
||||
|
||||
private void writeEntities(Clipboard clipboard, NBTOutputStream schematic) throws IOException {
|
||||
List<CompoundTag> entities = clipboard.getEntities().stream().map(e -> {
|
||||
BaseEntity state = e.getState();
|
||||
if (state == null) {
|
||||
return null;
|
||||
}
|
||||
Map<String, Tag> values = Maps.newHashMap();
|
||||
CompoundTag rawData = state.getNbtData();
|
||||
if (rawData != null) {
|
||||
values.putAll(rawData.getValue());
|
||||
}
|
||||
values.remove("id");
|
||||
values.put("Id", new StringTag(state.getType().getId()));
|
||||
values.put("Pos", writeVector(e.getLocation().toVector()));
|
||||
values.put("Rotation", writeRotation(e.getLocation()));
|
||||
|
||||
return new CompoundTag(values);
|
||||
}).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
if (entities.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
schematic.writeNamedTag("Entities", new ListTag(CompoundTag.class, entities));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
outputStream.close();
|
||||
|
@ -378,7 +378,7 @@ public class SchematicReader implements ClipboardReader {
|
||||
|
||||
BlockVector3 min = BlockVector3.at(originX, originY, originZ);
|
||||
if (!min.equals(BlockVector3.ZERO)) {
|
||||
new BlockArrayClipboard(clipboard, min);
|
||||
clipboard = new BlockArrayClipboard(clipboard, min);
|
||||
}
|
||||
return clipboard;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.extent.clipboard.io;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.sk89q.jnbt.ByteArrayTag;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
@ -114,6 +115,7 @@ public class SpongeSchematicWriter implements ClipboardWriter {
|
||||
metadata.put("WEOffsetX", new IntTag(offset.getBlockX()));
|
||||
metadata.put("WEOffsetY", new IntTag(offset.getBlockY()));
|
||||
metadata.put("WEOffsetZ", new IntTag(offset.getBlockZ()));
|
||||
metadata.put("FAWEVersion", new IntTag(Fawe.get().getVersion().build));
|
||||
|
||||
schematic.put("Metadata", new CompoundTag(metadata));
|
||||
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren