From de64b030544c41f9c0d5cab416fc0045eb3c1c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Thu, 21 Nov 2024 11:01:35 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=97=A7=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=A7=BB=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/video.ts | 98 ++++++++++--------- src/core/apis/file.ts | 2 +- src/core/apis/group.ts | 6 +- src/core/apis/msg.ts | 12 +-- src/core/entities/cache.ts | 97 +++++++++--------- src/onebot/action/guild/GetGuildList.ts | 2 +- src/onebot/action/guild/GetGuildProfile.ts | 2 +- src/onebot/action/index.ts | 4 +- src/onebot/action/msg/SetMsgEmojiLike.ts | 11 +-- src/onebot/cqcode.ts | 42 ++++---- .../event/notice/OB11GroupAdminNoticeEvent.ts | 2 +- .../event/notice/OB11GroupDecreaseEvent.ts | 4 +- 12 files changed, 143 insertions(+), 139 deletions(-) diff --git a/src/common/video.ts b/src/common/video.ts index 906f7e6a..e474926a 100644 --- a/src/common/video.ts +++ b/src/common/video.ts @@ -5,59 +5,67 @@ import type { LogWrapper } from './log'; export const defaultVideoThumbB64 = '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'; -export async function getVideoInfo(filePath: string, logger: LogWrapper) { - const size = fs.statSync(filePath).size; - return new Promise<{ - width: number, - height: number, - time: number, - format: string, - size: number, - filePath: string - }>((resolve, reject) => { - const ffmpegPath = process.env.FFMPEG_PATH; - if (ffmpegPath) - ffmpeg.setFfmpegPath(ffmpegPath); +interface VideoInfo { + width: number; + height: number; + time: number; + format: string; + size: number; + filePath: string; +} + +async function getFileSize(filePath: string): Promise { + const stats = await fs.promises.stat(filePath); + return stats.size; +} + +function setFfmpegPath() { + const ffmpegPath = process.env.FFMPEG_PATH; + if (ffmpegPath) { + ffmpeg.setFfmpegPath(ffmpegPath); + } +} + +function extractVideoStream(metadata: ffmpeg.FfprobeData): FfprobeStream | undefined { + return metadata.streams.find((s: FfprobeStream) => s.codec_type === 'video'); +} + +async function probeVideo(filePath: string): Promise { + return new Promise((resolve, reject) => { ffmpeg(filePath).ffprobe((err: any, metadata: ffmpeg.FfprobeData) => { if (err) { reject(new Error('无法获取视频信息。')); } else { - const videoStream = metadata.streams.find((s: FfprobeStream) => s.codec_type === 'video'); - if (videoStream) { - logger.log(`视频尺寸: ${videoStream.width}x${videoStream.height}`); - } else { - return reject(new Error('未找到视频流信息。')); - } - resolve({ - width: videoStream.width!, height: videoStream.height!, - time: +(videoStream.duration ?? 10), - format: metadata.format.format_name!, - size, - filePath, - }); + resolve(metadata); } }); }); } -export function checkFfmpeg(logger: LogWrapper, newPath: string | null = null): Promise { - return new Promise((resolve) => { - logger.log('开始检查ffmpeg', newPath); - if (newPath) { - ffmpeg.setFfmpegPath(newPath); +export async function getVideoInfo(filePath: string, logger: LogWrapper): Promise { + try { + const size = await getFileSize(filePath); + setFfmpegPath(); + const metadata = await probeVideo(filePath); + const videoStream = extractVideoStream(metadata); + + if (!videoStream) { + throw new Error('未找到视频流信息。'); } - try { - ffmpeg.getAvailableFormats((err: any) => { - if (err) { - logger.log('ffmpeg is not installed or not found in PATH:', err); - resolve(false); - } else { - logger.log('ffmpeg is installed.'); - resolve(true); - } - }); - } catch (e) { - resolve(false); + + logger.log(`视频尺寸: ${videoStream.width}x${videoStream.height}`); + if (!videoStream.width || !metadata.format.format_name || !videoStream.height) { + throw new Error('获取基础信息失败') } - }); -} + return { + width: videoStream.width, + height: videoStream.height, + time: +(videoStream.duration ?? 10), + format: metadata.format.format_name, + size, + filePath, + }; + } catch (error) { + throw new Error('无法获取视频信息。'); + } +} \ No newline at end of file diff --git a/src/core/apis/file.ts b/src/core/apis/file.ts index ebe4364f..cfe10a81 100644 --- a/src/core/apis/file.ts +++ b/src/core/apis/file.ts @@ -320,7 +320,7 @@ export class NTQQFileApi { } async downloadMedia(msgId: string, chatType: ChatType, peerUid: string, elementId: string, thumbPath: string, sourcePath: string, timeout = 1000 * 60 * 2, force: boolean = false) { - // 用于下载收到的消息中的图片等 + // 用于下载文件 if (sourcePath && fs.existsSync(sourcePath)) { if (force) { try { diff --git a/src/core/apis/group.ts b/src/core/apis/group.ts index 0380186c..ab4f0fa5 100644 --- a/src/core/apis/group.ts +++ b/src/core/apis/group.ts @@ -147,14 +147,11 @@ export class NTQQGroupApi { if (!members) { try { members = await this.getGroupMembers(groupCodeStr); - // 更新群成员列表 this.groupMemberCache.set(groupCodeStr, members); } catch (e) { return null; } } - - // log('getGroupMember', members); function getMember() { let member: GroupMember | undefined; if (isNumeric(memberUinOrUidStr)) { @@ -367,7 +364,6 @@ export class NTQQGroupApi { } } this.context.session.getGroupService().destroyMemberListScene(sceneId); - //console.log('GetGroupMembersV3 len :', result.result.infos.size, resMode2?.infos.size, groupQQ); return { infos: new Map([...(resMode2?.infos ?? []), ...result.result.infos]), finish: result.result.finish, @@ -430,7 +426,7 @@ export class NTQQGroupApi { return this.context.session.getGroupService().operateSysNotify( false, { - operateType: operateType, // 2 拒绝 + operateType: operateType, targetMsg: { seq: seq, // 通知序列号 type: type, diff --git a/src/core/apis/msg.ts b/src/core/apis/msg.ts index 4335fc73..8d575043 100644 --- a/src/core/apis/msg.ts +++ b/src/core/apis/msg.ts @@ -3,12 +3,7 @@ import { GroupFileInfoUpdateItem, InstanceContext, NapCatCore } from '@/core'; import { GeneralCallResult } from '@/core/services/common'; export class NTQQMsgApi { - getMsgByClientSeqAndTime(peer: Peer, replyMsgClientSeq: string, replyMsgTime: string) { - return this.context.session.getMsgService().getMsgByClientSeqAndTime(peer, replyMsgClientSeq, replyMsgTime); - } - // 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 + context: InstanceContext; core: NapCatCore; @@ -17,7 +12,10 @@ export class NTQQMsgApi { this.context = context; this.core = core; } - + getMsgByClientSeqAndTime(peer: Peer, replyMsgClientSeq: string, replyMsgTime: string) { + // https://bot.q.qq.com/wiki/develop/api-v2/openapi/emoji/model.html#EmojiType 可以用过特殊方式拉取 + return this.context.session.getMsgService().getMsgByClientSeqAndTime(peer, replyMsgClientSeq, replyMsgTime); + } async getAioFirstViewLatestMsgs(peer: Peer, MsgCount: number) { return this.context.session.getMsgService().getAioFirstViewLatestMsgs(peer, MsgCount); } diff --git a/src/core/entities/cache.ts b/src/core/entities/cache.ts index 8e4cf813..27d8433a 100644 --- a/src/core/entities/cache.ts +++ b/src/core/entities/cache.ts @@ -1,65 +1,68 @@ import { ChatType } from './msg'; -export interface CacheScanResult { - result: number; - size: [ // 单位为字节 - string, // 系统总存储空间 - string, // 系统可用存储空间 - string, // 系统已用存储空间 - string, // QQ总大小 - string, // 「聊天与文件」大小 - string, // 未知 - string, // 「缓存数据」大小 - string, // 「其他数据」大小 - string, // 未知 - ]; -} - +/** + * 聊天缓存列表 + */ export interface ChatCacheList { - pageCount: number; - infos: ChatCacheListItem[]; + pageCount: number; // 页数 + infos: ChatCacheListItem[]; // 聊天缓存项列表 } +/** + * 聊天缓存列表项 + */ export interface ChatCacheListItem { - chatType: ChatType; - basicChatCacheInfo: ChatCacheListItemBasic; - guildChatCacheInfo: unknown[]; // TODO: 没用过频道所以不知道这里边的详细内容 + chatType: ChatType; // 聊天类型 + basicChatCacheInfo: ChatCacheListItemBasic; // 基本聊天缓存信息 + guildChatCacheInfo: unknown[]; // 公会聊天缓存信息 } +/** + * 基本聊天缓存信息 + */ export interface ChatCacheListItemBasic { - chatSize: string; - chatTime: string; - uid: string; - uin: string; - remarkName: string; - nickName: string; - chatType?: ChatType; - isChecked?: boolean; + chatSize: string; // 聊天大小 + chatTime: string; // 聊天时间 + uid: string; // 用户ID + uin: string; // 用户号码 + remarkName: string; // 备注名 + nickName: string; // 昵称 + chatType?: ChatType; // 聊天类型(可选) + isChecked?: boolean; // 是否已检查(可选) } +/** + * 缓存文件类型枚举 + */ export enum CacheFileType { - IMAGE = 0, - VIDEO = 1, - AUDIO = 2, - DOCUMENT = 3, - OTHER = 4, + IMAGE = 0, // 图片 + VIDEO = 1, // 视频 + AUDIO = 2, // 音频 + DOCUMENT = 3, // 文档 + OTHER = 4, // 其他 } +/** + * 缓存文件列表 + */ export interface CacheFileList { - infos: CacheFileListItem[], + infos: CacheFileListItem[]; // 缓存文件项列表 } +/** + * 缓存文件列表项 + */ export interface CacheFileListItem { - fileSize: string; - fileTime: string; - fileKey: string; - elementId: string; - elementIdStr: string; - fileType: CacheFileType; - path: string; - fileName: string; - senderId: string; - previewPath: string; - senderName: string; - isChecked?: boolean; -} + fileSize: string; // 文件大小 + fileTime: string; // 文件时间 + fileKey: string; // 文件键 + elementId: string; // 元素ID + elementIdStr: string; // 元素ID字符串 + fileType: CacheFileType; // 文件类型 + path: string; // 路径 + fileName: string; // 文件名 + senderId: string; // 发送者ID + previewPath: string; // 预览路径 + senderName: string; // 发送者名称 + isChecked?: boolean; // 是否已检查(可选) +} \ No newline at end of file diff --git a/src/onebot/action/guild/GetGuildList.ts b/src/onebot/action/guild/GetGuildList.ts index 1195ea3e..8d586ad7 100644 --- a/src/onebot/action/guild/GetGuildList.ts +++ b/src/onebot/action/guild/GetGuildList.ts @@ -1,7 +1,7 @@ import { OneBotAction } from '@/onebot/action/OneBotAction'; import { ActionName } from '../types'; -export default class GetGuildList extends OneBotAction { +export class GetGuildList extends OneBotAction { actionName = ActionName.GetGuildList; async _handle(payload: null): Promise { diff --git a/src/onebot/action/guild/GetGuildProfile.ts b/src/onebot/action/guild/GetGuildProfile.ts index 5a623388..183b56a8 100644 --- a/src/onebot/action/guild/GetGuildProfile.ts +++ b/src/onebot/action/guild/GetGuildProfile.ts @@ -1,7 +1,7 @@ import { OneBotAction } from '@/onebot/action/OneBotAction'; import { ActionName } from '../types'; -export default class GetGuildProfile extends OneBotAction { +export class GetGuildProfile extends OneBotAction { actionName = ActionName.GetGuildProfile; async _handle(payload: null): Promise { diff --git a/src/onebot/action/index.ts b/src/onebot/action/index.ts index edbf8321..9c6be913 100644 --- a/src/onebot/action/index.ts +++ b/src/onebot/action/index.ts @@ -22,7 +22,6 @@ import GoCQHTTPGetStrangerInfo from './go-cqhttp/GetStrangerInfo'; import SendLike from './user/SendLike'; import SetGroupAddRequest from './group/SetGroupAddRequest'; import SetGroupLeave from './group/SetGroupLeave'; -import GetGuildList from './guild/GetGuildList'; import SetFriendAddRequest from './user/SetFriendAddRequest'; import SetGroupWholeBan from './group/SetGroupWholeBan'; import SetGroupName from './group/SetGroupName'; @@ -70,7 +69,6 @@ import { FetchEmojiLike } from './extends/FetchEmojiLike'; import { FetchUserProfileLike } from './extends/FetchUserProfileLike'; import { NapCatCore } from '@/core'; import { NapCatOneBot11Adapter } from '@/onebot'; -import GetGuildProfile from './guild/GetGuildProfile'; import { SetInputStatus } from './extends/SetInputStatus'; import { GetCSRF } from './system/GetCSRF'; import { DelGroupNotice } from './group/DelGroupNotice'; @@ -102,6 +100,8 @@ import { GetMiniAppArk } from "@/onebot/action/extends/GetMiniAppArk"; import { GetAiRecord } from "@/onebot/action/group/GetAiRecord"; import { SendGroupAiRecord } from "@/onebot/action/group/SendGroupAiRecord"; import { GetAiCharacters } from "@/onebot/action/extends/GetAiCharacters"; +import { GetGuildList } from './guild/GetGuildList'; +import { GetGuildProfile } from './guild/GetGuildProfile'; export type ActionMap = Map>; diff --git a/src/onebot/action/msg/SetMsgEmojiLike.ts b/src/onebot/action/msg/SetMsgEmojiLike.ts index e0e9305b..4d40e285 100644 --- a/src/onebot/action/msg/SetMsgEmojiLike.ts +++ b/src/onebot/action/msg/SetMsgEmojiLike.ts @@ -27,19 +27,18 @@ export class SetMsgEmojiLike extends OneBotAction { if (!payload.emoji_id) { throw new Error('emojiId not found'); } - if (!payload.set) { - payload.set = true; - } + payload.set = payload.set ?? true; const msgData = (await this.core.apis.MsgApi.getMsgsByMsgId(msg.Peer, [msg.MsgId])).msgList; - if (!msgData || msgData.length == 0 || !msgData[0].msgSeq) { + if (!msgData || msgData.length === 0 || !msgData[0].msgSeq) { throw new Error('find msg by msgid error'); } + return await this.core.apis.MsgApi.setEmojiLike( msg.Peer, msgData[0].msgSeq, payload.emoji_id.toString(), - typeof payload.set == 'string' ? payload.set === 'true' : !!payload + typeof payload.set === 'string' ? payload.set === 'true' : !!payload.set ); } -} +} \ No newline at end of file diff --git a/src/onebot/cqcode.ts b/src/onebot/cqcode.ts index 5aa5651f..eadfc2d3 100644 --- a/src/onebot/cqcode.ts +++ b/src/onebot/cqcode.ts @@ -24,7 +24,7 @@ function from(source: string) { return { type, data, capture }; } -function h(type: string, data: any) { +function convert(type: string, data: any) { return { type, data, @@ -37,31 +37,29 @@ export function decodeCQCode(source: string): OB11MessageData[] { while ((result = from(source))) { const { type, data, capture } = result; if (capture.index) { - elements.push(h('text', { text: unescape(source.slice(0, capture.index)) })); + elements.push(convert('text', { text: unescape(source.slice(0, capture.index)) })); } - elements.push(h(type, data)); + elements.push(convert(type, data)); source = source.slice(capture.index + capture[0].length); } - if (source) elements.push(h('text', { text: unescape(source) })); + if (source) elements.push(convert('text', { text: unescape(source) })); return elements; } +function CQCodeEscapeText(text: string) { + return text.replace(/&/g, '&') + .replace(/\[/g, '[') + .replace(/]/g, ']'); +} + +function CQCodeEscape(text: string) { + return text.replace(/&/g, '&') + .replace(/\[/g, '[') + .replace(/]/g, ']') + .replace(/,/g, ','); +} export function encodeCQCode(data: OB11MessageData) { - const CQCodeEscapeText = (text: string) => { - return text.replace(/&/g, '&') - .replace(/\[/g, '[') - .replace(/]/g, ']'); - - }; - - const CQCodeEscape = (text: string) => { - return text.replace(/&/g, '&') - .replace(/\[/g, '[') - .replace(/]/g, ']') - .replace(/,/g, ','); - }; - if (data.type === 'text') { return CQCodeEscapeText(data.data.text); } @@ -74,11 +72,13 @@ export function encodeCQCode(data: OB11MessageData) { } try { const text = value?.toString(); - if (text) result += `,${name}=${CQCodeEscape(text)}`; + if (text) { + result += `,${name}=${CQCodeEscape(text)}`; + } } catch (error) { - // If it can't be converted, skip this name-value pair + console.error(`Error encoding CQCode for ${name}:`, error); } } result += ']'; return result; -} +} \ No newline at end of file diff --git a/src/onebot/event/notice/OB11GroupAdminNoticeEvent.ts b/src/onebot/event/notice/OB11GroupAdminNoticeEvent.ts index 31a05bad..b64e5c7f 100644 --- a/src/onebot/event/notice/OB11GroupAdminNoticeEvent.ts +++ b/src/onebot/event/notice/OB11GroupAdminNoticeEvent.ts @@ -3,7 +3,7 @@ import { NapCatCore } from '@/core'; export class OB11GroupAdminNoticeEvent extends OB11GroupNoticeEvent { notice_type = 'group_admin'; - sub_type: 'set' | 'unset'; // "set" | "unset" + sub_type: 'set' | 'unset'; constructor(core: NapCatCore, group_id: number, user_id: number, sub_type: 'set' | 'unset') { super(core, group_id, user_id); diff --git a/src/onebot/event/notice/OB11GroupDecreaseEvent.ts b/src/onebot/event/notice/OB11GroupDecreaseEvent.ts index f914d23e..5a52664e 100644 --- a/src/onebot/event/notice/OB11GroupDecreaseEvent.ts +++ b/src/onebot/event/notice/OB11GroupDecreaseEvent.ts @@ -5,13 +5,13 @@ export type GroupDecreaseSubType = 'leave' | 'kick' | 'kick_me'; export class OB11GroupDecreaseEvent extends OB11GroupNoticeEvent { notice_type = 'group_decrease'; - sub_type: GroupDecreaseSubType = 'leave'; // TODO: 实现其他几种子类型的识别 ("leave" | "kick" | "kick_me") + sub_type: GroupDecreaseSubType = 'leave'; operator_id: number; constructor(core: NapCatCore, groupId: number, userId: number, operatorId: number, subType: GroupDecreaseSubType = 'leave') { super(core, groupId, userId); this.group_id = groupId; - this.operator_id = operatorId; // 实际上不应该这么实现,但是现在还没有办法识别用户是被踢出的,还是自己主动退出的 + this.operator_id = operatorId; this.user_id = userId; this.sub_type = subType; }