插件事件

插件事件是插件与控制台和服务器交互的重要方式。

当服务器触发某一事件时,MCDR 会以触发的参数传递至注册该事件的事件监听器,然后调用该监听器的回调函数

事件监听器是具有优先级的,默认优先级为 1000,插件可以在手动注册事件监听器时设置优先级,MCDR会根据优先级按升序来执行事件监听器

注册事件监听器

请参阅 MCDR 插件 文档中的插件注册表中的 事件监听器 部分。

MCDR 事件

默认的事件监听器

所有的 MCDR 事件监听器都有一个 “默认函数名称”。当你在插件文件内创建一个函数名称与“默认函数名称”相同的函数时,该函数会自动注册为相应的事件监听器。

这些事件监听器的优先级始终是默认的优先级(1000

MCDR 事件列表

插件被加载

插件被加载事件将在插件加载后被触发一次,若你需要注册一些事件监听器/命令/帮助消息,以及初始化参数,那么你应该将它们置于这个函数里。

def on_load(server: ServerInterface, prev_module):
    server.register_command(...)
    server.register_event_listener(...)
    server.register_help_message(...)

插件重载时,prev_module 参数会代表之前的插件实例。若第一次加载插件,则 prev_module 为 None。你使用该参数时,可让插件继承以前的插件实例中的内容,例如:

def on_load(server: ServerInterface, prev_module):
    global reload_counter
    if prev_module is not None:
        reload_counter = prev_module.reload_counter + 1
    else:
        reload_counter = 0

由于它是插件生命周期中的第一个事件,因此只能使用默认事件侦听器注册该事件,因此 on_load 函数是插件的入口点。

注意:你不应该在 on_load 函数中分发自定义事件,否则它将无效。 MCDR的事件侦听器存储此时尚未初始化。

  • 事件 ID:mcdr.plugin_loaded

  • 回调参数:ServerInterface,prev_plugin_module

  • 默认函数名称:on_load

插件被卸载

当 MCDR 卸载插件实例时,将触发该事件。这可能是由插件重载或卸载引起的。

  • 事件 ID:mcdr.plugin_unloaded

  • 回调参数:ServerInterface

  • 默认函数名称:on_unload

插件被“删除”

当 MCDR “删除”插件时,将触发该事件。它只能由插件卸载引起——是时候为你的插件做一些临死前清理了。

插件应进行临死清理的另一个事件是 MCDR 停止 事件。

以下是一个示例用法:

def on_remove(server: ServerInterface, info: Info):
    my_network_connection.disconnect()
    stop_my_new_thread()
  • 事件 ID:mcdr.plugin_removed

  • 回调参数:ServerInterface

  • 默认函数名称:on_remove

标准信息

服务器输出新一行文本,或者从控制台中输入文本时,触发此事件。 MCDR 将把文本解析为 Info 对象。在这种情况下,插件可以响应信息。

以下是一个示例用法:

def on_info(server: ServerInterface, info: Info):
    if not info.is_user and re.fullmatch(r'Starting Minecraft server on \S*', info.content):
        server.logger.info('Minecraft is starting at address {}'.format(info.content.rsplit(' ', 1)[1]))
  • 事件 ID:mcdr.general_info

  • 回调参数:ServerInterface,Info

  • 默认函数名称:on_info

用户信息

用户信息 事件与 标准信息 事件非常相似,但仅在用户发送信息时——更准确地说,info.is_userTrue 时——才会触发。

如果你需要一种简单的方式来处理用户输入,则可以使用此事件。

以下是一个示例用法:

def on_user_info(server: ServerInterface, info: Info):
    if info.content == 'Restart the server!':
        server.reply(info, 'Roger that. Server restarting...')
        server.restart()

如果你想要更复杂的命令系统,而不是在用户信息事件中手动解析它们,则建议你为插件注册一个命令树。参见 指令注册

  • 事件 ID:mcdr.user_info

  • 回调参数:ServerInterface,Info

  • 默认函数名称:user_info

服务端启动

服务端进程刚被 MCDR 启动时触发。

  • 事件 ID:mcdr.server_start

  • 回调参数:ServerInterface

  • 默认函数名称:on_server_start

服务端启动完成

服务器已完全启动时——例如,原版 Minecraft 服务器输出 Done (1.0s)! For help, type "help" 时——被触发。

  • 事件 ID:mcdr.server_startup

  • 回调参数:ServerInterface

  • 默认函数名称:on_server_startup

服务端终止

服务端进程终止。你可以通过判断进程的返回码执行不同操作。

例如:

def on_server_stop(server: ServerInterface, server_return_code: int):
    if server_return_code != 0:
        server.logger.info('Is it a server crash?')
  • 事件 ID:mcdr.server_stop

  • 回调参数:ServerInterface,server_return_code

  • 默认函数名称:on_server_stop

MCDR 启动

MCDR 正在启动。只有成功加载的插件才能接收此事件。

  • 事件 ID:mcdr.mcdr_start

  • 回调参数:ServerInterface

  • 默认函数名称:on_mcdr_start

MCDR 终止

MCDR 正在停止。是时候进行一些移除前的清理了——就像 插件被“删除” 事件时的那样。

  • 事件 ID:mcdr.mcdr_stop

  • 回调参数:ServerInterface

  • 默认函数名称:on_mcdr_stop

玩家加入

一名玩家加入了游戏。 MCDR 仅将玩家的名称解析为字符串,插件可以使用返回的 Info 实例进行更多自定义信息解析。

例如:

def on_player_joined(server: ServerInterface, player: str, info: Info):
    server.say('Welcome {}'.format(player))
  • 事件 ID:mcdr.plugin_joined

  • 回调参数:ServerInterface,player_name,Info

  • 默认函数名称:on_player_joined

玩家离开

一名玩家离开了游戏。插件可以清理与玩家相关的对象。

  • 事件 ID:mcdr.plugin_left

  • 回调参数:ServerInterface,player_name

  • 默认函数名称:on_player_left

自定义事件

除了 MCDR 本身,插件还可以分发自己的事件。你需要做的就是调用带有事件和一些参数的 server.dispatch_event API。查看 此处 以获取有关 API 的详细信息。

自定义事件是在插件之间传递消息的好办法。这也是一种不错的间接让插件响应其他插件请求的方式。