Class CommandNode<NCS>
- Type Parameters:
NCS- Native Command Source,平台原生命令来源类型
- Direct Known Subclasses:
ClientCommand,HelpCommand,InfoCommand,ListCommand,ReconnectAllCommand,ReconnectCommand,ReloadCommand,RootCommand,ServerCommand
命令树中的一个节点,既可以是根节点,也可以是任意层级的子节点。
命令来源:命令层只认识 CommandExecutionContext ——
不认识任何平台类型,也不通过 AbstractPlatformContext 回执或判断权限。
扩展点
第三方命令只需覆盖以下方法:
getName()—— 节点名(同层唯一,忽略大小写);getDescription()—— 描述;getUsage()/getPermissionNode()—— 可选覆盖;onExecute(io.github.theword.queqiao.core.command.CommandExecutionContext<NCS>, java.util.List<java.lang.String>)—— 实际命令业务扩展点。
final:它们承担 Core 不变量(结构封装、注册校验、执行模板),
不允许通过覆盖绕过。
线程安全契约(重要)
同一个 CommandNode 实例可能处理多个命令调用,实现不得把单次 invocation
的可变状态(当前 sender / args / context / player)存储在实例字段中。
Invocation 状态必须全部来自方法参数;实例字段只允许存放构造期注入的不可变依赖。
注册生命周期
registration phase(可 addChild)
↓
command tree completed(freeze)
↓
dispatch phase(execute / tabComplete;不得再修改结构)
结构进入 dispatch 阶段后不得并发修改。freeze() 之后任何
addChild(io.github.theword.queqiao.core.command.CommandNode<NCS>) 都会快速失败,因此上述不变量无法被绕过。- Since:
- 0.5.0
-
Field Summary
Fields -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionfinal voidaddChild(CommandNode<NCS> child) 添加子命令final intexecute(CommandExecutionContext<NCS> context, List<String> args) 执行命令final voidfreeze()冻结整棵命令树的结构final List<CommandNode<NCS>> 获取所有子命令abstract String获取命令描述final String获取完整命令路径final String获取完整权限节点abstract StringgetName()获取命令名称final CommandNode<NCS> 获取父命令获取命令权限节点getUsage()获取命令用法final booleanisFrozen()final booleanisRoot()判断是否为根命令protected abstract voidonExecute(CommandExecutionContext<NCS> context, List<String> args) 执行命令逻辑final voidsendCommandTree(CommandExecutionContext<NCS> context, CommandNode<NCS> command) 递归发送指定命令以及所有子命令的树形结构
-
Field Details
-
logger
protected final org.slf4j.Logger logger日志实现
-
-
Constructor Details
-
CommandNode
protected CommandNode(org.slf4j.Logger logger) 构造命令节点- Parameters:
logger- 日志实现,不得为 null
-
-
Method Details
-
addChild
添加子命令注册不变量(全部 fail-fast,抛
IllegalArgumentException):child不得为 null;- 子命令名称不得为 null 或空白;
- 同一父节点下名称不得重复(忽略大小写,与路由的匹配规则一致);
child不得已经属于另一个父节点 —— 不自动 detach;- 不得形成环(
child不能是自己或自己的祖先); - 结构已冻结时不得再注册。
刻意不做静默覆盖:重复注册属于装配错误,应在构建期就暴露, 而不是等到运行期表现为"某个子命令神秘消失"。
- Parameters:
child- 子命令,不得为 null- Throws:
IllegalArgumentException- 违反上述任一不变量IllegalStateException- 结构已冻结
-
freeze
public final void freeze()冻结整棵命令树的结构幂等:重复调用无副作用。
冻结后:
addChild(io.github.theword.queqiao.core.command.CommandNode<NCS>)抛IllegalStateException, 从而保证 dispatch 阶段不会与结构修改并发。CommandRouter.execute(io.github.theword.queqiao.core.command.CommandExecutionContext<NCS>, java.lang.String[])/CommandRouter.tabComplete(io.github.theword.queqiao.core.command.CommandExecutionContext<NCS>, java.lang.String[])会在首次调用时 自动冻结,因此正常路径无需手动调用本方法;需要在装配完成后立即封板时可显式调用。 -
isFrozen
public final boolean isFrozen()- Returns:
- 结构是否已冻结
-
getChildren
获取所有子命令- Returns:
- 只读的子命令列表
-
getParent
获取父命令- Returns:
- 父命令节点,根节点返回 null
-
isRoot
public final boolean isRoot()判断是否为根命令- Returns:
- 是否为根命令
-
getFullPath
获取完整命令路径示例:/queqiao client list
- Returns:
- 完整命令路径
-
getFullPermissionNode
获取完整权限节点从根节点开始拼接,示例:queqiao.client.list
- Returns:
- 完整权限节点
-
getName
获取命令名称- Returns:
- 命令名称
-
getDescription
获取命令描述- Returns:
- 命令描述
-
getUsage
获取命令用法默认返回完整路径,子类可以覆盖以添加参数说明
- Returns:
- 命令用法
-
getPermissionNode
获取命令权限节点默认返回完整权限节点,子类可以覆盖以自定义权限
- Returns:
- 权限节点
-
execute
执行命令模板方法:权限判定、分隔线、异常兜底都由本方法负责, 子类不应覆盖(本方法为
final),业务逻辑写在onExecute(io.github.theword.queqiao.core.command.CommandExecutionContext<NCS>, java.util.List<java.lang.String>)。异常处理:命令体的异常只回执一句通用提示,完整堆栈写入日志 —— 不把第三方命令的异常信息(可能含文件路径、内部状态、token / URL)暴露给命令调用者。
- Parameters:
context- 本次命令调用的执行上下文,不得为 nullargs- 命令参数,不得为 null(无参数传空列表)- Returns:
- 执行信号(见
CommandConstant) - Throws:
NullPointerException- context 或 args 为 null- Since:
- 0.5.0
-
onExecute
执行命令逻辑这是实际命令业务的唯一扩展点。
入参均已由
execute(io.github.theword.queqiao.core.command.CommandExecutionContext<NCS>, java.util.List<java.lang.String>)校验非 null;实现不得把 context / args 保存到实例字段(见类级线程安全契约)。- Parameters:
context- 本次命令调用的执行上下文,永不为 nullargs- 命令参数,永不为 null
-
sendCommandTree
递归发送指定命令以及所有子命令的树形结构- Parameters:
context- 本次命令调用的执行上下文,不得为 nullcommand- 当前命令节点,不得为 null- Throws:
NullPointerException- context 或 command 为 null
-