From 5dfe71a82e38ff6fe8c0ea6b67e5bf904dd5f19d Mon Sep 17 00:00:00 2001 From: Ktilis Date: Sat, 3 Jan 2026 16:03:21 +0500 Subject: [PATCH 1/2] Fix: cannot load worldedit schem file --- .../api/file/BuiltInWorldFileType.java | 1 + .../limboapi/file/WorldEditSchemFile.java | 5 + .../limboapi/file/WorldEditSchemNewFile.java | 93 +++++++++++++++++++ .../limboapi/file/WorldFileTypeRegistry.java | 1 + 4 files changed, 100 insertions(+) create mode 100644 plugin/src/main/java/net/elytrium/limboapi/file/WorldEditSchemNewFile.java diff --git a/api/src/main/java/net/elytrium/limboapi/api/file/BuiltInWorldFileType.java b/api/src/main/java/net/elytrium/limboapi/api/file/BuiltInWorldFileType.java index 35da4502..4c4818ea 100644 --- a/api/src/main/java/net/elytrium/limboapi/api/file/BuiltInWorldFileType.java +++ b/api/src/main/java/net/elytrium/limboapi/api/file/BuiltInWorldFileType.java @@ -10,5 +10,6 @@ public enum BuiltInWorldFileType { SCHEMATIC, WORLDEDIT_SCHEM, + WORLDEDIT_SCHEM_NEW, STRUCTURE } diff --git a/plugin/src/main/java/net/elytrium/limboapi/file/WorldEditSchemFile.java b/plugin/src/main/java/net/elytrium/limboapi/file/WorldEditSchemFile.java index 6c2fa9c6..30b785c7 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/file/WorldEditSchemFile.java +++ b/plugin/src/main/java/net/elytrium/limboapi/file/WorldEditSchemFile.java @@ -39,6 +39,11 @@ public class WorldEditSchemFile implements WorldFile { private final ListBinaryTag blockEntities; public WorldEditSchemFile(CompoundBinaryTag tag) { + // Check is it new worldedit schema + if (!tag.contains("Width")) { + throw new IllegalArgumentException("Invalid worldedit file format. Try using WORLDEDIT_SCHEM_NEW instead."); + } + this.width = tag.getShort("Width"); this.height = tag.getShort("Height"); this.length = tag.getShort("Length"); diff --git a/plugin/src/main/java/net/elytrium/limboapi/file/WorldEditSchemNewFile.java b/plugin/src/main/java/net/elytrium/limboapi/file/WorldEditSchemNewFile.java new file mode 100644 index 00000000..85438dae --- /dev/null +++ b/plugin/src/main/java/net/elytrium/limboapi/file/WorldEditSchemNewFile.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2021 - 2025 Elytrium + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package net.elytrium.limboapi.file; + +import com.velocitypowered.proxy.protocol.ProtocolUtils; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import net.elytrium.limboapi.api.LimboFactory; +import net.elytrium.limboapi.api.chunk.VirtualBlock; +import net.elytrium.limboapi.api.chunk.VirtualWorld; +import net.elytrium.limboapi.api.file.WorldFile; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.IntBinaryTag; +import net.kyori.adventure.nbt.ListBinaryTag; + +public class WorldEditSchemNewFile implements WorldFile { + + private final short width; + private final short height; + private final short length; + private final int[] blocks; + private final CompoundBinaryTag palette; + private final ListBinaryTag blockEntities; + + public WorldEditSchemNewFile(CompoundBinaryTag rootTag) { + CompoundBinaryTag schematicTag = rootTag.getCompound("Schematic"); + + // Check is it old or newer worldedit schema + if (!schematicTag.contains("Width")) { + throw new IllegalArgumentException("Invalid worldedit file format. Try using WORLDEDIT_SCHEM instead or open an issue on GitHub."); + } + + this.width = schematicTag.getShort("Width"); + this.height = schematicTag.getShort("Height"); + this.length = schematicTag.getShort("Length"); + + CompoundBinaryTag blocksTag = schematicTag.getCompound("Blocks"); + this.palette = blocksTag.getCompound("Palette"); + + ByteBuf blockDataBuf = Unpooled.wrappedBuffer(blocksTag.getByteArray("Data")); + this.blocks = new int[this.width * this.height * this.length]; + + for (int i = 0; i < this.blocks.length; i++) { + this.blocks[i] = ProtocolUtils.readVarInt(blockDataBuf); + } + + this.blockEntities = blocksTag.getList("BlockEntities"); + } + + @Override + public void toWorld(LimboFactory factory, VirtualWorld world, int offsetX, int offsetY, int offsetZ, int lightLevel) { + VirtualBlock[] palettedBlocks = new VirtualBlock[this.palette.keySet().size()]; + this.palette.forEach((entry) -> palettedBlocks[((IntBinaryTag) entry.getValue()).value()] = factory.createSimpleBlock(entry.getKey())); + + for (int posX = 0; posX < this.width; ++posX) { + for (int posY = 0; posY < this.height; ++posY) { + for (int posZ = 0; posZ < this.length; ++posZ) { + int index = (posY * this.length + posZ) * this.width + posX; + world.setBlock(posX + offsetX, posY + offsetY, posZ + offsetZ, palettedBlocks[this.blocks[index]]); + } + } + } + + for (BinaryTag blockEntity : this.blockEntities) { + CompoundBinaryTag blockEntityData = (CompoundBinaryTag) blockEntity; + int[] posTag = blockEntityData.getIntArray("Pos"); + world.setBlockEntity( + offsetX + posTag[0], + offsetY + posTag[1], + offsetZ + posTag[2], + blockEntityData, + factory.getBlockEntity(blockEntityData.getString("Id"))); + } + + world.fillSkyLight(lightLevel); + } +} diff --git a/plugin/src/main/java/net/elytrium/limboapi/file/WorldFileTypeRegistry.java b/plugin/src/main/java/net/elytrium/limboapi/file/WorldFileTypeRegistry.java index caca2e4d..91de6742 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/file/WorldFileTypeRegistry.java +++ b/plugin/src/main/java/net/elytrium/limboapi/file/WorldFileTypeRegistry.java @@ -30,6 +30,7 @@ public enum WorldFileTypeRegistry { SCHEMATIC(BuiltInWorldFileType.SCHEMATIC, MCEditSchematicFile::new), WORLDEDIT_SCHEM(BuiltInWorldFileType.WORLDEDIT_SCHEM, WorldEditSchemFile::new), + WORLDEDIT_SCHEM_NEW(BuiltInWorldFileType.WORLDEDIT_SCHEM_NEW, WorldEditSchemNewFile::new), STRUCTURE(BuiltInWorldFileType.STRUCTURE, StructureNbtFile::new); private static final EnumMap API_TYPE_MAP = new EnumMap<>(BuiltInWorldFileType.class); From ffddc6e0291ccd04d0cbb44b46b6ad04ec7e8f15 Mon Sep 17 00:00:00 2001 From: Ktilis Date: Tue, 6 Jan 2026 01:30:48 +0500 Subject: [PATCH 2/2] Fix: cannot load worldedit schem file - fit into one file --- .../api/file/BuiltInWorldFileType.java | 1 - .../limboapi/file/WorldEditSchemFile.java | 45 ++++++--- .../limboapi/file/WorldEditSchemNewFile.java | 93 ------------------- .../limboapi/file/WorldFileTypeRegistry.java | 1 - 4 files changed, 32 insertions(+), 108 deletions(-) delete mode 100644 plugin/src/main/java/net/elytrium/limboapi/file/WorldEditSchemNewFile.java diff --git a/api/src/main/java/net/elytrium/limboapi/api/file/BuiltInWorldFileType.java b/api/src/main/java/net/elytrium/limboapi/api/file/BuiltInWorldFileType.java index 4c4818ea..35da4502 100644 --- a/api/src/main/java/net/elytrium/limboapi/api/file/BuiltInWorldFileType.java +++ b/api/src/main/java/net/elytrium/limboapi/api/file/BuiltInWorldFileType.java @@ -10,6 +10,5 @@ public enum BuiltInWorldFileType { SCHEMATIC, WORLDEDIT_SCHEM, - WORLDEDIT_SCHEM_NEW, STRUCTURE } diff --git a/plugin/src/main/java/net/elytrium/limboapi/file/WorldEditSchemFile.java b/plugin/src/main/java/net/elytrium/limboapi/file/WorldEditSchemFile.java index 30b785c7..da75bf00 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/file/WorldEditSchemFile.java +++ b/plugin/src/main/java/net/elytrium/limboapi/file/WorldEditSchemFile.java @@ -38,25 +38,44 @@ public class WorldEditSchemFile implements WorldFile { private final CompoundBinaryTag palette; private final ListBinaryTag blockEntities; - public WorldEditSchemFile(CompoundBinaryTag tag) { - // Check is it new worldedit schema - if (!tag.contains("Width")) { - throw new IllegalArgumentException("Invalid worldedit file format. Try using WORLDEDIT_SCHEM_NEW instead."); - } + public WorldEditSchemFile(CompoundBinaryTag rootTag) { - this.width = tag.getShort("Width"); - this.height = tag.getShort("Height"); - this.length = tag.getShort("Length"); - this.palette = tag.getCompound("Palette"); + ByteBuf blockDataBuf; - ByteBuf blockDataBuf = Unpooled.wrappedBuffer(tag.getByteArray("BlockData")); - this.blocks = new int[this.width * this.height * this.length]; + if (rootTag.contains("Width")) { + // Check is it old worldedit schema + this.width = rootTag.getShort("Width"); + this.height = rootTag.getShort("Height"); + this.length = rootTag.getShort("Length"); + this.palette = rootTag.getCompound("Palette"); + + blockDataBuf = Unpooled.wrappedBuffer(rootTag.getByteArray("BlockData")); + + this.blockEntities = rootTag.getList("BlockEntities"); + + } else if (rootTag.getCompound("Schematic").contains("Blocks")) { + // Check is it new worldedit schema + CompoundBinaryTag schematicTag = rootTag.getCompound("Schematic"); + + this.width = schematicTag.getShort("Width"); + this.height = schematicTag.getShort("Height"); + this.length = schematicTag.getShort("Length"); + CompoundBinaryTag blocksTag = schematicTag.getCompound("Blocks"); + this.palette = blocksTag.getCompound("Palette"); + + blockDataBuf = Unpooled.wrappedBuffer(blocksTag.getByteArray("Data")); + + this.blockEntities = blocksTag.getList("BlockEntities"); + } else { + // Unknown schema, throw exception + throw new IllegalArgumentException("Invalid worldedit file format. Please open an issue on GitHub."); + } + + this.blocks = new int[this.width * this.height * this.length]; for (int i = 0; i < this.blocks.length; i++) { this.blocks[i] = ProtocolUtils.readVarInt(blockDataBuf); } - - this.blockEntities = tag.getList("BlockEntities"); } @Override diff --git a/plugin/src/main/java/net/elytrium/limboapi/file/WorldEditSchemNewFile.java b/plugin/src/main/java/net/elytrium/limboapi/file/WorldEditSchemNewFile.java deleted file mode 100644 index 85438dae..00000000 --- a/plugin/src/main/java/net/elytrium/limboapi/file/WorldEditSchemNewFile.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2021 - 2025 Elytrium - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package net.elytrium.limboapi.file; - -import com.velocitypowered.proxy.protocol.ProtocolUtils; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import net.elytrium.limboapi.api.LimboFactory; -import net.elytrium.limboapi.api.chunk.VirtualBlock; -import net.elytrium.limboapi.api.chunk.VirtualWorld; -import net.elytrium.limboapi.api.file.WorldFile; -import net.kyori.adventure.nbt.BinaryTag; -import net.kyori.adventure.nbt.CompoundBinaryTag; -import net.kyori.adventure.nbt.IntBinaryTag; -import net.kyori.adventure.nbt.ListBinaryTag; - -public class WorldEditSchemNewFile implements WorldFile { - - private final short width; - private final short height; - private final short length; - private final int[] blocks; - private final CompoundBinaryTag palette; - private final ListBinaryTag blockEntities; - - public WorldEditSchemNewFile(CompoundBinaryTag rootTag) { - CompoundBinaryTag schematicTag = rootTag.getCompound("Schematic"); - - // Check is it old or newer worldedit schema - if (!schematicTag.contains("Width")) { - throw new IllegalArgumentException("Invalid worldedit file format. Try using WORLDEDIT_SCHEM instead or open an issue on GitHub."); - } - - this.width = schematicTag.getShort("Width"); - this.height = schematicTag.getShort("Height"); - this.length = schematicTag.getShort("Length"); - - CompoundBinaryTag blocksTag = schematicTag.getCompound("Blocks"); - this.palette = blocksTag.getCompound("Palette"); - - ByteBuf blockDataBuf = Unpooled.wrappedBuffer(blocksTag.getByteArray("Data")); - this.blocks = new int[this.width * this.height * this.length]; - - for (int i = 0; i < this.blocks.length; i++) { - this.blocks[i] = ProtocolUtils.readVarInt(blockDataBuf); - } - - this.blockEntities = blocksTag.getList("BlockEntities"); - } - - @Override - public void toWorld(LimboFactory factory, VirtualWorld world, int offsetX, int offsetY, int offsetZ, int lightLevel) { - VirtualBlock[] palettedBlocks = new VirtualBlock[this.palette.keySet().size()]; - this.palette.forEach((entry) -> palettedBlocks[((IntBinaryTag) entry.getValue()).value()] = factory.createSimpleBlock(entry.getKey())); - - for (int posX = 0; posX < this.width; ++posX) { - for (int posY = 0; posY < this.height; ++posY) { - for (int posZ = 0; posZ < this.length; ++posZ) { - int index = (posY * this.length + posZ) * this.width + posX; - world.setBlock(posX + offsetX, posY + offsetY, posZ + offsetZ, palettedBlocks[this.blocks[index]]); - } - } - } - - for (BinaryTag blockEntity : this.blockEntities) { - CompoundBinaryTag blockEntityData = (CompoundBinaryTag) blockEntity; - int[] posTag = blockEntityData.getIntArray("Pos"); - world.setBlockEntity( - offsetX + posTag[0], - offsetY + posTag[1], - offsetZ + posTag[2], - blockEntityData, - factory.getBlockEntity(blockEntityData.getString("Id"))); - } - - world.fillSkyLight(lightLevel); - } -} diff --git a/plugin/src/main/java/net/elytrium/limboapi/file/WorldFileTypeRegistry.java b/plugin/src/main/java/net/elytrium/limboapi/file/WorldFileTypeRegistry.java index 91de6742..caca2e4d 100644 --- a/plugin/src/main/java/net/elytrium/limboapi/file/WorldFileTypeRegistry.java +++ b/plugin/src/main/java/net/elytrium/limboapi/file/WorldFileTypeRegistry.java @@ -30,7 +30,6 @@ public enum WorldFileTypeRegistry { SCHEMATIC(BuiltInWorldFileType.SCHEMATIC, MCEditSchematicFile::new), WORLDEDIT_SCHEM(BuiltInWorldFileType.WORLDEDIT_SCHEM, WorldEditSchemFile::new), - WORLDEDIT_SCHEM_NEW(BuiltInWorldFileType.WORLDEDIT_SCHEM_NEW, WorldEditSchemNewFile::new), STRUCTURE(BuiltInWorldFileType.STRUCTURE, StructureNbtFile::new); private static final EnumMap API_TYPE_MAP = new EnumMap<>(BuiltInWorldFileType.class);