koishi-plugin-chat-patch 5.0.3 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,7 +11,7 @@
11
11
  <link rel="stylesheet" href="./bcui/css/style.css">
12
12
  <link rel="stylesheet" href="./bcui/css/color-light.css">
13
13
  <link rel="stylesheet" href="./css/append-light.css">
14
- <script type="module" crossorigin src="./assets/index-CwyyQN13.js"></script>
14
+ <script type="module" crossorigin src="./assets/index-Cz89G4we.js"></script>
15
15
  <link rel="stylesheet" crossorigin href="./assets/index-BgOX_tNa.css">
16
16
  </head>
17
17
 
@@ -25,7 +25,7 @@ import { useChatStore } from '../state/chat'
25
25
  import { useContactStore } from '../state/contact'
26
26
  import { useSettingsStore } from '../state/settings'
27
27
  import { getMsgRawTxt, hasAtMe, updateBaseOnMsgList } from './utils/msgUtil'
28
- import { normalizeSessionId } from './utils/sessionUtil'
28
+ import { normalizeSessionId, setSessionContact } from './utils/sessionUtil'
29
29
  import { buildQqGroupAvatar } from './utils/avatarUtil'
30
30
  import type { ConnectionHistoryItem, LoginCacheElem } from './elements/system'
31
31
  import type { UserFriendElem, UserGroupElem } from './elements/information'
@@ -350,7 +350,7 @@ function updateBotStateGroup(
350
350
  const session = state?.onMsgList.find((item) => String(item.group_id) === sessionId)
351
351
  if (!state || !session) return
352
352
  apply(session as unknown as Record<string, unknown>)
353
- const key = normalizeSessionId(String(sessionId))
353
+ const key = normalizeSessionId(String(session.channel_id ?? session.channelId ?? sessionId))
354
354
  const baseList = [...state.baseList]
355
355
  const baseIndex = baseList.findIndex(([baseKey]) => normalizeSessionId(String(baseKey)) === key)
356
356
  const typedSession = session as unknown as UserFriendElem & UserGroupElem
@@ -550,6 +550,7 @@ function recordBotMessage(platform: string, selfId: string, msg: Record<string,
550
550
  identityDebug('recordBotMessage: skipped invalid session', { sessionId, msg })
551
551
  return
552
552
  }
553
+ const sessionKey = String(channelId || sessionId)
553
554
  identityDebug('recordBotMessage: session', { sessionId })
554
555
  const sender = getObject(msg.sender)
555
556
  const hasSenderAvatar = hasUsableAvatar(sender.avatar)
@@ -628,7 +629,7 @@ function recordBotMessage(platform: string, selfId: string, msg: Record<string,
628
629
  } else {
629
630
  state.onMsgList.unshift(session)
630
631
  }
631
- const baseKey = normalizeSessionId(String(sessionId))
632
+ const baseKey = normalizeSessionId(sessionKey)
632
633
  const baseList = [...state.baseList]
633
634
  const baseIndex = baseList.findIndex(([key]) => normalizeSessionId(String(key)) === baseKey)
634
635
  const typedSession = session as unknown as UserFriendElem & UserGroupElem
@@ -644,12 +645,9 @@ function recordBotMessage(platform: string, selfId: string, msg: Record<string,
644
645
  })
645
646
  if (
646
647
  isActiveBot({ platform, selfId }) &&
647
- !contactStore.baseOnMsgList.has(String(sessionId))
648
+ !contactStore.baseOnMsgList.has(normalizeSessionId(sessionKey))
648
649
  ) {
649
- contactStore.baseOnMsgList.set(
650
- String(sessionId),
651
- session as unknown as UserFriendElem & UserGroupElem,
652
- )
650
+ setSessionContact(contactStore.baseOnMsgList, session as unknown as UserFriendElem & UserGroupElem)
653
651
  updateBaseOnMsgList()
654
652
  }
655
653
 
@@ -678,7 +676,8 @@ function recordBotMessage(platform: string, selfId: string, msg: Record<string,
678
676
  // 实时消息直接写入当前聊天窗口,避免依赖旧的消息解析链路
679
677
  chatStore.messageList.push(msg)
680
678
  }
