Skip to content

Instantly share code, notes, and snippets.

@syuchan1005
Created November 19, 2016 09:21
Show Gist options
  • Save syuchan1005/739d4c189b52a4e060f86857911ecb02 to your computer and use it in GitHub Desktop.
Save syuchan1005/739d4c189b52a4e060f86857911ecb02 to your computer and use it in GitHub Desktop.
Convert .nbt file generated by structure block
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;
import org.bukkit.Bukkit;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* Created by syuchan on 2016/11/19.
*/
@Getter
@ToString
public class NBTFile {
private File nbtFile;
private List<BlockStats> blocks = new ArrayList<>();
private List<EntityData> entities = new ArrayList<>();
private List<BlockData> palette = new ArrayList<>();
private BlockPos size;
private String author;
private int DataVersion;
public NBTFile(File nbtFile) throws IOException, ReflectiveOperationException {
this.nbtFile = nbtFile;
Reflection.init();
Object nbtTagCompound = Reflection.a(new FileInputStream(this.nbtFile));
loadBlocks(nbtTagCompound);
loadEntities(nbtTagCompound);
loadPalette(nbtTagCompound);
this.size = toBlockPos(Reflection.getList(nbtTagCompound, "size", 3));
this.author = Reflection.getString(nbtTagCompound, "author");
this.DataVersion = Reflection.getInt(nbtTagCompound, "DataVersion");
}
private void loadBlocks(Object nbtTagCompound) throws ReflectiveOperationException {
Object block = Reflection.getList(nbtTagCompound, "blocks", 10);
for (int i = 0; i < Reflection.size(block); i++) {
Object b = Reflection.get(block, i);
this.blocks.add(new BlockStats(toBlockPos(Reflection.getList(b, "pos", 3)), Reflection.getInt(b, "state")));
}
}
private void loadEntities(Object nbtTagCompound) throws ReflectiveOperationException {
Object entity = Reflection.getList(nbtTagCompound, "entities", 10);
for (int i = 0; i < Reflection.size(entity); i++) {
Object e = Reflection.get(entity, i);
this.entities.add(
new EntityData(Reflection.getCompound(e, "nbt"),
toBlockPos(Reflection.getList(e, "blockPos", 3)),
toEntityPos(Reflection.getList(e, "pos", 3)))
);
}
}
private void loadPalette(Object nbtTagCompound) throws ReflectiveOperationException {
Object palettes = Reflection.getList(nbtTagCompound, "palette", 10);
for (int i = 0; i < Reflection.size(palettes); i++) {
Object p = Reflection.get(palettes, i);
BlockData.BlockDataBuilder builder = BlockData.builder().material(Reflection.getString(p, "Name"));
Object properties = Reflection.getCompound(p, "Properties");
if (Reflection.d(properties) > 0) {
if (Reflection.hasKey(properties, "color")) builder.color(Reflection.getString(properties, "color"));
if (Reflection.hasKey(properties, "variant"))
builder.variant(Reflection.getString(properties, "variant"));
if (Reflection.hasKey(properties, "facing")) builder.facing(Reflection.getString(properties, "facing"));
if (Reflection.hasKey(properties, "half")) builder.half(Reflection.getString(properties, "half"));
if (Reflection.hasKey(properties, "sharp")) builder.sharp(Reflection.getString(properties, "sharp"));
}
this.palette.add(builder.build());
}
}
private static BlockPos toBlockPos(Object nbtTagList) throws ReflectiveOperationException {
return new BlockPos(Reflection.c(nbtTagList, 0), Reflection.c(nbtTagList, 1), Reflection.c(nbtTagList, 2));
}
private static EntityPos toEntityPos(Object nbtTagList) throws ReflectiveOperationException {
return new EntityPos(Reflection.e(nbtTagList, 0), Reflection.e(nbtTagList, 1), Reflection.e(nbtTagList, 2));
}
@Getter
@AllArgsConstructor
@ToString
static class BlockPos {
private int X;
private int Y;
private int Z;
}
@Getter
@AllArgsConstructor
@ToString
static class EntityPos {
private double X;
private double Y;
private double Z;
}
@Getter
@Builder
@ToString
static class BlockData {
private String material;
private String color;
private String variant;
private String facing;
private String half;
private String sharp;
}
@Getter
@AllArgsConstructor
@ToString
static class BlockStats {
private BlockPos pos;
private int state;
}
@Getter
@AllArgsConstructor
@ToString
static class EntityData {
private Object entityNBT;
private BlockPos blockPos;
private EntityPos pos;
}
static class Reflection {
public static String nmsPackage = Bukkit.getServer().getClass().getPackage().getName()
.replaceAll("org\\.bukkit\\.craftbukkit", "net.minecraft.server");
private static Class NBTCompressedStreamToolsClass;
private static Method AMethod;
private static Class NBTTagCompoundClass;
private static Method GetListMethod;
private static Method GetStringMethod;
private static Method GetIntMethod;
private static Method GetCompoundMethod;
private static Method DMethod;
private static Method HasKeyMethod;
private static Class NBTTagListClass;
private static Method GetMethod;
private static Method SizeMethod;
private static Method CMethod;
private static Method EMethod;
public static void init() throws ClassNotFoundException, NoSuchMethodException {
System.out.println(nmsPackage);
NBTCompressedStreamToolsClass = Class.forName(nmsPackage + ".NBTCompressedStreamTools");
AMethod = NBTCompressedStreamToolsClass.getMethod("a", InputStream.class);
NBTTagCompoundClass = Class.forName(nmsPackage + ".NBTTagCompound");
GetListMethod = NBTTagCompoundClass.getMethod("getList", String.class, int.class);
GetStringMethod = NBTTagCompoundClass.getMethod("getString", String.class);
GetIntMethod = NBTTagCompoundClass.getMethod("getInt", String.class);
GetCompoundMethod = NBTTagCompoundClass.getMethod("getCompound", String.class);
DMethod = NBTTagCompoundClass.getMethod("d");
HasKeyMethod = NBTTagCompoundClass.getMethod("hasKey", String.class);
NBTTagListClass = Class.forName(nmsPackage + ".NBTTagList");
GetMethod = NBTTagListClass.getMethod("get", int.class);
SizeMethod = NBTTagListClass.getMethod("size");
CMethod = NBTTagListClass.getMethod("c", int.class);
EMethod = NBTTagListClass.getMethod("e", int.class);
}
public static Object a(InputStream inputStream) throws InvocationTargetException, IllegalAccessException {
return AMethod.invoke(null, inputStream);
}
public static Object getList(Object nbtTagCompound, String tagName, int typeId) throws InvocationTargetException, IllegalAccessException {
return GetListMethod.invoke(nbtTagCompound, tagName, typeId);
}
public static String getString(Object nbtTagCompound, String tagName) throws InvocationTargetException, IllegalAccessException {
return (String) GetStringMethod.invoke(nbtTagCompound, tagName);
}
public static int getInt(Object nbtTagCompound, String tagName) throws InvocationTargetException, IllegalAccessException {
return (int) GetIntMethod.invoke(nbtTagCompound, tagName);
}
public static Object getCompound(Object nbtTagCompound, String tagName) throws InvocationTargetException, IllegalAccessException {
return GetCompoundMethod.invoke(nbtTagCompound, tagName);
}
public static int d(Object nbtTagCompound) throws InvocationTargetException, IllegalAccessException {
return (int) DMethod.invoke(nbtTagCompound);
}
public static boolean hasKey(Object nbtTagCompound, String tagName) throws InvocationTargetException, IllegalAccessException {
return (boolean) HasKeyMethod.invoke(nbtTagCompound, tagName);
}
public static Object get(Object nbtTagList, int index) throws InvocationTargetException, IllegalAccessException {
return GetMethod.invoke(nbtTagList, index);
}
public static int size(Object nbtTagList) throws InvocationTargetException, IllegalAccessException {
return (int) SizeMethod.invoke(nbtTagList);
}
public static int c(Object nbtTagList, int index) throws InvocationTargetException, IllegalAccessException {
return (int) CMethod.invoke(nbtTagList, index);
}
public static double e(Object nbtTagList, int index) throws InvocationTargetException, IllegalAccessException {
return (double) EMethod.invoke(nbtTagList, index);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment