BlocklyNukkit WIKI

这里是BN百科

章节导览


命令系统

本章节中,将带您了解nukkit的命令系统,以及如何在BlocklyNukkit中使用它。

基本命令

在BlocklyNukkit中,我们使用manager基对象中的createCommand函数来创建新命令:
manager基对象

方法名 参数 返回值 解释
createCommand String name,String des,String call void 创建名称为name,描述为des的命令,回调函数的函数名为call
createCommand String name,String des,String call,String per void 同上,但是仅限有per权限的玩家可用

命令的回调函数需要接受两个参数,分别是命令发出者和命令的参数,我们通常用senderargs来接收这两个参数。 命令发出者是执行这个命令的事物的信息抽象,它并不是命令发出者本身!
命令发出者可以是玩家、可以是控制台、也可以是远程命令(QQ群互动、某些mc面板)。 关于命令发出者对象的详细信息,点击“命令发出者”跳转到javadoc。后面我们会详细讲述。
命令的参数是一个由字符串组成的数组(python中称列表),这个数组记录了玩家输入命令主名称后的内容。 每一条命令都由命令前缀、命令名称和命令参数三部分组成。
命令前缀是指命令开头的/,控制台输入时无前缀。
命令名称是命令的主要标识符,用于区分不同的命令,是每一条命令中第一个空格之前的、命令前缀之后的部分,如果没有空格的话,命令名称就是这条命令前缀之后的剩余部分。
命令参数是除了上述两项之外剩余内容一个空格分割成的数组。
举个例子:

/gamemode 1 Steve
命令前缀是/
命令名称是gamemode
命令参数是"1","Steve"

创建一个命令只需要调用createCommand即可,其中函数myCommandCallbak的名称可以是任意的:

function myCommandCallback(sender,args){
    console.log("命令被触发");
}
manager.createCommand("mycommand","我的测试命令","myCommandCallback");
def myCommandCallback(sender,args):
    logger.info(u"命令被触发")
manager.createCommand(u"mycommand",u"我的测试命令",u"myCommandCallback")
function myCommandCallback(sender,args)  
    logger:info("命令被触发")
end
manager:createCommand("mycommand","我的测试命令","myCommandCallback")  
function myCommandCallback($sender,$args){
    echo "命令被触发"; 
}
$manager->createCommand("mycommand","我的测试命令","myCommandCallback");

子命令与参数

注册命令的时候,我们注册的命令不能包含空格,你可能很多情况下会看见类似于money add xxxxxx这样的命令,实际上,这是通过判断参数的方式实现的
我们现在来实现一个包含firstsecond两个子命令的命令,并且在输入的命令不符合这两个子命令时发出提示:

function myCommandCallback(sender,args){
    if(args[0]=="first"){
        console.log("第一个子命令");
    }else if(args[0]=="second"){
        console.log("第二个子命令");
    }else{
        console.log("命令格式不对");
    }
}
manager.createCommand("mycommand","我的测试命令","myCommandCallback");
def myCommandCallback(sender,args):
    if args[0] == u"first":
        logger.info("第一个子命令")
    elif args[0] == u"second":
        logger.info("第二个子命令")
	else:
        logger.info(u"命令格式不对")
manager.createCommand(u"mycommand",u"我的测试命令",u"myCommandCallback")
function myCommandCallback(sender,args)  
    if(args[0] == "first") then
        logger:info("第一个子命令")
    elseif(args[0] == "second") then
        logger:info("第二个子命令")
    else
        logger:info("命令格式不对")
    end
end
manager:createCommand("mycommand","我的测试命令","myCommandCallback")  
function myCommandCallback($sender,$args){
    if(strcmp($args[0],"first") == 0){
        echo "第一个子命令";
    }else if(strcmp($args[0],"second") == 0){
        echo "第二个子命令";
    }else{
        echo "命令格式不对"; 
    }
}
$manager->createCommand("mycommand","我的测试命令","myCommandCallback");

命令发送者

之前我们已经提到过了命令发送者,通过这个对象我们可以获知一些输入命令的东西的基本信息。
javadoc上可以看到,命令发送者有如下几个常用的函数:

函数名 参数 返回值 解释
isPlayer void boolean 命令是否是玩家发出的
isOp void boolean 执行命令的人是否有op权限(控制台执行算有)
sendMessage String message void 向命令发送者返回信息
getName void String 获取命令发送者的名称(控制台发出恒为CONSOLE)

