qianji20000420
本帖最后由 qianji20000420 于 2017-8-6 16:23 编辑

导读

  • NMS概述
  • 如何利用反射来使NMS兼容不同版本的服务端


NMS

  • 什么是NMS呢?
NMS即为服务端核心里的net.minecraft.XXX包  他是服务端核心的最底层



使NMS兼容不同版本的服务端

我们先看看不同版本的NMS包都是什么样的。
这个是1.7.2的
这个是1.7.10的
这个是1.8.0的
每个版本的nms包名都不一样。那我们要如果用到nms里的类,方法什么的   只能适用到一个版本的服务器。
那我们如何来让一个插件能运用nms来适应不同版本的服务器呢?
这就要用到反射的知识了。

但是 这个包名又怎么获取呢?  看似有点规律,又没有规律
所以通过询问UD的大佬们得到了这样一个代码
  1. String packet = Bukkit.getServer().getClass().getPackage().getName();
  2. 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的包名不就是?
  1. String NMSname = "net.minecraft.server." + nmsversion;
复制代码
这样就获取到了NMS的包名。
然后我们就可以利用反射。。  胡作非为了!
比如我们要给一个物品添加 NBT数据,需要先获取到NMS对象
常规的做法应该是
  1. net.minecraft.server.v1_X_RX.ItemStack NMS = CraftItemStack.asNMSCopy(new ItemStack(Material.STONE));
复制代码
但是 那个X是多少 我们虽然知道 但是这块到底怎么写呢?
所以利用反射(asNMSCopy是org.bukkit.craftbukkit.v1_7_R4.inventory.CraftItemStack类下的一个方法)
  1. Class<?> cisi;
  2. Method asNMSCopy;
  3. Class<?> nmsi;
  4. Object item = null;
  5.        try {
  6.            cisi = Class.forName(packet + ".inventory.CraftItemStack");
  7.            asNMSCopy = cisi.getMethod("asNMSCopy", ItemStack.class);
  8.            item = asNMSCopy.invoke(item, new ItemStack(Material.STONE));
  9.         } catch (Exception e) {
  10.                 e.printStackTrace();
  11.         }
复制代码
这里我们这个子类不能抛出异常所以就先用try catch 围上把
这样就成功获取到了nms对象 - item是不是很神奇呢。
接下来的步骤就得看你们自己的了。~
推荐一个NBT教程:http://mcbbs.tvt.im/thread-697478-1-1.html(By:莫老) 讲的很详细啊


下一篇

没有了
返回索引贴
第一次做教程,如果教程中有遗漏的或说错的地方请及时指出哇。~

来自群组: Unknown Domain

第一页 上一页 下一页 最后一页