- 致编者:请牢记我们的域名wiki.mcbe-dev.net!
- 致编者:欢迎加入本Wiki的官方交流QQ群或Discord服务器!
- 基岩版1.19.31现已发布!(了解更多)
- Inner Core现已支持Xbox模组联机!(了解更多)
- 如果您是第一次来到本Wiki,欢迎注册一个账户
- 点击顶部的“编辑”或“编辑源代码”按钮即可编辑当前页面
- 请知悉:在不登录时也可以编辑和新建页面,但是您当前的IP地址会记录在编辑历史中
教程:编写脚本API/server模块基础
引言[编辑]
@minecraft/server
模块是脚本中很重要的一个模块,它管理着大部分方法和事件,像看门狗调用也是这个模块的一部分,进行这些学习可以帮助我们。
事件[编辑]
这里的事件是脚本api中的一个概念,通过订阅事件,我们可以监听游戏中发生的各种事情。
监听事件[编辑]
监听事件本质是订阅一个事件并对此事件进行处理的过程。
我们通过subscribe
来订阅事件,用unsubscribe
来完成退订。
把事件按运行方式分,可以分为AfterEvent
和BeforeEvent
两种,AfterEvent是在事件发生之后进行操作,BeforeEvent则可以在事件发生之前操作甚至取消事件的产生。
如果按照server模块中事类归属的类来区分的话,分为系统事件和世界事件。
接下来我们拿ItemUseBeforeEvent
这个World事件为例,观察事件是如何被订阅并处理的。
import * as mc from '@minecraft/server';
mc.world.beforeEvents.itemUse.subscribe();
这样我们就完成了对ItemUseBeforeEvent
的订阅,接下来我们需要对其进行处理,这里有两种方法。
箭头函数[编辑]
箭头函数是JavaScript中的一个功能强大的特性,它提供了一种更加简洁的方式来编写函数表达式。
事件的订阅处理就允许我们使用箭头函数,像下面这样。
mc.world.beforeEvents.itemUse.subscribe((event) => { //使用event来储存有关事件的数据
mc.world.sendMessage("你已使用道具");
});
我们不妨拿到游戏中去测试一番。
使用function()[编辑]
除了使用箭头函数以外,subscribe
的参数也支持直接使用函数名,不过需要您在清单文件中允许,具体的操作方法请见开始之前。
接下来仍然用ItemUseBeforeEvent
进行展示:
import * as mc from '@minecraft/server';
function itemUseEvent(event){ //使用event来接收数据
mc.world.sendMessage("你已使用道具");
};
mc.world.beforeEvents.itemUse.subscribe(itemUseEvent);
event数据[编辑]
event数据是监听事件被触发时,返回的有关内容,拿ItemUseBeforeEvent
举例,它只有一个回退属性cancel: boolean
,来完成事件的取消。
系统事件[编辑]
当Minecraft附加系统范围内发生特定类型的事件时,系统事件会被触发。
这里我们不多介绍,以 看门狗事件 为例。
在某些情况下,看门狗会试图终止脚本,如果你有特殊需要,不想让其被终止,我们就可以使用 BeforeEvent的回退机制,这个功能在Before特权系统中有具体介绍,接下来我们就看一下具体代码:
mc.system.beforeEvents.watchdogTerminate.subscribe((event) => { //订阅事件
event.cancel = true; //取消事件
console.warn('看门狗终止被取消,类型为' + event.terminateReason); //发送警告
});
要注意的是:
内存不足异常,不会被回退。
下面枚举一些经常会用到的系统事件,并给予展示:
世界事件[编辑]
世界事件API提供了许多事件API,当特定类型的事件发生在Minecraft的世界中,它们就会被监听到,下面给出一个示例:
mc.world.afterEvents.playerBreakBlock.subscribe((event) => {
event.player.sendMessage( //这是一个方法,用于对单独的玩家发送消息
`你打破了${event.block.typeId}` //block.typeId指的是方块类型
);
});
接下来枚举一些经常会用到的世界事件,并给予展示:
脚本事件[编辑]
脚本事件事实上属于 system 事件,由于它的特殊性,我们将它单独拿出来讲。
如果您阅读过 脚本API 就应该知道/scriptevent
命令可以完成包与包之间的互通。这种互通,具体的完成方法在以后会讲,现在请来了解一下它的原理。
我们通过订阅 scriptEventReceive
事件,可以获取到 scriptevent 命令给予的一些信息,并作出响应。
简单观察一下这个命令的基本语法:
scriptevent <messageId: string> <message: string>
我们可以找到messageId,这个是消息的id,用于指明这个消息是对哪个脚本发送的。问题在于,这个不是唯一标识符,如果您的脚本跟另外一个脚本同时注册了这个事件,并用相同的标识符响应,就可能出现混乱,同时订阅时间的时候,一个脚本甚至可以响应多个不同id的消息,这是需要注意的。
接下来我们看看scriptEventReceive
事件具体有哪些参数:
- id:string:对应着scriptevent命令中的<messageId: string>
- sourceType:string/ScriptEventSource:表示着执行这条命令者的类型,可以是 方块(例如命令方块),实体(可以是玩家),NPC 等
下面是 ScriptEventSource 的列举:
Block = "Block", //方块
Entity = "Entity", //实体
NPCDialogue = "NPCDialogue", //npc对话
Server = "Server" //服务器,可以是脚本api使用的runCommand方法,也可以是服务器主机
- initiator?:npc:对应npc对话中的npc
- sourceBlock?:block:对应执行的方块
- sourceEntity?:entity:对应执行的实体
要注意的是:
如果使用 execute 命令,那么 sourceType 等也会改变。
接下来我们来具体实践一下:
mc.system.afterEvents.scriptEventReceive.subscribe((event) => {
mc.world.sendMessage(`您成功执行了scriptevent命令,其id为${event.id},消息为${event.message},来源类型为${event.sourceType}`);
});
Before特权系统[编辑]
Before特权系统,指的是Before事件拥有的强大回退能力。
其可以取消将(或已)产生的事件,比如发送消息:
mc.world.beforeEvents.chatSend.subscribe((event) =>{
event.cancel = true;
event.player.sendMessage("消息发送已被取消");
});
同样,这个特权系统拥有强大的回退能力,但也有一定的限制。为了防止两个事件同时产生,在游戏时间点中间发生级联变化。特权系统不允许您使用可以引起其他事件的方法(例如:world.setTime()-设置游戏时间)。但我们拥有一些方法绕过他们:
进行提权[编辑]
进行提权可能是最简单有效的方法了,我们来看下面这一段代码:
mc.world.beforeEvents.chatSend.subscribe(event => {
event.cancel = true;
mc.world.setTime(13000);
});
正常来说就会在玩家发送一条消息之后,将游戏时间设置为 13000(夜晚),但它却会抛出一条无权限错误。
而如果使用system.run()
而将权限提高到 System 层级的话,就不会产生错误:
mc.world.beforeEvents.chatSend.subscribe(event => {
event.cancel = true;
system.run(() => {
mc.world.setTime(13000);
});
});
async稍后执行[编辑]
通过使用等待时间超过滴答的 async 函数,可以绕过特权系统。
mc.world.beforeEvents.chatSend.subscribe(async (event) => {
event.cancel = true;
await sleep(10); //sleep函数需要自己定义
mc.world.setTime(13000);
});
这个方法有一个很有趣的地方,本来我们订阅的是Before事件,应当在消息发送之前就将其回退掉,但现在我们却可以等待一段时间,再将其回退,就好像撤回了一般。
看门狗[编辑]
看门狗是脚本API的一个性能系统,一般情况下,当有脚本的时候它被启用。
配置[编辑]
自1.19.20以来,有一组监视器配置用于管理脚本环境的性能。这些选项不能在世界或服务器中修改,但可以通过专用服务器中的 server.properties
进行修改。以下是默认的看门狗设置,在所有设备上都是相同的。
该页面的编辑正在进行中。 请帮助我们扩充或改进这篇文章。 |
命令[编辑]
我的世界中允许使用 /script watchdog
命令来对开门狗进行一些操作
引用[编辑]
1.官方文档:Minecraft中的脚本介绍
2.官方文档:脚本api参考文档
3.官方文档:minecraft/server模块