有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何使用Reflector类。正确吗?

我目前正在开发一个Minecraft插件,应该能够管理暴徒。总之,在任何情况下,我希望我的插件是一个最大的多版本,所以我使用Reflector。但当我使用课堂时。我得到了不想要的职业

这就是我没有反射器的情况:

WorldServer nms = ((CraftWorld) entity.getWorld()).getHandle();
nms.addEntity((net.minecraft.server.v1_13_R2.Entity) ((CraftEntity) entity).getHandle(), SpawnReason.CUSTOM);

带反射镜:

try {
    // We get the craftworld class with nms so it can be used in multiple versions
    Class<?> craftWorldClass = getNMSClass("org.bukkit.craftbukkit.", "CraftWorld");

    // Cast the bukkit world to the craftworld
    Object craftWorldObject = craftWorldClass.cast(entity.getWorld());

    // Create variable with the method that get handle
    // https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/browse/src/main/java/org/bukkit/craftbukkit/CraftWorld.java#580
    Method getHandleMethod = craftWorldObject.getClass().getMethod("getHandle");

    // Attempt to invoke the method that creates the entity itself. This returns a net.minecraft.server entity
    Object worldServerObject = getHandleMethod.invoke(craftWorldObject);


    // We get the CraftEntity class
    Class<?> craftEntityClass = getNMSClass("org.bukkit.craftbukkit.", "entity.CraftEntity");

    //cast org.bukkit.entity.Entity to CraftEntity
    Object craftEntityObject = craftEntityClass.cast(entity);

    //get the method getHandle
    Method entityGetHandleMethod = craftEntityClass.getMethod("getHandle");

    //Attempt to invoke the method
    Object entityTypeObject = entityGetHandleMethod.invoke(craftEntityObject);

    // We get the Entity class of NMS
    Class<?> entityClass = getNMSClass("net.minecraft.server.", "Entity");

    System.out.println(entityClass);

    //cast CraftEntity to NMS Entity
    Object entityObject = entityClass.cast(entityTypeObject);

    System.out.println(entityTypeObject.getClass());
    System.out.println(entityObject.getClass());

    //get the method to add mob in world
    Method addEntityMethod = worldServerObject.getClass().getMethod("addEntity", entityClass, SpawnReason.CUSTOM.getClass());

    //Attempt to invoke the method
    addEntityMethod.invoke(entityObject, SpawnReason.CUSTOM);


} catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException exception) {
    exception.printStackTrace();
}


private static Class<?> getNMSClass(String prefix, String nmsClassString) throws ClassNotFoundException {
    // Getting the version by splitting the package
    String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3] + ".";

    // Combining the prefix + version + nmsClassString for the full class path
    String name = prefix + version + nmsClassString;
    return Class.forName(name);
}

因此,在我的逻辑中,我发现自己在输出时有一个NMS Entity类型的对象,但在我的测试中,我用的是一个NMS EntityZombie

输出:

[15:43:01 INFO]: class net.minecraft.server.v1_13_R2.Entity
[15:43:01 INFO]: class net.minecraft.server.v1_13_R2.EntityZombie
[15:43:01 INFO]: class net.minecraft.server.v1_13_R2.EntityZombie

那么我如何使用反射器来获得正确的类型呢

谢谢你的帮助^^


共 (1) 个答案

  1. # 1 楼答案

    ZombieEntity间接继承自实体(ZombieEntity->;EntityCreature->;EntityCreature->;EntityInsentient->;EntityLiving->;实体),这意味着它已经是一个实体

    您可以强制转换它,但强制转换不会更改类类型。 快速示例:

    String s = "This is a test";
    Object obj = (Object) s;
    System.out.println(obj.getClass().getName());
    // prints "java.lang.String"
    

    你的代码是正确的