开发前的准备:
- Java基础语法
- Java 反射
- 面向对象思想
- 耐心
普通注册指令
具体见 莫老(Zoyn_) 的文章 Bukkit插件开发教程 - 命令
过程简要:
- 利用plugin.yml注册指令(PluginCommand)
- 写CommandExecutor(与TabExecutor)
- 给PluginCommand设置CommandExecutor(与TabExecutor)
- 愉快的玩耍
优点:
方便(个鬼)- 便于理解
- 用户可以通过查看plugin.yml来了解插件的指令
缺点:
- 用户可自定义性不强(必须由插件作者修改插件中的代码才可以达到更新指令的效果)
- 不方便 每次注册指令都要写一堆代码
那么,有没有一种方法 可以使用户可以自定义指令呢?
当然有! 那就是 利用反射注册指令
反射注册指令
教程:
首先我们来看PluginCommand的Javadoc
我们可以找到 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实例啦!
首先是Command的方法(用于设置指令的基础属性):
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);
过程简要:
- 利用Constructor构造一个PluginCommand
2.给PluginCommand设置基础属性
3.利用CommandMap注册PluginCommand
4.愉快的玩耍
优点:
- 方便(写个函数)
- 可自定义性强(可以通过读取配置文件来实现用户自定义指令)
可以装杯
缺点:
- 难于理解(也不是很难)
- 用户不可以通过查看plugin.yml来了解插件的指令