开启辅助访问     
收藏本站

站内搜索

搜索

Minecraft(我的世界)苦力怕论坛

[BE教程] 附加包教程:56.命令

 发表于 2025-6-7 15:32:32 来自手机|显示全部楼层|阅读模式 IP:天津
本帖最后由 Cat_Anchor 于 2025-6-20 19:49 编辑

前言
在 1.21.80.22 中,官方加入了自定义命令功能,可以通过 SAPI 自定义命令。
准备
首先需要在 manifest.json 中导入 @minecraft-server 模块。在 dependencies 字段下:
  1. {
  2.   "module_name": "@minecraft/server",
  3.   "version": "2.1.0-beta"
  4. }
复制代码

注意其中的 version 字段。在 1.21.80 中,应该填写 2.0.0-beta,而在 1.21.90 中应该是 2.1.0-beta。

然后添加脚本模块,如果以前没有脚本模块的话。在 modules 字段下:
  1. {
  2.   "type": "script",
  3.   "language": "javascript",
  4.   "uuid": "", // 需要填写 UUID。
  5.   "entry": "main.js", // 可以替换为其他名称,但必须以 .js 结尾。
  6.   "version": "0.1.0"
  7. }
复制代码

之后在行为包根目录下创建 scripts 文件夹(如果以前没有创建的话),打开它,创建 main.js(或自定义的名称),打开这个文件。

我们需要导入一些用于创建自定义命令的类和枚举。
  1. import {
  2.   system,
  3.   CommandPermissionLevel,
  4.   CustomCommandParamType
  5. } from "@minecraft/server";
复制代码


其中,system 用于订阅世界启动的事件,我们需要在启动前注册自定义命令。CommandPermissionLevel 是自定义命令权限的枚举,CustomCommandParamType 是命令参数的枚举。
编写命令
现在我们可以开始了。为了方便编写多个命令,我们可以仿照自定义组件的写法,先定义一个列表,其中的每个对象都代表一个自定义命令,然后用 for ... of 遍历注册每个自定义命令。

首先来定义一个命令,比如渲染文本的命令:
  1. const commandDefinitions = [{
  2.   commandDefinition: {
  3.     name: "complementary:rendertext",
  4.     description: "在指定位置渲染文本",
  5.     permissionLevel: CommandPermissionLevel.GameDirectors,
  6.     cheatsRequired: true,
  7.     mandatoryParameters: [{
  8.       type: CustomCommandParamType.Location,
  9.       name: 'pos'
  10.     }, {
  11.       type: CustomCommandParamType.String,
  12.       name: 'text'
  13.     }],
  14.     optionalParameters: [{
  15.       type: CustomCommandParamType.Float,
  16.       name: 'time'
  17.     }, {
  18.       type: CustomCommandParamType.Float,
  19.       name: 'scale'
  20.     }, {
  21.       type: CustomCommandParamType.String,
  22.       name: 'color'
  23.     }, {
  24.       type: CustomCommandParamType.String,
  25.       name: 'rotation'
  26.     }]
  27.   },
  28.   functionName: rendertextCommand
  29. }];
复制代码


我们首先定义了一个 commandDefinitions 列表,存放全部的自定义命令。然后,其中的每个对象表示一个命令。每个命令分为两个部分,语法和逻辑。语法在 commandDefinition 中定义,逻辑在 functionName 中定义。

commandDefinition 表示这个命令的基本信息,比如命令,描述,还有语法。

name 表示命令的名称,必须包含命名空间。必须填写。名称可以是中文,比如“test:一个命令”是可行的。

description 表示命令的描述,就是在聊天栏中跟在命令名称后方的描述命令作用的提示性文字。必须填写。可以填写任何文本,包括 \n 这样的特殊字符。可以使用§改变文本格式。目前不能本地化(也就是不能使用 .lang 文件翻译)。

permissionLevel 表示命令执行所需权限。必须填写。需要输入 CommandPermissionLevel 枚举中的值。可用值如下(括号中的值是枚举中定义的值,也可以用括号前面的键来代表那个值):

CommandPermissionLevel.Any(0)- 任何玩家或其他来源都能执行此命令。

CommandPermissionLevel.GameDirectors(1)- 操作员或命令方块可以执行此命令。

CommandPermissionLevel.Admin(2)- 操作员可以执行此命令,命令方块不行。

CommandPermissionLevel.Host(3)- 服务器主机可以执行此命令。

CommandPermissionLevel.Owner(4)- 基岩版专用服务器(BDS,Bedrock Dedicated Server)可以执行此命令。

cheatsRequired 表示命令是否需要启用作弊才能执行。可选,默认为 true。

mandatoryParameters 表示这个命令的必需参数。是一个列表,列表中的对象是命令参数项。可选,如果不填,表示这个命令不需要必需参数。

optionalParameters 表示这个命令的可选参数。是一个列表,列表中的对象是命令参数项。可选,如果不填,表示这个命令不需要可选参数。

如果 mandatoryParameters 和 optionalParameters 都为空,那么此命令不需要也不应该被提供任何参数即可运行。

注意,一个自定义命令最多只能有 8 个参数

命令参数项是表示命令中一个参数的对象。其中 name 是此参数在聊天栏出现时的名称,type 是参数的类型。必须填写 name 和 type。比如一个可选的参数,在语法树中出现的形式是 [name: type]。

