diff --git a/manifest.json b/manifest.json
index a6db5f2..d03b050 100644
--- a/manifest.json
+++ b/manifest.json
@@ -4,7 +4,7 @@
   "name": "LLOneBot",
   "slug": "LLOneBot",
   "description": "实现 OneBot 11 协议,用于 QQ 机器人开发",
-  "version": "3.31.9",
+  "version": "3.31.10",
   "icon": "./icon.webp",
   "authors": [
     {
diff --git a/src/common/utils/eventTask.ts b/src/common/utils/eventTask.ts
deleted file mode 100644
index 2c84e03..0000000
--- a/src/common/utils/eventTask.ts
+++ /dev/null
@@ -1,234 +0,0 @@
-import { NodeIQQNTWrapperSession } from '@/ntqqapi/wrapper'
-import { randomUUID } from 'node:crypto'
-
-interface Internal_MapKey {
-  timeout: number
-  createtime: number
-  func: (...arg: any[]) => unknown
-  checker?: (...args: any[]) => boolean
-}
-
-export class ListenerClassBase {
-  [key: string]: string
-}
-
-export interface ListenerIBase {
-  new(listener: unknown): ListenerClassBase
-}
-
-// forked from https://github.com/NapNeko/NapCatQQ/blob/6f6b258f22d7563f15d84e7172c4d4cbb547f47e/src/common/utils/EventTask.ts#L20
-export class NTEventWrapper {
-  private ListenerMap: { [key: string]: ListenerIBase } | undefined//ListenerName-Unique -> Listener构造函数
-  private WrapperSession: NodeIQQNTWrapperSession | undefined//WrapperSession
-  private ListenerManger: Map<string, ListenerClassBase> = new Map<string, ListenerClassBase>() //ListenerName-Unique -> Listener实例
-  private EventTask = new Map<string, Map<string, Map<string, Internal_MapKey>>>()//tasks ListenerMainName -> ListenerSubName-> uuid -> {timeout,createtime,func}
-  public initialised = false
-
-  constructor() {
-  }
-
-  createProxyDispatch(ListenerMainName: string) {
-    const current = this
-    return new Proxy({}, {
-      get(target: any, prop: string, receiver: unknown) {
-        // console.log('get', prop, typeof target[prop])
-        if (typeof target[prop] === 'undefined') {
-          // 如果方法不存在,返回一个函数,这个函数调用existentMethod
-          return (...args: unknown[]) => {
-            current.dispatcherListener.apply(current, [ListenerMainName, prop, ...args]).then()
-          }
-        }
-        // 如果方法存在,正常返回
-        return Reflect.get(target, prop, receiver)
-      }
-    })
-  }
-
-  init({ ListenerMap, WrapperSession }: { ListenerMap: { [key: string]: typeof ListenerClassBase }, WrapperSession: NodeIQQNTWrapperSession }) {
-    this.ListenerMap = ListenerMap
-    this.WrapperSession = WrapperSession
-    this.initialised = true
-  }
-
-  createEventFunction<T extends (...args: any) => unknown>(eventName: string): T | undefined {
-    const eventNameArr = eventName.split('/')
-    type eventType = {
-      [key: string]: () => { [key: string]: (...params: Parameters<T>) => Promise<ReturnType<T>> }
-    }
-    if (eventNameArr.length > 1) {
-      const serviceName = 'get' + eventNameArr[0].replace('NodeIKernel', '')
-      const eventName = eventNameArr[1]
-      //getNodeIKernelGroupListener,GroupService
-      //console.log('2', eventName)
-      const services = (this.WrapperSession as unknown as eventType)[serviceName]()
-      let event = services[eventName]
-      //重新绑定this
-      event = event.bind(services)
-      if (event) {
-        return event as T
-      }
-      return undefined
-    }
-  }
-
-  createListenerFunction<T>(listenerMainName: string, uniqueCode: string = ''): T {
-    const ListenerType = this.ListenerMap![listenerMainName]
-    let Listener = this.ListenerManger.get(listenerMainName + uniqueCode)
-    if (!Listener && ListenerType) {
-      Listener = new ListenerType(this.createProxyDispatch(listenerMainName))
-      const ServiceSubName = listenerMainName.match(/^NodeIKernel(.*?)Listener$/)![1]
-      const Service = 'NodeIKernel' + ServiceSubName + 'Service/addKernel' + ServiceSubName + 'Listener'
-      const addfunc = this.createEventFunction<(listener: T) => number>(Service)
-      addfunc!(Listener as T)
-      //console.log(addfunc!(Listener as T))
-      this.ListenerManger.set(listenerMainName + uniqueCode, Listener)
-    }
-    return Listener as T
-  }
-
-  //统一回调清理事件
-  async dispatcherListener(ListenerMainName: string, ListenerSubName: string, ...args: unknown[]) {
-    //console.log("[EventDispatcher]",ListenerMainName, ListenerSubName, ...args)
-    this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.forEach((task, uuid) => {
-      //console.log(task.func, uuid, task.createtime, task.timeout)
-      if (task.createtime + task.timeout < Date.now()) {
-        this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.delete(uuid)
-        return
-      }
-      if (task.checker && task.checker(...args)) {
-        task.func(...args)
-      }
-    })
-  }
-
-  async CallNoListenerEvent<EventType extends (...args: any[]) => Promise<any>>(EventName = '', timeout: number = 3000, ...args: Parameters<EventType>) {
-    return new Promise<Awaited<ReturnType<EventType>>>(async (resolve, reject) => {
-      const EventFunc = this.createEventFunction<EventType>(EventName)
-      let complete = false
-      const Timeouter = setTimeout(() => {
-        if (!complete) {
-          reject(new Error('NTEvent EventName:' + EventName + ' timeout'))
-        }
-      }, timeout)
-      const retData = await EventFunc!(...args)
-      complete = true
-      resolve(retData)
-    })
-  }
-
-  async RegisterListen<ListenerType extends (...args: any[]) => void>(ListenerName = '', waitTimes = 1, timeout = 5000, checker: (...args: Parameters<ListenerType>) => boolean) {
-    return new Promise<Parameters<ListenerType>>((resolve, reject) => {
-      const ListenerNameList = ListenerName.split('/')
-      const ListenerMainName = ListenerNameList[0]
-      const ListenerSubName = ListenerNameList[1]
-      const id = randomUUID()
-      let complete = 0
-      let retData: Parameters<ListenerType> | undefined = undefined
-      const databack = () => {
-        if (complete == 0) {
-          reject(new Error(' ListenerName:' + ListenerName + ' timeout'))
-        } else {
-          resolve(retData!)
-        }
-      }
-      const Timeouter = setTimeout(databack, timeout)
-      const eventCallbak = {
-        timeout: timeout,
-        createtime: Date.now(),
-        checker: checker,
-        func: (...args: Parameters<ListenerType>) => {
-          complete++
-          retData = args
-          if (complete >= waitTimes) {
-            clearTimeout(Timeouter)
-            databack()
-          }
-        }
-      }
-      if (!this.EventTask.get(ListenerMainName)) {
-        this.EventTask.set(ListenerMainName, new Map())
-      }
-      if (!(this.EventTask.get(ListenerMainName)?.get(ListenerSubName))) {
-        this.EventTask.get(ListenerMainName)?.set(ListenerSubName, new Map())
-      }
-      this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.set(id, eventCallbak)
-      this.createListenerFunction(ListenerMainName)
-    })
-  }
-
-  async CallNormalEvent<EventType extends (...args: any[]) => Promise<any>, ListenerType extends (...args: any[]) => void>
-    (EventName = '', ListenerName = '', waitTimes = 1, timeout: number = 3000, checker: (...args: Parameters<ListenerType>) => boolean, ...args: Parameters<EventType>) {
-    return new Promise<[EventRet: Awaited<ReturnType<EventType>>, ...Parameters<ListenerType>]>(async (resolve, reject) => {
-      const id = randomUUID()
-      let complete = 0
-      let retData: Parameters<ListenerType> | undefined = undefined
-      let retEvent = {}
-      const databack = () => {
-        if (complete == 0) {
-          reject(new Error('Timeout: NTEvent EventName:' + EventName + ' ListenerName:' + ListenerName + ' EventRet:\n' + JSON.stringify(retEvent, null, 4) + '\n'))
-        } else {
-          resolve([retEvent as Awaited<ReturnType<EventType>>, ...retData!])
-        }
-      }
-
-      const ListenerNameList = ListenerName.split('/')
-      const ListenerMainName = ListenerNameList[0]
-      const ListenerSubName = ListenerNameList[1]
-
-      const Timeouter = setTimeout(databack, timeout)
-
-      const eventCallbak = {
-        timeout: timeout,
-        createtime: Date.now(),
-        checker: checker,
-        func: (...args: unknown[]) => {
-          complete++
-          //console.log('func', ...args)
-          retData = args as Parameters<ListenerType>
-          if (complete >= waitTimes) {
-            clearTimeout(Timeouter)
-            databack()
-          }
-        }
-      }
-      if (!this.EventTask.get(ListenerMainName)) {
-        this.EventTask.set(ListenerMainName, new Map())
-      }
-      if (!(this.EventTask.get(ListenerMainName)?.get(ListenerSubName))) {
-        this.EventTask.get(ListenerMainName)?.set(ListenerSubName, new Map())
-      }
-      this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.set(id, eventCallbak)
-      this.createListenerFunction(ListenerMainName)
-      const EventFunc = this.createEventFunction<EventType>(EventName)
-      retEvent = await EventFunc!(...args)
-    })
-  }
-}
-
-export const NTEventDispatch = new NTEventWrapper()
-
-// 示例代码 快速创建事件
-// let NTEvent = new NTEventWrapper()
-// let TestEvent = NTEvent.CreatEventFunction<(force: boolean) => Promise<Number>>('NodeIKernelProfileLikeService/GetTest')
-// if (TestEvent) {
-//     TestEvent(true)
-// }
-
-// 示例代码 快速创建监听Listener类
-// let NTEvent = new NTEventWrapper()
-// NTEvent.CreatListenerFunction<NodeIKernelMsgListener>('NodeIKernelMsgListener', 'core')
-
-
-// 调用接口
-//let NTEvent = new NTEventWrapper()
-//let ret = await NTEvent.CallNormalEvent<(force: boolean) => Promise<Number>, (data1: string, data2: number) => void>('NodeIKernelProfileLikeService/GetTest', 'NodeIKernelMsgListener/onAddSendMsg', 1, 3000, true)
-
-// 注册监听 解除监听
-// NTEventDispatch.RigisterListener('NodeIKernelMsgListener/onAddSendMsg','core',cb)
-// NTEventDispatch.UnRigisterListener('NodeIKernelMsgListener/onAddSendMsg','core')
-
-// let GetTest = NTEventDispatch.CreatEvent('NodeIKernelProfileLikeService/GetTest','NodeIKernelMsgListener/onAddSendMsg',Mode)
-// GetTest('test')
-
-// always模式
-// NTEventDispatch.CreatEvent('NodeIKernelProfileLikeService/GetTest','NodeIKernelMsgListener/onAddSendMsg',Mode,(...args:any[])=>{ console.log(args) })
\ No newline at end of file
diff --git a/src/common/utils/messageUnique.ts b/src/common/utils/messageUnique.ts
index 3df7330..2d9ea0b 100644
--- a/src/common/utils/messageUnique.ts
+++ b/src/common/utils/messageUnique.ts
@@ -10,154 +10,154 @@ import { DATA_DIR } from '../globalVars'
 import { FileCacheV2 } from '../types'
 
 interface SQLiteTables extends Tables {
-    message: {
-        shortId: number
-        msgId: string
-        chatType: number
-        peerUid: string
-    }
-    file_v2: FileCacheV2
+  message: {
+    shortId: number
+    msgId: string
+    chatType: number
+    peerUid: string
+  }
+  file_v2: FileCacheV2
 }
 
 interface MsgIdAndPeerByShortId {
-    MsgId: string
-    Peer: Peer
+  MsgId: string
+  Peer: Peer
 }
 
 // forked from https://github.com/NapNeko/NapCatQQ/blob/6f6b258f22d7563f15d84e7172c4d4cbb547f47e/src/common/utils/MessageUnique.ts#L84
 class MessageUniqueWrapper {
-    private msgDataMap: LimitedHashTable<string, number>
-    private msgIdMap: LimitedHashTable<string, number>
-    private db: Database<SQLiteTables> | undefined
+  private msgDataMap: LimitedHashTable<string, number>
+  private msgIdMap: LimitedHashTable<string, number>
+  private db: Database<SQLiteTables> | undefined
 
-    constructor(maxMap: number = 1000) {
-        this.msgIdMap = new LimitedHashTable<string, number>(maxMap)
-        this.msgDataMap = new LimitedHashTable<string, number>(maxMap)
+  constructor(maxMap: number = 1000) {
+    this.msgIdMap = new LimitedHashTable<string, number>(maxMap)
+    this.msgDataMap = new LimitedHashTable<string, number>(maxMap)
+  }
+
+  async init(uin: string) {
+    const dbDir = path.join(DATA_DIR, 'database')
+    if (!fs.existsSync(dbDir)) {
+      await fsPromise.mkdir(dbDir)
     }
+    const database = new Database<SQLiteTables>()
+    await database.connect(SQLite, {
+      path: path.join(dbDir, `${uin}.db`)
+    })
+    database.extend('message', {
+      shortId: 'integer(10)',
+      chatType: 'unsigned',
+      msgId: 'string(24)',
+      peerUid: 'string(24)'
+    }, {
+      primary: 'shortId'
+    })
+    database.extend('file_v2', {
+      fileName: 'string',
+      fileSize: 'string',
+      fileUuid: 'string(128)',
+      msgId: 'string(24)',
+      msgTime: 'unsigned(10)',
+      peerUid: 'string(24)',
+      chatType: 'unsigned',
+      elementId: 'string(24)',
+      elementType: 'unsigned',
+    }, {
+      primary: 'fileUuid',
+      indexes: ['fileName']
+    })
+    this.db = database
+  }
 
-    async init(uin: string) {
-        const dbDir = path.join(DATA_DIR, 'database')
-        if (!fs.existsSync(dbDir)) {
-            await fsPromise.mkdir(dbDir)
+  async getRecentMsgIds(Peer: Peer, size: number): Promise<string[]> {
+    const heads = this.msgIdMap.getHeads(size)
+    if (!heads) {
+      return []
+    }
+    const data: (MsgIdAndPeerByShortId | undefined)[] = []
+    for (const t of heads) {
+      data.push(await MessageUnique.getMsgIdAndPeerByShortId(t.value))
+    }
+    const ret = data.filter((t) => t?.Peer.chatType === Peer.chatType && t?.Peer.peerUid === Peer.peerUid)
+    return ret.map((t) => t?.MsgId).filter((t) => t !== undefined)
+  }
+
+  createMsg(peer: Peer, msgId: string): number {
+    const key = `${msgId}|${peer.chatType}|${peer.peerUid}`
+    const hash = createHash('md5').update(key).digest()
+    //设置第一个bit为0 保证shortId为正数
+    hash[0] &= 0x7f
+    const shortId = hash.readInt32BE(0)
+    //减少性能损耗
+    // const isExist = this.msgIdMap.getKey(shortId)
+    // if (isExist && isExist === msgId) {
+    //   return shortId
+    // }
+    this.msgIdMap.set(msgId, shortId)
+    this.msgDataMap.set(key, shortId)
+    this.db?.upsert('message', [{
+      msgId,
+      shortId,
+      chatType: peer.chatType,
+      peerUid: peer.peerUid
+    }], 'shortId').then()
+    return shortId
+  }
+
+  async getMsgIdAndPeerByShortId(shortId: number): Promise<MsgIdAndPeerByShortId | undefined> {
+    const data = this.msgDataMap.getKey(shortId)
+    if (data) {
+      const [msgId, chatTypeStr, peerUid] = data.split('|')
+      const peer: Peer = {
+        chatType: parseInt(chatTypeStr),
+        peerUid,
+        guildId: '',
+      }
+      return { MsgId: msgId, Peer: peer }
+    }
+    const items = await this.db?.get('message', { shortId })
+    if (items?.length) {
+      const { msgId, chatType, peerUid } = items[0]
+      return {
+        MsgId: msgId,
+        Peer: {
+          chatType,
+          peerUid,
+          guildId: '',
         }
-        const database = new Database<SQLiteTables>()
-        await database.connect(SQLite, {
-            path: path.join(dbDir, `${uin}.db`)
-        })
-        database.extend('message', {
-            shortId: 'integer(10)',
-            chatType: 'unsigned',
-            msgId: 'string(24)',
-            peerUid: 'string(24)'
-        }, {
-            primary: 'shortId'
-        })
-        database.extend('file_v2', {
-            fileName: 'string',
-            fileSize: 'string',
-            fileUuid: 'string(128)',
-            msgId: 'string(24)',
-            msgTime: 'unsigned(10)',
-            peerUid: 'string(24)',
-            chatType: 'unsigned',
-            elementId: 'string(24)',
-            elementType: 'unsigned',
-        }, {
-            primary: 'fileUuid',
-            indexes: ['fileName']
-        })
-        this.db = database
+      }
     }
+    return undefined
+  }
 
-    async getRecentMsgIds(Peer: Peer, size: number): Promise<string[]> {
-        const heads = this.msgIdMap.getHeads(size)
-        if (!heads) {
-            return []
-        }
-        const data: (MsgIdAndPeerByShortId | undefined)[] = []
-        for (const t of heads) {
-            data.push(await MessageUnique.getMsgIdAndPeerByShortId(t.value))
-        }
-        const ret = data.filter((t) => t?.Peer.chatType === Peer.chatType && t?.Peer.peerUid === Peer.peerUid)
-        return ret.map((t) => t?.MsgId).filter((t) => t !== undefined)
-    }
+  getShortIdByMsgId(msgId: string): number | undefined {
+    return this.msgIdMap.getValue(msgId)
+  }
 
-    createMsg(peer: Peer, msgId: string): number {
-        const key = `${msgId}|${peer.chatType}|${peer.peerUid}`
-        const hash = createHash('md5').update(key).digest()
-        //设置第一个bit为0 保证shortId为正数
-        hash[0] &= 0x7f
-        const shortId = hash.readInt32BE(0)
-        //减少性能损耗
-        // const isExist = this.msgIdMap.getKey(shortId)
-        // if (isExist && isExist === msgId) {
-        //   return shortId
-        // }
-        this.msgIdMap.set(msgId, shortId)
-        this.msgDataMap.set(key, shortId)
-        this.db?.upsert('message', [{
-            msgId,
-            shortId,
-            chatType: peer.chatType,
-            peerUid: peer.peerUid
-        }], 'shortId').then()
-        return shortId
-    }
+  async getPeerByMsgId(msgId: string) {
+    const shortId = this.msgIdMap.getValue(msgId)
+    if (!shortId) return undefined
+    return await this.getMsgIdAndPeerByShortId(shortId)
+  }
 
-    async getMsgIdAndPeerByShortId(shortId: number): Promise<MsgIdAndPeerByShortId | undefined> {
-        const data = this.msgDataMap.getKey(shortId)
-        if (data) {
-            const [msgId, chatTypeStr, peerUid] = data.split('|')
-            const peer: Peer = {
-                chatType: parseInt(chatTypeStr),
-                peerUid,
-                guildId: '',
-            }
-            return { MsgId: msgId, Peer: peer }
-        }
-        const items = await this.db?.get('message', { shortId })
-        if (items?.length) {
-            const { msgId, chatType, peerUid } = items[0]
-            return {
-                MsgId: msgId,
-                Peer: {
-                    chatType,
-                    peerUid,
-                    guildId: '',
-                }
-            }
-        }
-        return undefined
-    }
+  resize(maxSize: number): void {
+    this.msgIdMap.resize(maxSize)
+    this.msgDataMap.resize(maxSize)
+  }
 
-    getShortIdByMsgId(msgId: string): number | undefined {
-        return this.msgIdMap.getValue(msgId)
-    }
+  addFileCache(data: FileCacheV2) {
+    return this.db?.upsert('file_v2', [data], 'fileUuid')
+  }
 
-    async getPeerByMsgId(msgId: string) {
-        const shortId = this.msgIdMap.getValue(msgId)
-        if (!shortId) return undefined
-        return await this.getMsgIdAndPeerByShortId(shortId)
-    }
+  getFileCacheByName(fileName: string) {
+    return this.db?.get('file_v2', { fileName }, {
+      sort: { msgTime: 'desc' }
+    })
+  }
 
-    resize(maxSize: number): void {
-        this.msgIdMap.resize(maxSize)
-        this.msgDataMap.resize(maxSize)
-    }
-
-    addFileCache(data: FileCacheV2) {
-        return this.db?.upsert('file_v2', [data], 'fileUuid')
-    }
-
-    getFileCacheByName(fileName: string) {
-        return this.db?.get('file_v2', { fileName }, {
-            sort: { msgTime: 'desc' }
-        })
-    }
-
-    getFileCacheById(fileUuid: string) {
-        return this.db?.get('file_v2', { fileUuid })
-    }
+  getFileCacheById(fileUuid: string) {
+    return this.db?.get('file_v2', { fileUuid })
+  }
 }
 
 export const MessageUnique: MessageUniqueWrapper = new MessageUniqueWrapper()
\ No newline at end of file
diff --git a/src/common/utils/table.ts b/src/common/utils/table.ts
index bd2a6e0..29738af 100644
--- a/src/common/utils/table.ts
+++ b/src/common/utils/table.ts
@@ -1,72 +1,72 @@
 // forked from https://github.com/NapNeko/NapCatQQ/blob/6f6b258f22d7563f15d84e7172c4d4cbb547f47e/src/common/utils/MessageUnique.ts#L5
 export class LimitedHashTable<K, V> {
-    private keyToValue: Map<K, V> = new Map()
-    private valueToKey: Map<V, K> = new Map()
-    private maxSize: number
+  private keyToValue: Map<K, V> = new Map()
+  private valueToKey: Map<V, K> = new Map()
+  private maxSize: number
 
-    constructor(maxSize: number) {
-        this.maxSize = maxSize
-    }
+  constructor(maxSize: number) {
+    this.maxSize = maxSize
+  }
 
-    resize(count: number) {
-        this.maxSize = count
-    }
+  resize(count: number) {
+    this.maxSize = count
+  }
 
-    set(key: K, value: V): void {
-        this.keyToValue.set(key, value)
-        this.valueToKey.set(value, key)
-        while (this.keyToValue.size !== this.valueToKey.size) {
-            console.log('keyToValue.size !== valueToKey.size Error Atom')
-            this.keyToValue.clear()
-            this.valueToKey.clear()
-        }
-        while (this.keyToValue.size > this.maxSize || this.valueToKey.size > this.maxSize) {
-            const oldestKey = this.keyToValue.keys().next().value
-            this.valueToKey.delete(this.keyToValue.get(oldestKey)!)
-            this.keyToValue.delete(oldestKey)
-        }
+  set(key: K, value: V): void {
+    this.keyToValue.set(key, value)
+    this.valueToKey.set(value, key)
+    while (this.keyToValue.size !== this.valueToKey.size) {
+      console.log('keyToValue.size !== valueToKey.size Error Atom')
+      this.keyToValue.clear()
+      this.valueToKey.clear()
     }
+    while (this.keyToValue.size > this.maxSize || this.valueToKey.size > this.maxSize) {
+      const oldestKey = this.keyToValue.keys().next().value
+      this.valueToKey.delete(this.keyToValue.get(oldestKey)!)
+      this.keyToValue.delete(oldestKey)
+    }
+  }
 
-    getValue(key: K): V | undefined {
-        return this.keyToValue.get(key)
-    }
+  getValue(key: K): V | undefined {
+    return this.keyToValue.get(key)
+  }
 
-    getKey(value: V): K | undefined {
-        return this.valueToKey.get(value)
-    }
+  getKey(value: V): K | undefined {
+    return this.valueToKey.get(value)
+  }
 
-    deleteByValue(value: V): void {
-        const key = this.valueToKey.get(value)
-        if (key !== undefined) {
-            this.keyToValue.delete(key)
-            this.valueToKey.delete(value)
-        }
+  deleteByValue(value: V): void {
+    const key = this.valueToKey.get(value)
+    if (key !== undefined) {
+      this.keyToValue.delete(key)
+      this.valueToKey.delete(value)
     }
+  }
 
-    deleteByKey(key: K): void {
-        const value = this.keyToValue.get(key)
-        if (value !== undefined) {
-            this.keyToValue.delete(key)
-            this.valueToKey.delete(value)
-        }
+  deleteByKey(key: K): void {
+    const value = this.keyToValue.get(key)
+    if (value !== undefined) {
+      this.keyToValue.delete(key)
+      this.valueToKey.delete(value)
     }
+  }
 
-    getKeyList(): K[] {
-        return Array.from(this.keyToValue.keys())
-    }
+  getKeyList(): K[] {
+    return Array.from(this.keyToValue.keys())
+  }
 
-    //获取最近刚写入的几个值
-    getHeads(size: number): { key: K; value: V }[] | undefined {
-        const keyList = this.getKeyList()
-        if (keyList.length === 0) {
-            return undefined
-        }
-        const result: { key: K; value: V }[] = []
-        const listSize = Math.min(size, keyList.length)
-        for (let i = 0; i < listSize; i++) {
-            const key = keyList[listSize - i]
-            result.push({ key, value: this.keyToValue.get(key)! })
-        }
-        return result
+  //获取最近刚写入的几个值
+  getHeads(size: number): { key: K; value: V }[] | undefined {
+    const keyList = this.getKeyList()
+    if (keyList.length === 0) {
+      return undefined
     }
+    const result: { key: K; value: V }[] = []
+    const listSize = Math.min(size, keyList.length)
+    for (let i = 0; i < listSize; i++) {
+      const key = keyList[listSize - i]
+      result.push({ key, value: this.keyToValue.get(key)! })
+    }
+    return result
+  }
 }
\ No newline at end of file
diff --git a/src/ntqqapi/api/file.ts b/src/ntqqapi/api/file.ts
index e17bd57..6599064 100644
--- a/src/ntqqapi/api/file.ts
+++ b/src/ntqqapi/api/file.ts
@@ -21,7 +21,6 @@ import { Peer } from '@/ntqqapi/types/msg'
 import { calculateFileMD5 } from '@/common/utils/file'
 import { fileTypeFromFile } from 'file-type'
 import fsPromise from 'node:fs/promises'
-import { NTEventDispatch } from '@/common/utils/eventTask'
 import { OnRichMediaDownloadCompleteParams } from '@/ntqqapi/listeners'
 import { Time } from 'cosmokit'
 import { Service, Context } from 'cordis'
@@ -143,76 +142,32 @@ export class NTQQFileApi extends Service {
         return sourcePath
       }
     }
-    let filePath: string
-    if (NTEventDispatch.initialised) {
-      const data = await NTEventDispatch.CallNormalEvent<
-        (
-          params: {
-            fileModelId: string,
-            downloadSourceType: number,
-            triggerType: number,
-            msgId: string,
-            chatType: ChatType,
-            peerUid: string,
-            elementId: string,
-            thumbSize: number,
-            downloadType: number,
-            filePath: string
-          }) => Promise<unknown>,
-        (fileTransNotifyInfo: OnRichMediaDownloadCompleteParams) => void
-      >(
-        'NodeIKernelMsgService/downloadRichMedia',
-        'NodeIKernelMsgListener/onRichMediaDownloadComplete',
-        1,
-        timeout,
-        (arg: OnRichMediaDownloadCompleteParams) => {
-          if (arg.msgId === msgId) {
-            return true
-          }
-          return false
-        },
+    const data = await invoke<{ notifyInfo: OnRichMediaDownloadCompleteParams }>(
+      'nodeIKernelMsgService/downloadRichMedia',
+      [
         {
-          fileModelId: '0',
-          downloadSourceType: 0,
-          triggerType: 1,
-          msgId: msgId,
-          chatType: chatType,
-          peerUid: peerUid,
-          elementId: elementId,
-          thumbSize: 0,
-          downloadType: 1,
-          filePath: thumbPath
-        }
-      )
-      filePath = data[1].filePath
-    } else {
-      const data = await invoke<{ notifyInfo: OnRichMediaDownloadCompleteParams }>(
-        'nodeIKernelMsgService/downloadRichMedia',
-        [
-          {
-            getReq: {
-              fileModelId: '0',
-              downloadSourceType: 0,
-              triggerType: 1,
-              msgId: msgId,
-              chatType: chatType,
-              peerUid: peerUid,
-              elementId: elementId,
-              thumbSize: 0,
-              downloadType: 1,
-              filePath: thumbPath,
-            },
+          getReq: {
+            fileModelId: '0',
+            downloadSourceType: 0,
+            triggerType: 1,
+            msgId: msgId,
+            chatType: chatType,
+            peerUid: peerUid,
+            elementId: elementId,
+            thumbSize: 0,
+            downloadType: 1,
+            filePath: thumbPath,
           },
-          null,
-        ],
-        {
-          cbCmd: ReceiveCmdS.MEDIA_DOWNLOAD_COMPLETE,
-          cmdCB: payload => payload.notifyInfo.msgId === msgId,
-          timeout
-        }
-      )
-      filePath = data.notifyInfo.filePath
-    }
+        },
+        null,
+      ],
+      {
+        cbCmd: ReceiveCmdS.MEDIA_DOWNLOAD_COMPLETE,
+        cmdCB: payload => payload.notifyInfo.msgId === msgId,
+        timeout
+      }
+    )
+    let filePath = data.notifyInfo.filePath
     if (filePath.startsWith('\\')) {
       const downloadPath = TEMP_DIR
       filePath = path.join(downloadPath, filePath)
@@ -238,7 +193,7 @@ export class NTQQFileApi extends Service {
     const url: string = element.originImageUrl!  // 没有域名
     const md5HexStr = element.md5HexStr
     const fileMd5 = element.md5HexStr
-    
+
     if (url) {
       const parsedUrl = new URL(IMAGE_HTTP_HOST + url) //临时解析拼接
       const imageAppid = parsedUrl.searchParams.get('appid')
diff --git a/src/ntqqapi/api/friend.ts b/src/ntqqapi/api/friend.ts
index d447f3e..8eb3004 100644
--- a/src/ntqqapi/api/friend.ts
+++ b/src/ntqqapi/api/friend.ts
@@ -2,8 +2,7 @@ import { Friend, FriendV2, SimpleInfo, CategoryFriend } from '../types'
 import { ReceiveCmdS } from '../hook'
 import { invoke, NTMethod, NTClass } from '../ntcall'
 import { getSession } from '@/ntqqapi/wrapper'
-import { BuddyListReqType, NodeIKernelProfileService } from '../services'
-import { NTEventDispatch } from '@/common/utils/eventTask'
+import { BuddyListReqType } from '../services'
 import { Dict, pick } from 'cosmokit'
 import { Service, Context } from 'cordis'
 
@@ -19,7 +18,7 @@ export class NTQQFriendApi extends Service {
   }
 
   /** 大于或等于 26702 应使用 getBuddyV2 */
-  async getFriends(_forced = false) {
+  async getFriends() {
     const data = await invoke<{
       data: {
         categoryId: number
@@ -75,9 +74,7 @@ export class NTQQFriendApi extends Service {
       const buddyService = session.getBuddyService()
       const buddyListV2 = await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL)
       uids.push(...buddyListV2.data.flatMap(item => item.buddyUids))
-      const data = await NTEventDispatch.CallNoListenerEvent<NodeIKernelProfileService['getCoreAndBaseInfo']>(
-        'NodeIKernelProfileService/getCoreAndBaseInfo', 5000, 'nodeStore', uids
-      )
+      const data = await session.getProfileService().getCoreAndBaseInfo('nodeStore', uids)
       return Array.from(data.values())
     } else {
       const data = await invoke<{
@@ -92,11 +89,8 @@ export class NTQQFriendApi extends Service {
           afterFirstCmd: false,
         }
       )
-      const categoryUids: Map<number, string[]> = new Map()
-      for (const item of data.buddyCategory) {
-        categoryUids.set(item.categoryId, item.buddyUids)
-      }
-      return Object.values(data.userSimpleInfos).filter(v => v.baseInfo && categoryUids.get(v.baseInfo.categoryId)?.includes(v.uid!))
+      const uids = data.buddyCategory.flatMap(item => item.buddyUids)
+      return Object.values(data.userSimpleInfos).filter(v => uids.includes(v.uid!))
     }
   }
 
@@ -106,12 +100,10 @@ export class NTQQFriendApi extends Service {
     const session = getSession()
     if (session) {
       const uids: string[] = []
-      const buddyService = session?.getBuddyService()
+      const buddyService = session.getBuddyService()
       const buddyListV2 = await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL)
       uids.push(...buddyListV2.data.flatMap(item => item.buddyUids))
-      const data = await NTEventDispatch.CallNoListenerEvent<NodeIKernelProfileService['getCoreAndBaseInfo']>(
-        'NodeIKernelProfileService/getCoreAndBaseInfo', 5000, 'nodeStore', uids
-      )
+      const data = await session.getProfileService().getCoreAndBaseInfo('nodeStore', uids)
       for (const [, item] of data) {
         if (retMap.size > 5000) {
           break
@@ -155,9 +147,7 @@ export class NTQQFriendApi extends Service {
           })
           return item.buddyUids
         }))
-      const data = await NTEventDispatch.CallNoListenerEvent<NodeIKernelProfileService['getCoreAndBaseInfo']>(
-        'NodeIKernelProfileService/getCoreAndBaseInfo', 5000, 'nodeStore', uids
-      )
+      const data = await session.getProfileService().getCoreAndBaseInfo('nodeStore', uids)
       return Array.from(data).map(([key, value]) => {
         const category = categoryMap.get(key)
         return category ? { ...value, categoryId: category.categoryId, categroyName: category.categroyName } : value
diff --git a/src/ntqqapi/api/group.ts b/src/ntqqapi/api/group.ts
index 949e171..0e7a8de 100644
--- a/src/ntqqapi/api/group.ts
+++ b/src/ntqqapi/api/group.ts
@@ -1,5 +1,5 @@
 import { ReceiveCmdS } from '../hook'
-import { Group, GroupMember, GroupMemberRole, GroupNotifies, GroupRequestOperateTypes, GroupNotify, GetFileListParam } from '../types'
+import { Group, GroupMember, GroupMemberRole, GroupNotifies, GroupRequestOperateTypes, GetFileListParam } from '../types'
 import { invoke, NTClass, NTMethod } from '../ntcall'
 import { GeneralCallResult } from '../services'
 import { NTQQWindows } from './window'
@@ -24,7 +24,7 @@ export class NTQQGroupApi extends Service {
     super(ctx, 'ntGroupApi', true)
   }
 
-  async getGroups(forced = false): Promise<Group[]> {
+  async getGroups(): Promise<Group[]> {
     const result = await invoke<{
       updateType: number
       groupList: Group[]
diff --git a/src/ntqqapi/api/user.ts b/src/ntqqapi/api/user.ts
index 52cb1f5..cb4791d 100644
--- a/src/ntqqapi/api/user.ts
+++ b/src/ntqqapi/api/user.ts
@@ -65,7 +65,7 @@ export class NTQQUserApi extends Service {
     return ret
   }
 
-  async getUserDetailInfo(uid: string, _getLevel = false) {
+  async getUserDetailInfo(uid: string) {
     if (getBuildVersion() >= 26702) {
       return this.fetchUserDetailInfo(uid)
     }
diff --git a/src/ntqqapi/core.ts b/src/ntqqapi/core.ts
index e1524f2..4f38fce 100644
--- a/src/ntqqapi/core.ts
+++ b/src/ntqqapi/core.ts
@@ -2,8 +2,6 @@ import fs from 'node:fs'
 import { Service, Context } from 'cordis'
 import { registerCallHook, registerReceiveHook, ReceiveCmdS } from './hook'
 import { MessageUnique } from '../common/utils/messageUnique'
-import { NTEventDispatch } from '../common/utils/eventTask'
-import { wrapperConstructor, getSession } from './wrapper'
 import { Config as LLOBConfig } from '../common/types'
 import { llonebotError } from '../common/globalVars'
 import { isNumeric } from '../common/utils/misc'
@@ -45,10 +43,6 @@ class Core extends Service {
 
   public start() {
     llonebotError.otherError = ''
-    const WrapperSession = getSession()
-    if (WrapperSession) {
-      NTEventDispatch.init({ ListenerMap: wrapperConstructor, WrapperSession })
-    }
     MessageUnique.init(selfInfo.uin)
     this.registerListener()
     this.ctx.logger.info(`LLOneBot/${version}`)
diff --git a/src/ntqqapi/entities.ts b/src/ntqqapi/entities.ts
index 5f02e5c..451a6f3 100644
--- a/src/ntqqapi/entities.ts
+++ b/src/ntqqapi/entities.ts
@@ -201,7 +201,7 @@ export namespace SendElementEntities {
     // log("生成缩略图", _thumbPath)
     thumbPath.set(0, _thumbPath)
     const thumbMd5 = await calculateFileMD5(_thumbPath)
-    let element: SendVideoElement = {
+    const element: SendVideoElement = {
       elementType: ElementType.VIDEO,
       elementId: '',
       videoElement: {
diff --git a/src/ntqqapi/wrapper.ts b/src/ntqqapi/wrapper.ts
index 9250c9b..6530797 100644
--- a/src/ntqqapi/wrapper.ts
+++ b/src/ntqqapi/wrapper.ts
@@ -34,7 +34,7 @@ export interface WrapperApi {
 }
 
 export interface WrapperConstructor {
-  [key: string]: any
+  [key: string]: unknown
 }
 
 const wrapperApi: WrapperApi = {}
diff --git a/src/onebot11/action/go-cqhttp/UploadFile.ts b/src/onebot11/action/go-cqhttp/UploadFile.ts
index 24428b9..3502d2f 100644
--- a/src/onebot11/action/go-cqhttp/UploadFile.ts
+++ b/src/onebot11/action/go-cqhttp/UploadFile.ts
@@ -28,7 +28,7 @@ export class UploadGroupFile extends BaseAction<UploadGroupFilePayload, null> {
     }
     const sendFileEle = await SendElementEntities.file(this.ctx, downloadResult.path, payload.name, payload.folder_id)
     const peer = await createPeer(this.ctx, payload, CreatePeerMode.Group)
-    await sendMsg(this.ctx, peer, [sendFileEle], [], true)
+    await sendMsg(this.ctx, peer, [sendFileEle], [])
     return null
   }
 }
@@ -53,7 +53,7 @@ export class UploadPrivateFile extends BaseAction<UploadPrivateFilePayload, null
       throw new Error(downloadResult.errMsg)
     }
     const sendFileEle: SendFileElement = await SendElementEntities.file(this.ctx, downloadResult.path, payload.name)
-    await sendMsg(this.ctx, peer, [sendFileEle], [], true)
+    await sendMsg(this.ctx, peer, [sendFileEle], [])
     return null
   }
 }
diff --git a/src/onebot11/action/group/GetGroupList.ts b/src/onebot11/action/group/GetGroupList.ts
index 0e3f15d..d931247 100644
--- a/src/onebot11/action/group/GetGroupList.ts
+++ b/src/onebot11/action/group/GetGroupList.ts
@@ -10,8 +10,8 @@ interface Payload {
 class GetGroupList extends BaseAction<Payload, OB11Group[]> {
   actionName = ActionName.GetGroupList
 
-  protected async _handle(payload: Payload) {
-    const groupList = await this.ctx.ntGroupApi.getGroups(payload?.no_cache === true || payload?.no_cache === 'true')
+  protected async _handle() {
+    const groupList = await this.ctx.ntGroupApi.getGroups()
     return OB11Entities.groups(groupList)
   }
 }
diff --git a/src/onebot11/action/group/GetGroupMemberInfo.ts b/src/onebot11/action/group/GetGroupMemberInfo.ts
index e05ea91..b4d153d 100644
--- a/src/onebot11/action/group/GetGroupMemberInfo.ts
+++ b/src/onebot11/action/group/GetGroupMemberInfo.ts
@@ -18,7 +18,7 @@ class GetGroupMemberInfo extends BaseAction<Payload, OB11GroupMember> {
     if (member) {
       if (isNullable(member.sex)) {
         //log('获取群成员详细信息')
-        const info = await this.ctx.ntUserApi.getUserDetailInfo(member.uid, true)
+        const info = await this.ctx.ntUserApi.getUserDetailInfo(member.uid)
         //log('群成员详细信息结果', info)
         Object.assign(member, info)
       }
diff --git a/src/onebot11/action/msg/SendMsg.ts b/src/onebot11/action/msg/SendMsg.ts
index 35ced15..cf73588 100644
--- a/src/onebot11/action/msg/SendMsg.ts
+++ b/src/onebot11/action/msg/SendMsg.ts
@@ -214,7 +214,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnData> {
           }
           // log("分割后的转发节点", sendElementsSplit)
           for (const eles of sendElementsSplit) {
-            const nodeMsg = await sendMsg(this.ctx, selfPeer, eles, [], true)
+            const nodeMsg = await sendMsg(this.ctx, selfPeer, eles, [])
             if (!nodeMsg) {
               this.ctx.logger.warn('转发节点生成失败', eles)
               continue
diff --git a/src/onebot11/action/system/CanSendRecord.ts b/src/onebot11/action/system/CanSendRecord.ts
index d75f35f..665d5fb 100644
--- a/src/onebot11/action/system/CanSendRecord.ts
+++ b/src/onebot11/action/system/CanSendRecord.ts
@@ -5,7 +5,7 @@ interface ReturnType {
   yes: boolean
 }
 
-export default class CanSendRecord extends BaseAction<any, ReturnType> {
+export default class CanSendRecord extends BaseAction<null, ReturnType> {
   actionName = ActionName.CanSendRecord
 
   protected async _handle() {
diff --git a/src/onebot11/action/user/GetFriendList.ts b/src/onebot11/action/user/GetFriendList.ts
index 7c6e632..7bbead3 100644
--- a/src/onebot11/action/user/GetFriendList.ts
+++ b/src/onebot11/action/user/GetFriendList.ts
@@ -16,7 +16,7 @@ export class GetFriendList extends BaseAction<Payload, OB11User[]> {
     if (getBuildVersion() >= 26702) {
       return OB11Entities.friendsV2(await this.ctx.ntFriendApi.getBuddyV2(refresh))
     }
-    return OB11Entities.friends(await this.ctx.ntFriendApi.getFriends(refresh))
+    return OB11Entities.friends(await this.ctx.ntFriendApi.getFriends())
   }
 }
 
diff --git a/src/onebot11/adapter.ts b/src/onebot11/adapter.ts
index 0f16a32..b3a2bf3 100644
--- a/src/onebot11/adapter.ts
+++ b/src/onebot11/adapter.ts
@@ -399,7 +399,7 @@ class OneBot11Adapter extends Service {
       this.handleRecallMsg(input)
     })
     this.ctx.on('nt/message-sent', input => {
-      this.handleRecallMsg(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 b319998..68b04a1 100644
--- a/src/onebot11/entities.ts
+++ b/src/onebot11/entities.ts
@@ -173,8 +173,8 @@ export namespace OB11Entities {
               id: MessageUnique.createMsg(peer, replyMsg ? replyMsg.msgId : records.msgId).toString()
             }
           }
-        } catch (e: any) {
-          ctx.logger.error('获取不到引用的消息', replyElement, e.stack)
+        } catch (e) {
+          ctx.logger.error('获取不到引用的消息', replyElement, (e as Error).stack)
           continue
         }
       }
@@ -378,7 +378,7 @@ export namespace OB11Entities {
           if (element.grayTipElement.jsonGrayTipElement.busiId == 1061) {
             //判断业务类型
             //Poke事件
-            const pokedetail: any[] = json.items
+            const pokedetail: Dict[] = json.items
             //筛选item带有uid的元素
             const poke_uid = pokedetail.filter(item => item.uid)
             if (poke_uid.length == 2) {
diff --git a/src/onebot11/helper/createMessage.ts b/src/onebot11/helper/createMessage.ts
index 18ebd90..6ec850f 100644
--- a/src/onebot11/helper/createMessage.ts
+++ b/src/onebot11/helper/createMessage.ts
@@ -236,8 +236,7 @@ export async function sendMsg(
   ctx: Context,
   peer: Peer,
   sendElements: SendMessageElement[],
-  deleteAfterSentFiles: string[],
-  waitComplete = true,
+  deleteAfterSentFiles: string[]
 ) {
   if (!sendElements.length) {
     throw '消息体无法解析,请检查是否发送了不支持的消息类型'
diff --git a/src/onebot11/helper/quickOperation.ts b/src/onebot11/helper/quickOperation.ts
index c67d8f7..8127015 100644
--- a/src/onebot11/helper/quickOperation.ts
+++ b/src/onebot11/helper/quickOperation.ts
@@ -88,7 +88,7 @@ async function handleMsg(ctx: Context, msg: OB11Message, quickAction: QuickOpera
     }
     replyMessage = replyMessage.concat(convertMessage2List(reply, quickAction.auto_escape))
     const { sendElements, deleteAfterSentFiles } = await createSendElements(ctx, replyMessage, peer)
-    sendMsg(ctx, peer, sendElements, deleteAfterSentFiles, false).catch(e => ctx.logger.error(e))
+    sendMsg(ctx, peer, sendElements, deleteAfterSentFiles).catch(e => ctx.logger.error(e))
   }
   if (msg.message_type === 'group') {
     const groupMsgQuickAction = quickAction as QuickOperationGroupMessage
diff --git a/src/renderer/index.ts b/src/renderer/index.ts
index 685b606..17d16ac 100644
--- a/src/renderer/index.ts
+++ b/src/renderer/index.ts
@@ -1,7 +1,7 @@
 import { CheckVersion, Config } from '../common/types'
 import { SettingButton, SettingItem, SettingList, SettingSwitch, SettingSelect } from './components'
 import { version } from '../version'
-// @ts-expect-error
+// @ts-expect-error: Unreachable code error
 import StyleRaw from './style.css?raw'
 
 type HostsType = 'httpHosts' | 'wsHosts'
diff --git a/src/version.ts b/src/version.ts
index b0be24c..79bfc7b 100644
--- a/src/version.ts
+++ b/src/version.ts
@@ -1 +1 @@
-export const version = '3.31.9'
+export const version = '3.31.10'