fix: 手动频繁切换聊天窗口时导致旧的窗口接收不到消息

This commit is contained in:
linyuchen 2024-04-07 17:37:52 +08:00
parent 959eab441e
commit 81821e74d8
2 changed files with 414 additions and 356 deletions

View File

@ -1,8 +1,8 @@
import {BrowserWindow} from 'electron'; import {BrowserWindow} from 'electron';
import {NTQQApiClass} from "./ntcall"; import {NTQQApiClass, NTQQApiMethod} from "./ntcall";
import {NTQQMsgApi, sendMessagePool} from "./api/msg" import {NTQQMsgApi, sendMessagePool} from "./api/msg"
import {ChatType, Group, GroupMember, GroupMemberRole, RawMessage, User} from "./types"; import {ChatType, Group, GroupMember, GroupMemberRole, RawMessage, User} from "./types";
import {friends, getGroupMember, groups, selfInfo, tempGroupCodeMap, uidMaps} from "../common/data"; import {friends, getFriend, getGroupMember, groups, selfInfo, tempGroupCodeMap, uidMaps} from "../common/data";
import {OB11GroupDecreaseEvent} from "../onebot11/event/notice/OB11GroupDecreaseEvent"; import {OB11GroupDecreaseEvent} from "../onebot11/event/notice/OB11GroupDecreaseEvent";
import {v4 as uuidv4} from "uuid" import {v4 as uuidv4} from "uuid"
import {postOB11Event} from "../onebot11/server/postOB11Event"; import {postOB11Event} from "../onebot11/server/postOB11Event";
@ -11,7 +11,7 @@ import fs from "fs";
import {dbUtil} from "../common/db"; import {dbUtil} from "../common/db";
import {NTQQGroupApi} from "./api/group"; import {NTQQGroupApi} from "./api/group";
import {log} from "../common/utils/log"; import {log} from "../common/utils/log";
import {sleep} from "../common/utils/helper"; import {isNumeric, sleep} from "../common/utils/helper";
import {OB11Constructor} from "../onebot11/constructor"; import {OB11Constructor} from "../onebot11/constructor";
export let hookApiCallbacks: Record<string, (apiReturn: any) => void> = {} export let hookApiCallbacks: Record<string, (apiReturn: any) => void> = {}
@ -61,6 +61,12 @@ let receiveHooks: Array<{
id: string id: string
}> = [] }> = []
let callHooks: Array<{
method: NTQQApiMethod[],
hookFunc: ((callParams: unknown[]) => void | Promise<void>)
}> = []
export function hookNTQQApiReceive(window: BrowserWindow) { export function hookNTQQApiReceive(window: BrowserWindow) {
const originalSend = window.webContents.send; const originalSend = window.webContents.send;
const patchSend = (channel: string, ...args: NTQQApiReturnData) => { const patchSend = (channel: string, ...args: NTQQApiReturnData) => {
@ -137,6 +143,27 @@ export function hookNTQQApiCall(window: BrowserWindow) {
HOOK_LOG && log("call NTQQ api", thisArg, args); HOOK_LOG && log("call NTQQ api", thisArg, args);
} catch (e) { } catch (e) {
}
try {
const _args: unknown[] = args[3][1];
const cmdName: NTQQApiMethod = _args[0] as NTQQApiMethod;
const callParams = _args.slice(1);
callHooks.forEach(hook => {
if (hook.method.includes(cmdName)) {
new Promise((resolve, reject) => {
try {
let _ = hook.hookFunc(callParams)
if (hook.hookFunc.constructor.name === "AsyncFunction") {
(_ as Promise<void>).then()
}
} catch (e) {
log("hook call error", e, _args)
}
}).then()
}
})
} catch (e) {
} }
} }
return target.apply(thisArg, args); return target.apply(thisArg, args);
@ -187,6 +214,16 @@ export function registerReceiveHook<PayloadType>(method: ReceiveCmd | ReceiveCmd
return id; return id;
} }
export function registerCallHook(method: NTQQApiMethod | NTQQApiMethod[], hookFunc: (callParams: unknown[]) => void | Promise<void>): void {
if (!Array.isArray(method)) {
method = [method]
}
callHooks.push({
method,
hookFunc
})
}
export function removeReceiveHook(id: string) { export function removeReceiveHook(id: string) {
const index = receiveHooks.findIndex(h => h.id === id) const index = receiveHooks.findIndex(h => h.id === id)
receiveHooks.splice(index, 1); receiveHooks.splice(index, 1);
@ -454,3 +491,23 @@ registerReceiveHook<{
} }
} }
}) })
registerCallHook(NTQQApiMethod.DELETE_ACTIVE_CHAT, async (payload) => {
const peerUid = payload[0] as string;
log("激活的聊天窗口被删除,准备重新激活", peerUid);
let chatType = ChatType.friend;
if (isNumeric(peerUid)) {
chatType = ChatType.group;
}
else{
// 检查是否好友
if (!(await getFriend(peerUid))){
chatType = ChatType.temp;
}
}
const peer = {peerUid, chatType}
await sleep(1000);
NTQQMsgApi.activateChat(peer).then((r) => {
log("重新激活聊天窗口", peer, {result: r.result, errMsg: r.errMsg})
});
})

View File

@ -26,6 +26,7 @@ export enum NTQQApiMethod {
ACTIVE_CHAT_HISTORY = "nodeIKernelMsgService/getMsgsIncludeSelfAndAddActiveChat", // 激活聊天窗口,有时候必须这样才能收到消息, 并返回历史消息 ACTIVE_CHAT_HISTORY = "nodeIKernelMsgService/getMsgsIncludeSelfAndAddActiveChat", // 激活聊天窗口,有时候必须这样才能收到消息, 并返回历史消息
HISTORY_MSG = "nodeIKernelMsgService/getMsgsIncludeSelf", HISTORY_MSG = "nodeIKernelMsgService/getMsgsIncludeSelf",
GET_MULTI_MSG = "nodeIKernelMsgService/getMultiMsg", GET_MULTI_MSG = "nodeIKernelMsgService/getMultiMsg",
DELETE_ACTIVE_CHAT = "nodeIKernelMsgService/deleteActiveChatByUid",
LIKE_FRIEND = "nodeIKernelProfileLikeService/setBuddyProfileLike", LIKE_FRIEND = "nodeIKernelProfileLikeService/setBuddyProfileLike",
SELF_INFO = "fetchAuthData", SELF_INFO = "fetchAuthData",