diff --git a/manifest.json b/manifest.json index 805eb84..952c1eb 100644 --- a/manifest.json +++ b/manifest.json @@ -5,7 +5,7 @@ "slug": "LLOneBot", "description": "LiteLoaderQQNT的OneBotApi", "version": "3.13.11", - "thumbnail": "./icon.png", + "icon": "./icon.png", "authors": [ { "name": "linyuchen", diff --git a/src/main/main.ts b/src/main/main.ts index f59df63..1102a17 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -170,6 +170,12 @@ function onLoad() { postOB11Event(msg); // log("post msg", msg) }).catch(e => log("constructMessage error: ", e.stack.toString())); + OB11Constructor.GroupEvent(message).then(groupEvent=>{ + if (groupEvent){ + // log("post group event", groupEvent); + postOB11Event(groupEvent); + } + }) } } diff --git a/src/ntqqapi/hook.ts b/src/ntqqapi/hook.ts index a0c5427..860924f 100644 --- a/src/ntqqapi/hook.ts +++ b/src/ntqqapi/hook.ts @@ -168,24 +168,6 @@ async function processGroupEvent(payload) { break; } } - - } else if (existGroup.memberCount < group.memberCount) { - const oldMembers = existGroup.members; - const oldMembersSet = new Set(); - for (const member of oldMembers) { - oldMembersSet.add(member.uin); - } - - await sleep(200); - const newMembers = await NTQQApi.getGroupMembers(group.groupCode); - - group.members = newMembers; - for (const member of newMembers) { - if (!oldMembersSet.has(member.uin)) { - postOB11Event(new OB11GroupIncreaseEvent(group.groupCode, parseInt(member.uin))); - break; - } - } } } } diff --git a/src/ntqqapi/types.ts b/src/ntqqapi/types.ts index 542f319..8d0b1ed 100644 --- a/src/ntqqapi/types.ts +++ b/src/ntqqapi/types.ts @@ -112,6 +112,7 @@ export enum PicType { gif = 2000, jpg = 1000 } + export interface SendPicElement { elementType: ElementType.PIC, elementId: "", @@ -218,8 +219,8 @@ export interface PttElement { export interface ArkElement { bytesData: string; - linkInfo:null, - subElementType:null + linkInfo: null, + subElementType: null } export const IMAGE_HTTP_HOST = "https://gchat.qpic.cn" @@ -245,7 +246,8 @@ export interface GrayTipElement { operatorMemRemark?: string; wording: string; // 自定义的撤回提示语 } - aioOpGrayTipElement: TipAioOpGrayTipElement + aioOpGrayTipElement: TipAioOpGrayTipElement, + groupElement: TipGroupElement } export interface FaceElement { @@ -278,15 +280,20 @@ export interface VideoElement { "sourceVideoCodecFormat": 0 } -export interface TipAioOpGrayTipElement{ +export interface TipAioOpGrayTipElement { // 这是什么提示来着? operateType: number, peerUid: string, fromGrpCodeOfTmpChat: string, } +export enum TipGroupElementType { + memberIncrease = 1, + ban = 8 +} + export interface TipGroupElement { - "type": 1, // 1是表示有人加入群, 自己加入群也会收到这个 - "role": 0, + "type": TipGroupElementType, // 1是表示有人加入群, 自己加入群也会收到这个 + "role": 0, // 暂时不知 "groupName": string, // 暂时获取不到 "memberUid": string, "memberNick": string, @@ -295,7 +302,7 @@ export interface TipGroupElement { "adminNick": string, "adminRemark": string, "createGroup": null, - "memberAdd": { + "memberAdd"?: { "showType": 1, "otherAdd": null, "otherAddByOtherQRCode": null, @@ -305,7 +312,22 @@ export interface TipGroupElement { "otherInviteYou": null, "youInviteOther": null }, - "shutUp": null + "shutUp"?: { + "curTime": string, + "duration": string, // 禁言时间,秒 + "admin": { + "uid": string, + "card": string, + "name": string, + "role": GroupMemberRole + }, + "member": { + "uid": string + "card": string, + "name": string, + "role": GroupMemberRole + } + } } diff --git a/src/onebot11/constructor.ts b/src/onebot11/constructor.ts index 8b1d003..8e544b5 100644 --- a/src/onebot11/constructor.ts +++ b/src/onebot11/constructor.ts @@ -8,13 +8,25 @@ import { OB11User, OB11UserSex } from "./types"; -import {AtType, ChatType, Group, GroupMember, IMAGE_HTTP_HOST, RawMessage, SelfInfo, User} from '../ntqqapi/types'; -import {getFriend, getGroupMember, selfInfo, tempGroupCodeMap} from '../common/data'; -import {getConfigUtil, log} from "../common/utils"; +import { + AtType, + ChatType, + Group, + GroupMember, + IMAGE_HTTP_HOST, + RawMessage, + SelfInfo, + TipGroupElementType, + User +} from '../ntqqapi/types'; +import {getFriend, getGroup, getGroupMember, selfInfo, tempGroupCodeMap} from '../common/data'; +import {getConfigUtil, log, sleep} from "../common/utils"; import {NTQQApi} from "../ntqqapi/ntcall"; import {EventType} from "./event/OB11BaseEvent"; import {encodeCQCode} from "./cqcode"; import {dbUtil} from "../common/db"; +import {OB11GroupIncreaseEvent} from "./event/notice/OB11GroupIncreaseEvent"; +import {OB11GroupBanEvent} from "./event/notice/OB11GroupBanEvent"; export class OB11Constructor { @@ -97,7 +109,7 @@ export class OB11Constructor { } else if (element.replyElement) { message_data["type"] = "reply" // log("收到回复消息", element.replyElement.replayMsgSeq) - try{ + try { const replyMsg = await dbUtil.getMsgBySeqId(element.replyElement.replayMsgSeq) // log("找到回复消息", replyMsg.msgShortId, replyMsg.msgId) if (replyMsg) { @@ -105,7 +117,7 @@ export class OB11Constructor { } else { continue } - }catch (e) { + } catch (e) { log("获取不到引用的消息", e.stack, element.replyElement.replayMsgSeq) } @@ -116,10 +128,9 @@ export class OB11Constructor { // message_data["data"]["path"] = element.picElement.sourcePath const url = element.picElement.originImageUrl const fileMd5 = element.picElement.md5HexStr - if (url){ + if (url) { message_data["data"]["url"] = IMAGE_HTTP_HOST + url - } - else if (fileMd5 && element.picElement.fileUuid.indexOf("_") === -1){ // fileuuid有下划线的是Linux发送的,这个url是另外的格式,目前尚未得知如何组装 + } else if (fileMd5 && element.picElement.fileUuid.indexOf("_") === -1) { // fileuuid有下划线的是Linux发送的,这个url是另外的格式,目前尚未得知如何组装 message_data["data"]["url"] = `${IMAGE_HTTP_HOST}/gchatpic_new/0/0-0-${fileMd5.toUpperCase()}/0` } // message_data["data"]["file_id"] = element.picElement.fileUuid @@ -193,7 +204,10 @@ export class OB11Constructor { message_data["type"] = OB11MessageDataType.face; message_data["data"]["id"] = element.faceElement.faceIndex.toString(); } - + // todo: 解析入群grayTipElement + else if (element.grayTipElement?.aioOpGrayTipElement) { + log("收到 group gray tip 消息", element.grayTipElement.aioOpGrayTipElement) + } // if (message_data.data.file) { // let filePath: string = message_data.data.file; // if (!enableLocalFile2Url) { @@ -230,6 +244,44 @@ export class OB11Constructor { return resMsg; } + static async GroupEvent(msg: RawMessage): Promise { + for (let element of msg.elements) { + const groupElement = element.grayTipElement?.groupElement + if (groupElement) { + // log("收到群提示消息", groupElement) + if (groupElement.type == TipGroupElementType.memberIncrease) { + log("收到群成员增加消息", groupElement) + await sleep(1000); + const member = await getGroupMember(msg.peerUid, null, groupElement.memberUid); + let memberUin = member?.uin; + if (!memberUin) { + memberUin = (await NTQQApi.getUserDetailInfo(groupElement.memberUid)).uin + } + // log("获取新群成员QQ", memberUin) + const adminMember = await getGroupMember(msg.peerUid, null, groupElement.adminUid); + // log("获取同意新成员入群的管理员", adminMember) + if (memberUin) { + const operatorUin = adminMember?.uin || memberUin + let event = new OB11GroupIncreaseEvent(parseInt(msg.peerUid), parseInt(memberUin), parseInt(operatorUin)); + // log("构造群增加事件", event) + return event; + } + } + else if (groupElement.type === TipGroupElementType.ban) { + log("收到群群员禁言提示", groupElement) + const memberUid = groupElement.shutUp.member.uid + const adminUid = groupElement.shutUp.admin.uid + const memberUin = (await getGroupMember(msg.peerUid, null, memberUid))?.uin || (await NTQQApi.getUserDetailInfo(memberUid))?.uin + const adminUin = (await getGroupMember(msg.peerUid, null, adminUid))?.uin || (await NTQQApi.getUserDetailInfo(adminUid))?.uin + const duration = parseInt(groupElement.shutUp.duration) + if (memberUin && adminUin) { + return new OB11GroupBanEvent(parseInt(msg.peerUid), parseInt(memberUin), parseInt(adminUin), duration, duration > 0 ? "ban" : "lift_ban"); + } + } + } + } + } + static friend(friend: User): OB11User { return { user_id: parseInt(friend.uin), diff --git a/src/onebot11/event/notice/OB11GroupBanEvent.ts b/src/onebot11/event/notice/OB11GroupBanEvent.ts new file mode 100644 index 0000000..1939539 --- /dev/null +++ b/src/onebot11/event/notice/OB11GroupBanEvent.ts @@ -0,0 +1,17 @@ +import {OB11GroupNoticeEvent} from "./OB11GroupNoticeEvent"; + +export class OB11GroupBanEvent extends OB11GroupNoticeEvent { + notice_type = "group_ban"; + operator_id: number; + duration: number; + sub_type: "ban" | "lift_ban"; + + constructor(groupId: number, userId: number, operatorId: number, duration: number, sub_type: "ban" | "lift_ban") { + super(); + this.group_id = groupId; + this.operator_id = operatorId; + this.user_id = userId; + this.duration = duration; + this.sub_type = sub_type; + } +} diff --git a/src/onebot11/event/notice/OB11GroupIncreaseEvent.ts b/src/onebot11/event/notice/OB11GroupIncreaseEvent.ts index 4382925..d7e9158 100644 --- a/src/onebot11/event/notice/OB11GroupIncreaseEvent.ts +++ b/src/onebot11/event/notice/OB11GroupIncreaseEvent.ts @@ -5,10 +5,10 @@ export class OB11GroupIncreaseEvent extends OB11GroupNoticeEvent { sub_type = "approve"; // TODO: 实现其他几种子类型的识别 ("approve" | "invite") operator_id: number; - constructor(groupId: number, userId: number) { + constructor(groupId: number, userId: number, operatorId: number) { super(); this.group_id = groupId; - this.operator_id = userId; // 实际上不应该这么实现,但是现在还没有办法识别用户是被邀请的,还是主动加入的 + this.operator_id = operatorId; this.user_id = userId; } } diff --git a/src/version.ts b/src/version.ts index b4b5657..dde39cf 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const version = "3.13.11" \ No newline at end of file +export const version = "3.14.0" \ No newline at end of file