通过这些函数,我们可以对轻松地返回命令执行信息到执行命令的玩家,而不是无脑把信息都输出到控制台,还可以进行检测,让某个命令只能被op执行。
这里给出一个简单的示例:

function myCommandCallback(sender,args){
    if(sender.isPlayer()){
        console.log("玩家在执行命令");
    }else{
        console.log("控制台在执行命令");
    }
    if(sender.isOp()){
        sender.sendMessage("尊敬的OP,命令成功执行");
    }else{
        sender.sendMessage("您不配!");
    }
}
manager.createCommand("mycommand","我的测试命令","myCommandCallback");
def myCommandCallback(sender,args):
    if sender.isPlayer():
        logger.info(u"玩家在执行命令")
    else:
        logger.info(u"控制台在执行命令")
    if sender.isOp():
        sender.sendMessage(u"尊敬的OP,命令成功执行")
    else:
        sender.sendMessage(u"您不配!")
manager.createCommand(u"mycommand",u"我的测试命令",u"myCommandCallback")
function myCommandCallback(sender,args)  
    if(sender:isPlayer()) then
        logger:info("玩家在执行命令")
    else
        logger:info("控制台在执行命令")
    end
    if(sender:isOp()) then
        sender:sendMessage("尊敬的OP,命令成功执行")
    else
        sender:sendMessage("您不配!")
    end
end
manager:createCommand("mycommand","我的测试命令","myCommandCallback")  
function myCommandCallback($sender,$args){
    if($sender->isPlayer()){
        echo "玩家在执行命令";
    }else{
        echo "控制台在执行命令";
    }
    if($sender->isOp()){
        $sender->sendMessage("尊敬的OP,命令成功执行");
    }else{
        $sender->sendMessage("您不配!");
    }
}
$manager->createCommand("mycommand","我的测试命令","myCommandCallback");

再次提醒,命令发送者并不是玩家,你可以通过getName获取命令发送者的名字,如果是玩家发送的,那么获取到的名字就是玩家的名字,再通过server基对象获取玩家对象。

function myCommandCallback(sender,args){
    if(sender.isPlayer()){
        var player = server.getPlayer(sender.getName());
        //player变量是执行命令的玩家
    }
}
manager.createCommand("mycommand","我的测试命令","myCommandCallback");
def myCommandCallback(sender,args):
    if sender.isPlayer():
        player = server.getPlayer(sender.getName())
        # player变量是执行命令的玩家
manager.createCommand(u"mycommand",u"我的测试命令",u"myCommandCallback")
function myCommandCallback(sender,args)  
    if(sender:isPlayer()) then
        player = server:getPlayer(sender:getName())
        -- player变量是执行命令的玩家
    end
end
manager:createCommand("mycommand","我的测试命令","myCommandCallback")  
function myCommandCallback($sender,$args){
    global $server;
    if($sender->isPlayer()){
        $player = $server->getPlayer($sender->getName());
        //player变量是执行命令的玩家
    }
}
$manager->createCommand("mycommand","我的测试命令","myCommandCallback");

命令权限

很多命令都由命令的权限节点控制,bn同样给提供了通过权限节点来控制玩家是否能够执行一条命令的功能。

补充信息:权限节点
权限节点,是nukkit提供的一种控制玩家能力的系统,不同于原版的访客、成员、管理员系统,权限节点系统能够更精确的控制玩家的能力,比如精确到某一条特定的命令是否可以执行。
通过此系统,你可以让非op玩家执行一些只能op执行的命令,也可以让op不能执行某些命令。在nukkit中,权限节点系统和op系统两个玩家能力控制系统是并存的。
每一个权限节点都是一个字符串,内容是任意的,但我们通常使用插件名.命令名的格式来进行。
你可以通过LuckPerm等插件来控制权限节点,没有命令所需权限节点的玩家在输入命令的时候不会收到命令补全提示,也不会在玩家的命令列表或帮助列表出现。

创建一个权限节点很简单,可以通过manager基对象下面的createPermission函数来创建。
创建了命令节点之后,我们可以通过manager基对象下面的removePermission函数来把权限节点删除。
请注意,创建的权限节点在服务器关闭时不会保存,但玩家拥有的权限节点会被保留,你需要每次在服务器启动的时候都重新创建。
创建了权限节点之后,我们就可以通过manager基对象下面的checkPlayerPermission函数来检查玩家是否有指定的权限节点。通过此方法,你可以做到只让指定的玩家执行命令。

