MCDR 插件
什么是 MCDR 插件?
MCDR 插件是位于插件目录中的一个以 .py
或 .mcdr
为后缀的文件,也可以是一个具有特定文件结构的目录。见 插件格式 文档以获得更多有关插件格式的信息
插件目录的列表可以在 配置文件 中定义。启动时,MCDR 会自动加载每个插件目录中的每个插件
快速开始
打开你设置的 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!
好耶,你成功写出了你的第一个插件!
元数据
元数据提供了插件的基本信息。它是一个包含多个键值对的 json 对象,如:
{
"id": "example_plugin",
"version": "1.0.0",
"name": "Example Plugin",
"description": "Example plugin for MCDR",
"author": "Fallen_Breath",
"link": "https://github.com/MCDReforged/MCDReforged-ExamplePlugin",
"dependencies": {
"mcdreforged": ">=2.0.0-alpha.1"
}
}
不同的 插件格式 有着不同的声明元数据的方法,但其元数据的内容是一致的
参见
元数据 文档
入口点
在 MCDR 加载你的插件时,MCDR 会导入你指定的入口点模块。入口点是你的插件与 MCDR 间的桥梁
对 单文件插件 而言,入口点就是插件自己。对于 多文件插件,入口点声明于其元数据中,默认值是插件的 id,即位于以插件 id 为名的文件夹中的 __init__.py
举个例子:
MyPlugin.mcdr
my_plugin/
__init__.py
source.py
mcdreforged.plugin.json
在这个多文件插件中,当入口点的值为默认值时,MCDR 会导入模块 my_plugin
,也就是加载 MyPlugin.mcdr
内 my_plugin/
文件夹中的 __init__.py
位于 __init__.py
中的 on_load
函数将会被注册为事件监听器
如果入口点被设置为了 my_plugin.source
,那么 MCDR 将会导入模块 my_plugin.source
,也就是加载 my_plugin/
文件夹中的 source.py
入口点模块的实例被用于 get_plugin_instance()
中,也是 插件被加载 事件的第二个参数
插件注册表
插件注册表是一个插件注册的东西的集合。在每次加载插件之前,它都会被清空,因此你最好在 插件被加载 事件中注册它们
事件监听器
有 3 种方法可以注册事件侦听器的插件
使用特定名称在 入口点 模块全局范围内声明一个函数。它是注册监听器的老办法,仅适用于 MCDR 提供的事件。有关详细信息,请查看 默认的事件监听器
例如,下面广泛使用的函数是默认的 插件被加载 事件监听器
def on_load(server, prev): do_something()
手动调用
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) server.register_event_listener(MCDRPluginEvents.PLUGIN_UNLOADED, my_on_unload, priority=2000) server.register_event_listener('myplugin.task_done', on_my_task_done)
使用
event_listener()
装饰器
指令
除了在如 on_user_info
的用户信息事件回调中手动解析用户输入 info.content
,MCDR 还为插件提供了一个指令构建系统来帮助插件注册它们的指令
查看 指令树 文档以获取有关构建指令树的更多详细信息
假设你已经使用根文字节点 root 构建了指令树,则你可以使用 register_command()
方法在 MCDR 中注册这一棵指令树:
server.register_command(root_node)
帮助信息
插件可以使用 register_help_message()
将其帮助消息注册到 MCDR,以便用户使用 !!help 指令 来查看所有插件的帮助消息
翻译
如果你的插件需要处理一些诸如信息本地化的翻译工作,你可以让 MCDR 来帮你:通过 register_translation()
注册一个翻译,并使用 tr()
或者 rtr()
来获取翻译后的字符串
导入插件
在多文件插件被加载时,MCDR 将会把多文件插件的文件路径追加至 sys.path
中。对于打包插件而言,文件路径是 .mcdr
文件的路径;对于文件夹插件而已,文件路径是其文件夹的路径
因此,你可以简单的通过 import
语句导入插件 id 的方式,来导入其他插件。这也是推荐的导入方式,因为这可以为你的 IDE 提供了代码高亮等信息
除此之外,你还可以使用 get_plugin_instance()
方法来导入其他插件的入口点。这也是 导入单文件插件的唯一方法。对于多文件插件而言,其返回的值与直接导入插件是相同的
import my_lib_plugin as libA
libB = server.get_plugin_instance('my_lib_plugin')
print(libA == libB) # True
别忘了在你的插件元数据中声明你的插件依赖,否则 MCDR 将不能保证插件加载顺序是正确的