type 接受 CustomCommandParamType 枚举中的值:

CustomCommandParamType.BlockType("BlockType")- 方块类型。

CustomCommandParamType.Boolean("Boolean")- 布尔值。

CustomCommandParamType.EntitySelector("EntitySelector")- 实体选择器。

CustomCommandParamType.EntityType("EntityType")- 实体类型。

CustomCommandParamType.Enum("Enum")- 枚举。此时 name 需要是已经注册的枚举。会出现自动补全提示。仍可以输入不是枚举中的值并被解析。

CustomCommandParamType.Float("Float")- 浮点数。

CustomCommandParamType.Integer("Integer")- 整数。

CustomCommandParamType.ItemType("ItemType")- 物品类型。会出现自动补全提示。

CustomCommandParamType.Location("Location")- 位置,也就是以空格分割的三维坐标。

CustomCommandParamType.PlayerSelector("PlayerSelector")- 玩家选择器。仅能选择玩家的实体选择器。

CustomCommandParamType.String("String")- 字符串。

functionName 表示命令的逻辑处理部分,是一个回调函数,执行命令时将命令的执行环境和解析的命令参数传递给这个函数。传递的顺序是首先传递命令的执行环境,然后根据语法顺序依次传递解析后的参数。

在以上示例中,functionName 是 rendertextCommand 这个函数。所以接下来定义这个函数。

  1. function rendertextCommand(e, pos, text, time = 5, scale = 1, color, rot) {
  2.   let shape = new DebugText(pos, text);
  3.   shape.text = text;
  4.   shape.color = parseCommandParamRGB(color);
  5.   shape.rotation = parseCommandParamRotation(rot);
  6.   shape.timeLeft = time > 0 ? time * 50000 : undefined;
  7.   shape.scale = scale;
  8.   debugDrawer.addShape(shape);
  9.   return {
  10.     status: 0,
  11.     message: `尝试渲染了以下文本:${text}。`
  12.   };
  13. }
复制代码


可以看到,这个函数接收的参数是 (e, pos, text, time = 5, scale = 1, color, rot)。第一个是 e,表示命令的执行环境;其他的是刚才定义的参数。

命令的执行环境中包含 sourceBlock sourceEntity 和 initiator 属性,根据命令执行的来源而选择性存在,含义如下:

sourceBlock 表示执行命令的方块,比如命令方块。

sourceEntity 表示执行命令的实体,比如在聊天栏执行命令时的玩家,或者被给予指示执行命令的 NPC。

initiator 表示与 NPC 互动并导致 NPC 执行命令的玩家。

命令的执行环境中还有命令执行的来源信息,会通过 sourceType 属性告诉我们命令执行来自哪里。

sourceType 属性的值如下:

Block - 方块执行了这个命令。此时 sourceBlock 属性存在。

Entity - 实体执行了这个命令。此时 sourceEntity 属性存在。

NPCDialogue - 玩家通过 NPC 执行了这个命令。此时 sourceEntity 和 initiator 属性存在。

Server - 服务器执行了这个命令。此时命令没有其他执行环境。

rendertextCommand 函数还返回了一个对象,表示命令的执行结果。这个对象有 message 和 status 两个字段。

message 表示命令返回的消息。可选,不能本地化。

status 表示命令的执行状态。必须填写 CustomCommandStatus 枚举中的值:

CustomCommandStatus.Success(0)- 命令执行成功。
CustomCommandStatus.Failure(1)- 命令执行失败。

使用 CustomCommandParamType.Enum 类型的参数时,我们需要自定义枚举。可以仿照定义命令的方式定义枚举:
  1. const enumDefinitions = [{
  2.   name: 'complementary:configOperations',
  3.   values: ['open', 'reset']
  4. }];
复制代码


name 是枚举的命令,需要与命令参数定义中的 name 一致。必须有命名空间。显示命令语法时,会隐藏命名空间。

values 是枚举的值。

现在来注册已经定义的命令和枚举:
  1. system.beforeEvents.startup.subscribe((i) => {
  2.   for (const e of enumDefinitions) {
  3.     i.customCommandRegistry.registerEnum(e.name, e.values);
  4.   }
  5.   for (const e of commandDefinitions) {
  6.     i.customCommandRegistry.registerCommand(e.commandDefinition, e.functionName);
  7.   }
  8. });
复制代码


我们首先订阅通过 system 访问的 System 类中 beforeEvents 中的 startup 事件,然后通过 for ... of 循环遍历 enumDefinitions 枚举定义和 commandDefinitions 枚举定义。对于其中每个元素,都执行 customCommandRegistry.registerEnum 和 customCommandRegistry.registerCommand,将之前定义的参数传递给这两个函数。

就这样,我们成功定义了命令。
总结
这一期讲解了如何定义新的命令。


苦力怕论坛,感谢有您~

本版积分规则

本站
关于我们
联系我们
坛史纲要
官方
哔哩哔哩
技术博客
下载
网易版
安卓版
JAVA
反馈
意见建议
教程中心
更多
捐助本站
QQ群
QQ群

QQ群

访问手机版

访问手机版

手机版|小黑屋|系统状态|klpbbs.com

| 由 木韩网络 提供支持 | GMT+8, 2026-2-3 04:56

声明:本站与Mojang以及微软公司没有从属关系

Powered by Discuz! X3.4