Huhu Leute,
ja ich weiß, die meisten von euch mögen kein Java, aber vielleicht hat ja trotzdem jemand eine Idee
Aaaaalso ich programmiere Minecraft-Plugins und nutze dafür die Spigot-API. Leider enthält die nicht immer alle verfügbaren Methoden und Klassen und daher muss man manchmal auf die darunterliegenden "NMS"-Klassen (den original Code des Spiels, den die API nicht zur Verfügung stellt) zurückgreifen.
Problem: Die Klassennamen bzw die Namen der Packages ändern sich mit jeder Version, z.B.:
Wenn ein Minecraft-Update released wird, steht da statt "1_16_R3" zum Beispiel "1_17_R0" und das is natürlich... blöd. Daher muss ich teilweise auf Reflection zurückgreifen, und das ist gelinde gesagt scheiße.
Beispiel:
Aus diesem hier:
private void blabla() {
EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
PacketPlayOutEntityStatus statusPacket = new PacketPlayOutEntityStatus(entityPlayer, TOTEM_MAGIC_BYTE);
entityPlayer.playerConnection.sendPacket(statusPacket);
}
wird das hier:
private void blabla() {
try {
Class<?> statusPacketClass = NMSUtils.getNMSClass("PacketPlayOutEntityStatus");
Class<?> entityPlayerClass = NMSUtils.getNMSClass("EntityPlayer");
Class<?> entityClass = NMSUtils.getNMSClass("Entity");
Class<?> craftPlayerClass = NMSUtils.getBukkitNMSClass("entity.CraftPlayer");
Method getHandleMethod = craftPlayerClass.getMethod("getHandle");
Method sendPacketMethod = NMSUtils.getNMSClass("PlayerConnection").getMethod("sendPacket", NMSUtils.getNMSClass("Packet"));
Constructor<?> packetConstructor = statusPacketClass.getConstructor(entityClass, byte.class);
Object craftPlayer = craftPlayerClass.cast(p);
Object entityPlayer = getHandleMethod.invoke(craftPlayer, null);
Object packet = packetConstructor.newInstance(entityPlayerClass.cast(entityPlayer), TOTEM_MAGIC_VALUE);
sendPacketMethod.invoke(NMSUtils.getConnection(p), packet);
} catch (Exception ignored) {
}
}
public static class NMSUtils {
public static Class<?> getNMSClass(String nmsClassString) throws ClassNotFoundException {
String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3] + ".";
String name = "net.minecraft.server." + version + nmsClassString;
return Class.forName(name);
}
public static Class<?> getBukkitNMSClass(String nmsClassString) throws ClassNotFoundException {
String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3] + ".";
String name = "org.bukkit.craftbukkit." + version + nmsClassString;
return Class.forName(name);
}
public static @Nullable Object getConnection(Player player) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
Method getHandle = player.getClass().getMethod("getHandle");
Object nmsPlayer = getHandle.invoke(player);
Field conField = nmsPlayer.getClass().getField("playerConnection");
Object con = conField.get(nmsPlayer);
return con;
}
}
Alles anzeigen
Das ist "unschön". Normalerweise sollte es ja für IDEs problemlos möglich sein, den originalen Code in Reflections zu verpacken. IntelliJ und Eclipse können das aber meines Wissens nach nicht, und ein passendes Plugin habe ich auch bisweilen nicht gefunden.
Kennt jemand irgendein Tool/Website/IDE-Plugin mit dem das möglich ist? Was normalerweise 2 Minuten dauert, dauert so nämlich teilweise eine halbe Stunde und das is wirklich blöd
Ich geh stark davon aus dass es sowas noch nicht gibt, wenn doch - ich bin über jede Antwort froh
Schönes Wochenende Schönen Abend