Add support for schematics v3 output <3
This commit is contained in:
1 parent
a7204cceb7
commit
95ed2a8a85
3 files changed
+79
-25
No files matched your search
@@ -5,27 +5,20 @@ import io.ib67.sfcraft.ServerModule;
|
|||||||
import io.ib67.sfcraft.config.SFConfig;
|
import io.ib67.sfcraft.config.SFConfig;
|
||||||
import io.ib67.sfcraft.module.SignatureService;
|
import io.ib67.sfcraft.module.SignatureService;
|
||||||
import io.ib67.sfcraft.util.Helper;
|
import io.ib67.sfcraft.util.Helper;
|
||||||
import io.ib67.sfcraft.util.LitematicConverter;
|
import io.ib67.sfcraft.util.litematic.LitematicConverter;
|
||||||
|
import io.ib67.sfcraft.util.litematic.LitematicConverterV3;
|
||||||
import io.javalin.Javalin;
|
import io.javalin.Javalin;
|
||||||
import io.javalin.http.Context;
|
import io.javalin.http.Context;
|
||||||
import io.javalin.http.UploadedFile;
|
import io.javalin.http.UploadedFile;
|
||||||
import io.netty.buffer.Unpooled;
|
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import net.minecraft.nbt.NbtCompound;
|
|
||||||
import net.minecraft.nbt.NbtIo;
|
import net.minecraft.nbt.NbtIo;
|
||||||
import net.minecraft.nbt.NbtSizeTracker;
|
import net.minecraft.nbt.NbtSizeTracker;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ForkJoinPool;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
@Log4j2
|
@Log4j2
|
||||||
public class WebModule extends ServerModule {
|
public class WebModule extends ServerModule {
|
||||||
@@ -87,7 +80,7 @@ public class WebModule extends ServerModule {
|
|||||||
log.info("Saved " + fileName + " as a schematic.");
|
log.info("Saved " + fileName + " as a schematic.");
|
||||||
} else if (fileName.endsWith(".litematic")) {
|
} else if (fileName.endsWith(".litematic")) {
|
||||||
log.error("Handling new {}", fileName);
|
log.error("Handling new {}", fileName);
|
||||||
var converter = new LitematicConverter(
|
var converter = new LitematicConverterV3(
|
||||||
file.content(),
|
file.content(),
|
||||||
new NbtSizeTracker(config.maxSchematicSize, 16)
|
new NbtSizeTracker(config.maxSchematicSize, 16)
|
||||||
);
|
);
|
||||||
|
|||||||
+15
-15
@@ -1,4 +1,4 @@
|
|||||||
package io.ib67.sfcraft.util;
|
package io.ib67.sfcraft.util.litematic;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
@@ -6,8 +6,6 @@ import lombok.SneakyThrows;
|
|||||||
import net.minecraft.nbt.*;
|
import net.minecraft.nbt.*;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.PipedInputStream;
|
|
||||||
import java.io.PipedOutputStream;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -17,8 +15,8 @@ import java.util.stream.Collectors;
|
|||||||
* Uses {@link NbtCompound} from Minecraft.
|
* Uses {@link NbtCompound} from Minecraft.
|
||||||
*/
|
*/
|
||||||
public class LitematicConverter implements AutoCloseable {
|
public class LitematicConverter implements AutoCloseable {
|
||||||
private final InputStream input;
|
protected final InputStream input;
|
||||||
private final NbtSizeTracker sizeTracker;
|
protected final NbtSizeTracker sizeTracker;
|
||||||
|
|
||||||
public LitematicConverter(InputStream input, NbtSizeTracker sizeTracker) {
|
public LitematicConverter(InputStream input, NbtSizeTracker sizeTracker) {
|
||||||
this.input = input;
|
this.input = input;
|
||||||
@@ -41,7 +39,7 @@ public class LitematicConverter implements AutoCloseable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private NbtCompound convertRegionToSchematic(int dataVersion, NbtCompound region) {
|
protected NbtCompound convertRegionToSchematic(int dataVersion, NbtCompound region) {
|
||||||
var worldEditTag = new NbtCompound();
|
var worldEditTag = new NbtCompound();
|
||||||
|
|
||||||
// prepare metadata
|
// prepare metadata
|
||||||
@@ -69,7 +67,7 @@ public class LitematicConverter implements AutoCloseable {
|
|||||||
return schematicsRoot;
|
return schematicsRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
private SizeTuple readSizeTuple(NbtCompound region) {
|
protected SizeTuple readSizeTuple(NbtCompound region) {
|
||||||
var size = (NbtCompound) region.get("Size");
|
var size = (NbtCompound) region.get("Size");
|
||||||
var sizeX = size.getInt("x");
|
var sizeX = size.getInt("x");
|
||||||
var sizeY = size.getInt("y");
|
var sizeY = size.getInt("y");
|
||||||
@@ -77,27 +75,29 @@ public class LitematicConverter implements AutoCloseable {
|
|||||||
return new SizeTuple(sizeX, sizeY, sizeZ);
|
return new SizeTuple(sizeX, sizeY, sizeZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
private NbtList convertToWETileEntities(NbtList tileEntities) {
|
protected NbtList convertToWETileEntities(NbtList tileEntities) {
|
||||||
var weTEs = new NbtList();
|
var weTEs = new NbtList();
|
||||||
for (NbtElement _tileEntity : tileEntities) {
|
for (NbtElement _tileEntity : tileEntities) {
|
||||||
|
var weTE = new NbtCompound();
|
||||||
var tE = (NbtCompound) _tileEntity;
|
var tE = (NbtCompound) _tileEntity;
|
||||||
tE.putIntArray("Pos", new int[]{
|
weTE.putIntArray("Pos", new int[]{
|
||||||
tE.getInt("x"),
|
tE.getInt("x"),
|
||||||
tE.getInt("y"),
|
tE.getInt("y"),
|
||||||
tE.getInt("z")
|
tE.getInt("z")
|
||||||
});
|
});
|
||||||
tE.putString("Id", tE.getString("id"));
|
weTE.putString("Id", tE.getString("id"));
|
||||||
// other properties
|
// other properties
|
||||||
tE.remove("x");
|
tE.remove("x");
|
||||||
tE.remove("y");
|
tE.remove("y");
|
||||||
tE.remove("z");
|
tE.remove("z");
|
||||||
tE.remove("id");
|
tE.remove("id");
|
||||||
weTEs.add(tE);
|
weTE.put("Data",tE);
|
||||||
|
weTEs.add(weTE);
|
||||||
}
|
}
|
||||||
return weTEs;
|
return weTEs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private NbtCompound convertToWEPalette(NbtList paletteNbt) {
|
protected NbtCompound convertToWEPalette(NbtList paletteNbt) {
|
||||||
var wePalette = new NbtCompound();
|
var wePalette = new NbtCompound();
|
||||||
for (int i = 0; i < paletteNbt.size(); i++) {
|
for (int i = 0; i < paletteNbt.size(); i++) {
|
||||||
var entry = (NbtCompound) paletteNbt.get(i);
|
var entry = (NbtCompound) paletteNbt.get(i);
|
||||||
@@ -117,7 +117,7 @@ public class LitematicConverter implements AutoCloseable {
|
|||||||
return wePalette;
|
return wePalette;
|
||||||
}
|
}
|
||||||
|
|
||||||
private NbtElement convertToWeMeta(SizeTuple size, NbtCompound region) {
|
protected NbtElement convertToWeMeta(SizeTuple size, NbtCompound region) {
|
||||||
var pos = (NbtCompound) region.get("Position");
|
var pos = (NbtCompound) region.get("Position");
|
||||||
var nbt = new NbtCompound();
|
var nbt = new NbtCompound();
|
||||||
nbt.putInt("WEOffsetX", pos.getInt("x") + (size.x < 0 ? size.x + 1 : 0));
|
nbt.putInt("WEOffsetX", pos.getInt("x") + (size.x < 0 ? size.x + 1 : 0));
|
||||||
@@ -126,7 +126,7 @@ public class LitematicConverter implements AutoCloseable {
|
|||||||
return nbt;
|
return nbt;
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] convertToWEBlocks(int totalBlocks, NbtCompound region) {
|
protected byte[] convertToWEBlocks(int totalBlocks, NbtCompound region) {
|
||||||
var buf = Unpooled.buffer();
|
var buf = Unpooled.buffer();
|
||||||
var blockStates = region.getLongArray("BlockStates");
|
var blockStates = region.getLongArray("BlockStates");
|
||||||
|
|
||||||
@@ -162,7 +162,7 @@ public class LitematicConverter implements AutoCloseable {
|
|||||||
return buf.array();
|
return buf.array();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int writeBlocks(ByteBuf buf, short block) {
|
protected static int writeBlocks(ByteBuf buf, short block) {
|
||||||
int b = block >>> 7;
|
int b = block >>> 7;
|
||||||
if (b == 0) {
|
if (b == 0) {
|
||||||
buf.writeByte(block);
|
buf.writeByte(block);
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package io.ib67.sfcraft.util.litematic;
|
||||||
|
|
||||||
|
import net.minecraft.nbt.NbtCompound;
|
||||||
|
import net.minecraft.nbt.NbtElement;
|
||||||
|
import net.minecraft.nbt.NbtSizeTracker;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
public class LitematicConverterV3 extends LitematicConverter {
|
||||||
|
public LitematicConverterV3(InputStream input, NbtSizeTracker sizeTracker) {
|
||||||
|
super(input, sizeTracker);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NbtCompound convertRegionToSchematic(int dataVersion, NbtCompound region) {
|
||||||
|
var schematicsTag = new NbtCompound();
|
||||||
|
|
||||||
|
// prepare metadata
|
||||||
|
var size = readSizeTuple(region);
|
||||||
|
schematicsTag.put("Metadata", convertToWeMeta(size, region));
|
||||||
|
schematicsTag.putInt("DataVersion", dataVersion);
|
||||||
|
schematicsTag.putInt("Version", 3);
|
||||||
|
schematicsTag.putIntArray("Offset", new int[3]);
|
||||||
|
|
||||||
|
// dimensional data.
|
||||||
|
schematicsTag.putShort("Height", (short) Math.abs(size.y()));
|
||||||
|
schematicsTag.putShort("Length", (short) Math.abs(size.z()));
|
||||||
|
schematicsTag.putShort("Width", (short) Math.abs(size.x()));
|
||||||
|
|
||||||
|
// block & tile entities
|
||||||
|
var paletteNbt = region.getList("BlockStatePalette", NbtElement.COMPOUND_TYPE);
|
||||||
|
var wePalette = convertToWEPalette(paletteNbt);
|
||||||
|
var tileEntities = region.getList("TileEntities", NbtElement.COMPOUND_TYPE);
|
||||||
|
|
||||||
|
var blocksNbt = new NbtCompound();
|
||||||
|
blocksNbt.put("Palette", wePalette);
|
||||||
|
blocksNbt.putByteArray("Data", convertToWEBlocks(Math.abs(size.x() * size.y() * size.z()), region));
|
||||||
|
blocksNbt.put("BlockEntities", convertToWETileEntities(tileEntities));
|
||||||
|
|
||||||
|
schematicsTag.put("Blocks", blocksNbt);
|
||||||
|
var schematicsRoot = new NbtCompound();
|
||||||
|
schematicsRoot.put("Schematic", schematicsTag);
|
||||||
|
return schematicsRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected NbtElement convertToWeMeta(SizeTuple size, NbtCompound region) {
|
||||||
|
var pos = (NbtCompound) region.get("Position");
|
||||||
|
var worldEditNbt = new NbtCompound();
|
||||||
|
worldEditNbt.putIntArray("Origin", new int[]{
|
||||||
|
pos.getInt("x") + (size.x() < 0 ? size.x() + 1 : 0),
|
||||||
|
pos.getInt("y") + (size.y() < 0 ? size.y() + 1 : 0),
|
||||||
|
pos.getInt("z") + (size.z() < 0 ? size.z() + 1 : 0)
|
||||||
|
});
|
||||||
|
var Metadata = new NbtCompound();
|
||||||
|
Metadata.put("WorldEdit", worldEditNbt);
|
||||||
|
Metadata.putLong("Date", System.currentTimeMillis());
|
||||||
|
|
||||||
|
return Metadata;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user