我需要使用来自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;
它将返回该包的类。
答案 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();
}