diff --git a/src/main/main.ts b/src/main/main.ts index a1b1032..c103f37 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -198,6 +198,13 @@ function onLoad() { postOb11Event(privateEvent) } }) + // OB11Constructor.FriendAddEvent(message).then((friendAddEvent) => { + // log(message) + // if (friendAddEvent) { + // // log("post friend add event", friendAddEvent); + // postOb11Event(friendAddEvent) + // } + // }) } } @@ -216,7 +223,7 @@ function onLoad() { pokeEvent = new OB11GroupPokeEvent(parseInt(id)) } else { - pokeEvent = new OB11FriendPokeEvent(parseInt(id)) + pokeEvent = new OB11FriendPokeEvent(parseInt(selfInfo.uin), parseInt(id)) } postOb11Event(pokeEvent) }) @@ -311,34 +318,36 @@ function onLoad() { // if (notify.user2.uid) { // member2 = await getGroupMember(notify.group.groupCode, null, notify.user2.uid); // } - if ( - [GroupNotifyTypes.ADMIN_SET, GroupNotifyTypes.ADMIN_UNSET, GroupNotifyTypes.ADMIN_UNSET_OTHER].includes( - notify.type, - ) - ) { - const member1 = await getGroupMember(notify.group.groupCode, notify.user1.uid) - log('有管理员变动通知') - refreshGroupMembers(notify.group.groupCode).then() - let groupAdminNoticeEvent = new OB11GroupAdminNoticeEvent() - groupAdminNoticeEvent.group_id = parseInt(notify.group.groupCode) - log('开始获取变动的管理员') - if (member1) { - log('变动管理员获取成功') - groupAdminNoticeEvent.user_id = parseInt(member1.uin) - groupAdminNoticeEvent.sub_type = [ - GroupNotifyTypes.ADMIN_UNSET, - GroupNotifyTypes.ADMIN_UNSET_OTHER, - ].includes(notify.type) - ? 'unset' - : 'set' - // member1.role = notify.type == GroupNotifyTypes.ADMIN_SET ? GroupMemberRole.admin : GroupMemberRole.normal; - postOb11Event(groupAdminNoticeEvent, true) - } - else { - log('获取群通知的成员信息失败', notify, getGroup(notify.group.groupCode)) - } - } - else if (notify.type == GroupNotifyTypes.MEMBER_EXIT || notify.type == GroupNotifyTypes.KICK_MEMBER) { + // 原本的群管变更通知事件处理 + // if ( + // [GroupNotifyTypes.ADMIN_SET, GroupNotifyTypes.ADMIN_UNSET, GroupNotifyTypes.ADMIN_UNSET_OTHER].includes( + // notify.type, + // ) + // ) { + // const member1 = await getGroupMember(notify.group.groupCode, notify.user1.uid) + // log('有管理员变动通知') + // refreshGroupMembers(notify.group.groupCode).then() + // let groupAdminNoticeEvent = new OB11GroupAdminNoticeEvent() + // groupAdminNoticeEvent.group_id = parseInt(notify.group.groupCode) + // log('开始获取变动的管理员') + // if (member1) { + // log('变动管理员获取成功') + // groupAdminNoticeEvent.user_id = parseInt(member1.uin) + // groupAdminNoticeEvent.sub_type = [ + // GroupNotifyTypes.ADMIN_UNSET, + // GroupNotifyTypes.ADMIN_UNSET_OTHER, + // ].includes(notify.type) + // ? 'unset' + // : 'set' + // // member1.role = notify.type == GroupNotifyTypes.ADMIN_SET ? GroupMemberRole.admin : GroupMemberRole.normal; + // postOb11Event(groupAdminNoticeEvent, true) + // } + // else { + // log('获取群通知的成员信息失败', notify, getGroup(notify.group.groupCode)) + // } + // } + // else + if (notify.type == GroupNotifyTypes.MEMBER_EXIT || notify.type == GroupNotifyTypes.KICK_MEMBER) { log('有成员退出通知', notify) try { const member1 = await NTQQUserApi.getUserDetailInfo(notify.user1.uid) diff --git a/src/ntqqapi/api/group.ts b/src/ntqqapi/api/group.ts index 06d00c5..6617dcc 100644 --- a/src/ntqqapi/api/group.ts +++ b/src/ntqqapi/api/group.ts @@ -5,6 +5,7 @@ import { deleteGroup, uidMaps } from '../../common/data' import { dbUtil } from '../../common/db' import { log } from '../../common/utils/log' import { NTQQWindowApi, NTQQWindows } from './window' +import { wrapperApi } from '../native/wrapper' export class NTQQGroupApi { @@ -282,4 +283,28 @@ export class NTQQGroupApi { }) } static publishGroupBulletin(groupQQ: string, title: string, content: string) {} + static async removeGroupEssence(GroupCode: string, msgId: string) { + // 代码没测过 + // 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom + let MsgData = await wrapperApi.NodeIQQNTWrapperSession.getMsgService().getMsgsIncludeSelf({ chatType: 2, guildId: '', peerUid: GroupCode }, msgId, 1, false); + let param = { + groupCode: GroupCode, + msgRandom: parseInt(MsgData.msgList[0].msgRandom), + msgSeq: parseInt(MsgData.msgList[0].msgSeq) + }; + // GetMsgByShoretID(ShoretID); -> MsgService.getMsgs(Peer,MsgId,1,false); -> 组出参数 + return wrapperApi.NodeIQQNTWrapperSession.getGroupService().removeGroupEssence(param); + } + static async addGroupEssence(GroupCode: string, msgId: string) { + // 代码没测过 + // 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom + let MsgData = await wrapperApi.NodeIQQNTWrapperSession.getMsgService().getMsgsIncludeSelf({ chatType: 2, guildId: '', peerUid: GroupCode }, msgId, 1, false); + let param = { + groupCode: GroupCode, + msgRandom: parseInt(MsgData.msgList[0].msgRandom), + msgSeq: parseInt(MsgData.msgList[0].msgSeq) + }; + // GetMsgByShoretID(ShoretID); -> MsgService.getMsgs(Peer,MsgId,1,false); -> 组出参数 + return wrapperApi.NodeIQQNTWrapperSession.getGroupService().addGroupEssence(param); + } } diff --git a/src/ntqqapi/api/msg.ts b/src/ntqqapi/api/msg.ts index 54ca551..1bd2da8 100644 --- a/src/ntqqapi/api/msg.ts +++ b/src/ntqqapi/api/msg.ts @@ -1,22 +1,17 @@ import { callNTQQApi, GeneralCallResult, NTQQApiMethod } from '../ntcall' -import { ChatType, RawMessage, SendMessageElement } from '../types' +import { ChatType, RawMessage, SendMessageElement, Peer } from '../types' import { dbUtil } from '../../common/db' import { selfInfo } from '../../common/data' import { ReceiveCmdS, registerReceiveHook } from '../hook' import { log } from '../../common/utils/log' import { sleep } from '../../common/utils/helper' import { isQQ998 } from '../../common/utils' +import { wrapperApi } from '@/ntqqapi/native/wrapper' export let sendMessagePool: Record void) | null> = {} // peerUid: callbackFunc export let sentMessages: Record = {} // msgId: RawMessage -export interface Peer { - chatType: ChatType - peerUid: string // 如果是群聊uid为群号,私聊uid就是加密的字符串 - guildId?: '' -} - async function sendWaiter(peer: Peer, waitComplete = true, timeout: number = 10000) { // 等待上一个相同的peer发送完 const peerUid = peer.peerUid @@ -293,4 +288,7 @@ export class NTQQMsgApi { }) }) } + static async getMsgsBySeqAndCount(peer: Peer, seq: string, count: number, desc: boolean, z: boolean) { + return await wrapperApi.NodeIQQNTWrapperSession.getMsgService().getMsgsBySeqAndCount(peer, seq, count, desc, z); + } } diff --git a/src/ntqqapi/hook.ts b/src/ntqqapi/hook.ts index ca2708d..3e9fee6 100644 --- a/src/ntqqapi/hook.ts +++ b/src/ntqqapi/hook.ts @@ -23,6 +23,7 @@ import { log } from '@/common/utils' import { isNumeric, sleep } from '@/common/utils' import { OB11Constructor } from '../onebot11/constructor' import { OB11GroupCardEvent } from '../onebot11/event/notice/OB11GroupCardEvent' +import { OB11GroupAdminNoticeEvent } from '../onebot11/event/notice/OB11GroupAdminNoticeEvent' export let hookApiCallbacks: Record void> = {} @@ -369,6 +370,13 @@ export async function startHook() { postOb11Event( new OB11GroupCardEvent(parseInt(groupCode), parseInt(member.uin), member.cardName, existMember.cardName), ) + } else if (member.role != existMember.role) { + log('有管理员变动通知') + let groupAdminNoticeEvent = new OB11GroupAdminNoticeEvent() + groupAdminNoticeEvent.group_id = parseInt(groupCode) + groupAdminNoticeEvent.user_id = parseInt(member.uin) + groupAdminNoticeEvent.sub_type = member.role == GroupMemberRole.admin ? 'set' : 'unset' + postOb11Event(groupAdminNoticeEvent, true) } Object.assign(existMember, member) } diff --git a/src/ntqqapi/types/msg.ts b/src/ntqqapi/types/msg.ts index 1e74520..e50295f 100644 --- a/src/ntqqapi/types/msg.ts +++ b/src/ntqqapi/types/msg.ts @@ -415,3 +415,9 @@ export interface RawMessage { multiForwardMsgElement: MultiForwardMsgElement }[] } + +export interface Peer { + chatType: ChatType; + peerUid: string; // 如果是群聊uid为群号,私聊uid就是加密的字符串 + guildId?: string; +} \ No newline at end of file diff --git a/src/onebot11/action/go-cqhttp/DelEssenceMsg.ts b/src/onebot11/action/go-cqhttp/DelEssenceMsg.ts new file mode 100644 index 0000000..2bc5c3b --- /dev/null +++ b/src/onebot11/action/go-cqhttp/DelEssenceMsg.ts @@ -0,0 +1,24 @@ + +import BaseAction from '../BaseAction'; +import { ActionName } from '../types'; +import { NTQQGroupApi } from '../../../ntqqapi/api/group' +import { dbUtil } from '@/common/db'; + +interface Payload { + message_id: number | string; +} + +export default class GoCQHTTPDelEssenceMsg extends BaseAction { + actionName = ActionName.GoCQHTTP_DelEssenceMsg; + + protected async _handle(payload: Payload): Promise { + const msg = await dbUtil.getMsgByShortId(parseInt(payload.message_id.toString())); + if (!msg) { + throw new Error('msg not found'); + } + return await NTQQGroupApi.removeGroupEssence( + msg.peerUid, + msg.msgId + ); + } +} diff --git a/src/onebot11/action/go-cqhttp/SetEssenceMsg.ts b/src/onebot11/action/go-cqhttp/SetEssenceMsg.ts new file mode 100644 index 0000000..682eddd --- /dev/null +++ b/src/onebot11/action/go-cqhttp/SetEssenceMsg.ts @@ -0,0 +1,23 @@ +import BaseAction from '../BaseAction'; +import { ActionName } from '../types'; +import { NTQQGroupApi } from '../../../ntqqapi/api/group' +import { dbUtil } from '@/common/db'; + +interface Payload { + message_id: number | string; +} + +export default class GoCQHTTPSetEssenceMsg extends BaseAction { + actionName = ActionName.GoCQHTTP_SetEssenceMsg; + + protected async _handle(payload: Payload): Promise { + const msg = await dbUtil.getMsgByShortId(parseInt(payload.message_id.toString())); + if (!msg) { + throw new Error('msg not found'); + } + return await NTQQGroupApi.addGroupEssence( + msg.peerUid, + msg.msgId + ); + } +} diff --git a/src/onebot11/action/index.ts b/src/onebot11/action/index.ts index 3785082..a0a8b02 100644 --- a/src/onebot11/action/index.ts +++ b/src/onebot11/action/index.ts @@ -50,6 +50,10 @@ import { ForwardFriendSingleMsg, ForwardGroupSingleMsg } from './msg/ForwardSing import { GetGroupEssence } from './group/GetGroupEssence' import { GetGroupHonorInfo } from './group/GetGroupHonorInfo' import { GoCQHTTHandleQuickOperation } from './go-cqhttp/QuickOperation' +import GoCQHTTPSetEssenceMsg from './go-cqhttp/SetEssenceMsg' +import GoCQHTTPDelEssenceMsg from './go-cqhttp/DelEssenceMsg' +import GetEvent from './llonebot/GetEvent' + export const actionHandlers = [ new GetFile(), @@ -59,6 +63,7 @@ export const actionHandlers = [ new GetGroupAddRequest(), new SetQQAvatar(), new GetFriendWithCategory(), + new GetEvent(), // onebot11 new SendLike(), new GetMsg(), @@ -106,7 +111,9 @@ export const actionHandlers = [ new GoCQHTTPUploadPrivateFile(), new GoCQHTTPGetGroupMsgHistory(), new GoCQHTTGetForwardMsgAction(), - new GoCQHTTHandleQuickOperation() + new GoCQHTTHandleQuickOperation(), + new GoCQHTTPSetEssenceMsg(), + new GoCQHTTPDelEssenceMsg() ] function initActionMap() { diff --git a/src/onebot11/action/llonebot/GetEvent.ts b/src/onebot11/action/llonebot/GetEvent.ts new file mode 100644 index 0000000..09827b1 --- /dev/null +++ b/src/onebot11/action/llonebot/GetEvent.ts @@ -0,0 +1,23 @@ +import BaseAction from '../BaseAction' +import { ActionName } from '../types' +import { getHttpEvent } from '../../server/event-for-http' +import { PostEventType } from '../../server/post-ob11-event' +// import { log } from "../../../common/utils"; + +interface Payload { + key: string + timeout: number +} + +export default class GetEvent extends BaseAction { + actionName = ActionName.GetEvent + protected async _handle(payload: Payload): Promise { + let key = '' + if (payload.key) { + key = payload.key; + } + let timeout = parseInt(payload.timeout?.toString()) || 0; + let evts = await getHttpEvent(key,timeout); + return evts; + } +} diff --git a/src/onebot11/action/types.ts b/src/onebot11/action/types.ts index 1b61ecc..88cdd0f 100644 --- a/src/onebot11/action/types.ts +++ b/src/onebot11/action/types.ts @@ -22,6 +22,7 @@ export enum ActionName { Debug = 'llonebot_debug', GetFile = 'get_file', GetFriendsWithCategory = 'get_friends_with_category', + GetEvent = 'get_event', // onebot 11 SendLike = 'send_like', GetLoginInfo = 'get_login_info', @@ -70,4 +71,6 @@ export enum ActionName { GoCQHTTP_GetEssenceMsg = "get_essence_msg_list", GoCQHTTP_HandleQuickOperation = ".handle_quick_operation", GetGroupHonorInfo = "get_group_honor_info", + GoCQHTTP_SetEssenceMsg = 'set_essence_msg', + GoCQHTTP_DelEssenceMsg = 'delete_essence_msg', } diff --git a/src/onebot11/constructor.ts b/src/onebot11/constructor.ts index addc4fb..df39b01 100644 --- a/src/onebot11/constructor.ts +++ b/src/onebot11/constructor.ts @@ -15,6 +15,7 @@ import { FaceIndex, GrayTipElementSubType, Group, + Peer, GroupMember, PicType, RawMessage, @@ -34,6 +35,7 @@ import { OB11GroupUploadNoticeEvent } from './event/notice/OB11GroupUploadNotice import { OB11GroupNoticeEvent } from './event/notice/OB11GroupNoticeEvent' import { NTQQUserApi } from '../ntqqapi/api/user' import { NTQQFileApi } from '../ntqqapi/api/file' +import { NTQQMsgApi } from '../ntqqapi/api/msg' import { calcQQLevel } from '../common/utils/qqlevel' import { log } from '../common/utils/log' import { sleep } from '../common/utils/helper' @@ -49,6 +51,7 @@ import { OB11FriendRecallNoticeEvent } from './event/notice/OB11FriendRecallNoti import { OB11GroupRecallNoticeEvent } from './event/notice/OB11GroupRecallNoticeEvent' import { OB11FriendPokeEvent, OB11GroupPokeEvent } from './event/notice/OB11PokeEvent' import { OB11BaseNoticeEvent } from './event/notice/OB11BaseNoticeEvent'; +import { OB11GroupEssenceEvent } from './event/notice/OB11GroupEssenceEvent'; let lastRKeyUpdateTime = 0 @@ -109,33 +112,40 @@ export class OB11Constructor { } for (let element of msg.elements) { - let message_data: OB11MessageData | any = { - data: {}, - type: 'unknown', + let message_data: OB11MessageData = { + data: {} as any, + type: 'unknown' as any, } if (element.textElement && element.textElement?.atType !== AtType.notAt) { - message_data['type'] = OB11MessageDataType.at + let qq: string + let name: string | undefined if (element.textElement.atType == AtType.atAll) { - // message_data["data"]["mention"] = "all" - message_data['data']['qq'] = 'all' + qq = 'all' } else { - let atUid = element.textElement.atNtUid + const { atNtUid, content } = element.textElement let atQQ = element.textElement.atUid if (!atQQ || atQQ === '0') { - const atMember = await getGroupMember(msg.peerUin, atUid) + const atMember = await getGroupMember(msg.peerUin, atNtUid) if (atMember) { atQQ = atMember.uin } } if (atQQ) { - // message_data["data"]["mention"] = atQQ - message_data['data']['qq'] = atQQ + qq = atQQ + name = content.replace('@', '') + } + } + message_data = { + type: OB11MessageDataType.at, + data: { + qq, + name } } } else if (element.textElement) { - message_data['type'] = 'text' + message_data['type'] = OB11MessageDataType.text let text = element.textElement.content if (!text.trim()) { continue @@ -143,7 +153,7 @@ export class OB11Constructor { message_data['data']['text'] = text } else if (element.replyElement) { - message_data['type'] = 'reply' + message_data['type'] = OB11MessageDataType.reply // log("收到回复消息", element.replyElement.replayMsgSeq) try { const replyMsg = await dbUtil.getMsgBySeqId(element.replyElement.replayMsgSeq) @@ -159,7 +169,7 @@ export class OB11Constructor { } } else if (element.picElement) { - message_data['type'] = 'image' + message_data['type'] = OB11MessageDataType.image // message_data["data"]["file"] = element.picElement.sourcePath let fileName = element.picElement.fileName const sourcePath = element.picElement.sourcePath @@ -204,9 +214,9 @@ export class OB11Constructor { message_data['data']['file_size'] = videoOrFileElement.fileSize if (element.videoElement) { message_data['data']['url'] = await NTQQFileApi.getVideoUrl({ - chatType: msg.chatType, - peerUid: msg.peerUid, - }, msg.msgId, element.elementId, + chatType: msg.chatType, + peerUid: msg.peerUid, + }, msg.msgId, element.elementId, ) } dbUtil @@ -296,7 +306,7 @@ export class OB11Constructor { message_data['type'] = OB11MessageDataType.forward message_data['data']['id'] = msg.msgId } - if (message_data.type !== 'unknown' && message_data.data) { + if ((message_data.type as string) !== 'unknown' && message_data.data) { const cqCode = encodeCQCode(message_data) if (messagePostFormat === 'string') { (resMsg.message as string) += cqCode @@ -321,11 +331,11 @@ export class OB11Constructor { if (element.grayTipElement.jsonGrayTipElement.busiId == 1061) { //判断业务类型 //Poke事件 - let pokedetail: any[] = json.items; + const pokedetail: any[] = json.items; //筛选item带有uid的元素 - pokedetail = pokedetail.filter(item => item.uid); - if (pokedetail.length == 2) { - return new OB11FriendPokeEvent(parseInt((uidMaps[pokedetail[0].uid])!), parseInt((uidMaps[pokedetail[1].uid]))); + const poke_uid = pokedetail.filter(item => item.uid); + if (poke_uid.length == 2) { + return new OB11FriendPokeEvent(parseInt((uidMaps[poke_uid[0].uid])!), parseInt((uidMaps[poke_uid[1].uid])), pokedetail); } } //下面得改 上面也是错的grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE @@ -526,20 +536,43 @@ export class OB11Constructor { if (grayTipElement.jsonGrayTipElement.busiId == 1061) { //判断业务类型 //Poke事件 - let pokedetail: any[] = json.items; + const pokedetail: any[] = json.items; //筛选item带有uid的元素 - pokedetail = pokedetail.filter(item => item.uid); - if (pokedetail.length == 2) { - return new OB11GroupPokeEvent(parseInt(msg.peerUid), parseInt((uidMaps[pokedetail[0].uid])!), parseInt((uidMaps[pokedetail[1].uid]))); + const poke_uid = pokedetail.filter(item => item.uid); + if (poke_uid.length == 2) { + return new OB11GroupPokeEvent(parseInt(msg.peerUid), parseInt((uidMaps[poke_uid[0].uid])!), parseInt((uidMaps[poke_uid[1].uid])), pokedetail); } } - const memberUin = json.items[1].param[0] - const title = json.items[3].txt - log('收到群成员新头衔消息', json) - getGroupMember(msg.peerUid, memberUin).then((member) => { - member.memberSpecialTitle = title - }) - return new OB11GroupTitleEvent(parseInt(msg.peerUid), parseInt(memberUin), title) + if (grayTipElement.jsonGrayTipElement.busiId == 2401) { + log('收到群精华消息', json) + const searchParams = new URL(json.items[0].jp).searchParams; + const msgSeq = searchParams.get('msgSeq')!; + const Group = searchParams.get('groupCode'); + const Businessid = searchParams.get('businessid'); + const Peer: Peer = { + guildId: '', + chatType: ChatType.group, + peerUid: Group! + }; + let msgList = (await NTQQMsgApi.getMsgsBySeqAndCount(Peer, msgSeq.toString(), 1, true, true)).msgList; + const origMsg = await dbUtil.getMsgByLongId(msgList[0].msgId); + const postMsg = await dbUtil.getMsgBySeqId(origMsg.msgSeq) ?? origMsg; + // 如果 senderUin 为 0,可能是 历史消息 或 自身消息 + if (msgList[0].senderUin === '0') { + msgList[0].senderUin = postMsg?.senderUin ?? selfInfo.uin; + } + return new OB11GroupEssenceEvent(parseInt(msg.peerUid), postMsg.msgShortId, parseInt(msgList[0].senderUin)); + // 获取MsgSeq+Peer可获取具体消息 + } + if (grayTipElement.jsonGrayTipElement.busiId == 2407) { + const memberUin = json.items[1].param[0] + const title = json.items[3].txt + log('收到群成员新头衔消息', json) + getGroupMember(msg.peerUid, memberUin).then((member) => { + member.memberSpecialTitle = title + }) + return new OB11GroupTitleEvent(parseInt(msg.peerUid), parseInt(memberUin), title) + } } } } diff --git a/src/onebot11/cqcode.ts b/src/onebot11/cqcode.ts index 6b61160..6ffcddb 100644 --- a/src/onebot11/cqcode.ts +++ b/src/onebot11/cqcode.ts @@ -50,7 +50,6 @@ export function encodeCQCode(data: OB11MessageData) { } const CQCodeEscape = (text: string) => { - text = text.toString() return text.replace(/\&/g, '&').replace(/\[/g, '[').replace(/\]/g, ']').replace(/,/g, ',') } @@ -61,15 +60,15 @@ export function encodeCQCode(data: OB11MessageData) { let result = '[CQ:' + data.type for (const name in data.data) { const value = data.data[name] + if (value === undefined) { + continue + } try { - // Check if the value can be converted to a string - value.toString(); + const text = value.toString() + result += `,${name}=${CQCodeEscape(text)}` } catch (error) { // If it can't be converted, skip this name-value pair - // console.warn(`Skipping problematic name-value pair. Name: ${name}, Value: ${value}`); - continue; } - result += `,${name}=${CQCodeEscape(value)}` } result += ']' return result diff --git a/src/onebot11/event/notice/OB11GroupEssenceEvent.ts b/src/onebot11/event/notice/OB11GroupEssenceEvent.ts new file mode 100644 index 0000000..ae1053e --- /dev/null +++ b/src/onebot11/event/notice/OB11GroupEssenceEvent.ts @@ -0,0 +1,14 @@ +import { OB11GroupNoticeEvent } from './OB11GroupNoticeEvent'; +export class OB11GroupEssenceEvent extends OB11GroupNoticeEvent { + notice_type = 'essence'; + message_id: number; + sender_id: number; + sub_type: 'add' | 'delete' = 'add'; + + constructor(groupId: number, message_id: number, sender_id: number) { + super(); + this.group_id = groupId; + this.message_id = message_id; + this.sender_id = sender_id; + } +} diff --git a/src/onebot11/event/notice/OB11PokeEvent.ts b/src/onebot11/event/notice/OB11PokeEvent.ts index 4811a35..0f98ef6 100644 --- a/src/onebot11/event/notice/OB11PokeEvent.ts +++ b/src/onebot11/event/notice/OB11PokeEvent.ts @@ -5,25 +5,28 @@ import { OB11BaseEvent } from '../OB11BaseEvent' class OB11PokeEvent extends OB11BaseNoticeEvent { notice_type = 'notify' sub_type = 'poke' - target_id = parseInt(selfInfo.uin) + target_id = 0 user_id: number + raw_message: any } export class OB11FriendPokeEvent extends OB11PokeEvent { - constructor(user_id: number, target_id: number) { + + constructor(user_id: number, target_id: number, raw_message: any) { super(); this.target_id = target_id; this.user_id = user_id; + this.raw_message = raw_message; } } export class OB11GroupPokeEvent extends OB11PokeEvent { group_id: number - - constructor(group_id: number, user_id: number = 0, target_id: number = 0) { + constructor(group_id: number, user_id: number = 0, target_id: number = 0, raw_message: any) { super() this.group_id = group_id this.target_id = target_id this.user_id = user_id + this.raw_message = raw_message } } diff --git a/src/onebot11/server/event-for-http.ts b/src/onebot11/server/event-for-http.ts new file mode 100644 index 0000000..086aa2a --- /dev/null +++ b/src/onebot11/server/event-for-http.ts @@ -0,0 +1,68 @@ +import { PostEventType } from "./post-ob11-event" + + +interface HttpEventType { + seq: number + event: PostEventType +} + +interface HttpUserType { + lastAccessTime: number + userSeq: number +} + +let curentSeq:number = 0; +let eventList:HttpEventType[] = []; +let httpUser:Record = {}; + + +export function postHttpEvent(event: PostEventType) { + curentSeq += 1; + eventList.push({ + seq: curentSeq, + event: event + }); + while(eventList.length > 100) { + eventList.shift(); + } +} + + +export async function getHttpEvent(userKey:string,timeout = 0) { + let toRetEvent = []; + + // 清除过时的user,5分钟没访问过的user将被删除 + let now = Date.now(); + for(let key in httpUser) { + let user = httpUser[key]; + if(now - user.lastAccessTime > 1000 * 60 * 5) { + delete httpUser[key]; + } + } + + // 增加新的user + if(!httpUser[userKey] ) { + httpUser[userKey] = { + lastAccessTime: now, + userSeq: curentSeq + } + } + + let user = httpUser[userKey]; + // 等待数据到来,暂时先这么写吧...... + while(curentSeq == user.userSeq && Date.now() - now < timeout) { + await new Promise( resolve => setTimeout(resolve, 10) ); + } + // 取数据 + for(let i = 0; i < eventList.length; i++) { + let evt = eventList[i]; + if(evt.seq > user.userSeq) { + toRetEvent.push(evt.event); + } + } + + // 更新user数据 + user.lastAccessTime = Date.now(); + user.userSeq = curentSeq; + return toRetEvent; +} diff --git a/src/onebot11/server/post-ob11-event.ts b/src/onebot11/server/post-ob11-event.ts index d78f130..c781ea6 100644 --- a/src/onebot11/server/post-ob11-event.ts +++ b/src/onebot11/server/post-ob11-event.ts @@ -8,6 +8,7 @@ import { log } from '@/common/utils' import { getConfigUtil } from '@/common/config' import crypto from 'crypto' import { handleQuickOperation, QuickOperationEvent } from '../action/quick-operation' +import { postHttpEvent } from './event-for-http' export type PostEventType = OB11Message | OB11BaseMetaEvent | OB11BaseNoticeEvent @@ -78,4 +79,9 @@ export function postOb11Event(msg: PostEventType, reportSelf = false, postWs = t if (postWs) { postWsEvent(msg) } + if(!(msg.post_type == 'meta_event' && (msg as OB11BaseMetaEvent).meta_event_type == 'heartbeat')) { + // 不上报心跳 + postHttpEvent(msg) + } + } diff --git a/src/onebot11/types.ts b/src/onebot11/types.ts index de9c2ed..90a9f3c 100644 --- a/src/onebot11/types.ts +++ b/src/onebot11/types.ts @@ -195,6 +195,7 @@ export interface OB11MessageAt { type: OB11MessageDataType.at data: { qq: string | 'all' + name?: string } } @@ -241,6 +242,20 @@ export interface OB11MessageJson { data: { data: string /* , config: { token: string } */ } } +export interface OB11MessageMarkdown { + type: OB11MessageDataType.markdown + data: { + data: string + } +} + +export interface OB11MessageForward { + type: OB11MessageDataType.forward + data: { + id: string + } +} + export type OB11MessageData = | OB11MessageText | OB11MessageFace @@ -258,6 +273,8 @@ export type OB11MessageData = | OB11MessagePoke | OB11MessageDice | OB11MessageRPS + | OB11MessageMarkdown + | OB11MessageForward export interface OB11PostSendMsg { message_type?: 'private' | 'group'