Skip to content

Commit 8c5847a

Browse files
committed
Simplify and modernise packet wrapper to fix issues and support more data types
1 parent 6320d51 commit 8c5847a

2 files changed

Lines changed: 220 additions & 158 deletions

File tree

Lines changed: 62 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,94 @@
11
package dev._2lstudios.hamsterapi.utils;
22

3+
import org.bukkit.Bukkit;
34
import org.bukkit.inventory.ItemStack;
45

56
import 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+
*/
713
public 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

Comments
 (0)