@@ -12,6 +12,7 @@ declare module 'cordis' {
1212 message : {
1313 shortId : number
1414 msgId : string
15+ uniqueMsgId : string
1516 chatType : number
1617 peerUid : string
1718 }
@@ -47,6 +48,7 @@ class Store extends Service {
4748 shortId : 'integer(10)' ,
4849 chatType : 'unsigned' ,
4950 msgId : 'string(24)' ,
51+ uniqueMsgId : 'string(64)' ,
5052 peerUid : 'string(24)'
5153 } , {
5254 primary : 'shortId'
@@ -75,17 +77,31 @@ class Store extends Service {
7577 } )
7678 }
7779
78- createMsgShortId ( peer : Peer , msgId : string ) : number {
79- const existingShortId = this . getShortIdByMsgInfo ( peer , msgId )
80+ getUniqueMsgId ( msg : RawMessage ) : string {
81+ return `${ msg . chatType } -${ msg . peerUid } -${ msg . msgSeq } -${ msg . msgRandom } }`
82+ }
83+
84+ createMsgShortId ( msg : RawMessage ) : number {
85+ const peer = {
86+ chatType : msg . chatType ,
87+ peerUid : msg . peerUid ,
88+ guildId : ''
89+ }
90+ // QQ 本地给的 msgId 是和 Protobuf 给的不一致
91+ // 并且本地的 msgId 是根据一个本地保存的随机字符串 + 某种算法生成的,如果将 QQ 数据库清空了,这个随机字符串会变
92+ // 这就导致每次清空数据库后收到的同一条消息的 msgId 都不一样
93+ // 所以这里改成用 msgSeq + msgRandom 来生成 shortId,保证清空 QQ 数据库后收到同一条消息收到 shortId 都一致
94+ const uniqueMsgId = this . getUniqueMsgId ( msg )
95+ const existingShortId = this . getShortIdByMsgInfo ( peer , uniqueMsgId )
8096 if ( existingShortId ) {
8197 return existingShortId
8298 }
83- const key = `${ msgId } |${ peer . chatType } |${ peer . peerUid } `
84- const hash = createHash ( 'md5' ) . update ( key ) . digest ( )
99+ const hash = createHash ( 'md5' ) . update ( uniqueMsgId ) . digest ( )
85100 const shortId = hash . readInt32BE ( ) // OneBot 11 要求 message_id 为 int32
86- this . cache . set ( key , shortId )
101+ this . cache . set ( uniqueMsgId , shortId )
87102 this . ctx . database . upsert ( 'message' , [ {
88- msgId,
103+ msgId : msg . msgId ,
104+ uniqueMsgId,
89105 shortId,
90106 chatType : peer . chatType ,
91107 peerUid : peer . peerUid
@@ -124,6 +140,20 @@ class Store extends Service {
124140 return ( await this . ctx . database . get ( 'message' , { msgId } ) ) [ 0 ] ?. shortId
125141 }
126142
143+ async getShortIdByUniqueMsgId ( uniqueMsgId : string ) : Promise < number | undefined > {
144+ return ( await this . ctx . database . get ( 'message' , { uniqueMsgId } ) ) [ 0 ] ?. shortId
145+ }
146+
147+ async checkMsgExist ( msg : RawMessage ) : Promise < boolean > {
148+ const uniqueMsgId = this . getUniqueMsgId ( msg )
149+ const existingShortId = await this . getShortIdByUniqueMsgId ( uniqueMsgId )
150+ if ( existingShortId ) {
151+ return true
152+ }
153+ this . createMsgShortId ( msg )
154+ return false
155+ }
156+
127157 getShortIdByMsgInfo ( peer : Peer , msgId : string ) {
128158 const cacheKey = `${ msgId } |${ peer . chatType } |${ peer . peerUid } `
129159 return this . cache . getValue ( cacheKey )
0 commit comments