diff --git a/package.json b/package.json index 3ffd3b87..86df3aa7 100644 --- a/package.json +++ b/package.json @@ -19,10 +19,9 @@ }, "devDependencies": { "@babel/core": "^7.24.7", - "@babel/preset-typescript": "^7.24.7", - "vite-plugin-babel": "^1.2.0", "@babel/plugin-proposal-class-properties": "^7.18.6", "@babel/plugin-proposal-decorators": "^7.24.7", + "@babel/preset-typescript": "^7.24.7", "@log4js-node/log4js-api": "^1.0.2", "@protobuf-ts/plugin": "^2.9.4", "@rollup/plugin-node-resolve": "^15.2.3", @@ -31,6 +30,7 @@ "@types/express": "^4.17.21", "@types/figlet": "^1.5.8", "@types/fluent-ffmpeg": "^2.1.24", + "@types/jest": "^29.5.12", "@types/node": "^20.11.30", "@types/qrcode-terminal": "^0.12.2", "@types/uuid": "^10.0.0", @@ -47,6 +47,7 @@ "rollup-plugin-obfuscator": "^1.1.0", "typescript": "^5.3.3", "vite": "^5.2.6", + "vite-plugin-babel": "^1.2.0", "vite-plugin-cp": "^4.0.8", "vite-plugin-dts": "^3.8.2", "vite-tsconfig-paths": "^4.3.2" diff --git a/src/common/utils/MessageUnique.ts b/src/common/utils/MessageUnique.ts index db2e8d77..eeec8eed 100644 --- a/src/common/utils/MessageUnique.ts +++ b/src/common/utils/MessageUnique.ts @@ -1,63 +1,30 @@ +import { Peer } from '@/core'; import crypto from 'crypto'; -class CircularQueue { - private items: T[] = []; - private front: number = 0; - private maxSize: number; - constructor(maxSize: number) { - this.maxSize = maxSize; - } - - enqueue(item: T): void { - if (this.items.length == this.maxSize) { - this.front = (this.front + 1) % this.maxSize; - } - this.items[(this.front + this.items.length) % this.maxSize] = item; - } - - dequeue(): T | undefined { - return this.items.length == 0 ? undefined : this.items[(this.front + 1) % this.items.length]; - } - - size(): number { - return this.items.length; - } -} - class LimitedHashTable { private keyToValue: Map = new Map(); private valueToKey: Map = new Map(); - private keyQueue: CircularQueue = new CircularQueue(0); - private valueQueue: CircularQueue = new CircularQueue(0); private maxSize: number; constructor(maxSize: number) { this.maxSize = maxSize; } - private removeFromQueues(key: K, value: V): void { - this.keyQueue.dequeue(); - this.valueQueue.dequeue(); - } - set(key: K, value: V): void { - let isExist = this.keyToValue.get(key); + const isExist = this.keyToValue.get(key); if (isExist && isExist === value) { return; } this.keyToValue.set(key, value); this.valueToKey.set(value, key); - this.keyQueue.enqueue(key); - this.valueQueue.enqueue(value); - - if (this.keyQueue.size() > this.maxSize || this.valueQueue.size() > this.maxSize) { - const removedKey = this.keyQueue.dequeue(); - const removedValue = this.valueQueue.dequeue(); - if (removedKey !== undefined && removedValue !== undefined) { - this.keyToValue.delete(removedKey); - this.valueToKey.delete(removedValue); - this.removeFromQueues(removedKey, removedValue); - } + while (this.keyToValue.size !== this.valueToKey.size){ + console.log('keyToValue.size !== valueToKey.size'); + } + while (this.keyToValue.size > this.maxSize || this.valueToKey.size > this.maxSize) { + //删除旧的值 + const oldestKey = this.keyToValue.keys().next().value; + this.keyToValue.delete(oldestKey); + this.valueToKey.delete(oldestKey); } } @@ -69,12 +36,11 @@ class LimitedHashTable { return this.valueToKey.get(value); } - deleteByValue(value: V) { + deleteByValue(value: V): void { const key = this.valueToKey.get(value); if (key !== undefined) { this.keyToValue.delete(key); this.valueToKey.delete(value); - this.removeFromQueues(key, value); } } @@ -83,41 +49,47 @@ class LimitedHashTable { if (value !== undefined) { this.keyToValue.delete(key); this.valueToKey.delete(value); - this.removeFromQueues(key, value); } } } class MessageUniqueWrapper { private msgIdMap: LimitedHashTable; - constructor(MaxMap: number = 1000) { - this.msgIdMap = new LimitedHashTable(MaxMap); + constructor(maxMap: number = 1000) { + this.msgIdMap = new LimitedHashTable(maxMap); } - createMsg(MsgId: string) { - const hash = crypto.createHash('sha256'); - hash.update(MsgId); - const ShortId = parseInt(hash.digest('hex').slice(0, 8), 16); - let isExist = this.msgIdMap.getKey(ShortId) - if (isExist && isExist === MsgId) { - return true; + createMsg(peer: Peer, msgId: string): number | undefined { + const key = `${msgId}|${peer.chatType}|${peer.peerUid}`; + const hash = crypto.createHash('sha1').update(key); + const shortId = parseInt(hash.digest('hex').slice(0, 8), 16); + const isExist = this.msgIdMap.getKey(shortId); + if (isExist && isExist === msgId) { + return undefined; } - return this.msgIdMap.set(MsgId, ShortId); + + this.msgIdMap.set(key, shortId); + return shortId; } - getMsgIdByShortId(ShortId: number) { - return this.msgIdMap.getKey(ShortId); + getMsgIdAndPeerByShortId(shortId: number): { MsgId: string; Peer: Peer } | undefined { + const data = this.msgIdMap.getKey(shortId); + if (data) { + const [msgId, chatTypeStr, peerUid] = data.split('|'); + const peer: Peer = { + chatType: parseInt(chatTypeStr), + peerUid, + guildId: '', + }; + return { MsgId: msgId, Peer: peer }; + } + return undefined; } - getShortIdByMsgId(MsgId: string) { - return this.msgIdMap.getValue(MsgId); - } - - CreateMsgIdList(MsgIdList: string[]) { - return MsgIdList.map((MsgId) => { - return this.createMsg(MsgId); - }); + getShortIdByMsgId(msgId: string): number | undefined { + return this.msgIdMap.getValue(msgId); } } -export const MessageUnique = new MessageUniqueWrapper(); \ No newline at end of file +export const MessageUnique = new MessageUniqueWrapper(); + diff --git a/test/MessageUnique.ts b/test/MessageUnique.ts new file mode 100644 index 00000000..5349644e --- /dev/null +++ b/test/MessageUnique.ts @@ -0,0 +1,95 @@ +describe('MessageUniqueWrapper', () => { + let messageUniqueWrapper: MessageUniqueWrapper; + + beforeEach(() => { + messageUniqueWrapper = new MessageUniqueWrapper(); + }); + + test('createMsg should return a unique shortId for a new message', () => { + const peer = new Peer(); + peer.chatType = 1; + peer.peerUid = '123'; + const msgId = 'msgId123'; + + const key = `${msgId}|${peer.chatType}|${peer.peerUid}`; + const hash = crypto.createHash('sha1').update(key); + const expectedShortId = parseInt(hash.digest('hex').slice(0, 8), 16); + + const shortId = messageUniqueWrapper.createMsg(peer, msgId); + + expect(shortId).toBeDefined(); + expect(shortId).toBe(expectedShortId); + }); + + test('createMsg should return undefined if the same message is added again', () => { + const peer = new Peer(); + peer.chatType = 1; + peer.peerUid = '123'; + const msgId = 'msgId123'; + + const shortId = messageUniqueWrapper.createMsg(peer, msgId); + const secondShortId = messageUniqueWrapper.createMsg(peer, msgId); + + expect(shortId).toBeDefined(); + expect(secondShortId).toBeUndefined(); + }); + + test('getMsgIdAndPeerByShortId should return the message and peer for a given shortId', () => { + const peer = new Peer(); + peer.chatType = 1; + peer.peerUid = '123'; + const msgId = 'msgId123'; + + messageUniqueWrapper.createMsg(peer, msgId); + + const shortId = messageUniqueWrapper.getShortIdByMsgId(msgId); + const result = messageUniqueWrapper.getMsgIdAndPeerByShortId(shortId); + + expect(result).toBeDefined(); + expect(result.MsgId).toBe(msgId); + expect(result.Peer.chatType).toBe(peer.chatType); + expect(result.Peer.peerUid).toBe(peer.peerUid); + }); + + test('getMsgIdAndPeerByShortId should return undefined if the shortId does not exist', () => { + const peer = new Peer(); + peer.chatType = 1; + peer.peerUid = '123'; + const msgId = 'msgId123'; + + messageUniqueWrapper.createMsg(peer, msgId); + + const invalidShortId = 12345678; + const result = messageUniqueWrapper.getMsgIdAndPeerByShortId(invalidShortId); + + expect(result).toBeUndefined(); + }); + + test('getShortIdByMsgId should return the shortId for a given message Id', () => { + const peer = new Peer(); + peer.chatType = 1; + peer.peerUid = '123'; + const msgId = 'msgId123'; + + messageUniqueWrapper.createMsg(peer, msgId); + + const shortId = messageUniqueWrapper.getShortIdByMsgId(msgId); + + expect(shortId).toBeDefined(); + expect(typeof shortId).toBe('number'); + }); + + test('getShortIdByMsgId should return undefined if the message Id does not exist', () => { + const peer = new Peer(); + peer.chatType = 1; + peer.peerUid = '123'; + const msgId = 'msgId123'; + + messageUniqueWrapper.createMsg(peer, msgId); + + const invalidMsgId = 'invalidMsgId'; + const shortId = messageUniqueWrapper.getShortIdByMsgId(invalidMsgId); + + expect(shortId).toBeUndefined(); + }); + }); \ No newline at end of file diff --git a/test/NapCatNative.cjs b/test/NapCatNative.cjs deleted file mode 100644 index bc83cfe0..00000000 --- a/test/NapCatNative.cjs +++ /dev/null @@ -1,4 +0,0 @@ -let t = require('./NapCatNative.node'); -console.log(t); -let r = t.ClearElectronAsNode(); -console.log(r); \ No newline at end of file diff --git a/test/NapCatNative.node b/test/NapCatNative.node deleted file mode 100644 index f6c7ce6a..00000000 Binary files a/test/NapCatNative.node and /dev/null differ diff --git a/test/README.md b/test/README.md deleted file mode 100644 index 6faf9ad8..00000000 --- a/test/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Test For NapCatQQ -This is a test for NapCatQQ. - -# 计划 -1. 根据配置文件启动不同的测试 Event与Api -2. 标记特殊注意的测试 \ No newline at end of file diff --git a/test/api/msg/SendPicMsg.py b/test/api/msg/SendPicMsg.py deleted file mode 100644 index 2a893b74..00000000 --- a/test/api/msg/SendPicMsg.py +++ /dev/null @@ -1,4 +0,0 @@ -def send_pic_local_msg(user, file): - pass -def send_pic_http_msg(user, pic_url): - pass \ No newline at end of file diff --git a/test/boot.py b/test/boot.py deleted file mode 100644 index 307dceec..00000000 --- a/test/boot.py +++ /dev/null @@ -1,6 +0,0 @@ -import requests -import pyyaml -def __main__(): - print("TEST") - -__main__() \ No newline at end of file diff --git a/test/config/all.yaml b/test/config/all.yaml deleted file mode 100644 index 99f10893..00000000 --- a/test/config/all.yaml +++ /dev/null @@ -1 +0,0 @@ -# todo \ No newline at end of file diff --git a/test/framwork/__init__.py b/test/framwork/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/test/framwork/msg/SendMsg.py b/test/framwork/msg/SendMsg.py deleted file mode 100644 index 53b2a63d..00000000 --- a/test/framwork/msg/SendMsg.py +++ /dev/null @@ -1 +0,0 @@ -#发送消息 \ No newline at end of file diff --git a/test/requirements.txt b/test/requirements.txt deleted file mode 100644 index 90f8e3b3..00000000 --- a/test/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -pyyaml==5.4.1 \ No newline at end of file