Advertisement
Guest User

XTAGS

a guest
Nov 4th, 2018
362
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 22.40 KB | None | 0 0
  1. import java.lang.reflect.Constructor;
  2. import java.lang.reflect.Field;
  3. import java.lang.reflect.Method;
  4. import java.util.HashMap;
  5. import java.util.List;
  6. import java.util.Map;
  7. import java.util.UUID;
  8. import java.util.regex.Matcher;
  9. import java.util.regex.Pattern;
  10.  
  11. import org.apache.commons.codec.binary.Base64;
  12. import org.bukkit.Bukkit;
  13. import org.bukkit.Location;
  14. import org.bukkit.Material;
  15. import org.bukkit.block.Block;
  16. import org.bukkit.entity.Entity;
  17. import org.bukkit.inventory.ItemStack;
  18. import org.bukkit.inventory.meta.ItemMeta;
  19.  
  20. import com.google.common.primitives.Primitives;
  21. import com.mojang.authlib.GameProfile;
  22. import com.mojang.authlib.properties.Property;
  23.  
  24. /**
  25.  * Sets/Gets NBT tags from ItemStacks
  26.  *
  27.  * @version 6.5
  28.  * @author BananaPuncher714
  29.  */
  30. public class XTags {
  31.     private static final Map< String, Class<?> > classCache;
  32.     private static final Map< String, Method > methodCache;
  33.     private static final Map< Class< ? >, Constructor< ? > > constructorCache;
  34.     private static final Map< Class< ? >, Class< ? > > NBTClasses;
  35.     private static final Map< Class< ? >, Field > NBTTagFieldCache;
  36.     private static Field NBTListData;
  37.     private static Field NBTCompoundMap;
  38.     private static final String version;
  39.  
  40.     static {
  41.         version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
  42.  
  43.         classCache = new HashMap< String, Class<?> >();
  44.         try {
  45.             classCache.put( "NBTBase", Class.forName( "net.minecraft.server." + version + "." + "NBTBase" ) );
  46.             classCache.put( "NBTTagCompound", Class.forName( "net.minecraft.server." + version + "." + "NBTTagCompound" ) );
  47.             classCache.put( "NBTTagList", Class.forName( "net.minecraft.server." + version + "." + "NBTTagList" ) );
  48.             classCache.put( "NBTBase", Class.forName( "net.minecraft.server." + version + "." + "NBTBase" ) );
  49.  
  50.             classCache.put( "ItemStack", Class.forName( "net.minecraft.server." + version + "." + "ItemStack" ) );
  51.             classCache.put( "CraftItemStack", Class.forName( "org.bukkit.craftbukkit." + version + ".inventory." + "CraftItemStack" ) );
  52.  
  53.             classCache.put( "Entity", Class.forName( "net.minecraft.server." + version + "." + "Entity" ) );
  54.             classCache.put( "CraftEntity", Class.forName( "org.bukkit.craftbukkit." + version + ".entity." + "CraftEntity" ) );
  55.             classCache.put( "EntityLiving", Class.forName( "net.minecraft.server." + version + "." + "EntityLiving" ) );
  56.  
  57.             classCache.put( "CraftWorld", Class.forName( "org.bukkit.craftbukkit." + version + "." + "CraftWorld" ) );
  58.             classCache.put( "CraftBlockState", Class.forName( "org.bukkit.craftbukkit." + version + ".block." + "CraftBlockState" ) );
  59.             classCache.put( "BlockPosition", Class.forName( "net.minecraft.server." + version + "." + "BlockPosition" ) );
  60.             classCache.put( "TileEntity", Class.forName( "net.minecraft.server." + version + "." + "TileEntity" ) );
  61.             classCache.put( "World", Class.forName( "net.minecraft.server." + version + "." + "World" ) );
  62.            
  63.             classCache.put( "TileEntitySkull", Class.forName( "net.minecraft.server." + version + "." + "TileEntitySkull" ) );
  64.         } catch (ClassNotFoundException e) {
  65.             e.printStackTrace();
  66.         }
  67.  
  68.         NBTClasses = new HashMap< Class< ? >, Class< ? > >();
  69.         try {
  70.             NBTClasses.put( Byte.class, Class.forName( "net.minecraft.server." + version + "." + "NBTTagByte" ) );
  71.             NBTClasses.put( String.class, Class.forName( "net.minecraft.server." + version + "." + "NBTTagString" ) );
  72.             NBTClasses.put( Double.class, Class.forName( "net.minecraft.server." + version + "." + "NBTTagDouble" ) );
  73.             NBTClasses.put( Integer.class, Class.forName( "net.minecraft.server." + version + "." + "NBTTagInt" ) );
  74.             NBTClasses.put( Long.class, Class.forName( "net.minecraft.server." + version + "." + "NBTTagLong" ) );
  75.             NBTClasses.put( Short.class, Class.forName( "net.minecraft.server." + version + "." + "NBTTagShort" ) );
  76.             NBTClasses.put( Float.class, Class.forName( "net.minecraft.server." + version + "." + "NBTTagFloat" ) );
  77.             NBTClasses.put( Class.forName( "[B" ), Class.forName( "net.minecraft.server." + version + "." + "NBTTagByteArray" ) );
  78.             NBTClasses.put( Class.forName( "[I" ), Class.forName( "net.minecraft.server." + version + "." + "NBTTagIntArray" ) );
  79.         } catch (ClassNotFoundException e) {
  80.             e.printStackTrace();
  81.         }
  82.  
  83.         methodCache = new HashMap< String, Method >();
  84.         try {
  85.             methodCache.put( "get", getNMSClass( "NBTTagCompound" ).getMethod( "get", String.class ) );
  86.             methodCache.put( "set", getNMSClass( "NBTTagCompound" ).getMethod( "set", String.class, getNMSClass( "NBTBase" ) ) );
  87.             methodCache.put( "hasKey", getNMSClass( "NBTTagCompound" ).getMethod( "hasKey", String.class ) );
  88.             methodCache.put( "setIndex", getNMSClass( "NBTTagList" ).getMethod( "a", int.class, getNMSClass( "NBTBase" ) ) );
  89.             methodCache.put( "add", getNMSClass( "NBTTagList" ).getMethod( "add", getNMSClass( "NBTBase" ) ) );
  90.  
  91.             methodCache.put( "hasTag", getNMSClass( "ItemStack" ).getMethod( "hasTag" ) );
  92.             methodCache.put( "getTag", getNMSClass( "ItemStack" ).getMethod( "getTag" ) );
  93.             methodCache.put( "setTag", getNMSClass( "ItemStack" ).getMethod( "setTag", getNMSClass( "NBTTagCompound" ) ) );
  94.             methodCache.put( "asNMSCopy", getNMSClass( "CraftItemStack" ).getMethod( "asNMSCopy", ItemStack.class ) );
  95.             methodCache.put( "asBukkitCopy", getNMSClass( "CraftItemStack" ).getMethod( "asBukkitCopy", getNMSClass( "ItemStack" ) ) );
  96.  
  97.             methodCache.put( "getEntityHandle", getNMSClass( "CraftEntity" ).getMethod( "getHandle" ) );
  98.             methodCache.put( "getEntityTag", getNMSClass( "Entity" ).getMethod( "c", getNMSClass( "NBTTagCompound" ) ) );
  99.             methodCache.put( "setEntityTag", getNMSClass( "Entity" ).getMethod( "f", getNMSClass( "NBTTagCompound" ) ) );
  100.  
  101.             if ( version.contains( "1_12" ) ) {
  102.                 methodCache.put( "setTileTag", getNMSClass( "TileEntity" ).getMethod( "load", getNMSClass( "NBTTagCompound" ) ) );
  103.             } else {
  104.                 methodCache.put( "setTileTag", getNMSClass( "TileEntity" ).getMethod( "a", getNMSClass( "NBTTagCompound" ) ) );
  105.             }
  106.             methodCache.put( "getTileEntity", getNMSClass( "World" ).getMethod( "getTileEntity", getNMSClass( "BlockPosition" ) ) );
  107.             methodCache.put( "getWorldHandle", getNMSClass( "CraftWorld" ).getMethod( "getHandle" ) );
  108.            
  109.             methodCache.put( "setGameProfile", getNMSClass( "TileEntitySkull" ).getMethod( "setGameProfile", GameProfile.class ) );
  110.         } catch( Exception e ) {
  111.             e.printStackTrace();
  112.         }
  113.  
  114.         try {
  115.             methodCache.put( "getTileTag", getNMSClass( "TileEntity" ).getMethod( "save", getNMSClass( "NBTTagCompound" ) ) );
  116.         } catch( NoSuchMethodException exception ) {
  117.             try {
  118.                 methodCache.put( "getTileTag", getNMSClass( "TileEntity" ).getMethod( "b", getNMSClass( "NBTTagCompound" ) ) );
  119.             } catch ( Exception exception2 ) {
  120.                 exception2.printStackTrace();
  121.             }
  122.         } catch( Exception exception ) {
  123.             exception.printStackTrace();
  124.         }
  125.  
  126.         constructorCache = new HashMap< Class< ? >, Constructor< ? > >();
  127.         try {
  128.             constructorCache.put( getNBTTag( Byte.class ), getNBTTag( Byte.class ).getConstructor( byte.class ) );
  129.             constructorCache.put( getNBTTag( String.class ), getNBTTag( String.class ).getConstructor( String.class ) );
  130.             constructorCache.put( getNBTTag( Double.class ), getNBTTag( Double.class ).getConstructor( double.class ) );
  131.             constructorCache.put( getNBTTag( Integer.class ), getNBTTag( Integer.class ).getConstructor( int.class ) );
  132.             constructorCache.put( getNBTTag( Long.class ), getNBTTag( Long.class ).getConstructor( long.class ) );
  133.             constructorCache.put( getNBTTag( Float.class ), getNBTTag( Float.class ).getConstructor( float.class ) );
  134.             constructorCache.put( getNBTTag( Short.class ), getNBTTag( Short.class ).getConstructor( short.class ) );
  135.             constructorCache.put( getNBTTag( Class.forName( "[B" ) ), getNBTTag( Class.forName( "[B" ) ).getConstructor( Class.forName( "[B" ) ) );
  136.             constructorCache.put( getNBTTag( Class.forName( "[I" ) ), getNBTTag( Class.forName( "[I" ) ).getConstructor( Class.forName( "[I" ) ) );
  137.  
  138.             constructorCache.put( getNMSClass( "BlockPosition" ), getNMSClass( "BlockPosition" ).getConstructor( int.class, int.class, int.class ) );
  139.         } catch( Exception e ) {
  140.             e.printStackTrace();
  141.         }
  142.  
  143.         NBTTagFieldCache = new HashMap< Class< ? >, Field >();
  144.         try {
  145.             for ( Class< ? > clazz : NBTClasses.values() ) {
  146.                 Field data = clazz.getDeclaredField( "data" );
  147.                 data.setAccessible( true );
  148.                 NBTTagFieldCache.put( clazz, data );
  149.             }
  150.         } catch( Exception e ) {
  151.             e.printStackTrace();
  152.         }
  153.  
  154.         try {
  155.             NBTListData = getNMSClass( "NBTTagList" ).getDeclaredField( "list" );
  156.             NBTListData.setAccessible( true );
  157.             NBTCompoundMap = getNMSClass( "NBTTagCompound" ).getDeclaredField( "map" );
  158.             NBTCompoundMap.setAccessible( true );
  159.         } catch( Exception e ) {
  160.             e.printStackTrace();
  161.         }
  162.     }
  163.  
  164.     public static Class<?> getPrimitiveClass( Class<?> clazz ) {
  165.         return Primitives.unwrap( clazz );
  166.     }
  167.  
  168.     public static Class< ? > getNBTTag( Class< ? > primitiveType ) {
  169.         if ( NBTClasses.containsKey( primitiveType ) )
  170.             return NBTClasses.get( primitiveType );
  171.         return primitiveType;
  172.     }
  173.  
  174.     public static Object getNBTVar( Object object ) {
  175.         if ( object == null ) return null;
  176.         Class< ? > clazz = object.getClass();
  177.         try {
  178.             if ( NBTTagFieldCache.containsKey( clazz ) ) {
  179.                 return NBTTagFieldCache.get( clazz ).get( object );
  180.             }
  181.         } catch ( Exception exception ) {
  182.             exception.printStackTrace();
  183.         }
  184.         return null;
  185.     }
  186.  
  187.     public static Method getMethod( String name ) {
  188.         return methodCache.containsKey( name ) ? methodCache.get( name ) : null;
  189.     }
  190.  
  191.     public static Constructor< ? > getConstructor( Class< ? > clazz ) {
  192.         return constructorCache.containsKey( clazz ) ? constructorCache.get( clazz ) : null;
  193.     }
  194.  
  195.     public static Class<?> getNMSClass(String name) {
  196.         if ( classCache.containsKey( name ) ) {
  197.             return classCache.get( name );
  198.         }
  199.  
  200.         try {
  201.             return Class.forName("net.minecraft.server." + version + "." + name);
  202.         } catch (ClassNotFoundException e) {
  203.             e.printStackTrace();
  204.             return null;
  205.         }
  206.     }
  207.    
  208.     public static String getMatch( String string, String regex ) {
  209.         Pattern pattern = Pattern.compile( regex );
  210.         Matcher matcher = pattern.matcher( string );
  211.         if ( matcher.find() ) {
  212.             return matcher.group( 1 );
  213.         } else {
  214.             return null;
  215.         }
  216.     }
  217.  
  218.     public final static ItemStack getHead( String skinURL ) {
  219.         Material material = Material.getMaterial( "SKULL_ITEM" );
  220.         if ( material == null ) {
  221.             // Most likely 1.13 materials
  222.             material = Material.getMaterial( "PLAYER_HEAD" );
  223.         }
  224.         ItemStack head = new ItemStack( material, 1, ( short ) 3 );
  225.         if ( skinURL == null || skinURL.isEmpty() ) {
  226.             return head;
  227.         }
  228.         ItemMeta headMeta = head.getItemMeta();
  229.         GameProfile profile = new GameProfile( UUID.randomUUID(), null);
  230.         byte[] encodedData = Base64.encodeBase64( String.format( "{textures:{SKIN:{\"url\":\"%s\"}}}", skinURL ).getBytes() );
  231.         profile.getProperties().put("textures", new Property("textures", new String(encodedData)));
  232.         Field profileField = null;
  233.         try {
  234.             profileField = headMeta.getClass().getDeclaredField("profile");
  235.         } catch ( NoSuchFieldException | SecurityException e ) {
  236.             e.printStackTrace();
  237.         }
  238.         profileField.setAccessible(true);
  239.         try {
  240.             profileField.set(headMeta, profile);
  241.         } catch (IllegalArgumentException | IllegalAccessException e) {
  242.             e.printStackTrace();
  243.         }
  244.         head.setItemMeta(headMeta);
  245.         return head;
  246.     }
  247.    
  248.     public final static String getTexture( ItemStack head ) {
  249.         ItemMeta meta = head.getItemMeta();
  250.         Field profileField = null;
  251.         try {
  252.             profileField = meta.getClass().getDeclaredField("profile");
  253.         } catch ( NoSuchFieldException | SecurityException e ) {
  254.             e.printStackTrace();
  255.         }
  256.         profileField.setAccessible(true);
  257.         try {
  258.             GameProfile profile = ( GameProfile ) profileField.get( meta );
  259.             if ( profile == null ) {
  260.                 return null;
  261.             }
  262.  
  263.             for ( Property prop : profile.getProperties().values() ) {
  264.                 if ( prop.getName().equals( "textures" ) ) {
  265.                     String texture = new String( Base64.decodeBase64( prop.getValue() ) );
  266.                     return getMatch( texture, "\\{\"url\":\"(.*?)\"\\}" );
  267.                 }
  268.             }
  269.             return null;
  270.         } catch ( IllegalArgumentException | IllegalAccessException | SecurityException e) {
  271.             e.printStackTrace();
  272.             return null;
  273.         }
  274.     }
  275.  
  276.     /**
  277.      * Gets an NBT tag in a given item with the specified keys
  278.      *
  279.      * @param item
  280.      * The itemstack to get the keys from
  281.      * @param key
  282.      * The keys to fetch; an integer after a key value indicates that it should get the nth place of
  283.      * the previous compound because it is a list;
  284.      * @return
  285.      * The item represented by the keys, and an integer if it is showing how long a list is.
  286.      */
  287.     public static Object getItemTag( ItemStack item, Object... keys ) {
  288.         if ( item == null ) {
  289.             return null;
  290.         }
  291.         try {
  292.             Object stack = null;
  293.             stack = getMethod( "asNMSCopy" ).invoke( null, item );
  294.  
  295.             Object tag = null;
  296.  
  297.             if ( getMethod( "hasTag" ).invoke( stack ).equals( true ) ) {
  298.                 tag = getMethod( "getTag" ).invoke( stack );
  299.             } else {
  300.                 tag = getNMSClass( "NBTTagCompound" ).newInstance();
  301.             }
  302.  
  303.             return getTag( tag, keys );
  304.         } catch ( Exception exception ) {
  305.             exception.printStackTrace();
  306.             return null;
  307.         }
  308.     }
  309.  
  310.     /**
  311.      * Sets an NBT tag in an item with the provided keys and value
  312.      *
  313.      * @param item
  314.      * The itemstack to set
  315.      * @param key
  316.      * The keys to set, String for NBTCompound, int or null for an NBTTagList
  317.      * @param value
  318.      * The value to set
  319.      * @return
  320.      * A new ItemStack with the updated NBT tags
  321.      */
  322.     public static ItemStack setItemTag( ItemStack item, Object value, Object... keys ) {
  323.         if ( item == null ) {
  324.             return null;
  325.         }
  326.         try {
  327.             Object stack = getMethod( "asNMSCopy" ).invoke( null, item );
  328.  
  329.             Object tag = null;
  330.  
  331.             if ( getMethod( "hasTag" ).invoke( stack ).equals( true ) ) {
  332.                 tag = getMethod( "getTag" ).invoke( stack );
  333.             } else {
  334.                 tag = getNMSClass( "NBTTagCompound" ).newInstance();
  335.             }
  336.  
  337.             setTag( tag, value, keys );
  338.             getMethod( "setTag" ).invoke( stack, tag );
  339.             return ( ItemStack ) getMethod( "asBukkitCopy" ).invoke( null, stack );
  340.         } catch ( Exception exception ) {
  341.             exception.printStackTrace();
  342.             return null;
  343.         }
  344.     }
  345.  
  346.     /**
  347.      * Gets an NBT tag in a given entity with the specified keys
  348.      *
  349.      * @param block
  350.      * The entity to get the keys from
  351.      * @param key
  352.      * The keys to fetch; an integer after a key value indicates that it should get the nth place of
  353.      * the previous compound because it is a list;
  354.      * @return
  355.      * The item represented by the keys, and an integer if it is showing how long a list is.
  356.      */
  357.     public static Object getEntityTag( Entity entity, Object... keys ) {
  358.         if ( entity == null ) {
  359.             return entity;
  360.         }
  361.         try {
  362.             Object NMSEntity = getMethod( "getEntityHandle" ).invoke( entity );
  363.  
  364.             Object tag = getNMSClass( "NBTTagCompound" ).newInstance();
  365.  
  366.             getMethod( "getEntityTag" ).invoke( NMSEntity, tag );
  367.  
  368.             return getTag( tag, keys );
  369.         } catch ( Exception exception ) {
  370.             exception.printStackTrace();
  371.             return null;
  372.         }
  373.     }
  374.  
  375.     /**
  376.      * Sets an NBT tag in an entity with the provided keys and value
  377.      *
  378.      * @param item
  379.      *
  380.      * The entity to set
  381.      * @param key
  382.      * The keys to set, String for NBTCompound, int or null for an NBTTagList
  383.      * @param value
  384.      * The value to set
  385.      * @return
  386.      * A new ItemStack with the updated NBT tags
  387.      */
  388.     public static void setEntityTag( Entity entity, Object value, Object... keys ) {
  389.         if ( entity == null ) {
  390.             return;
  391.         }
  392.         try {
  393.             Object NMSEntity = getMethod( "getEntityHandle" ).invoke( entity );
  394.  
  395.             Object tag = getNMSClass( "NBTTagCompound" ).newInstance() ;
  396.  
  397.             getMethod( "getEntityTag" ).invoke( NMSEntity, tag );
  398.  
  399.             setTag( tag, value, keys );
  400.  
  401.             getMethod( "setEntityTag" ).invoke( NMSEntity, tag );
  402.         } catch ( Exception exception ) {
  403.             exception.printStackTrace();
  404.             return;
  405.         }
  406.     }
  407.  
  408.     /**
  409.      * Gets an NBT tag in a given block with the specified keys
  410.      *
  411.      * @param block
  412.      * The block to get the keys from
  413.      * @param key
  414.      * The keys to fetch; an integer after a key value indicates that it should get the nth place of
  415.      * the previous compound because it is a list;
  416.      * @return
  417.      * The item represented by the keys, and an integer if it is showing how long a list is.
  418.      */
  419.     public static Object getBlockTag( Block block, Object... keys ) {
  420.         try {
  421.             if ( block == null || !getNMSClass( "CraftBlockState" ).isInstance( block.getState() ) ) {
  422.                 return null;
  423.             }
  424.             Location location = block.getLocation();
  425.            
  426.             Object blockPosition = getConstructor( getNMSClass( "BlockPosition" ) ).newInstance( location.getBlockX(), location.getBlockY(), location.getBlockZ() );
  427.  
  428.             Object nmsWorld = getMethod( "getWorldHandle" ).invoke( location.getWorld() );
  429.            
  430.             Object tileEntity = getMethod( "getTileEntity" ).invoke( nmsWorld, blockPosition );
  431.  
  432.             Object tag = getNMSClass( "NBTTagCompound" ).newInstance();
  433.            
  434.             getMethod( "getTileTag" ).invoke( tileEntity, tag );
  435.  
  436.             return getTag( tag, keys );
  437.         } catch( Exception exception ) {
  438.             exception.printStackTrace();
  439.             return null;
  440.         }
  441.     }
  442.  
  443.     /**
  444.      * Sets an NBT tag in an block with the provided keys and value
  445.      *
  446.      * @param item
  447.      * The block to set
  448.      * @param key
  449.      * The keys to set, String for NBTCompound, int or null for an NBTTagList
  450.      * @param value
  451.      * The value to set
  452.      * @return
  453.      * A new ItemStack with the updated NBT tags
  454.      */
  455.     public static void setBlockTag( Block block, Object value, Object... keys ) {
  456.         try {
  457.             if ( block == null || !getNMSClass( "CraftBlockState" ).isInstance( block.getState() ) ) {
  458.                 return;
  459.             }
  460.             Location location = block.getLocation();
  461.  
  462.             Object blockPosition = getConstructor( getNMSClass( "BlockPosition" ) ).newInstance( location.getBlockX(), location.getBlockY(), location.getBlockZ() );
  463.  
  464.             Object nmsWorld = getMethod( "getWorldHandle" ).invoke( location.getWorld() );
  465.  
  466.             Object tileEntity = getMethod( "getTileEntity" ).invoke( nmsWorld, blockPosition );
  467.  
  468.             Object tag = getNMSClass( "NBTTagCompound" ).newInstance();
  469.            
  470.             getMethod( "getTileTag" ).invoke( tileEntity, tag );
  471.  
  472.             setTag( tag, value, keys );
  473.  
  474.             getMethod( "setTileTag" ).invoke( tileEntity, tag );
  475.         } catch( Exception exception ) {
  476.             exception.printStackTrace();
  477.             return;
  478.         }
  479.     }
  480.    
  481.     public static void setSkullTexture( Block block, String texture ) {
  482.         GameProfile profile = new GameProfile( UUID.randomUUID(), null );
  483.         profile.getProperties().put( "textures", new com.mojang.authlib.properties.Property( "textures", new String( Base64.encodeBase64( String.format( "{textures:{SKIN:{\"url\":\"%s\"}}}", texture ).getBytes() ) ) ) );
  484.        
  485.         try {
  486.             Location location = block.getLocation();
  487.            
  488.             Object blockPosition = getConstructor( getNMSClass( "BlockPosition" ) ).newInstance( location.getBlockX(), location.getBlockY(), location.getBlockZ() );
  489.  
  490.             Object nmsWorld = getMethod( "getWorldHandle" ).invoke( location.getWorld() );
  491.  
  492.             Object tileEntity = getMethod( "getTileEntity" ).invoke( nmsWorld, blockPosition );
  493.  
  494.             getMethod( "setGameProfile" ).invoke( tileEntity, profile );
  495.         } catch( Exception exception ) {
  496.             exception.printStackTrace();
  497.         }
  498.     }
  499.  
  500.     private static void setTag( Object tag, Object value, Object... keys ) throws Exception {
  501.         Object notCompound = getConstructor( getNBTTag( value.getClass() ) ).newInstance( value );
  502.  
  503.         Object compound = tag;
  504.         for ( int index = 0; index < keys.length; index++ ) {
  505.             Object key = keys[ index ];
  506.             if ( index + 1 == keys.length ) {
  507.                 if ( key == null ) {
  508.                     getMethod( "add" ).invoke( compound, notCompound );
  509.                 } else if ( key instanceof Integer ) {
  510.                     getMethod( "setIndex" ).invoke( compound, ( int ) key, notCompound );
  511.                 } else {
  512.                     getMethod( "set" ).invoke( compound, ( String ) key, notCompound );
  513.                 }
  514.                 break;
  515.             }
  516.             Object oldCompound = compound;
  517.             if ( key instanceof Integer ) {
  518.                 compound = ( ( List< ? > ) NBTListData.get( compound ) ).get( ( int ) key );
  519.             } else if ( key != null ) {
  520.                 compound = getMethod( "get" ).invoke( compound, ( String ) key );
  521.             }
  522.             if ( compound == null || key == null ) {
  523.                 if ( keys[ index + 1 ] == null || keys[ index + 1 ] instanceof Integer ) {
  524.                     compound = getNMSClass( "NBTTagList" ).newInstance();
  525.                 } else {
  526.                     compound = getNMSClass( "NBTTagCompound" ).newInstance();
  527.                 }
  528.                 if ( oldCompound.getClass().getSimpleName().equals( "NBTTagList" ) ) {
  529.                     getMethod( "add" ).invoke( oldCompound, compound );
  530.                 } else {
  531.                     getMethod( "set" ).invoke( oldCompound, ( String ) key, compound );
  532.                 }
  533.             }
  534.         }
  535.     }
  536.  
  537.     private static Object getTag( Object tag, Object... keys ) throws Exception {
  538.         if ( keys.length == 0 ) {
  539.             return getTags( tag );
  540.         }
  541.  
  542.         Object notCompound = tag;
  543.  
  544.         for ( Object key : keys ) {
  545.             if ( notCompound == null ) {
  546.                 return null;
  547.             } else if ( getNMSClass( "NBTTagCompound" ).isInstance( notCompound ) ) {
  548.                 notCompound = getMethod( "get" ).invoke( notCompound, ( String ) key );
  549.             } else if ( getNMSClass( "NBTTagList" ).isInstance( notCompound ) ) {
  550.                 notCompound = ( ( List< ? > ) NBTListData.get( notCompound ) ).get( ( int ) key );
  551.             } else {
  552.                 return getNBTVar( notCompound );
  553.             }
  554.         }
  555.         if ( notCompound == null ) {
  556.             return null;
  557.         } else if ( getNMSClass( "NBTTagList" ).isInstance( notCompound ) ) {
  558.             return getTags( notCompound );
  559.         } else if ( getNMSClass( "NBTTagCompound" ).isInstance( notCompound ) ) {
  560.             return getTags( notCompound );
  561.         } else {
  562.             return getNBTVar( notCompound );
  563.         }
  564.     }
  565.  
  566.     @SuppressWarnings( "unchecked" )
  567.     private static Object getTags( Object tag ) {
  568.         Map< Object, Object > tags = new HashMap< Object, Object >();
  569.         try {
  570.             if ( getNMSClass( "NBTTagCompound" ).isInstance( tag ) ) {
  571.                 Map< String, Object > tagCompound = ( Map< String, Object > ) NBTCompoundMap.get( tag );
  572.                 for ( String key : tagCompound.keySet() ) {
  573.                     Object value = tagCompound.get( key );
  574.                     if ( getNMSClass( "NBTTagEnd" ).isInstance( value ) ) {
  575.                         continue;
  576.                     }
  577.                     tags.put( key, getTag( value ) );
  578.                 }
  579.             } else if ( getNMSClass( "NBTTagList" ).isInstance( tag ) ) {
  580.                 List< Object > tagList = ( List< Object > ) NBTListData.get( tag );
  581.                 for ( int index = 0; index < tagList.size(); index++ ) {
  582.                     Object value = tagList.get( index );
  583.                     if ( getNMSClass( "NBTTagEnd" ).isInstance( value ) ) {
  584.                         continue;
  585.                     }
  586.                     tags.put( index, getTag( value ) );
  587.                 }
  588.             } else {
  589.                 return getNBTVar( tag );
  590.             }
  591.             return tags;
  592.         } catch ( Exception e ) {
  593.             e.printStackTrace();
  594.             return tags;
  595.         }
  596.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement