从 MCDR 0.x 迁移至 MCDR 1.x

文件结构

MCDR 已将其文件结构重构为适合作为 python 软件包安装的结构,因此于 MCDR 0.x 中使用的某些文件/文件夹可直接删除:

  • utils/

  • resources/

  • requirements.txt

  • LICENSE

  • readme.md

  • readme_cn.md

  • MCDReforged.py (如果你仍要使用它可以从 github 获取——现在它只作为 MCDR 的启动脚本)

日志文件夹已从 log/ 重命名为 logs/

配置文件

配置文件有相当多的变化,虽然 MCDR 在使用旧版配置文件的情况下仍然可以使用,但我们仍强烈建议你生成一个新的默认配置文件,并将旧配置项填入新的配置文件中

你可以将旧的 config.yml 重命名为 old_config.yml 并启动 MCDR。 MCDR 将重新生成一份配置文件并自动退出。然后打开这两个配置文件并迁移你的配置选项

权限文件

权限系统没有任何改变,因此你可以继续用着旧的权限文件

插件

大部分旧的 MCDR 插件只需做出一些小改动以适配新的 MCDR。有些旧插件甚至无需更改即可运行在新的 MCDR 中

元数据

元数据是插件内部的一个全局变量。它用来存储插件的基本信息和依赖关系。一个插件有必要声明它的元数据,这样 MCDR 才能正确地处理所有的插件

如果一个旧式插件没有声明元数据,它仍然可以被 MCDR 加载,但在控制台中将会显示一个警告

参见

元数据 文档

监听器

兼容性

新版的 MCDR 实现了更好的事件和监听器系统,插件可以将任意函数注册为事件监听器

大多数 MCDR 0.x 风格的事件监听器都保留了下来,现在作为相关事件的自动注册的默认监听器工作

  • on_info

  • on_user_info

  • on_server_startup

  • on_server_stop

  • on_mcdr_stop

  • on_player_joined

  • on_player_left

如果你定义了一个在以上列表中的函数,那么 MCDR 会在你的插件加被加载时自动把它注册为一个事件监听器。这个监听器的默认优先级是 1000

以下两个事件已从 MCDR 中移除:

  • on_death_message

  • on_player_made_advancement

如果你的插件依赖于这两个事件,这里有一个替代方案:即将到来

监听器参数

在 MCDR 0.x 中,玩家加入的事件监听器接受 2 或 3 个参数。以下的两个定义方式都有效:

def on_player_joined(server: PluginServerInterface, player: str):
    pass
def on_player_joined(server: PluginServerInterface, player: str, info: Info):
    pass

然而,在当前版本的 MCDR 中,前者将不被接受,只有定义 3 个参数的后者被接受

除了玩家加入的事件监听器外,其他事件监听器的回调参数保持不变

多线程

MCDR 0.x 为每个插件分配单独的线程以执行其事件监听器回调。这种做法带来了不可预知的插件执行顺序,并极大影响了整体性能。这样的多线程也使得在所有插件完成回调后很难执行任何工作

在新版 MCDR 中,所有事件监听器回调在名为 TaskExecutor 的单线程中调用,以解决上述的问题

如果你的插件依赖于来自 MCDR 的多线程以执行一些并行操作,或你的插件需要执行一些 I/O 或网络操作,并需要耗费一些时间,那最好创建一个新线程来手动执行它们,以保证 MCDR 不会被这些操作阻塞

MCDR 还提供了一个简单的函数装饰器 @new_thread,用于在调用函数时使函数为多线程。下面是一个示例:

from mcdreforged.api.decorator import *

# undecorated function
def my_slow_method1():
    time.sleep(10)

@new_thread  # decorated function, will run at a new thread
def my_slow_method2():
    time.sleep(10)

@new_thread('MyThread')  # specify the thread name
def my_slow_method3():
    time.sleep(10)

借助 @new_thread 修饰器,在每次调用 my_slow_method2 时,一个新的守护线程会被自动创建并执行它

模块位置

如果你的插件需要导入一些 MCDR 内置模块,如 RText 或 Rcon,请查看模块的位置

MCDR 集合了所有有用的类/函数至 mcdreforged.api 包中。建议从 api 包中导入所需的模块

如需导入所有 RText 类,可使用 from mcdreforged.api.rtext import *

如需导入所有 Rcon 类,可使用 from mcdreforged.api.rcon import * 。注意,Rcon 类已被重命名为 RconConnection

对于懒人,你可以使用 from mcdreforged.api.all import * 来向插件中导入所有内置模块

服务器实例 API

如果给定的 info 参数不是来自用户,则 reply 方法将产生一个 TypeError

add_help_message 方法已重命名为 register_help_message

其它

console_command_prefix

console_command_prefix 已被移除——它曾用于防止将 !! 开头的控制台输入被发送至服务器标准输入流

在当前版本中,MCDR 不会阻止将此类控制台输入发送到服务器,除非它与已注册指令树的根节点匹配

因此,如果插件使用手动解析方法解析 on_user_info 等里面的用户指令,则需要在指令处理中调用 cancel_send_to_server() 方法,否则在控制台中输入的指令可能会被发送到服务器标准输入流中

参见

指令树 文档