MCDR 插件

什么是 MCDR 插件?

MCDR 插件是位于插件目录中的一个以 .py 为后缀的 python 源文件。插件目录的列表可以在 配置文件 中定义。

启动时,MCDR 会自动加载插件目录内的每个插件。此外,MCDR 会将所有插件目录加入到 sys.path 中,以使插件可以直接导入插件文件夹中的模块。

在源代码的 plugins/ 文件夹中有一个名为 SamplePlugin.py 的示例插件,你可以查看其内容以供参考。

快速开始

打开你设置的 MCDR 的插件目录之一,创建一个名为 HelloWorld.py 的文件。

cd my_plugin_folder
touch HelloWorld.py

打开它并输入如下代码:

PLUGIN_METADATA = {
    'id': 'hello_world',
    'version': '1.0.0',
    'name': 'My Hello World Plugin'
}


def on_load(server, old):
    server.logger.info('Hello world!')

返回MCDR控制台,输入 !!MCDR reload plugin 。你应该会看到插件发送了一条 hello world。

[TaskExecutor/INFO] [hello_world]: Hello world!

好耶,你成功写出了你的第一个插件!

元数据

元数据字段提供了插件的基本信息。如你在 快速上手 部分中所见,元数据声明于插件的全局作用域中,是一个名为 PLUGIN_METADATA 的包含着若干个键值对的 dict

以下是一个元数据字段,其中包含所有可能的键值。

PLUGIN_METADATA = {
    'id': 'my_plugin_id',
    'version': '1.0.0',
    'name': 'My Plugin',  # RText component is allowed
    'description': 'A plugin to do something cool',  # RText component is allowed
    'author': 'myself',
    'link': 'https://github.com',
    'dependencies': {
        'mcdreforged': '>=1.0.0',
        'an_important_api': '*'
    }
}

如果插件未声明元数据字段,则控制台中将出现警告,并使用备用值。

id

ID(即插件 ID)是你插件的“身份证号”。它应由小写字母,数字和下划线组成,长度为 1 到 64。

以下是一些可用的插件 ID:

  • my_plugin

  • anotherhelper123

  • __a_cool_plugin__

但不允许使用以下ID:

  • MyPlugin

  • another-helper-123

  • a cool plugin

MCDR 使用插件 ID 来区分不同的插件并检查插件间的依赖。 MCDR 中加载的所有插件都应使用不同的插件 ID。如果新加载的插件具有与现有插件完全相同的插件 ID,则新插件将无法加载。

请明智地选择你的插件 ID。强烈建议你在发布插件后不要再更改插件 ID。

  • 字段键名:id

  • 字段类型:str

  • 备用值:不含 .py 后缀的插件文件名

version

version 字段代表你的插件版本。它基本上采用了 语义化版本 的格式,不过限制较少,如你可以定义任意长度的版本号。

以下一些可用的版本:

  • 1.0.0

  • 2.0

  • 1.2.3-pre4

  • 1.8.9-rc.8

  • 1.14.1-beta.4+build.54

遵循 语义化版本 格式为你的插件定义版本字符串是一个好主意——易于维护、易于理解。

  • 字段键名:version

  • 字段类型:str

  • 备用值:0.0.0

name

你的插件名称——给你的插件起一个好听的名字吧。你可以使用的任何字符,也可以用 RText

尽量不要使插件名称太长。你可以把插件的详细信息放在 description 之中。

  • 字段键名:name

  • 字段类型:str 或 RTextBase

  • 备用值:插件 ID

description

你的插件详细。把插件的详细信息放在这里吧。同样的,这里也可以使用 RText

此字段是可选的。如果你想偷懒的话可以不填写。

  • 字段键名:description

  • 字段类型:str 或 RTextBase

  • 备用值:None

author

插件作者。如果只有一个作者,可使用 string 而非 list。

此字段是可选的。如果你想偷懒的话可以不填写。

  • 字段键名:author

  • 字段类型:str 或 list[str]

  • 备用值:None

dependencies

插件的依赖关系。应为一个字典,其中包含多个键值对。键为插件所依赖的插件 ID,值是插件所依赖插件的版本要求。

如果你的插件对 MCDR 版本有需求,请使用 mcdreforged 作为插件 ID。

