Cat_A***Cat_A***当前离线UID82897性别保密经验 EP铁粒 粒回帖0主题精华在线时间 小时注册时间2021-7-23最后登录1970-1-1查看:2705|回复:0
发表于 2025-6-7 15:32:32 来自手机|只看该作者|倒序浏览|阅读模式 IP:天津 本帖最后由 Cat_Anchor 于 2025-6-20 19:49 编辑 前言在 1.21.80.22 中,官方加入了自定义命令功能,可以通过 SAPI 自定义命令。准备首先需要在 manifest.json 中导入 @minecraft-server 模块。在 dependencies 字段下:{ "module_name": "@minecraft/server", "version": "2.1.0-beta"}复制代码
注意其中的 version 字段。在 1.21.80 中,应该填写 2.0.0-beta,而在 1.21.90 中应该是 2.1.0-beta。
然后添加脚本模块,如果以前没有脚本模块的话。在 modules 字段下:{ "type": "script", "language": "javascript", "uuid": "", // 需要填写 UUID。 "entry": "main.js", // 可以替换为其他名称,但必须以 .js 结尾。 "version": "0.1.0"}复制代码
之后在行为包根目录下创建 scripts 文件夹(如果以前没有创建的话),打开它,创建 main.js(或自定义的名称),打开这个文件。
我们需要导入一些用于创建自定义命令的类和枚举。import { system, CommandPermissionLevel, CustomCommandParamType} from "@minecraft/server";复制代码
其中,system 用于订阅世界启动的事件,我们需要在启动前注册自定义命令。CommandPermissionLevel 是自定义命令权限的枚举,CustomCommandParamType 是命令参数的枚举。编写命令现在我们可以开始了。为了方便编写多个命令,我们可以仿照自定义组件的写法,先定义一个列表,其中的每个对象都代表一个自定义命令,然后用 for ... of 遍历注册每个自定义命令。
首先来定义一个命令,比如渲染文本的命令:const commandDefinitions = [{ commandDefinition: { name: "complementary:rendertext", description: "在指定位置渲染文本", permissionLevel: CommandPermissionLevel.GameDirectors, cheatsRequired: true, mandatoryParameters: [{ type: CustomCommandParamType.Location, name: 'pos' }, { type: CustomCommandParamType.String, name: 'text' }], optionalParameters: [{ type: CustomCommandParamType.Float, name: 'time' }, { type: CustomCommandParamType.Float, name: 'scale' }, { type: CustomCommandParamType.String, name: 'color' }, { type: CustomCommandParamType.String, name: 'rotation' }] }, functionName: rendertextCommand}];复制代码
我们首先定义了一个 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 这个函数。所以接下来定义这个函数。function rendertextCommand(e, pos, text, time = 5, scale = 1, color, rot) { let shape = new DebugText(pos, text); shape.text = text; shape.color = parseCommandParamRGB(color); shape.rotation = parseCommandParamRotation(rot); shape.timeLeft = time > 0 ? time * 50000 : undefined; shape.scale = scale; debugDrawer.addShape(shape); return { status: 0, message: `尝试渲染了以下文本:${text}。` };}复制代码
可以看到,这个函数接收的参数是 (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 类型的参数时,我们需要自定义枚举。可以仿照定义命令的方式定义枚举:const enumDefinitions = [{ name: 'complementary:configOperations', values: ['open', 'reset']}];复制代码
name 是枚举的命令,需要与命令参数定义中的 name 一致。必须有命名空间。显示命令语法时,会隐藏命名空间。
values 是枚举的值。
现在来注册已经定义的命令和枚举:system.beforeEvents.startup.subscribe((i) => { for (const e of enumDefinitions) { i.customCommandRegistry.registerEnum(e.name, e.values); } for (const e of commandDefinitions) { i.customCommandRegistry.registerCommand(e.commandDefinition, e.functionName); }});复制代码
我们首先订阅通过 system 访问的 System 类中 beforeEvents 中的 startup 事件,然后通过 for ... of 循环遍历 enumDefinitions 枚举定义和 commandDefinitions 枚举定义。对于其中每个元素,都执行 customCommandRegistry.registerEnum 和 customCommandRegistry.registerCommand,将之前定义的参数传递给这两个函数。
就这样,我们成功定义了命令。总结这一期讲解了如何定义新的命令。第五十五期 第五十六期 第五十七期本主题由 星涵喵 于 2025-6-21 10:29 审核通过分享到: QQ好友和群收藏4支持7帖子永久地址: 点击复制苦力怕论坛 - 论坛版权1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关
2、本站所有主题由该帖子作者发表,该帖子作者享有帖子相关版权
3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者的同意
4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
7、Minecraft(我的世界)苦力怕论坛管理员和版主有权不事先通知发贴者而删除本文苦力怕论坛,感谢有您~回复使用道具举报
提升卡观察者