P.S. 推荐使用此方法来制作只能OP执行的命令,这样普通玩家就不会在命令列表中看到你注册的命令了

方法名 参数 返回值 解释
createPermission String per,String description,String defaultper void 创建一个权限,名称为per,描述为description,默认授予组为defaultper(OP/ALL/NONE 管理员/全体/控制台)
removePermission String per void 删除一个权限
checkPlayerPermission String per,Player player boolean 检查一个玩家是否有per权限
createCommand String name,String des,String call,String per void 同上,但是仅限有per权限的玩家可用

这里将上面的例子用权限节点改写一下:

manager.createPermission("demo.mycommand","我测测试命令的权限节点","OP");
function myCommandCallback(sender,args){
    if(manager.checkPlayerPermission("demo.mycommand",server.getPlayer(sender.getName()))){
        sender.sendMessage("命令成功执行");
    }else{
        sender.sendMessage("您不配!");
    }
}
manager.createCommand("mycommand","我的测试命令","myCommandCallback");
manager.createPermission(u"demo.mycommand",u"我测测试命令的权限节点",u"OP")
def myCommandCallback(sender,args):
    if manager.checkPlayerPermission(u"demo.mycommand",server.getPlayer(sender.getName())):
        sender.sendMessage(u"命令成功执行")
    else:
        sender.sendMessage(u"您不配!")
manager.createCommand(u"mycommand",u"我的测试命令",u"myCommandCallback")
manager:createPermission("demo.mycommand","我测测试命令的权限节点","OP")
function myCommandCallback(sender,args)  
    if(manager:checkPlayerPermission("demo.mycommand",server:getPlayer(sender:getName()))) then
        sender:sendMessage("尊敬的OP,命令成功执行")
    else
        sender:sendMessage("您不配!")
    end
end
manager:createCommand("mycommand","我的测试命令","myCommandCallback")  
$manager->createPermission("demo.mycommand","我测测试命令的权限节点","OP");
function myCommandCallback($sender,$args){
    global $manager;
    global $server;
    if($manager->checkPlayerPermission("demo.mycommand",$server->getPlayer($sender->getName()))){
        $sender->sendMessage("命令成功执行");
    }else{
        $sender->sendMessage("您不配!");
    }
}
$manager->createCommand("mycommand","我的测试命令","myCommandCallback");

你也可以把您不配!改成原版命令执行失败的提示语,这样看起来更不违和。

闭包与匿名函数

在BlocklyNukkit中,我们通常把匿名函数(js),箭头函数(js),lambda表达式(python),闭包(lua & php)统称为匿名函数。
BlocklyNukkit的API中所有传入函数名的地方,都可以通过F()函数将匿名函数修饰后当作函数名传入。这个匿名函数将在调用指定的函数名的函数时被调用。

比如,在命令中,我们可以这样使用:

manager.createCommand("mycommand","我的测试命令",F(function (sender,args){
    console.log("命令被触发");
}));
manager.createCommand(u"mycommand",u"我的测试命令",F(lambda sender,args:logger.info(u"命令被触发")))
manager:createCommand("mycommand","我的测试命令",F(function (sender,args)  
    logger:info("命令被触发")
end))  
$manager->createCommand("mycommand","我的测试命令",F(function myCommandCallback($sender,$args){
    echo "命令被触发"; 
}));

命令补全器

详见命令补全器章节

执行命令

众所周知,你可以在游戏聊天框中输入/xxx...来执行命令,也可以在控制台输入命令来执行。
当然,你可以通过插件来执行命令,server基对象中有关于执行命令的dispatchCommand函数,查阅编程开发文档可知:

返回值类型 函数名
boolean dispatchCommand(CommandSender sender, String commandLine)
ConsoleCommandSender getConsoleSender()

dispatchCommand函数第一个参数是命令发送者,它既可以是通过getConsoleSender函数获得的ConsoleCommandSender(控制台命令发送器),此时命令将相当于从服务器控制台输入并执行,也可以是一个玩家对象,此时命令将相当于在玩家聊天框中输入并执行,不过并不会在玩家客户端上打开聊天框,这样执行命令相当于原版execute,这将受到玩家权限限制。第二个参数是命令具体内容字符串。


不满意?前往编辑此页面

导航