第一章 第四节 如何编写命令
参与编写者: MagicLu550
建议学习时间: 30分钟
学习要点: 学习自己创建一个简易的命令,了解指令和指令映射,了解SimpleCommand的使用
其实创建一个简易的命令很简单,我们可以在PluginBase
中重写onCommand
方法,进行equals
识别,比如
1 | public class PluginMain extends PluginBase{ |
nukkit的原生命令也是很多基于Command创建的.很多项目是需求指令
以使得用户和您的项目操作,也就是作为一个 接口(Interface) ,接下来我们介绍以下nukkit的命令。
nukkit的命令的父类是Command,它有很多的构造方法
1 | public Command(String name) { |
我们可以知道,nukkit的命令都是toLowerCase的,即小写,也就是说,命令不区分大小写。
对于命令如何存储,服务端如何识别一个命令,我们从源码中找到以下资料:
–
命令的区分标识是fallBackPrefix+:+label,默认为指令的名称,一般fallBackPrefix都写""
这一块知识缺点将会有其他人补充[1]
代码依据 - SimpleCommandMap.java
1 | 159 private boolean registerAlias(Command command, boolean isAlias, String fallbackPrefix, String label) { |
–
存储指令的容器是实现CommandMap接口的,即SimpleCommandMap,我们可以通过
1 | this.getServer().getCommandMap(); |
得到CommandMap.
Command,CommandMap有很多方法
-
Command
-
根构造方法的参数为
1
2
3
4
5
6
7
8
9String name, String description, String usageMessage, String[] aliases
第一个name是指令名称,最终会转换为全小写
第二个description是指令介绍,用于给玩家查看使用的
第三个usageMessage就是当玩家对命令使用错误,返回的信息
第四个aliases就是指令的别名,指令可以有多个别名当然,也有简化的构造方法,可以根据你的需求任意调用,这里不多阐述,其他的都是为默认值
-
Command的主要属性
如同command的构造方法一样,command我们需要了解的属性基本也就是这四个。其他属性将会
在nukkit原理解析的时候讲解 -
Command的比较常用的方法
-
boolean execute(CommandSender commandSender, String label, String[] strings)
这个方法是需要开发者自行实现的方法,当指令被触发,就会执行execute里的代码
它的参数我们在第二章提到了 -
String getName()
这个可以获取指令的名称
其余方法我们将会在后期附件讲解到,如果有想要知悉的其他方法,我们会另外在这里做补充,
或者您认为常用的,也可以pull request添加进去 -
-
-
CommandMap
- boolean register(String fallbackPrefix, Command command)
可以注册指令,fallbackPrefix是前缀,用于服务端存储命令对象的标识
nukkit的本地命令的fallbackPrefix为nukkit
command则为你的自定义命令对象 - void registerAll(String fallbackPrefix, List<? extends Command> commands)
这个可以一次性注册多个指令 - boolean dispatch(CommandSender sender, String cmdLine)
这个调用一个命令,cmdLine就是日常所输入的命令 - void registerSimpleCommands(Object object)
这个是调用简单指令,通过注解实现的指令对象,我们后面将会演示如何使用它。
- boolean register(String fallbackPrefix, Command command)
nukkit官方后来推出一系列简化操作,如SimpleCommand,SimpleConfig等,我们这里解释以下SimpleCommand
SimpleCommand运用了注解,同样通过 反射 实现的,我们可以看到官方的源码来探讨它的使用
SimpleCommandMap.java
1 | @Override |
@Override
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
if (this.forbidConsole && sender instanceof ConsoleCommandSender) {
this.sendInGameMessage(sender);
return false;
} else if (!this.testPermission(sender)) {
return false;
} else if (this.maxArgs != 0 && args.length > this.maxArgs) {
this.sendUsageMessage(sender);
return false;
} else if (this.minArgs != 0 && args.length < this.minArgs) {
this.sendUsageMessage(sender);
return false;
}
boolean success = false;
try {
//这里执行我们的命令
success = (Boolean) this.method.invoke(this.object, sender, commandLabel, args);
} catch (Exception exception) {
Server.getInstance().getLogger().logException(exception);
}
if (!success) {
this.sendUsageMessage(sender);
}
return success;
}
1 | 这段代码我们可以知道方法的参数有规范要求的 |
最终通过registerSimpleCommand注册即可.事实上是对Command的封装
command的用户组(这里参考自snake1999的文章)
1 | permissions: #这个标签我们只写一次就ok了 |
这里我们发现了default,这个的选项有以下几种
- op,代表服务器管理员,在ops.txt中规定。
- notop,代表除服务器管理员外的所有玩家。
- true,代表所有玩家。
- false,代表空集。如果某个命令对应这个权限,那就没有人能够使用这个命令(控制台除外)。
大家可以根据这些选项来控制指令的使用范围了
参考文献: