动作处理器开发
QI 的动作 YAML 不能写逻辑分支。要把 if/switch/状态判断引入动作系统,唯一正道是实现一个动作处理器,逻辑写在 Kotlin/Java 里,YAML 只引用它并传 payload。
1. 接口 QinhActionHandler
kotlin
interface QinhActionHandler {
val handlerId: String // 唯一 ID,建议 "命名空间:名"
fun dispatch(context: QinhActionContext): ActionDispatchResult
fun isAvailable(): Boolean = true // 依赖插件未启用时返回 false
}返回值 ActionDispatchResult:
| 值 | 含义 |
|---|---|
HANDLED | 成功执行(会触发扣消耗 / 记冷却) |
NOT_HANDLED | 处理器拒绝(如校验失败) |
HANDLER_UNAVAILABLE | 依赖未加载 |
2. 上下文 QinhActionContext
kotlin
data class QinhActionContext(
val trigger: String, // 触发器名(如 "left_click")
val player: Player,
val item: ItemStack,
val itemId: String,
val handlerId: String,
val payload: String, // YAML 里传的原始 payload
val compileEpoch: Long?,
val providerSnapshot: ProviderSnapshot,
val triggerType: TriggerType?,
val rawContext: RawSkillContext, // 扩展上下文(潜行状态等)
)3. 注册
kotlin
QinhItemsAPI.actions().registerHandler(object : QinhActionHandler {
override val handlerId = "myplugin:smart_cast"
override fun dispatch(ctx: QinhActionContext): ActionDispatchResult {
val payload = ctx.payload.trim()
if (payload.isEmpty()) return ActionDispatchResult.NOT_HANDLED
// 复杂逻辑:if / switch / 状态判断都写这里
if (ctx.player.level < 10) {
ctx.player.sendMessage("§c等级不足")
return ActionDispatchResult.NOT_HANDLED
}
ctx.player.sendMessage("释放:$payload")
return ActionDispatchResult.HANDLED
}
})在你插件的 onEnable() 里注册即可。之后 YAML 就能引用:
yaml
refs:
- handler: myplugin:smart_cast
payload: "fireball"4. payload schema
可选:为处理器声明字段结构,让 GUI 编辑器自动生成表单并做校验。
kotlin
QinhItemsAPI.actions().registerPayloadSchema("myplugin:smart_cast") {
serializeMode = PayloadSerializeMode.JSON // 或 PLAIN
string(key = "skill", required = true, label = "技能 ID")
int(key = "power", default = "1", label = "强度")
double(key = "multiplier", label = "倍数")
bool(key = "silent", default = "false", label = "静默?")
}字段类型
| DSL | 类型 | 校验 |
|---|---|---|
string(...) | STRING | 任意文本 |
int(...) | INT | 整数 |
double(...) | DOUBLE | 浮点 |
bool(...) | BOOL | true/false/1/0 |
序列化模式
- PLAIN:单字段,payload 是裸字符串。
- JSON:多字段,payload 是 JSON 对象,如
{"skill":"fireball","power":"2"}。
GUI 编辑流程见 动作编辑器。Codec 操作:
kotlin
PayloadSchemaCodec.defaults(schema) // 默认值
PayloadSchemaCodec.deserializeForEditor(schema, payload)
PayloadSchemaCodec.serialize(schema, editorMap)
PayloadSchemaValidator.validate(schema, fieldMap) // Result(ok, errors)5. 直接派发(不经触发器)
kotlin
val report = QinhItemsAPI.actions().dispatch(player, item, "left_click")返回 DispatchReport,含每个处理器的结果。
6. 边界回顾
| 谁做什么 |
|---|
| 服主写「什么时候发生什么」:触发器 + refs |
| 开发者写「怎么发生」:处理器内部逻辑 |
服主在 YAML 里组合处理器,开发者把复杂度收进处理器。这条边界让配置可被 GUI 完整编辑,见 动作系统概览 → 设计。
7. 校验:处理器引用
保存 / 加载时 ActionRefDeclarationValidator 会校验:handler 非空、无空格、建议 命名空间:id 格式;未注册的 handler 会警告(运行时 HANDLER_UNAVAILABLE)。