【问题标题】:onCommand() setup correctly but doesn't get executed at allonCommand() 设置正确,但根本没有执行
【发布时间】:2019-08-02 10:55:46
【问题描述】:

我的问题是我有一个简单的 Minecraft 插件,我只想让它执行一个命令。我以前做过命令,所以这些步骤对我来说很清楚。我的 plugin.yml 设置正确(服务器检测到我添加的命令并显示它的帮助页面等),并且 onCommand() 函数的设置方式也与我在所有其他插件中的设置方式相同。插件本身可以工作(主要是我测试的 onEnable() 函数)但是 onCommand() 只是没有被调用。

我已经尝试过不同的 plugin.yml 格式以及将 @Override 注释添加到 onCommand() 中,Eclipse 并不真正希望我这样做。我也知道我使用的 API (com.PluginBase) 可以在其他项目中使用它。执行命令时不会产生异常,在聊天中只显示我输入的命令。

这是 Main.java:

package org.Professions;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.material.Command;
import org.bukkit.plugin.java.JavaPlugin;

import com.PluginBase.Chat;

public class Main extends JavaPlugin {

    public void onEnable() {
        Chat.getInstance().sendErrorMessageToConsole("Professions enabled");
        Bukkit.getPluginCommand("profession").setExecutor((CommandExecutor) this);
    }

    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {

        Chat.getInstance().sendErrorMessageToConsole("Got the command: " + label);

        /*
         * Check if command sender is a player
         * and if the command is for this plugin
         */
        if
        (
                sender instanceof Player == false
                || !label.toLowerCase().equals("profession")
        ) {
            return true;
        }

        // Get the player who send the command
        Player player = (Player) sender;

        // Check if the player has given the right amount of arguments
        if (args.length != 1) {

            // Notify the player of invalid argument use
            Chat.getInstance().sendMessageToPlayer(player, ChatColor.RED + "Invalid arguments. Usage: /profession <name>");

            // Stop executing code after we've determined an incorrect amount of arguments
            return true;
        }

        // Get the players new profession from the first argument he gave for the command
        String profession = args[1];

        // Set the players name in the playerlist to feature his professions
        player.setPlayerListName
        (
                ChatColor.GREEN + "[" + profession + "] "   // the players' profession
                + ChatColor.WHITE + player.getName()        // the actual player name
        );

        // Always return true since if the command wasn't for this plugin we return false earlier
        return true;
    }
}

这是我的 plugin.yml:

name: Professions
main: org.Professions.Main
version: 1.0
api-version: 1.13
depend: [PluginBase]
commands:
    profession:
        description: Change your profession
        usage: /<command>
        aliases: [p]

【问题讨论】:

  • 在 IntelliJ 中,您甚至可以通过单击生成重载方法。只需扩展一个类并按 Alt + Insert,然后选择“覆盖方法”,intellij 将采用所有正确的导入和方法签名。如果需要,我相信 Eclipse 会通过插件提供相同的功能

标签: java minecraft bukkit


【解决方案1】:

您忘记实现 CommandExecutor 并注册命令。

您的代码应如下所示:

public class Main extends JavaPlugin implements CommandExecutor{

    @Override
    public void onEnable(){
    //...
    getCommand("profession").setExecutor(this);
    }
    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {

//...
    }
}

另外,我想给你一些关于我的世界插件编码的建议。您不应该在主类中发出命令,它们应该属于自己的类。例如,您的 profession 命令将与它的所有参数一起进入 ProfessionCmd 类(例如,/profession give 也将在那里)。

【讨论】:

    【解决方案2】:

    这是您的问题的原因吗?

    // Get the players new profession from the first argument he gave for the command
    String profession = args[1];    // <-- [0] ?
    

    【讨论】:

    • 这是一个错误(发布后很快就修复了)但实际错误是我使用了 'org.bukkit.material.Command' (这是游戏中的实际块)而不是 'org .bukkit.command.Command'(这是指聊天行命令),这当然意味着我要求的参数类型与超类方法不同,因此实际上并没有覆盖该方法
    • 好吧,那么公平:) 享受
    • 为什么args[1] 会成为问题?如果 args 在数组中没有索引为 1 的元素,插件将抛出 ArrayIndexOutOfBoundsException
    • 你当然是对的。我“只是”提议 - 通过推论 ;-) 因为我不知道是否可以在所有情况下有效地显示异常(我不是 Minecraft 插件专家),所以我专注于在聊天中没有输出的代码问题..因此只引导我到与前面的 IF 和相关评论不一致的 args[1] 行。通过消除,如果我错了,问题必须更加微妙:)
    【解决方案3】:

    而不是这个命令注册:

    Bukkit.getPluginCommand("profession").setExecutor((CommandExecutor) this);
    

    使用:

    getCommand("profession").setExecutor(this);
    

    您不需要将 CommandExecutor 与您的主类一起转换,因为它已经在 J​​avaPlugin 中继承。

    getCommand()包含在JavaPlugin抽象类中,所以不必以Bukkit.getPluginCommand()开头。它只用于其他资源,如果你想得到一个命令作为命令对象。

    您还可以在onCommand 方法中检查玩家执行的命令。仅当您在一个类中处理多个命令时才需要这样做。

    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
        if (cmd.getName().equalsIgnoreCase("profession")) {
            // code here
        }
    }
    

    【讨论】:

    • @Override 不是必需的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-12
    • 2018-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多