Created
November 19, 2016 09:21
-
-
Save syuchan1005/739d4c189b52a4e060f86857911ecb02 to your computer and use it in GitHub Desktop.
Convert .nbt file generated by structure block
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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