指令相关
API 包 路径: mcdreforged.api.command
指令源
- class mcdreforged.command.command_source.CommandSource[源代码]
基类:
ABC
CommandSource
是一个指令执行源的抽象模型。它提供了若干有助于指令执行的方法类继承树状图
CommandSource ├── InfoCommandSource │ ├── PlayerCommandSource │ └── ConsoleCommandSource └── PluginCommandSource
插件可以定义一个由
CommandSource
继承而来的类来自定义自己的指令源- get_server() ServerInterface [源代码]
返回 ServerInterface 实例
- get_preference() PreferenceItem [源代码]
返回此指令源的偏好
在默认情况下,该方法将返回 MCDR 默认的偏好设置。见方法
ServerInterface.get_default_preference()
子类可能会重写这个方法,以返回自定义的偏好。比如,
PlayerCommandSource
的该方法将返回对应玩家的偏好在 v2.1.0 版本加入.
- preferred_language_context()[源代码]
一个快速的工具方法,使用该指令源的偏好中的语言来创建一个
RTextMCDRTranslation.language_context()
上下文参见
示例用法:
with source.preferred_language_context(): message = source.get_server().rtr('my_plugin.placeholder').to_plain_text() text.set_click_event(RAction.suggest_command, message)
在 v2.1.0 版本加入.
- has_permission(level: int) bool [源代码]
一个用于测试权限需求的工具方法
- 参数:
level – 用于比较的权限等级
- 返回:
若指令源权限级别不低于给定的权限级别,则返回
True
,否则返回False
- has_permission_higher_than(level: int) bool [源代码]
与
CommandSource.has_permission()
相似,但指令源权限需 高于 给定的权限才返回True
- 参数:
level – 用于比较的权限等级
- 返回:
若指令源权限级别高于给定的权限级别,则返回
True
,否则返回False
指令节点
- class mcdreforged.command.builder.nodes.basic.AbstractNode[源代码]
基类:
ABC
AbstractNode
是所有指令节点的基础类。它同时也是一个抽象类。它提供了多种用于构建指令树的方法- then(node: AbstractNode) Self [源代码]
将子节点附加到其子列表中,然后返回自身
用于构建指令树结构
- 参数:
node – 要添加到当前节点的子列表中的节点实例
例子:
Literal('!!email'). \ then(Literal('list')). \ then(Literal('remove'). \ then(Integer('email_id')) ). \ then(Literal('send'). \ then(Text('player'). \ then(GreedyText('message')) ) )
- runs(func: Callable[[], Any] | Callable[[CommandSource], Any] | Callable[[CommandSource, CommandContext], Any]) Self [源代码]
设置节点的回调函数。在该节点上的指令解析完成后,将执行指定的回调函数
回调函数可以接受 0 至 2 个参数(一个
CommandSource
作为指令源,一个dict
(CommandContext
) 作为上下文)。举个例子,下面的 4 个函数均为可用的回调函数:def callback1(): pass def callback2(source: CommandSource): pass def callback3(source: CommandSource, context: dict): pass callback4 = lambda src: src.reply('pong') node1.runs(callback1) node2.runs(callback2) node3.runs(callback3) node4.runs(callback4)
它们都可以用作
runs
方法的参数这种动态回调参数适配在所有指令节点的回调调用中使用
- 参数:
func – 一个最多可接收 2 个参数的,返回一个 bool 的可调用对象。参数列表:
CommandSource
、dict
(CommandContext
)
- requires(requirement: Callable[[], bool] | Callable[[CommandSource], bool] | Callable[[CommandSource, CommandContext], bool], failure_message_getter: Callable[[], str | RTextBase] | Callable[[CommandSource], str | RTextBase] | Callable[[CommandSource, CommandContext], str | RTextBase] | None = None) Self [源代码]
设置节点的需要的测试器回调。进入此节点时,MCDR将调用需求测试器以查看当前指令源和上下文是否符合你设定的条件
如果测试器返回 True,则MCDR将继续解析指令的其余部分
如果测试器返回
False
,则会引发RequirementNotMet
异常。此时,如果failure_message_getter
参数可用,MCDR 将调用failure_message_getter
以获取消息字符串作为 RequirementNotMet 的异常消息,否则将使用默认消息在 v2.7.0 版本加入: 若多次调用
requires()
,则将使用“与”逻辑合并所有需求,即仅当所有需求都被满足时测试才算通过- 参数:
requirement – 一个最多可接收 2 个参数的,返回一个 bool 的可调用对象。参数列表:
CommandSource
、dict
(CommandContext
)failure_message_getter – 一个最多可接收 2 个参数的,返回一个 str 或一个
RTextBase
的可调用对象。参数列表:CommandSource
、dict
(CommandContext
)
示例用法:
node1.requires(lambda src: src.has_permission(3)) # Permission check node2.requires(lambda src, ctx: ctx['page_count'] <= get_max_page()) # Dynamic range check node3.requires(lambda src, ctx: is_legal(ctx['target']), lambda src, ctx: 'target {} is illegal'.format(ctx['target'])) # Customized failure message
- redirects(redirect_node: AbstractNode) Self [源代码]
将所有后续的子节点指令解析重定向到另一个给定节点
重定向的逻辑:
子节点的遍历
指令回调函数,若当前节点并不包含指令回调函数
未重定向的逻辑:
指令解析,即从指令中解析节点的字面量 / 参数值
节点需求测试
指令建议获取
用途示例:
你需要一个简短的指令和一个全路径指令来执行相同的指令
当解析命令时,你希望重复进入一个命令节点的子节点
注意
redirects()
和then()
之间的区别。redirects()
是重定向子节点,而then()
是添加子节点- 参数:
redirect_node – 当前节点的重定向目标
- suggests(suggestion: Callable[[], Iterable[str]] | Callable[[CommandSource], Iterable[str]] | Callable[[CommandSource, CommandContext], Iterable[str]]) Self [源代码]
设置该节点的指令建议提供函数
字面量节点
Literal
不支持这个方法例子:
Literal('!!whereis'). \ then( Text('player_name'). suggests(lambda: ['Steve', 'Alex']). runs(lambda src, ctx: find_player(src, ctx['player_name'])) )
当用户在控制台中输入
!!whereis
及一个空格字符时,MCDR 将会展示包含"Steve"
及"Alex"
的输入建议- 参数:
suggestion – 一个最多可接收 2 个参数的,返回一个
Iterable[str]
的可调用对象。参数列表:CommandSource
、dict
(CommandContext
)
- on_error(error_type: Type[CommandError], handler: Callable[[], Any] | Callable[[CommandSource], Any] | Callable[[CommandSource, CommandError], Any] | Callable[[CommandSource, CommandError, CommandContext], Any], *, handled: bool = False) Self [源代码]
当发生指令错误时,给定的将调用给定的处理程序以处理错误
- 参数:
error_type –
CommandError
的子类handler – 一个最多可接收 3 个参数的可调用对象。参数列表:
CommandError
、CommandSource
、dict
(CommandContext
)
- 关键字参数:
handled – 如果将 handled 设置为 True,则在调用处理程序回调时会自动调用
CommandError.set_handled
- on_child_error(error_type: Type[CommandError], handler: Callable[[], Any] | Callable[[CommandSource], Any] | Callable[[CommandSource, CommandError], Any] | Callable[[CommandSource, CommandError, CommandContext], Any], *, handled: bool = False) Self [源代码]
与
on_error()
类似,不过它仅在该节点收到了一个来自其子孙节点的指令错误时触发
- class mcdreforged.command.builder.nodes.basic.Literal(literal: str)[源代码]
基类:
EntryNode
字面值节点是一个特殊的节点。它不输出任何值,更像是一个指令分支的载体
字面值节点可以在其构造的函数中接受 str 作为其字面值。当解析指令的下一个元素与节点的字面值完全匹配时,字面值节点才接受并解析指令
字面值节点是唯一可以发起指令执行的节点
- class mcdreforged.command.builder.nodes.basic.ArgumentNode(name: str)[源代码]
基类:
AbstractNode
,ABC
参数节点是一个抽象类,是所有储存解析值的节点类的基础
它拥有着一个 str 属性
name
,用于作为键在上下文中储存解析的值
- class mcdreforged.command.builder.nodes.arguments.NumberNode(name)[源代码]
基类:
ArgumentNode
,ABC
所有数字相关参数节点的基类
它被
Number
,Integer
和Float
继承。它代表一种基于数字的节点对于一个
NumberNode
实例,你可以限制数字的范围。如果解析的数字超出范围,将抛出NumberOutOfRange
异常默认情况下,没有范围限制
- at_min(min_value: int | float) NumberNode [源代码]
设置数字范围的下限。边界值将包含于范围内
- 参数:
min_value – 数字范围的下限
- at_max(max_value: int | float) NumberNode [源代码]
设置数字范围的上限。边界值将包含于范围内
- 参数:
max_value – 数字范围的上限
- class mcdreforged.command.builder.nodes.arguments.Number(name)[源代码]
基类:
NumberNode
一个整数,或一个浮点数
如果下一个元素不是一个数字,一个
InvalidNumber
异常将被抛出
- class mcdreforged.command.builder.nodes.arguments.Integer(name)[源代码]
基类:
NumberNode
一个整数
如果下一个元素不是一个整数,一个
InvalidInteger
异常将被抛出
- class mcdreforged.command.builder.nodes.arguments.Float(name)[源代码]
基类:
NumberNode
一个浮点数
如果下一个元素不是一个浮点数,一个
InvalidFloat
异常将被抛出
- class mcdreforged.command.builder.nodes.arguments.TextNode(name)[源代码]
基类:
ArgumentNode
,ABC
这是一个抽象类。它被
Text
,QuotableText
和GreedyText
继承。它代表一种基于文本的节点对于一个
TextNode
实例,你可以限制文本参数的长度范围。如果解析的文本长度超出范围,则将抛出TextLengthOutOfRange
异常默认情况下,没有长度范围限制
- class mcdreforged.command.builder.nodes.arguments.Text(name)[源代码]
基类:
TextNode
一个不包含空格字符的文本参数
它会持续读取字符,直到遇到一个空格字符
- class mcdreforged.command.builder.nodes.arguments.QuotableText(name)[源代码]
基类:
Text
一个支持读入空格字符的文本参数
它的工作方式与
Text
节点一样,但是它提供了一种输入带有空格的文本的方法:使用两个双引号将文本内容括起来使用双引号括住文本内容后,你可以使用转义字符
\
来转义"
或\
本身例如,以下是可被
QuotableText
接受的一些文本:Something
"Something with space characters"
"or escapes \ like " this"
- class mcdreforged.command.builder.nodes.arguments.GreedyText(name)[源代码]
基类:
TextNode
一个贪婪的文本参数,将接受剩余的所有输入字符串
它的原理很简单:它贪婪地取出指令中所有剩余的文本
将任何子节点附加到
GreedyText
上不是明智的决定,因为那样的话子节点将永远无法读到任何剩余指令
- class mcdreforged.command.builder.nodes.arguments.Boolean(name: str)[源代码]
基类:
ArgumentNode
一个简易的布尔值参数,仅支持输入
true
或false
,并将其储存为对应的 bool 值。忽略大小写如果输入非法,抛出
InvalidBoolean
异常在 v2.3.0 版本加入.
- class mcdreforged.command.builder.nodes.arguments.Enumeration(name: str, enum_class: Type[Enum])[源代码]
基类:
ArgumentNode
一个与给定的枚举类(Enum)相关联的节点,用于读取枚举中类的枚举值
枚举类本身是其构造函数所需的参数之一
如果输入参数不是所提供的枚举类中的合法枚举名,抛出
InvalidEnumeration
异常示例用法:
class MyColor(Enum): red = 'red color' blue = 'blue color' green = 'green color' node = Enumeration('arg', MyColor)
在 v2.3.0 版本加入.
指令构建器
- class mcdreforged.command.builder.tools.SimpleCommandBuilder[源代码]
一个无需考虑树结构指令构造器。声明&定义,你要做的就这些
在 v2.6.0 版本加入.
- exception Error[源代码]
在
SimpleCommandBuilder
中使用的自定义异常
- command(command: str) Callable[[CommandCallbackFunc], CommandCallbackFunc] [源代码]
- command(command: str, callback: Callable[[], Any] | Callable[[CommandSource], Any] | Callable[[CommandSource, CommandContext], Any]) None
定义一条指令及其回调函数
指令路径字符串由多个由空格分隔开的元素组成,这些元素即为对应的指令节点的名字,他们描述了指令树中的一条从根节点到目标节点的路径
如果一个节点拥有一个被
"<"
和">"
包裹住的名字,它将被视为一个参数节点,例如"<my_arg>"
。否则,它将被视作一个字面量节点,如"my_literal"
你需要使用
arg()
方法来给出参数节点的定义。你也可以使用literal()
方法来给出自定义字面量节点的定义例子:
builder.command('!!email list', list_email) builder.command('!!email remove <email_id>', remove_email) builder.command('!!email send <player> <message>', send_email)
除此之外,你还可以把此方法用作一个装饰器,来装饰指令回调函数。只需仅传入第一个参数即可:
# This syntactic sugar does the same thing as `builder.command('!!email list', list_email)` @builder.command('!!email list') def list_email(source: CommandSource, context: CommandContext): pass # You can even chain the decorator. All given commands will use function `foo_bar()` as the callback @builder.command('!!email foo') @builder.command('!!email bar') def foo_bar(source: CommandSource, context: CommandContext): pass
- 参数:
command – 一个指令路径字符串,如
"!!calc add <value_a> <value_b>"
callback – 本条指令的回调函数,将被传递给
AbstractNode.then
方法
在 v2.10.0 版本加入: 现在它可以用作一个装饰回调函数的装饰器了
- arg(arg_name: str, node_factory: Callable[[str], ArgNodeType]) NodeDefinition[ArgNodeType] [源代码]
为一个参数名字定义参数节点。所有在
command()
出现的参数名字均需要被定义注意到几乎所有的 MCDR 内置参数节点均可使用 1 个参数名参数来构造(如
Text
、Number
),因此你可以直接在这里填入参数节点的类名例子:
builder.arg('my_arg', QuotableText) builder.arg('my_arg', lambda name: Integer(name).at_min(0))
- 参数:
arg_name – 参数节点的名称。可选地,它可以被
"<>"
括住。例子:"my_arg"
、"<my_arg>"
node_factory – 一个参数节点的构造函数,接受参数节点名字作为其唯一一个参数,返回一个
ArgumentNode
实例
- 返回:
一个
NodeDefinition
对象。借助它,你可以进一步的自定义这个节点定义
- literal(literal_name: str, node_factory: Callable[[str], Literal] | None = None) NodeDefinition[Literal] [源代码]
为一个字面量名字定义一个字面量节点。如果你想要一些拥有自定义功能的字面量节点它将会很有用。如果你仅仅一个普通的字面量节点,你无需调用这个方法来给出定义,因为本构建器会使用默认的
Literal
构造函数来构造字面量节点- 参数:
literal_name – 字面量节点的名字
node_factory – 一个字面量节点的构造函数,接受字面量节点名字作为其唯一一个参数,返回一个
Literal
实例。参数为可选参数
- 返回:
一个
NodeDefinition
对象。借助它,你可以进一步的自定义这个节点定义
- build(*, use_cache: bool = True) List[AbstractNode] [源代码]
构建指令树
拥有相同名字的节点将被复用。比如,如果你定义了 3 个指令了,指令路径分别为
"!!foo"
、"!!foo bar"
和 “!!foo baz"
,那么根节点"!!foo"
将被复用,最后将会只有一个"!!foo"
节点- 关键字参数:
use_cache – 若设为 false,不使用结果缓存,总是构建新的指令树
- 返回:
一个列表,储存着构建完成的指令树的根节点。构建结果将被缓存,直到你再次操作这个指令构建器。借助
clean_cache()
,你可以主动地清空构建结果缓存- 抛出:
SimpleCommandBuilder.Error – 如果存在未定义的参数节点
在 v2.9.0 版本加入: 添加
use_cache
关键字参数
- register(server: PluginServerInterface)[源代码]
一个为懒人提供的工具方法,使用方法
build()
构建指令树,并将构建结果向 MCDR 注册- 参数:
server – 你的插件的
PluginServerInterface
实例- 抛出:
SimpleCommandBuilder.Error – 如果构建失败,或者构建结果中存在非字面量的根节点
- add_children_for(parent_node: AbstractNode)[源代码]
一个为懒人提供的工具方法,使用方法
build()
构建指令树,随后借助then()
方法,将构建结果添加为给定指令节点的子节点- 参数:
parent_node – 将作为构建结果节点的父亲的指令节点
- 抛出:
SimpleCommandBuilder.Error – 若构建失败
在 v2.8.0 版本加入.
- class mcdreforged.command.builder.tools.NodeDefinition[源代码]
一个储存着额外的自定义信息的节点定义类
- post_process(post_processor: Callable[[NodeType], Any]) Self [源代码]
为当前节点定义增加一个后续处理函数
在
SimpleCommandBuilder.build()
中,当一个节点被构造后,所有的后续处理函数将被作用于这个节点对象上
- requires(requirement: Callable[[], bool] | Callable[[CommandSource], bool] | Callable[[CommandSource, CommandContext], bool], failure_message_getter: Callable[[], str | RTextBase] | Callable[[CommandSource], str | RTextBase] | Callable[[CommandSource, CommandContext], str | RTextBase] | None = None) Self [源代码]
- suggests(suggestion: Callable[[], Iterable[str]] | Callable[[CommandSource], Iterable[str]] | Callable[[CommandSource, CommandContext], Iterable[str]]) Self [源代码]
- on_error(error_type: Type[CommandError], handler: Callable[[], Any] | Callable[[CommandSource], Any] | Callable[[CommandSource, CommandError], Any] | Callable[[CommandSource, CommandError, CommandContext], Any], *, handled: bool = False) Self [源代码]
- on_child_error(error_type: Type[CommandError], handler: Callable[[], Any] | Callable[[CommandSource], Any] | Callable[[CommandSource, CommandError], Any] | Callable[[CommandSource, CommandError, CommandContext], Any], *, handled: bool = False) Self [源代码]
工具
- class mcdreforged.command.builder.tools.Requirements[源代码]
一些常用的,用于指令节点需求测试的回调函数工厂
示例用法:
node.requires(Requirements.has_permission(1))
在 v2.6.0 版本加入.
- classmethod has_permission(level: int) Callable[[CommandSource], bool] [源代码]
检查指令源是否拥有给定的权限等级
- 参数:
level – 最小的可被接受的权限等级
- classmethod is_player() Callable[[CommandSource], bool] [源代码]
检查指令源是否为玩家
- classmethod is_console() Callable[[CommandSource], bool] [源代码]
检查指令源是否为控制台
异常
- exception mcdreforged.command.builder.exception.CommandErrorBase[源代码]
-
所有指令相关错误的异常基类
类继承树状图
CommandErrorBase ├── IllegalNodeOperation └── CommandError ├── UnknownCommand ├── UnknownArgument ├── RequirementNotMet └── CommandSyntaxError └── IllegalArgument ├── AbstractOutOfRange │ ├── NumberOutOfRange │ └── TextLengthOutOfRange ├── InvalidNumber ├── InvalidInteger ├── InvalidFloat ├── IllegalEscapesUsage ├── UnclosedQuotedString ├── EmptyText ├── InvalidBoolean └── InvalidEnumeration
- exception mcdreforged.command.builder.exception.CommandError(message: str | RTextBase, parsed_command: str, failed_command: str)[源代码]
基类:
CommandErrorBase
,ABC
解析指令出错时抛出的异常基类
- exception mcdreforged.command.builder.exception.UnknownCommand(parsed_command, failed_command)[源代码]
基类:
CommandError
指令解析完全,但当前节点并不包含指令回调函数
- exception mcdreforged.command.builder.exception.UnknownArgument(parsed_command: str, failed_command: str)[源代码]
基类:
CommandError
指令字符串仍有剩余,但已经没有匹配的子指令节点了
- exception mcdreforged.command.builder.exception.RequirementNotMet(parsed_command: str, failed_command: str, reason: str | RTextBase | None)[源代码]
基类:
CommandError
指令源进入本节点所需的需求未被满足
- exception mcdreforged.command.builder.exception.CommandSyntaxError(message: str | RTextBase, char_read: int | str)[源代码]
基类:
CommandError
,ABC
指令解析出错的异常基类
- exception mcdreforged.command.builder.exception.IllegalArgument(message: str | RTextBase, char_read: int | str)[源代码]
-
参数节点解析出错的异常基类,通常由错误的参数语法导致
- exception mcdreforged.command.builder.exception.AbstractOutOfRange(message: str | RTextBase, char_read: int | str, value, range_l, range_r)[源代码]
基类:
IllegalArgument
,ABC
超出范围相关错误的异常基类
- exception mcdreforged.command.builder.exception.NumberOutOfRange(char_read: int | str, value, range_l, range_r)[源代码]
-
解析出的数值超出了限制范围
- exception mcdreforged.command.builder.exception.InvalidNumber(char_read: int | str)[源代码]
-
解析结果不是一个合法的数字
- exception mcdreforged.command.builder.exception.InvalidInteger(char_read: int | str)[源代码]
-
解析结果不是一个合法的整数
- exception mcdreforged.command.builder.exception.InvalidFloat(char_read: int | str)[源代码]
-
解析结果不是一个合法的浮点数
- exception mcdreforged.command.builder.exception.TextLengthOutOfRange(char_read: int | str, value, range_l, range_r)[源代码]
-
文本长度超出了限制范围
- exception mcdreforged.command.builder.exception.IllegalEscapesUsage(char_read: int | str)[源代码]
-
文本包含了非法的转义符
\
用法
- exception mcdreforged.command.builder.exception.UnclosedQuotedString(char_read: int | str)[源代码]
-
双引号未闭合
- exception mcdreforged.command.builder.exception.InvalidBoolean(char_read: int | str)[源代码]
-
解析结果不是一个合法的布尔值
杂项
- class mcdreforged.command.builder.common.CommandContext(source: CommandSource, command: str)[源代码]
-
CommandContext
储存着当前指令解析过程中的信息。它是一个继承自 dict 的类CommandContext
最常见的用法是储存参数节点
解析出的结果。参数节点的名字以及解析结果将作为键值对储存于CommandContext
中,这意味着你可以使用 dict 的方法,如context['arg_name']
,来访问这些参数值CommandContext
还提供了其他有用的,可用于获取当前指令上下文的方法- property source: CommandSource
触发当前指令解析的指令源
- property node_path: List[AbstractNode]
从指令树的根节点到当前节点的路径
- mcdreforged.command.builder.command_builder_util.DIVIDER = ' '
在指令字符串中用于分割元素的分隔符——空格
- mcdreforged.command.builder.command_builder_util.remove_divider_prefix(text: str) str [源代码]
移除给定文本的分隔符前缀。它通常于获取指令字符串的下一个元素时使用
例子:
>>> remove_divider_prefix('foo bar') 'foo bar' >>> remove_divider_prefix(' foo bar') 'foo bar'
- 参数:
text – 将被移除分隔符前缀的文本
- mcdreforged.command.builder.command_builder_util.get_element(text: str) str [源代码]
从剩余的输入字符串中获取一个元素
例子:
>>> get_element('foo bar') 'foo' >>> get_element('foo bar') 'foo' >>> get_element('fooooo') 'fooooo' >>> get_element(' foo') ''
- 参数:
text – 将被解析的剩余输入串。它不应以
DIVIDER
为前缀
- mcdreforged.command.builder.command_builder_util.get_int(text: str) Tuple[int | None, int] [源代码]
从剩余的输入字符串中获取一个 int
例子:
>>> get_int('1234 abc') (1234, 4) >>> get_int('foo bar') (None, 3) >>> get_int(' 1234 abc') (None, 0)
- 参数:
text – 将被解析的剩余输入串。它不应以
DIVIDER
为前缀- 返回:
一个储存着 (值, 读取字符个数) 的元组。如果解析失败,值将会为 None
- mcdreforged.command.builder.command_builder_util.get_float(text: str) Tuple[float | None, int] [源代码]
从剩余的输入字符串中获取一个 float
例子:
>>> get_float('123.4 abc') (123.4, 5) >>> get_float('foo bar') (None, 3) >>> get_int(' 123.4 abc') (None, 0)
- 参数:
text – 将被解析的剩余输入串。它不应以
DIVIDER
为前缀- 返回:
一个储存着 (值, 读取字符个数) 的元组。如果解析失败,值将会为 None