MCDRpost API--自定义 Handler

一般来说,MCDRpost已经能够适应大多数服务端,但是对于某些特殊情况(比如1.9版本) [1],MCDRpost可能无法满足需求, 考虑到插件对 Minecraft 的兼容性,插件暴露了一定的 API 用于 Minecraft 一些特殊服务端的适配

核心 API 有:

你可以在导入的时候使用下面的方式:

from mcdrpost.api import *

当然如果不希望污染全局变量也可以这样:

from mcdrpost import api as mp

详细文档

处理器

class mcdrpost.api.AbstractVersionHandler[源代码]

基类:ABC

版本处理器

server

psi 实例

Type:

PluginServerInterface

sound_player

音效播放器

Type:

AbstractSoundPlayer

final __init__() None[源代码]
final classmethod is_builtin() bool[源代码]

此处理器是否为 MCDRpost 内置的处理器

abstractmethod replace(player: str, item: Item) None[源代码]

替换玩家副手物品

参数:
  • player (str) -- 玩家名

  • item (Item) -- 物品字符串

abstractmethod get_offhand_item(player: str) Item[源代码]

获取玩家副手物品

参数:

player (str) -- 玩家 id

property play_sound: AbstractSoundPlayer

播放提示音

你可以重写这个 property 来更换音效,但请注意刚实例化的 Handler 的 sound_player 属性 是 None,要判断一下并赋值

class mcdrpost.api.DefaultVersionHandler[源代码]

基类:AbstractVersionHandler

这是对 Minecraft 1.17~1.20.5 的简易 Handler

get_offhand_item(player: str) Item[源代码]
replace(player: str, item: Item) None[源代码]
static item2str(item: Item) str[源代码]
mcdrpost.api.register_handler(handler: type[AbstractVersionHandler], checker: Callable[[Environment], bool]) None[源代码]

向 MCDRpost 注册 Handler

参数:

声音播放器

class mcdrpost.api.AbstractSoundPlayer(server: PluginServerInterface)[源代码]

基类:ABC

音效播放

server

MCDR 服务器接口

Type:

PluginServerInterface

final __init__(server: PluginServerInterface)[源代码]
abstractmethod successfully_receive(player: str)[源代码]

播放音效: 当成功接受订单时

参数:

player (str) -- 玩家 id

abstractmethod successfully_post(sender: str, receiver: str)[源代码]

播放音效: 当成功发送订单时

请给收件人和发件人播放音效

参数:
  • sender (str) -- 发件人

  • receiver (str) -- 收件人

Returns:

abstractmethod has_something_to_receive(player: str)[源代码]

播放音效: 登陆后发现有订单未接受时

参数:

player (str) -- 玩家 id

class mcdrpost.api.NewSoundPlayer(server: PluginServerInterface)[源代码]

基类:AbstractSoundPlayer

1.13 及以上版本的音效播放器

successfully_receive(player: str)[源代码]
successfully_post(sender: str, receiver: str)[源代码]
has_something_to_receive(player: str)[源代码]
class mcdrpost.api.OldSoundPlayer(server: PluginServerInterface)[源代码]

基类:AbstractSoundPlayer

1.13 以下版本的音效播放器

successfully_receive(player: str)[源代码]
successfully_post(sender: str, receiver: str)[源代码]
has_something_to_receive(player: str)[源代码]

类型

class mcdrpost.api.Item(**kwargs)[源代码]

基类:Serializable

物品数据类,表示 Minecraft 中的物品

备注

Minecraft 1.20.5 之后的 components 数据和之前的 tag 标签都存放在 components中

在 3.4.1 版本加入: 新增验证功能

id: str

物品的唯一标识符

count: int

物品数量

components: dict

物品的组件信息或标签

validate_attribute(attr_name: str, attr_value: Any, **kwargs)[源代码]
class mcdrpost.api.Environment(server: PluginServerInterface)[源代码]

基类:object

__init__(server: PluginServerInterface) None[源代码]
property server_version: MinecraftVersion

Minecraft 服务器版本

property mcdr_handler: str

MCDR 正在使用的 handler

示例

我们建议使用插件定义你的 Handler,下面是一个单文件插件的例子

PLUGIN_METADATA = {
    'id': 'example_handler',
    'version': '1.0.0',
    'name': 'Example Handler',
    'author': 'xieyuen',
    'description': 'An example of custom handler',
    'dependencies': {
        'mcdrpost': '>=3.3.2-beta5'
    }
}


def on_load(_server, _old):
    import minecraft_data_api as api
    from mcdrpost.api import AbstractVersionHandler, Item, OFFHAND_CODE, register_handler

    class ExampleHandler(AbstractVersionHandler):
        def replace(self, player: str, item: Item) -> None:
            self.server.execute(f'item replace entity {player} with {self.item2str(item)}')

        @staticmethod
        def item2str(item: Item) -> str:
            return f'{item.id}{item.components} {item.count}'

        @staticmethod
        def dict2item(item: dict) -> Item:
            return Item(
                id=item['id'],
                count=item['Count'],
                components=item.get('tag', {})
            )

        def get_offhand_item(self, player: str) -> Item:
            item = api.convert_minecraft_json(
                self.server.rcon_query(
                    f'data get entity {player} {OFFHAND_CODE}'
                )
            )

            return self.dict2item(item)

    register_handler(
        ExampleHandler,
        lambda env: '1.20.5' > env.server_version >= '1.17'
    )

备注

on_load() 函数中定义是为了保证 MCDR 能正确加载插件, 因为 MCDR 要先读取 Metadata 才知道插件依赖 MCDRpost,而此时 MCDRpost 不一定已经被加载 放在函数中先不运行就可以避免没有优先加载 MCDRpost 导致的问题

注意:如果是多文件插件就没有这种问题,放在外面定义就好

如果是用多文件插件的话,你甚至不需要定义 on_load, 只需要在入口点内定义 Handler 并注册就好

example_handler/entry.py 文件内

import minecraft_data_api as api
from mcdrpost.api import AbstractVersionHandler, Item, OFFHAND_CODE, register_handler


class ExampleHandler(AbstractVersionHandler):
    def replace(self, player: str, item: Item) -> None:
        self.server.execute(f'item replace entity {player} with {self.item2str(item)}')

    @staticmethod
    def item2str(item: Item) -> str:
        return f'{item.id}{item.components} {item.count}'

    @staticmethod
    def dict2item(item: dict) -> Item:
        return Item(
            id=item['id'],
            count=item['Count'],
            components=item.get('tag', {})
        )

    def get_offhand_item(self, player: str) -> Item:
        item = api.convert_minecraft_json(
            self.server.rcon_query(
                f'data get entity {player} {OFFHAND_CODE}'
            )
        )

        return self.dict2item(item)


register_handler(
    ExampleHandler,
    lambda env: '1.20.5' > env.server_version >= '1.17'
)

脚注