Java 带有NMS和反射的ClassCastException

Java 带有NMS和反射的ClassCastException,java,reflection,bukkit,Java,Reflection,Bukkit,我一直在尝试对NetMinecraft服务器类使用反射,因为它们依赖于版本。我创建了一个类来模拟PacketPlayOutWorldParticles,但我想做更多。因为我需要打开一个箱子,所以,首先我要确保这个包能正常工作。然后我做了这个: public class ChestReflection { // Reference // PacketPlayOutBlockAction packet = new PacketPlayOutBlockAction(new //

我一直在尝试对NetMinecraft服务器类使用反射,因为它们依赖于版本。我创建了一个类来模拟
PacketPlayOutWorldParticles
,但我想做更多。因为我需要打开一个
箱子
,所以,首先我要确保这个包能正常工作。然后我做了这个:

public class ChestReflection {
    // Reference
    // PacketPlayOutBlockAction packet = new PacketPlayOutBlockAction(new
    // BlockPosition(x, y, z), BlockChest, 1, 1);

    private Class<?> getNMSClass(String nmsClassString) throws ClassNotFoundException {
        String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3] + ".";
        String name = "net.minecraft.server." + version + nmsClassString;
        Class<?> nmsClass = Class.forName(name);
        return nmsClass;
    }

    private Object getConnection(Player player) throws SecurityException, NoSuchMethodException, NoSuchFieldException,
            IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        Method getHandle = player.getClass().getMethod("getHandle");
        Object nmsPlayer = getHandle.invoke(player);
        Field conField = nmsPlayer.getClass().getField("playerConnection");
        Object con = conField.get(nmsPlayer);
        return con;
    }

    private Object getBlockPosition(Location loc)
            throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException,
            InvocationTargetException, NoSuchMethodException, SecurityException {
        Class<?> nmsBlockPosition = getNMSClass("BlockPosition");
        Object nmsBlockPositionInstance = nmsBlockPosition
                .getConstructor(new Class[] { Double.TYPE, Double.TYPE, Double.TYPE })
                .newInstance(new Object[] { loc.getX(), loc.getY(), loc.getZ() });

        return nmsBlockPositionInstance;
    }

    public void setChest(Player player, int open, Location loc) {
        try {
            Class<?> nmsBlockPositionClass = getNMSClass("BlockPosition");
            Object nmsBlockPos = getBlockPosition(loc);
            Class<?> nmsPacketBlockAction = getNMSClass("PacketPlayOutBlockAction");
            Class<?> nmsBlock = getNMSClass("Block");
            Object nmsChest = getNMSClass("Blocks").getField("Chest");
            Class<?> nmsPacket = getNMSClass("Packet");

            Object nmsPackInstance = nmsPacketBlockAction
                    .getConstructor(new Class[] { nmsBlockPositionClass, nmsBlock, Integer.TYPE, Integer.TYPE })
                    .newInstance(new Object[] { nmsBlockPos, nmsChest, Integer.valueOf(1), Integer.valueOf(open) });
            Method sendPacket = getConnection(player).getClass().getMethod("sendPacket", nmsPacket);
            sendPacket.invoke(new Object[] { nmsPackInstance });

        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException
                | InvocationTargetException | NoSuchMethodException | SecurityException | NoSuchFieldException e) {
            e.printStackTrace();
        }
        // -this is the reference-
        new PacketPlayOutBlockAction(new BlockPosition(loc.getX(), loc.getY(), loc.getZ()), Blocks.CHEST, 1, 0);
    }

    public void setChestOpenForEveryone(int open, Location loc) {
        for (Player player : Bukkit.getOnlinePlayers()) {
            setChest(player, open, loc);
        }
    }
}
这给了我一个错误:

Error: java.lang.IllegalArgumentException: java.lang.ClassCastException@61f9358b

我不知道是什么引起的。另外,我还包括了不带反射的数据包以供参考。

nmsChest
的类型是
java.lang.reflect.Field
,而不是
which.Block
。要获取该字段的值,必须执行以下操作:

  • 如果
    Blocks.CHEST
    是一个枚举值(或者它是
    Blocks.CHEST
    ?您似乎混淆了它们):


nmsChest
的类型为
java.lang.reflect.Field
,而不是
which.Block
。要获取该字段的值,必须执行以下操作:

  • 如果
    Blocks.CHEST
    是一个枚举值(或者它是
    Blocks.CHEST
    ?您似乎混淆了它们):


不要将所有这些方法调用连接到一个长语句中,而是尝试将它们分离到单独的语句中。在@FredK推荐的内容上,我推荐您缓存构造函数字段、方法和类,而不是每次都执行查找,因为这对服务器来说很耗时。更多信息:(在“反射缺点”下阅读)不要将所有这些方法调用连接到一个长语句中,而是尝试将它们分离到单独的语句中。在@FredK推荐的内容上,我推荐您缓存构造函数字段、方法和类,而不是每次都执行查找,因为这对服务器来说很耗时。更多信息:(在“反射缺点”下阅读)
Error: java.lang.IllegalArgumentException: java.lang.ClassCastException@61f9358b
nmsChest = Enum.valueOf((Class<Enum>) getNMSClass("Blocks"), "CHEST");
nmsChest = getNMSClass("Blocks").getField("CHEST").get(null);