diff --git a/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/FaweSchematicHandler.java b/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/FaweSchematicHandler.java index bffed2622..12426beea 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/FaweSchematicHandler.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/FaweSchematicHandler.java @@ -1,10 +1,14 @@ package com.boydti.fawe.regions.general.plot; import com.boydti.fawe.FaweCache; +import com.boydti.fawe.object.FaweOutputStream; import com.boydti.fawe.object.FaweQueue; import com.boydti.fawe.object.clipboard.ReadOnlyClipboard; +import com.boydti.fawe.object.io.FastByteArrayOutputStream; +import com.boydti.fawe.object.io.FastByteArraysInputStream; import com.boydti.fawe.object.io.PGZIPOutputStream; import com.boydti.fawe.util.EditSessionBuilder; +import com.boydti.fawe.util.IOUtil; import com.boydti.fawe.util.SetQueue; import com.boydti.fawe.util.TaskManager; import com.github.intellectualsites.plotsquared.plot.PlotSquared; @@ -15,12 +19,23 @@ import com.github.intellectualsites.plotsquared.plot.util.MainUtil; import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler; import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue; import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.CompressedCompoundTag; +import com.sk89q.jnbt.CompressedSchematicTag; import com.sk89q.jnbt.NBTOutputStream; +import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.extent.clipboard.io.SpongeSchematicWriter; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; +import net.jpountz.lz4.LZ4BlockInputStream; +import net.jpountz.lz4.LZ4BlockOutputStream; + +import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; @@ -30,6 +45,7 @@ import java.net.URL; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.zip.GZIPInputStream; public class FaweSchematicHandler extends SchematicHandler { @Override @@ -62,10 +78,8 @@ public class FaweSchematicHandler extends SchematicHandler { ReadOnlyClipboard clipboard = ReadOnlyClipboard.of(editSession, region); Clipboard holder = new BlockArrayClipboard(region, clipboard); - // TODO FIXME -// com.sk89q.jnbt.CompoundTag weTag = SchematicWriter.writeTag(holder); -// CompoundTag tag = new CompoundTag((Map) (Map) weTag.getValue()); -// whenDone.run(tag); + CompressedSchematicTag tag = new CompressedSchematicTag(holder); + whenDone.run(tag); } }); } @@ -77,12 +91,29 @@ public class FaweSchematicHandler extends SchematicHandler { return false; } try { + PlotSquared.debug("Saving " + path); File tmp = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), path); + PlotSquared.debug(tmp); tmp.getParentFile().mkdirs(); - com.sk89q.jnbt.CompoundTag weTag = (com.sk89q.jnbt.CompoundTag) FaweCache.asTag(tag); - try (OutputStream stream = new FileOutputStream(tmp); NBTOutputStream output = new NBTOutputStream(new PGZIPOutputStream(stream))) { - Map map = weTag.getValue(); - output.writeNamedTag("Schematic", map.containsKey("Schematic") ? map.get("Schematic") : weTag); + if (tag instanceof CompressedCompoundTag) { + CompressedCompoundTag cTag = (CompressedCompoundTag) tag; + if (cTag instanceof CompressedSchematicTag) { + System.out.println("Write directly"); + Clipboard clipboard = (Clipboard) cTag.getSource(); + try (OutputStream stream = new FileOutputStream(tmp); NBTOutputStream output = new NBTOutputStream(new BufferedOutputStream(new PGZIPOutputStream(stream)))) { + new SpongeSchematicWriter(output).write(clipboard); + } + } else { + try (OutputStream stream = new FileOutputStream(tmp); BufferedOutputStream output = new BufferedOutputStream(new PGZIPOutputStream(stream))) { + DataInputStream is = cTag.adapt(cTag.getSource()); + IOUtil.copy(is, stream); + } + } + } else { + try (OutputStream stream = new FileOutputStream(tmp); NBTOutputStream output = new NBTOutputStream(new PGZIPOutputStream(stream))) { + Map map = tag.getValue(); + output.writeNamedTag("Schematic", map.containsKey("Schematic") ? map.get("Schematic") : tag); + } } } catch (FileNotFoundException e) { e.printStackTrace(); diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/CompoundTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/CompoundTag.java index 7b75a4642..a6b90ecb1 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/CompoundTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/CompoundTag.java @@ -27,7 +27,7 @@ import java.util.Map; /** * The {@code TAG_Compound} tag. */ -public final class CompoundTag extends Tag { +public class CompoundTag extends Tag { private final Map value; @@ -57,7 +57,7 @@ public final class CompoundTag extends Tag { * @return true if the tag contains the given key */ public boolean containsKey(String key) { - return value.containsKey(key); + return getValue().containsKey(key); } @Override @@ -94,7 +94,7 @@ public final class CompoundTag extends Tag { * @return a byte array */ public byte[] getByteArray(String key) { - Tag tag = value.get(key); + Tag tag = getValue().get(key); if (tag instanceof ByteArrayTag) { return ((ByteArrayTag) tag).getValue(); } else { @@ -112,7 +112,7 @@ public final class CompoundTag extends Tag { * @return a byte */ public byte getByte(String key) { - Tag tag = value.get(key); + Tag tag = getValue().get(key); if (tag instanceof ByteTag) { return ((ByteTag) tag).getValue(); } else { @@ -130,7 +130,7 @@ public final class CompoundTag extends Tag { * @return a double */ public double getDouble(String key) { - Tag tag = value.get(key); + Tag tag = getValue().get(key); if (tag instanceof DoubleTag) { return ((DoubleTag) tag).getValue(); } else { @@ -149,7 +149,7 @@ public final class CompoundTag extends Tag { * @return a double */ public double asDouble(String key) { - Tag tag = value.get(key); + Tag tag = getValue().get(key); if (tag instanceof ByteTag) { return ((ByteTag) tag).getValue(); @@ -183,7 +183,7 @@ public final class CompoundTag extends Tag { * @return a float */ public float getFloat(String key) { - Tag tag = value.get(key); + Tag tag = getValue().get(key); if (tag instanceof FloatTag) { return ((FloatTag) tag).getValue(); } else { @@ -201,7 +201,7 @@ public final class CompoundTag extends Tag { * @return an int array */ public int[] getIntArray(String key) { - Tag tag = value.get(key); + Tag tag = getValue().get(key); if (tag instanceof IntArrayTag) { return ((IntArrayTag) tag).getValue(); } else { @@ -219,7 +219,7 @@ public final class CompoundTag extends Tag { * @return an int */ public int getInt(String key) { - Tag tag = value.get(key); + Tag tag = getValue().get(key); if (tag instanceof IntTag) { return ((IntTag) tag).getValue(); } else { @@ -238,7 +238,7 @@ public final class CompoundTag extends Tag { * @return an int */ public int asInt(String key) { - Tag tag = value.get(key); + Tag tag = getValue().get(key); if (tag instanceof ByteTag) { return ((ByteTag) tag).getValue(); @@ -272,7 +272,7 @@ public final class CompoundTag extends Tag { * @return a list of tags */ public List getList(String key) { - Tag tag = value.get(key); + Tag tag = getValue().get(key); if (tag instanceof ListTag) { return ((ListTag) tag).getValue(); } else { @@ -290,7 +290,7 @@ public final class CompoundTag extends Tag { * @return a tag list instance */ public ListTag getListTag(String key) { - Tag tag = value.get(key); + Tag tag = getValue().get(key); if (tag instanceof ListTag) { return (ListTag) tag; } else { @@ -313,7 +313,7 @@ public final class CompoundTag extends Tag { */ @SuppressWarnings("unchecked") public List getList(String key, Class listType) { - Tag tag = value.get(key); + Tag tag = getValue().get(key); if (tag instanceof ListTag) { ListTag listTag = (ListTag) tag; if (listTag.getType().equals(listType)) { @@ -336,7 +336,7 @@ public final class CompoundTag extends Tag { * @return an int array */ public long[] getLongArray(String key) { - Tag tag = value.get(key); + Tag tag = getValue().get(key); if (tag instanceof LongArrayTag) { return ((LongArrayTag) tag).getValue(); } else { @@ -354,7 +354,7 @@ public final class CompoundTag extends Tag { * @return a long */ public long getLong(String key) { - Tag tag = value.get(key); + Tag tag = getValue().get(key); if (tag instanceof LongTag) { return ((LongTag) tag).getValue(); } else { @@ -373,7 +373,7 @@ public final class CompoundTag extends Tag { * @return a long */ public long asLong(String key) { - Tag tag = value.get(key); + Tag tag = getValue().get(key); if (tag instanceof ByteTag) { return ((ByteTag) tag).getValue(); @@ -407,7 +407,7 @@ public final class CompoundTag extends Tag { * @return a short */ public short getShort(String key) { - Tag tag = value.get(key); + Tag tag = getValue().get(key); if (tag instanceof ShortTag) { return ((ShortTag) tag).getValue(); } else { @@ -425,7 +425,7 @@ public final class CompoundTag extends Tag { * @return a string */ public String getString(String key) { - Tag tag = value.get(key); + Tag tag = getValue().get(key); if (tag instanceof StringTag) { return ((StringTag) tag).getValue(); } else { @@ -436,8 +436,8 @@ public final class CompoundTag extends Tag { @Override public String toString() { StringBuilder bldr = new StringBuilder(); - bldr.append("TAG_Compound").append(": ").append(value.size()).append(" entries\r\n{\r\n"); - for (Map.Entry entry : value.entrySet()) { + bldr.append("TAG_Compound").append(": ").append(getValue().size()).append(" entries\r\n{\r\n"); + for (Map.Entry entry : getValue().entrySet()) { bldr.append(" ").append(entry.getValue().toString().replaceAll("\r\n", "\r\n ")).append("\r\n"); } bldr.append("}"); diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/CompressedCompoundTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/CompressedCompoundTag.java new file mode 100644 index 000000000..6ce8b20f1 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/CompressedCompoundTag.java @@ -0,0 +1,42 @@ +package com.sk89q.jnbt; + +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +public abstract class CompressedCompoundTag extends CompoundTag { + private T in; + + public CompressedCompoundTag(T in) { + super(new HashMap<>()); + this.in = in; + } + + @Override + public Map getValue() { + if (in != null) decompress(); + return super.getValue(); + } + + public abstract DataInputStream adapt(T src) throws IOException; + + public T getSource() { + return in; + } + + private void decompress() { + try (NBTInputStream nbtIn = new NBTInputStream(adapt(in))) { + in = null; + CompoundTag tag = (CompoundTag) nbtIn.readTag(); + Map value = tag.getValue(); + Map raw = super.getValue(); + for (Map.Entry entry : value.entrySet()) { + raw.put(entry.getKey(), entry.getValue()); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/CompressedSchematicTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/CompressedSchematicTag.java new file mode 100644 index 000000000..bfdeb68ec --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/CompressedSchematicTag.java @@ -0,0 +1,33 @@ +package com.sk89q.jnbt; + +import com.boydti.fawe.object.io.FastByteArrayOutputStream; +import com.boydti.fawe.object.io.FastByteArraysInputStream; +import com.boydti.fawe.object.io.PGZIPOutputStream; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.extent.clipboard.io.SpongeSchematicWriter; +import net.jpountz.lz4.LZ4BlockInputStream; +import net.jpountz.lz4.LZ4BlockOutputStream; + +import java.io.DataInputStream; +import java.io.IOException; +import java.util.zip.GZIPInputStream; + +public class CompressedSchematicTag extends CompressedCompoundTag { + public CompressedSchematicTag(Clipboard holder) { + super(holder); + } + + @Override + public DataInputStream adapt(Clipboard src) throws IOException { + System.out.println("Decompress"); + FastByteArrayOutputStream blocksOut = new FastByteArrayOutputStream(); + try (LZ4BlockOutputStream lz4out = new LZ4BlockOutputStream(blocksOut)) { + NBTOutputStream nbtOut = new NBTOutputStream(lz4out); + new SpongeSchematicWriter(nbtOut).write(getSource()); + } catch (IOException e) { + throw new RuntimeException(e); + } + FastByteArraysInputStream in = new FastByteArraysInputStream(blocksOut.toByteArrays()); + return new DataInputStream(new LZ4BlockInputStream(in)); + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java index 74748983e..4cb2e13c5 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java @@ -216,12 +216,12 @@ public class SpongeSchematicReader extends NBTSchematicReader { }); streamer.readFully(); if (fc == null) setupClipboard(length * width * height, uuid); - else fc.setDimensions(BlockVector3.at(width, height, length)); + fc.setDimensions(BlockVector3.at(width, height, length)); BlockVector3 origin = min; CuboidRegion region; if (offsetX != Integer.MIN_VALUE && offsetY != Integer.MIN_VALUE && offsetZ != Integer.MIN_VALUE) { origin = origin.subtract(BlockVector3.at(offsetX, offsetY, offsetZ)); - region = new CuboidRegion(min, min.add(width, height, length).subtract(BlockVector3.ONE)); + region = new CuboidRegion(origin, origin.add(width, height, length).subtract(BlockVector3.ONE)); } else { region = new CuboidRegion(min, min.add(width, height, length).subtract(BlockVector3.ONE)); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java index 33ef02976..8fa8404f3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java @@ -91,7 +91,6 @@ public class SpongeSchematicWriter implements ClipboardWriter { if (length > MAX_SIZE) { throw new IllegalArgumentException("Length of region too large for a .schematic"); } -//<<<<<<< HEAD // output final DataOutput rawStream = outputStream.getOutputStream(); outputStream.writeLazyCompoundTag("Schematic", out -> {