From c2b331660360e112fefe47ca60238a5873c8fa23 Mon Sep 17 00:00:00 2001 From: linyuchen Date: Tue, 16 Apr 2024 23:15:33 +0800 Subject: [PATCH] fix: send empty forward msg fix: ignore post history msg before login fix: quit group not sync to groups of data feat: support post url params feat: support port http heart --- src/common/config.ts | 1 + src/common/data.ts | 9 + src/common/server/http.ts | 3 + src/common/types.ts | 1 + src/main/main.ts | 12 +- src/main/setConfig.ts | 10 +- src/ntqqapi/api/group.ts | 8 +- src/ntqqapi/hook.ts | 20 +- src/onebot11/action/group/GetGroupList.ts | 24 +- src/onebot11/action/index.ts | 2 + src/onebot11/action/msg/SendMsg.ts | 11 +- src/onebot11/constructor.ts | 869 +++++++++++----------- src/onebot11/server/http.ts | 34 +- src/onebot11/server/postOB11Event.ts | 6 +- src/renderer/index.ts | 3 + 15 files changed, 555 insertions(+), 458 deletions(-) diff --git a/src/common/config.ts b/src/common/config.ts index 600d20e..6ae2723 100644 --- a/src/common/config.ts +++ b/src/common/config.ts @@ -39,6 +39,7 @@ export class ConfigUtil { enableWs: true, enableWsReverse: false, messagePostFormat: "array", + enableHttpHeart: false } let defaultConfig: Config = { ob11: ob11Default, diff --git a/src/common/data.ts b/src/common/data.ts index a6b3c44..982c980 100644 --- a/src/common/data.ts +++ b/src/common/data.ts @@ -58,6 +58,15 @@ export async function getGroup(qq: string): Promise { return group } +export function deleteGroup(groupCode: string) { + const groupIndex = groups.findIndex(group => group.groupCode === groupCode.toString()) + // log(groups, groupCode, groupIndex); + if (groupIndex !== -1) { + log("删除群", groupCode); + groups.splice(groupIndex, 1) + } +} + export async function getGroupMember(groupQQ: string | number, memberUinOrUid: string | number) { groupQQ = groupQQ.toString() memberUinOrUid = memberUinOrUid.toString() diff --git a/src/common/server/http.ts b/src/common/server/http.ts index ccaf49f..e32472c 100644 --- a/src/common/server/http.ts +++ b/src/common/server/http.ts @@ -95,6 +95,9 @@ export abstract class HttpServerBase { if (method == "get") { payload = req.query } + else if (req.query){ + payload = {...req.query, ...req.body} + } log("收到http请求", url, payload); try { res.send(await handler(res, payload)) diff --git a/src/common/types.ts b/src/common/types.ts index 7a89537..7cad1df 100644 --- a/src/common/types.ts +++ b/src/common/types.ts @@ -9,6 +9,7 @@ export interface OB11Config { enableWs?: boolean enableWsReverse?: boolean messagePostFormat?: 'array' | 'string' + enableHttpHeart?: boolean } export interface CheckVersion { result: boolean, diff --git a/src/main/main.ts b/src/main/main.ts index 005aa58..e7c6d2e 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -34,7 +34,7 @@ import { GroupNotifyTypes, RawMessage } from "../ntqqapi/types"; -import {ob11HTTPServer} from "../onebot11/server/http"; +import {httpHeart, ob11HTTPServer} from "../onebot11/server/http"; import {OB11FriendRecallNoticeEvent} from "../onebot11/event/notice/OB11FriendRecallNoticeEvent"; import {OB11GroupRecallNoticeEvent} from "../onebot11/event/notice/OB11GroupRecallNoticeEvent"; import {postOB11Event} from "../onebot11/server/postOB11Event"; @@ -148,7 +148,10 @@ function onLoad() { async function postReceiveMsg(msgList: RawMessage[]) { const {debug, reportSelfMessage} = getConfigUtil().getConfig(); for (let message of msgList) { - + // 过滤启动之前的消息 + if (parseInt(message.msgTime) < startTime / 1000) { + continue; + } // log("收到新消息", message.msgId, message.msgSeq) // if (message.senderUin !== selfInfo.uin){ message.msgShortId = await dbUtil.addMsg(message); @@ -379,7 +382,7 @@ function onLoad() { }) } - let startTime = 0; + let startTime = 0; // 毫秒 async function start() { log("llonebot pid", process.pid) @@ -402,6 +405,9 @@ function onLoad() { if (config.ob11.enableWsReverse) { ob11ReverseWebsockets.start(); } + if (config.ob11.enableHttpHeart){ + httpHeart.start(); + } log("LLOneBot start") } diff --git a/src/main/setConfig.ts b/src/main/setConfig.ts index 7759f56..423ee80 100644 --- a/src/main/setConfig.ts +++ b/src/main/setConfig.ts @@ -1,5 +1,5 @@ import {Config} from "../common/types"; -import {ob11HTTPServer} from "../onebot11/server/http"; +import {httpHeart, ob11HTTPServer} from "../onebot11/server/http"; import {ob11WebsocketServer} from "../onebot11/server/ws/WebsocketServer"; import {ob11ReverseWebsockets} from "../onebot11/server/ws/ReverseWebsocket"; import {llonebotError} from "../common/data"; @@ -54,6 +54,14 @@ export async function setConfig(config: Config) { } } } + if (config.ob11.enableHttpHeart){ + // 启动http心跳 + httpHeart.start(); + } + else{ + // 关闭http心跳 + httpHeart.stop(); + } log("old config", oldConfig) log("配置已更新", config) checkFfmpeg(config.ffmpeg).then() diff --git a/src/ntqqapi/api/group.ts b/src/ntqqapi/api/group.ts index 8e49db5..8730a58 100644 --- a/src/ntqqapi/api/group.ts +++ b/src/ntqqapi/api/group.ts @@ -1,7 +1,7 @@ import {ReceiveCmdS} from "../hook"; import {Group, GroupMember, GroupMemberRole, GroupNotifies, GroupNotify, GroupRequestOperateTypes} from "../types"; import {callNTQQApi, GeneralCallResult, NTQQApiClass, NTQQApiMethod} from "../ntcall"; -import {uidMaps} from "../../common/data"; +import {deleteGroup, uidMaps} from "../../common/data"; import {dbUtil} from "../../common/db"; import {log} from "../../common/utils/log"; import {NTQQWindowApi, NTQQWindows} from "./window"; @@ -102,13 +102,17 @@ export class NTQQGroupApi{ }); } static async quitGroup(groupQQ: string) { - await callNTQQApi({ + const result = await callNTQQApi({ methodName: NTQQApiMethod.QUIT_GROUP, args: [ {"groupCode": groupQQ}, null ] }) + if (result.result === 0){ + deleteGroup(groupQQ); + } + return result; } static async kickMember(groupQQ: string, kickUids: string[], refuseForever: boolean = false, kickReason: string = '') { return await callNTQQApi( diff --git a/src/ntqqapi/hook.ts b/src/ntqqapi/hook.ts index 6cd3f2f..fe78af7 100644 --- a/src/ntqqapi/hook.ts +++ b/src/ntqqapi/hook.ts @@ -2,7 +2,16 @@ import {BrowserWindow} from 'electron'; import {NTQQApiClass, NTQQApiMethod} from "./ntcall"; import {NTQQMsgApi, sendMessagePool} from "./api/msg" import {ChatType, Group, GroupMember, GroupMemberRole, RawMessage, User} from "./types"; -import {friends, getFriend, getGroupMember, groups, selfInfo, tempGroupCodeMap, uidMaps} from "../common/data"; +import { + deleteGroup, + friends, + getFriend, + getGroupMember, + groups, + selfInfo, + tempGroupCodeMap, + uidMaps +} from "../common/data"; import {OB11GroupDecreaseEvent} from "../onebot11/event/notice/OB11GroupDecreaseEvent"; import {v4 as uuidv4} from "uuid" import {postOB11Event} from "../onebot11/server/postOB11Event"; @@ -233,6 +242,11 @@ let activatedGroups: string[] = []; async function updateGroups(_groups: Group[], needUpdate: boolean = true) { for (let group of _groups) { + log("update group", group); + if (group.privilegeFlag === 0){ + deleteGroup(group.groupCode); + continue; + } log("update group", group) // if (!activatedGroups.includes(group.groupCode)) { NTQQMsgApi.activateChat({peerUid: group.groupCode, chatType: ChatType.group}).then((r) => { @@ -294,7 +308,9 @@ async function processGroupEvent(payload: { groupList: Group[] }) { } } } - + if (group.privilegeFlag === 0){ + deleteGroup(group.groupCode); + } } } diff --git a/src/onebot11/action/group/GetGroupList.ts b/src/onebot11/action/group/GetGroupList.ts index f48aff2..69cdbd3 100644 --- a/src/onebot11/action/group/GetGroupList.ts +++ b/src/onebot11/action/group/GetGroupList.ts @@ -6,17 +6,27 @@ import {ActionName} from "../types"; import {NTQQGroupApi} from "../../../ntqqapi/api"; import {log} from "../../../common/utils"; +interface Payload { + no_cache: boolean +} -class GetGroupList extends BaseAction { - actionName = ActionName.GetGroupList +class GetGroupList extends BaseAction { + actionName = ActionName.GetGroupList - protected async _handle(payload: null) { - // if (groups.length === 0) { - // const groups = await NTQQGroupApi.getGroups(true) - // log("get groups", groups) - // } + protected async _handle(payload: Payload) { + if (groups.length === 0 + // || payload.no_cache === true + ) { + try { + const groups = await NTQQGroupApi.getGroups(true) + // log("get groups", groups) return OB11Constructor.groups(groups); + } catch (e) { + + } } + return OB11Constructor.groups(groups); + } } export default GetGroupList \ No newline at end of file diff --git a/src/onebot11/action/index.ts b/src/onebot11/action/index.ts index 7702be9..3e760a7 100644 --- a/src/onebot11/action/index.ts +++ b/src/onebot11/action/index.ts @@ -91,6 +91,8 @@ function initActionMap() { const actionMap = new Map>(); for (const action of actionHandlers) { actionMap.set(action.actionName, action); + actionMap.set(action.actionName + '_async', action); + actionMap.set(action.actionName + '_rate_limited', action); } return actionMap diff --git a/src/onebot11/action/msg/SendMsg.ts b/src/onebot11/action/msg/SendMsg.ts index cb03f8a..5ab9fe1 100644 --- a/src/onebot11/action/msg/SendMsg.ts +++ b/src/onebot11/action/msg/SendMsg.ts @@ -74,15 +74,15 @@ export interface ReturnDataType { export function convertMessage2List(message: OB11MessageMixType, autoEscape = false) { if (typeof message === "string") { - if (!autoEscape) { - message = decodeCQCode(message.toString()) - } else { + if (autoEscape === true) { message = [{ type: OB11MessageDataType.text, data: { text: message } }] + } else { + message = decodeCQCode(message.toString()) } } else if (!Array.isArray(message)) { message = [message] @@ -329,7 +329,7 @@ export class SendMsg extends BaseAction { } else { throw ("发送消息参数错误, 请指定group_id或user_id") } - const messages = convertMessage2List(payload.message, !!payload.auto_escape); + const messages = convertMessage2List(payload.message, payload.auto_escape); if (this.getSpecialMsgNum(payload, OB11MessageDataType.node)) { try { const returnMsg = await this.handleForwardNode(peer, messages as OB11MessageNode[], group) @@ -508,6 +508,9 @@ export class SendMsg extends BaseAction { // nodeIds.push(nodeMsg.msgId) // await sleep(500); // 开发转发 + if (nodeMsgIds.length === 0) { + throw Error("转发消息失败,节点为空") + } try { log("开发转发", nodeMsgIds) return await NTQQMsgApi.multiForwardMsg(srcPeer, destPeer, nodeMsgIds) diff --git a/src/onebot11/constructor.ts b/src/onebot11/constructor.ts index 4416003..89310a7 100644 --- a/src/onebot11/constructor.ts +++ b/src/onebot11/constructor.ts @@ -1,28 +1,28 @@ import { - OB11Group, - OB11GroupMember, - OB11GroupMemberRole, - OB11Message, - OB11MessageData, - OB11MessageDataType, - OB11User, - OB11UserSex + OB11Group, + OB11GroupMember, + OB11GroupMemberRole, + OB11Message, + OB11MessageData, + OB11MessageDataType, + OB11User, + OB11UserSex } from "./types"; import { - AtType, - ChatType, FaceIndex, - GrayTipElementSubType, - Group, - GroupMember, - IMAGE_HTTP_HOST, IMAGE_HTTP_HOST_NT, - RawMessage, - SelfInfo, - Sex, - TipGroupElementType, - User, - VideoElement + AtType, + ChatType, FaceIndex, + GrayTipElementSubType, + Group, + GroupMember, + IMAGE_HTTP_HOST, IMAGE_HTTP_HOST_NT, + RawMessage, + SelfInfo, + Sex, + TipGroupElementType, + User, + VideoElement } from '../ntqqapi/types'; -import {getFriend, getGroupMember, selfInfo, tempGroupCodeMap} from '../common/data'; +import {deleteGroup, getFriend, getGroupMember, groups, selfInfo, tempGroupCodeMap} from '../common/data'; import {EventType} from "./event/OB11BaseEvent"; import {encodeCQCode} from "./cqcode"; import {dbUtil} from "../common/db"; @@ -39,447 +39,450 @@ import {getConfigUtil} from "../common/config"; import {OB11GroupTitleEvent} from "./event/notice/OB11GroupTitleEvent"; import {OB11GroupCardEvent} from "./event/notice/OB11GroupCardEvent"; import {OB11GroupDecreaseEvent} from "./event/notice/OB11GroupDecreaseEvent"; +import {NTQQGroupApi} from "../ntqqapi/api"; let lastRKeyUpdateTime = 0; export class OB11Constructor { - static async message(msg: RawMessage): Promise { - let config = getConfigUtil().getConfig(); - const {enableLocalFile2Url, ob11: {messagePostFormat}} = config; - const message_type = msg.chatType == ChatType.group ? "group" : "private"; - const resMsg: OB11Message = { - self_id: parseInt(selfInfo.uin), - user_id: parseInt(msg.senderUin), - time: parseInt(msg.msgTime) || Date.now(), - message_id: msg.msgShortId, - real_id: msg.msgShortId, - message_type: msg.chatType == ChatType.group ? "group" : "private", - sender: { - user_id: parseInt(msg.senderUin), - nickname: msg.sendNickName, - card: msg.sendMemberName || "", - }, - raw_message: "", - font: 14, - sub_type: "friend", - message: messagePostFormat === 'string' ? '' : [], - message_format: messagePostFormat === 'string' ? 'string' : 'array', - post_type: selfInfo.uin == msg.senderUin ? EventType.MESSAGE_SENT : EventType.MESSAGE, - } - if (msg.chatType == ChatType.group) { - resMsg.sub_type = "normal" // 这里go-cqhttp是group,而onebot11标准是normal, 蛋疼 - resMsg.group_id = parseInt(msg.peerUin) - const member = await getGroupMember(msg.peerUin, msg.senderUin); - if (member) { - resMsg.sender.role = OB11Constructor.groupMemberRole(member.role); - resMsg.sender.nickname = member.nick + static async message(msg: RawMessage): Promise { + let config = getConfigUtil().getConfig(); + const {enableLocalFile2Url, ob11: {messagePostFormat}} = config; + const message_type = msg.chatType == ChatType.group ? "group" : "private"; + const resMsg: OB11Message = { + self_id: parseInt(selfInfo.uin), + user_id: parseInt(msg.senderUin), + time: parseInt(msg.msgTime) || Date.now(), + message_id: msg.msgShortId, + real_id: msg.msgShortId, + message_type: msg.chatType == ChatType.group ? "group" : "private", + sender: { + user_id: parseInt(msg.senderUin), + nickname: msg.sendNickName, + card: msg.sendMemberName || "", + }, + raw_message: "", + font: 14, + sub_type: "friend", + message: messagePostFormat === 'string' ? '' : [], + message_format: messagePostFormat === 'string' ? 'string' : 'array', + post_type: selfInfo.uin == msg.senderUin ? EventType.MESSAGE_SENT : EventType.MESSAGE, + } + if (msg.chatType == ChatType.group) { + resMsg.sub_type = "normal" // 这里go-cqhttp是group,而onebot11标准是normal, 蛋疼 + resMsg.group_id = parseInt(msg.peerUin) + const member = await getGroupMember(msg.peerUin, msg.senderUin); + if (member) { + resMsg.sender.role = OB11Constructor.groupMemberRole(member.role); + resMsg.sender.nickname = member.nick + } + } else if (msg.chatType == ChatType.friend) { + resMsg.sub_type = "friend" + const friend = await getFriend(msg.senderUin); + if (friend) { + resMsg.sender.nickname = friend.nick; + } + } else if (msg.chatType == ChatType.temp) { + resMsg.sub_type = "group" + const tempGroupCode = tempGroupCodeMap[msg.peerUin] + if (tempGroupCode) { + resMsg.group_id = parseInt(tempGroupCode) + } + } + + for (let element of msg.elements) { + let message_data: OB11MessageData | any = { + data: {}, + type: "unknown" + } + if (element.textElement && element.textElement?.atType !== AtType.notAt) { + message_data["type"] = OB11MessageDataType.at + if (element.textElement.atType == AtType.atAll) { + // message_data["data"]["mention"] = "all" + message_data["data"]["qq"] = "all" + } else { + let atUid = element.textElement.atNtUid + let atQQ = element.textElement.atUid + if (!atQQ || atQQ === "0") { + const atMember = await getGroupMember(msg.peerUin, atUid) + if (atMember) { + atQQ = atMember.uin } - } else if (msg.chatType == ChatType.friend) { - resMsg.sub_type = "friend" - const friend = await getFriend(msg.senderUin); - if (friend) { - resMsg.sender.nickname = friend.nick; + } + if (atQQ) { + // message_data["data"]["mention"] = atQQ + message_data["data"]["qq"] = atQQ + } + } + } else if (element.textElement) { + message_data["type"] = "text" + let text = element.textElement.content + if (!text.trim()) { + continue; + } + message_data["data"]["text"] = text + } else if (element.replyElement) { + message_data["type"] = "reply" + // log("收到回复消息", element.replyElement.replayMsgSeq) + try { + const replyMsg = await dbUtil.getMsgBySeqId(element.replyElement.replayMsgSeq) + // log("找到回复消息", replyMsg.msgShortId, replyMsg.msgId) + if (replyMsg) { + message_data["data"]["id"] = replyMsg.msgShortId.toString() + } else { + continue + } + } catch (e) { + log("获取不到引用的消息", e.stack, element.replyElement.replayMsgSeq) + } + + } else if (element.picElement) { + message_data["type"] = "image" + // message_data["data"]["file"] = element.picElement.sourcePath + message_data["data"]["file"] = element.picElement.fileName + // message_data["data"]["path"] = element.picElement.sourcePath + const url = element.picElement.originImageUrl + const fileMd5 = element.picElement.md5HexStr + const fileUuid = element.picElement.fileUuid + // let currentRKey = config.imageRKey || "CAQSKAB6JWENi5LMk0kc62l8Pm3Jn1dsLZHyRLAnNmHGoZ3y_gDZPqZt-64" + let currentRKey = "CAQSKAB6JWENi5LMk0kc62l8Pm3Jn1dsLZHyRLAnNmHGoZ3y_gDZPqZt-64" + if (url) { + if (url.startsWith("/download")) { + if (url.includes("&rkey=")) { + // 正则提取rkey + // const rkey = url.match(/&rkey=([^&]+)/)[1] + // // log("图片url已有rkey", rkey) + // if (rkey != currentRKey){ + // config.imageRKey = rkey + // if (Date.now() - lastRKeyUpdateTime > 1000 * 60) { + // lastRKeyUpdateTime = Date.now() + // getConfigUtil().setConfig(config) + // } + // } + message_data["data"]["url"] = IMAGE_HTTP_HOST + url + } else { + // 有可能会碰到appid为1406的,这个不能使用新的NT域名,并且需要把appid改为1407才可访问 + message_data["data"]["url"] = `${IMAGE_HTTP_HOST}/download?appid=1407&fileid=${fileUuid}&rkey=${currentRKey}&spec=0` } - } else if (msg.chatType == ChatType.temp) { - resMsg.sub_type = "group" - const tempGroupCode = tempGroupCodeMap[msg.peerUin] - if (tempGroupCode) { - resMsg.group_id = parseInt(tempGroupCode) + } else { + message_data["data"]["url"] = IMAGE_HTTP_HOST + url + } + } else if (fileMd5) { + message_data["data"]["url"] = `${IMAGE_HTTP_HOST}/gchatpic_new/0/0-0-${fileMd5.toUpperCase()}/0` + } + // message_data["data"]["file_id"] = element.picElement.fileUuid + message_data["data"]["file_size"] = element.picElement.fileSize + dbUtil.addFileCache(element.picElement.fileName, { + fileName: element.picElement.fileName, + filePath: element.picElement.sourcePath, + fileSize: element.picElement.fileSize.toString(), + url: message_data["data"]["url"], + downloadFunc: async () => { + await NTQQFileApi.downloadMedia(msg.msgId, msg.chatType, msg.peerUid, + element.elementId, element.picElement.thumbPath?.get(0) || "", element.picElement.sourcePath) + } + }).then() + // 不在自动下载图片 + + } else if (element.videoElement || element.fileElement) { + const videoOrFileElement = element.videoElement || element.fileElement + const ob11MessageDataType = element.videoElement ? OB11MessageDataType.video : OB11MessageDataType.file + message_data["type"] = ob11MessageDataType; + message_data["data"]["file"] = videoOrFileElement.fileName + message_data["data"]["path"] = videoOrFileElement.filePath + message_data["data"]["file_id"] = videoOrFileElement.fileUuid + message_data["data"]["file_size"] = videoOrFileElement.fileSize + dbUtil.addFileCache(videoOrFileElement.fileUuid, { + msgId: msg.msgId, + fileName: videoOrFileElement.fileName, + filePath: videoOrFileElement.filePath, + fileSize: videoOrFileElement.fileSize, + downloadFunc: async () => { + await NTQQFileApi.downloadMedia( + msg.msgId, msg.chatType, msg.peerUid, + element.elementId, + ob11MessageDataType == OB11MessageDataType.video ? (videoOrFileElement as VideoElement).thumbPath.get(0) : null, + videoOrFileElement.filePath) + } + }).then() + // 怎么拿到url呢 + } else if (element.pttElement) { + message_data["type"] = OB11MessageDataType.voice; + message_data["data"]["file"] = element.pttElement.fileName + message_data["data"]["path"] = element.pttElement.filePath + // message_data["data"]["file_id"] = element.pttElement.fileUuid + message_data["data"]["file_size"] = element.pttElement.fileSize + dbUtil.addFileCache(element.pttElement.fileName, { + fileName: element.pttElement.fileName, + filePath: element.pttElement.filePath, + fileSize: element.pttElement.fileSize, + }).then() + + // log("收到语音消息", msg) + // window.LLAPI.Ptt2Text(message.raw.msgId, message.peer, messages).then(text => { + // console.log("语音转文字结果", text); + // }).catch(err => { + // console.log("语音转文字失败", err); + // }) + } else if (element.arkElement) { + message_data["type"] = OB11MessageDataType.json; + message_data["data"]["data"] = element.arkElement.bytesData; + } else if (element.faceElement) { + const faceId = element.faceElement.faceIndex; + if (faceId === FaceIndex.dice) { + message_data["type"] = OB11MessageDataType.dice + message_data["data"]["result"] = element.faceElement.resultId; + } else if (faceId === FaceIndex.RPS) { + message_data["type"] = OB11MessageDataType.RPS + message_data["data"]["result"] = element.faceElement.resultId; + } else { + message_data["type"] = OB11MessageDataType.face; + message_data["data"]["id"] = element.faceElement.faceIndex.toString(); + } + } else if (element.marketFaceElement) { + message_data["type"] = OB11MessageDataType.mface; + message_data["data"]["text"] = element.marketFaceElement.faceName; + } else if (element.markdownElement) { + message_data["type"] = OB11MessageDataType.markdown; + message_data["data"]["data"] = element.markdownElement.content; + } else if (element.multiForwardMsgElement) { + message_data["type"] = OB11MessageDataType.forward; + message_data["data"]["id"] = msg.msgId + } + if (message_data.type !== "unknown" && message_data.data) { + const cqCode = encodeCQCode(message_data); + if (messagePostFormat === 'string') { + (resMsg.message as string) += cqCode; + } else (resMsg.message as OB11MessageData[]).push(message_data); + + resMsg.raw_message += cqCode; + } + } + resMsg.raw_message = resMsg.raw_message.trim(); + return resMsg; + } + + static async GroupEvent(msg: RawMessage): Promise { + if (msg.chatType !== ChatType.group) { + return; + } + if (msg.senderUin) { + let member = await getGroupMember(msg.peerUid, msg.senderUin); + if (member && member.cardName !== msg.sendMemberName) { + const event = new OB11GroupCardEvent(parseInt(msg.peerUid), parseInt(msg.senderUin), msg.sendMemberName, member.cardName) + member.cardName = msg.sendMemberName; + return event + } + } + // log("group msg", msg); + for (let element of msg.elements) { + const grayTipElement = element.grayTipElement + const groupElement = grayTipElement?.groupElement + if (groupElement) { + // log("收到群提示消息", groupElement) + if (groupElement.type == TipGroupElementType.memberIncrease) { + log("收到群成员增加消息", groupElement) + await sleep(1000); + const member = await getGroupMember(msg.peerUid, groupElement.memberUid); + let memberUin = member?.uin; + if (!memberUin) { + memberUin = (await NTQQUserApi.getUserDetailInfo(groupElement.memberUid)).uin + } + // log("获取新群成员QQ", memberUin) + const adminMember = await getGroupMember(msg.peerUid, groupElement.adminUid); + // log("获取同意新成员入群的管理员", adminMember) + if (memberUin) { + const operatorUin = adminMember?.uin || memberUin + let event = new OB11GroupIncreaseEvent(parseInt(msg.peerUid), parseInt(memberUin), parseInt(operatorUin)); + // log("构造群增加事件", event) + return event; + } + } else if (groupElement.type === TipGroupElementType.ban) { + log("收到群群员禁言提示", groupElement) + const memberUid = groupElement.shutUp.member.uid + const adminUid = groupElement.shutUp.admin.uid + let memberUin: string = "" + let duration = parseInt(groupElement.shutUp.duration) + let sub_type: "ban" | "lift_ban" = duration > 0 ? "ban" : "lift_ban" + if (memberUid) { + memberUin = (await getGroupMember(msg.peerUid, memberUid))?.uin || (await NTQQUserApi.getUserDetailInfo(memberUid))?.uin + } else { + memberUin = "0"; // 0表示全员禁言 + if (duration > 0) { + duration = -1 } - } - - for (let element of msg.elements) { - let message_data: OB11MessageData | any = { - data: {}, - type: "unknown" + } + const adminUin = (await getGroupMember(msg.peerUid, adminUid))?.uin || (await NTQQUserApi.getUserDetailInfo(adminUid))?.uin + if (memberUin && adminUin) { + return new OB11GroupBanEvent(parseInt(msg.peerUid), parseInt(memberUin), parseInt(adminUin), duration, sub_type); + } + } else if (groupElement.type == TipGroupElementType.kicked) { + log(`收到我被踢出或退群提示, 群${msg.peerUid}`, groupElement) + deleteGroup(msg.peerUid); + NTQQGroupApi.quitGroup(msg.peerUid).then() + try { + const adminUin = (await getGroupMember(msg.peerUid, groupElement.adminUid))?.uin || (await NTQQUserApi.getUserDetailInfo(groupElement.adminUid))?.uin + if (adminUin) { + return new OB11GroupDecreaseEvent(parseInt(msg.peerUid), parseInt(selfInfo.uin), parseInt(adminUin), "kick_me"); } - if (element.textElement && element.textElement?.atType !== AtType.notAt) { - message_data["type"] = OB11MessageDataType.at - if (element.textElement.atType == AtType.atAll) { - // message_data["data"]["mention"] = "all" - message_data["data"]["qq"] = "all" - } else { - let atUid = element.textElement.atNtUid - let atQQ = element.textElement.atUid - if (!atQQ || atQQ === "0") { - const atMember = await getGroupMember(msg.peerUin, atUid) - if (atMember) { - atQQ = atMember.uin - } - } - if (atQQ) { - // message_data["data"]["mention"] = atQQ - message_data["data"]["qq"] = atQQ - } - } - } else if (element.textElement) { - message_data["type"] = "text" - let text = element.textElement.content - if (!text.trim()) { - continue; - } - message_data["data"]["text"] = text - } else if (element.replyElement) { - message_data["type"] = "reply" - // log("收到回复消息", element.replyElement.replayMsgSeq) - try { - const replyMsg = await dbUtil.getMsgBySeqId(element.replyElement.replayMsgSeq) - // log("找到回复消息", replyMsg.msgShortId, replyMsg.msgId) - if (replyMsg) { - message_data["data"]["id"] = replyMsg.msgShortId.toString() - } else { - continue - } - } catch (e) { - log("获取不到引用的消息", e.stack, element.replyElement.replayMsgSeq) - } + } catch (e) { + return new OB11GroupDecreaseEvent(parseInt(msg.peerUid), parseInt(selfInfo.uin), 0, "leave"); + } + } + } else if (element.fileElement) { + return new OB11GroupUploadNoticeEvent(parseInt(msg.peerUid), parseInt(msg.senderUin), { + id: element.fileElement.fileUuid, + name: element.fileElement.fileName, + size: parseInt(element.fileElement.fileSize), + busid: element.fileElement.fileBizId || 0 + }) + } - } else if (element.picElement) { - message_data["type"] = "image" - // message_data["data"]["file"] = element.picElement.sourcePath - message_data["data"]["file"] = element.picElement.fileName - // message_data["data"]["path"] = element.picElement.sourcePath - const url = element.picElement.originImageUrl - const fileMd5 = element.picElement.md5HexStr - const fileUuid = element.picElement.fileUuid - // let currentRKey = config.imageRKey || "CAQSKAB6JWENi5LMk0kc62l8Pm3Jn1dsLZHyRLAnNmHGoZ3y_gDZPqZt-64" - let currentRKey = "CAQSKAB6JWENi5LMk0kc62l8Pm3Jn1dsLZHyRLAnNmHGoZ3y_gDZPqZt-64" - if (url) { - if (url.startsWith("/download")) { - if (url.includes("&rkey=")) { - // 正则提取rkey - // const rkey = url.match(/&rkey=([^&]+)/)[1] - // // log("图片url已有rkey", rkey) - // if (rkey != currentRKey){ - // config.imageRKey = rkey - // if (Date.now() - lastRKeyUpdateTime > 1000 * 60) { - // lastRKeyUpdateTime = Date.now() - // getConfigUtil().setConfig(config) - // } - // } - message_data["data"]["url"] = IMAGE_HTTP_HOST + url - } - else{ - // 有可能会碰到appid为1406的,这个不能使用新的NT域名,并且需要把appid改为1407才可访问 - message_data["data"]["url"] = `${IMAGE_HTTP_HOST}/download?appid=1407&fileid=${fileUuid}&rkey=${currentRKey}&spec=0` - } - } else { - message_data["data"]["url"] = IMAGE_HTTP_HOST + url - } - } else if (fileMd5) { - message_data["data"]["url"] = `${IMAGE_HTTP_HOST}/gchatpic_new/0/0-0-${fileMd5.toUpperCase()}/0` - } - // message_data["data"]["file_id"] = element.picElement.fileUuid - message_data["data"]["file_size"] = element.picElement.fileSize - dbUtil.addFileCache(element.picElement.fileName, { - fileName: element.picElement.fileName, - filePath: element.picElement.sourcePath, - fileSize: element.picElement.fileSize.toString(), - url: message_data["data"]["url"], - downloadFunc: async () => { - await NTQQFileApi.downloadMedia(msg.msgId, msg.chatType, msg.peerUid, - element.elementId, element.picElement.thumbPath?.get(0) || "", element.picElement.sourcePath) - } - }).then() - // 不在自动下载图片 + if (grayTipElement) { + if (grayTipElement.subElementType == GrayTipElementSubType.INVITE_NEW_MEMBER) { + log("收到新人被邀请进群消息", grayTipElement) + const xmlElement = grayTipElement.xmlElement + if (xmlElement?.content) { + const regex = /jp="(\d+)"/g; - } else if (element.videoElement || element.fileElement) { - const videoOrFileElement = element.videoElement || element.fileElement - const ob11MessageDataType = element.videoElement ? OB11MessageDataType.video : OB11MessageDataType.file - message_data["type"] = ob11MessageDataType; - message_data["data"]["file"] = videoOrFileElement.fileName - message_data["data"]["path"] = videoOrFileElement.filePath - message_data["data"]["file_id"] = videoOrFileElement.fileUuid - message_data["data"]["file_size"] = videoOrFileElement.fileSize - dbUtil.addFileCache(videoOrFileElement.fileUuid, { - msgId: msg.msgId, - fileName: videoOrFileElement.fileName, - filePath: videoOrFileElement.filePath, - fileSize: videoOrFileElement.fileSize, - downloadFunc: async () => { - await NTQQFileApi.downloadMedia( - msg.msgId, msg.chatType, msg.peerUid, - element.elementId, - ob11MessageDataType == OB11MessageDataType.video ? (videoOrFileElement as VideoElement).thumbPath.get(0) : null, - videoOrFileElement.filePath) - } - }).then() - // 怎么拿到url呢 - } else if (element.pttElement) { - message_data["type"] = OB11MessageDataType.voice; - message_data["data"]["file"] = element.pttElement.fileName - message_data["data"]["path"] = element.pttElement.filePath - // message_data["data"]["file_id"] = element.pttElement.fileUuid - message_data["data"]["file_size"] = element.pttElement.fileSize - dbUtil.addFileCache(element.pttElement.fileName, { - fileName: element.pttElement.fileName, - filePath: element.pttElement.filePath, - fileSize: element.pttElement.fileSize, - }).then() + let matches = []; + let match = null - // log("收到语音消息", msg) - // window.LLAPI.Ptt2Text(message.raw.msgId, message.peer, messages).then(text => { - // console.log("语音转文字结果", text); - // }).catch(err => { - // console.log("语音转文字失败", err); - // }) - } else if (element.arkElement) { - message_data["type"] = OB11MessageDataType.json; - message_data["data"]["data"] = element.arkElement.bytesData; - } else if (element.faceElement) { - const faceId = element.faceElement.faceIndex; - if (faceId === FaceIndex.dice){ - message_data["type"] = OB11MessageDataType.dice - message_data["data"]["result"] = element.faceElement.resultId; - } - else if (faceId === FaceIndex.RPS){ - message_data["type"] = OB11MessageDataType.RPS - message_data["data"]["result"] = element.faceElement.resultId; - } - else{ - message_data["type"] = OB11MessageDataType.face; - message_data["data"]["id"] = element.faceElement.faceIndex.toString(); - } - } else if (element.marketFaceElement) { - message_data["type"] = OB11MessageDataType.mface; - message_data["data"]["text"] = element.marketFaceElement.faceName; - } else if (element.markdownElement){ - message_data["type"] = OB11MessageDataType.markdown; - message_data["data"]["data"] = element.markdownElement.content; - } else if (element.multiForwardMsgElement){ - message_data["type"] = OB11MessageDataType.forward; - message_data["data"]["id"] = msg.msgId + while ((match = regex.exec(xmlElement.content)) !== null) { + matches.push(match[1]); } - if (message_data.type !== "unknown" && message_data.data) { - const cqCode = encodeCQCode(message_data); - if (messagePostFormat === 'string') { - (resMsg.message as string) += cqCode; - } else (resMsg.message as OB11MessageData[]).push(message_data); - - resMsg.raw_message += cqCode; + // log("新人进群匹配到的QQ号", matches) + if (matches.length === 2) { + const [inviter, invitee] = matches; + return new OB11GroupIncreaseEvent(parseInt(msg.peerUid), parseInt(invitee), parseInt(inviter), "invite"); } + } + } else if (grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE) { + const json = JSON.parse(grayTipElement.jsonGrayTipElement.jsonStr) + /* + { + align: 'center', + items: [ + { txt: '恭喜', type: 'nor' }, + { + col: '3', + jp: '5', + param: ["QQ号"], + txt: '林雨辰', + type: 'url' + }, + { txt: '获得群主授予的', type: 'nor' }, + { + col: '3', + jp: '', + txt: '好好好', + type: 'url' + }, + { txt: '头衔', type: 'nor' } + ] + } + + * */ + const memberUin = json.items[1].param[0] + const title = json.items[3].txt + log("收到群成员新头衔消息", json) + getGroupMember(msg.peerUid, memberUin).then(member => { + member.memberSpecialTitle = title + }) + return new OB11GroupTitleEvent(parseInt(msg.peerUid), parseInt(memberUin), title) } - resMsg.raw_message = resMsg.raw_message.trim(); - return resMsg; + } } + } - static async GroupEvent(msg: RawMessage): Promise { - if (msg.chatType !== ChatType.group) { - return; - } - if (msg.senderUin){ - let member = await getGroupMember(msg.peerUid, msg.senderUin); - if (member && member.cardName !== msg.sendMemberName) { - const event = new OB11GroupCardEvent(parseInt(msg.peerUid), parseInt(msg.senderUin), msg.sendMemberName, member.cardName) - member.cardName = msg.sendMemberName; - return event - } - } - // log("group msg", msg); - for (let element of msg.elements) { - const grayTipElement = element.grayTipElement - const groupElement = grayTipElement?.groupElement - if (groupElement) { - // log("收到群提示消息", groupElement) - if (groupElement.type == TipGroupElementType.memberIncrease) { - log("收到群成员增加消息", groupElement) - await sleep(1000); - const member = await getGroupMember(msg.peerUid, groupElement.memberUid); - let memberUin = member?.uin; - if (!memberUin) { - memberUin = (await NTQQUserApi.getUserDetailInfo(groupElement.memberUid)).uin - } - // log("获取新群成员QQ", memberUin) - const adminMember = await getGroupMember(msg.peerUid, groupElement.adminUid); - // log("获取同意新成员入群的管理员", adminMember) - if (memberUin) { - const operatorUin = adminMember?.uin || memberUin - let event = new OB11GroupIncreaseEvent(parseInt(msg.peerUid), parseInt(memberUin), parseInt(operatorUin)); - // log("构造群增加事件", event) - return event; - } - } else if (groupElement.type === TipGroupElementType.ban) { - log("收到群群员禁言提示", groupElement) - const memberUid = groupElement.shutUp.member.uid - const adminUid = groupElement.shutUp.admin.uid - let memberUin: string = "" - let duration = parseInt(groupElement.shutUp.duration) - let sub_type: "ban" | "lift_ban" = duration > 0 ? "ban" : "lift_ban" - if (memberUid) { - memberUin = (await getGroupMember(msg.peerUid, memberUid))?.uin || (await NTQQUserApi.getUserDetailInfo(memberUid))?.uin - } else { - memberUin = "0"; // 0表示全员禁言 - if (duration > 0) { - duration = -1 - } - } - const adminUin = (await getGroupMember(msg.peerUid, adminUid))?.uin || (await NTQQUserApi.getUserDetailInfo(adminUid))?.uin - if (memberUin && adminUin) { - return new OB11GroupBanEvent(parseInt(msg.peerUid), parseInt(memberUin), parseInt(adminUin), duration, sub_type); - } - } - else if (groupElement.type == TipGroupElementType.kicked){ - log("收到我被踢出提示", groupElement) - const adminUin = (await getGroupMember(msg.peerUid, groupElement.adminUid))?.uin || (await NTQQUserApi.getUserDetailInfo(groupElement.adminUid))?.uin - if (adminUin) { - return new OB11GroupDecreaseEvent(parseInt(msg.peerUid), parseInt(selfInfo.uin), parseInt(adminUin), "kick_me"); - } - } - } else if (element.fileElement) { - return new OB11GroupUploadNoticeEvent(parseInt(msg.peerUid), parseInt(msg.senderUin), { - id: element.fileElement.fileUuid, - name: element.fileElement.fileName, - size: parseInt(element.fileElement.fileSize), - busid: element.fileElement.fileBizId || 0 - }) - } - - if (grayTipElement) { - if (grayTipElement.subElementType == GrayTipElementSubType.INVITE_NEW_MEMBER) { - log("收到新人被邀请进群消息", grayTipElement) - const xmlElement = grayTipElement.xmlElement - if (xmlElement?.content) { - const regex = /jp="(\d+)"/g; - - let matches = []; - let match = null - - while ((match = regex.exec(xmlElement.content)) !== null) { - matches.push(match[1]); - } - // log("新人进群匹配到的QQ号", matches) - if (matches.length === 2) { - const [inviter, invitee] = matches; - return new OB11GroupIncreaseEvent(parseInt(msg.peerUid), parseInt(invitee), parseInt(inviter), "invite"); - } - } - } else if (grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE) { - const json = JSON.parse(grayTipElement.jsonGrayTipElement.jsonStr) - /* - { - align: 'center', - items: [ - { txt: '恭喜', type: 'nor' }, - { - col: '3', - jp: '5', - param: ["QQ号"], - txt: '林雨辰', - type: 'url' - }, - { txt: '获得群主授予的', type: 'nor' }, - { - col: '3', - jp: '', - txt: '好好好', - type: 'url' - }, - { txt: '头衔', type: 'nor' } - ] - } - - * */ - const memberUin = json.items[1].param[0] - const title = json.items[3].txt - log("收到群成员新头衔消息", json) - getGroupMember(msg.peerUid, memberUin).then(member => { - member.memberSpecialTitle = title - }) - return new OB11GroupTitleEvent(parseInt(msg.peerUid), parseInt(memberUin), title) - } - } - } + static friend(friend: User): OB11User { + return { + user_id: parseInt(friend.uin), + nickname: friend.nick, + remark: friend.remark, + sex: OB11Constructor.sex(friend.sex), + level: friend.qqLevel && calcQQLevel(friend.qqLevel) || 0 } + } - static friend(friend: User): OB11User { - return { - user_id: parseInt(friend.uin), - nickname: friend.nick, - remark: friend.remark, - sex: OB11Constructor.sex(friend.sex), - level: friend.qqLevel && calcQQLevel(friend.qqLevel) || 0 - } + static selfInfo(selfInfo: SelfInfo): OB11User { + return { + user_id: parseInt(selfInfo.uin), + nickname: selfInfo.nick, } + } - static selfInfo(selfInfo: SelfInfo): OB11User { - return { - user_id: parseInt(selfInfo.uin), - nickname: selfInfo.nick, - } - } + static friends(friends: User[]): OB11User[] { + return friends.map(OB11Constructor.friend) + } - static friends(friends: User[]): OB11User[] { - return friends.map(OB11Constructor.friend) - } + static groupMemberRole(role: number): OB11GroupMemberRole | undefined { + return { + 4: OB11GroupMemberRole.owner, + 3: OB11GroupMemberRole.admin, + 2: OB11GroupMemberRole.member + }[role] + } - static groupMemberRole(role: number): OB11GroupMemberRole | undefined { - return { - 4: OB11GroupMemberRole.owner, - 3: OB11GroupMemberRole.admin, - 2: OB11GroupMemberRole.member - }[role] + static sex(sex: Sex): OB11UserSex { + const sexMap = { + [Sex.male]: OB11UserSex.male, + [Sex.female]: OB11UserSex.female, + [Sex.unknown]: OB11UserSex.unknown } + return sexMap[sex] || OB11UserSex.unknown + } - static sex(sex: Sex): OB11UserSex { - const sexMap = { - [Sex.male]: OB11UserSex.male, - [Sex.female]: OB11UserSex.female, - [Sex.unknown]: OB11UserSex.unknown - } - return sexMap[sex] || OB11UserSex.unknown + static groupMember(group_id: string, member: GroupMember): OB11GroupMember { + return { + group_id: parseInt(group_id), + user_id: parseInt(member.uin), + nickname: member.nick, + card: member.cardName, + sex: OB11Constructor.sex(member.sex), + age: 0, + area: "", + level: 0, + qq_level: member.qqLevel && calcQQLevel(member.qqLevel) || 0, + join_time: 0, // 暂时没法获取 + last_sent_time: 0, // 暂时没法获取 + title_expire_time: 0, + unfriendly: false, + card_changeable: true, + is_robot: member.isRobot, + shut_up_timestamp: member.shutUpTime, + role: OB11Constructor.groupMemberRole(member.role), + title: member.memberSpecialTitle || "", } + } - static groupMember(group_id: string, member: GroupMember): OB11GroupMember { - return { - group_id: parseInt(group_id), - user_id: parseInt(member.uin), - nickname: member.nick, - card: member.cardName, - sex: OB11Constructor.sex(member.sex), - age: 0, - area: "", - level: 0, - qq_level: member.qqLevel && calcQQLevel(member.qqLevel) || 0, - join_time: 0, // 暂时没法获取 - last_sent_time: 0, // 暂时没法获取 - title_expire_time: 0, - unfriendly: false, - card_changeable: true, - is_robot: member.isRobot, - shut_up_timestamp: member.shutUpTime, - role: OB11Constructor.groupMemberRole(member.role), - title: member.memberSpecialTitle || "", - } + static stranger(user: User): OB11User { + return { + ...user, + user_id: parseInt(user.uin), + nickname: user.nick, + sex: OB11Constructor.sex(user.sex), + age: 0, + qid: user.qid, + login_days: 0, + level: user.qqLevel && calcQQLevel(user.qqLevel) || 0, } + } - static stranger(user: User): OB11User { - return { - ...user, - user_id: parseInt(user.uin), - nickname: user.nick, - sex: OB11Constructor.sex(user.sex), - age: 0, - qid: user.qid, - login_days: 0, - level: user.qqLevel && calcQQLevel(user.qqLevel) || 0, - } - } + static groupMembers(group: Group): OB11GroupMember[] { + log("construct ob11 group members", group) + return group.members.map(m => OB11Constructor.groupMember(group.groupCode, m)) + } - static groupMembers(group: Group): OB11GroupMember[] { - log("construct ob11 group members", group) - return group.members.map(m => OB11Constructor.groupMember(group.groupCode, m)) + static group(group: Group): OB11Group { + return { + group_id: parseInt(group.groupCode), + group_name: group.groupName, + member_count: group.memberCount, + max_member_count: group.maxMember } + } - static group(group: Group): OB11Group { - return { - group_id: parseInt(group.groupCode), - group_name: group.groupName, - member_count: group.memberCount, - max_member_count: group.maxMember - } - } - - static groups(groups: Group[]): OB11Group[] { - return groups.map(OB11Constructor.group) - } + static groups(groups: Group[]): OB11Group[] { + return groups.map(OB11Constructor.group) + } } diff --git a/src/onebot11/server/http.ts b/src/onebot11/server/http.ts index ac7a95b..e614f66 100644 --- a/src/onebot11/server/http.ts +++ b/src/onebot11/server/http.ts @@ -1,8 +1,11 @@ import {Response} from "express"; import {OB11Response} from "../action/OB11Response"; import {HttpServerBase} from "../../common/server/http"; -import {actionHandlers} from "../action"; +import {actionHandlers, actionMap} from "../action"; import {getConfigUtil} from "../../common/config"; +import {postOB11Event} from "./postOB11Event"; +import {OB11HeartbeatEvent} from "../event/meta/OB11HeartbeatEvent"; +import {selfInfo} from "../../common/data"; class OB11HTTPServer extends HttpServerBase { name = "OneBot V11 server" @@ -21,9 +24,32 @@ class OB11HTTPServer extends HttpServerBase { export const ob11HTTPServer = new OB11HTTPServer(); setTimeout(() => { - for (const action of actionHandlers) { + for (const [actionName, action] of actionMap) { for (const method of ["post", "get"]) { - ob11HTTPServer.registerRouter(method, action.actionName, (res, payload) => action.handle(payload)) + ob11HTTPServer.registerRouter(method, actionName, (res, payload) => action.handle(payload)) } } -}, 0) \ No newline at end of file +}, 0) + + +class HTTPHeart{ + intervalId: NodeJS.Timeout | null = null + start(){ + const {heartInterval} = getConfigUtil().getConfig(); + if (this.intervalId) { + clearInterval(this.intervalId); + } + this.intervalId = setInterval(() => { + // ws的心跳是ws自己维护的 + postOB11Event(new OB11HeartbeatEvent(selfInfo.online, true, heartInterval), false, false) + }, heartInterval) + } + + stop(){ + if (this.intervalId){ + clearInterval(this.intervalId) + } + } +} + +export const httpHeart = new HTTPHeart(); \ No newline at end of file diff --git a/src/onebot11/server/postOB11Event.ts b/src/onebot11/server/postOB11Event.ts index 876ea1d..4c22920 100644 --- a/src/onebot11/server/postOB11Event.ts +++ b/src/onebot11/server/postOB11Event.ts @@ -69,7 +69,7 @@ export function postWsEvent(event: PostEventType) { } } -export function postOB11Event(msg: PostEventType, reportSelf = false) { +export function postOB11Event(msg: PostEventType, reportSelf = false, postWs = true) { const config = getConfigUtil().getConfig(); // 判断msg是否是event if (!config.reportSelfMessage && !reportSelf) { @@ -172,5 +172,7 @@ export function postOB11Event(msg: PostEventType, reportSelf = false) { }); } } - postWsEvent(msg); + if (postWs){ + postWsEvent(msg); + } } \ No newline at end of file diff --git a/src/renderer/index.ts b/src/renderer/index.ts index 28308ad..d370d76 100644 --- a/src/renderer/index.ts +++ b/src/renderer/index.ts @@ -68,6 +68,9 @@ async function onSettingWindowCreated(view: Element) { `
`, 'config-ob11-httpPort', config.ob11.enableHttp ), + SettingItem('启用 HTTP 心跳', null, + SettingSwitch('ob11.enableHttpHeart', config.ob11.enableHttpHeart, {'control-display-id': 'config-ob11-enableHttpHeart'}), + ), SettingItem('启用 HTTP 事件上报', null, SettingSwitch('ob11.enableHttpPost', config.ob11.enableHttpPost, {'control-display-id': 'config-ob11-httpHosts'}), ),