# 命令执行器

# 认识命令机制

MC中的命令是一个字符串, 用来实现游戏内高级功能.

在MC客户端中, 玩家将在聊天框内输入命令.
当且仅当在“聊天”内, 命令与普通的聊天内容的区别在于其内容的第一个字符是一个斜杠/.

该字符串中的空格表示一个分隔, 开头的一节为命令的名称.
除去命令的名称, 剩下的部分从空格处断开可以分成一个数组.

例如, a b c是一个命令, 其命令名称为a, 其参数可用一个数组args表示为:

args[0]: "b"
args[1]: "c"

# 定义新命令

如果我们需要定义一个新的命令, 首先我们需要在plugin.yml文件中增加相关信息:

name: HelloWorldPlugin
main: rinya.bukkit.helloworldplugin.HelloWorldPluginMain
version: 1
author: rinya
commands:
  rua:
    description: RUA!RUA!RUA!

plugin.yml文件里, 我们增加了commands.rua键, 这就可以代表注册了一个rua命令. 我们给他增加了一个description子键表示对该命令的描述, 描述信息会出现在/help菜单里.

请注意, 请尽可能不要在plugin.yml文件里出现中文! 这可能会出现问题!

commands.命令名键可以有很多个子键, 这些都不是必须添加的, 甚至它可以没有子键. 具体子键如下:

用途 例子
description 描述作用. 将会在/help中显示 description: "I am a cute command."
aliases 设置别名. 比如登录插件login命令也可以用/l命令代替. aliases: [l, log]
permission 设置命令需要的权限 permission: rua.use
permission-message 没权限时的提示语 permission-message: "YOU HAVE NO PERMISSION!"
usage 命令的用法. usage: /<command> YOUR_NAME

注意:

  1. <command>在usage里可以代表你的命令名.
  2. 你的命令设置了aliases后命令名不能按照aliases称呼. 比如你给login命令设置了aliases: [l]你不能也叫他l命令, 它还是login命令.
  3. 不推荐使用permissionpermission-message, 因为plugin.yml里出现中文爱出问题. 事实上, 我们可以用Player.hasPermission方法在监听命令的时候自己亲自判断有没有权限.
  4. 如果一个名称被别的插件注册了或设置为了某个命令的别称, 会出现冲突问题, 尽量避免.
  5. 别弄中文的命令.

# onCommand

我们可以类似Listener, 做一个CommandExecutor监听命令.

public class DemoCommand implements CommandExecutor {
	@Override
	public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
		sender.sendMessage("HI!");
		return true; //true代表命令执行没问题, 返回false的话Bukkit会给命令输入方一个错误提示语
	}
}

然后也同理, 在onEnable里加入注册:

Bukkit.getPluginCommand("rua").setExecutor(new DemoCommand());

但是如果onCommand方法放在了主类里, 那就不需要注册了.

onCommand方法有四个参数, 分别为:

  1. CommandSender sender —— 命令输入方, 实际传入的有可能是Console, 有可能是Player或者其他情况.
  2. Command cmd —— 所执行的命令对象.
  3. String[] args —— 参数. 例如/rua a b的话, args[0]为"a", args[1]为"b".

警告: 字符串的比较, 请不要使用==, 因为其比对的是内存地址, 可能造成一些没有预料到的结果! 建议使用equals方法, 例如args[0].equals(string)

如果你的命令希望只被玩家使用, 通常这样判断:

if(!(sender instanceof Player)){
	sender.sendMessage("你不是玩家!不能用!");
	return true; //不返回true, Bukkit还会显示出来一串错误提示, 你可以试试看.
}

判断完为玩家后, 若希望判断其有没有权限执行命令, 可以:

Player p=(Player)sender; //sender可以直接强转为Player
if(p.hasPermission("rua.use")){
	p.sendMessage("你有权限!");
}

玩家将会在聊天区域内看到输出:

你有权限!

Bukkit内可以用ChatColor表示颜色前缀, 例如:

p.sendMessage(ChatColor.RED+"你输错了!"); //输出红色的 "你输错了"
p.sendMessage(ChatColor.RED+"还可以"+ChatColor.YELLOW+"两种颜色混着用!");
p.sendMessage(ChatColor.BOLD+"猜猜我会显示成什么效果");
p.sendMessage(ChatColor.RED+""+ChatColor.BOLD+"猜猜我会显示成什么效果");
p.sendMessage(ChatColor.BOLD+""+ChatColor.RED+"猜猜我会显示成什么效果");

String str = "&4哈哈"; //假如你从配置文件里读出来了一串 "&4哈哈".
p.sendMessage(str); //这样会显示出 "&4哈哈", 不带颜色
p.sendMessage(ChatColor.translateAlternateColorCodes('&',str)); //这样就带颜色了

还有其他的好玩的东西, 把下面的代码放在onEnable方法里试试看:

System.out.println(ChatColor.RED+"猜猜我是什么效果"); 
this.getLogger().info(ChatColor.RED+"你再猜猜我是什么效果");

以后推荐您用getLogger().info方法代替System.out.println(也就是sout、sysout方法)!

在实际应用的时候, 还要小心args.length! 玩家只输入/rua没有参数的时候, 小心因为自己的疏忽造成ArrayIndexOutOfBoundsException!