diff --git a/packages/napcat-onebot/api/group.ts b/packages/napcat-onebot/api/group.ts index f6c55788..a959cc61 100644 --- a/packages/napcat-onebot/api/group.ts +++ b/packages/napcat-onebot/api/group.ts @@ -19,6 +19,7 @@ import { OB11GroupCardEvent } from '@/napcat-onebot/event/notice/OB11GroupCardEv import { OB11GroupPokeEvent } from '@/napcat-onebot/event/notice/OB11PokeEvent'; import { OB11GroupEssenceEvent } from '@/napcat-onebot/event/notice/OB11GroupEssenceEvent'; import { OB11GroupTitleEvent } from '@/napcat-onebot/event/notice/OB11GroupTitleEvent'; +import { OB11GroupGrayTipEvent } from '@/napcat-onebot/event/notice/OB11GroupGrayTipEvent'; import { OB11GroupUploadNoticeEvent } from '../event/notice/OB11GroupUploadNoticeEvent'; import { OB11GroupNameEvent } from '../event/notice/OB11GroupNameEvent'; import { FileNapCatOneBotUUID } from 'napcat-common/src/file-uuid'; @@ -206,15 +207,24 @@ export class OneBotGroupApi { } return undefined; } - - async parseOtherJsonEvent (msg: RawMessage, jsonStr: string, context: InstanceContext) { - const json = JSON.parse(jsonStr); - const type = json.items[json.items.length - 1]?.txt; + async parseOtherJsonEvent (msg: RawMessage, jsonGrayTipElement: GrayTipElement['jsonGrayTipElement'], context: InstanceContext) { + let json: { items?: { txt?: string; param?: string[] }[] }; + try { + json = JSON.parse(jsonGrayTipElement.jsonStr); + } catch (e) { + context.logger.logWarn('灰条消息JSON解析失败', jsonGrayTipElement.jsonStr, e); + return undefined; + } + const type = json.items?.[json.items.length - 1]?.txt; await this.core.apis.GroupApi.refreshGroupMemberCachePartial(msg.peerUid, msg.senderUid); if (type === '头衔') { - const memberUin = json.items[1].param[0]; - const title = json.items[3].txt; + const memberUin = json.items?.[1]?.param?.[0]; + const title = json.items?.[3]?.txt; context.logger.logDebug('收到群成员新头衔消息', json); + if (memberUin == null || title == null) { + context.logger.logWarn('收到格式异常的群成员新头衔灰条消息', json); + return undefined; + } return new OB11GroupTitleEvent( this.core, +msg.peerUid, @@ -225,6 +235,27 @@ export class OneBotGroupApi { context.logger.logDebug('收到机器人被踢消息', json); } else { context.logger.logWarn('收到未知的灰条消息', json); + + // 如果有真实发送者(非0),生成事件上报,可用于检测和撤回伪造灰条 + const senderUin = Number(msg.senderUin) || 0; + if (senderUin !== 0) { + const peer = { chatType: ChatType.KCHATTYPEGROUP, guildId: '', peerUid: msg.peerUid }; + const messageId = MessageUnique.createUniqueMsgId(peer, msg.msgId); + return new OB11GroupGrayTipEvent( + this.core, + +msg.peerUin, + senderUin, + messageId, + jsonGrayTipElement.busiId, + jsonGrayTipElement.jsonStr, + { + msgSeq: msg.msgSeq, + msgTime: msg.msgTime, + msgId: msg.msgId, + json, + } + ); + } } return undefined; } @@ -376,7 +407,7 @@ export class OneBotGroupApi { return await this.parse51TypeEvent(msg, grayTipElement); } else { console.log('Unknown JSON event:', grayTipElement.jsonGrayTipElement, JSON.stringify(grayTipElement)); - return await this.parseOtherJsonEvent(msg, grayTipElement.jsonGrayTipElement.jsonStr, this.core.context); + return await this.parseOtherJsonEvent(msg, grayTipElement.jsonGrayTipElement, this.core.context); } } return undefined; diff --git a/packages/napcat-onebot/event/notice/OB11GroupGrayTipEvent.ts b/packages/napcat-onebot/event/notice/OB11GroupGrayTipEvent.ts new file mode 100644 index 00000000..e6062a71 --- /dev/null +++ b/packages/napcat-onebot/event/notice/OB11GroupGrayTipEvent.ts @@ -0,0 +1,35 @@ +import { OB11BaseNoticeEvent } from './OB11BaseNoticeEvent'; +import { NapCatCore } from 'napcat-core'; + +/** + * 群灰条消息事件 + * 用于上报未知类型的灰条消息,便于下游检测和处理伪造灰条攻击 + */ +export class OB11GroupGrayTipEvent extends OB11BaseNoticeEvent { + notice_type = 'notify'; + sub_type = 'gray_tip'; + group_id: number; + user_id: number; // 真实发送者QQ(如果是伪造的灰条,这就是攻击者) + message_id: number; // 消息ID,可用于撤回 + busi_id: string; // 业务ID + content: string; // 灰条内容(JSON字符串) + raw_info: unknown; // 原始信息 + + constructor ( + core: NapCatCore, + groupId: number, + userId: number, + messageId: number, + busiId: string, + content: string, + rawInfo: unknown + ) { + super(core); + this.group_id = groupId; + this.user_id = userId; + this.message_id = messageId; + this.busi_id = busiId; + this.content = content; + this.raw_info = rawInfo; + } +}