diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV3.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV3.java index 55e249740..0e48f32d0 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV3.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV3.java @@ -41,6 +41,8 @@ import org.apache.logging.log4j.Logger; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinIntArrayTag; +import org.enginehub.linbus.tree.LinTagType; import org.jetbrains.annotations.ApiStatus; import java.io.BufferedInputStream; @@ -88,6 +90,7 @@ public class FastSchematicReaderV3 implements ClipboardReader { private VersionedDataFixer dataFixer; private BlockVector3 offset; + private BlockVector3 origin = BlockVector3.ZERO; private BlockState[] blockPalette; private BiomeType[] biomePalette; private int dataVersion = -1; @@ -137,6 +140,24 @@ public class FastSchematicReaderV3 implements ClipboardReader { this.dataVersion = this.dataInputStream.readInt(); this.dataFixer = ReaderUtil.getVersionedDataFixer(this.dataVersion, platform, platform.getDataVersion()); } + case "Metadata" -> { + LinCompoundTag metadataCompoundTag = + (LinCompoundTag) this.nbtInputStream.readTagPayload(NBTConstants.TYPE_COMPOUND, 0).toLinTag(); + + LinCompoundTag worldEditTag = metadataCompoundTag.findTag("WorldEdit", LinTagType.compoundTag()); + if (worldEditTag != null) { // allowed to be optional + LinIntArrayTag originTag = worldEditTag.findTag("Origin", LinTagType.intArrayTag()); + if (originTag != null) { // allowed to be optional + int[] parts = originTag.value(); + + if (parts.length != 3) { + throw new IOException("`Metadata > WorldEdit > Origin` int array length is invalid."); + } + + this.origin = BlockVector3.at(parts[0], parts[1], parts[2]); + } + } + } case "Offset" -> { this.dataInputStream.skipNBytes(4); // Array Length field (4 byte int) this.offset = BlockVector3.at( @@ -173,7 +194,7 @@ public class FastSchematicReaderV3 implements ClipboardReader { clipboard.setOrigin(this.offset.multiply(-1)); if (clipboard instanceof SimpleClipboard simpleClipboard && !this.offset.equals(BlockVector3.ZERO)) { - clipboard = new BlockArrayClipboard(simpleClipboard, this.offset); + clipboard = new BlockArrayClipboard(simpleClipboard, this.offset.add(this.origin)); } return clipboard; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV3Reader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV3Reader.java index 978cb8ba5..15032be82 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV3Reader.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV3Reader.java @@ -135,7 +135,7 @@ public class SpongeSchematicV3Reader implements ClipboardReader { Map palette = ReaderUtil.decodePalette(paletteObject, fixer); byte[] blocks = blockContainer.getTag("Data", LinTagType.byteArrayTag()).value(); - LinListTag blockEntities = blockContainer.getListTag("BlockEntities", LinTagType.compoundTag()); + LinListTag blockEntities = blockContainer.findListTag("BlockEntities", LinTagType.compoundTag()); ReaderUtil.initializeClipboardFromBlocks(clipboard, palette, blocks, blockEntities, fixer, true); }