我们先看看不同版本的NMS包都是什么样的。
这个是1.7.2的
这个是1.7.10的
这个是1.8.0的
每个版本的nms包名都不一样。那我们要如果用到nms里的类,方法什么的 只能适用到一个版本的服务器。
那我们如何来让一个插件能运用nms来适应不同版本的服务器呢?
这就要用到反射的知识了。
但是 这个包名又怎么获取呢? 看似有点规律,又没有规律
所以通过询问UD的大佬们得到了这样一个代码- String packet = Bukkit.getServer().getClass().getPackage().getName();
- String nmsversion = packet.substring(packet.lastIndexOf('.') + 1);
复制代码 我先解释以下这串代码,Bukkit.getServer().getClass()获取到的是CraftServer的Class对象
为什么要获取这个对象呢?
我们发现
这个是1.7.2的
这个是1.7.10的
这个是1.8.0的
! 这命名方式不是一致的吗。
获取完Class对象之后再getPackage().getName()获取包名
在1.7.10服务端输出如下
第二行就是在第一行的基础上取最后一个“.”后面的内容了。
那NMS的包名不就是?
- String NMSname = "net.minecraft.server." + nmsversion;
复制代码 这样就获取到了NMS的包名。
然后我们就可以利用反射。。 胡作非为了!
比如我们要给一个物品添加 NBT数据,需要先获取到NMS对象
常规的做法应该是
- net.minecraft.server.v1_X_RX.ItemStack NMS = CraftItemStack.asNMSCopy(new ItemStack(Material.STONE));
复制代码 但是 那个X是多少 我们虽然知道 但是这块到底怎么写呢?
所以利用反射(asNMSCopy是org.bukkit.craftbukkit.v1_7_R4.inventory.CraftItemStack类下的一个方法)
- Class<?> cisi;
- Method asNMSCopy;
- Class<?> nmsi;
- Object item = null;
- try {
- cisi = Class.forName(packet + ".inventory.CraftItemStack");
- asNMSCopy = cisi.getMethod("asNMSCopy", ItemStack.class);
- item = asNMSCopy.invoke(item, new ItemStack(Material.STONE));
- } catch (Exception e) {
- e.printStackTrace();
- }
复制代码 这里我们这个子类不能抛出异常所以就先用try catch 围上把
这样就成功获取到了nms对象 - item是不是很神奇呢。
接下来的步骤就得看你们自己的了。~
推荐一个NBT教程:http://mcbbs.tvt.im/thread-697478-1-1.html(By:莫老) 讲的很详细啊
|
|
|