From c35cd6e8167e954d8f4b14f02ee11703002360bc Mon Sep 17 00:00:00 2001 From: Pierre Maurice Schwang Date: Mon, 10 Jun 2024 21:03:42 +0200 Subject: [PATCH] fix: make FastSchematicWriterV3 work --- .../FaweDelegateSchematicHandler.java | 6 +- .../clipboard/io/FastSchematicWriterV3.java | 66 +++++++++++-------- .../clipboard/io/BuiltInClipboardFormat.java | 30 +++++++++ 3 files changed, 71 insertions(+), 31 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/FaweDelegateSchematicHandler.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/FaweDelegateSchematicHandler.java index c9379d788..9c9cc3612 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/FaweDelegateSchematicHandler.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/FaweDelegateSchematicHandler.java @@ -29,7 +29,7 @@ import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat; import com.sk89q.worldedit.extent.clipboard.io.MCEditSchematicReader; -import com.sk89q.worldedit.extent.clipboard.io.SpongeSchematicReader; +import com.sk89q.worldedit.extent.clipboard.io.sponge.SpongeSchematicV3Reader; import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; @@ -249,8 +249,8 @@ public class FaweDelegateSchematicHandler { return null; } try { - SpongeSchematicReader schematicReader = - new SpongeSchematicReader(new NBTInputStream(new GZIPInputStream(is))); + SpongeSchematicV3Reader schematicReader = + new SpongeSchematicV3Reader(new NBTInputStream(new GZIPInputStream(is))); Clipboard clip = schematicReader.read(); return new Schematic(clip); } catch (IOException e2) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriterV3.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriterV3.java index 62ad65776..2addc67bd 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriterV3.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriterV3.java @@ -25,6 +25,7 @@ import net.jpountz.lz4.LZ4BlockOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.DataOutput; import java.io.IOException; import java.util.Arrays; import java.util.Iterator; @@ -89,9 +90,9 @@ public class FastSchematicWriterV3 implements ClipboardWriter { ); schematic.writeLazyCompoundTag("Metadata", out -> this.writeMetadata(out, clipboard)); - schematic.writeNamedTag("Width", region.getWidth()); - schematic.writeNamedTag("Height", region.getHeight()); - schematic.writeNamedTag("Length", region.getLength()); + schematic.writeNamedTag("Width", (short) region.getWidth()); + schematic.writeNamedTag("Height", (short) region.getHeight()); + schematic.writeNamedTag("Length", (short) region.getLength()); schematic.writeNamedTag("Offset", new int[]{ offset.x(), offset.y(), offset.z() @@ -115,8 +116,9 @@ public class FastSchematicWriterV3 implements ClipboardWriter { private void writeBlocks(NBTOutputStream blocks, Clipboard clipboard) throws IOException { final int[] tiles = new int[]{0}; - try (ByteArrayOutputStream tileBytes = new ByteArrayOutputStream(); - NBTOutputStream tileOut = new NBTOutputStream(new LZ4BlockOutputStream(tileBytes))) { + final ByteArrayOutputStream tileBytes = new ByteArrayOutputStream(); + try (LZ4BlockOutputStream lz4Stream = new LZ4BlockOutputStream(tileBytes); + NBTOutputStream tileOut = new NBTOutputStream(lz4Stream)) { this.writePalette( blocks, BlockTypesCache.states.length, @@ -149,7 +151,8 @@ public class FastSchematicWriterV3 implements ClipboardWriter { BlockStateHolder::getAsString, clipboard ); - + lz4Stream.finish(); + } finally { // Write Tiles if (tiles[0] > 0) { blocks.writeNamedTagName("BlockEntities", NBTConstants.TYPE_LIST); @@ -173,27 +176,27 @@ public class FastSchematicWriterV3 implements ClipboardWriter { ); } - private void writeEntity(NBTOutputStream blocks, Clipboard clipboard, Entity entity) throws IOException { + private void writeEntity(NBTOutputStream out, Clipboard clipboard, Entity entity) throws IOException { final BaseEntity state = entity.getState(); if (state == null) { - return; + throw new IOException("Entity has no state"); } - blocks.writeNamedTag("Id", state.getType().id()); + out.writeNamedTag("Id", state.getType().id()); - blocks.writeNamedTagName("Pos", NBTConstants.TYPE_LIST); - blocks.write(NBTConstants.TYPE_FLOAT); - blocks.write(3); - blocks.writeFloat((float) entity.getLocation().x() - clipboard.getMinimumPoint().x()); - blocks.writeFloat((float) entity.getLocation().y() - clipboard.getMinimumPoint().y()); - blocks.writeFloat((float) entity.getLocation().z() - clipboard.getMinimumPoint().z()); + out.writeNamedTagName("Pos", NBTConstants.TYPE_LIST); + out.write(NBTConstants.TYPE_FLOAT); + out.writeInt(3); + out.writeFloat((float) entity.getLocation().x() - clipboard.getMinimumPoint().x()); + out.writeFloat((float) entity.getLocation().y() - clipboard.getMinimumPoint().y()); + out.writeFloat((float) entity.getLocation().z() - clipboard.getMinimumPoint().z()); - blocks.writeLazyCompoundTag("Data", data -> { + out.writeLazyCompoundTag("Data", data -> { CompoundTag nbt = state.getNbtData(); if (nbt != null) { - final Map value = nbt.getValue(); - value.remove("id"); - value.remove("Rotation"); - value.forEach((s, tag) -> { + nbt.getValue().forEach((s, tag) -> { + if (s.equals("id") || s.equals("Rotation")) { + return; + } try { data.writeNamedTag(s, tag); } catch (IOException e) { @@ -205,10 +208,12 @@ public class FastSchematicWriterV3 implements ClipboardWriter { // Write rotation list data.writeNamedTagName("Rotation", NBTConstants.TYPE_LIST); data.write(NBTConstants.TYPE_FLOAT); - data.write(2); + data.writeInt(2); data.writeFloat(entity.getLocation().getYaw()); data.writeFloat(entity.getLocation().getPitch()); }); + + out.write(NBTConstants.TYPE_END); // End the compound } private void writePalette( @@ -219,8 +224,8 @@ public class FastSchematicWriterV3 implements ClipboardWriter { Clipboard clipboard ) throws IOException { int dataBytesUsed = 0; - try (ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - LZ4BlockOutputStream dataOut = new LZ4BlockOutputStream(bytes)) { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + try (LZ4BlockOutputStream dataOut = new LZ4BlockOutputStream(bytes)) { int index = 0; char[] palette = new char[capacity]; Arrays.fill(palette, Character.MAX_VALUE); @@ -244,15 +249,20 @@ public class FastSchematicWriterV3 implements ClipboardWriter { dataOut.write(value & 127 | 128); value >>>= 7; } + dataOut.write(value); + dataBytesUsed++; } // End Palette tag out.write(NBTConstants.TYPE_END); - + dataOut.finish(); + } finally { // Write Data tag - try (LZ4BlockInputStream reader = new LZ4BlockInputStream(new ByteArrayInputStream(bytes.toByteArray()))) { - out.writeNamedTagName("Data", NBTConstants.TYPE_BYTE_ARRAY); - out.writeInt(dataBytesUsed); - IOUtil.copy(reader, dataOut); + if (dataBytesUsed > 0) { + try (LZ4BlockInputStream reader = new LZ4BlockInputStream(new ByteArrayInputStream(bytes.toByteArray()))) { + out.writeNamedTagName("Data", NBTConstants.TYPE_BYTE_ARRAY); + out.writeInt(dataBytesUsed); + IOUtil.copy(reader, (DataOutput) out); + } } } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java index 334eb2aeb..2d060c8c3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java @@ -21,6 +21,7 @@ package com.sk89q.worldedit.extent.clipboard.io; import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicReaderV2; import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicWriterV2; +import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicWriterV3; import com.fastasyncworldedit.core.extent.clipboard.io.schematic.MinecraftStructure; import com.fastasyncworldedit.core.extent.clipboard.io.schematic.PNGWriter; import com.fastasyncworldedit.core.internal.io.ResettableFileInputStream; @@ -57,6 +58,35 @@ import java.util.zip.GZIPOutputStream; public enum BuiltInClipboardFormat implements ClipboardFormat { //FAWE start - register fast clipboard io + FAST_NEW("new_fast") { // For testing purposes + @Override + public ClipboardReader getReader(final InputStream inputStream) throws IOException { + return SPONGE_V3_SCHEMATIC.getReader(inputStream); + } + + @Override + public ClipboardWriter getWriter(OutputStream outputStream) throws IOException { + OutputStream gzip; + if (outputStream instanceof ParallelGZIPOutputStream || outputStream instanceof GZIPOutputStream) { + gzip = outputStream; + } else { + outputStream = new BufferedOutputStream(outputStream); + gzip = new ParallelGZIPOutputStream(outputStream); + } + NBTOutputStream nbtStream = new NBTOutputStream(new BufferedOutputStream(gzip)); + return new FastSchematicWriterV3(nbtStream); + } + + @Override + public boolean isFormat(final File file) { + return FAST.isFormat(file); + } + + @Override + public String getPrimaryFileExtension() { + return FAST.getPrimaryFileExtension(); + } + }, FAST("fast", "fawe", "sponge", "schem") { @Override public String getPrimaryFileExtension() {