diff --git a/manifest.json b/manifest.json
index 65a7b54..a186757 100644
--- a/manifest.json
+++ b/manifest.json
@@ -4,7 +4,7 @@
   "name": "LLOneBot",
   "slug": "LLOneBot",
   "description": "实现 OneBot 11 协议,用于 QQ 机器人开发",
-  "version": "3.33.10",
+  "version": "3.34.0",
   "icon": "./icon.webp",
   "authors": [
     {
diff --git a/src/common/utils/legacyLog.ts b/src/common/utils/legacyLog.ts
index 217c9e8..0010d2f 100644
--- a/src/common/utils/legacyLog.ts
+++ b/src/common/utils/legacyLog.ts
@@ -2,24 +2,7 @@ import fs from 'fs'
 import path from 'node:path'
 import { getConfigUtil } from '../config'
 import { LOG_DIR } from '../globalVars'
-import { Dict } from 'cosmokit'
-
-function truncateString(obj: Dict | null, maxLength = 500) {
-  if (obj !== null && typeof obj === 'object') {
-    Object.keys(obj).forEach((key) => {
-      if (typeof obj[key] === 'string') {
-        // 如果是字符串且超过指定长度,则截断
-        if (obj[key].length > maxLength) {
-          obj[key] = obj[key].substring(0, maxLength) + '...'
-        }
-      } else if (typeof obj[key] === 'object') {
-        // 如果是对象或数组,则递归调用
-        truncateString(obj[key], maxLength)
-      }
-    })
-  }
-  return obj
-}
+import { inspect } from 'node:util'
 
 export const logFileName = `llonebot-${new Date().toLocaleString('zh-CN')}.log`.replace(/\//g, '-').replace(/:/g, '-')
 
@@ -29,9 +12,8 @@ export function log(...msg: unknown[]) {
   }
   let logMsg = ''
   for (const msgItem of msg) {
-    // 判断是否是对象
     if (typeof msgItem === 'object') {
-      logMsg += JSON.stringify(truncateString(msgItem)) + ' '
+      logMsg += inspect(msgItem, { depth: 10, compact: true, breakLength: Infinity }) + ' '
       continue
     }
     logMsg += msgItem + ' '
diff --git a/src/main/main.ts b/src/main/main.ts
index 5ce2a50..6079a29 100644
--- a/src/main/main.ts
+++ b/src/main/main.ts
@@ -191,7 +191,9 @@ function onLoad() {
     ctx.plugin(SQLiteDriver, {
       path: path.join(dbDir, `${selfInfo.uin}.db`)
     })
-    ctx.plugin(Store)
+    ctx.plugin(Store, {
+      msgCacheExpire: config.msgCacheExpire! * 1000
+    })
     ctx.start()
     ipcMain.on(CHANNEL_SET_CONFIG_CONFIRMED, (event, config: LLOBConfig) => {
       ctx.parallel('llonebot/config-updated', config)
diff --git a/src/main/store.ts b/src/main/store.ts
index 3b1a6ee..aa8d7c9 100644
--- a/src/main/store.ts
+++ b/src/main/store.ts
@@ -1,4 +1,4 @@
-import { Peer } from '@/ntqqapi/types'
+import { Peer, RawMessage } from '@/ntqqapi/types'
 import { createHash } from 'node:crypto'
 import { LimitedHashTable } from '@/common/utils/table'
 import { FileCacheV2 } from '@/common/types'
@@ -24,13 +24,15 @@ interface MsgInfo {
   peer: Peer
 }
 
-export default class Store extends Service {
+class Store extends Service {
   static inject = ['database', 'model']
   private cache: LimitedHashTable<string, number>
+  private messages: Map<string, RawMessage>
 
-  constructor(protected ctx: Context) {
+  constructor(protected ctx: Context, public config: Store.Config) {
     super(ctx, 'store', true)
     this.cache = new LimitedHashTable(1000)
+    this.messages = new Map()
     this.initDatabase()
   }
 
@@ -123,4 +125,29 @@ export default class Store extends Service {
   getFileCacheById(fileUuid: string) {
     return this.ctx.database.get('file_v2', { fileUuid })
   }
+
+  async addMsgCache(msg: RawMessage) {
+    const expire = this.config.msgCacheExpire
+    if (expire === 0) {
+      return
+    }
+    const id = msg.msgId
+    this.messages.set(id, msg)
+    setTimeout(() => {
+      this.messages.delete(id)
+    }, expire)
+  }
+
+  getMsgCache(msgId: string) {
+    return this.messages.get(msgId)
+  }
 }
+
+namespace Store {
+  export interface Config {
+    /** 单位为毫秒 */
+    msgCacheExpire: number
+  }
+}
+
+export default Store
diff --git a/src/ntqqapi/api/file.ts b/src/ntqqapi/api/file.ts
index d2ff5af..5ec5d8e 100644
--- a/src/ntqqapi/api/file.ts
+++ b/src/ntqqapi/api/file.ts
@@ -16,7 +16,6 @@ import path from 'node:path'
 import { existsSync } from 'node:fs'
 import { ReceiveCmdS } from '../hook'
 import { RkeyManager } from '@/ntqqapi/helper/rkey'
-import { getSession } from '@/ntqqapi/wrapper'
 import { OnRichMediaDownloadCompleteParams, Peer } from '@/ntqqapi/types/msg'
 import { calculateFileMD5 } from '@/common/utils/file'
 import { fileTypeFromFile } from 'file-type'
@@ -39,39 +38,28 @@ export class NTQQFileApi extends Service {
     this.rkeyManager = new RkeyManager(ctx, 'https://llob.linyuchen.net/rkey')
   }
 
-  async getVideoUrl(peer: Peer, msgId: string, elementId: string) {
-    const session = getSession()
-    if (session) {
-      return (await session.getRichMediaService().getVideoPlayUrlV2(
-        peer,
-        msgId,
-        elementId,
-        0,
-        { downSourceType: 1, triggerType: 1 }
-      )).urlResult.domainUrl[0]?.url
-    } else {
-      const data = await invoke('nodeIKernelRichMediaService/getVideoPlayUrlV2', [{
-        peer,
-        msgId,
-        elemId: elementId,
-        videoCodecFormat: 0,
-        exParams: {
-          downSourceType: 1,
-          triggerType: 1
-        },
-      }, null])
-      if (data.result !== 0) {
-        this.ctx.logger.warn('getVideoUrl', data)
+  async getVideoUrl(peer: Peer, msgId: string, elementId: string): Promise<string | undefined> {
+    const data = await invoke('nodeIKernelRichMediaService/getVideoPlayUrlV2', [{
+      peer,
+      msgId,
+      elemId: elementId,
+      videoCodecFormat: 0,
+      params: {
+        downSourceType: 1,
+        triggerType: 1
       }
-      return data.urlResult.domainUrl[0]?.url
+    }])
+    if (data.result !== 0) {
+      this.ctx.logger.warn('getVideoUrl', data)
     }
+    return data.urlResult.domainUrl[0]?.url
   }
 
   async getFileType(filePath: string) {
     return fileTypeFromFile(filePath)
   }
 
-  // 上传文件到QQ的文件夹
+  /** 上传文件到 QQ 的文件夹 */
   async uploadFile(filePath: string, elementType = ElementType.Pic, elementSubType = 0) {
     const fileMd5 = await calculateFileMD5(filePath)
     let fileName = path.basename(filePath)
@@ -174,8 +162,8 @@ export class NTQQFileApi extends Service {
     if (url) {
       const parsedUrl = new URL(IMAGE_HTTP_HOST + url) //临时解析拼接
       const imageAppid = parsedUrl.searchParams.get('appid')
-      const isNewPic = imageAppid && ['1406', '1407'].includes(imageAppid)
-      if (isNewPic) {
+      const isNTPic = imageAppid && ['1406', '1407'].includes(imageAppid)
+      if (isNTPic) {
         let rkey = parsedUrl.searchParams.get('rkey')
         if (rkey) {
           return IMAGE_HTTP_HOST_NT + url
diff --git a/src/ntqqapi/api/friend.ts b/src/ntqqapi/api/friend.ts
index fd65f5a..3c92ae3 100644
--- a/src/ntqqapi/api/friend.ts
+++ b/src/ntqqapi/api/friend.ts
@@ -1,8 +1,7 @@
-import { Friend, FriendV2, SimpleInfo, CategoryFriend, BuddyListReqType } from '../types'
+import { Friend, SimpleInfo, CategoryFriend } from '../types'
 import { ReceiveCmdS } from '../hook'
 import { invoke, NTMethod, NTClass } from '../ntcall'
 import { getSession } from '@/ntqqapi/wrapper'
-import { Dict, pick } from 'cosmokit'
 import { Service, Context } from 'cordis'
 
 declare module 'cordis' {
@@ -60,7 +59,7 @@ export class NTQQFriendApi extends Service {
     }
   }
 
-  async getBuddyV2(refresh = false): Promise<FriendV2[]> {
+  async getBuddyV2(refresh = false): Promise<SimpleInfo[]> {
     const data = await invoke<{
       buddyCategory: CategoryFriend[]
       userSimpleInfos: Record<string, SimpleInfo>
@@ -118,12 +117,7 @@ export class NTQQFriendApi extends Service {
   }
 
   async isBuddy(uid: string): Promise<boolean> {
-    const session = getSession()
-    if (session) {
-      return session.getBuddyService().isBuddy(uid)
-    } else {
-      return await invoke('nodeIKernelBuddyService/isBuddy', [{ uid }, null])
-    }
+    return await invoke('nodeIKernelBuddyService/isBuddy', [{ uid }])
   }
 
   async getBuddyRecommendContact(uin: string) {
diff --git a/src/ntqqapi/api/msg.ts b/src/ntqqapi/api/msg.ts
index e119444..4207a10 100644
--- a/src/ntqqapi/api/msg.ts
+++ b/src/ntqqapi/api/msg.ts
@@ -27,17 +27,12 @@ export class NTQQMsgApi extends Service {
     }
   }
 
-  async setEmojiLike(peer: Peer, msgSeq: string, emojiId: string, setEmoji: boolean = true) {
+  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
     // 其实以官方文档为准是最好的,https://bot.q.qq.com/wiki/develop/api-v2/openapi/emoji/model.html#EmojiType
-    const session = getSession()
     const emojiType = emojiId.length > 3 ? '2' : '1'
-    if (session) {
-      return session.getMsgService().setMsgEmojiLikes(peer, msgSeq, emojiId, emojiType, setEmoji)
-    } else {
-      return await invoke(NTMethod.EMOJI_LIKE, [{ peer, msgSeq, emojiId, emojiType, setEmoji }, null])
-    }
+    return await invoke(NTMethod.EMOJI_LIKE, [{ peer, msgSeq, emojiId, emojiType, setEmoji }])
   }
 
   async getMultiMsg(peer: Peer, rootMsgId: string, parentMsgId: string) {
@@ -58,59 +53,41 @@ export class NTQQMsgApi extends Service {
   }
 
   async getAioFirstViewLatestMsgs(peer: Peer, cnt: number) {
-    return await invoke('nodeIKernelMsgService/getAioFirstViewLatestMsgs', [{ peer, cnt }, null])
+    return await invoke('nodeIKernelMsgService/getAioFirstViewLatestMsgs', [{ peer, cnt }])
   }
 
-  async getMsgsByMsgId(peer: Peer | undefined, msgIds: string[] | undefined) {
+  async getMsgsByMsgId(peer: Peer, msgIds: string[]) {
     if (!peer) throw new Error('peer is not allowed')
     if (!msgIds) throw new Error('msgIds is not allowed')
-    const session = getSession()
-    if (session) {
-      return session.getMsgService().getMsgsByMsgId(peer, msgIds)
-    } else {
-      return await invoke('nodeIKernelMsgService/getMsgsByMsgId', [{ peer, msgIds }, null])
-    }
+    return await invoke('nodeIKernelMsgService/getMsgsByMsgId', [{ peer, msgIds }])
   }
 
   async getMsgHistory(peer: Peer, msgId: string, cnt: number, isReverseOrder: boolean = false) {
-    const session = getSession()
     // 消息时间从旧到新
-    if (session) {
-      return session.getMsgService().getMsgsIncludeSelf(peer, msgId, cnt, isReverseOrder)
-    } else {
-      return await invoke(NTMethod.HISTORY_MSG, [{ peer, msgId, cnt, queryOrder: isReverseOrder }, null])
-    }
+    return await invoke(NTMethod.HISTORY_MSG, [{ peer, msgId, cnt, queryOrder: isReverseOrder }])
   }
 
   async recallMsg(peer: Peer, msgIds: string[]) {
-    const session = getSession()
-    if (session) {
-      return session.getMsgService().recallMsg(peer, msgIds)
-    } else {
-      return await invoke(NTMethod.RECALL_MSG, [{ peer, msgIds }, null])
-    }
+    return await invoke(NTMethod.RECALL_MSG, [{ peer, msgIds }])
   }
 
   async sendMsg(peer: Peer, msgElements: SendMessageElement[], timeout = 10000) {
-    const msgId = await this.generateMsgUniqueId(peer.chatType)
-    peer.guildId = msgId
+    const uniqueId = await this.generateMsgUniqueId(peer.chatType)
+    peer.guildId = uniqueId
     const data = await invoke<{ msgList: RawMessage[] }>(
       'nodeIKernelMsgService/sendMsg',
-      [
-        {
-          msgId: '0',
-          peer,
-          msgElements,
-          msgAttributeInfos: new Map()
-        },
-        null
-      ],
+      [{
+        msgId: '0',
+        peer,
+        msgElements,
+        msgAttributeInfos: new Map()
+      }],
       {
         cbCmd: 'nodeIKernelMsgListener/onMsgInfoListUpdate',
         afterFirstCmd: false,
         cmdCB: payload => {
           for (const msgRecord of payload.msgList) {
-            if (msgRecord.guildId === msgId && msgRecord.sendStatus === 2) {
+            if (msgRecord.guildId === uniqueId && msgRecord.sendStatus === 2) {
               return true
             }
           }
@@ -119,22 +96,35 @@ export class NTQQMsgApi extends Service {
         timeout
       }
     )
-    return data.msgList.find(msgRecord => msgRecord.guildId === msgId)
+    return data.msgList.find(msgRecord => msgRecord.guildId === uniqueId)
   }
 
   async forwardMsg(srcPeer: Peer, destPeer: Peer, msgIds: string[]) {
-    const session = getSession()
-    if (session) {
-      return session.getMsgService().forwardMsg(msgIds, srcPeer, [destPeer], [])
-    } else {
-      return await invoke(NTMethod.FORWARD_MSG, [{
+    const uniqueId = await this.generateMsgUniqueId(destPeer.chatType)
+    destPeer.guildId = uniqueId
+    const data = await invoke<{ msgList: RawMessage[] }>(
+      'nodeIKernelMsgService/forwardMsg',
+      [{
         msgIds,
         srcContact: srcPeer,
         dstContacts: [destPeer],
         commentElements: [],
         msgAttributeInfos: new Map(),
-      }, null])
-    }
+      }],
+      {
+        cbCmd: 'nodeIKernelMsgListener/onMsgInfoListUpdate',
+        afterFirstCmd: false,
+        cmdCB: payload => {
+          for (const msgRecord of payload.msgList) {
+            if (msgRecord.guildId === uniqueId && msgRecord.sendStatus === 2) {
+              return true
+            }
+          }
+          return false
+        }
+      }
+    )
+    return data.msgList.filter(msgRecord => msgRecord.guildId === uniqueId)
   }
 
   async multiForwardMsg(srcPeer: Peer, destPeer: Peer, msgIds: string[]): Promise<RawMessage> {
@@ -145,27 +135,24 @@ export class NTQQMsgApi extends Service {
     const selfUid = selfInfo.uid
     const data = await invoke<{ msgList: RawMessage[] }>(
       'nodeIKernelMsgService/multiForwardMsgWithComment',
-      [
-        {
-          msgInfos,
-          srcContact: srcPeer,
-          dstContact: destPeer,
-          commentElements: [],
-          msgAttributeInfos: new Map(),
-        },
-        null,
-      ],
+      [{
+        msgInfos,
+        srcContact: srcPeer,
+        dstContact: destPeer,
+        commentElements: [],
+        msgAttributeInfos: new Map(),
+      }],
       {
         cbCmd: 'nodeIKernelMsgListener/onMsgInfoListUpdate',
         afterFirstCmd: false,
         cmdCB: payload => {
           for (const msgRecord of payload.msgList) {
-            if (msgRecord.peerUid == destPeer.peerUid && msgRecord.senderUid == selfUid) {
+            if (msgRecord.peerUid === destPeer.peerUid && msgRecord.senderUid === selfUid) {
               return true
             }
           }
           return false
-        },
+        }
       }
     )
     for (const msg of data.msgList) {
@@ -174,10 +161,10 @@ export class NTQQMsgApi extends Service {
         continue
       }
       const forwardData = JSON.parse(arkElement.arkElement!.bytesData)
-      if (forwardData.app != 'com.tencent.multimsg') {
+      if (forwardData.app !== 'com.tencent.multimsg') {
         continue
       }
-      if (msg.peerUid == destPeer.peerUid && msg.senderUid == selfUid) {
+      if (msg.peerUid === destPeer.peerUid && msg.senderUid === selfUid) {
         return msg
       }
     }
@@ -240,7 +227,7 @@ export class NTQQMsgApi extends Service {
         isIncludeCurrent: true,
         pageLimit: 1,
       }
-    }, null])
+    }])
   }
 
   async setMsgRead(peer: Peer) {
@@ -254,7 +241,7 @@ export class NTQQMsgApi extends Service {
       emojiId,
       emojiType,
       cnt: count
-    }, null])
+    }])
   }
 
   async fetchFavEmojiList(count: number) {
@@ -267,7 +254,8 @@ export class NTQQMsgApi extends Service {
   }
 
   async generateMsgUniqueId(chatType: number) {
-    const uniqueId = await invoke('nodeIKernelMsgService/generateMsgUniqueId', [{ chatType }])
+    const time = await this.getServerTime()
+    const uniqueId = await invoke('nodeIKernelMsgService/generateMsgUniqueId', [{ chatType, time }])
     if (typeof uniqueId === 'string') {
       return uniqueId
     } else {
@@ -275,4 +263,32 @@ export class NTQQMsgApi extends Service {
       return `${Date.now()}${random}`
     }
   }
+
+  async queryMsgsById(chatType: ChatType, msgId: string) {
+    const msgTime = this.getMsgTimeFromId(msgId)
+    return await invoke('nodeIKernelMsgService/queryMsgsWithFilterEx', [{
+      msgId,
+      msgTime: '0',
+      msgSeq: '0',
+      params: {
+        chatInfo: {
+          peerUid: '',
+          chatType
+        },
+        filterMsgToTime: msgTime,
+        filterMsgFromTime: msgTime,
+        isIncludeCurrent: true,
+        pageLimit: 1,
+      }
+    }])
+  }
+
+  getMsgTimeFromId(msgId: string) {
+    // 小概率相差1毫秒
+    return String(BigInt(msgId) >> 32n)
+  }
+
+  async getServerTime() {
+    return await invoke('nodeIKernelMSFService/getServerTime', [null])
+  }
 }
diff --git a/src/ntqqapi/api/user.ts b/src/ntqqapi/api/user.ts
index ccea3ca..22cce9f 100644
--- a/src/ntqqapi/api/user.ts
+++ b/src/ntqqapi/api/user.ts
@@ -1,9 +1,9 @@
-import { User, UserDetailInfoByUin, UserDetailInfoByUinV2, UserDetailInfoListenerArg, UserDetailSource, ProfileBizType } from '../types'
+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 { Time } from 'cosmokit'
+import { isNullable, Time } from 'cosmokit'
 import { Service, Context } from 'cordis'
 import { selfInfo } from '@/common/globalVars'
 
@@ -34,17 +34,14 @@ export class NTQQUserApi extends Service {
   }
 
   async fetchUserDetailInfo(uid: string) {
-    const result = await invoke<{ info: UserDetailInfoListenerArg }>(
+    const result = await invoke<{ info: UserDetailInfo }>(
       'nodeIKernelProfileService/fetchUserDetailInfo',
-      [
-        {
-          callFrom: 'BuddyProfileStore',
-          uid: [uid],
-          source: UserDetailSource.KSERVER,
-          bizList: [ProfileBizType.KALL]
-        },
-        null
-      ],
+      [{
+        callFrom: 'BuddyProfileStore',
+        uid: [uid],
+        source: UserDetailSource.KSERVER,
+        bizList: [ProfileBizType.KALL]
+      }],
       {
         cbCmd: 'nodeIKernelProfileListener/onUserDetailInfoChanged',
         afterFirstCmd: false,
@@ -70,13 +67,10 @@ export class NTQQUserApi extends Service {
     }
     const result = await invoke<{ info: User }>(
       'nodeIKernelProfileService/getUserDetailInfoWithBizInfo',
-      [
-        {
-          uid,
-          bizList: [0]
-        },
-        null,
-      ],
+      [{
+        uid,
+        bizList: [0]
+      }],
       {
         cbCmd: 'nodeIKernelProfileListener/onProfileDetailInfoChanged',
         afterFirstCmd: false,
@@ -129,9 +123,7 @@ export class NTQQUserApi extends Service {
   }
 
   async getUidByUinV1(uin: string) {
-    const session = getSession()
-    // 通用转换开始尝试
-    let uid = (await session?.getUixConvertService().getUid([uin]))?.uidInfo.get(uin)
+    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()) {
@@ -181,20 +173,14 @@ export class NTQQUserApi extends Service {
   async getUserDetailInfoByUinV2(uin: string) {
     return await invoke<UserDetailInfoByUinV2>(
       'nodeIKernelProfileService/getUserDetailInfoByUin',
-      [
-        { uin },
-        null,
-      ],
+      [{ uin }]
     )
   }
 
   async getUserDetailInfoByUin(uin: string) {
     return await invoke<UserDetailInfoByUin>(
       'nodeIKernelProfileService/getUserDetailInfoByUin',
-      [
-        { uin },
-        null,
-      ],
+      [{ uin }]
     )
   }
 
@@ -202,31 +188,21 @@ export class NTQQUserApi extends Service {
     const ret = await invoke('nodeIKernelUixConvertService/getUin', [{ uids: [uid] }])
     let uin = ret.uinInfo.get(uid)
     if (!uin) {
-      uin = (await this.getUserDetailInfo(uid)).uin //从QQ Native 转换
+      uin = (await this.getUserDetailInfo(uid)).uin
     }
     return uin
   }
 
   async getUinByUidV2(uid: string) {
-    const session = getSession()
-    if (session) {
-      let uin = (await session.getGroupService().getUinByUids([uid])).uins.get(uid)
-      if (uin) return uin
-      uin = (await session.getProfileService().getUinByUid('FriendsServiceImpl', [uid])).get(uid)
-      if (uin) return uin
-      uin = (await session.getUixConvertService().getUin([uid])).uinInfo.get(uid)
-      if (uin) return uin
-    } else {
-      let uin = (await invoke('nodeIKernelGroupService/getUinByUids', [{ uid: [uid] }])).uins.get(uid)
-      if (uin) return uin
-      uin = (await invoke('nodeIKernelProfileService/getUinByUid', [{ callFrom: 'FriendsServiceImpl', uid: [uid] }])).get(uid)
-      if (uin) return uin
-      uin = (await invoke('nodeIKernelUixConvertService/getUin', [{ uids: [uid] }])).uinInfo.get(uid)
-      if (uin) return uin
-    }
-    let uin = (await this.ctx.ntFriendApi.getBuddyIdMap(true)).get(uid)
+    let uin = (await invoke('nodeIKernelGroupService/getUinByUids', [{ uid: [uid] }])).uins.get(uid)
     if (uin) return uin
-    uin = (await this.getUserDetailInfo(uid)).uin //从QQ Native 转换
+    uin = (await invoke('nodeIKernelProfileService/getUinByUid', [{ callFrom: 'FriendsServiceImpl', uid: [uid] }])).get(uid)
+    if (uin) return uin
+    uin = (await invoke('nodeIKernelUixConvertService/getUin', [{ uids: [uid] }])).uinInfo.get(uid)
+    if (uin) return uin
+    uin = (await this.ctx.ntFriendApi.getBuddyIdMap(true)).get(uid)
+    if (uin) return uin
+    uin = (await this.getUserDetailInfo(uid)).uin
     return uin
   }
 
@@ -246,13 +222,10 @@ export class NTQQUserApi extends Service {
     }
   }
 
-  async getSelfNick(refresh = false) {
+  async getSelfNick(refresh = true) {
     if ((refresh || !selfInfo.nick) && selfInfo.uid) {
-      const userInfo = await this.getUserDetailInfo(selfInfo.uid)
-      if (userInfo) {
-        Object.assign(selfInfo, { nick: userInfo.nick })
-        return userInfo.nick
-      }
+      const { profiles } = await this.getUserSimpleInfo(selfInfo.uid)
+      selfInfo.nick = profiles[selfInfo.uid].coreInfo.nick
     }
     return selfInfo.nick
   }
@@ -281,4 +254,44 @@ export class NTQQUserApi extends Service {
       }
     }, null])
   }
+
+  async getUserSimpleInfo(uid: string, force = true) {
+    return await invoke<{ profiles: Record<string, SimpleInfo> }>(
+      'nodeIKernelProfileService/getUserSimpleInfo',
+      [{
+        uids: [uid],
+        force
+      }],
+      {
+        cbCmd: 'onProfileSimpleChanged',
+        afterFirstCmd: false,
+        cmdCB: payload => !isNullable(payload.profiles[uid]),
+      }
+    )
+  }
+
+  async getCoreAndBaseInfo(uids: string[]) {
+    return await invoke(
+      'nodeIKernelProfileService/getCoreAndBaseInfo',
+      [{
+        uids,
+        callFrom: 'nodeStore'
+      }]
+    )
+  }
+
+  async getRobotUinRange() {
+    const data = await invoke(
+      'nodeIKernelRobotService/getRobotUinRange',
+      [{
+        req: {
+          justFetchMsgConfig: '1',
+          type: 1,
+          version: 0,
+          aioKeywordVersion: 0
+        }
+      }]
+    )
+    return data.response.robotUinRanges
+  }
 }
diff --git a/src/ntqqapi/core.ts b/src/ntqqapi/core.ts
index 4a703f7..a5496fa 100644
--- a/src/ntqqapi/core.ts
+++ b/src/ntqqapi/core.ts
@@ -2,7 +2,6 @@ import { unlink } from 'node:fs/promises'
 import { Service, Context } from 'cordis'
 import { registerCallHook, registerReceiveHook, ReceiveCmdS } from './hook'
 import { Config as LLOBConfig } from '../common/types'
-import { llonebotError } from '../common/globalVars'
 import { isNumeric } from '../common/utils/misc'
 import { NTMethod } from './ntcall'
 import {
@@ -13,7 +12,8 @@ import {
   GroupMember,
   CategoryFriend,
   SimpleInfo,
-  ChatType
+  ChatType,
+  BuddyReqType
 } from './types'
 import { selfInfo } from '../common/globalVars'
 import { version } from '../version'
@@ -24,25 +24,26 @@ declare module 'cordis' {
     app: Core
   }
   interface Events {
-    'nt/message-created': (input: RawMessage[]) => void
+    'nt/message-created': (input: RawMessage) => void
     'nt/message-deleted': (input: RawMessage) => void
     'nt/message-sent': (input: RawMessage) => void
-    'nt/group-notify': (input: GroupNotify[]) => void
-    'nt/friend-request': (input: FriendRequest[]) => void
+    'nt/group-notify': (input: GroupNotify) => void
+    'nt/friend-request': (input: FriendRequest) => void
     'nt/group-member-info-updated': (input: { groupCode: string, members: GroupMember[] }) => void
     'nt/system-message-created': (input: Uint8Array) => void
   }
 }
 
 class Core extends Service {
-  static inject = ['ntMsgApi', 'ntFriendApi', 'ntGroupApi']
+  static inject = ['ntMsgApi', 'ntFriendApi', 'ntGroupApi', 'store']
+  public startTime = 0
 
   constructor(protected ctx: Context, public config: Core.Config) {
     super(ctx, 'app', true)
   }
 
   public start() {
-    llonebotError.otherError = ''
+    this.startTime = Date.now()
     this.registerListener()
     this.ctx.logger.info(`LLOneBot/${version}`)
     this.ctx.on('llonebot/config-updated', input => {
@@ -121,7 +122,7 @@ class Core extends Service {
               this.ctx.ntMsgApi.getMsgHistory(peer, '', 20).then(({ msgList }) => {
                 const lastTempMsg = msgList.at(-1)
                 if (Date.now() / 1000 - Number(lastTempMsg?.msgTime) < 5) {
-                  this.ctx.parallel('nt/message-created', [lastTempMsg!])
+                  this.ctx.parallel('nt/message-created', lastTempMsg!)
                 }
               })
             })
@@ -161,7 +162,16 @@ class Core extends Service {
     })
 
     registerReceiveHook<{ msgList: RawMessage[] }>([ReceiveCmdS.NEW_MSG, ReceiveCmdS.NEW_ACTIVE_MSG], payload => {
-      this.ctx.parallel('nt/message-created', payload.msgList)
+      for (const message of payload.msgList) {
+        // 过滤启动之前的消息
+        if (parseInt(message.msgTime) < this.startTime / 1000) {
+          continue
+        }
+        if (message.senderUin && message.senderUin !== '0') {
+          this.ctx.store.addMsgCache(message)
+        }
+        this.ctx.parallel('nt/message-created', message)
+      }
     })
 
     const sentMsgIds = new Map<string, boolean>()
@@ -199,20 +209,28 @@ class Core extends Service {
         } catch (e) {
           return
         }
-        const list = notifies.filter(v => {
-          const flag = v.group.groupCode + '|' + v.seq + '|' + v.type
-          if (groupNotifyFlags.includes(flag)) {
-            return false
+        for (const notify of notifies) {
+          const flag = notify.group.groupCode + '|' + notify.seq + '|' + notify.type
+          const notifyTime = parseInt(notify.seq) / 1000
+          if (groupNotifyFlags.includes(flag) || notifyTime < this.startTime) {
+            continue
           }
           groupNotifyFlags.push(flag)
-          return true
-        })
-        this.ctx.parallel('nt/group-notify', list)
+          this.ctx.parallel('nt/group-notify', notify)
+        }
       }
     })
 
     registerReceiveHook<FriendRequestNotify>(ReceiveCmdS.FRIEND_REQUEST, payload => {
-      this.ctx.parallel('nt/friend-request', payload.data.buddyReqs)
+      for (const req of payload.data.buddyReqs) {
+        if (!!req.isInitiator || (req.isDecide && req.reqType !== BuddyReqType.MeInitiatorWaitPeerConfirm)) {
+          continue
+        }
+        if (+req.reqTime < this.startTime / 1000) {
+          continue
+        }
+        this.ctx.parallel('nt/friend-request', req)
+      }
     })
 
     invoke('nodeIKernelMsgListener/onRecvSysMsg', [], { registerEvent: true })
diff --git a/src/ntqqapi/entities.ts b/src/ntqqapi/entities.ts
index ef0671b..64d0bd2 100644
--- a/src/ntqqapi/entities.ts
+++ b/src/ntqqapi/entities.ts
@@ -23,9 +23,7 @@ import { encodeSilk } from '../common/utils/audio'
 import { Context } from 'cordis'
 import { isNullable } from 'cosmokit'
 
-//export const mFaceCache = new Map<string, string>() // emojiId -> faceName
-
-export namespace SendElementEntities {
+export namespace SendElement {
   export function text(content: string): SendTextElement {
     return {
       elementType: ElementType.Text,
diff --git a/src/ntqqapi/helper/rkey.ts b/src/ntqqapi/helper/rkey.ts
index afd091b..726a009 100644
--- a/src/ntqqapi/helper/rkey.ts
+++ b/src/ntqqapi/helper/rkey.ts
@@ -31,30 +31,18 @@ export class RkeyManager {
 
   isExpired(): boolean {
     const now = new Date().getTime() / 1000
-    // console.log(`now: ${now}, expired_time: ${this.rkeyData.expired_time}`)
     return now > this.rkeyData.expired_time
   }
 
   async refreshRkey() {
-    //刷新rkey
     this.rkeyData = await this.fetchServerRkey()
   }
 
-  async fetchServerRkey() {
-    return new Promise<ServerRkeyData>((resolve, reject) => {
-      fetch(this.serverUrl)
-        .then(response => {
-          if (!response.ok) {
-            return reject(response.statusText) // 请求失败,返回错误信息
-          }
-          return response.json() // 解析 JSON 格式的响应体
-        })
-        .then(data => {
-          resolve(data)
-        })
-        .catch(error => {
-          reject(error)
-        })
-    })
+  async fetchServerRkey(): Promise<ServerRkeyData> {
+    const response = await fetch(this.serverUrl)
+    if (!response.ok) {
+      throw new Error(response.statusText)
+    }
+    return response.json()
   }
 }
diff --git a/src/ntqqapi/hook.ts b/src/ntqqapi/hook.ts
index f973183..9e7ddea 100644
--- a/src/ntqqapi/hook.ts
+++ b/src/ntqqapi/hook.ts
@@ -26,7 +26,6 @@ export enum ReceiveCmdS {
   SELF_STATUS = 'nodeIKernelProfileListener/onSelfStatusChanged',
   CACHE_SCAN_FINISH = 'nodeIKernelStorageCleanListener/onFinishScan',
   MEDIA_UPLOAD_COMPLETE = 'nodeIKernelMsgListener/onRichMediaUploadComplete',
-  SKEY_UPDATE = 'onSkeyUpdate',
 }
 
 type NTReturnData = [
@@ -96,7 +95,7 @@ export function hookNTQQApiCall(window: BrowserWindow, onlyLog: boolean) {
       const isLogger = args[3]?.[0]?.eventName?.startsWith('ns-LoggerApi')
       if (!isLogger) {
         try {
-          logHook && log('call NTQQ api', thisArg, args)
+          logHook && log('call NTQQ api', args)
         } catch (e) { }
         if (!onlyLog) {
           try {
diff --git a/src/ntqqapi/ntcall.ts b/src/ntqqapi/ntcall.ts
index 5ed6ad3..c7197e7 100644
--- a/src/ntqqapi/ntcall.ts
+++ b/src/ntqqapi/ntcall.ts
@@ -13,7 +13,8 @@ import {
   NodeIKernelUixConvertService,
   NodeIKernelRichMediaService,
   NodeIKernelTicketService,
-  NodeIKernelTipOffService
+  NodeIKernelTipOffService,
+  NodeIKernelRobotService
 } from './services'
 
 export enum NTClass {
@@ -39,7 +40,6 @@ export enum NTMethod {
   MEDIA_FILE_PATH = 'nodeIKernelMsgService/getRichMediaFilePathForGuild',
   RECALL_MSG = 'nodeIKernelMsgService/recallMsg',
   EMOJI_LIKE = 'nodeIKernelMsgService/setMsgEmojiLikes',
-  FORWARD_MSG = 'nodeIKernelMsgService/forwardMsgWithComment',
 
   SELF_INFO = 'fetchAuthData',
   FILE_TYPE = 'getFileType',
@@ -93,6 +93,7 @@ interface NTService {
   nodeIKernelRichMediaService: NodeIKernelRichMediaService
   nodeIKernelTicketService: NodeIKernelTicketService
   nodeIKernelTipOffService: NodeIKernelTipOffService
+  nodeIKernelRobotService: NodeIKernelRobotService
 }
 
 interface InvokeOptions<ReturnType> {
diff --git a/src/ntqqapi/services/NodeIKernelMsgService.ts b/src/ntqqapi/services/NodeIKernelMsgService.ts
index 449b8e1..af6276a 100644
--- a/src/ntqqapi/services/NodeIKernelMsgService.ts
+++ b/src/ntqqapi/services/NodeIKernelMsgService.ts
@@ -10,7 +10,9 @@ export interface NodeIKernelMsgService {
 
   setStatus(args: { status: number, extStatus: number, batteryStatus: number }): Promise<GeneralCallResult>
 
-  forwardMsg(msgIds: string[], srcContact: Peer, dstContacts: Peer[], commentElements: MessageElement[]): Promise<GeneralCallResult>
+  forwardMsg(msgIds: string[], srcContact: Peer, dstContacts: Peer[], commentElements: MessageElement[]): Promise<GeneralCallResult & {
+    detailErr: Map<unknown, unknown>
+  }>
 
   forwardMsgWithComment(...args: unknown[]): Promise<GeneralCallResult>
 
@@ -71,7 +73,7 @@ export interface NodeIKernelMsgService {
 
   downloadRichMedia(...args: unknown[]): unknown
 
-  setMsgEmojiLikes(...args: unknown[]): unknown
+  setMsgEmojiLikes(...args: unknown[]): Promise<GeneralCallResult>
 
   getMsgEmojiLikesList(peer: Peer, msgSeq: string, emojiId: string, emojiType: string, cookie: string, bForward: boolean, number: number): Promise<{
     result: number
diff --git a/src/ntqqapi/services/NodeIKernelRobotService.ts b/src/ntqqapi/services/NodeIKernelRobotService.ts
new file mode 100644
index 0000000..4dca0a3
--- /dev/null
+++ b/src/ntqqapi/services/NodeIKernelRobotService.ts
@@ -0,0 +1,13 @@
+import { GeneralCallResult } from './common'
+
+export interface NodeIKernelRobotService {
+  getRobotUinRange(req: unknown): Promise<GeneralCallResult & {
+    response: {
+      version: number
+      robotUinRanges: {
+        minUin: string
+        maxUin: string
+      }[]
+    }
+  }>
+}
diff --git a/src/ntqqapi/services/index.ts b/src/ntqqapi/services/index.ts
index 2ce5f5a..f233136 100644
--- a/src/ntqqapi/services/index.ts
+++ b/src/ntqqapi/services/index.ts
@@ -9,3 +9,4 @@ export * from './NodeIKernelUixConvertService'
 export * from './NodeIKernelRichMediaService'
 export * from './NodeIKernelTicketService'
 export * from './NodeIKernelTipOffService'
+export * from './NodeIKernelRobotService'
diff --git a/src/ntqqapi/types/notify.ts b/src/ntqqapi/types/notify.ts
index 3d8362f..cdf5189 100644
--- a/src/ntqqapi/types/notify.ts
+++ b/src/ntqqapi/types/notify.ts
@@ -56,20 +56,8 @@ export enum GroupRequestOperateTypes {
 }
 
 export enum BuddyReqType {
-  KMEINITIATOR,
-  KPEERINITIATOR,
-  KMEAGREED,
-  KMEAGREEDANDADDED,
-  KPEERAGREED,
-  KPEERAGREEDANDADDED,
-  KPEERREFUSED,
-  KMEREFUSED,
-  KMEIGNORED,
-  KMEAGREEANYONE,
-  KMESETQUESTION,
-  KMEAGREEANDADDFAILED,
-  KMSGINFO,
-  KMEINITIATORWAITPEERCONFIRM
+  MsgInfo = 12,
+  MeInitiatorWaitPeerConfirm = 13,
 }
 
 export interface FriendRequest {
@@ -128,4 +116,4 @@ export interface GroupExtParam {
     memberIcon: number
     memberInfoSeq: number
   }
-}
\ No newline at end of file
+}
diff --git a/src/ntqqapi/types/user.ts b/src/ntqqapi/types/user.ts
index 09054d7..99f8d8d 100644
--- a/src/ntqqapi/types/user.ts
+++ b/src/ntqqapi/types/user.ts
@@ -221,11 +221,6 @@ interface RelationFlags {
   isHidePrivilegeIcon: number
 }
 
-export interface FriendV2 extends SimpleInfo {
-  categoryId?: number
-  categroyName?: string
-}
-
 interface CommonExt {
   constellation: number
   shengXiao: number
@@ -255,7 +250,7 @@ interface PhotoWall {
   picList: Pic[]
 }
 
-export interface UserDetailInfoListenerArg {
+export interface UserDetailInfo {
   uid: string
   uin: string
   simpleInfo: SimpleInfo
diff --git a/src/onebot11/action/go-cqhttp/UploadGroupFile.ts b/src/onebot11/action/go-cqhttp/UploadGroupFile.ts
index 10ba0e5..72cc3ad 100644
--- a/src/onebot11/action/go-cqhttp/UploadGroupFile.ts
+++ b/src/onebot11/action/go-cqhttp/UploadGroupFile.ts
@@ -1,6 +1,6 @@
 import { BaseAction, Schema } from '../BaseAction'
 import { ActionName } from '../types'
-import { SendElementEntities } from '@/ntqqapi/entities'
+import { SendElement } from '@/ntqqapi/entities'
 import { uri2local } from '@/common/utils'
 import { sendMsg, createPeer, CreatePeerMode } from '../../helper/createMessage'
 
@@ -27,7 +27,7 @@ export class UploadGroupFile extends BaseAction<Payload, null> {
     if (!success) {
       throw new Error(errMsg)
     }
-    const file = await SendElementEntities.file(this.ctx, path, payload.name || fileName, payload.folder ?? payload.folder_id)
+    const file = await SendElement.file(this.ctx, path, payload.name || fileName, payload.folder ?? payload.folder_id)
     const peer = await createPeer(this.ctx, payload, CreatePeerMode.Group)
     await sendMsg(this.ctx, peer, [file], [])
     return null
diff --git a/src/onebot11/action/go-cqhttp/UploadPrivateFile.ts b/src/onebot11/action/go-cqhttp/UploadPrivateFile.ts
index 667b791..7c1c07c 100644
--- a/src/onebot11/action/go-cqhttp/UploadPrivateFile.ts
+++ b/src/onebot11/action/go-cqhttp/UploadPrivateFile.ts
@@ -1,6 +1,6 @@
 import { BaseAction, Schema } from '../BaseAction'
 import { ActionName } from '../types'
-import { SendElementEntities } from '@/ntqqapi/entities'
+import { SendElement } from '@/ntqqapi/entities'
 import { uri2local } from '@/common/utils'
 import { sendMsg, createPeer, CreatePeerMode } from '../../helper/createMessage'
 
@@ -23,7 +23,7 @@ export class UploadPrivateFile extends BaseAction<UploadPrivateFilePayload, null
     if (!success) {
       throw new Error(errMsg)
     }
-    const sendFileEle = await SendElementEntities.file(this.ctx, path, payload.name || fileName)
+    const sendFileEle = await SendElement.file(this.ctx, path, payload.name || fileName)
     const peer = await createPeer(this.ctx, payload, CreatePeerMode.Private)
     await sendMsg(this.ctx, peer, [sendFileEle], [])
     return null
diff --git a/src/onebot11/action/index.ts b/src/onebot11/action/index.ts
index 1558639..a439a2c 100644
--- a/src/onebot11/action/index.ts
+++ b/src/onebot11/action/index.ts
@@ -45,7 +45,7 @@ import { GetGroupMsgHistory } from './go-cqhttp/GetGroupMsgHistory'
 import GetFile from './file/GetFile'
 import { GetForwardMsg } from './go-cqhttp/GetForwardMsg'
 import { GetCookies } from './user/GetCookie'
-import { SetMsgEmojiLike } from './msg/SetMsgEmojiLike'
+import { SetMsgEmojiLike } from './llonebot/SetMsgEmojiLike'
 import { ForwardFriendSingleMsg, ForwardGroupSingleMsg } from './msg/ForwardSingleMsg'
 import { GetEssenceMsgList } from './go-cqhttp/GetGroupEssence'
 import { GetGroupHonorInfo } from './group/GetGroupHonorInfo'
@@ -71,6 +71,7 @@ import { UploadGroupFile } from './go-cqhttp/UploadGroupFile'
 import { UploadPrivateFile } from './go-cqhttp/UploadPrivateFile'
 import { GetGroupFileUrl } from './go-cqhttp/GetGroupFileUrl'
 import { GetGroupNotice } from './go-cqhttp/GetGroupNotice'
+import { GetRobotUinRange } from './llonebot/GetRobotUinRange'
 
 export function initActionMap(adapter: Adapter) {
   const actionHandlers = [
@@ -87,6 +88,8 @@ export function initActionMap(adapter: Adapter) {
     new GetFriendMsgHistory(adapter),
     new FetchEmojiLike(adapter),
     new FetchCustomFace(adapter),
+    new SetMsgEmojiLike(adapter),
+    new GetRobotUinRange(adapter),
     // onebot11
     new SendLike(adapter),
     new GetMsg(adapter),
@@ -117,7 +120,6 @@ export function initActionMap(adapter: Adapter) {
     new GetRecord(adapter),
     new CleanCache(adapter),
     new GetCookies(adapter),
-    new SetMsgEmojiLike(adapter),
     new ForwardFriendSingleMsg(adapter),
     new ForwardGroupSingleMsg(adapter),
     // go-cqhttp
diff --git a/src/onebot11/action/llonebot/GetRobotUinRange.ts b/src/onebot11/action/llonebot/GetRobotUinRange.ts
new file mode 100644
index 0000000..151dc51
--- /dev/null
+++ b/src/onebot11/action/llonebot/GetRobotUinRange.ts
@@ -0,0 +1,11 @@
+import { BaseAction } from '../BaseAction'
+import { ActionName } from '../types'
+import { Dict } from 'cosmokit'
+
+export class GetRobotUinRange extends BaseAction<void, Dict[]> {
+  actionName = ActionName.GetRobotUinRange
+
+  async _handle() {
+    return await this.ctx.ntUserApi.getRobotUinRange()
+  }
+}
diff --git a/src/onebot11/action/msg/SetMsgEmojiLike.ts b/src/onebot11/action/llonebot/SetMsgEmojiLike.ts
similarity index 100%
rename from src/onebot11/action/msg/SetMsgEmojiLike.ts
rename to src/onebot11/action/llonebot/SetMsgEmojiLike.ts
diff --git a/src/onebot11/action/msg/ForwardSingleMsg.ts b/src/onebot11/action/msg/ForwardSingleMsg.ts
index 18098c3..b11d1e0 100644
--- a/src/onebot11/action/msg/ForwardSingleMsg.ts
+++ b/src/onebot11/action/msg/ForwardSingleMsg.ts
@@ -19,8 +19,8 @@ abstract class ForwardSingleMsg extends BaseAction<Payload, null> {
     }
     const peer = await createPeer(this.ctx, payload)
     const ret = await this.ctx.ntMsgApi.forwardMsg(msg.peer, peer, [msg.msgId])
-    if (ret.result !== 0) {
-      throw new Error(`转发消息失败 ${ret.errMsg}`)
+    if (ret.length === 0) {
+      throw new Error(`转发消息失败`)
     }
     return null
   }
diff --git a/src/onebot11/action/msg/GetMsg.ts b/src/onebot11/action/msg/GetMsg.ts
index 1ddf0dd..27de7ca 100644
--- a/src/onebot11/action/msg/GetMsg.ts
+++ b/src/onebot11/action/msg/GetMsg.ts
@@ -25,14 +25,11 @@ class GetMsg extends BaseAction<PayloadType, OB11Message> {
       peerUid: msgInfo.peer.peerUid,
       chatType: msgInfo.peer.chatType
     }
-    const msg = this.adapter.getMsgCache(msgInfo.msgId) ?? (await this.ctx.ntMsgApi.getMsgsByMsgId(peer, [msgInfo.msgId])).msgList[0]
+    const msg = this.ctx.store.getMsgCache(msgInfo.msgId) ?? (await this.ctx.ntMsgApi.getMsgsByMsgId(peer, [msgInfo.msgId])).msgList[0]
     const retMsg = await OB11Entities.message(this.ctx, msg)
     if (!retMsg) {
       throw new Error('消息为空')
     }
-    retMsg.message_id = this.ctx.store.createMsgShortId(peer, msg.msgId)
-    retMsg.message_seq = retMsg.message_id
-    retMsg.real_id = retMsg.message_id
     return retMsg
   }
 }
diff --git a/src/onebot11/action/types.ts b/src/onebot11/action/types.ts
index 2cb911f..7b9edb6 100644
--- a/src/onebot11/action/types.ts
+++ b/src/onebot11/action/types.ts
@@ -25,6 +25,8 @@ export enum ActionName {
   FetchCustomFace = 'fetch_custom_face',
   GetFriendMsgHistory = 'get_friend_msg_history',
   SendForwardMsg = 'send_forward_msg',
+  SetMsgEmojiLike = 'set_msg_emoji_like',
+  GetRobotUinRange = 'get_robot_uin_range',
   // onebot 11
   SendLike = 'send_like',
   GetLoginInfo = 'get_login_info',
@@ -38,7 +40,6 @@ export enum ActionName {
   SendGroupMsg = 'send_group_msg',
   SendPrivateMsg = 'send_private_msg',
   DeleteMsg = 'delete_msg',
-  SetMsgEmojiLike = 'set_msg_emoji_like',
   SetGroupAddRequest = 'set_group_add_request',
   SetFriendAddRequest = 'set_friend_add_request',
   SetGroupLeave = 'set_group_leave',
@@ -58,7 +59,7 @@ export enum ActionName {
   GetCookies = 'get_cookies',
   ForwardFriendSingleMsg = 'forward_friend_single_msg',
   ForwardGroupSingleMsg = 'forward_group_single_msg',
-  // 以下为go-cqhttp api
+  // go-cqhttp
   GoCQHTTP_SendGroupForwardMsg = 'send_group_forward_msg',
   GoCQHTTP_SendPrivateForwardMsg = 'send_private_forward_msg',
   GoCQHTTP_GetStrangerInfo = 'get_stranger_info',
diff --git a/src/onebot11/adapter.ts b/src/onebot11/adapter.ts
index 5e2b38c..1c60dcd 100644
--- a/src/onebot11/adapter.ts
+++ b/src/onebot11/adapter.ts
@@ -37,8 +37,6 @@ declare module 'cordis' {
 class OneBot11Adapter extends Service {
   static inject = ['ntMsgApi', 'ntFileApi', 'ntFileCacheApi', 'ntFriendApi', 'ntGroupApi', 'ntUserApi', 'ntWindowApi', 'ntWebApi', 'store']
 
-  public messages: Map<string, RawMessage> = new Map()
-  public startTime = 0
   private ob11WebSocket: OB11WebSocket
   private ob11WebSocketReverseManager: OB11WebSocketReverseManager
   private ob11Http: OB11Http
@@ -74,24 +72,6 @@ class OneBot11Adapter extends Service {
     })
   }
 
-  /** 缓存近期消息内容 */
-  public async addMsgCache(msg: RawMessage) {
-    const expire = this.config.msgCacheExpire * 1000
-    if (expire === 0) {
-      return
-    }
-    const id = msg.msgId
-    this.messages.set(id, msg)
-    setTimeout(() => {
-      this.messages.delete(id)
-    }, expire)
-  }
-
-  /** 获取近期消息内容 */
-  public getMsgCache(msgId: string) {
-    return this.messages.get(msgId)
-  }
-
   public dispatch(event: OB11BaseEvent | OB11Message) {
     if (this.config.enableWs) {
       this.ob11WebSocket.emitEvent(event)
@@ -108,115 +88,99 @@ class OneBot11Adapter extends Service {
     }
   }
 
-  private async handleGroupNotify(notifies: GroupNotify[]) {
-    for (const notify of notifies) {
-      try {
-        const notifyTime = parseInt(notify.seq) / 1000
-        if (notifyTime < this.startTime) {
-          continue
-        }
-        const flag = notify.group.groupCode + '|' + notify.seq + '|' + notify.type
-        if ([GroupNotifyType.MEMBER_LEAVE_NOTIFY_ADMIN, GroupNotifyType.KICK_MEMBER_NOTIFY_ADMIN].includes(notify.type)) {
-          this.ctx.logger.info('有成员退出通知', notify)
-          const member1Uin = await this.ctx.ntUserApi.getUinByUid(notify.user1.uid)
-          let operatorId = member1Uin
-          let subType: GroupDecreaseSubType = 'leave'
-          if (notify.user2.uid) {
-            // 是被踢的
-            const member2Uin = await this.ctx.ntUserApi.getUinByUid(notify.user2.uid)
-            if (member2Uin) {
-              operatorId = member2Uin
-            }
-            subType = 'kick'
+  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)) {
+        this.ctx.logger.info('有成员退出通知', notify)
+        const member1Uin = await this.ctx.ntUserApi.getUinByUid(notify.user1.uid)
+        let operatorId = member1Uin
+        let subType: GroupDecreaseSubType = 'leave'
+        if (notify.user2.uid) {
+          // 是被踢的
+          const member2Uin = await this.ctx.ntUserApi.getUinByUid(notify.user2.uid)
+          if (member2Uin) {
+            operatorId = member2Uin
           }
-          const event = new OB11GroupDecreaseEvent(
-            parseInt(notify.group.groupCode),
-            parseInt(member1Uin),
-            parseInt(operatorId),
-            subType,
-          )
-          this.dispatch(event)
+          subType = 'kick'
         }
-        else if (notify.type === GroupNotifyType.REQUEST_JOIN_NEED_ADMINI_STRATOR_PASS && notify.status === GroupNotifyStatus.KUNHANDLE) {
-          this.ctx.logger.info('有加群请求')
-          const requestUin = await this.ctx.ntUserApi.getUinByUid(notify.user1.uid)
-          const event = new OB11GroupRequestEvent(
-            parseInt(notify.group.groupCode),
-            parseInt(requestUin) || 0,
-            flag,
-            notify.postscript,
-          )
-          this.dispatch(event)
-        }
-        else if (notify.type === GroupNotifyType.INVITED_BY_MEMBER && notify.status === GroupNotifyStatus.KUNHANDLE) {
-          this.ctx.logger.info('收到邀请我加群通知')
-          const userId = await this.ctx.ntUserApi.getUinByUid(notify.user2.uid)
-          const event = new OB11GroupRequestEvent(
-            parseInt(notify.group.groupCode),
-            parseInt(userId) || 0,
-            flag,
-            notify.postscript,
-            undefined,
-            'invite'
-          )
-          this.dispatch(event)
-        }
-        else if (notify.type === GroupNotifyType.INVITED_NEED_ADMINI_STRATOR_PASS && notify.status === GroupNotifyStatus.KUNHANDLE) {
-          this.ctx.logger.info('收到群员邀请加群通知')
-          const userId = await this.ctx.ntUserApi.getUinByUid(notify.user1.uid)
-          const event = new OB11GroupRequestEvent(
-            parseInt(notify.group.groupCode),
-            parseInt(userId) || 0,
-            flag,
-            notify.postscript
-          )
-          this.dispatch(event)
-        }
-      } catch (e) {
-        this.ctx.logger.error('解析群通知失败', (e as Error).stack)
+        const event = new OB11GroupDecreaseEvent(
+          parseInt(notify.group.groupCode),
+          parseInt(member1Uin),
+          parseInt(operatorId),
+          subType,
+        )
+        this.dispatch(event)
       }
+      else if (notify.type === GroupNotifyType.REQUEST_JOIN_NEED_ADMINI_STRATOR_PASS && notify.status === GroupNotifyStatus.KUNHANDLE) {
+        this.ctx.logger.info('有加群请求')
+        const requestUin = await this.ctx.ntUserApi.getUinByUid(notify.user1.uid)
+        const event = new OB11GroupRequestEvent(
+          parseInt(notify.group.groupCode),
+          parseInt(requestUin) || 0,
+          flag,
+          notify.postscript,
+        )
+        this.dispatch(event)
+      }
+      else if (notify.type === GroupNotifyType.INVITED_BY_MEMBER && notify.status === GroupNotifyStatus.KUNHANDLE) {
+        this.ctx.logger.info('收到邀请我加群通知')
+        const userId = await this.ctx.ntUserApi.getUinByUid(notify.user2.uid)
+        const event = new OB11GroupRequestEvent(
+          parseInt(notify.group.groupCode),
+          parseInt(userId) || 0,
+          flag,
+          notify.postscript,
+          undefined,
+          'invite'
+        )
+        this.dispatch(event)
+      }
+      else if (notify.type === GroupNotifyType.INVITED_NEED_ADMINI_STRATOR_PASS && notify.status === GroupNotifyStatus.KUNHANDLE) {
+        this.ctx.logger.info('收到群员邀请加群通知')
+        const userId = await this.ctx.ntUserApi.getUinByUid(notify.user1.uid)
+        const event = new OB11GroupRequestEvent(
+          parseInt(notify.group.groupCode),
+          parseInt(userId) || 0,
+          flag,
+          notify.postscript
+        )
+        this.dispatch(event)
+      }
+    } catch (e) {
+      this.ctx.logger.error('解析群通知失败', (e as Error).stack)
     }
   }
 
-  private handleMsg(msgList: RawMessage[]) {
-    for (const message of msgList) {
-      // 过滤启动之前的消息
-      if (parseInt(message.msgTime) < this.startTime / 1000) {
-        continue
+  private handleMsg(message: RawMessage) {
+    OB11Entities.message(this.ctx, message).then(msg => {
+      if (!msg) {
+        return
       }
-      this.addMsgCache(message)
+      if (!this.config.debug && msg.message.length === 0) {
+        return
+      }
+      const isSelfMsg = msg.user_id.toString() === selfInfo.uin
+      if (isSelfMsg && !this.config.reportSelfMessage) {
+        return
+      }
+      if (isSelfMsg) {
+        msg.target_id = parseInt(message.peerUin)
+      }
+      this.dispatch(msg)
+    }).catch(e => this.ctx.logger.error('constructMessage error: ', e.stack.toString()))
 
-      OB11Entities.message(this.ctx, message)
-        .then((msg) => {
-          if (!msg) {
-            return
-          }
-          if (!this.config.debug && msg.message.length === 0) {
-            return
-          }
-          const isSelfMsg = msg.user_id.toString() === selfInfo.uin
-          if (isSelfMsg && !this.config.reportSelfMessage) {
-            return
-          }
-          if (isSelfMsg) {
-            msg.target_id = parseInt(message.peerUin)
-          }
-          this.dispatch(msg)
-        })
-        .catch((e) => this.ctx.logger.error('constructMessage error: ', e.stack.toString()))
+    OB11Entities.groupEvent(this.ctx, message).then(groupEvent => {
+      if (groupEvent) {
+        this.dispatch(groupEvent)
+      }
+    })
 
-      OB11Entities.groupEvent(this.ctx, message).then((groupEvent) => {
-        if (groupEvent) {
-          this.dispatch(groupEvent)
-        }
-      })
-
-      OB11Entities.privateEvent(this.ctx, message).then((privateEvent) => {
-        if (privateEvent) {
-          this.dispatch(privateEvent)
-        }
-      })
-    }
+    OB11Entities.privateEvent(this.ctx, message).then(privateEvent => {
+      if (privateEvent) {
+        this.dispatch(privateEvent)
+      }
+    })
   }
 
   private handleRecallMsg(message: RawMessage) {
@@ -235,30 +199,22 @@ class OneBot11Adapter extends Service {
     })
   }
 
-  private async handleFriendRequest(buddyReqs: FriendRequest[]) {
-    for (const req of buddyReqs) {
-      if (!!req.isInitiator || (req.isDecide && req.reqType !== BuddyReqType.KMEINITIATORWAITPEERCONFIRM)) {
-        continue
-      }
-      if (+req.reqTime < this.startTime / 1000) {
-        continue
-      }
-      let userId = 0
-      try {
-        const requesterUin = await this.ctx.ntUserApi.getUinByUid(req.friendUid)
-        userId = parseInt(requesterUin)
-      } catch (e) {
-        this.ctx.logger.error('获取加好友者QQ号失败', e)
-      }
-      const flag = req.friendUid + '|' + req.reqTime
-      const comment = req.extWords
-      const friendRequestEvent = new OB11FriendRequestEvent(
-        userId,
-        comment,
-        flag
-      )
-      this.dispatch(friendRequestEvent)
+  private async handleFriendRequest(req: FriendRequest) {
+    let userId = 0
+    try {
+      const requesterUin = await this.ctx.ntUserApi.getUinByUid(req.friendUid)
+      userId = parseInt(requesterUin)
+    } catch (e) {
+      this.ctx.logger.error('获取加好友者QQ号失败', e)
     }
+    const flag = req.friendUid + '|' + req.reqTime
+    const comment = req.extWords
+    const friendRequestEvent = new OB11FriendRequestEvent(
+      userId,
+      comment,
+      flag
+    )
+    this.dispatch(friendRequestEvent)
   }
 
   private async handleConfigUpdated(config: LLOBConfig) {
@@ -374,7 +330,6 @@ class OneBot11Adapter extends Service {
   }
 
   public start() {
-    this.startTime = Date.now()
     if (this.config.enableWs) {
       this.ob11WebSocket.start()
     }
@@ -397,7 +352,7 @@ class OneBot11Adapter extends Service {
       this.handleRecallMsg(input)
     })
     this.ctx.on('nt/message-sent', input => {
-      this.handleMsg([input])
+      this.handleMsg(input)
     })
     this.ctx.on('nt/group-notify', input => {
       this.handleGroupNotify(input)
diff --git a/src/onebot11/entities.ts b/src/onebot11/entities.ts
index daffca6..8912e8b 100644
--- a/src/onebot11/entities.ts
+++ b/src/onebot11/entities.ts
@@ -20,7 +20,7 @@ import {
   Sex,
   TipGroupElementType,
   User,
-  FriendV2
+  SimpleInfo
 } from '../ntqqapi/types'
 import { EventType } from './event/OB11BaseEvent'
 import { encodeCQCode } from './cqcode'
@@ -338,7 +338,6 @@ export namespace OB11Entities {
             key: marketFaceElement.key
           }
         }
-        //mFaceCache.set(emojiId, element.marketFaceElement.faceName!)
       }
       else if (element.markdownElement) {
         const { markdownElement } = element
@@ -519,11 +518,11 @@ export namespace OB11Entities {
             if (!replyMsgList?.length) {
               return
             }
-            const shortId = ctx.store.getShortIdByMsgInfo(peer, replyMsgList[0].msgId)
+            const shortId = ctx.store.createMsgShortId(peer, replyMsgList[0].msgId)
             return new OB11GroupMsgEmojiLikeEvent(
               parseInt(msg.peerUid),
               parseInt(senderUin),
-              shortId!,
+              shortId,
               [{
                 emoji_id: emojiId,
                 count: 1,
@@ -569,8 +568,7 @@ export namespace OB11Entities {
                 pokedetail
               )
             }
-          }
-          if (grayTipElement.jsonGrayTipElement?.busiId === '2401' && json.items[2]) {
+          } else if (grayTipElement.jsonGrayTipElement?.busiId === '2401' && json.items[2]) {
             ctx.logger.info('收到群精华消息', json)
             const searchParams = new URL(json.items[2].jp).searchParams
             const msgSeq = searchParams.get('seq')
@@ -592,8 +590,7 @@ export namespace OB11Entities {
               parseInt(essence.items[0]?.msgSenderUin ?? sourceMsg.senderUin),
               parseInt(essence.items[0]?.opUin ?? '0'),
             )
-          }
-          if (grayTipElement.jsonGrayTipElement?.busiId === '2407') {
+          } else if (grayTipElement.jsonGrayTipElement?.busiId === '2407') {
             const memberUin = json.items[1].param[0]
             const title = json.items[3].txt
             ctx.logger.info('收到群成员新头衔消息', json)
@@ -603,6 +600,11 @@ export namespace OB11Entities {
               }
             })
             return new OB11GroupTitleEvent(parseInt(msg.peerUid), parseInt(memberUin), title)
+          } else if (grayTipElement.jsonGrayTipElement?.busiId === '19217') {
+            ctx.logger.info('收到新人被邀请进群消息', grayTipElement)
+            const userId = new URL(json.items[2].jp).searchParams.get('robot_uin')
+            const operatorId = new URL(json.items[0].jp).searchParams.get('uin')
+            return new OB11GroupIncreaseEvent(Number(msg.peerUid), Number(userId), Number(operatorId), 'invite')
           }
         }
       }
@@ -649,7 +651,7 @@ export namespace OB11Entities {
     return friends.map(friend)
   }
 
-  export function friendV2(raw: FriendV2): OB11User {
+  export function friendV2(raw: SimpleInfo): OB11User {
     return {
       ...omit(raw.baseInfo, ['richBuffer', 'phoneNum']),
       ...omit(raw.coreInfo, ['nick']),
@@ -661,7 +663,7 @@ export namespace OB11Entities {
     }
   }
 
-  export function friendsV2(raw: FriendV2[]): OB11User[] {
+  export function friendsV2(raw: SimpleInfo[]): OB11User[] {
     return raw.map(friendV2)
   }
 
diff --git a/src/onebot11/event/notice/OB11MsgEmojiLikeEvent.ts b/src/onebot11/event/notice/OB11MsgEmojiLikeEvent.ts
index 9173aa0..b33d045 100644
--- a/src/onebot11/event/notice/OB11MsgEmojiLikeEvent.ts
+++ b/src/onebot11/event/notice/OB11MsgEmojiLikeEvent.ts
@@ -8,17 +8,15 @@ export interface MsgEmojiLike {
 export class OB11GroupMsgEmojiLikeEvent extends OB11GroupNoticeEvent {
   notice_type = 'group_msg_emoji_like'
   message_id: number
-  sub_type?: 'ban' | 'lift_ban'
   likes: MsgEmojiLike[]
   group_id: number
   user_id: number
 
-  constructor(groupId: number, userId: number, messageId: number, likes: MsgEmojiLike[], sub_type?: 'ban' | 'lift_ban') {
+  constructor(groupId: number, userId: number, messageId: number, likes: MsgEmojiLike[]) {
     super()
     this.group_id = groupId
     this.user_id = userId // 可为空,表示是对别人的消息操作,如果是对bot自己的消息则不为空
     this.message_id = messageId
     this.likes = likes
-    this.sub_type = sub_type
   }
 }
diff --git a/src/onebot11/helper/createMessage.ts b/src/onebot11/helper/createMessage.ts
index b8b08c6..7bbb6a3 100644
--- a/src/onebot11/helper/createMessage.ts
+++ b/src/onebot11/helper/createMessage.ts
@@ -15,7 +15,7 @@ import {
 } from '../types'
 import { decodeCQCode } from '../cqcode'
 import { Peer } from '@/ntqqapi/types/msg'
-import { SendElementEntities } from '@/ntqqapi/entities'
+import { SendElement } from '@/ntqqapi/entities'
 import { selfInfo } from '@/common/globalVars'
 import { uri2local } from '@/common/utils'
 import { Context } from 'cordis'
@@ -36,7 +36,7 @@ export async function createSendElements(
       case OB11MessageDataType.text: {
         const text = sendMsg.data?.text
         if (text) {
-          sendElements.push(SendElementEntities.text(sendMsg.data!.text))
+          sendElements.push(SendElement.text(sendMsg.data!.text))
         }
       }
         break
@@ -62,7 +62,7 @@ export async function createSendElements(
               }
             }
             if (isAdmin && remainAtAllCount > 0) {
-              sendElements.push(SendElementEntities.at(atQQ, atQQ, AtType.All, '@全体成员'))
+              sendElements.push(SendElement.at(atQQ, atQQ, AtType.All, '@全体成员'))
             }
           }
           else if (peer.chatType === ChatType.Group) {
@@ -70,14 +70,14 @@ export async function createSendElements(
             if (atMember) {
               const display = `@${atMember.cardName || atMember.nick}`
               sendElements.push(
-                SendElementEntities.at(atQQ, atMember.uid, AtType.One, display),
+                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(
-                SendElementEntities.at(atQQ, uid, AtType.One, display),
+                SendElement.at(atQQ, uid, AtType.One, display),
               )
             }
           }
@@ -97,7 +97,7 @@ export async function createSendElements(
           )).msgList[0]
           if (replyMsg) {
             sendElements.push(
-              SendElementEntities.reply(
+              SendElement.reply(
                 replyMsg.msgSeq,
                 replyMsg.msgId,
                 replyMsg.senderUin!,
@@ -111,13 +111,13 @@ export async function createSendElements(
       case OB11MessageDataType.face: {
         const faceId = sendMsg.data?.id
         if (faceId) {
-          sendElements.push(SendElementEntities.face(parseInt(faceId)))
+          sendElements.push(SendElement.face(parseInt(faceId)))
         }
       }
         break
       case OB11MessageDataType.mface: {
         sendElements.push(
-          SendElementEntities.mface(
+          SendElement.mface(
             +sendMsg.data.emoji_package_id,
             sendMsg.data.emoji_id,
             sendMsg.data.key,
@@ -127,7 +127,7 @@ export async function createSendElements(
       }
         break
       case OB11MessageDataType.image: {
-        const res = await SendElementEntities.pic(
+        const res = await SendElement.pic(
           ctx,
           (await handleOb11FileLikeMessage(ctx, sendMsg, { deleteAfterSentFiles })).path,
           sendMsg.data.summary || '',
@@ -140,7 +140,7 @@ export async function createSendElements(
         break
       case OB11MessageDataType.file: {
         const { path, fileName } = await handleOb11FileLikeMessage(ctx, sendMsg, { deleteAfterSentFiles })
-        sendElements.push(await SendElementEntities.file(ctx, path, fileName))
+        sendElements.push(await SendElement.file(ctx, path, fileName))
       }
         break
       case OB11MessageDataType.video: {
@@ -150,38 +150,38 @@ export async function createSendElements(
           const uri2LocalRes = await uri2local(thumb)
           if (uri2LocalRes.success) thumb = uri2LocalRes.path
         }
-        const res = await SendElementEntities.video(ctx, path, fileName, thumb)
+        const res = await SendElement.video(ctx, path, fileName, thumb)
         deleteAfterSentFiles.push(res.videoElement.filePath)
         sendElements.push(res)
       }
         break
       case OB11MessageDataType.voice: {
         const { path } = await handleOb11FileLikeMessage(ctx, sendMsg, { deleteAfterSentFiles })
-        sendElements.push(await SendElementEntities.ptt(ctx, path))
+        sendElements.push(await SendElement.ptt(ctx, path))
       }
         break
       case OB11MessageDataType.json: {
-        sendElements.push(SendElementEntities.ark(sendMsg.data.data))
+        sendElements.push(SendElement.ark(sendMsg.data.data))
       }
         break
       case OB11MessageDataType.dice: {
         const resultId = sendMsg.data?.result
-        sendElements.push(SendElementEntities.dice(resultId))
+        sendElements.push(SendElement.dice(resultId))
       }
         break
       case OB11MessageDataType.RPS: {
         const resultId = sendMsg.data?.result
-        sendElements.push(SendElementEntities.rps(resultId))
+        sendElements.push(SendElement.rps(resultId))
       }
         break
       case OB11MessageDataType.contact: {
         const { type, id } = sendMsg.data
         const data = type === 'qq' ? ctx.ntFriendApi.getBuddyRecommendContact(id) : ctx.ntGroupApi.getGroupRecommendContact(id)
-        sendElements.push(SendElementEntities.ark(await data))
+        sendElements.push(SendElement.ark(await data))
       }
         break
       case OB11MessageDataType.shake: {
-        sendElements.push(SendElementEntities.shake())
+        sendElements.push(SendElement.shake())
       }
         break
     }
diff --git a/src/version.ts b/src/version.ts
index 3dd42de..29e963a 100644
--- a/src/version.ts
+++ b/src/version.ts
@@ -1 +1 @@
-export const version = '3.33.10'
+export const version = '3.34.0'