681
- const knownSessionAvatar = contactStore.baseOnMsgList.get(String(sessionId))
679
+ const knownSessionAvatar = contactStore.baseOnMsgList.get(normalizeSessionId(sessionKey))
680
+ ?? contactStore.baseOnMsgList.get(normalizeSessionId(sessionId))
682
681
  const knownWithAvatar = hasUsableAvatar(session.avatar)
683
682
  || Boolean(
684
683
  knownSessionAvatar &&
@@ -777,10 +776,10 @@ export function restoreBotStateFromMessageCache(platform: string, selfId: string
777
776
  const baseList = [...state.baseList]
778
777
  const baseKeys = new Set(baseList.map(([key]) => normalizeSessionId(key)))
779
778
  const existing = new Set(state.onMsgList.map((item) => {
780
- return String(item.user_id ?? item.group_id ?? '')
779
+ return String(item.channel_id ?? item.channelId ?? item.user_id ?? item.group_id ?? '')
781
780
  }))
782
781
  for (const session of sessions) {
783
- const id = String(session.user_id ?? session.group_id ?? '')
782
+ const id = String(session.channel_id ?? session.channelId ?? session.user_id ?? session.group_id ?? '')
784
783
  if (id && !existing.has(id)) {
785
784
  state.onMsgList.unshift(session)
786
785
  existing.add(id)
@@ -1360,6 +1359,7 @@ async function loadAllBotsCache() {
1360
1359
  for (const raw of groupRaws) {
1361
1360
  const id = normalizeGroupId(getString(raw.group_id) || getString(raw.id))
1362
1361
  if (!id) continue
1362
+ raw.group_id = id
1363
1363
  const name = getString(raw.group_name) || getString(raw.name)
1364
1364
  const avatar = hasUsableAvatar(raw.avatar)
1365
1365
  ? getString(raw.avatar)
@@ -1492,6 +1492,7 @@ function buildGroupItem(
1492
1492
  const channel = getObject(root.channel)
1493
1493
  const item = { ...getObject(raw) }
1494
1494
  const id = normalizeGroupId(getString(item.group_id) || getString(item.id) || getString(item.guild_id) || '')
1495
+ item.group_id = id
1495
1496
  const name = getString(guild.name)
1496
1497
  || getString(channel.name)
1497
1498
  || getString(item.group_name)
@@ -90,8 +90,10 @@ import {
90
90
  getSessionId,
91
91
  getMissingGroupPreviewSessions,
92
92
  mergeEarlySessionContacts,
93
+ normalizeGroupId,
93
94
  normalizeSessionId,
94
95
  resolveIncomingSession,
96
+ setSessionContact,
95
97
  } from './utils/sessionUtil'
96
98
 
97
99
  const popInfo = new PopInfo()
@@ -1604,7 +1606,12 @@ function saveUser(msg: { [key: string]: any }, type: string) {
1604
1606
  list = list.filter((item, index, arr) => {
1605
1607
  return (
1606
1608
  arr.findIndex((item2) => {
1607
- return item2.group_id == item.group_id
1609
+ const idA = String(item2.channel_id ?? item2.channelId ?? item2.group_id)
1610
+ const idB = String(item.channel_id ?? item.channelId ?? item.group_id)
1611
+ return idA === idB || (
1612
+ !item2.channel_id && !item.channel_id &&
1613
+ normalizeGroupId(idA) === normalizeGroupId(idB)
1614
+ )
1608
1615
  }) == index
1609
1616
  )
1610
1617
  })
@@ -1676,11 +1683,11 @@ function saveUser(msg: { [key: string]: any }, type: string) {
1676
1683
  )
1677
1684
  const existingIds = new Set(
1678
1685
  contactStore.userList.map((item) => {
1679
- return String(item.user_id ?? item.group_id ?? '')
1686
+ return normalizeSessionId(String(item.channel_id ?? item.channelId ?? item.user_id ?? item.group_id ?? ''))
1680
1687
  }),
1681
1688
  )
1682
1689
  const freshList = list.filter((item) => {
1683
- return !existingIds.has(String(item.user_id ?? item.group_id ?? ''))
1690
+ return !existingIds.has(normalizeSessionId(String(item.channel_id ?? item.channelId ?? item.user_id ?? item.group_id ?? '')))
1684
1691
  })
1685
1692
  contactStore.userList = contactStore.userList.concat(freshList)
1686
1693
  if (
@@ -2474,8 +2481,10 @@ function newMsg(_: string, data: any) {
2474
2481
 
2475
2482
  // 会话状态更新 ============================================
2476
2483
  const sessionId = isTempGroupMessage ? sender : id
2477
- const normalizedSessionId = normalizeSessionId(sessionId)
2484
+ const sessionKey = String(sessionChannelId || sessionId)
2485
+ const normalizedSessionId = normalizeSessionId(sessionKey)
2478
2486
  let session = contactStore.baseOnMsgList.get(normalizedSessionId)
2487
+ ?? contactStore.baseOnMsgList.get(normalizeSessionId(sessionId))
2479
2488
  if (!session) {
2480
2489
  if (isTempGroupMessage) {
2481
2490
  session = {
@@ -2521,7 +2530,7 @@ function newMsg(_: string, data: any) {
2521
2530
  if (data.atall) { session.highlight = $t('[@全体]') }
2522
2531
  if (isImportant) { session.highlight = $t('[特別关心]') }
2523
2532
  }
2524
- contactStore.baseOnMsgList.set(normalizedSessionId, session)
2533
+ setSessionContact(contactStore.baseOnMsgList, session)
2525
2534
  updateBaseOnMsgList()
2526
2535
  }
2527
2536
 
@@ -443,7 +443,7 @@ export function satoriEventToOneBot(
443
443
  const userId = getString(user.id)
444
444
  || (isGroup ? '' : getString(channel.id).replace(/^private:/, ''))
445
445
  const groupId = isGroup
446
- ? getString(guild.id) || normalizeGroupId(getString(channel.id))
446
+ ? normalizeGroupId(getString(guild.id)) || normalizeGroupId(getString(channel.id))
447
447
  : ''
448
448
  const directChannelId = isGroup ? groupId : userId
449
449
  const nickname = getString(user.name) || getString(user.nick) || userId
@@ -685,7 +685,7 @@ function messageListFromResponse(data: unknown): unknown[] {
685
685
  const member = getObject(message.member)
686
686
  const isGroup = isGroupChannel(channel, guild)
687
687
  const groupId = isGroup
688
- ? getString(guild.id) || normalizeGroupId(getString(channel.id))
688
+ ? normalizeGroupId(getString(guild.id)) || normalizeGroupId(getString(channel.id))
689
689
  : ''
690
690
  const userId = getString(user.id)
691
691
  || (isGroup ? '' : getString(channel.id).replace(/^private:/, ''))
@@ -740,7 +740,8 @@ export function satoriResponseToOneBot(
740
740
  const mapped = list.map((item) => {
741
741
  const value = getObject(item)
742
742
  const user = getObject(value.user)
743
- const id = getString(value.id)
743
+ const rawId = getString(value.id)
744
+ const id = action === 'get_group_list' ? normalizeGroupId(rawId) : rawId
744
745
  const friendName = getString(user.name)
745
746
  || getString(user.nick)
746
747
  || getString(value.name)
@@ -295,15 +295,15 @@ export function getMsgRawTxt(data: any): string {
295
295
  const atText = String(message[i].text)
296
296
  back += atText.startsWith('@') ? atText : '@' + atText
297
297
  break
298
- case 'text':
299
- back += message[i].text
300
- .replaceAll('\n', ' ')
301
- .replaceAll('\r', ' ')
302
- break
303
- case 'i18n':
304
- back += message[i].path || '[i18n]'
305
- break
306
- case 'forward':
298
+ case 'text':
299
+ back += message[i].text
300
+ .replaceAll('\n', ' ')
301
+ .replaceAll('\r', ' ')
302
+ break
303
+ case 'i18n':
304
+ back += message[i].path || '[i18n]'
305
+ break
306
+ case 'forward':
307
307
  back += '[' + $t('聊天记录') + ']'
308
308
  break
309
309
  case 'face':
@@ -365,7 +365,7 @@ export function hasAtMe(data: any): boolean {
365
365
  * @param data
366
366
  * @returns CQCode 字符串
367
367
  */
368
- export function parseJSONCQCode(data: any) {
368
+ export function parseJSONCQCode(data: any) {
369
369
  let back = ''
370
370
  data.forEach((item: any) => {
371
371
  if (item.type != 'text') {
@@ -380,9 +380,9 @@ export function parseJSONCQCode(data: any) {
380
380
  }
381
381
  })
382
382
  return back
383
- }
384
-
385
- /**
383
+ }
384
+
385
+ /**
386
386
  * 将扁平的 CQCode 消息处理成消息对象
387
387
  * @param msg CQCode 消息
388
388
  * @returns 消息对象
@@ -425,10 +425,10 @@ export function parseCQ(data: any) {
425
425
  .substring(RegExp.$2.lastIndexOf('=') + 1)
426
426
  .replaceAll('\\n', '\n')
427
427
  // 对 html 转义字符进行反转义
428
- const a = document.createElement('a')
429
- a.innerHTML = info.text
430
- info.text = a.innerText
431
- }
428
+ const a = document.createElement('a')
429
+ a.innerHTML = info.text
430
+ info.text = a.innerText
431
+ }
432
432
  // 对回复消息进行特殊处理
433
433
  if (info.type == 'reply') {
434
434
  data.source = {
@@ -604,15 +604,15 @@ async function persistBase64Media(msg: string | any[] | undefined): Promise<stri
604
604
  }))
605
605
  }
606
606
 
607
- export async function sendMsgRaw(
608
- id: string,
609
- type: string,
610
- msg: string | any[] | undefined,
611
- preShow = false,
612
- echo = 'sendMsgBack',
613
- targetChannelId?: string,
614
- targetGuildId?: string,
615
- ) {
607
+ export async function sendMsgRaw(
608
+ id: string,
609
+ type: string,
610
+ msg: string | any[] | undefined,
611
+ preShow = false,
612
+ echo = 'sendMsgBack',
613
+ targetChannelId?: string,
614
+ targetGuildId?: string,
615
+ ) {
616
616
  const chatStore = useChatStore()
617
617
  const authStore = useAuthStore()
618
618
  const contactStore = useContactStore()
@@ -742,11 +742,11 @@ export async function sendMsgRaw(
742
742
  Connector.send(
743
743
  authStore.jsonMap.message_list.name_group_send ??
744
744
  'send_msg',
745
- {
746
- group_id: id,
747
- guild_id: String(targetGuildId ?? chatStore.chatInfo.show.guild_id ?? id),
748
- channel_id: String(targetChannelId ?? chatStore.chatInfo.show.channel_id ?? id),
749
- message: msg,
745
+ {
746
+ group_id: id,
747
+ guild_id: String(targetGuildId ?? chatStore.chatInfo.show.guild_id ?? id),
748
+ channel_id: String(targetChannelId ?? chatStore.chatInfo.show.channel_id ?? id),
749
+ message: msg,
750
750
  },
751
751
  echo + '_uuid_' + msgUUID,
752
752
  )
@@ -757,9 +757,9 @@ export async function sendMsgRaw(
757
757
  authStore.jsonMap.message_list.name_temp_send ??
758
758
  'send_temp_msg',
759
759
  {
760
- user_id: id.split('/')[0],
761
- group_id: id.split('/')[1],
762
- channel_id: String(targetChannelId ?? chatStore.chatInfo.show.channel_id ?? `private:${String(id).split('/')[0]}`),
760
+ user_id: id.split('/')[0],
761
+ group_id: id.split('/')[1],
762
+ channel_id: String(targetChannelId ?? chatStore.chatInfo.show.channel_id ?? `private:${String(id).split('/')[0]}`),
763
763
  message: msg,
764
764
  },
765
765
  echo + '_uuid_' + msgUUID,
@@ -769,8 +769,8 @@ export async function sendMsgRaw(
769
769
  authStore.jsonMap.message_list.name_user_send ??
770
770
  'send_msg',
771
771
  {
772
- user_id: id,
773
- channel_id: String(targetChannelId ?? chatStore.chatInfo.show.channel_id ?? (/^(?:group|room|chat|channel|guild|private):/i.test(String(id)) ? String(id) : `private:${String(id)}`)),
772
+ user_id: id,
773
+ channel_id: String(targetChannelId ?? chatStore.chatInfo.show.channel_id ?? (/^(?:group|room|chat|channel|guild|private):/i.test(String(id)) ? String(id) : `private:${String(id)}`)),
774
774
  message: msg,
775
775
  },
776
776
  echo + '_uuid_' + msgUUID,
@@ -1,13 +1,35 @@
1
1
  import type { Session } from '../elements/information'
2
2
 
3
+ export function normalizeGroupId(value: string): string {
4
+ const raw = value.replace(/^(?:group|room|chat|channel|guild):/i, '').trim()
5
+ const wrapped = raw.match(/^\[_?([\s\S]+?)_?\]$/)
6
+ return wrapped ? wrapped[1] : raw || value
7
+ }
8
+
3
9
  export function normalizeSessionId(value: number | string): string {
4
10
  return String(value)
5
11
  }
6
12
 
7
13
  export function getSessionId(item: Session): number | string {
14
+ const channelId = item.channel_id ?? item.channelId
15
+ if (channelId !== undefined && channelId !== null && String(channelId) !== '') {
16
+ return channelId
17
+ }
8
18
  return item.user_id ?? item.group_id ?? 0
9
19
  }
10
20
 
21
+ export function setSessionContact(
22
+ map: Map<number | string, Session>,
23
+ item: Session,
24
+ ) {
25
+ const key = normalizeSessionId(getSessionId(item))
26
+ map.set(key, item)
27
+ const legacyId = item.user_id ?? item.group_id
28
+ if (legacyId !== undefined && legacyId !== null && String(legacyId) !== key) {
29
+ map.set(normalizeSessionId(String(legacyId)), item)
30
+ }
31
+ }
32
+
11
33
  export function findSessionContact(
12
34
  contacts: Session[],
13
35
  sessionId: number | string,
@@ -401,14 +401,16 @@
401
401
  }
402
402
  }
403
403
  // 清除新消息标记
404
- const item = contactStore.baseOnMsgList.get(normalizeSessionId(id))
404
+ const sessionKey = data.channel_id ?? data.channelId ?? id
405
+ const item = contactStore.baseOnMsgList.get(normalizeSessionId(sessionKey))
406
+ ?? contactStore.baseOnMsgList.get(normalizeSessionId(id))
405
407
  if(item) {
406
408
  if(item.new_msg) {
407
409
  item.new_msg = false
408
410
  contactStore.newMsgCount--
409
411
  }
410
412
  item.highlight = undefined
411
- contactStore.baseOnMsgList.set(normalizeSessionId(id), item)
413
+ contactStore.baseOnMsgList.set(normalizeSessionId(sessionKey), item)
412
414
  // 关闭所有通知
413
415
  new Notify().closeAll((item.group_id ?? item.user_id).toString())
414
416
  }
@@ -472,14 +474,16 @@
472
474
  */
473
475
  function readMsg(data: UserFriendElem & UserGroupElem) {
474
476
  const id = data.group_id ? data.group_id : data.user_id
475
- const item = contactStore.baseOnMsgList.get(normalizeSessionId(id))
477
+ const sessionKey = data.channel_id ?? data.channelId ?? id
478
+ const item = contactStore.baseOnMsgList.get(normalizeSessionId(sessionKey))
479
+ ?? contactStore.baseOnMsgList.get(normalizeSessionId(id))
476
480
  if(item) {
477
481
  if(item.new_msg) {
478
482
  item.new_msg = false
479
483
  contactStore.newMsgCount--
480
484
  }
481
485
  item.highlight = undefined
482
- contactStore.baseOnMsgList.set(normalizeSessionId(id), item)
486
+ contactStore.baseOnMsgList.set(normalizeSessionId(sessionKey), item)
483
487
  }
484
488
  // pop
485
489
  new PopInfo().add(
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-chat-patch",
3
3
  "description": "[<ruby>chat-patch<rp>(</rp><rt>点我预览效果</rt><rp>)</rp></ruby>](https://i0.hdslb.com/bfs/openplatform/71074dfc9e5256fc3333d8bd8478bec1af874046.png) 视奸小插件((bushi( (低性能警告)。手机端适配。灵感来自 chat 插件。",
4
- "version": "5.0.3",
4
+ "version": "5.1.0",
5
5
  "scripts": {
6
6
  "build:web": "npm --prefix client/web run build",
7
7
  "prepack": "npm run build:web",