Bukkit 利用反射注册指令

开发前的准备:

  • Java基础语法
  • Java 反射
  • 面向对象思想
  • 耐心

普通注册指令

具体见 莫老(Zoyn_) 的文章 Bukkit插件开发教程 - 命令

过程简要:

  1. 利用plugin.yml注册指令(PluginCommand)
  2. CommandExecutor(与TabExecutor)
  3. PluginCommand设置CommandExecutor(与TabExecutor)
  4. 愉快的玩耍

优点:

  • 方便(个鬼)
  • 便于理解
  • 用户可以通过查看plugin.yml来了解插件的指令

缺点:

  • 用户可自定义性不强(必须由插件作者修改插件中的代码才可以达到更新指令的效果)
  • 不方便 每次注册指令都要写一堆代码

那么,有没有一种方法 可以使用户可以自定义指令呢?
当然有! 那就是 利用反射注册指令


反射注册指令

教程:

首先我们来看PluginCommand的Javadoc

我们可以找到 PluginCommand 这个类的构造器:

PluginCommand构造器

可以看到,我们只需要提供指令名称(String name)和主类实例(Plugin owner)即可构造一个指令
但是呢 这个构造器是被protected修饰的
怎么办呢?

没错 是时候使用反射了!
直接上代码:

#用getDeclaredConstructor方法获取一个类的构造器
Constructor constructor = PluginCommand.class.getDeclaredConstructor(String.class, Plugin.class);
#忽略访问修饰符的检查
constructor.setAccessible(true);

这时候,要构造一个PluginCommand就非常简单了:

String name = "test"
Plugin plugin = Main.getInstance;
PluginCommand command = constructor.newInstance(name, plugin);

然后我们就可以愉快地操作这个PluginCommand实例啦!


PluginCommand的方法

首先是Command的方法(用于设置指令的基础属性):


Command方法1
Command方法2
List aliases;
command.setAliases(aliases);

以此类推...

给PluginCommand设置CommandExecutor

command.setExecutor(commandExecutor);

给PluginCommand设置TabExecutor

command.setTabCompleter(tabExecutor);

这里不再做详解 看Javadoc就可以 (有脑子就能看懂)

我们现在有一个PluginCommand实例 并且已经给它设置了CommandExecutor(与TabExecutor)
但是我们并没有在Bukkit里注册它 那么怎么注册呢?

通过查阅Javadoc,我们可以发现PluginCommand的父类Command有两个方法:


这两个方法一个是注册指令 一个是注销指令

一定有人会问: 这个CommandMap是什么?
CommandMap的Javadoc (里面有方法接上)
这里不做详解 ...

了解CommandMap是什么后,我们该怎么获取它呢?
SimplePluginManager Javadoc
废话不多说 直接上代码

#获取SimplePluginManager类中的commandMap字段
Field field = SimplePluginManager.class.getDeclaredField("commandMap");
#忽略访问修饰符的检查
field.setAccessible(true);
CommandMap commandMap = (CommandMap) f.get(plugin.getServer().getPluginManager());

然后是注册指令PluginCommand:

command.register(commandMap);

到这里 一个完整的指令已经注册到了Bukkit中了
我们可以愉快地玩耍啦!

完整代码:

#用getDeclaredConstructor方法获取一个类的构造器
Constructor constructor = PluginCommand.class.getDeclaredConstructor(String.class, Plugin.class);
#忽略访问修饰符的检查
constructor.setAccessible(true);

String name = "test"
Plugin plugin = Main.getInstance;
PluginCommand command = constructor.newInstance(name, plugin);
String permission;
command.setPermission(permission);
List aliases;
command.setAliases(aliases);
command.setExecutor(commandExecutor);
command.setTabCompleter(tabExecutor);

#获取SimplePluginManager类中的commandMap字段
Field field = SimplePluginManager.class.getDeclaredField("commandMap");
#忽略访问修饰符的检查
field.setAccessible(true);
CommandMap commandMap = (CommandMap) f.get(plugin.getServer().getPluginManager());
command.register(commandMap);

过程简要:

  1. 利用Constructor构造一个PluginCommand
    2.给PluginCommand设置基础属性
    3.利用CommandMap注册PluginCommand
    4.愉快的玩耍

优点:

  • 方便(写个函数)
  • 可自定义性强(可以通过读取配置文件来实现用户自定义指令)
  • 可以装杯

缺点:

  • 难于理解(也不是很难)
  • 用户不可以通过查看plugin.yml来了解插件的指令

你可能感兴趣的:(Bukkit 利用反射注册指令)