1- package org .broken .arrow .library .itemcreator .utility .compound ;
1+ package org .broken .arrow .library .itemcreator .utility .nms ;
22
3+ import org .broken .arrow .library .itemcreator .utility .compound .CompoundTag ;
4+ import org .broken .arrow .library .itemcreator .utility .compound .NbtData ;
35import org .broken .arrow .library .logging .Logging ;
46import org .broken .arrow .library .logging .Validate ;
57import org .bukkit .Bukkit ;
1113import java .lang .invoke .MethodHandles ;
1214import java .lang .invoke .MethodType ;
1315import java .lang .reflect .Constructor ;
14- import java .util .Arrays ;
1516import java .util .logging .Level ;
1617
1718/**
@@ -363,7 +364,7 @@ private CompoundTag getCompoundTag(final String name, final boolean usingName) {
363364 }
364365 }
365366 this .compoundState = CompoundState .CREATED ;
366- return new CompoundTag (nested != null ? nested : root );
367+ return new CompoundTag (( nested != null ? nested : root ) );
367368 } catch (Throwable e ) {
368369 logger .logError (e , () -> "Failed to initialize CompoundTag" );
369370 this .compoundState = CompoundState .ERROR ;
@@ -400,14 +401,18 @@ private CompoundTag getCompound(final String name, final boolean usingName) {
400401 }
401402 }
402403 this .compoundState = CompoundState .CREATED ;
403- return new CompoundTag (nested != null ? nested : root );
404+ return new CompoundTag (( nested != null ? nested : root ) );
404405 } catch (Throwable e ) {
405406 logger .logError (e , () -> "Failed to initialize CompoundTag" );
406407 this .compoundState = CompoundState .ERROR ;
407408 }
408409 return null ;
409410 }
410411
412+ private static String getNbtTagBasePath () {
413+ return getNmsPath () + ".NBTBase" ;
414+ }
415+
411416 private static String getCraftBukkitPath () {
412417 return "org.bukkit.craftbukkit." + getPackageVersion ();
413418 }
@@ -430,6 +435,8 @@ public static class CompoundSession {
430435 private static final MethodHandle setShort ;
431436 private static final MethodHandle setByte ;
432437 private static final MethodHandle getByte ;
438+ private static final MethodHandle setByteArray ;
439+ private static final MethodHandle getByteArray ;
433440 private static final MethodHandle setBoolean ;
434441 private static final MethodHandle getBoolean ;
435442 private final Object handle ;
@@ -445,6 +452,8 @@ public static class CompoundSession {
445452 MethodHandle setShortM = null ;
446453 MethodHandle setByteM = null ;
447454 MethodHandle getByteM = null ;
455+ MethodHandle setByteArrayM = null ;
456+ MethodHandle getByteArrayM = null ;
448457 MethodHandle setBooleanM = null ;
449458 MethodHandle getBooleanM = null ;
450459 try {
@@ -471,6 +480,11 @@ public static class CompoundSession {
471480 getByteM = lookup .findVirtual (nbtTag , "getByte" ,
472481 MethodType .methodType (byte .class , String .class ));
473482
483+ setByteArrayM = lookup .findVirtual (nbtTag , "setByteArray" ,
484+ MethodType .methodType (void .class , String .class , byte [].class ));
485+ getByteArrayM = lookup .findVirtual (nbtTag , "getByteArray" ,
486+ MethodType .methodType (byte [].class , String .class ));
487+
474488 setStringM = lookup .findVirtual (nbtTag , "setString" ,
475489 MethodType .methodType (void .class , String .class , String .class ));
476490 getStringM = lookup .findVirtual (nbtTag , "getString" ,
@@ -494,7 +508,8 @@ public static class CompoundSession {
494508 setShort = setShortM ;
495509 setByte = setByteM ;
496510 getByte = getByteM ;
497-
511+ setByteArray = setByteArrayM ;
512+ getByteArray = getByteArrayM ;
498513 setBoolean = setBooleanM ;
499514 getBoolean = getBooleanM ;
500515
@@ -520,7 +535,7 @@ public static boolean isReady() {
520535 * @return returns the NBTTagCompound object.
521536 */
522537 @ Nonnull
523- Object getHandle () {
538+ public Object getHandle () {
524539 return handle ;
525540 }
526541
@@ -577,13 +592,17 @@ public void setInt(@Nonnull final String key, final int value) {
577592 * Gets a int value from the underlying NBTTagCompound.
578593 *
579594 * @param key the key of the int value
580- * @return the stored int value, or {@code -1} if unavailable
595+ * @return the stored int value, or {@code -1} if reflection fail
596+ * or if the key does not exist in the NBT data.
581597 */
582598 public int getInt (@ Nonnull final String key ) {
583599 if (getInt == null ) return -1 ;
584600
585601 try {
586- return (int ) getInt .invoke (handle , key );
602+ Object intObject = getInt .invoke (handle , key );
603+ if (intObject == null )
604+ return -1 ;
605+ return (int ) intObject ;
587606 } catch (Throwable e ) {
588607 logger .logError (e , () -> "Failed to retrieve int value from reflection" );
589608 }
@@ -612,11 +631,14 @@ public void setString(@Nonnull final String key, final String value) {
612631 * @param key the key of the string value
613632 * @return the stored string value, or empty string if unavailable
614633 */
634+ @ Nonnull
615635 public String getString (@ Nonnull final String key ) {
616636 if (getString == null ) return "" ;
617637
618638 try {
619- return (String ) getString .invoke (handle , key );
639+ Object stringObject = getString .invoke (handle , key );
640+ if (stringObject == null ) return "" ;
641+ return (String ) stringObject ;
620642 } catch (Throwable e ) {
621643 logger .logError (e , () -> "Failed to retrieve string value from reflection" );
622644 }
@@ -643,19 +665,65 @@ public void setByte(@Nonnull final String key, final byte value) {
643665 * Gets a byte value from the underlying NBTTagCompound.
644666 *
645667 * @param key the key of the byte value
646- * @return the stored byte value, or {@code -1} if unavailable
668+ * @return the stored byte value, or {@code -1} if reflection fail
669+ * or if the key does not exist in the NBT data.
647670 */
648671 public byte getByte (@ Nonnull final String key ) {
649672 if (getByte == null ) return -1 ;
650673
651674 try {
652- return (byte ) getByte .invoke (handle , key );
675+ Object byteObject = getByte .invoke (handle , key );
676+ if (byteObject == null ) return -1 ;
677+ return (byte ) byteObject ;
653678 } catch (Throwable e ) {
654679 logger .logError (e , () -> "Failed to retrieve byte value from reflection" );
655680 }
656681 return -1 ;
657682 }
658683
684+
685+ /**
686+ * Sets a byte array in the underlying NBTTagCompound.
687+ *
688+ * @param key the key to set
689+ * @param value the byte array to assign
690+ */
691+ public void setByteArray (@ Nonnull final String key , final byte [] value ) {
692+ if (setByteArray == null ) return ;
693+
694+ try {
695+ setByteArray .invoke (handle , key , value );
696+ } catch (Throwable e ) {
697+ logger .logError (e , () -> "Failed to set byte value from reflection" );
698+ }
699+ }
700+
701+ /**
702+ * Retrieves a byte array from the underlying NBTTagCompound.
703+ *
704+ * <p>If the reflective access fails (e.g., missing method reference or an
705+ * exception during invocation), this method returns an empty byte array.
706+ * A {@code null} value is only returned if the underlying NBT structure
707+ * itself represents the tag as non-existent.</p>
708+ *
709+ * @param key the key of the stored byte array
710+ * @return the byte array associated with the key, an empty array if reflection
711+ * access fails, or {@code null} if the key does not exist in the NBT data.
712+ */
713+ @ Nullable
714+ public byte [] getByteArray (@ Nonnull final String key ) {
715+ if (getByteArray == null ) return new byte [0 ];
716+
717+ try {
718+ Object byteArray = getByteArray .invoke (handle , key );
719+ if (byteArray == null ) return null ;
720+ return (byte []) byteArray ;
721+ } catch (Throwable e ) {
722+ logger .logError (e , () -> "Failed to retrieve byte value from reflection" );
723+ }
724+ return new byte [0 ];
725+ }
726+
659727 /**
660728 * Sets a boolean value in the underlying NBTTagCompound.
661729 *
@@ -682,7 +750,9 @@ public boolean getBoolean(@Nonnull final String key) {
682750 if (getBoolean == null ) return false ;
683751
684752 try {
685- return (boolean ) getBoolean .invoke (handle , key );
753+ Object booleanObject = getBoolean .invoke (handle , key );
754+ if (booleanObject == null ) return false ;
755+ return (boolean ) booleanObject ;
686756 } catch (Throwable e ) {
687757 logger .logError (e , () -> "Failed to retrieve boolean value from reflection" );
688758 }
@@ -709,13 +779,16 @@ public void setShort(@Nonnull final String key, final short value) {
709779 * Gets a short value from the underlying NBTTagCompound.
710780 *
711781 * @param key the key of the short value
712- * @return the stored short value, or {@code -1} if unavailable
782+ * @return the stored short value, or {@code -1} if reflection fail
783+ * or if the key does not exist in the NBT data.
713784 */
714785 public short getShort (@ Nonnull final String key ) {
715786 if (getShort == null ) return -1 ;
716787
717788 try {
718- return (short ) getShort .invoke (handle , key );
789+ Object shortObject = getShort .invoke (handle , key );
790+ if (shortObject == null ) return -1 ;
791+ return (short ) shortObject ;
719792 } catch (Throwable e ) {
720793 logger .logError (e , () -> "Failed to retrieve short value from reflection" );
721794 }
@@ -728,9 +801,6 @@ private static String getNbtTagPath() {
728801 return getNmsPath () + ".NBTTagCompound" ;
729802 }
730803
731- private static String getNbtTagBasePath () {
732- return getNmsPath () + ".NBTBase" ;
733- }
734804
735805 private static String getNmsPath () {
736806 return "net.minecraft.server." + getPackageVersion ();
0 commit comments