Event 事件指南
事件的概念
每当服务器中发生了特定的行为,一个事件对象就会产生。
事件是对某种行为或动作的描述,比如玩家登录、 玩家离开、玩家发送消息等等。
种种的行为或动作都对应一个事件对象作为它们的抽象,事件对象中带有这个行为或者动作中的一些关键信息,比如玩家 发送消息事件 对象中就带有发送事件的 玩家对象、发送的消息字符串 等等,而玩家对象又包含这个玩家的 位置、生命值、物品栏 等等数据。
插件可以向 Nukkit-MOT 注册监听器来在事件发生的时候做出反应。
每个事件对象都包含了对事件的描述,通常事件监听器会在事件发生之前被调用,此时监听器可以通过取消事件来阻止事件真的发生,如果没有任何事件监听器取消了这个事件,那么它就会真正地在游戏内发生。
监听器的执行是单线程的,所有监听器在注册的时候都要给 Nukkit-MOT 提供它的优先级,Nukkit-MOT 会按照优先级将监听器排序,然后依次执行监听器。
单线程意味着,您不能在事件中执行耗时操作,否则会影响服务器的正常运行。
很可能在您的插件的监听器被执行之间这个事件已经被取消了,但通常这不会影响您的监听器的执行,您的监听器仍然会被执行,您可以通过 event.isCancelled()
来判断事件是否被取消了。
特别注意的是,优先级越高,执行顺序越往后排。 也就是说,优先级越低,越优先执行!
流程图
事件监听器
事件监听器在游戏服务器插件开发中是一个关键组件,用于处理游戏中发生的各种事件。这部分将详细介绍如何在Nukkit插件中抽象和实现一个事件监听器,设置其优先级,并进行注册,以便在插件中有效响应服务器和玩家的活动。
实现监听器
创建一个事件监听器涉及到实现 Listener
接口,并使用 @EventHandler
注解来标记那些应当在特定事件发生时被调用的方法。下面是一个具体的实现示例,用于监听服务器命令事件:
package cn.nukkitmot.exampleplugin;
import cn.nukkit.event.EventHandler;
import cn.nukkit.event.EventPriority;
import cn.nukkit.event.Listener;
import cn.nukkit.event.server.ServerCommandEvent;
import cn.nukkit.event.player.PlayerChatEvent;
public class EventListener implements Listener {
private final ExamplePlugin plugin;
public EventListener(ExamplePlugin plugin) {
this.plugin = plugin;
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = false)
public void onServerCommand(ServerCommandEvent event) {
if (event.isCancelled()) {
return;
}
// Log the command to server console
this.plugin.getLogger().info("ServerCommandEvent is called with command: " + event.getCommand());
// Here you can add additional logic to modify the behavior based on the command
if (event.getCommand().equalsIgnoreCase("stop")) {
this.plugin.getLogger().info("Server stop command issued!");
// Perform additional actions before server stops
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerChat(PlayerChatEvent event) {
if (event.getMessage().includes("cnm")) { // 检测消息中是否有 cnm
event.setCancelled(true);
}
}
}
在演示代码中,onServerCommand
方法会在服务器命令事件触发时执行。通过此方法,可以进一步处理事件,例如检查命令内容并作出相应响应。
而 onPlayerChat
方法会在玩家聊天事件触发时执行。通过此方法,可以拦截玩家发送的消息,并进行相应的处理。
优先级
事件的处理优先级是调整插件间互动的重要手段。在 Nukkit 中,事件可以根据其重要性被分配不同的优先级,如下所示:
引用自 cn.nukkit.event.EventPriority
public enum EventPriority {
/**
* 事件调用非常不重要且应该首先执行,以便其他插件可以进一步定制结果
*/
LOWEST(0),
/**
* 事件调用的重要性较低
*/
LOW(1),
/**
* 事件调用重要性一般,这也是默认的优先级。
*/
NORMAL(2),
/**
* 事件调用的重要性较高
*/
HIGH(3),
/**
* 事件调用至关重要,必须在事件结果上有最终决定权
*/
HIGHEST(4),
/**
* 事件仅用于监控事件的结果。
*
* 在这个优先级下不应对事件做任何修改
*
* 修改指的是通过 `Event#setCanneled()` 取消事件,以及修改事件携带的数据。
*/
MONITOR(5);
private final int slot;
EventPriority(int slot) {
this.slot = slot;
}
public int getSlot() {
return slot;
}
}
注册监听器
事件监听器必须在插件启动时注册,以确保它们能够响应事件。这可以通过插件的 onEnable
方法完成:
public class ExamplePlugin extends PluginBase {
@Override
public void onEnable() {
// 注册事件监听器
this.getServer().getPluginManager().registerEvents(new EventListener(this), this);
}
}
此方法中,我们创建了 EventListener
的实例,并通过插件管理器注册它。这确保了每当相关事件发生时,我们的 EventListener
可以接收并处理这些事件。
结语
当你使用命令 /stop
将会触发事件 ServerCommandEvent
,然后 onServerCommand
会被调用,你可以添加一些逻辑来处理这个事件。
当玩家发送消息时,onPlayerChat
会被调用,若消息中包含 cnm
则事件被取消,玩家的消息也不会在游戏中真的发送。