From f508500367d530d81f24c068687956bd62287828 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=AA=80=E8=BD=B6=E6=AD=A5=E6=A3=8B?=
<57583509+oissevalt@users.noreply.github.com>
Date: Wed, 3 Jul 2024 16:24:51 +0800
Subject: [PATCH] Refined type info
---
examples_ts/seal.d.ts | 1075 ++++++++++++++++++++++++++++-------------
1 file changed, 728 insertions(+), 347 deletions(-)
diff --git a/examples_ts/seal.d.ts b/examples_ts/seal.d.ts
index 2245e78..dc97b55 100644
--- a/examples_ts/seal.d.ts
+++ b/examples_ts/seal.d.ts
@@ -1,393 +1,774 @@
+/** 海豹核心的 JS 接口.*/
declare namespace seal {
- /** 信息上下文 */
- export interface MsgContext {
- /** 当前群信息 */
- group: GroupInfo;
- /** 当前群的玩家数据 */
- player: GroupPlayerInfo;
- /** 当前群内是否启用bot(注:强制@时这个值也是true,此项是给特殊指令用的) */
- isCurGroupBotOn: boolean;
- /** 是否私聊 */
- isPrivate: boolean;
- /** 权限等级 40邀请者 50管理 60群主 100master */
- privilegeLevel: number;
- /** 代骰附加文本 */
- delegateText: string
- /** 对通知列表发送消息 */
- notice(text: string): void
-
- // 谨慎使用角色卡相关 api ,有可能写坏数据库
-
- /** 绑定角色卡到当前群 */
- chBindCur(name: string)
- /* 获取当前群绑定角色 返回名字或者空字符串*/
- chBindCurGet(): string
- /** 获取一个正在绑定状态的卡,可用于该卡片是否绑卡检测 */
- chBindGet(name: string): ValueMap
- /** 返回当前卡绑定的群列表 */
- chBindGetList(): string[]
- /** 解除某个角色的绑定 返回绑定过的群列表 */
- chUnbind(name: string): string[]
- /** 解除绑定 成功返回 `[角色名,true]`,失败返回 `["",false]` */
- chUnbindCur(name: string): [string, boolean]
-
-
- /* 判断角色是否存在 */
- chExists(name: string): boolean
- /** 新建角色 成功 true;存在同名角色 false */
- chNew(name: string): boolean
- /** 清空当前群角色卡变量 返回被清空的变量数量 */
- chVarsClear(): number
- /** 获取当前角色 ValueMap */
- chVarsGet(): [ValueMap,boolean]
- /** 获取当前角色变量数量,底层为 `ValueMap.len()` */
- chVarsNumGet(): number
- /** 更新角色卡操作时间 */
- chVarsUpdateTime(): void
-
- // 这些接口不推荐使用,太麻烦了
- /** 获取角色数据 成功返回 ValueMap ,失败返回 null */
- chGet(name: string): ValueMap | null
- /** 加载角色,成功返回 ValueMap ,失败返回 null */
- chLoad(name: string): ValueMap | null
- /** 加载个人群内数据 */
- loadGroupVars(g: GroupInfo, p: GroupPlayerInfo): void
- /** 加载个人全局数据 */
- loadPlayerGlobalVars(): void
- /** 加载个人群内数据 */
- loadPlayerGroupVars(): void
+ /**
+ * 依据模板设定 `ctx` 中玩家名片. 返回格式化后的名片.
+ * @param ctx 玩家上下文, 将设定 `ctx.player.userId` 的名片.
+ * @param tmpl 名片模版.
+ */
+ export function applyPlayerGroupCardByTemplate(ctx: MsgContext, tmpl: string): string;
- }
+ /**
+ * 从提供的终结点信息和原始消息创造一个独立的上下文.
+ * @param ep 终结点信息.
+ * @param msg 原始信息.
+ */
+ export function createTempCtx(ep: EndPointInfo, msg: Message): MsgContext;
- export interface ValueMap {
- /** 获取 */
- get(k): [any, boolean]
- /** 添加 */
- set(k, v): void
- /** 删除 */
- del(k): void
- /** 数量 */
- len(): number
- /** 迭代 */
- next(): [any, any, boolean]
- /** 遍历 参数不能传入 `()=>null`,但可以传入 `()=>{}` 或者 `function(){}` */
- iterate(fun: (k,v)=>void): void
- // 加锁
- lock(): void
- // 解锁
- unlock(): void
- }
+ /**
+ * 格式化一条信息,相当于 text 指令.
+ * @param ctx 上下文信息, 读取个人变量等时所用.
+ * @param text 要格式化的信息.
+ */
+ export function format(ctx: seal.MsgContext, text: string): string;
+
+ /**
+ * 取回一条由骰主自定义的文本信息, 例如检定大失败提示. 如果有多条信息则随机返回一条.
+ * `key` 的格式为 `分类:标识符`, 在 WebUI 中可以看见, 如 `COC:检定_大失败`.
+ */
+ export function formatTmpl(ctx: seal.MsgContext, key: string): string;
+
+ /**
+ * 允许代骰时, 获取第一个自己以外的被 @ 对象. 返回的上下文独立于 `ctx`.
+ * @param ctx 原始上下文.
+ * @param cmdArgs 原始指令参数.
+ * @see CmdItemInfo.allowDelegate
+ */
+ export function getCtxProxyFirst(ctx: MsgContext, cmdArgs: CmdArgs): MsgContext;
- /** 群信息 */
- export interface GroupInfo {
- active: boolean;
- groupId: string;
- groupName: string;
- /** COC规则序号 */
- cocRuleIndex: number;
- /** 当前log名字,若未开启为空 */
- logCurName: string;
- /** 当前log是否开启 */
- logOn: boolean;
- /** 是否显示入群迎新信息 */
- showGroupWelcome: boolean;
- /** 入群迎新文本 */
- groupWelcomeMessage: string;
- /** 最后指令时间(时间戳) */
- recentCommandTime: number;
- /** 入群时间(时间戳) */
- enteredTime: number;
- /** 邀请人ID */
- inviteUserId: string;
+ /**
+ * 创建一个新的 `Message` 实例, 其任何字段都是默认值.
+ */
+ export function newMessage(): Message;
+
+ /**
+ * 在 `msg` 所在上下文内发送消息. 群聊/私聊取决于 [`msg.messageType`]{@link Message.messageType},
+ * 发送对象取决于 [`msg.groupId`]{@link Message.groupId}(群聊)或
+ * [`msg.sender.userId`]{@link Message.sender}(私聊).
+ * @param ctx 群组上下文, 在该函数内几乎没有用, 但可能被下游事件使用, 因此建议保证其数据有效.
+ * @param msg 原消息.
+ * @param text 要发送的消息.
+ */
+ export function replyToSender(ctx: MsgContext, msg: Message, text: string): void;
+
+ /**
+ * 私聊发送消息给 [`msg.sender.userId`]{@link Message.sender}.
+ * @param ctx 群组上下文, 在该函数内几乎没有用, 但可能被下游事件使用, 因此建议保证其数据有效.
+ * @param msg 原始消息.
+ * @param text 要发送的消息.
+ */
+ export function replyPerson(ctx: MsgContext, msg: Message, text: string): void;
+
+ /**
+ * 群聊发送消息给 [`msg.groupId`]{@link Message.groupId}, 原始消息必须是群聊事件.
+ * @param ctx 群组上下文, 在该函数内几乎没有用, 但可能被下游事件使用, 因此建议保证其数据有效.
+ * @param msg 原始消息.
+ * @param text 要发送的消息.
+ */
+ export function replyGroup(ctx: MsgContext, msg: Message, text: string): void;
+
+ /** 黑名单管理接口. */
+ export const ban: {
+ /**
+ * 添加一个封禁项目.
+ * @param ctx 上下文信息, 用于提取用户名与个人变量等.
+ * @param id 要封禁的用户或群组 ID, 需带上平台前缀.
+ * @param place 事发地点, 群组或私聊. 一般与 `ctx.group.groupId` 相同.
+ * @param reason 封禁理由.
+ */
+ addBan(ctx: MsgContext, id: string, place: string, reason: string): void;
+
+ /**
+ * 添加一个豁免项目.
+ * @param ctx 上下文信息, 用于提取用户名与个人变量等.
+ * @param id 要信任的用户或群组 ID, 需带上平台前缀.
+ * @param place 事发地点, 群组或私聊. 一般与 `ctx.group.groupId` 相同.
+ * @param reason 信任理由.
+ */
+ addTrust(ctx: MsgContext, id: string, place: string, reason: string): void;
+
+ /**
+ * 移除名单中的一个项目.
+ * @param ctx 上下文信息, 用于提取用户名与个人变量等.
+ * @param id 项目 ID.
+ */
+ remove(ctx: MsgContext, id: string): void;
+
+ /** 列出当前所有的黑名单, 可能耗时较长. */
+ getList(): BanListInfoItem[];
+
+ /**
+ * 获取名单中的一个项目.
+ * @param id 项目 ID.
+ */
+ getUser(id: string): BanListInfoItem;
}
- /** 群内玩家数据 */
- export interface GroupPlayerInfo {
- /** 用户昵称 */
- name: string;
- /** 用户ID */
- userId: string;
- /** 上次执行指令时间 */
- lastCommandTime: number;
- /** 上次发送指令时间(即sn) */
- autoSetNameTemplate: string;
+ /** CoC 规则相关. */
+ export const coc: {
+ // TODO
}
- /** 消息详情 */
- export interface Message {
- /** 当前平台,如QQ */
- platform: string;
- /** 消息内容 */
- message: string;
- /** 发送时间 */
- time: number;
- /** 群消息/私聊消息 */
- messageType: 'group' | 'private';
- /** 群ID */
- groupId: string;
- /** 发送者信息 */
- sender: Sender;
- /** 原始ID,用于撤回等情况 */
- rawId: string | number;
+ /** 牌堆相关. */
+ export const deck: {
+ // TODO
}
- /** 发送者信息 */
- export interface Sender {
- nickname: string;
- userId: string;
+ /** 插件管理相关. */
+ export const ext: {
+ /** 获得一个新的指令项目. */
+ newCmdItemInfo(): CmdItemInfo;
+
+ /**
+ * 获得一个新的指令执行结果.
+ * @param solved 执行结果 `solved` 字段的值, 推荐始终为 `true`,
+ * 详见 [`CmdItemInfo.solve`]{@link CmdItemInfo.solve}.
+ */
+ newCmdExecuteResult(solved: boolean): CmdExecuteResult;
+
+ /**
+ * 新建一个扩展.
+ * @param name 扩展名称, 注意事项见 [`ExtInfo.name`]{@link ExtInfo.name}.
+ * @param author 作者名称.
+ * @param version 版本号, 注意事项见 [`ExtInfo.version`]{@link ExtInfo.version}.
+ */
+ 'new'(name: string, author: string, version: string): ExtInfo;
+
+ /**
+ * 查找一个扩展.
+ * @param name 扩展名.
+ */
+ find(name: string): ExtInfo | undefined;
+
+ /**
+ * 注册一个扩展. 扩展名不能和已有的冲突.
+ * @param info 要注册的扩展信息.
+ */
+ register(info: ExtInfo): void;
+
+ /**
+ * 注册一个字符串配置项. 如果 `info` 尚未被注册, 该函数会抛出一个异常.
+ * @param info 配置项所属的插件.
+ * @param key 配置项标识符, 在插件内必须唯一.
+ * @param defaultValue 配置项默认值.
+ * @param description 配置项描述.
+ */
+ registerStringConfig(info: ExtInfo, key: string, defaultValue: string, description: string): void;
+
+ /**
+ * 注册一个整数型配置项. 如果 `info` 尚未被注册或 `defaultValue` 不是整数, 该函数会抛出一个异常.
+ * @param info 配置项所属的插件.
+ * @param key 配置项标识符, 在插件内必须唯一.
+ * @param defaultValue 配置项默认值, 内部类型为 `int64`.
+ * @param description 配置项描述.
+ */
+ registerIntConfig(info: ExtInfo, key: string, defaultValue: number, description: string): void;
+
+ /**
+ * 注册一个布尔值配置项. 如果 `info` 尚未被注册, 该函数会抛出一个异常.
+ * @param info 配置项所属的插件.
+ * @param key 配置项标识符, 在插件内必须唯一.
+ * @param defaultValue 配置项默认值.
+ * @param description 配置项描述.
+ */
+ registerBoolConfig(info: ExtInfo, key: string, defaultValue: boolean, description: string): void;
+
+ /**
+ * 注册一个浮点数配置项. 如果 `info` 尚未被注册, 该函数会抛出一个异常.
+ * @param info 配置项所属的插件.
+ * @param key 配置项标识符, 在插件内必须唯一.
+ * @param defaultValue 配置项默认值, 内部类型为 `float64`.
+ * @param description 配置项描述.
+ */
+ registerFloatConfig(info: ExtInfo, key: string, defaultValue: number, description: string): void;
+
+ /**
+ * 注册一个模版配置项. 如果 `info` 尚未被注册, 该函数会抛出一个异常.
+ * @param info 配置项所属的插件.
+ * @param key 配置项标识符, 在插件内必须唯一.
+ * @param defaultValue 配置项默认值.
+ * @param description 配置项描述.
+ */
+ registerTemplateConfig(info: ExtInfo, key: string, defaultValue: string[], description: string): void;
+
+ /**
+ * 注册一个选项卡配置项. 如果 `info` 尚未被注册, 该函数会抛出一个异常.
+ * @param info 配置项所属的插件.
+ * @param key 配置项标识符, 在插件内必须唯一.
+ * @param defaultValue 配置项默认值.
+ * @param options 所有可行的选项.
+ * @param description 配置项描述.
+ */
+ registerOptionConfig(info: ExtInfo, key: string, defaultValue: string, options: string[], description: string): void;
+
+ /**
+ * 新建一个任意类型的配置项, 返回原始配置项对象. 注意事项见 [`ConfigItem`]{@link ConfigItem} 各字段.
+ * 如果 `info` 尚未被注册, 该函数会引发 panic.
+ * @param info 配置项所属的插件.
+ * @param key 配置项标识符, 在插件内必须唯一.
+ * @param defaultValue 配置项默认值.
+ * @param description 配置项描述.
+ */
+ newConfigItem(info: ExtInfo, key: string, defaultValue: any, description: string): ConfigItem;
+
+ /**
+ * 注册不定个任意类型的配置项, 注意事项见 [`ConfigItem`]{@link ConfigItem} 各字段.
+ * 如果 `info` 尚未被注册, 该函数会抛出一个异常.
+ * @param info 配置项所属的插件.
+ * @param config 要注册的配置项.
+ */
+ registerConfig(info: ExtInfo, ...config: ConfigItem[]): void;
+
+ /**
+ * 获取一个已经注册的配置项.
+ * @param info 配置项所属的插件.
+ * @param key 配置项的标识符.
+ */
+ getConfig(info: ExtInfo, key: string): ConfigItem | undefined;
+
+ /**
+ * 获取一个字符串配置项当前的值. 如果配置项名称不存在或类型不匹配则引发 panic.
+ * @param info 配置项所属的插件.
+ * @param key 配置项标识符.
+ */
+ getStringConfig(info: ExtInfo, key: string): string;
+
+ /**
+ * 获取一个整数型配置项当前的值. 如果配置项名称不存在或类型不匹配则引发 panic.
+ * @param info 配置项所属的插件.
+ * @param key 配置项标识符.
+ */
+ getIntConfig(info: ExtInfo, key: string): number;
+
+ /**
+ * 获取一个布尔值配置项当前的值. 如果配置项名称不存在或类型不匹配则引发 panic.
+ * @param info 配置项所属的插件.
+ * @param key 配置项标识符.
+ */
+ getBoolConfig(info: ExtInfo, key: string): boolean;
+
+ /**
+ * 获取一个浮点数配置项当前的值. 如果配置项名称不存在或类型不匹配则引发 panic.
+ * @param info 配置项所属的插件.
+ * @param key 配置项标识符.
+ */
+ getFloatConfig(info: ExtInfo, key: string): number;
+
+ /**
+ * 获取一个模版配置项当前的值. 如果配置项名称不存在或类型不匹配则引发 panic.
+ * @param info 配置项所属的插件.
+ * @param key 配置项标识符.
+ */
+ getTemplateConfig(info: ExtInfo, key: string): string[];
+
+ /**
+ * 获取一个选项卡配置项当前的值. 如果配置项名称不存在或类型不匹配则引发 panic.
+ * @param info 配置项所属的插件.
+ * @param key 配置项标识符.
+ */
+ getOptionConfig(info: ExtInfo, key: string): string;
+
+ /**
+ * 取消注册不定个配置项.
+ * @param info 配置项所属的插件.
+ * @param key 配置项标识符.
+ */
+ unregisterConfig(info: ExtInfo, ...key: string[]): void;
}
- /** 通信端点,即骰子关联的帐号的信息 */
- export interface EndPointInfo {
- id: string;
- /** 昵称 */
- nickname: string;
- /** 状态 0 断开 1已连接 2连接中 3连接失败 */
- state: number;
- /** 用户id */
- userId: string;
- /** 命令执行数量 */
- cmdExecutedNum: number;
- /** 最后命令执行时间 */
- cmdExecutedLastTime: number;
- /** 平台 */
- platform: string;
- /** 是否启用 */
- enable: boolean;
-
- // adapter: PlatformAdapter;
+ /** 与内置脚本语言互动的接口. */
+ export const vars: {
+ /** 变量系统中存在 `key` 且类型正确, 返回 `[number, true]`, 否则返回 `[0, false]`. */
+ intGet(ctx: MsgContext, key: string): [number, boolean];
+ /** 赋值 `key` 为 `value`, 等价于指令 `.text {key=value}`. `value` 类型为数字. */
+ intSet(ctx: MsgContext, key: string, value: number): void;
+ /** 变量系统中存在 `key` 且类型正确 返回 `[string, true]`, 否则返回 `['', false]`. */
+ strGet(ctx: MsgContext, key: string): [string, boolean];
+ /** 赋值 `key` 为 `value`, 等价于指令 `.text {key=value}`. `value` 类型为字符串. */
+ strSet(ctx: MsgContext, key: string, value: string): void;
}
+ /** 代表一个 @ 的信息. */
export interface AtInfo {
- userId: string;
+ /** 被 @ 的用户 ID. */
+ userId: string
+
+ /**
+ * 深拷贝一个上下文信息, 并将 `player.userId` 字段设置为自己. 如果 `ctx` 是有效的,
+ * 返回新的上下文和 `true`, 否则返回 `undefined` 和 `false`.
+ * @param ctx 要拷贝的上下文.
+ */
+ copyCtx(ctx: MsgContext): [MsgContext | undefined, boolean];
}
- export interface Kwarg {
- /** 名称 */
- name: string;
- /** 是否存在value */
- valueExists: boolean;
- /** value的值 */
- value: string;
- /** 将value转换为bool,如'0' ''等会自动转为false */
- asBool: boolean;
+ /** 代表黑名单中的一个项目. */
+ export interface BanListInfoItem {
+ /** 项目 ID. */
+ id: string;
+
+ /** 用户或群组名, 在最后一次读写时更新. */
+ name: string;
+
+ /** 怒气值, 不同怒气值的具体行为由骰主设置. 内部类型为 `int64`. */
+ score: number;
+
+ /** 黑名单等级, 0 无特殊行为, -10 为警告, -30 为禁止, 30 为信任. 内部类型为 `BanRankType`. */
+ rank: number;
+
+ /** 历来被记录的时间戳. 内部类型为 `[]int64`.*/
+ times: number[];
+
+ /** 历来被记录的原因.*/
+ reasons: string[];
+
+ /** 历来被记录的地点.*/
+ places: string[];
+
+ /** 第一次上黑名单时间. 内部类型为 `int64`.*/
+ banTime: number;
}
+ /** 代表一次指令的用户参数. */
export interface CmdArgs {
- /** 当前命令,与指令的name相对,例如.ra时,command为ra */
- command: string;
- /** 指令参数,如“.ra 力量 测试”时,参数1为“力量”,参数2为“测试” */
- args: string[];
- /** 当前被at的有哪些 */
- at: AtInfo[];
- /** 参数的原始文本 */
- rawArgs: string;
- /** 我被at了 */
- amIBeMentioned: boolean;
- /** 同上,但要求是第一个被at的 */
- amIBeMentionedFirst: boolean;
- /** 一种格式化后的参数,也就是中间所有分隔符都用一个空格替代 */
- cleanArgs: string;
- // 暂不提供,未来可能有变化
- // specialExecuteTimes: number;
- // 但是额外指出, `ra10#50` 时此项 = 10,并且 argv[0] 会被处理为 50;请注意这一点
-
- /** 获取关键字参数,如“.ra 50 --key=20 --asm”时,有两个kwarg,一个叫key,一个叫asm */
- getKwarg(key: string): Kwarg;
- /** 获取第N个参数,从1开始,如“.ra 力量50 推门” 参数1为“力量50”,参数2是“推门” */
- getArgN(n: number): string;
- /** 分离前缀 如 `.stdel力量` => [del,力量] ,直接修改 argv 属性*/
- chopPrefixToArgsWith(...s: string[]): boolean
- /** 吃掉前缀并去除复数空格 `set xxx xxx` => `xxx xxx`,返回修改后的字符串和是否修改成功的布尔值 */
- eatPrefixWith(...s: string[]): [string, boolean]
- /** 将第 n 个参数及之后参数用空格拼接起来; 如指令 `send to qq x1 x2`,n=3返回 `x1 x2` */
- getRestArgsFrom(n: number): number
- /** 检查第N项参数是否为某个字符串,n从1开始,若没有第n项参数也视为失败 */
- isArgEqual(n: number, ...s: string[]): boolean
- }
+ /** 指令名称. */
+ command: string;
+ /**
+ * 指令参数. 诸如 `3#`(如果指令允许
+ * [`enableExecuteTimesParse`]{@link CmdItemInfo.enableExecuteTimesParse})和
+ * `--key=value` 这样的特殊参数不会包含在内.*/
+ args: string[];
- interface CmdItemInfo {
- solve: (ctx: MsgContext, msg: Message, cmdArgs: CmdArgs) => CmdExecuteResult;
-
- /** 指令名称 */
- name: string;
- /** 长帮助,带换行的较详细说明 */
- help: string;
- /** 允许代骰 */
- allowDelegate: boolean;
- /** 私聊不可用 */
- disabledInPrivate: boolean;
-
- /** 高级模式。默认模式下行为是:需要在当前群/私聊开启,或@自己时生效(需要为第一个@目标)。一般不建议使用 */
- // raw: boolean;
- /** 是否检查当前可用状况,包括群内可用和是私聊两种方式,如失败不进入solve */
- // checkCurrentBotOn: boolean;
- /** 是否检查@了别的骰子,如失败不进入solve */
- // checkMentionOthers: boolean;
- }
+ /** 键值对参数, 如 `--key=3`. */
+ kwargs: Kwarg[];
+
+ /** 所有 @ 的信息. */
+ at: AtInfo[];
+
+ /** 原始的参数, 不包含指令名称. */
+ rawArgs: string;
+
+ /** 骰子自己是否被 @. */
+ amIBeMentioned: boolean;
+
+ /** 骰子自己是否首先被 @. */
+ amIBeMentionedFirst: boolean;
+
+ /** 清洁过的参数字符串, 所有参数用一个空格隔开, 同样不包括特殊参数. */
+ cleanArgs: string;
+
+ /** 诸如 `3#`(如果指令允许
+ * [`enableExecuteTimesParse`]{@link CmdItemInfo.enableExecuteTimesParse})的参数.
+ */
+ specialExecuteTimes: number;
+
+ /** 原始信息, 等同于 `Message.message`. */
+ rawText: string;
+
+ /** 获取第 `n` 个参数, `n` 从 1 开始. 如果参数总量小于 `n` 则返回空字符串. */
+ getArgN(n: number): string;
+
+ /** 获取键为 `key` 的键值对参数. */
+ getKwarg(key: string): Kwarg | undefined;
+
+ /**
+ * 从指令名中分离出前缀, 如 `.stpow` 中的 `pow` 会被分离. 此方法会永久修改 `CmdArgs`
+ * 的状态. 返回是否有前缀被分离.
+ * @param s 要分离的前缀.
+ */
+ chopPrefixToArgsWith(...s: string[]): boolean;
+
+ /**
+ * 在 [`cleanArgs`]{@link cleanArgs} 中尝试删去所给前缀, 有匹配到的前缀即删去并立刻返回
+ * `true`, 否则返回 `["", false]`.
+ * @param s 要删除的前缀.
+ */
+ eatPrefixWith(...s: string[]): [string, boolean];
+
+ /**
+ * 检查第 `n` 个参数是否为 `s` 中的任何一个, `n` 从 1 开始. 如果有则返回 `true`.
+ */
+ isArgEqual(n: number, ...s: string[]): boolean;
- interface ExtInfo {
- /** 名字 */
- name: string;
- /** 版本 */
- version: string;
- /** 名字 */
- author: string;
- /** 指令映射 */
- cmdMap: { [key: string]: CmdItemInfo };
- /** 是否加载完成 */
- isLoaded: boolean
- /** 存放数据 */
- storageSet(key: string, value: string);
- /** 取数据 */
- storageGet(key: string): string;
- /** 匹配非指令消息 */
- onNotCommandReceived: (ctx: MsgContext, msg: Message) => void
- /** 试图匹配自定义指令(只对内置扩展有意义) */ // 已废弃
- // onCommandOverride: (ctx: MsgContext, msg: Message, cmdArgs: CmdArgs) => boolean;
- /** 监听 收到指令 事件 */
- onCommandReceived: (ctx: MsgContext, msg: Message, cmdArgs: CmdArgs) => void
- /** 监听 收到消息 事件,如 log 模块记录收到文本 */
- onMessageReceived: (ctx: MsgContext, msg: Message) => void
- /** 监听 发送消息 事件,如 log 模块记录指令文本 */
- onMessageSend: (ctx: MsgContext, msg: Message) => void
- /** 获取扩展介绍文本 */
- getDescText(): string
- /** 监听 加载时 事件,如 deck 模块需要读取牌堆文件 */
- onLoad: (...any: any) => void
- /** 初始化数据,读写数据时会自动调用 */
- storageInit()
- /** 读数据 如果无需自定义错误处理就无需使用 */
- storageGetRaw(k: string)
- /** 写数据 如果无需自定义错误处理就无需使用 */
- storageSetRaw(k: string, v: string)
+ /** 获取 [`cleanArgs`]{@link cleanArgs} 中从 `n` 开始的所有参数, 包括第 `n` 个. */
+ getRestArgsFrom(n: number): string;
+
+ // 省略了一些不应在 JS 插件中使用的方法.
}
+ /** 代表指令执行结果. */
+ export interface CmdExecuteResult {
+ /** 是否是指令. 用 `seal.ext.newCmdExecuteResult` 取得时始终为 `true`. */
+ matched: boolean;
+
+ /** 是否响应此指令. */
+ solved: boolean;
- interface CmdExecuteResult {
- /** 是否顺利完成执行 */
- solved: boolean;
- /** 是否返回帮助信息 */
- showHelp: boolean;
+ /** 是否显示帮助信息(使用 `CmdItemInfo.help` 而非 `helpFunc`). */
+ showHelp: boolean;
}
- export const ext: {
- /**
- * 新建一个扩展
- */
- new: (name: string, author: string, version: string) => ExtInfo;
-
- /**
- * 创建指令结果对象
- * @param success 是否执行成功
- */
- newCmdExecuteResult(success: boolean): CmdExecuteResult;
-
- /**
- * 注册一个扩展
- * @param ext
- */
- register(ext: ExtInfo): unknown;
-
- /**
- * 按名字查找扩展对象
- * @param name
- */
- find(name: string): ExtInfo;
- /** 创建指令对象 */
- newCmdItemInfo(): CmdItemInfo;
+ /** 代表插件中定义的一个指令. */
+ export interface CmdItemInfo {
+ /**
+ * 指令名称. 这并不一定是触发指令的名称(后者是在对应插件的 `cmdMap`中注册的),
+ * 例如骰点指令的 `name` 可以是 `roll`, 而在 `cmdMap` 中注册为 `r`.
+ *
+ * 与其他指令名称冲突会导致该指令所属的插件解析失败.
+ */
+ name: string;
+
+ /** 指令帮助. */
+ help: string;
+
+ /** 帮助文档生成函数. 如果该项被定义, `help` 指令会优先调用它来生成帮助信息, 否则使用 `help` 的内容. */
+ helpFunc: (isShort: boolean) => string;
+
+ /**
+ * 指令的核心逻辑函数. 指令触发者和群组上下文信息在 `ctx` 和 `msg` 中取得. **不要直接修改 `ctx` 和 `msg`
+ * 中的内容**, 如确有需要可以深拷贝一份使用. 这两个对象是按引用传递的, 修改它们可能会导致后续写入错误的数据.
+ *
+ * 通常建议直接返回 `seal.ext.newCmdExecuteResult(true)`, 尽量不要将执行结果的 `solved` 字段设置为
+ * `false`, 否则骰子会在控制台中打印令人困惑的"骰子关闭/忽略指令/未知指令"内容.
+ */
+ solve: (ctx: MsgContext, msg: Message, cmdArgs: CmdArgs) => CmdExecuteResult;
+
+ /**
+ * 是否允许代骰. 如果为 `false`,在使用指令时 @ 骰子以外的用户(无论此用户是否被标记为骰子),
+ * 骰子会优先认为该指令不由自己负责. 将此项设为 `true` 来改变这一行为.
+ *
+ * 允许代骰后, 可以使用 `cmdArgs.at`, `seal.getCtxProxyFirst` 等. 普通模式下可在
+ * `solve` 中将 [`ctx.delegateText`]{@link MsgContext.delegateText} 设置为空字符串来关闭代骰文本.
+ */
+ allowDelegate: boolean;
+
+ /**
+ * 是否在私聊中禁用此命令. 设置为 `true` 后, 若用户尝试在私聊中使用该指令, 骰子会回复骰主自定义的
+ * `核心:提示_私聊不可用` 内容.
+ */
+ disabledInPrivate: boolean;
+
+ /** 是否解析骰点次数, 如 `.r 3#` 中的 `3#`. 如果不启用, 这样的文本会被当作普通参数处理. */
+ enableExecuteTimesParse: boolean;
+
+ /**
+ * 是否开启高级模式. 在高级模式下:
+ * 1. 不检查 `disabledInPrivate`.
+ * 2. 不检查 `allowDelegate`, 代骰时不发送 `ctx.DelegateText`.
+ * 3. 启用 `checkCurrentBotOn` 和 `checkMentionOthers`.
+ */
+ raw: boolean;
+
+ /**
+ * 是否要求骰子被启用, **仅在高级模式下有效**. 如果设置为 `true`,
+ * 当骰子在当前群组中关闭时, 即使被 @ 也不会处理该指令.
+ */
+ checkCurrentBotOn: boolean;
+
+ /**
+ * 是否要求提及他人, **仅在高级模式下有效**. 如果设置为 `true`,
+ * 如 @ 了除骰子以外的其他用户, 骰子不会响应指令.
+ */
+ checkMentionOthers: boolean;
}
- interface CocRuleInfo {
- /** 序号 */
- index: number;
- /** .setcoc key */
- key: string;
- /** 已切换至规则 Name: Desc */
- name: string;
- /** 规则描述 */
- desc: string;
-
- /**
- * 检定函数
- * @param ctx 上下文对象
- * @param d100 使用骰子骰出的值
- * @param checkValue 检定线,对应属性,例如力量、敏捷等
- */
- check(ctx: MsgContext, d100: number, checkValue: number): CocRuleCheckRet;
+ /** 代表一个允许用户自定义的插件配置项. */
+ export interface ConfigItem {
+ /** 配置项标识符. */
+ key: string;
+
+ /** 配置项类型. */
+ type: "string" | "int" | "bool" | "float" | "template" | "option";
+
+ /** 当前启用的值, 可被骰主更改. */
+ value: any;
+
+ /** 默认值. */
+ defaultValue: any;
+
+ /** 所有可用选项, 仅在类型为"option"时可用. */
+ option: any[];
+
+ /**
+ * 该配置项是否已经过时. 不要在插件端手动修改它; 当插件注册的配置项更改时,
+ * 旧的配置项会自动被标记为过时.
+ */
+ deprecated: boolean;
+
+ /** 对该配置项的描述. */
+ description: string;
}
- interface CocRuleCheckRet {
- /** 成功级别,失败小于0,成功大于0。大失败-2 失败-1 成功1 困难成功2 极难成功3 大成功4 */
- successRank: number;
- /** 大成功数值 */
- criticalSuccessValue: number;
+ /** 一个终结点信息. */
+ export interface EndPointInfo {
+ /** 终结点内部 ID, 不是账号 ID. */
+ id: string;
+
+ /** 最后一次登录时获取的账号名. */
+ nickname: string;
+
+ /** 终结点状态. 0 断开, 1 已连接, 2 连接中, 3 连接失败. */
+ state: number;
+
+ /** 账号 ID. */
+ userId: string;
+
+ /** 账号加入的群组统计, 不保证准确. 内部类型为 `int64`. */
+ groupNum: number;
+
+ /** 指令执行统计. 内部类型为 `int64`. */
+ cmdExecutedNum: number;
+
+ /** 最后指令执行时间. 内部类型为 `int64`. */
+ cmdExecutedLastTime: number;
+
+ /**
+ * 累计在线时间.
+ * @deprecated 源码中尚未实现.
+ */
+ onlineTotalTime: number;
+
+ /** 工作平台. */
+ platform: string;
+
+ /** 是否启用. */
+ enable: boolean;
}
- export const coc: {
- newRule(): CocRuleInfo;
- newRuleCheckResult(): CocRuleCheckRet;
- registerRule(rule: CocRuleInfo): boolean;
+ /** 代表一个插件的信息. */
+ export interface ExtInfo {
+ /** 插件名称, 不能与内置插件名(log, fun, story 等)相同. */
+ name: string;
+
+ /** 插件别名, 不能与内置插件名(log, fun, story 等)相同. */
+ aliases: string[];
+
+ /**
+ * 插件版本. 推荐使用 Semantic Versioning, 即 `大版本.小版本.补丁`.
+ * 如果插件目录下存在多个名称相同但版本不同的插件, 它们可能会全部被读取, 从而造成冲突.
+ */
+ version: string;
+
+ /**
+ * 是否在骰子加入新群时自动开启该插件. 从 `seal.ext.new` 取得时为 `true`.
+ * 可被骰主在插件管理中更改.
+ */
+ autoActive: boolean;
+
+ /**
+ * 该插件的指令集合. 指令只有在这里注册的名字才会被用户触发, 而自身的 `name` 与此无关.
+ * 指令可以将多个名字关联到自身.
+ */
+ cmdMap: {[_: string]: CmdItemInfo};
+
+ /** 插件作者. */
+ author: string;
+
+ /** 插件是否已经被加载. */
+ isLoaded: boolean;
+
+ /** 收到非指令时的回调函数. */
+ onNotCommandReceived: (ctx: MsgContext, msg: Message) => void;
+
+ /** 收到指令(包括本插件的指令和其他插件的指令)时的回调函数. 在正常执行完指令后被调用. */
+ onCommandReceived: (ctx: MsgContext, msg: Message, cmdArgs: CmdArgs) => void;
+
+ /** 收到任何信息时的回调函数. 如果信息是指令, 则在处理完后被调用. */
+ onMessageReceived: (ctx: MsgContext, msg: Message) => void;
+
+ /**
+ * 消息被删除时的回调函数. 被调用时 `ctx` 中的任何字段都不保证有效,
+ * `msg` 中仅保证 `time`, `groupId` 或 `channelId` 有效.
+ */
+ onMessageDeleted: (ctx: MsgContext, msg: Message) => void;
+
+ /**
+ * 消息被修改时的回调函数. 仅在部分平台有效. 被调用时 `ctx` 中的任何字段都不保证有效,
+ * `msg` 中仅保证 `time`, `message`, `groupId` 或 `channelId` 有效.
+ */
+ onMessageEdit: (ctx: MsgContext, msg: Message) => void;
+
+ /** 骰子加入新群组时的回调函数. 在发送完入群致辞后被调用. 仅保证 `msg` 中的 `groupId` 或 `channelId` 有效. */
+ onGroupJoined: (ctx: MsgContext, msg: Message) => void;
+
+ // 在源码中从未读取过这个字段
+ // /** 他人加入新群组时的回调函数. 在发送完欢迎词后被调用. */
+ // onGroupMemberJoined: (ctx: MsgContext, msg: Message) => void;
+
+ /** 一些平台上, 骰子加入新服务器时的回调函数. 在发送完入群致辞后被调用. 仅保证 `msg` 中的 `guildId` 有效. */
+ onGuildJoined: (ctx: MsgContext, msg: Message) => void;
+
+ /** 用户添加骰子为好友后的回调函数. 在发送完致辞后被调用. 仅保证 `msg` 中的 `sender.userId` 有效. */
+ onBecomeFriend: (ctx: MsgContext, msg: Message) => void;
+
+ /** 插件加载完成后的回调函数. */
+ onLoad: () => void;
+
+ /** 系统内部用来获取插件信息的函数, 在执行 `.help <插件名>` 时可能被调用. */
+ getDescText: (info: ExtInfo) => string;
+
+ /**
+ * 从插件独有的数据库中获取名为 `key` 的数据表.
+ * @example
+ * const data = JSON.parse(extension.storageGet("player_levels") || "{}");
+ */
+ storageGet(key: string): string;
+
+ /**
+ * 向插件独有的数据库中存储名为 `key` 的数据表.
+ * @example
+ * const data = { name: "Alice", age: 32 };
+ * extension.storageSet("player_profile", JSON.stringify(data));
+ */
+ storageSet(key: string, value: string): void;
+
+ // 省略了不应在 JS 插件中使用的方法.
}
- /** 回复发送者(发送者私聊即私聊回复,群内即群内回复) */
- export function replyToSender(ctx: MsgContext, msg: Message, text: string): void;
- /** 回复发送者(私聊回复,典型应用场景如暗骰) */
- export function replyPerson(ctx: MsgContext, msg: Message, text: string): void;
- /** 回复发送者(群内回复,私聊时无效) */
- export function replyGroup(ctx: MsgContext, msg: Message, text: string): void;
- /** 格式化文本 等价于 `text` 指令 */
- export function format(ctx: MsgContext, text: string): string;
- /** 获取回复文案 */
- export function formatTmpl(ctx: MsgContext, text: string): string
- /** 代骰模式下,获取被代理人信息 */
- export function getCtxProxyFirst(ctx: MsgContext, cmdArgs: CmdArgs): MsgContext;
- /** 新建一条消息 */
- export function newMessage(): Message;
- /** 创建一个临时Context */
- export function createTempCtx(ep: EndPointInfo, msg: Message): MsgContext;
- /** 应用名片模板,返回值为格式化完成的名字。此时已经设置好名片(如有权限) */
- export function applyPlayerGroupCardByTemplate(ctx: MsgContext, tmpl: string): string;
+ /** 群组信息. */
+ export interface GroupInfo {
+ /** 骰子在该群组内是否开启. */
+ active: boolean;
- /** 获取/修改 VM 变量 ,如 `$t`、`$g` */
- export const vars: {
- /** VM 中存在 key 且类型正确 返回 `[number,true]` ,否则返回 `[0,false]` */
- intGet(ctx: MsgContext, key: string): [number, boolean];
- /** 赋值 key 为 value 等价于指令 `text {key=value}` value 类型为数字 */
- intSet(ctx: MsgContext, key: string, value: number): void;
- /** VM 中存在 key 且类型正确 返回 `[string,true]` ,否则返回 `['',false]` */
- strGet(ctx: MsgContext, key: string): [string, boolean];
- /** 赋值 key 为 value 等价于指令 `text {key=value}` value 类型为字符串 */
- strSet(ctx: MsgContext, key: string, value: string): void;
+ /** 群组 ID. */
+ groupId: string;
+
+ /** 某些平台上的服务器 ID. */
+ guildId: string;
+
+ /** 某些平台上的频道 ID. */
+ channelId: string;
+
+ /** 群组名称. */
+ groupName: string;
+
+ /** COC 规则序号, 见 `setcoc` 指令. */
+ cocRuleIndex: number;
+
+ /** 如果当前有 log, 当前 log 的名字. */
+ logCurName: string;
+
+ /** 当前群组内是否开启 log. */
+ logOn: boolean;
+
+ /** 骰子最后发送消息的事件. */
+ recentDiceSendTime: number;
+
+ /** 是否在该群组发送欢迎消息. */
+ showGroupWelcome: boolean;
+
+ /** 欢迎消息文本. */
+ groupWelcomeMessage: string;
+
+ /** 骰子进群时间. */
+ enteredTime: number;
+
+ /** 邀请骰子进群的用户 ID. */
+ inviteUserId: number;
+
+ // 省略了一些不应在 JS 环境内使用的方法.
}
- export const gameSystem: {
- /** 添加一个规则模板,需要是JSON文本格式 */
- newTemplate(data: string);
- /** 添加一个规则模板,需要是YAML文本格式 */
- newTemplateByYaml(data: string);
+ /** 群组中用户信息. */
+ export interface GroupPlayerInfo {
+ /** 用户昵称, 该字段是缓存的, 可能不准确. */
+ name: string;
+
+ /** 用户 ID. */
+ userId: number;
+
+ /** 最后发送指令的时间. 内部类型为 `int64`. */
+ lastCommandTime: number;
+
+ /** 名片模版. */
+ autoSetNameTemplate: string;
}
+ /** 键值对参数类型. */
+ export interface Kwarg {
+ /** 键名. */
+ name: string;
+
+ /** 该参数是否有值. */
+ valueExists: boolean;
- /** deck */
- export interface deckResult {
- /** 是否存在 */
- "exists": boolean,
- /** 错误信息 */
- "err": string,
- /** 抽牌结果 */
- "result": string | null
+ /** 如果有值, 该参数的值. */
+ value: string;
+
+ /** 将该参数转换为布尔值. */
+ asBool: boolean;
+
+ /** 将该参数转换为 `--ok` 或者 `--key=value` 格式.*/
+ string(): string;
}
- export const deck: {
- /**
- * 抽牌函数
- * @param ctx
- * @param name 牌堆名
- * @param isShuffle 是否放回
- */
- draw(ctx: MsgContext, name: string, isShuffle: boolean): deckResult
+ /** 信息源. 在不同的上下文中, 并不是所有字段都有效. */
+ export interface Message {
+ /** 信息发送的时间戳. 内部类型为 `int64`. */
+ time: number;
+
+ /** 是私聊还是群聊. */
+ messageType: "private" | "group";
+
+ /** 消息所在的群组 ID. */
+ groupId: string;
+
+ /** 类似 Discord 的平台中, 一个频道(类似一个群)的 ID. */
+ channelId: string;
+
+ /** 类似 Discord 的平台中, 一个服务器的 ID. */
+ guildId: string;
+
+ /** 消息发送人信息. */
+ sender: { nickname: string, userId: string };
+
+ /** 原始消息内容. */
+ message: string;
+
+ /** 原始消息 ID, 具体格式视具体平台和 SDK 而定. */
+ rawId: any;
+
+ /** 消息平台代号. */
+ platform: string;
+
+ /** 群组名, 在一些上下文中没有有效值. */
+ groupName: string;
+
+ // /** 消息段. */
+ // segment: IMessageElement[];
}
-}
+ /** 信息上下文. 在不同的上下文中, 并不是所有字段都有效. */
+ export interface MsgContext {
+ /** 群组信息. 指令的解析函数中, `ctx` 一般是缓存的. 其他一些事件中这个字段可能无效. */
+ group: GroupInfo;
+
+ /** 主要用户信息. 通常是发送指令或消息的用户. */
+ player: GroupPlayerInfo;
+
+ /** 终结点信息, 可以简单地理解为一个骰子账号. */
+ endPoint: EndPointInfo;
+
+ /** 当前群组骰子是否开启. */
+ isCurGroupBotOn: boolean;
+
+ /** 当前是否是私聊. */
+ isPrivate: boolean;
+
+ /** `player` 的权限等级. -30 黑名单, 0 一般用户, 40 邀请者, 50 管理, 60 群主, 70 信任, 100 骰主*/
+ privilegeLevel: number;
+
+ /** 代骰文本, 代骰时可修改. */
+ delegateText: string;
+
+ /** 对骰主通知列表中的每个 ID, 如果与当前终结点平台相同则发送通知信息, 否则跳过. */
+ notice(text: string): void;
+
+ /**
+ * 对骰主通知列表中的每个 ID, 如果与当前终结点平台相同则发送通知信息, 否则搜索所有可用终结点,
+ * 用平台相同的终结点发送通知.
+ */
+ noticeCrossPlatform(text: string): void;
+
+ // 省略了许多不适合在 JS 环境使用的方法.
+ }
+}
\ No newline at end of file