From 3ccd10ac3b4412ce18ef09c0ce9f908bd8075585 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: Tue, 28 May 2024 20:50:29 +0800 Subject: [PATCH] refactor: Info --- src/common/utils/db.ts | 508 ++++++++++++++++++ src/common/utils/file.ts | 2 +- src/onebot11/action/file/GetFile.ts | 2 +- .../action/go-cqhttp/GetForwardMsg.ts | 2 +- .../action/go-cqhttp/GetFriendMsgHistory.ts | 2 +- .../action/go-cqhttp/GetGroupMsgHistory.ts | 2 +- .../action/group/GetGroupMemberList.ts | 2 +- src/onebot11/action/msg/DeleteMsg.ts | 2 +- src/onebot11/action/msg/ForwardSingleMsg.ts | 124 ++--- src/onebot11/action/msg/GetMsg.ts | 2 +- .../msg/SendMsg/create-send-elements.ts | 2 +- .../action/msg/SendMsg/handle-forward-node.ts | 2 +- src/onebot11/action/msg/SendMsg/index.ts | 2 +- src/onebot11/action/msg/SetMsgEmojiLike.ts | 2 +- src/onebot11/action/system/CleanCache.ts | 2 +- src/onebot11/constructor.ts | 2 +- src/onebot11/main.ts | 2 +- src/onebot11/server/postOB11Event.ts | 2 +- 18 files changed, 586 insertions(+), 78 deletions(-) create mode 100644 src/common/utils/db.ts diff --git a/src/common/utils/db.ts b/src/common/utils/db.ts new file mode 100644 index 00000000..4a32d587 --- /dev/null +++ b/src/common/utils/db.ts @@ -0,0 +1,508 @@ +import { ElementType, FileElement, PicElement, PttElement, RawMessage, VideoElement } from '../../core/src/entities'; + +import sqlite3 from 'sqlite3'; +import { log, logDebug, logError } from '@/common/utils/log'; +import { NTQQMsgApi } from '@/core'; +import LRU from "@/common/utils/LRUCache"; + +export interface IRember { + last_sent_time: number; + join_time: number; + user_id: number; +} + + +type DBMsg = { + id: number, + shortId: number, + longId: string, + seq: number, + peerUid: string, + chatType: number, +} + +type DBFile = { + name: string; // 文件名 + path: string; + url: string; + size: number; + uuid: string; + msgId: string; + elementId: string; + element: PicElement | VideoElement | FileElement | PttElement; + elementType: ElementType.PIC | ElementType.VIDEO | ElementType.FILE | ElementType.PTT; +} + + +class DBUtilBase { + protected db: sqlite3.Database | undefined; + + async init(dbPath: string) { + if (this.db) { + return; + } + return new Promise((resolve, reject) => { + this.db = new sqlite3.Database(dbPath, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, (err) => { + if (err) { + logError('Could not connect to database', err); + reject(err); + return; + } + this.createTable(); + resolve(); + }); + }); + } + + protected createTable() { + throw new Error('Method not implemented.'); + } + + close() { + this.db?.close(); + } +} + +class DBUtil extends DBUtilBase { + private msgCache: Map = new Map(); + private globalMsgShortId = -2147483640; + private groupIds: number[] = []; + private LURCache = new LRU(); + private LastSentCache = new (class { + private cache: { gid: number; uid: number }[] = []; + private maxSize: number; + + constructor(maxSize: number = 5000) { + this.maxSize = maxSize; + } + + get(gid: number, uid: number): boolean { + const exists = this.cache.some( + (entry) => entry.gid === gid && entry.uid === uid + ); + if (!exists) { + this.cache.push({ gid, uid }); + if (this.cache.length > this.maxSize) { + this.cache.shift(); + } + } + + return exists; + } + })(); + + constructor() { + super(); + const interval = 1000 * 60 * 10; // 10分钟清理一次缓存 + setInterval(() => { + logDebug('清理消息缓存'); + this.msgCache.forEach((msg, key) => { + if ((Date.now() - parseInt(msg.msgTime) * 1000) > interval) { + this.msgCache.delete(key); + } + }); + }, interval); + } + + async init(dbPath: string) { + await super.init(dbPath); + this.globalMsgShortId = await this.getCurrentMaxShortId(); + + + // 初始化群缓存列表 + this.db!.serialize(() => { + const sql = `SELECT * FROM sqlite_master WHERE type='table'`; + this.db!.all(sql, [], (err, rows: { name: string }[]) => { + if (err) return logError(err); + rows.forEach((row) => this.groupIds.push(parseInt(row.name))); + //logDebug(`已加载 ${groupIds.length} 个群`); + }); + }); + + + this.LURCache.on(async (node) => { + const { value: time, groupId, userId } = node; + + logDebug("插入发言时间", userId, groupId); + await this.createGroupInfoTimeTableIfNotExist(groupId); + + const method = await this.getDataSetMethod(groupId, userId); + logDebug("插入发言时间方法判断", userId, groupId, method); + + const sql = + method == "update" + ? `UPDATE "${groupId}" SET last_sent_time = ? WHERE user_id = ?` + : `INSERT INTO "${groupId}" (last_sent_time, user_id) VALUES (?, ?)`; + + this.db!.all(sql, [time, userId], (err) => { + if (err) { + return logError("插入/更新发言时间失败", userId, groupId); + } + logDebug("插入/更新发言时间成功", userId, groupId); + }); + + }); + } + async getDataSetMethod(groupId: number, userId: number) { + // 缓存记录 + if (this.LastSentCache.get(groupId, userId)) { + logDebug("缓存命中", userId, groupId); + return "update"; + } + + // 数据库判断 + return new Promise<"insert" | "update">((resolve, reject) => { + this.db!.all( + `SELECT * FROM "${groupId}" WHERE user_id = ?`, + [userId], + (err, rows) => { + if (err) { + logError("查询发言时间存在失败", userId, groupId, err); + return logError("插入发言时间失败", userId, groupId, err); + } + + if (rows.length === 0) { + logDebug("查询发言时间不存在", userId, groupId); + return resolve("insert"); + } + + logDebug("查询发言时间存在", userId, groupId); + resolve("update"); + } + ); + }); + } + async createGroupInfoTimeTableIfNotExist(groupId: number) { + const createTableSQL = (groupId: number) => + `CREATE TABLE IF NOT EXISTS "${groupId}" ( + user_id INTEGER, + last_sent_time INTEGER, + join_time INTEGER, + PRIMARY KEY (user_id) + );`; + + if (this.groupIds.includes(groupId)) { + return; + } + return new Promise((resolve, reject) => { + const sql = createTableSQL(groupId); + this.db!.all(sql, (err) => { + if (err) { + reject(err); + return; + } + this.groupIds.push(groupId); + resolve(true); + }); + }); + } + protected createTable() { + // 消息记录 + const createTableSQL = ` + CREATE TABLE IF NOT EXISTS msgs ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + shortId INTEGER NOT NULL UNIQUE, + longId TEXT NOT NULL UNIQUE, + seq INTEGER NOT NULL, + peerUid TEXT NOT NULL, + chatType INTEGER NOT NULL + )`; + this.db!.run(createTableSQL, function (err) { + if (err) { + logError('Could not create table msgs', err.stack); + } + }); + + // 文件缓存 + const createFileTableSQL = ` + CREATE TABLE IF NOT EXISTS files ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + path TEXT NOT NULL, + url TEXT, + size INTEGER NOT NULL, + uuid TEXT, + elementType INTEGER, + element TEXT NOT NULL, + elementId TEXT NOT NULL, + msgId TEXT NOT NULL + )`; + this.db!.run(createFileTableSQL, function (err) { + if (err) { + logError('Could not create table files', err); + } + }); + + // 接收到的临时会话消息uid + const createTempUinTableSQL = ` + CREATE TABLE IF NOT EXISTS temp_uins ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + uid TEXT, + uin TEXT + )`; + this.db!.run(createTempUinTableSQL, function (err) { + if (err) { + logError('Could not create table temp_uins', err); + } + }); + } + + private async getCurrentMaxShortId() { + return new Promise((resolve, reject) => { + this.db!.get('SELECT MAX(shortId) as maxId FROM msgs', (err, row: { maxId: number }) => { + if (err) { + logDebug('Could not get max short id, Use default -2147483640', err); + return resolve(-2147483640); + } + logDebug('数据库中消息最大短id', row?.maxId); + resolve(row?.maxId ?? -2147483640); + }); + }); + } + + private async getMsg(query: string, params: any[]) { + const stmt = this.db!.prepare(query); + return new Promise((resolve, reject) => { + stmt.get(...params, (err: any, row: DBMsg) => { + // log("getMsg", row, err); + if (err) { + logError('Could not get msg', err, query, params); + return resolve(null); + } + if (!row) { + // logDebug('不存在数据库中的消息,不进行处理', query, params); + resolve(null); + return; + } + const msgId = row.longId; + NTQQMsgApi.getMsgsByMsgId({ peerUid: row.peerUid, chatType: row.chatType }, [msgId]).then(res => { + const msg = res.msgList[0]; + if (!msg) { + resolve(null); + return; + } + msg.id = row.shortId; + resolve(msg); + }).catch(e => { + resolve(null); + }); + }); + }); + } + + async getMsgByShortId(shortId: number): Promise { + if (this.msgCache.has(shortId)) { + return this.msgCache.get(shortId)!; + } + const getStmt = 'SELECT * FROM msgs WHERE shortId = ?'; + return this.getMsg(getStmt, [shortId]); + } + + async getMsgByLongId(longId: string): Promise { + if (this.msgCache.has(longId)) { + return this.msgCache.get(longId)!; + } + return this.getMsg('SELECT * FROM msgs WHERE longId = ?', [longId]); + } + + async getMsgBySeq(peerUid: string, seq: string): Promise { + const stmt = 'SELECT * FROM msgs WHERE peerUid = ? AND seq = ?'; + return this.getMsg(stmt, [peerUid, seq]); + } + + async addMsg(msg: RawMessage, update = true): Promise { + const existMsg = await this.getMsgByLongId(msg.msgId); + if (existMsg) { + // logDebug('消息已存在,更新数据库', msg.msgId); + if (update) this.updateMsg(msg).then(); + return existMsg.id!; + } + const stmt = this.db!.prepare('INSERT INTO msgs (shortId, longId, seq, peerUid, chatType) VALUES (?, ?, ?, ?, ?)'); + // const runAsync = promisify(stmt.run.bind(stmt)); + const shortId = ++this.globalMsgShortId; + msg.id = shortId; + //logDebug(`记录消息到数据库, 消息长id: ${msg.msgId}, 短id: ${msg.id}`); + this.msgCache.set(shortId, msg); + this.msgCache.set(msg.msgId, msg); + stmt.run(this.globalMsgShortId, msg.msgId, msg.msgSeq.toString(), msg.peerUid, msg.chatType, (err: any) => { + if (err) { + if (err.errno === 19) { + this.getMsgByLongId(msg.msgId).then((msg: RawMessage | null) => { + if (msg) { + this.msgCache.set(shortId, msg); + this.msgCache.set(msg.msgId, msg); + // logDebug('获取消息短id成功', msg.id); + } else { + logError('db could not get msg by long id', err); + } + }).catch(e => logError('db getMsgByLongId error', e)); + } else { + logError('db could not add msg', err); + } + } + }); + return shortId; + } + + async updateMsg(msg: RawMessage) { + const existMsg = this.msgCache.get(msg.msgId); + if (existMsg) { + Object.assign(existMsg, msg); + } + //logDebug(`更新消息, shortId:${msg.id}, seq: ${msg.msgSeq}, msgId: ${msg.msgId}`); + const stmt = this.db!.prepare('UPDATE msgs SET seq=? WHERE longId=?'); + stmt.run(msg.msgSeq, msg.msgId, (err: any) => { + if (err) { + logError('updateMsg db error', err); + } + }); + + } + + async addFileCache(file: DBFile) { + const stmt = this.db!.prepare('INSERT INTO files (name, path, url, size, uuid, elementType ,element, elementId, msgId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)'); + return new Promise((resolve, reject) => { + stmt.run(file.name, file.path, file.url, file.size, file.uuid, + file.elementType, + JSON.stringify(file.element), + file.elementId, + file.msgId, + function (err: any) { + if (err) { + logError('db could not add file', err); + reject(err); + } + resolve(null); + }); + }); + } + + private async getFileCache(query: string, params: any[]) { + const stmt = this.db!.prepare(query); + return new Promise((resolve, reject) => { + stmt.get(...params, (err: any, row: DBFile & { element: string }) => { + if (err) { + logError('db could not get file cache', err); + reject(err); + } + if (row) { + row.element = JSON.parse(row.element); + } + resolve(row); + }); + }); + } + + async getFileCacheByName(name: string): Promise { + return this.getFileCache('SELECT * FROM files WHERE name = ?', [name]); + } + + async getFileCacheByUuid(uuid: string): Promise { + return this.getFileCache('SELECT * FROM files WHERE uuid = ?', [uuid]); + } + + // todo: 是否所有的文件都有uuid?语音消息有没有uuid? + async updateFileCache(file: DBFile) { + const stmt = this.db!.prepare('UPDATE files SET path = ?, url = ? WHERE uuid = ?'); + return new Promise((resolve, reject) => { + stmt.run(file.path, file.url, file.uuid, function (err: any) { + if (err) { + logError('db could not update file cache', err); + reject(err); + } + resolve(null); + }); + }); + } + + // 被动收到的临时会话消息uin->uid + async getReceivedTempUinMap() { + const stmt = 'SELECT * FROM temp_uins'; + return new Promise>((resolve, reject) => { + this.db!.all(stmt, (err, rows: { uin: string, uid: string }[]) => { + if (err) { + logError('db could not get temp uin map', err); + reject(err); + } + const map: Record = {}; + rows.forEach(row => { + map[row.uin] = row.uid; + }); + resolve(map); + }); + }); + } + + // 通过uin获取临时会话消息uid + async getUidByTempUin(uid: string) { + const stmt = 'SELECT * FROM temp_uins WHERE uin = ?'; + return new Promise((resolve, reject) => { + this.db!.get(stmt, [uid], (err, row: { uin: string, uid: string }) => { + if (err) { + logError('db could not get temp uin map', err); + reject(err); + } + resolve(row?.uid); + }); + }); + } + + async addTempUin(uin: string, uid: string) { + const existUid = await this.getUidByTempUin(uin); + if (!existUid) { + const stmt = this.db!.prepare('INSERT INTO temp_uins (uin, uid) VALUES (?, ?)'); + return new Promise((resolve, reject) => { + stmt.run(uin, uid, function (err: any) { + if (err) { + logError('db could not add temp uin', err); + reject(err); + } + resolve(null); + }); + }); + } + } + async getLastSentTimeAndJoinTime( + groupId: number + ): Promise { + logDebug("读取发言时间", groupId); + return new Promise((resolve, reject) => { + this.db!.all(`SELECT * FROM "${groupId}" `, (err, rows: IRember[]) => { + if (err) { + logError("查询发言时间失败", groupId); + return resolve([]); + } + logDebug("查询发言时间成功", groupId, rows); + resolve(rows); + }); + }); + } + + insertLastSentTime( + groupId: number, + userId: number, + time: number + ) { + this.LURCache.set(groupId, userId, time) + } + async insertJoinTime( + groupId: number, + userId: number, + time: number + ) { + await this.createGroupInfoTimeTableIfNotExist(groupId); + this.db!.all( + `INSERT OR REPLACE INTO "${groupId}" (user_id, last_sent_time, join_time) VALUES (?,?,?)`, + [userId, time, time], + (err) => { + if (err) + logError(err), + Promise.reject(), + console.log("插入入群时间失败", userId, groupId); + } + ); + } +} + + +export const dbUtil = new DBUtil(); diff --git a/src/common/utils/file.ts b/src/common/utils/file.ts index 55d5a7a5..2afed7e6 100644 --- a/src/common/utils/file.ts +++ b/src/common/utils/file.ts @@ -4,7 +4,7 @@ import crypto from 'crypto'; import util from 'util'; import path from 'node:path'; import { log } from './log'; -import { dbUtil } from '@/core/utils/db'; +import { dbUtil } from '@/common/utils/db'; import * as fileType from 'file-type'; import { v4 as uuidv4 } from 'uuid'; import { napCatCore } from '@/core'; diff --git a/src/onebot11/action/file/GetFile.ts b/src/onebot11/action/file/GetFile.ts index 1e77858a..16efdfed 100644 --- a/src/onebot11/action/file/GetFile.ts +++ b/src/onebot11/action/file/GetFile.ts @@ -1,6 +1,6 @@ import BaseAction from '../BaseAction'; import fs from 'fs/promises'; -import { dbUtil } from '@/core/utils/db'; +import { dbUtil } from '@/common/utils/db'; import { ob11Config } from '@/onebot11/config'; import { log, logDebug } from '@/common/utils/log'; import { sleep } from '@/common/utils/helper'; diff --git a/src/onebot11/action/go-cqhttp/GetForwardMsg.ts b/src/onebot11/action/go-cqhttp/GetForwardMsg.ts index 980faf83..b1a8b470 100644 --- a/src/onebot11/action/go-cqhttp/GetForwardMsg.ts +++ b/src/onebot11/action/go-cqhttp/GetForwardMsg.ts @@ -1,7 +1,7 @@ import BaseAction from '../BaseAction'; import { OB11ForwardMessage, OB11Message, OB11MessageData } from '../../types'; import { NTQQMsgApi } from '@/core/apis'; -import { dbUtil } from '@/core/utils/db'; +import { dbUtil } from '@/common/utils/db'; import { OB11Constructor } from '../../constructor'; import { ActionName, BaseCheckResult } from '../types'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; diff --git a/src/onebot11/action/go-cqhttp/GetFriendMsgHistory.ts b/src/onebot11/action/go-cqhttp/GetFriendMsgHistory.ts index 2492951f..9b147278 100644 --- a/src/onebot11/action/go-cqhttp/GetFriendMsgHistory.ts +++ b/src/onebot11/action/go-cqhttp/GetFriendMsgHistory.ts @@ -3,7 +3,7 @@ import { OB11Message, OB11User } from '../../types'; import { getFriend, friends, uid2UinMap, getUidByUin } from '@/core/data'; import { ActionName } from '../types'; import { ChatType } from '@/core/entities'; -import { dbUtil } from '@/core/utils/db'; +import { dbUtil } from '@/common/utils/db'; import { NTQQMsgApi } from '@/core/apis/msg'; import { OB11Constructor } from '../../constructor'; import { logDebug } from '@/common/utils/log'; diff --git a/src/onebot11/action/go-cqhttp/GetGroupMsgHistory.ts b/src/onebot11/action/go-cqhttp/GetGroupMsgHistory.ts index e89729ce..2155626f 100644 --- a/src/onebot11/action/go-cqhttp/GetGroupMsgHistory.ts +++ b/src/onebot11/action/go-cqhttp/GetGroupMsgHistory.ts @@ -3,7 +3,7 @@ import { OB11Message, OB11User } from '../../types'; import { getGroup, groups } from '@/core/data'; import { ActionName } from '../types'; import { ChatType } from '@/core/entities'; -import { dbUtil } from '@/core/utils/db'; +import { dbUtil } from '@/common/utils/db'; import { NTQQMsgApi } from '@/core/apis/msg'; import { OB11Constructor } from '../../constructor'; import { logDebug } from '@/common/utils/log'; diff --git a/src/onebot11/action/group/GetGroupMemberList.ts b/src/onebot11/action/group/GetGroupMemberList.ts index 15479d3d..523c0f65 100644 --- a/src/onebot11/action/group/GetGroupMemberList.ts +++ b/src/onebot11/action/group/GetGroupMemberList.ts @@ -8,7 +8,7 @@ import { WebApi } from '@/core/apis/webapi'; import { logDebug } from '@/common/utils/log'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { ob11Config } from '@/onebot11/config'; -import { dbUtil } from '@/core/utils/db'; +import { dbUtil } from '@/common/utils/db'; const SchemaData = { type: 'object', diff --git a/src/onebot11/action/msg/DeleteMsg.ts b/src/onebot11/action/msg/DeleteMsg.ts index 560dfd32..99eeffc2 100644 --- a/src/onebot11/action/msg/DeleteMsg.ts +++ b/src/onebot11/action/msg/DeleteMsg.ts @@ -1,7 +1,7 @@ import { NTQQMsgApi } from '@/core/apis'; import { ActionName } from '../types'; import BaseAction from '../BaseAction'; -import { dbUtil } from '@/core/utils/db'; +import { dbUtil } from '@/common/utils/db'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; const SchemaData = { diff --git a/src/onebot11/action/msg/ForwardSingleMsg.ts b/src/onebot11/action/msg/ForwardSingleMsg.ts index c33e12f6..5b87ec8c 100644 --- a/src/onebot11/action/msg/ForwardSingleMsg.ts +++ b/src/onebot11/action/msg/ForwardSingleMsg.ts @@ -1,62 +1,62 @@ -import BaseAction from '../BaseAction'; -import { NTQQMsgApi } from '@/core/apis'; -import { ChatType, Peer } from '@/core/entities'; -import { dbUtil } from '@/core/utils/db'; -import { getUidByUin } from '@/core/data'; -import { ActionName } from '../types'; -import { FromSchema, JSONSchema } from 'json-schema-to-ts'; - -const SchemaData = { - type: 'object', - properties: { - message_id: { type: 'number' }, - group_id: { type: 'number' }, - user_id: { type: 'number' } - }, - required: ['message_id'] -} as const satisfies JSONSchema; - -type Payload = FromSchema; - -class ForwardSingleMsg extends BaseAction { - protected async getTargetPeer(payload: Payload): Promise { - if (payload.user_id) { - const peerUid = getUidByUin(payload.user_id.toString()); - if (!peerUid) { - throw new Error(`无法找到私聊对象${payload.user_id}`); - } - return { chatType: ChatType.friend, peerUid }; - } - return { chatType: ChatType.group, peerUid: payload.group_id!.toString() }; - } - - protected async _handle(payload: Payload): Promise { - const msg = await dbUtil.getMsgByShortId(payload.message_id); - if (!msg) { - throw new Error(`无法找到消息${payload.message_id}`); - } - const peer = await this.getTargetPeer(payload); - const ret = await NTQQMsgApi.forwardMsg( - { - chatType: msg.chatType, - peerUid: msg.peerUid, - }, - peer, - [msg.msgId], - ); - if (ret.result !== 0) { - throw new Error(`转发消息失败 ${ret.errMsg}`); - } - return null; - } -} - -export class ForwardFriendSingleMsg extends ForwardSingleMsg { - PayloadSchema = SchemaData; - actionName = ActionName.ForwardFriendSingleMsg; -} - -export class ForwardGroupSingleMsg extends ForwardSingleMsg { - PayloadSchema = SchemaData; - actionName = ActionName.ForwardGroupSingleMsg; -} +import BaseAction from '../BaseAction'; +import { NTQQMsgApi } from '@/core/apis'; +import { ChatType, Peer } from '@/core/entities'; +import { dbUtil } from '@/common/utils/db'; +import { getUidByUin } from '@/core/data'; +import { ActionName } from '../types'; +import { FromSchema, JSONSchema } from 'json-schema-to-ts'; + +const SchemaData = { + type: 'object', + properties: { + message_id: { type: 'number' }, + group_id: { type: 'number' }, + user_id: { type: 'number' } + }, + required: ['message_id'] +} as const satisfies JSONSchema; + +type Payload = FromSchema; + +class ForwardSingleMsg extends BaseAction { + protected async getTargetPeer(payload: Payload): Promise { + if (payload.user_id) { + const peerUid = getUidByUin(payload.user_id.toString()); + if (!peerUid) { + throw new Error(`无法找到私聊对象${payload.user_id}`); + } + return { chatType: ChatType.friend, peerUid }; + } + return { chatType: ChatType.group, peerUid: payload.group_id!.toString() }; + } + + protected async _handle(payload: Payload): Promise { + const msg = await dbUtil.getMsgByShortId(payload.message_id); + if (!msg) { + throw new Error(`无法找到消息${payload.message_id}`); + } + const peer = await this.getTargetPeer(payload); + const ret = await NTQQMsgApi.forwardMsg( + { + chatType: msg.chatType, + peerUid: msg.peerUid, + }, + peer, + [msg.msgId], + ); + if (ret.result !== 0) { + throw new Error(`转发消息失败 ${ret.errMsg}`); + } + return null; + } +} + +export class ForwardFriendSingleMsg extends ForwardSingleMsg { + PayloadSchema = SchemaData; + actionName = ActionName.ForwardFriendSingleMsg; +} + +export class ForwardGroupSingleMsg extends ForwardSingleMsg { + PayloadSchema = SchemaData; + actionName = ActionName.ForwardGroupSingleMsg; +} diff --git a/src/onebot11/action/msg/GetMsg.ts b/src/onebot11/action/msg/GetMsg.ts index 42cf1846..43e5ffbb 100644 --- a/src/onebot11/action/msg/GetMsg.ts +++ b/src/onebot11/action/msg/GetMsg.ts @@ -2,7 +2,7 @@ import { OB11Message } from '../../types'; import { OB11Constructor } from '../../constructor'; import BaseAction from '../BaseAction'; import { ActionName } from '../types'; -import { dbUtil } from '@/core/utils/db'; +import { dbUtil } from '@/common/utils/db'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; diff --git a/src/onebot11/action/msg/SendMsg/create-send-elements.ts b/src/onebot11/action/msg/SendMsg/create-send-elements.ts index 7a23a9d7..14f8c80e 100644 --- a/src/onebot11/action/msg/SendMsg/create-send-elements.ts +++ b/src/onebot11/action/msg/SendMsg/create-send-elements.ts @@ -10,7 +10,7 @@ import { SendMsgElementConstructor } from '@/core'; import { getGroupMember } from '@/core/data'; -import { dbUtil } from '@/core/utils/db'; +import { dbUtil } from '@/common/utils/db'; import { logDebug, logError } from '@/common/utils/log'; import { uri2local } from '@/common/utils/file'; import { ob11Config } from '@/onebot11/config'; diff --git a/src/onebot11/action/msg/SendMsg/handle-forward-node.ts b/src/onebot11/action/msg/SendMsg/handle-forward-node.ts index 3fe9e706..dff0bb42 100644 --- a/src/onebot11/action/msg/SendMsg/handle-forward-node.ts +++ b/src/onebot11/action/msg/SendMsg/handle-forward-node.ts @@ -1,7 +1,7 @@ import { ChatType, ElementType, Group, NTQQMsgApi, Peer, RawMessage, SendMessageElement } from '@/core'; import { OB11MessageNode } from '@/onebot11/types'; import { selfInfo } from '@/core/data'; -import { dbUtil } from '@/core/utils/db'; +import { dbUtil } from '@/common/utils/db'; import createSendElements from '@/onebot11/action/msg/SendMsg/create-send-elements'; import { logDebug, logError } from '@/common/utils/log'; import { sleep } from '@/common/utils/helper'; diff --git a/src/onebot11/action/msg/SendMsg/index.ts b/src/onebot11/action/msg/SendMsg/index.ts index c60149d5..4c1a2391 100644 --- a/src/onebot11/action/msg/SendMsg/index.ts +++ b/src/onebot11/action/msg/SendMsg/index.ts @@ -8,7 +8,7 @@ import { } from '@/onebot11/types'; import { ActionName, BaseCheckResult } from '@/onebot11/action/types'; import { getFriend, getGroup, getUidByUin } from '@/core/data'; -import { dbUtil } from '@/core/utils/db'; +import { dbUtil } from '@/common/utils/db'; import { ChatType, ElementType, Group, NTQQMsgApi, Peer, SendMessageElement, } from '@/core'; import fs from 'node:fs'; import { logDebug, logError } from '@/common/utils/log'; diff --git a/src/onebot11/action/msg/SetMsgEmojiLike.ts b/src/onebot11/action/msg/SetMsgEmojiLike.ts index 038edea6..a468aee7 100644 --- a/src/onebot11/action/msg/SetMsgEmojiLike.ts +++ b/src/onebot11/action/msg/SetMsgEmojiLike.ts @@ -1,6 +1,6 @@ import { ActionName } from '../types'; import BaseAction from '../BaseAction'; -import { dbUtil } from '@/core/utils/db'; +import { dbUtil } from '@/common/utils/db'; import { NTQQMsgApi } from '@/core/apis'; import { FromSchema, JSONSchema } from 'json-schema-to-ts'; diff --git a/src/onebot11/action/system/CleanCache.ts b/src/onebot11/action/system/CleanCache.ts index 81d7ed0c..0951539c 100644 --- a/src/onebot11/action/system/CleanCache.ts +++ b/src/onebot11/action/system/CleanCache.ts @@ -7,7 +7,7 @@ import { ChatCacheListItemBasic, CacheFileType } from '@/core/entities'; -import { dbUtil } from '@/core/utils/db'; +import { dbUtil } from '@/common/utils/db'; import { NTQQFileApi, NTQQFileCacheApi } from '@/core/apis/file'; export default class CleanCache extends BaseAction { diff --git a/src/onebot11/constructor.ts b/src/onebot11/constructor.ts index 1cfcaa8d..ae949b0e 100644 --- a/src/onebot11/constructor.ts +++ b/src/onebot11/constructor.ts @@ -26,7 +26,7 @@ import { } from '@/core/entities'; import { EventType } from './event/OB11BaseEvent'; import { encodeCQCode } from './cqcode'; -import { dbUtil } from '@/core/utils/db'; +import { dbUtil } from '@/common/utils/db'; import { OB11GroupIncreaseEvent } from './event/notice/OB11GroupIncreaseEvent'; import { OB11GroupBanEvent } from './event/notice/OB11GroupBanEvent'; import { OB11GroupUploadNoticeEvent } from './event/notice/OB11GroupUploadNoticeEvent'; diff --git a/src/onebot11/main.ts b/src/onebot11/main.ts index 0c8f662c..edcb114d 100644 --- a/src/onebot11/main.ts +++ b/src/onebot11/main.ts @@ -18,7 +18,7 @@ import { httpHeart, ob11HTTPServer } from '@/onebot11/server/http'; import { ob11WebsocketServer } from '@/onebot11/server/ws/WebsocketServer'; import { ob11ReverseWebsockets } from '@/onebot11/server/ws/ReverseWebsocket'; import { friendRequests, getFriend, getGroup, getGroupMember, groupNotifies, selfInfo, uid2UinMap } from '@/core/data'; -import { dbUtil } from '@/core/utils/db'; +import { dbUtil } from '@/common/utils/db'; import { BuddyListener, GroupListener, NodeIKernelBuddyListener } from '@/core/listeners'; import { OB11FriendRequestEvent } from '@/onebot11/event/request/OB11FriendRequest'; import { NTQQGroupApi, NTQQUserApi } from '@/core/apis'; diff --git a/src/onebot11/server/postOB11Event.ts b/src/onebot11/server/postOB11Event.ts index 197943f0..d7d91aad 100644 --- a/src/onebot11/server/postOB11Event.ts +++ b/src/onebot11/server/postOB11Event.ts @@ -11,7 +11,7 @@ import { normalize, sendMsg } from '../action/msg/SendMsg'; import { OB11FriendRequestEvent } from '../event/request/OB11FriendRequest'; import { OB11GroupRequestEvent } from '../event/request/OB11GroupRequest'; import { isNull } from '@/common/utils/helper'; -import { dbUtil } from '@/core/utils/db'; +import { dbUtil } from '@/common/utils/db'; import { friendRequests, getGroup, getUidByUin, groupNotifies, selfInfo } from '@/core/data'; import { NTQQFriendApi, NTQQGroupApi, NTQQMsgApi } from '@/core/apis'; import createSendElements from '../action/msg/SendMsg/create-send-elements';