如何从一个铸造对象调用一个方法 - Reflection API

时间:2015-03-23 03:59:48

标签: java reflection bukkit

我需要使用来自Java中的类型化方法的帮助。如果没有反射,它看起来像PlayerConnection con = ((CraftPlayer) player).getHandle().playerConnection;,但由于我使用的API用于此程序/插件,包后缀会随版本号而变化,所以我试图弄清楚让它发挥作用的思考。稍后在代码中,我尝试使用con变量将其作为数据包发送,使用PlayerConnection类型中的方法。所以没有反射它看起来像con.sendPacket(packet);数据包变量我想我得到了它。

对于后台代码信息,我已经创建了一个获取服务器版本的方法,并创建了另一个获取类的方法。因此,您可以键入getClass("")而不是显示Class.forName();,而getClass()方法返回Class并且已经在其中添加了包名称。有关更多信息,这将是一个示例:

input:
getClass("Packet");

output:
net.minecraft.1_8R2.Packet;

它将返回该包的类。

1 个答案:

答案 0 :(得分:0)

您可以使用Class<?>

获取.newInstance()的新实例
Class<?> clazz = getClass("Packet");
Object packet = clazz.newInstance();

然后,要获得CraftPlayer课程,您可以使用:

Class<?> craftplayer = getClass("CraftPlayer"); 
//make another method that chooses the org.bukkit.* class
//instead of the net.minecraft.server.* class, and use that here
//in place of getClass()

然后,要获得播放器的句柄,您可以使用:

Method getHandle = craftplayer.getMethod("getHandle");
Object nms = getHandle.invoke(player);

接下来,您可以使用以下方法获取sendPacket()方法:

Field connfield = nms.getClass().getField("playerConnection");
Object connection = connfield.get(nms);
Method sendPacket = connection.getClass().getMethod("sendPacket", clazz); 
//clazz is getClass("Packet");

然后您可以使用以下命令调用它:

sendPacket.invoke(connection, packet);
//packet is getClass("Packet").newInstance()

所以,你可以使用这样的东西:

try{
  Class<?> clazz = getClass("Packet");
  Object packet = clazz.newInstance();

  Class<?> craftplayer = getClass("CraftPlayer"); 
  //make another method that chooses the org.bukkit.* class instead of the net.minecraft.server.* class, and use that here

  Method getHandle = craftplayer.getMethod("getHandle");
  Object nms = getHandle.invoke(player);

  Field connfield = nms.getClass().getField("playerConnection");
  Object connection = connfield.get(nms);
  Method sendPacket = connection.getClass().getMethod("sendPacket", clazz); 
  sendPacket.invoke(connection, packet);
}
catch(Exception ex){
  //an error occurred, and the packet could not be sent.
  ex.printStackTrace();
}