From 8c0cc8beba1515026543c77bb72aadddda0b1662 Mon Sep 17 00:00:00 2001 From: idranme <96647698+idranme@users.noreply.github.com> Date: Sun, 6 Oct 2024 10:28:52 +0800 Subject: [PATCH] refactor --- package.json | 7 +- src/common/utils/file.ts | 19 +- src/common/utils/legacyLog.ts | 11 +- src/common/utils/upgrade.ts | 20 +- src/ntqqapi/api/file.ts | 58 +++-- src/ntqqapi/api/friend.ts | 18 +- src/ntqqapi/api/group.ts | 206 +++++++----------- src/ntqqapi/api/msg.ts | 63 ++---- src/ntqqapi/api/user.ts | 99 +++------ src/ntqqapi/api/window.ts | 3 +- src/ntqqapi/entities.ts | 30 +-- src/ntqqapi/helper/face_config.json | 12 +- .../services/NodeIKernelGroupService.ts | 2 + src/ntqqapi/services/NodeIKernelMsgService.ts | 4 + .../services/NodeIKernelProfileLikeService.ts | 2 +- src/ntqqapi/types/msg.ts | 127 ++++++----- src/ntqqapi/types/notify.ts | 78 ++----- .../action/go-cqhttp/GetGroupFileUrl.ts | 2 +- .../action/go-cqhttp/GetGroupSystemMsg.ts | 4 +- .../action/go-cqhttp/SendGroupNotice.ts | 2 +- .../action/go-cqhttp/UploadGroupFile.ts | 2 +- .../action/go-cqhttp/UploadPrivateFile.ts | 2 +- .../action/group/GetGroupMemberInfo.ts | 4 +- src/onebot11/action/llonebot/Debug.ts | 6 +- .../action/llonebot/GetGroupAddRequest.ts | 2 +- src/onebot11/action/llonebot/SetQQAvatar.ts | 4 +- src/onebot11/adapter.ts | 59 ++--- src/onebot11/connect/ws.ts | 2 +- src/onebot11/entities.ts | 46 ++-- src/onebot11/helper/createMessage.ts | 46 ++-- 30 files changed, 385 insertions(+), 555 deletions(-) diff --git a/package.json b/package.json index 7aee440..2fded7f 100644 --- a/package.json +++ b/package.json @@ -18,16 +18,19 @@ "license": "MIT", "dependencies": { "@minatojs/driver-sqlite": "^4.6.0", + "@satorijs/element": "^3.1.7", + "@satorijs/protocol": "^1.4.2", + "compare-versions": "^6.1.1", "cordis": "^3.18.1", "cors": "^2.8.5", - "cosmokit": "^1.6.2", + "cosmokit": "^1.6.3", "express": "^5.0.0", "fast-xml-parser": "^4.5.0", - "file-type": "^19.5.0", "fluent-ffmpeg": "^2.1.3", "minato": "^3.6.0", "protobufjs": "^7.4.0", "silk-wasm": "^3.6.1", + "ts-case-convert": "^2.1.0", "ws": "^8.18.0" }, "devDependencies": { diff --git a/src/common/utils/file.ts b/src/common/utils/file.ts index b05593b..6bb9c9a 100644 --- a/src/common/utils/file.ts +++ b/src/common/utils/file.ts @@ -4,7 +4,7 @@ import path from 'node:path' import { TEMP_DIR } from '../globalVars' import { randomUUID, createHash } from 'node:crypto' import { fileURLToPath } from 'node:url' -import { fileTypeFromFile } from 'file-type' +import { Context } from 'cordis' // 定义一个异步函数来检查文件是否存在 export function checkFileReceived(path: string, timeout: number = 3000): Promise { @@ -118,7 +118,7 @@ type Uri2LocalRes = { isLocal: boolean } -export async function uri2local(uri: string, filename?: string, needExt?: boolean): Promise { +export async function uri2local(ctx: Context, uri: string, needExt?: boolean): Promise { const { type } = checkUriType(uri) if (type === FileUriType.FileURL) { @@ -136,15 +136,16 @@ export async function uri2local(uri: string, filename?: string, needExt?: boolea try { const res = await fetchFile(uri) const match = res.url.match(/.+\/([^/?]*)(?=\?)?/) + let filename: string if (match?.[1]) { - filename ??= match[1].replace(/[/\\:*?"<>|]/g, '_') + filename = match[1].replace(/[/\\:*?"<>|]/g, '_') } else { - filename ??= randomUUID() + filename = randomUUID() } let filePath = path.join(TEMP_DIR, filename) await fsPromise.writeFile(filePath, res.data) if (needExt && !path.extname(filePath)) { - const ext = (await fileTypeFromFile(filePath))?.ext + const ext = (await ctx.ntFileApi.getFileType(filePath)).ext filename += `.${ext}` await fsPromise.rename(filePath, `${filePath}.${ext}`) filePath = `${filePath}.${ext}` @@ -157,12 +158,12 @@ export async function uri2local(uri: string, filename?: string, needExt?: boolea } if (type === FileUriType.OneBotBase64) { - filename ??= randomUUID() + let filename = randomUUID() let filePath = path.join(TEMP_DIR, filename) const base64 = uri.replace(/^base64:\/\//, '') await fsPromise.writeFile(filePath, base64, 'base64') if (needExt) { - const ext = (await fileTypeFromFile(filePath))?.ext + const ext = (await ctx.ntFileApi.getFileType(filePath)).ext filename += `.${ext}` await fsPromise.rename(filePath, `${filePath}.${ext}`) filePath = `${filePath}.${ext}` @@ -174,12 +175,12 @@ export async function uri2local(uri: string, filename?: string, needExt?: boolea // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types const capture = /^data:([\w/.+-]+);base64,(.*)$/.exec(uri) if (capture) { - filename ??= randomUUID() + let filename = randomUUID() const [, _type, base64] = capture let filePath = path.join(TEMP_DIR, filename) await fsPromise.writeFile(filePath, base64, 'base64') if (needExt) { - const ext = (await fileTypeFromFile(filePath))?.ext + const ext = (await ctx.ntFileApi.getFileType(filePath)).ext filename += `.${ext}` await fsPromise.rename(filePath, `${filePath}.${ext}`) filePath = `${filePath}.${ext}` diff --git a/src/common/utils/legacyLog.ts b/src/common/utils/legacyLog.ts index 0010d2f..c779ffc 100644 --- a/src/common/utils/legacyLog.ts +++ b/src/common/utils/legacyLog.ts @@ -13,10 +13,15 @@ export function log(...msg: unknown[]) { let logMsg = '' for (const msgItem of msg) { if (typeof msgItem === 'object') { - logMsg += inspect(msgItem, { depth: 10, compact: true, breakLength: Infinity }) + ' ' - continue + logMsg += inspect(msgItem, { + depth: 10, + compact: true, + breakLength: Infinity, + maxArrayLength: 220 + }) + ' ' + } else { + logMsg += msgItem + ' ' } - logMsg += msgItem + ' ' } const currentDateTime = new Date().toLocaleString() logMsg = `${currentDateTime} ${logMsg}\n\n` diff --git a/src/common/utils/upgrade.ts b/src/common/utils/upgrade.ts index d625195..bdf10df 100644 --- a/src/common/utils/upgrade.ts +++ b/src/common/utils/upgrade.ts @@ -3,25 +3,19 @@ import { writeFile } from 'node:fs/promises' import { version } from '../../version' import { log, fetchFile } from '.' import { TEMP_DIR } from '../globalVars' +import { compare } from 'compare-versions' const downloadMirrorHosts = ['https://ghp.ci/'] const releasesMirrorHosts = ['https://kkgithub.com'] export async function checkNewVersion() { - const latestVersionText = await getRemoteVersion() - const latestVersion = latestVersionText.split('.') + const latestVersion = await getRemoteVersion() log('LLOneBot latest version', latestVersion) - const currentVersion = version.split('.') - //log('llonebot current version', currentVersion) - for (const k of [0, 1, 2]) { - const latest = parseInt(latestVersion[k]) - const current = parseInt(currentVersion[k]) - if (latest > current) { - log('') - return { result: true, version: latestVersionText } - } else if (latest < current) { - break - } + if (latestVersion === '') { + return { result: false, version: latestVersion } + } + if (compare(latestVersion, version, '>')) { + return { result: true, version: latestVersion } } return { result: false, version: version } } diff --git a/src/ntqqapi/api/file.ts b/src/ntqqapi/api/file.ts index 5ec5d8e..52325e0 100644 --- a/src/ntqqapi/api/file.ts +++ b/src/ntqqapi/api/file.ts @@ -18,7 +18,6 @@ import { ReceiveCmdS } from '../hook' import { RkeyManager } from '@/ntqqapi/helper/rkey' import { OnRichMediaDownloadCompleteParams, Peer } from '@/ntqqapi/types/msg' import { calculateFileMD5 } from '@/common/utils/file' -import { fileTypeFromFile } from 'file-type' import { copyFile, stat, unlink } from 'node:fs/promises' import { Time } from 'cosmokit' import { Service, Context } from 'cordis' @@ -56,7 +55,12 @@ export class NTQQFileApi extends Service { } async getFileType(filePath: string) { - return fileTypeFromFile(filePath) + return await invoke<{ + ext: string + mime: string + }>(NTMethod.FILE_TYPE, [filePath], { + className: NTClass.FS_API + }) } /** 上传文件到 QQ 的文件夹 */ @@ -111,23 +115,20 @@ export class NTQQFileApi extends Service { } const data = await invoke<{ notifyInfo: OnRichMediaDownloadCompleteParams }>( 'nodeIKernelMsgService/downloadRichMedia', - [ - { - getReq: { - fileModelId: '0', - downloadSourceType: 0, - triggerType: 1, - msgId: msgId, - chatType: chatType, - peerUid: peerUid, - elementId: elementId, - thumbSize: 0, - downloadType: 1, - filePath: thumbPath, - }, + [{ + getReq: { + fileModelId: '0', + downloadSourceType: 0, + triggerType: 1, + msgId: msgId, + chatType: chatType, + peerUid: peerUid, + elementId: elementId, + thumbSize: 0, + downloadType: 1, + filePath: thumbPath, }, - null, - ], + }], { cbCmd: ReceiveCmdS.MEDIA_DOWNLOAD_COMPLETE, cmdCB: payload => payload.notifyInfo.msgId === msgId, @@ -186,14 +187,11 @@ export class NTQQFileApi extends Service { async downloadFileForModelId(peer: Peer, fileModelId: string, timeout = 2 * Time.minute) { const data = await invoke<{ notifyInfo: OnRichMediaDownloadCompleteParams }>( 'nodeIKernelRichMediaService/downloadFileForModelId', - [ - { - peer, - fileModelIdList: [fileModelId], - save_path: '' - }, - null, - ], + [{ + peer, + fileModelIdList: [fileModelId], + save_path: '' + }], { cbCmd: ReceiveCmdS.MEDIA_DOWNLOAD_COMPLETE, cmdCB: payload => payload.notifyInfo.fileModelId === fileModelId, @@ -211,7 +209,7 @@ export class NTQQFileCacheApi extends Service { } async setCacheSilentScan(isSilent: boolean = true) { - return await invoke(NTMethod.CACHE_SET_SILENCE, [{ isSilent }, null]) + return await invoke(NTMethod.CACHE_SET_SILENCE, [{ isSilent }]) } getCacheSessionPathList() { @@ -225,7 +223,7 @@ export class NTQQFileCacheApi extends Service { scanCache() { invoke(ReceiveCmdS.CACHE_SCAN_FINISH, [], { registerEvent: true }) - return invoke(NTMethod.CACHE_SCAN, [null, null], { timeout: 300 * Time.second }) + return invoke(NTMethod.CACHE_SCAN, [], { timeout: 300 * Time.second }) } getHotUpdateCachePath() { @@ -245,13 +243,13 @@ export class NTQQFileCacheApi extends Service { pageSize: pageSize, order: 1, lastRecord: _lastRecord, - }, null]) + }]) } async clearChatCache(chats: ChatCacheListItemBasic[] = [], fileKeys: string[] = []) { return await invoke(NTMethod.CACHE_CHAT_CLEAR, [{ chats, fileKeys, - }, null]) + }]) } } diff --git a/src/ntqqapi/api/friend.ts b/src/ntqqapi/api/friend.ts index 3c92ae3..47cb431 100644 --- a/src/ntqqapi/api/friend.ts +++ b/src/ntqqapi/api/friend.ts @@ -24,15 +24,11 @@ export class NTQQFriendApi extends Service { categroyMbCount: number buddyList: Friend[] }[] - }>( - 'getBuddyList', - [], - { - className: NTClass.NODE_STORE_API, - cbCmd: ReceiveCmdS.FRIENDS, - afterFirstCmd: false, - } - ) + }>('getBuddyList', [], { + className: NTClass.NODE_STORE_API, + cbCmd: ReceiveCmdS.FRIENDS, + afterFirstCmd: false + }) const _friends: Friend[] = [] for (const item of data.data) { _friends.push(...item.buddyList) @@ -121,13 +117,13 @@ export class NTQQFriendApi extends Service { } async getBuddyRecommendContact(uin: string) { - const ret = await invoke('nodeIKernelBuddyService/getBuddyRecommendContactArkJson', [{ uin }, null]) + const ret = await invoke('nodeIKernelBuddyService/getBuddyRecommendContactArkJson', [{ uin }]) return ret.arkMsg } async setBuddyRemark(uid: string, remark: string) { return await invoke('nodeIKernelBuddyService/setBuddyRemark', [{ remarkParams: { uid, remark } - }, null]) + }]) } } diff --git a/src/ntqqapi/api/group.ts b/src/ntqqapi/api/group.ts index 9c4fd31..a9d9edb 100644 --- a/src/ntqqapi/api/group.ts +++ b/src/ntqqapi/api/group.ts @@ -15,9 +15,7 @@ import { invoke, NTClass, NTMethod } from '../ntcall' import { GeneralCallResult } from '../services' import { NTQQWindows } from './window' import { getSession } from '../wrapper' -import { NodeIKernelGroupService } from '../services' import { Service, Context } from 'cordis' -import { isNumeric } from '@/common/utils/misc' declare module 'cordis' { interface Context { @@ -28,8 +26,6 @@ declare module 'cordis' { export class NTQQGroupApi extends Service { static inject = ['ntWindowApi'] - public groupMembers: Map> = new Map>() - constructor(protected ctx: Context) { super(ctx, 'ntGroupApi', true) } @@ -51,49 +47,37 @@ export class NTQQGroupApi extends Service { } async getGroupMembers(groupCode: string, num = 3000): Promise> { - const session = getSession() - let result: Awaited> - if (session) { - const groupService = session.getGroupService() - const sceneId = groupService.createMemberListScene(groupCode, 'groupMemberList_MainWindow') - result = await groupService.getNextMemberList(sceneId, undefined, num) - } else { - const sceneId = await invoke(NTMethod.GROUP_MEMBER_SCENE, [{ groupCode, scene: 'groupMemberList_MainWindow' }]) - result = await invoke(NTMethod.GROUP_MEMBERS, [{ sceneId, num }, null]) + const sceneId = await invoke(NTMethod.GROUP_MEMBER_SCENE, [{ groupCode, scene: 'groupMemberList_MainWindow' }]) + const data = await invoke(NTMethod.GROUP_MEMBERS, [{ sceneId, num }]) + if (data.errCode !== 0) { + throw new Error('获取群成员列表出错,' + data.errMsg) } - if (result.errCode !== 0) { - throw ('获取群成员列表出错,' + result.errMsg) - } - return result.result.infos + return data.result.infos } - async getGroupMember(groupCode: string, memberUinOrUid: string) { - if (!this.groupMembers.has(groupCode)) { - try { - // 更新群成员列表 - this.groupMembers.set(groupCode, await this.getGroupMembers(groupCode)) + async getGroupMember(groupCode: string, uid: string, forceUpdate = false) { + invoke('nodeIKernelGroupListener/onMemberInfoChange', [], { + registerEvent: true + }) + + const data = await invoke<{ + groupCode: string + members: Map + }>( + 'nodeIKernelGroupService/getMemberInfo', + [{ + groupCode, + uids: [uid], + forceUpdate + }], + { + cbCmd: 'nodeIKernelGroupListener/onMemberInfoChange', + afterFirstCmd: false, + cmdCB: payload => payload.members.has(uid), + timeout: 2000 } - catch (e) { - return - } - } - let members = this.groupMembers.get(groupCode)! - const getMember = () => { - let member: GroupMember | undefined = undefined - if (isNumeric(memberUinOrUid)) { - member = Array.from(members.values()).find(member => member.uin === memberUinOrUid) - } else { - member = members.get(memberUinOrUid) - } - return member - } - let member = getMember() - if (!member) { - this.groupMembers.set(groupCode, await this.getGroupMembers(groupCode)) - members = this.groupMembers.get(groupCode)! - member = getMember() - } - return member + ) + return data.members.get(uid)! } async getGroupIgnoreNotifies() { @@ -105,11 +89,12 @@ export class NTQQGroupApi extends Service { ) } - async getSingleScreenNotifies(num: number) { + async getSingleScreenNotifies(number: number, startSeq = '') { invoke(ReceiveCmdS.GROUP_NOTIFY, [], { registerEvent: true }) + return (await invoke( 'nodeIKernelGroupService/getSingleScreenNotifies', - [{ doubt: false, startSeq: '', number: num }, null], + [{ doubt: false, startSeq, number }], { cbCmd: ReceiveCmdS.GROUP_NOTIFY, afterFirstCmd: false, @@ -122,68 +107,35 @@ export class NTQQGroupApi extends Service { const groupCode = flagitem[0] const seq = flagitem[1] const type = parseInt(flagitem[2]) - const session = getSession() - if (session) { - return session.getGroupService().operateSysNotify(false, { - operateType, // 2 拒绝 + return await invoke(NTMethod.HANDLE_GROUP_REQUEST, [{ + doubt: false, + operateMsg: { + operateType, targetMsg: { - seq, // 通知序列号 + seq, type, groupCode, postscript: reason || ' ' // 仅传空值可能导致处理失败,故默认给个空格 - } - }) - } else { - return await invoke(NTMethod.HANDLE_GROUP_REQUEST, [{ - doubt: false, - operateMsg: { - operateType, - targetMsg: { - seq, - type, - groupCode, - postscript: reason || ' ' // 仅传空值可能导致处理失败,故默认给个空格 - }, }, - }, null]) - } + }, + }]) } async quitGroup(groupCode: string) { - const session = getSession() - if (session) { - return session.getGroupService().quitGroup(groupCode) - } else { - return await invoke(NTMethod.QUIT_GROUP, [{ groupCode }, null]) - } + return await invoke(NTMethod.QUIT_GROUP, [{ groupCode }]) } async kickMember(groupCode: string, kickUids: string[], refuseForever = false, kickReason = '') { - const session = getSession() - if (session) { - return session.getGroupService().kickMember(groupCode, kickUids, refuseForever, kickReason) - } else { - return await invoke(NTMethod.KICK_MEMBER, [{ groupCode, kickUids, refuseForever, kickReason }]) - } + return await invoke(NTMethod.KICK_MEMBER, [{ groupCode, kickUids, refuseForever, kickReason }]) } + /** timeStamp为秒数, 0为解除禁言 */ async banMember(groupCode: string, memList: Array<{ uid: string, timeStamp: number }>) { - // timeStamp为秒数, 0为解除禁言 - const session = getSession() - if (session) { - return session.getGroupService().setMemberShutUp(groupCode, memList) - } else { - return await invoke(NTMethod.MUTE_MEMBER, [{ groupCode, memList }]) - } + return await invoke(NTMethod.MUTE_MEMBER, [{ groupCode, memList }]) } async banGroup(groupCode: string, shutUp: boolean) { - const session = getSession() - if (session) { - return session.getGroupService().setGroupShutUp(groupCode, shutUp) - } else { - return await invoke(NTMethod.MUTE_GROUP, [{ groupCode, shutUp }, null]) - } + return await invoke(NTMethod.MUTE_GROUP, [{ groupCode, shutUp }]) } async setMemberCard(groupCode: string, memberUid: string, cardName: string) { @@ -191,7 +143,7 @@ export class NTQQGroupApi extends Service { if (session) { return session.getGroupService().modifyMemberCardName(groupCode, memberUid, cardName) } else { - return await invoke(NTMethod.SET_MEMBER_CARD, [{ groupCode, uid: memberUid, cardName }, null]) + return await invoke(NTMethod.SET_MEMBER_CARD, [{ groupCode, uid: memberUid, cardName }]) } } @@ -200,21 +152,16 @@ export class NTQQGroupApi extends Service { if (session) { return session.getGroupService().modifyMemberRole(groupCode, memberUid, role) } else { - return await invoke(NTMethod.SET_MEMBER_ROLE, [{ groupCode, uid: memberUid, role }, null]) + return await invoke(NTMethod.SET_MEMBER_ROLE, [{ groupCode, uid: memberUid, role }]) } } async setGroupName(groupCode: string, groupName: string) { - const session = getSession() - if (session) { - return session.getGroupService().modifyGroupName(groupCode, groupName, false) - } else { - return await invoke(NTMethod.SET_GROUP_NAME, [{ groupCode, groupName }, null]) - } + return await invoke(NTMethod.SET_GROUP_NAME, [{ groupCode, groupName }]) } async getGroupRemainAtTimes(groupCode: string) { - return await invoke(NTMethod.GROUP_AT_ALL_REMAIN_COUNT, [{ groupCode }, null]) + return await invoke(NTMethod.GROUP_AT_ALL_REMAIN_COUNT, [{ groupCode }]) } async removeGroupEssence(groupCode: string, msgId: string) { @@ -235,7 +182,7 @@ export class NTQQGroupApi extends Service { msgRandom: Number(data?.msgList[0].msgRandom), msgSeq: Number(data?.msgList[0].msgSeq) } - }, null]) + }]) } } @@ -257,33 +204,30 @@ export class NTQQGroupApi extends Service { msgRandom: Number(data?.msgList[0].msgRandom), msgSeq: Number(data?.msgList[0].msgSeq) } - }, null]) + }]) } } async createGroupFileFolder(groupId: string, folderName: string) { - return await invoke('nodeIKernelRichMediaService/createGroupFolder', [{ groupId, folderName }, null]) + return await invoke('nodeIKernelRichMediaService/createGroupFolder', [{ groupId, folderName }]) } async deleteGroupFileFolder(groupId: string, folderId: string) { - return await invoke('nodeIKernelRichMediaService/deleteGroupFolder', [{ groupId, folderId }, null]) + return await invoke('nodeIKernelRichMediaService/deleteGroupFolder', [{ groupId, folderId }]) } async deleteGroupFile(groupId: string, fileIdList: string[], busIdList: number[]) { - return await invoke('nodeIKernelRichMediaService/deleteGroupFile', [{ groupId, busIdList, fileIdList }, null]) + return await invoke('nodeIKernelRichMediaService/deleteGroupFile', [{ groupId, busIdList, fileIdList }]) } async getGroupFileList(groupId: string, fileListForm: GetFileListParam) { invoke('nodeIKernelMsgListener/onGroupFileInfoUpdate', [], { registerEvent: true }) const data = await invoke<{ fileInfo: GroupFileInfo }>( 'nodeIKernelRichMediaService/getGroupFileList', - [ - { - groupId, - fileListForm - }, - null, - ], + [{ + groupId, + fileListForm + }], { cbCmd: 'nodeIKernelMsgListener/onGroupFileInfoUpdate', afterFirstCmd: false, @@ -296,17 +240,17 @@ export class NTQQGroupApi extends Service { async publishGroupBulletin(groupCode: string, req: PublishGroupBulletinReq) { const ntUserApi = this.ctx.get('ntUserApi')! const psKey = (await ntUserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com')! - return await invoke('nodeIKernelGroupService/publishGroupBulletin', [{ groupCode, psKey, req }, null]) + return await invoke('nodeIKernelGroupService/publishGroupBulletin', [{ groupCode, psKey, req }]) } async uploadGroupBulletinPic(groupCode: string, path: string) { const ntUserApi = this.ctx.get('ntUserApi')! const psKey = (await ntUserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com')! - return await invoke('nodeIKernelGroupService/uploadGroupBulletinPic', [{ groupCode, psKey, path }, null]) + return await invoke('nodeIKernelGroupService/uploadGroupBulletinPic', [{ groupCode, psKey, path }]) } async getGroupRecommendContact(groupCode: string) { - const ret = await invoke('nodeIKernelGroupService/getGroupRecommendContactArkJson', [{ groupCode }, null]) + const ret = await invoke('nodeIKernelGroupService/getGroupRecommendContactArkJson', [{ groupCode }]) return ret.arkJson } @@ -317,7 +261,7 @@ export class NTQQGroupApi extends Service { msgSeq: +msgSeq, msgRandom: +msgRandom } - }, null]) + }]) } async getGroupHonorList(groupCode: string) { @@ -326,31 +270,33 @@ export class NTQQGroupApi extends Service { req: { groupCode: [+groupCode] } - }, null]) + }]) } - async getGroupAllInfo(groupCode: string, timeout = 1000) { - invoke('nodeIKernelGroupListener/onGroupAllInfoChange', [], { registerEvent: true }) + async getGroupAllInfo(groupCode: string) { + invoke('nodeIKernelGroupListener/onGroupAllInfoChange', [], { + registerEvent: true + }) + return await invoke<{ groupAll: GroupAllInfo }>( 'nodeIKernelGroupService/getGroupAllInfo', - [ - { - groupCode, - source: 4 - }, - null - ], + [{ + groupCode, + source: 4 + }], { cbCmd: 'nodeIKernelGroupListener/onGroupAllInfoChange', afterFirstCmd: false, - cmdCB: payload => payload.groupAll.groupCode === groupCode, - timeout + cmdCB: payload => payload.groupAll.groupCode === groupCode } ) } async getGroupBulletinList(groupCode: string) { - invoke('nodeIKernelGroupListener/onGetGroupBulletinListResult', [], { registerEvent: true }) + invoke('nodeIKernelGroupListener/onGetGroupBulletinListResult', [], { + registerEvent: true + }) + const ntUserApi = this.ctx.get('ntUserApi')! const psKey = (await ntUserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com')! return await invoke<{ @@ -377,4 +323,8 @@ export class NTQQGroupApi extends Service { } ) } + + async setGroupAvatar(groupCode: string, path: string) { + return await invoke('nodeIKernelGroupService/setHeader', [{ path, groupCode }]) + } } diff --git a/src/ntqqapi/api/msg.ts b/src/ntqqapi/api/msg.ts index 4207a10..9af3862 100644 --- a/src/ntqqapi/api/msg.ts +++ b/src/ntqqapi/api/msg.ts @@ -1,7 +1,5 @@ import { invoke, NTMethod } from '../ntcall' -import { GeneralCallResult } from '../services' import { RawMessage, SendMessageElement, Peer, ChatType } from '../types' -import { getSession } from '@/ntqqapi/wrapper' import { Service, Context } from 'cordis' import { selfInfo } from '@/common/globalVars' @@ -19,37 +17,27 @@ export class NTQQMsgApi extends Service { } async getTempChatInfo(chatType: ChatType, peerUid: string) { - const session = getSession() - if (session) { - return session.getMsgService().getTempChatInfo(chatType, peerUid) - } else { - return await invoke('nodeIKernelMsgService/getTempChatInfo', [{ chatType, peerUid }, null]) - } + return await invoke('nodeIKernelMsgService/getTempChatInfo', [{ chatType, peerUid }]) } async setEmojiLike(peer: Peer, msgSeq: string, emojiId: string, setEmoji: boolean) { - // nt_qq//global//nt_data//Emoji//emoji-resource//sysface_res/apng/ 下可以看到所有QQ表情预览 - // nt_qq\global\nt_data\Emoji\emoji-resource\face_config.json 里面有所有表情的id, 自带表情id是QSid, 标准emoji表情id是QCid + // nt_qq/global/nt_data/Emoji/emoji-resource/sysface_res/apng/ 下可以看到所有QQ表情预览 + // nt_qq/global/nt_data/Emoji/emoji-resource/face_config.json 里面有所有表情的id, 自带表情id是QSid, 标准emoji表情id是QCid // 其实以官方文档为准是最好的,https://bot.q.qq.com/wiki/develop/api-v2/openapi/emoji/model.html#EmojiType const emojiType = emojiId.length > 3 ? '2' : '1' return await invoke(NTMethod.EMOJI_LIKE, [{ peer, msgSeq, emojiId, emojiType, setEmoji }]) } async getMultiMsg(peer: Peer, rootMsgId: string, parentMsgId: string) { - const session = getSession() - if (session) { - return session.getMsgService().getMultiMsg(peer, rootMsgId, parentMsgId) - } else { - return await invoke(NTMethod.GET_MULTI_MSG, [{ peer, rootMsgId, parentMsgId }, null]) - } + return await invoke(NTMethod.GET_MULTI_MSG, [{ peer, rootMsgId, parentMsgId }]) } async activateChat(peer: Peer) { - return await invoke(NTMethod.ACTIVE_CHAT_PREVIEW, [{ peer, cnt: 1 }, null]) + return await invoke(NTMethod.ACTIVE_CHAT_PREVIEW, [{ peer, cnt: 1 }]) } - async activateChatAndGetHistory(peer: Peer) { - return await invoke(NTMethod.ACTIVE_CHAT_HISTORY, [{ peer, cnt: 20 }, null]) + async activateChatAndGetHistory(peer: Peer, cnt: number) { + return await invoke(NTMethod.ACTIVE_CHAT_HISTORY, [{ peer, cnt, msgId: '0', queryOrder: true }]) } async getAioFirstViewLatestMsgs(peer: Peer, cnt: number) { @@ -62,9 +50,9 @@ export class NTQQMsgApi extends Service { return await invoke('nodeIKernelMsgService/getMsgsByMsgId', [{ peer, msgIds }]) } - async getMsgHistory(peer: Peer, msgId: string, cnt: number, isReverseOrder: boolean = false) { - // 消息时间从旧到新 - return await invoke(NTMethod.HISTORY_MSG, [{ peer, msgId, cnt, queryOrder: isReverseOrder }]) + async getMsgHistory(peer: Peer, msgId: string, cnt: number, queryOrder = false) { + // 默认情况下消息时间从旧到新 + return await invoke(NTMethod.HISTORY_MSG, [{ peer, msgId, cnt, queryOrder }]) } async recallMsg(peer: Peer, msgIds: string[]) { @@ -96,6 +84,7 @@ export class NTQQMsgApi extends Service { timeout } ) + delete peer.guildId return data.msgList.find(msgRecord => msgRecord.guildId === uniqueId) } @@ -124,6 +113,7 @@ export class NTQQMsgApi extends Service { } } ) + delete destPeer.guildId return data.msgList.filter(msgRecord => msgRecord.guildId === uniqueId) } @@ -171,27 +161,8 @@ export class NTQQMsgApi extends Service { throw new Error('转发消息超时') } - async getMsgsBySeqAndCount(peer: Peer, msgSeq: string, count: number, desc: boolean, z: boolean) { - const session = getSession() - if (session) { - return await session.getMsgService().getMsgsBySeqAndCount(peer, msgSeq, count, desc, z) - } else { - return await invoke('nodeIKernelMsgService/getMsgsBySeqAndCount', [{ - peer, - cnt: count, - msgSeq, - queryOrder: desc - }, null]) - } - } - async getSingleMsg(peer: Peer, msgSeq: string) { - const session = getSession() - if (session) { - return await session.getMsgService().getSingleMsg(peer, msgSeq) - } else { - return await invoke('nodeIKernelMsgService/getSingleMsg', [{ peer, msgSeq }, null]) - } + return await invoke('nodeIKernelMsgService/getSingleMsg', [{ peer, msgSeq }]) } async queryFirstMsgBySeq(peer: Peer, msgSeq: string) { @@ -209,7 +180,7 @@ export class NTQQMsgApi extends Service { isIncludeCurrent: true, pageLimit: 1, } - }, null]) + }]) } async queryMsgsWithFilterExBySeq(peer: Peer, msgSeq: string, filterMsgTime: string, filterSendersUid: string[] = []) { @@ -231,7 +202,7 @@ export class NTQQMsgApi extends Service { } async setMsgRead(peer: Peer) { - return await invoke('nodeIKernelMsgService/setMsgRead', [{ peer }, null]) + return await invoke('nodeIKernelMsgService/setMsgRead', [{ peer }]) } async getMsgEmojiLikesList(peer: Peer, msgSeq: string, emojiId: string, emojiType: string, count: number) { @@ -250,7 +221,7 @@ export class NTQQMsgApi extends Service { count, backwardFetch: true, forceRefresh: true - }, null]) + }]) } async generateMsgUniqueId(chatType: number) { @@ -289,6 +260,6 @@ export class NTQQMsgApi extends Service { } async getServerTime() { - return await invoke('nodeIKernelMSFService/getServerTime', [null]) + return await invoke('nodeIKernelMSFService/getServerTime', []) } } diff --git a/src/ntqqapi/api/user.ts b/src/ntqqapi/api/user.ts index 22cce9f..3d245b8 100644 --- a/src/ntqqapi/api/user.ts +++ b/src/ntqqapi/api/user.ts @@ -1,7 +1,6 @@ import { User, UserDetailInfoByUin, UserDetailInfoByUinV2, UserDetailInfo, UserDetailSource, ProfileBizType, SimpleInfo } from '../types' import { invoke } from '../ntcall' import { getBuildVersion } from '@/common/utils' -import { getSession } from '@/ntqqapi/wrapper' import { RequestUtil } from '@/common/utils/request' import { isNullable, Time } from 'cosmokit' import { Service, Context } from 'cordis' @@ -20,15 +19,12 @@ export class NTQQUserApi extends Service { super(ctx, 'ntUserApi', true) } - async setQQAvatar(path: string) { + async setSelfAvatar(path: string) { return await invoke( 'nodeIKernelProfileService/setHeader', - [ - { path }, - null, - ], + [{ path }], { - timeout: 10 * Time.second, // 10秒不一定够 + timeout: 10 * Time.second // 10秒不一定够 } ) } @@ -92,49 +88,25 @@ export class NTQQUserApi extends Service { } async getPSkey(domains: string[]) { - return await invoke('nodeIKernelTipOffService/getPskey', [{ domains, isForNewPCQQ: true }, null]) + return await invoke('nodeIKernelTipOffService/getPskey', [{ domains, isForNewPCQQ: true }]) } async like(uid: string, count = 1) { - const session = getSession() - if (session) { - return session.getProfileLikeService().setBuddyProfileLike({ - friendUid: uid, - sourceId: 71, - doLikeCount: count, - doLikeTollCount: 0 - }) - } else { - return await invoke( - 'nodeIKernelProfileLikeService/setBuddyProfileLike', - [ - { - doLikeUserInfo: { - friendUid: uid, - sourceId: 71, - doLikeCount: count, - doLikeTollCount: 0 - } - }, - null, - ], - ) - } + return await invoke( + 'nodeIKernelProfileLikeService/setBuddyProfileLike', + [{ + doLikeUserInfo: { + friendUid: uid, + sourceId: 71, + doLikeCount: count, + doLikeTollCount: 0 + } + }] + ) } - async getUidByUinV1(uin: string) { + async getUidByUinV1(uin: string, groupCode?: string) { let uid = (await invoke('nodeIKernelUixConvertService/getUid', [{ uins: [uin] }])).uidInfo.get(uin) - if (!uid) { - for (const membersList of this.ctx.ntGroupApi.groupMembers.values()) { //从群友列表转 - for (const member of membersList.values()) { - if (member.uin === uin) { - uid = member.uid - break - } - } - if (uid) break - } - } if (!uid) { const unveifyUid = (await this.getUserDetailInfoByUin(uin)).info.uid //特殊转换 if (unveifyUid.indexOf('*') === -1) { @@ -145,29 +117,30 @@ export class NTQQUserApi extends Service { const friends = await this.ctx.ntFriendApi.getFriends() //从好友列表转 uid = friends.find(item => item.uin === uin)?.uid } + if (!uid && groupCode) { + const members = await this.ctx.ntGroupApi.getGroupMembers(groupCode) + uid = Array.from(members.values()).find(e => e.uin === uin)?.uid + } return uid } - async getUidByUinV2(uin: string, groupCode?: string) { - let uid = (await invoke('nodeIKernelGroupService/getUidByUins', [{ uin: [uin] }])).uids.get(uin) + async getUidByUinV2(uin: string) { + let uid = (await invoke('nodeIKernelGroupService/getUidByUins', [{ uinList: [uin] }])).uids.get(uin) if (uid) return uid uid = (await invoke('nodeIKernelProfileService/getUidByUin', [{ callFrom: 'FriendsServiceImpl', uin: [uin] }])).get(uin) if (uid) return uid uid = (await invoke('nodeIKernelUixConvertService/getUid', [{ uins: [uin] }])).uidInfo.get(uin) if (uid) return uid const unveifyUid = (await this.getUserDetailInfoByUinV2(uin)).detail.uid - if (!unveifyUid.includes('*')) return unveifyUid - if (groupCode) { - const member = await this.ctx.ntGroupApi.getGroupMember(groupCode, uin) - return member?.uid - } + //if (!unveifyUid.includes('*')) return unveifyUid + return unveifyUid } async getUidByUin(uin: string, groupCode?: string) { if (getBuildVersion() >= 26702) { - return this.getUidByUinV2(uin, groupCode) + return this.getUidByUinV2(uin) } - return this.getUidByUinV1(uin) + return this.getUidByUinV1(uin, groupCode) } async getUserDetailInfoByUinV2(uin: string) { @@ -194,7 +167,7 @@ export class NTQQUserApi extends Service { } async getUinByUidV2(uid: string) { - let uin = (await invoke('nodeIKernelGroupService/getUinByUids', [{ uid: [uid] }])).uins.get(uid) + let uin = (await invoke('nodeIKernelGroupService/getUinByUids', [{ uidList: [uid] }])).uins.get(uid) if (uin) return uin uin = (await invoke('nodeIKernelProfileService/getUinByUid', [{ callFrom: 'FriendsServiceImpl', uid: [uid] }])).get(uid) if (uin) return uin @@ -214,18 +187,13 @@ export class NTQQUserApi extends Service { } async forceFetchClientKey() { - const session = getSession() - if (session) { - return await session.getTicketService().forceFetchClientKey('') - } else { - return await invoke('nodeIKernelTicketService/forceFetchClientKey', [{ url: '' }, null]) - } + return await invoke('nodeIKernelTicketService/forceFetchClientKey', [{ url: '' }]) } async getSelfNick(refresh = true) { if ((refresh || !selfInfo.nick) && selfInfo.uid) { - const { profiles } = await this.getUserSimpleInfo(selfInfo.uid) - selfInfo.nick = profiles[selfInfo.uid].coreInfo.nick + const data = await this.getUserSimpleInfo(selfInfo.uid) + selfInfo.nick = data.coreInfo.nick } return selfInfo.nick } @@ -237,7 +205,7 @@ export class NTQQUserApi extends Service { extStatus, batteryStatus, } - }, null]) + }]) } async getProfileLike(uid: string) { @@ -252,11 +220,11 @@ export class NTQQUserApi extends Service { start: 0, limit: 20, } - }, null]) + }]) } async getUserSimpleInfo(uid: string, force = true) { - return await invoke<{ profiles: Record }>( + const data = await invoke<{ profiles: Record }>( 'nodeIKernelProfileService/getUserSimpleInfo', [{ uids: [uid], @@ -268,6 +236,7 @@ export class NTQQUserApi extends Service { cmdCB: payload => !isNullable(payload.profiles[uid]), } ) + return data.profiles[uid] } async getCoreAndBaseInfo(uids: string[]) { diff --git a/src/ntqqapi/api/window.ts b/src/ntqqapi/api/window.ts index e63be71..2b485aa 100644 --- a/src/ntqqapi/api/window.ts +++ b/src/ntqqapi/api/window.ts @@ -35,7 +35,7 @@ export class NTQQWindowApi extends Service { super(ctx, 'ntWindowApi', true) } - // 打开窗口并获取对应的下发事件 + /** 打开窗口并获取对应的下发事件 */ async openWindow( ntQQWindow: NTQQWindow, args: unknown[], @@ -53,7 +53,6 @@ export class NTQQWindowApi extends Service { ) setTimeout(() => { for (const w of BrowserWindow.getAllWindows()) { - // log("close window", w.webContents.getURL()) if (w.webContents.getURL().indexOf(ntQQWindow.windowUrlHash) != -1) { w.close() } diff --git a/src/ntqqapi/entities.ts b/src/ntqqapi/entities.ts index 64d0bd2..eafcea5 100644 --- a/src/ntqqapi/entities.ts +++ b/src/ntqqapi/entities.ts @@ -52,15 +52,15 @@ export namespace SendElement { } } - export function reply(msgSeq: string, msgId: string, senderUin: string, senderUinStr: string): SendReplyElement { + export function reply(msgSeq: string, msgId: string, senderUin: string): SendReplyElement { return { elementType: ElementType.Reply, elementId: '', replyElement: { - replayMsgSeq: msgSeq, // raw.msgSeq - replayMsgId: msgId, // raw.msgId + replayMsgSeq: msgSeq, + replayMsgId: msgId, senderUin: senderUin, - senderUinStr: senderUinStr, + senderUinStr: senderUin, }, } } @@ -251,19 +251,19 @@ export namespace SendElement { } } - export function face(faceId: number): SendFaceElement { + export function face(faceId: number, faceType?: number): SendFaceElement { // 从face_config.json中获取表情名称 const sysFaces = faceConfig.sysface - const emojiFaces = faceConfig.emoji - const face = sysFaces.find((face) => face.QSid === faceId.toString()) - faceId = parseInt(faceId.toString()) - // let faceType = parseInt(faceId.toString().substring(0, 1)); - let faceType = 1 - if (faceId >= 222) { - faceType = 2 - } - if (face?.AniStickerType) { - faceType = 3; + const face = sysFaces.find(face => face.QSid === String(faceId)) + if (!faceType) { + if (faceId < 222) { + faceType = 1 + } else { + faceType = 2 + } + if (face?.AniStickerType) { + faceType = 3 + } } return { elementType: ElementType.Face, diff --git a/src/ntqqapi/helper/face_config.json b/src/ntqqapi/helper/face_config.json index 84bb8fe..da7890a 100644 --- a/src/ntqqapi/helper/face_config.json +++ b/src/ntqqapi/helper/face_config.json @@ -1,5 +1,15 @@ { "sysface": [ + { + "QSid": "419", + "QDes": "/火车", + "IQLid": "419", + "AQLid": "419", + "EMCode": "10419", + "AniStickerType": 3, + "AniStickerPackId": "1", + "AniStickerId": "47" + }, { "QSid": "392", "QDes": "/龙年快乐", @@ -3662,4 +3672,4 @@ "EMCode": "401016" } ] -} \ No newline at end of file +} diff --git a/src/ntqqapi/services/NodeIKernelGroupService.ts b/src/ntqqapi/services/NodeIKernelGroupService.ts index 4247a4b..cf37bd9 100644 --- a/src/ntqqapi/services/NodeIKernelGroupService.ts +++ b/src/ntqqapi/services/NodeIKernelGroupService.ts @@ -123,4 +123,6 @@ export interface NodeIKernelGroupService { addGroupEssence(param: { groupCode: string, msgRandom: number, msgSeq: number }): Promise removeGroupEssence(param: { groupCode: string, msgRandom: number, msgSeq: number }): Promise + + setHeader(args: unknown[]): Promise } diff --git a/src/ntqqapi/services/NodeIKernelMsgService.ts b/src/ntqqapi/services/NodeIKernelMsgService.ts index af6276a..e1881eb 100644 --- a/src/ntqqapi/services/NodeIKernelMsgService.ts +++ b/src/ntqqapi/services/NodeIKernelMsgService.ts @@ -20,6 +20,10 @@ export interface NodeIKernelMsgService { getAioFirstViewLatestMsgs(peer: Peer, num: number): Promise + getAioFirstViewLatestMsgsAndAddActiveChat(...args: unknown[]): Promise + + getMsgsIncludeSelfAndAddActiveChat(...args: unknown[]): Promise + getMsgsIncludeSelf(peer: Peer, msgId: string, count: number, queryOrder: boolean): Promise getMsgsBySeqAndCount(peer: Peer, seq: string, count: number, desc: boolean, unknownArg: boolean): Promise diff --git a/src/ntqqapi/services/NodeIKernelProfileLikeService.ts b/src/ntqqapi/services/NodeIKernelProfileLikeService.ts index 5d98f8e..9551e9e 100644 --- a/src/ntqqapi/services/NodeIKernelProfileLikeService.ts +++ b/src/ntqqapi/services/NodeIKernelProfileLikeService.ts @@ -3,7 +3,7 @@ import { GeneralCallResult } from './common' import { Dict } from 'cosmokit' export interface NodeIKernelProfileLikeService { - setBuddyProfileLike(...args: unknown[]): { result: number, errMsg: string, succCounts: number } + setBuddyProfileLike(...args: unknown[]): GeneralCallResult & { succCounts: number } getBuddyProfileLike(req: BuddyProfileLikeReq): Promise + members: Map // uid -> remark } jsonGrayTipElement?: { busiId: string @@ -241,7 +297,6 @@ export interface GrayTipElement { } } - export enum FaceIndex { Dice = 358, RPS = 359, // 石头剪刀布 @@ -268,6 +323,10 @@ export interface MarketFaceElement { key: string imageWidth?: number imageHeight?: number + supportSize?: { + width: number + height: number + }[] } export interface VideoElement { @@ -326,58 +385,6 @@ export interface InlineKeyboardElement { ] } -export interface TipAioOpGrayTipElement { - // 这是什么提示来着? - operateType: number - peerUid: string - fromGrpCodeOfTmpChat: string -} - -export enum TipGroupElementType { - MemberIncrease = 1, - Kicked = 3, // 被移出群 - Ban = 8, -} - -export interface TipGroupElement { - type: TipGroupElementType // 1是表示有人加入群, 自己加入群也会收到这个 - role: 0 // 暂时不知 - groupName: string // 暂时获取不到 - memberUid: string - memberNick: string - memberRemark: string - adminUid: string - adminNick: string - adminRemark: string - createGroup: null - memberAdd?: { - showType: 1 - otherAdd: null - otherAddByOtherQRCode: null - otherAddByYourQRCode: null - youAddByOtherQRCode: null - otherInviteOther: null - otherInviteYou: null - youInviteOther: null - } - shutUp?: { - curTime: string - duration: string // 禁言时间,秒 - admin: { - uid: string - card: string - name: string - role: GroupMemberRole - } - member: { - uid: string - card: string - name: string - role: GroupMemberRole - } - } -} - export interface StructLongMsgElement { xmlContent: string resId: string @@ -409,11 +416,25 @@ export interface RawMessage { guildId: string sendNickName: string sendMemberName?: string // 发送者群名片 + sendRemarkName?: string // 发送者好友备注 chatType: ChatType sendStatus?: number // 消息状态,别人发的2是已撤回,自己发的2是已发送 recallTime: string // 撤回时间, "0"是没有撤回 records: RawMessage[] elements: MessageElement[] + peerName: string + multiTransInfo?: { + status: number + msgId: number + friendFlag: number + fromFaceUrl: string + } + emojiLikesList: { + emojiId: string + emojiType: string + likesCnt: string + isClicked: boolean + }[] } export interface Peer { diff --git a/src/ntqqapi/types/notify.ts b/src/ntqqapi/types/notify.ts index cdf5189..0f2d466 100644 --- a/src/ntqqapi/types/notify.ts +++ b/src/ntqqapi/types/notify.ts @@ -1,19 +1,19 @@ export enum GroupNotifyType { - INVITED_BY_MEMBER = 1, - REFUSE_INVITED, - REFUSED_BY_ADMINI_STRATOR, - AGREED_TOJOIN_DIRECT, // 有人接受了邀请入群 - INVITED_NEED_ADMINI_STRATOR_PASS, // 有人邀请了别人入群 - AGREED_TO_JOIN_BY_ADMINI_STRATOR, - REQUEST_JOIN_NEED_ADMINI_STRATOR_PASS, - SET_ADMIN, - KICK_MEMBER_NOTIFY_ADMIN, - KICK_MEMBER_NOTIFY_KICKED, - MEMBER_LEAVE_NOTIFY_ADMIN, // 主动退出 - CANCEL_ADMIN_NOTIFY_CANCELED, // 我被取消管理员 - CANCEL_ADMIN_NOTIFY_ADMIN, // 其他人取消管理员 - TRANSFER_GROUP_NOTIFY_OLDOWNER, - TRANSFER_GROUP_NOTIFY_ADMIN + InvitedByMember = 1, + RefuseInvited, + RefusedByAdminiStrator, + AgreedTojoinDirect, // 有人接受了邀请入群 + InvitedNeedAdminiStratorPass, // 有人邀请了别人入群 + AgreedToJoinByAdminiStrator, + RequestJoinNeedAdminiStratorPass, + SetAdmin, + KickMemberNotifyAdmin, + KickMemberNotifyKicked, + MemberLeaveNotifyAdmin, // 主动退出 + CancelAdminNotifyCanceled, // 我被取消管理员 + CancelAdminNotifyAdmin, // 其他人取消管理员 + TransferGroupNotifyOldowner, + TransferGroupNotifyAdmin } export interface GroupNotifies { @@ -23,11 +23,11 @@ export interface GroupNotifies { } export enum GroupNotifyStatus { - KINIT, // 初始化 - KUNHANDLE, // 未处理 - KAGREED, // 同意 - KREFUSED, // 拒绝 - KIGNORED // 忽略 + Init, // 初始化 + Unhandle, // 未处理 + Agreed, // 同意 + Refused, // 拒绝 + Ignored // 忽略 } export interface GroupNotify { @@ -79,41 +79,3 @@ export interface FriendRequestNotify { buddyReqs: FriendRequest[] } } - -export enum MemberExtSourceType { - DEFAULTTYPE = 0, - TITLETYPE = 1, - NEWGROUPTYPE = 2, -} - -export interface GroupExtParam { - groupCode: string - seq: string - beginUin: string - dataTime: string - uinList: Array - uinNum: string - groupType: string - richCardNameVer: string - sourceType: MemberExtSourceType - memberExtFilter: { - memberLevelInfoUin: number - memberLevelInfoPoint: number - memberLevelInfoActiveDay: number - memberLevelInfoLevel: number - memberLevelInfoName: number - levelName: number - dataTime: number - userShowFlag: number - sysShowFlag: number - timeToUpdate: number - nickName: number - specialTitle: number - levelNameNew: number - userShowFlagNew: number - msgNeedField: number - cmdUinFlagExt3Grocery: number - memberIcon: number - memberInfoSeq: number - } -} diff --git a/src/onebot11/action/go-cqhttp/GetGroupFileUrl.ts b/src/onebot11/action/go-cqhttp/GetGroupFileUrl.ts index 78942f2..2a489b6 100644 --- a/src/onebot11/action/go-cqhttp/GetGroupFileUrl.ts +++ b/src/onebot11/action/go-cqhttp/GetGroupFileUrl.ts @@ -50,7 +50,7 @@ export class GetGroupFileUrl extends BaseAction { private async search(groupId: string, fileId: string, folderId?: string) { let modelId: string | undefined let nextIndex: number | undefined - let folders: GroupFileInfo['item'] = [] + const folders: GroupFileInfo['item'] = [] while (nextIndex !== 0) { const res = await this.ctx.ntGroupApi.getGroupFileList(groupId, { sortType: 1, diff --git a/src/onebot11/action/go-cqhttp/GetGroupSystemMsg.ts b/src/onebot11/action/go-cqhttp/GetGroupSystemMsg.ts index 6ccf040..e22d12c 100644 --- a/src/onebot11/action/go-cqhttp/GetGroupSystemMsg.ts +++ b/src/onebot11/action/go-cqhttp/GetGroupSystemMsg.ts @@ -38,7 +38,7 @@ export class GetGroupSystemMsg extends BaseAction { invitor_nick: notify.user1.nickName, group_id: +notify.group.groupCode, group_name: notify.group.groupName, - checked: notify.status !== GroupNotifyStatus.KUNHANDLE, + checked: notify.status !== GroupNotifyStatus.Unhandle, actor: notify.user2?.uid ? Number(await this.ctx.ntUserApi.getUinByUid(notify.user2.uid)) : 0 }) } else if (notify.type == 7) { @@ -49,7 +49,7 @@ export class GetGroupSystemMsg extends BaseAction { message: notify.postscript, group_id: +notify.group.groupCode, group_name: notify.group.groupName, - checked: notify.status !== GroupNotifyStatus.KUNHANDLE, + checked: notify.status !== GroupNotifyStatus.Unhandle, actor: notify.user2?.uid ? Number(await this.ctx.ntUserApi.getUinByUid(notify.user2.uid)) : 0 }) } diff --git a/src/onebot11/action/go-cqhttp/SendGroupNotice.ts b/src/onebot11/action/go-cqhttp/SendGroupNotice.ts index c1575f0..59a84fa 100644 --- a/src/onebot11/action/go-cqhttp/SendGroupNotice.ts +++ b/src/onebot11/action/go-cqhttp/SendGroupNotice.ts @@ -28,7 +28,7 @@ export class SendGroupNotice extends BaseAction { let picInfo: { id: string, width: number, height: number } | undefined if (payload.image) { - const { path, isLocal, success, errMsg } = await uri2local(payload.image, undefined, true) + const { path, isLocal, success, errMsg } = await uri2local(this.ctx, payload.image, true) if (!success) { throw new Error(`设置群公告失败, 错误信息: uri2local: ${errMsg}`) } diff --git a/src/onebot11/action/go-cqhttp/UploadGroupFile.ts b/src/onebot11/action/go-cqhttp/UploadGroupFile.ts index 72cc3ad..80c4a99 100644 --- a/src/onebot11/action/go-cqhttp/UploadGroupFile.ts +++ b/src/onebot11/action/go-cqhttp/UploadGroupFile.ts @@ -23,7 +23,7 @@ export class UploadGroupFile extends BaseAction { }) protected async _handle(payload: Payload): Promise { - const { success, errMsg, path, fileName } = await uri2local(payload.file) + const { success, errMsg, path, fileName } = await uri2local(this.ctx, payload.file) if (!success) { throw new Error(errMsg) } diff --git a/src/onebot11/action/go-cqhttp/UploadPrivateFile.ts b/src/onebot11/action/go-cqhttp/UploadPrivateFile.ts index 7c1c07c..79e4fa5 100644 --- a/src/onebot11/action/go-cqhttp/UploadPrivateFile.ts +++ b/src/onebot11/action/go-cqhttp/UploadPrivateFile.ts @@ -19,7 +19,7 @@ export class UploadPrivateFile extends BaseAction { - const { success, errMsg, path, fileName } = await uri2local(payload.file) + const { success, errMsg, path, fileName } = await uri2local(this.ctx, payload.file) if (!success) { throw new Error(errMsg) } diff --git a/src/onebot11/action/group/GetGroupMemberInfo.ts b/src/onebot11/action/group/GetGroupMemberInfo.ts index 8fe323c..211d5eb 100644 --- a/src/onebot11/action/group/GetGroupMemberInfo.ts +++ b/src/onebot11/action/group/GetGroupMemberInfo.ts @@ -18,7 +18,9 @@ class GetGroupMemberInfo extends BaseAction { protected async _handle(payload: Payload) { const groupCode = payload.group_id.toString() - const member = await this.ctx.ntGroupApi.getGroupMember(groupCode, payload.user_id.toString()) + const uid = await this.ctx.ntUserApi.getUidByUin(payload.user_id.toString()) + if (!uid) throw new Error('无法获取用户信息') + const member = await this.ctx.ntGroupApi.getGroupMember(groupCode, uid) if (member) { if (isNullable(member.sex)) { const info = await this.ctx.ntUserApi.getUserDetailInfo(member.uid) diff --git a/src/onebot11/action/llonebot/Debug.ts b/src/onebot11/action/llonebot/Debug.ts index 35ab94e..e0aa09b 100644 --- a/src/onebot11/action/llonebot/Debug.ts +++ b/src/onebot11/action/llonebot/Debug.ts @@ -16,10 +16,8 @@ export default class Debug extends BaseAction { for (const ntqqApiClass of ntqqApi) { const method = ntqqApiClass[payload.method as keyof typeof ntqqApiClass] if (method && method instanceof Function) { - const result = method.apply(ntqqApiClass, payload.args) - if (method.constructor.name === 'AsyncFunction') { - return await result - } + const result = await method.apply(ntqqApiClass, payload.args) + this.ctx.logger.info('debug', result) return result } } diff --git a/src/onebot11/action/llonebot/GetGroupAddRequest.ts b/src/onebot11/action/llonebot/GetGroupAddRequest.ts index 920cd39..07ccc8c 100644 --- a/src/onebot11/action/llonebot/GetGroupAddRequest.ts +++ b/src/onebot11/action/llonebot/GetGroupAddRequest.ts @@ -13,7 +13,7 @@ export default class GetGroupAddRequest extends BaseAction { const data = await this.ctx.ntGroupApi.getGroupIgnoreNotifies() - const notifies = data.notifies.filter(notify => notify.status === GroupNotifyStatus.KUNHANDLE) + const notifies = data.notifies.filter(notify => notify.status === GroupNotifyStatus.Unhandle) const returnData: OB11GroupRequestNotify[] = [] for (const notify of notifies) { const uin = await this.ctx.ntUserApi.getUinByUid(notify.user1.uid) diff --git a/src/onebot11/action/llonebot/SetQQAvatar.ts b/src/onebot11/action/llonebot/SetQQAvatar.ts index 0f8ed82..7c9351b 100644 --- a/src/onebot11/action/llonebot/SetQQAvatar.ts +++ b/src/onebot11/action/llonebot/SetQQAvatar.ts @@ -11,13 +11,13 @@ export default class SetAvatar extends BaseAction { actionName = ActionName.SetQQAvatar protected async _handle(payload: Payload): Promise { - const { path, isLocal, errMsg } = await uri2local(payload.file) + const { path, isLocal, errMsg } = await uri2local(this.ctx, payload.file) if (errMsg) { throw new Error(errMsg) } if (path) { await checkFileReceived(path, 5000) // 文件不存在QQ会崩溃,需要提前判断 - const ret = await this.ctx.ntUserApi.setQQAvatar(path) + const ret = await this.ctx.ntUserApi.setSelfAvatar(path) if (!isLocal) { unlink(path) } diff --git a/src/onebot11/adapter.ts b/src/onebot11/adapter.ts index 1c60dcd..45d6dce 100644 --- a/src/onebot11/adapter.ts +++ b/src/onebot11/adapter.ts @@ -4,10 +4,7 @@ import { GroupNotify, GroupNotifyType, RawMessage, - BuddyReqType, FriendRequest, - GroupMember, - GroupMemberRole, GroupNotifyStatus } from '../ntqqapi/types' import { OB11GroupRequestEvent } from './event/request/OB11GroupRequest' @@ -23,7 +20,6 @@ import { OB11BaseMetaEvent } from './event/meta/OB11BaseMetaEvent' import { postHttpEvent } from './helper/eventForHttp' import { initActionMap } from './action' import { llonebotError } from '../common/globalVars' -import { OB11GroupCardEvent } from './event/notice/OB11GroupCardEvent' import { OB11GroupAdminNoticeEvent } from './event/notice/OB11GroupAdminNoticeEvent' import { OB11ProfileLikeEvent } from './event/notice/OB11ProfileLikeEvent' import { SysMsg } from '@/ntqqapi/proto/compiled' @@ -35,8 +31,10 @@ declare module 'cordis' { } class OneBot11Adapter extends Service { - static inject = ['ntMsgApi', 'ntFileApi', 'ntFileCacheApi', 'ntFriendApi', 'ntGroupApi', 'ntUserApi', 'ntWindowApi', 'ntWebApi', 'store'] - + static inject = [ + 'ntMsgApi', 'ntFileApi', 'ntFileCacheApi', 'ntFriendApi', + 'ntGroupApi', 'ntUserApi', 'ntWindowApi', 'ntWebApi', 'store' + ] private ob11WebSocket: OB11WebSocket private ob11WebSocketReverseManager: OB11WebSocketReverseManager private ob11Http: OB11Http @@ -91,7 +89,7 @@ class OneBot11Adapter extends Service { private async handleGroupNotify(notify: GroupNotify) { try { const flag = notify.group.groupCode + '|' + notify.seq + '|' + notify.type - if ([GroupNotifyType.MEMBER_LEAVE_NOTIFY_ADMIN, GroupNotifyType.KICK_MEMBER_NOTIFY_ADMIN].includes(notify.type)) { + if ([GroupNotifyType.MemberLeaveNotifyAdmin, GroupNotifyType.KickMemberNotifyAdmin].includes(notify.type)) { this.ctx.logger.info('有成员退出通知', notify) const member1Uin = await this.ctx.ntUserApi.getUinByUid(notify.user1.uid) let operatorId = member1Uin @@ -112,7 +110,7 @@ class OneBot11Adapter extends Service { ) this.dispatch(event) } - else if (notify.type === GroupNotifyType.REQUEST_JOIN_NEED_ADMINI_STRATOR_PASS && notify.status === GroupNotifyStatus.KUNHANDLE) { + else if (notify.type === GroupNotifyType.RequestJoinNeedAdminiStratorPass && notify.status === GroupNotifyStatus.Unhandle) { this.ctx.logger.info('有加群请求') const requestUin = await this.ctx.ntUserApi.getUinByUid(notify.user1.uid) const event = new OB11GroupRequestEvent( @@ -123,7 +121,7 @@ class OneBot11Adapter extends Service { ) this.dispatch(event) } - else if (notify.type === GroupNotifyType.INVITED_BY_MEMBER && notify.status === GroupNotifyStatus.KUNHANDLE) { + else if (notify.type === GroupNotifyType.InvitedByMember && notify.status === GroupNotifyStatus.Unhandle) { this.ctx.logger.info('收到邀请我加群通知') const userId = await this.ctx.ntUserApi.getUinByUid(notify.user2.uid) const event = new OB11GroupRequestEvent( @@ -136,7 +134,7 @@ class OneBot11Adapter extends Service { ) this.dispatch(event) } - else if (notify.type === GroupNotifyType.INVITED_NEED_ADMINI_STRATOR_PASS && notify.status === GroupNotifyStatus.KUNHANDLE) { + else if (notify.type === GroupNotifyType.InvitedNeedAdminiStratorPass && notify.status === GroupNotifyStatus.Unhandle) { this.ctx.logger.info('收到群员邀请加群通知') const userId = await this.ctx.ntUserApi.getUinByUid(notify.user1.uid) const event = new OB11GroupRequestEvent( @@ -147,6 +145,20 @@ class OneBot11Adapter extends Service { ) this.dispatch(event) } + else if ([ + GroupNotifyType.SetAdmin, + GroupNotifyType.CancelAdminNotifyCanceled, + GroupNotifyType.CancelAdminNotifyAdmin + ].includes(notify.type)) { + this.ctx.logger.info('收到管理员变动通知') + const uin = await this.ctx.ntUserApi.getUinByUid(notify.user1.uid) + const event = new OB11GroupAdminNoticeEvent( + notify.type === GroupNotifyType.SetAdmin ? 'set' : 'unset', + parseInt(notify.group.groupCode), + parseInt(uin), + ) + this.dispatch(event) + } } catch (e) { this.ctx.logger.error('解析群通知失败', (e as Error).stack) } @@ -306,29 +318,6 @@ class OneBot11Adapter extends Service { }) } - private async handleGroupMemberInfoUpdated(groupCode: string, members: GroupMember[]) { - for (const member of members) { - const existMember = await this.ctx.ntGroupApi.getGroupMember(groupCode, member.uin) - if (existMember) { - if (member.cardName !== existMember.cardName) { - this.ctx.logger.info('群成员名片变动', `${groupCode}: ${existMember.uin}`, existMember.cardName, '->', member.cardName) - this.dispatch( - new OB11GroupCardEvent(parseInt(groupCode), parseInt(member.uin), member.cardName, existMember.cardName), - ) - } else if (member.role !== existMember.role) { - this.ctx.logger.info('有管理员变动通知') - const groupAdminNoticeEvent = new OB11GroupAdminNoticeEvent( - member.role == GroupMemberRole.admin ? 'set' : 'unset', - parseInt(groupCode), - parseInt(member.uin) - ) - this.dispatch(groupAdminNoticeEvent) - } - Object.assign(existMember, member) - } - } - } - public start() { if (this.config.enableWs) { this.ob11WebSocket.start() @@ -360,9 +349,6 @@ class OneBot11Adapter extends Service { this.ctx.on('nt/friend-request', input => { this.handleFriendRequest(input) }) - this.ctx.on('nt/group-member-info-updated', input => { - this.handleGroupMemberInfoUpdated(input.groupCode, input.members) - }) this.ctx.on('nt/system-message-created', input => { const sysMsg = SysMsg.SystemMessage.decode(input) const { msgType, subType, subSubType } = sysMsg.msgSpec[0] ?? {} @@ -385,7 +371,6 @@ namespace OneBot11Adapter { token: string debug: boolean reportSelfMessage: boolean - msgCacheExpire: number musicSignUrl?: string enableLocalFile2Url: boolean ffmpeg?: string diff --git a/src/onebot11/connect/ws.ts b/src/onebot11/connect/ws.ts index 9ea9e82..e22699b 100644 --- a/src/onebot11/connect/ws.ts +++ b/src/onebot11/connect/ws.ts @@ -214,7 +214,7 @@ class OB11WebSocketReverse { let receive: { action: ActionName | null; params: unknown; echo?: unknown } = { action: null, params: {} } try { receive = JSON.parse(msg.toString()) - this.ctx.logger.info('收到反向Websocket消息', receive) + this.ctx.logger.info('收到反向 Websocket 消息', receive) } catch (e) { return this.reply(this.wsClient!, OB11Response.error('json解析失败,请检查数据格式', 1400, receive.echo)) } diff --git a/src/onebot11/entities.ts b/src/onebot11/entities.ts index 8912e8b..2b198ab 100644 --- a/src/onebot11/entities.ts +++ b/src/onebot11/entities.ts @@ -30,7 +30,6 @@ import { OB11GroupUploadNoticeEvent } from './event/notice/OB11GroupUploadNotice import { OB11GroupNoticeEvent } from './event/notice/OB11GroupNoticeEvent' import { calcQQLevel } from '../common/utils/misc' import { OB11GroupTitleEvent } from './event/notice/OB11GroupTitleEvent' -import { OB11GroupCardEvent } from './event/notice/OB11GroupCardEvent' import { OB11GroupDecreaseEvent } from './event/notice/OB11GroupDecreaseEvent' import { OB11GroupMsgEmojiLikeEvent } from './event/notice/OB11MsgEmojiLikeEvent' import { OB11FriendAddNoticeEvent } from './event/notice/OB11FriendAddNoticeEvent' @@ -39,7 +38,7 @@ import { OB11GroupRecallNoticeEvent } from './event/notice/OB11GroupRecallNotice import { OB11FriendPokeEvent, OB11GroupPokeEvent } from './event/notice/OB11PokeEvent' import { OB11BaseNoticeEvent } from './event/notice/OB11BaseNoticeEvent' import { OB11GroupEssenceEvent } from './event/notice/OB11GroupEssenceEvent' -import { omit, isNullable, pick, Dict } from 'cosmokit' +import { omit, pick, Dict } from 'cosmokit' import { Context } from 'cordis' import { selfInfo } from '@/common/globalVars' import { pathToFileURL } from 'node:url' @@ -80,7 +79,7 @@ export namespace OB11Entities { if (msg.chatType === ChatType.Group) { resMsg.sub_type = 'normal' resMsg.group_id = parseInt(msg.peerUin) - const member = await ctx.ntGroupApi.getGroupMember(msg.peerUin, msg.senderUin) + const member = await ctx.ntGroupApi.getGroupMember(msg.peerUin, msg.senderUid) if (member) { resMsg.sender.role = groupMemberRole(member.role) resMsg.sender.nickname = member.nick @@ -89,12 +88,12 @@ export namespace OB11Entities { } else if (msg.chatType === ChatType.C2C) { resMsg.sub_type = 'friend' - resMsg.sender.nickname = (await ctx.ntUserApi.getUserDetailInfo(msg.senderUid)).nick + resMsg.sender.nickname = (await ctx.ntUserApi.getUserSimpleInfo(msg.senderUid)).coreInfo.nick } else if (msg.chatType === ChatType.TempC2CFromGroup) { resMsg.sub_type = 'group' resMsg.temp_source = 0 //群聊 - resMsg.sender.nickname = (await ctx.ntUserApi.getUserDetailInfo(msg.senderUid)).nick + resMsg.sender.nickname = (await ctx.ntUserApi.getUserSimpleInfo(msg.senderUid)).coreInfo.nick const ret = await ctx.ntMsgApi.getTempChatInfo(ChatType.TempC2CFromGroup, msg.senderUid) if (ret?.result === 0) { resMsg.sender.group_id = Number(ret.tmpChatInfo?.groupCode) @@ -403,7 +402,7 @@ export namespace OB11Entities { if (msg.chatType !== ChatType.Group) { return } - if (msg.senderUin) { + /**if (msg.senderUin) { const member = await ctx.ntGroupApi.getGroupMember(msg.peerUid, msg.senderUin) if (member && member.cardName !== msg.sendMemberName) { const event = new OB11GroupCardEvent( @@ -415,24 +414,17 @@ export namespace OB11Entities { member.cardName = msg.sendMemberName! return event } - } + }*/ for (const element of msg.elements) { const grayTipElement = element.grayTipElement const groupElement = grayTipElement?.groupElement if (groupElement) { if (groupElement.type === TipGroupElementType.MemberIncrease) { ctx.logger.info('收到群成员增加消息', groupElement) - await ctx.sleep(1000) - const member = await ctx.ntGroupApi.getGroupMember(msg.peerUid, groupElement.memberUid) - let memberUin = member?.uin - if (!memberUin) { - memberUin = (await ctx.ntUserApi.getUserDetailInfo(groupElement.memberUid)).uin - } - const adminMember = await ctx.ntGroupApi.getGroupMember(msg.peerUid, groupElement.adminUid) - if (memberUin) { - const operatorUin = adminMember?.uin || memberUin - return new OB11GroupIncreaseEvent(parseInt(msg.peerUid), parseInt(memberUin), parseInt(operatorUin)) - } + const { memberUid, adminUid } = groupElement + const memberUin = await ctx.ntUserApi.getUinByUid(memberUid) + const operatorUin = adminUid ? await ctx.ntUserApi.getUinByUid(adminUid) : memberUin + return new OB11GroupIncreaseEvent(+msg.peerUid, +memberUin, +operatorUin) } else if (groupElement.type === TipGroupElementType.Ban) { ctx.logger.info('收到群成员禁言提示', groupElement) @@ -547,10 +539,9 @@ export namespace OB11Entities { while ((match = regex.exec(xmlElement.content)) !== null) { matches.push(match[1]) } - // log("新人进群匹配到的QQ号", matches) if (matches.length === 2) { - const [inviter, invitee] = matches - return new OB11GroupIncreaseEvent(parseInt(msg.peerUid), parseInt(invitee), parseInt(inviter), 'invite') + const [invitor, invitee] = matches + return new OB11GroupIncreaseEvent(+msg.peerUid, +invitee, +invitor, 'invite') } } } @@ -594,11 +585,6 @@ export namespace OB11Entities { const memberUin = json.items[1].param[0] const title = json.items[3].txt ctx.logger.info('收到群成员新头衔消息', json) - ctx.ntGroupApi.getGroupMember(msg.peerUid, memberUin).then(member => { - if (!isNullable(member)) { - member.memberSpecialTitle = title - } - }) return new OB11GroupTitleEvent(parseInt(msg.peerUid), parseInt(memberUin), title) } else if (grayTipElement.jsonGrayTipElement?.busiId === '19217') { ctx.logger.info('收到新人被邀请进群消息', grayTipElement) @@ -616,13 +602,7 @@ export namespace OB11Entities { msg: RawMessage, shortId: number ): Promise { - const msgElement = msg.elements.find( - (element) => element.grayTipElement?.subElementType === GrayTipElementSubType.Revoke, - ) - if (!msgElement) { - return - } - const revokeElement = msgElement.grayTipElement!.revokeElement + const revokeElement = msg.elements[0].grayTipElement?.revokeElement if (msg.chatType === ChatType.Group) { const operator = await ctx.ntGroupApi.getGroupMember(msg.peerUid, revokeElement!.operatorUid) return new OB11GroupRecallNoticeEvent( diff --git a/src/onebot11/helper/createMessage.ts b/src/onebot11/helper/createMessage.ts index 7bbb6a3..0a32d53 100644 --- a/src/onebot11/helper/createMessage.ts +++ b/src/onebot11/helper/createMessage.ts @@ -56,7 +56,7 @@ export async function createSendElements( remainAtAllCount = (await ctx.ntGroupApi.getGroupRemainAtTimes(groupCode)).atInfo .RemainAtAllCountForUin ctx.logger.info(`群${groupCode}剩余at全体次数`, remainAtAllCount) - const self = await ctx.ntGroupApi.getGroupMember(groupCode, selfInfo.uin) + const self = await ctx.ntGroupApi.getGroupMember(groupCode, selfInfo.uid) isAdmin = self?.role === GroupMemberRole.admin || self?.role === GroupMemberRole.owner } catch (e) { } @@ -66,44 +66,24 @@ export async function createSendElements( } } else if (peer.chatType === ChatType.Group) { - const atMember = await ctx.ntGroupApi.getGroupMember(peer.peerUid, atQQ) - if (atMember) { - const display = `@${atMember.cardName || atMember.nick}` - sendElements.push( - SendElement.at(atQQ, atMember.uid, AtType.One, display), - ) - } else { - const atNmae = sendMsg.data?.name - const uid = await ctx.ntUserApi.getUidByUin(atQQ) || '' - const display = atNmae ? `@${atNmae}` : '' - sendElements.push( - SendElement.at(atQQ, uid, AtType.One, display), - ) - } + const uid = await ctx.ntUserApi.getUidByUin(atQQ) ?? '' + const atNmae = sendMsg.data?.name + const display = atNmae ? `@${atNmae}` : '' + sendElements.push(SendElement.at(atQQ, uid, AtType.One, display)) } } } break case OB11MessageDataType.reply: { if (sendMsg.data?.id) { - const replyMsgId = await ctx.store.getMsgInfoByShortId(+sendMsg.data.id) - if (!replyMsgId) { - ctx.logger.warn('回复消息不存在', replyMsgId) + const info = await ctx.store.getMsgInfoByShortId(+sendMsg.data.id) + if (!info) { + ctx.logger.warn('回复消息不存在', info) continue } - const replyMsg = (await ctx.ntMsgApi.getMsgsByMsgId( - replyMsgId.peer, - [replyMsgId.msgId!] - )).msgList[0] - if (replyMsg) { - sendElements.push( - SendElement.reply( - replyMsg.msgSeq, - replyMsg.msgId, - replyMsg.senderUin!, - replyMsg.senderUin!, - ), - ) + const source = (await ctx.ntMsgApi.getMsgsByMsgId(info.peer, [info.msgId])).msgList[0] + if (source) { + sendElements.push(SendElement.reply(source.msgSeq, source.msgId, source.senderUin)) } } } @@ -147,7 +127,7 @@ export async function createSendElements( const { path, fileName } = await handleOb11FileLikeMessage(ctx, sendMsg, { deleteAfterSentFiles }) let thumb = sendMsg.data.thumb if (thumb) { - const uri2LocalRes = await uri2local(thumb) + const uri2LocalRes = await uri2local(ctx, thumb) if (uri2LocalRes.success) thumb = uri2LocalRes.path } const res = await SendElement.video(ctx, path, fileName, thumb) @@ -206,7 +186,7 @@ async function handleOb11FileLikeMessage( fileName, errMsg, success, - } = (await uri2local(inputdata?.url || inputdata.file)) + } = (await uri2local(ctx, inputdata.url || inputdata.file)) if (!success) { ctx.logger.error(errMsg)