Skip to content

命令执行器 ​

命令是玩家在聊天框输入的、以 / 开头的字符串,用来触发功能。注册命令后,玩家敲 /你的命令 就能调用插件逻辑。

命令的结构 ​

一个命令字符串按空格切分:

/give Steve diamond 3
  • 命令名:give
  • 参数数组 args:args[0]="Steve"、args[1]="diamond"、args[2]="3"

在 plugin.yml 注册命令 ​

定义命令第一步是在 plugin.yml 声明:

yml
name: HelloWorld
main: tdiant.helloworld.HelloWorld
version: 1
commands:
  rua:
    description: RUA!RUA!RUA!
    aliases: [hi, hello]
    permission: helloworld.use
    permission-message: "你没有权限!"
    usage: "/<command> <玩家名>"

plugin.yml 别写中文

plugin.yml 里出现中文容易出问题。提示语、用法都建议用英文,权限判断的提示在代码里自己处理(见下)。

commands 的子键 ​

键用途
description描述,显示在 /help
aliases别名数组,如 [l, log]
permission所需权限
permission-message无权限时的提示
usage用法说明

不推荐用 plugin.yml 的 permission

plugin.yml 里中文易出问题,且权限控制不够灵活。推荐在代码里用 player.hasPermission(...) 自己判断(见下)。

CommandExecutor 处理命令 ​

类似监听器,命令处理也用一个接口——CommandExecutor。最简单的方式是让主类实现它:

java
public class HelloWorld extends JavaPlugin implements CommandExecutor {
    @Override
    public void onEnable() {
        // 把 rua 命令的处理者设为本类
        getCommand("rua").setExecutor(this);
    }

    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        if (!(sender instanceof Player)) {
            sender.sendMessage("只有玩家能用这个命令!");
            return true;
        }
        Player player = (Player) sender;

        if (args.length == 0) {
            player.sendMessage(ChatColor.RED + "用法:/rua <玩家名>");
            return false; // 返回 false 会显示 plugin.yml 里的 usage
        }

        // 权限判断
        if (!player.hasPermission("helloworld.use")) {
            player.sendMessage(ChatColor.RED + "你没有权限!");
            return true;
        }

        Player target = Bukkit.getPlayer(args[0]);
        if (target == null) {
            player.sendMessage(ChatColor.RED + "玩家不在线或不存在");
            return true;
        }

        target.sendMessage(ChatColor.GOLD + player.getName() + " 对你 RUA 了!");
        return true;
    }
}

参数说明 ​

参数含义
sender命令发送者(玩家/控制台/命令方块),用 CommandSender 统一表示
command命令对象
label实际使用的命令名(可能是别名)
args参数数组

返回值 ​

  • 返回 true:命令执行成功
  • 返回 false:用法错误,服务端会显示 plugin.yml 里的 usage

区分"用法错误"和"业务失败"

参数缺失、格式不对 → 返回 false(让用户看用法)。业务逻辑失败(如玩家不在线)→ 自己发提示、返回 true(别再弹 usage,否则刷屏)。

拆分到单独的类 ​

主类实现 CommandExecutor 适合小插件。大了就拆:

java
public class RuaCommand implements CommandExecutor {
    private final HelloWorld plugin;

    public RuaCommand(HelloWorld plugin) {
        this.plugin = plugin;
    }

    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
        // ... 逻辑
        return true;
    }
}

注册:

java
getCommand("rua").setExecutor(new RuaCommand(this));

Tab 自动补全 ​

实现 TabCompleter 让玩家输命令时按 Tab 能补全参数:

java
public class RuaTabCompleter implements TabCompleter {
    @Override
    public List<String> onTabComplete(CommandSender sender, Command cmd, String alias, String[] args) {
        if (args.length == 1) {
            // 补全在线玩家名
            List<String> names = new ArrayList<>();
            for (Player p : Bukkit.getOnlinePlayers()) {
                if (p.getName().toLowerCase().startsWith(args[0].toLowerCase())) {
                    names.add(p.getName());
                }
            }
            return names;
        }
        return Collections.emptyList();
    }
}

注册:

java
getCommand("rua").setTabCompleter(new RuaTabCompleter());

返回空列表而非 null

没补全内容时返回 Collections.emptyList(),别返回 null——null 会让服务端回退到默认补全(通常是所有玩家名),可能不是你要的。


至此你掌握了插件四大基础:主类、事件、配置、命令。能写出绝大多数常用插件了。接下来进入进阶内容做更复杂的东西。