版本要求是一个包含若干个版本约束的字符串。约束按空格划分,每个每个由一个运算符和一个基础版本字符串组成。描述基版本时允许使用通配符。

运算符列表:

运算符

示例说明

示例说明

允许的值

不允许的值

>=

>=1.2.3

目标版本应大于等于 1.2.3

1.2.3,1.3.0

1.2.0

>

>1.2.3

目标版本应大于 1.2.3

1.2.4,1.3.0

1.2.0,1.2.3

<=

<=1.2.3

目标版本应小于等于 1.2.3

1.2.3,1.1.0

1.2.4,2.0.0

<

<1.2.3

目标版本应小于 1.2.3

1.1.0

1.2.3,1.5

=

=1.2.3

目标版本应等于 1.2.3

1.2.3

1.2,1.2.4

1.2.3

如果未指定运算符,则默认使用 = 。在这种情况下,目标版本应等于1.2.3

1.2.3

1.2,1.2.4

^

^1.2.3

目标版本应大于等于 1.2.3,且目标版本的第一个版本分段应等于基版本

1.2.3,1.2.4,1.4.4

1.0.0,2.0.0

~

~1.2.3

目标版本应大于等于 1.2.3,并且目标版本的第一和第二版本分段应等于基版本

1.2.3,1.2.4

1.0.0,1.4.4,2.0.0

查看 此处(EN)此处(中文) 以获取版本要求的更多详细信息。

如果存在多个声明的条件,则仅当所有条件都接受目标版本时,才接受目标版本。

这里是一个依赖关系示例:

'dependencies': {
    'mcdreforged': '>=1.0.0 <2.0',
    'my_library': '>=1.0.0',
    'an_important_api': '*',
    'another_api_1': '1.0.*',
    'another_api_2': '2.7.x',
}

MCDR 将确保仅在满足所有依赖项要求时,你的插件才能成功加载。依赖项缺失,依赖项版本不匹配或出现依赖环路,都会导致依赖关系检查失败。

该字段是可选的,如果你的插件没有任何依赖关系,则可以忽略它。

  • 字段键名:dependencies

  • 字段类型:Dict[str]

  • 备用值:None

插件注册表

插件注册表是一个插件注册的东西的集合。在每次加载插件之前,它都会被清空,因此你最好在 插件被加载 事件中注册它们。

事件监听器

有两种方法可以注册事件侦听器的插件。

  1. 使用特定名称在全局范围内声明一个函数。它是注册监听器的老办法,仅适用于 MCDR 提供的事件。有关详细信息,请查看 此处

    例如,下面广泛使用的函数是默认的 插件被加载 事件监听器。

    def on_load(server, prev):
        do_something()
    
  2. 手动调用 server.register_event_listener 方法来注册事件监听器。你可以为事件监听器指定可调用对象和优先级。

    查看 此处 以获取有关事件监听器注册的更多详细信息。

    以下是一些关于手动注册事件监听器的例子:

    def my_on_mcdr_general_info(server, info):
        pass
    
    def on_my_task_done(server, my_task_info, my_task_data):  # the 2nd and 3rd parameter is determined by the plugin that emits this event
        pass
    
    def on_load(server, prev):
        server.register_event_listener('mcdr.general_info', my_on_mcdr_general_info, priority=500)  # TODO: use better event identifier
        server.register_event_listener('myplugin.task_done', on_my_task_done)  # TODO: use better event identifier
    

请参阅 ServerInterface 文档中有关 register_event_listener 方法的说明,以了解更多详细信息。

指令

除了在如 on_user_info 的用户信息事件回调中手动解析用户输入 info.content,MCDR 还为插件提供了一个指令构建系统来帮助插件注册它们的指令。

查看 指令 文档以获取有关构建指令树的更多详细信息。

假设你已经使用根文字节点 root 构建了指令树,则你可以使用以下代码在 MCDR 中注册这一棵指令树:

server.register_command(root)

查看 ServerInterface 文档中有关 register_command 方法的参考,以获取其用法的更多详细信息。

帮助信息

插件可以使用 server.register_help_message 将其帮助消息注册到MCDR,以便用户使用 !!help 指令 来查看所有插件的帮助消息。

查看 ServerInterface 文档中有关 register_help_message 方法的参考,以了解其用法的更多详细信息。