11package dev ._2lstudios .hamsterapi .utils ;
22
3+ import org .bukkit .Bukkit ;
34import org .bukkit .inventory .ItemStack ;
45
56import java .lang .reflect .Method ;
67
8+ /**
9+ * A utility class to convert between Bukkit ItemStacks and their internal
10+ * NMS (net.minecraft.server) counterparts.
11+ * This class uses reflection to remain compatible across different Minecraft versions.
12+ */
713public class NMSItemStackConverter {
8- private static Class <?> CRAFT_ITEM_STACK_CLASS ;
9- private static Method AS_NMS_COPY_METHOD ;
14+
15+ private static final Class <?> CRAFT_ITEM_STACK_CLASS ;
16+ private static final Class <?> NMS_ITEM_STACK_CLASS ;
17+ private static final Method AS_NMS_COPY_METHOD ;
18+ private static final Method AS_BUKKIT_COPY_METHOD ;
1019
1120 static {
1221 try {
13- // Try with versioned path first
22+ // Find the CraftItemStack class, which is the bridge between Bukkit and NMS.
23+ // It can exist in a versioned package path, so we check that first.
1424 String version = getServerVersion ();
15- String versionedPath = "org.bukkit.craftbukkit." + version + ".inventory.CraftItemStack" ;
16-
17- try {
18- CRAFT_ITEM_STACK_CLASS = Class .forName (versionedPath );
19- } catch (ClassNotFoundException e ) {
20- // Fall back to non-versioned path if versioned path fails
21- String nonVersionedPath = "org.bukkit.craftbukkit.inventory.CraftItemStack" ;
22- CRAFT_ITEM_STACK_CLASS = Class .forName (nonVersionedPath );
23- }
24-
25+ String craftItemStackPath = "org.bukkit.craftbukkit." + version + ".inventory.CraftItemStack" ;
26+ CRAFT_ITEM_STACK_CLASS = Class .forName (craftItemStackPath );
27+
28+ // Get the method to convert a Bukkit ItemStack TO an NMS ItemStack.
29+ // Signature: public static net.minecraft.world.item.ItemStack asNMSCopy(org.bukkit.inventory.ItemStack)
2530 AS_NMS_COPY_METHOD = CRAFT_ITEM_STACK_CLASS .getMethod ("asNMSCopy" , ItemStack .class );
31+
32+ // We can determine the NMS ItemStack class from the return type of the asNMSCopy method.
33+ // This is more reliable than guessing the class path.
34+ NMS_ITEM_STACK_CLASS = AS_NMS_COPY_METHOD .getReturnType ();
35+
36+ // Now get the method to convert an NMS ItemStack BACK TO a Bukkit ItemStack.
37+ // Signature: public static org.bukkit.inventory.ItemStack asBukkitCopy(net.minecraft.world.item.ItemStack)
38+ AS_BUKKIT_COPY_METHOD = CRAFT_ITEM_STACK_CLASS .getMethod ("asBukkitCopy" , NMS_ITEM_STACK_CLASS );
39+
2640 } catch (Exception e ) {
27- e .printStackTrace ();
41+ // If any of these critical reflection steps fail, the utility is unusable.
42+ // Throw a runtime exception to indicate a severe setup error.
43+ throw new RuntimeException ("NMSItemStackConverter failed to initialize. Your server version may not be compatible." , e );
2844 }
2945 }
3046
3147 /**
32- * Converts a Bukkit ItemStack back to NMS ItemStack
33- * @param bukkitItem The Bukkit ItemStack to convert
34- * @return The NMS ItemStack
48+ * Converts a Bukkit ItemStack to its NMS counterpart.
49+ *
50+ * @param bukkitItem The Bukkit ItemStack to convert.
51+ * @return The corresponding NMS ItemStack as an Object, or null if conversion fails.
3552 */
3653 public static Object convertToNMS (ItemStack bukkitItem ) {
37- if (bukkitItem == null ) return null ;
38-
54+ if (bukkitItem == null ) {
55+ return null ;
56+ }
3957 try {
58+ // Invokes the static method: CraftItemStack.asNMSCopy(bukkitItem)
4059 return AS_NMS_COPY_METHOD .invoke (null , bukkitItem );
4160 } catch (Exception e ) {
42- e .printStackTrace ();
61+ // Graceful failure
62+ return null ;
63+ }
64+ }
65+
66+ /**
67+ * Converts an NMS ItemStack object back to a Bukkit ItemStack.
68+ *
69+ * @param nmsItem The NMS ItemStack (as an Object) to convert.
70+ * @return The corresponding Bukkit ItemStack, or null if conversion fails.
71+ */
72+ public static ItemStack convertToBukkit (Object nmsItem ) {
73+ if (nmsItem == null ) {
74+ return null ;
75+ }
76+ try {
77+ // Invokes the static method: CraftItemStack.asBukkitCopy(nmsItem)
78+ return (ItemStack ) AS_BUKKIT_COPY_METHOD .invoke (null , nmsItem );
79+ } catch (Exception e ) {
80+ // Graceful failure
4381 return null ;
4482 }
4583 }
4684
4785 /**
48- * Gets the current server version
49- * @return The version package string (e.g. "v1_16_R3")
86+ * Gets the server's version string used in package names (e.g., "v1_18_R2").
87+ *
88+ * @return The version package string.
5089 */
5190 private static String getServerVersion () {
52- String packageName = org . bukkit . Bukkit .getServer ().getClass ().getPackage ().getName ();
91+ String packageName = Bukkit .getServer ().getClass ().getPackage ().getName ();
5392 return packageName .substring (packageName .lastIndexOf ('.' ) + 1 );
5493 }
5594}
0 commit comments