From 01ade09b9f9d23b26e7912ea6ce09388a07475bf Mon Sep 17 00:00:00 2001 From: Pierre Maurice Schwang Date: Sun, 30 Jun 2024 02:23:28 +0200 Subject: [PATCH] chore: check for magic bytes in schematic (not tested yet) --- .../clipboard/io/FastSchematicWriterV2.java | 2 +- .../clipboard/io/BuiltInClipboardFormat.java | 37 ++++++++++++++++++- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriterV2.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriterV2.java index f0b688ff8..3bd302876 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriterV2.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriterV2.java @@ -103,11 +103,11 @@ public class FastSchematicWriterV2 implements ClipboardWriter { final DataOutput rawStream = outputStream.getOutputStream(); outputStream.writeLazyCompoundTag("Schematic", out -> { + out.writeNamedTag("Version", CURRENT_VERSION); out.writeNamedTag( "DataVersion", WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion() ); - out.writeNamedTag("Version", CURRENT_VERSION); out.writeNamedTag("Width", (short) width); out.writeNamedTag("Height", (short) height); out.writeNamedTag("Length", (short) length); 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 8a57411d6..98bd975bd 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 @@ -50,6 +50,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.Arrays; import java.util.Locale; import java.util.Set; import java.util.zip.GZIPInputStream; @@ -83,8 +84,13 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { @Override public boolean isFormat(final InputStream inputStream) { - try (final DataInputStream stream = new DataInputStream(new FastBufferedInputStream(new GZIPInputStream(inputStream))); + try (final DataInputStream stream = new DataInputStream(new BufferedInputStream(new GZIPInputStream(inputStream))); final NBTInputStream nbt = new NBTInputStream(stream)) { + stream.mark(SPONGE_V3_MAGIC.length); + if (Arrays.equals(stream.readNBytes(SPONGE_V3_MAGIC.length), SPONGE_V3_MAGIC)) { + return stream.readInt() == FastSchematicWriterV3.CURRENT_VERSION; + } + stream.reset(); if (stream.readByte() != NBTConstants.TYPE_COMPOUND) { return false; } @@ -394,10 +400,37 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { }; //FAWE end + private static final byte[] SPONGE_V2_MAGIC = new byte[]{ + 0x10, // TAG_Compound + 0x00, 0x09, // len("Schematic") - unsigned short + 0x53, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x74, 0x69, 0x63, // "Schematic" (modified UTF-8) + 0x03, // TAG_INT + 0x00, 0x07, // len("Version") - unsigned short + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E // "Version" (modified UTF-8) + }; + + private static final byte[] SPONGE_V3_MAGIC = new byte[]{ + 0x10, // TAG_Compound + 0x00, 0x00, // len("") - unsigned short (no following bytes for string because there is none) + 0x10, // TAG_Compound + 0x00, 0x09, // len("Schematic") - unsigned short + 0x53, 0x63, 0x68, 0x65, 0x6D, 0x61, 0x74, 0x69, 0x63, // "Schematic" (modified UTF-8) + 0x03, // TAG_INT + 0x00, 0x07, // len("Version") - unsigned short + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E // "Version" (modified UTF-8) + }; + private static boolean detectOldSpongeSchematic(InputStream inputStream, int version) { //FAWE start - dont utilize linbus - WorldEdit approach is not really streamed - try (final DataInputStream stream = new DataInputStream(new FastBufferedInputStream(new GZIPInputStream(inputStream))); + try (final DataInputStream stream = new DataInputStream(new BufferedInputStream(new GZIPInputStream(inputStream))); final NBTInputStream nbt = new NBTInputStream(stream)) { + stream.mark(SPONGE_V2_MAGIC.length); + // If magic sequence found, return early (schematic was created by FAWE) + if (Arrays.equals(stream.readNBytes(SPONGE_V2_MAGIC.length), SPONGE_V2_MAGIC)) { + return stream.readInt() == version; + } + stream.reset(); + if (stream.readByte() != NBTConstants.TYPE_COMPOUND) { return false; }