package org.pepsoft.worldpainter.biomeschemes; import org.jnbt.CompoundTag; import org.jnbt.ListTag; import org.jnbt.StringTag; import org.jnbt.Tag; import org.pepsoft.minecraft.Material; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Map; /** * Created by Pepijn on 26-6-2016. */ public class MC10InterfaceHelper { public MC10InterfaceHelper(Class<?> compoundTagClass, Method addTagToCompoundTagMethod, Class<?> listTagClass, Method addTagToListTagMethod, Constructor<?> stringTagConstructor, Method nbtToBlockDataMethod, Method getBlockMethod, Method blockToIdMethod, Method blockToDataMethod) { this.compoundTagClass = compoundTagClass; this.listTagClass = listTagClass; this.stringTagConstructor = stringTagConstructor; this.nbtToBlockDataMethod = nbtToBlockDataMethod; this.getBlockMethod = getBlockMethod; this.blockToIdMethod = blockToIdMethod; this.blockToDataMethod = blockToDataMethod; this.addTagToCompoundTagMethod = addTagToCompoundTagMethod; this.addTagToListTagMethod = addTagToListTagMethod; } /** * Decode block information from the palette in a structure file. * * @param tag The NBT compound tag from the palette in the structure file. * @return The decoded material. */ public Material decodeStructureMaterial(CompoundTag tag) { try { Object blockData = nbtToBlockDataMethod.invoke(null, convertNBT(tag)); Object block = getBlockMethod.invoke(blockData); return Material.get((Integer) blockToIdMethod.invoke(null, block), (Integer) blockToDataMethod.invoke(block, blockData)); } catch (IllegalAccessException e) { throw new RuntimeException("Access denied while decoding structure block", e); } catch (InvocationTargetException e) { throw new RuntimeException("Exception thrown while decoding structure block", e); } catch (InstantiationException e) { throw new RuntimeException("Instantiation exception thrown while decoding structure block", e); } } private Object convertNBT(Tag tag) throws InstantiationException, IllegalAccessException, InvocationTargetException { if (tag instanceof CompoundTag) { return convertNBT((CompoundTag) tag); } else if (tag instanceof ListTag) { return convertNBT(((ListTag) tag)); } else if (tag instanceof StringTag) { return convertNBT((StringTag) tag); } else { throw new UnsupportedOperationException("Unsupported tag type " + tag.getClass().getSimpleName() + " encountered"); } } private Object convertNBT(CompoundTag compoundTag) throws IllegalAccessException, InstantiationException, InvocationTargetException { Object mcTag = compoundTagClass.newInstance(); for (Map.Entry<String, Tag> entry: compoundTag.getValue().entrySet()) { addTagToCompoundTagMethod.invoke(mcTag, entry.getKey(), convertNBT(entry.getValue())); } return mcTag; } private Object convertNBT(ListTag listTag) throws IllegalAccessException, InstantiationException, InvocationTargetException { Object mcTag = listTagClass.newInstance(); for (Tag tag: listTag.getValue()) { addTagToListTagMethod.invoke(mcTag, convertNBT(tag)); } return mcTag; } private Object convertNBT(StringTag stringTag) throws IllegalAccessException, InvocationTargetException, InstantiationException { return stringTagConstructor.newInstance(stringTag.getValue()); } private final Class<?> compoundTagClass, listTagClass; private final Constructor<?> stringTagConstructor; private final Method nbtToBlockDataMethod, getBlockMethod, blockToIdMethod, blockToDataMethod, addTagToCompoundTagMethod, addTagToListTagMethod; }