如何正确使用 Reflector Class.cast()?



我目前正在开发一个应该能够管理生物的Minecraft插件。简而言之,无论如何,我希望我的插件是最大多版本,所以我使用 Reflector。但是当我使用Class.cast(Object o(时,我得到了不需要的类。

这是我没有反射器的东西:

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 实体类型的对象,但在我的测试中,我遇到了一个 NMS 实体僵尸

输出:

[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

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

感谢您的帮助^^

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

您投射了它,但投射不会更改类类型。 快速示例:

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

您的代码是正确的。

最新更新