Switch 指令
开关式指令。这是「命令式指令」的一类特化,用于特定的存在类似开启/关闭的两种相反状态的指令。它通常同时提供 开/关
两个指令头。
Q: #ban 114514191
A: 封禁用户 114514191 成功!
Q: #unban 114514191
A: 取消封禁用户 114514191 成功!
基本属性
Switch 指令拥有六个独有属性,它的定义如下:
type SwitchConfig = CommandCfg & {
type: Switch["type"];
mode: "single" | "divided";
onKey: string;
offKey: string;
header: string;
regexps: string[] | string[][];
};
type
- 类型:
"switch"
必填项,固定值 switch
,用于标记这是一个 Switch
类型指令。
mode
- 类型:
"single" | "divided"
- 允许用户配置:
是
表示开关类指令的构成模式。
- 设置为
single
时,表示单指令头模式。onKey
与offKey
将被|
连接作为可选单元,最终被组装为形如header (on|off)
的表达式。 - 设置为
divided
时,表示拆分指令头模式。此时header
配置将被忽略,开关关键词将作为header
,最终将被组装为形如(onKey|offKey) prams
的表达式。
onKey
- 类型: string
- 允许用户配置:
是
必填项,表示指令状态为「开」的关键词。
offKey
- 类型: string
- 允许用户配置:
是
必填项,表示指令状态为「关」的关键词。
header
- 类型: string
- 允许用户配置:
是
必填项,表示该指令的唯一指令头。类似 Order.headers,同样可以使用 __
来忽略指令起始符。
regexps
- 类型: string[]|string[][]
- 允许用户配置:
否
必填项,与 Order.regexps 基本一致。
特别的,Switch
指令还允许你在正则表达式中使用 #{OPT}
来标识开/关关键词的位置,如 [ "#{OPT}", "\\d+" ]
,这将导出如 /#calc (add|sub) \d+/
的指令。 #{OPT}
标识在 divided
模式中不生效。
开关插槽
在 Switch 命令中
入口函数
Switch 指令的入口函数定义方式为:
import { defineDirective } from "@/modules/command/main";
export default defineDirective( "switch", i => {
// 入口函数内容
} );
下面对参数 i
中与其他指令行为有所不同的属性做出说明:
matchResult
其类型如下:
interface SwitchMatchResult {
type: "switch";
switch: string;
match: string[];
isOn: boolean;
}
由于 Switch 指令存在两种 mode
,这里分别针对两种指令示例讨论;
mode
为 single
的指令示例:
const switchTest = {
type: "switch",
mode: "single",
header: "open",
regexp: [ "\\d{9}", "#{OPT}", "[\u4e00-\u9fa5]+" ],
onKey: "on",
offKey: "off",
// ... 其他配置
};
此时用户输入: #open 114514191 on 任意门
mode
为 divided
的指令示例:
const switchTest = {
type: "switch",
mode: "divided",
header: "",
regexp: [ "\\d{9}", "[\u4e00-\u9fa5]+" ],
onKey: "open",
offKey: "close",
// ... 其他配置
};
此时用户输入: #open 114514191 任意门
header
匹配到的指令头,当指令 mode
不同时有两种表现形式,根据上面提供的示例:
single
: 值为"#open"
divided
: 值永远为空字符串""
switch
匹配到的开关关键词,当指令 mode
不同时有两种表现形式,根据上面提供的示例:
single
: 值为"on"
divided
: 值为"#open"
match
与 Order.matchResult.match 行为一致。需要注意的是,开关占位符 ${OPT}
也会按照声明位置出现在结果数组中。根据上面提供的示例:
single
: 值为["114514191", "on", "任意门"]
divided
: 值为["114514191", "任意门"]
isOn
当前是否为开启状态,用于确认用户触发的是指令的哪一种状态。根据上面提供的示例:
single
: 此时用户输入的 switchKey 为on
,与onKey
一致,isOn 值为true
divided
: 此时用户输入的 switchKey 为open
,与onKey
一致,isOn 值为true
示例
下面是一个完整的 Switch
指令示例,其中分别给出了 mode
两种模式的配置方案:
/* 指令配置 */
/* mode - single */
const switchSingle: SwitchConfig = {
type: "switch",
mode: "single",
cmdKey: "silvery-star.switch-single",
desc: ["single模式", "[任意内容] #{OPT}"],
headers: "switch_single",
main: "achieves/switch",
onKey: "on",
offKey: "off",
regexps: [".+", "#{OPT}"],
detail: "触发案例:#switch_single 空调 on"
};
/* mode - single */
const switchDivided: SwitchConfig = {
type: "switch",
mode: "divided",
cmdKey: "silvery-star.switch-divided",
desc: ["divided模式", "[任意内容]"],
headers: "",
main: "achieves/switch",
onKey: "switch_divided_open",
offKey: "switch_divided_close",
regexps: [".+"],
detail: "触发案例:#switch_divided_open 空调"
};
/* achieves/echo.ts */
import { defineDirective } from "@/modules/command/main";
export default defineDirective( "order", async i => {
const isOn = i.matchResult.isOn;
const [ device ] = i.matchResult.match;
await i.sendMessage( `${ device }${ isOn ? "启动" : "关闭" }成功` );
} );