mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2024-11-21 09:36:35 +00:00
674 lines
28 KiB
TypeScript
674 lines
28 KiB
TypeScript
import { napCatCore } from '@/core';
|
||
import { DebugGroupListener, MsgListener, TempOnRecvParams } from '@/core/listeners';
|
||
import { OB11Constructor } from '@/onebot11/constructor';
|
||
import { postOB11Event } from '@/onebot11/server/postOB11Event';
|
||
import {
|
||
BuddyReqType,
|
||
ChatType,
|
||
ElementType,
|
||
FriendRequest,
|
||
Group,
|
||
GroupMember,
|
||
GroupMemberRole,
|
||
GroupNotify,
|
||
GroupNotifyTypes,
|
||
KickedOffLineInfo,
|
||
RawMessage
|
||
} from '@/core/entities';
|
||
import { OB11Config, ob11Config } from '@/onebot11/config';
|
||
import { httpHeart, ob11HTTPServer } from '@/onebot11/server/http';
|
||
import { ob11WebsocketServer } from '@/onebot11/server/ws/WebsocketServer';
|
||
import { ob11ReverseWebsockets } from '@/onebot11/server/ws/ReverseWebsocket';
|
||
import { getGroup, getGroupMember, groupMembers, selfInfo, tempGroupCodeMap } from '@/core/data';
|
||
import { BuddyListener, GroupListener, NodeIKernelBuddyListener } from '@/core/listeners';
|
||
import { OB11FriendRequestEvent } from '@/onebot11/event/request/OB11FriendRequest';
|
||
import { NTQQGroupApi, NTQQUserApi, WebApi } from '@/core/apis';
|
||
import { log, logDebug, logError, setLogSelfInfo } from '@/common/utils/log';
|
||
import { OB11GroupRequestEvent } from '@/onebot11/event/request/OB11GroupRequest';
|
||
import { OB11GroupAdminNoticeEvent } from '@/onebot11/event/notice/OB11GroupAdminNoticeEvent';
|
||
import { GroupDecreaseSubType, OB11GroupDecreaseEvent } from '@/onebot11/event/notice/OB11GroupDecreaseEvent';
|
||
import { OB11FriendRecallNoticeEvent } from '@/onebot11/event/notice/OB11FriendRecallNoticeEvent';
|
||
import { OB11GroupRecallNoticeEvent } from '@/onebot11/event/notice/OB11GroupRecallNoticeEvent';
|
||
import { logMessage, logNotice, logRequest } from '@/onebot11/log';
|
||
import { OB11Message } from '@/onebot11/types';
|
||
import { isEqual } from '@/common/utils/helper';
|
||
import { MessageUnique } from '@/common/utils/MessageUnique';
|
||
import { OB11InputStatusEvent } from './event/notice/OB11InputStatusEvent';
|
||
|
||
//下面几个其实应该移进Core-Data 缓存实现 但是现在在这里方便
|
||
//
|
||
export interface LineDevice {
|
||
app_id: string;
|
||
device_name: string;
|
||
device_kind: string;
|
||
}
|
||
export const DeviceList = new Array<LineDevice>();
|
||
|
||
//peer->cached(boolen)
|
||
// const PokeCache = new Map<string, boolean>();
|
||
|
||
function check_http_ws_equal(conf: any) { // 放在NapCatOnebot11里能被onReady调用却不能被SetConfig调用 不知道为什么 只能放这里了
|
||
return isEqual(conf.http.port, conf.ws.port) && isEqual(conf.http.host, conf.ws.host);
|
||
}
|
||
|
||
export class NapCatOnebot11 {
|
||
private bootTime: number = Date.now() / 1000; // 秒
|
||
|
||
|
||
constructor() {
|
||
// console.log('ob11 init');
|
||
napCatCore.onLoginSuccess(this.onReady.bind(this));
|
||
}
|
||
|
||
public onReady() {
|
||
logDebug('ob11 ready');
|
||
ob11Config.read();
|
||
const serviceInfo = `
|
||
HTTP服务 ${ob11Config.http.enable ? '已启动' : '未启动'}, ${ob11Config.http.host}:${ob11Config.http.port}
|
||
HTTP上报服务 ${ob11Config.http.enablePost ? '已启动' : '未启动'}, 上报地址: ${ob11Config.http.postUrls}
|
||
WebSocket服务 ${ob11Config.ws.enable ? '已启动' : '未启动'}, ${ob11Config.ws.host}:${ob11Config.ws.port}
|
||
WebSocket反向服务 ${ob11Config.reverseWs.enable ? '已启动' : '未启动'}, 反向地址: ${ob11Config.reverseWs.urls}
|
||
`;
|
||
log(serviceInfo);
|
||
NTQQUserApi.getUserDetailInfo(selfInfo.uid).then(user => {
|
||
selfInfo.nick = user.nick;
|
||
setLogSelfInfo(selfInfo);
|
||
}).catch(logError);
|
||
if (ob11Config.http.enable) {
|
||
ob11HTTPServer.start(ob11Config.http.port, ob11Config.http.host);
|
||
}
|
||
if (ob11Config.ws.enable) {
|
||
if (check_http_ws_equal(ob11Config) && ob11HTTPServer.server) { // ob11HTTPServer.server != null 隐含了 ob11Config.http.enable == true 的条件
|
||
ob11WebsocketServer.start(ob11HTTPServer.server);
|
||
} else {
|
||
ob11WebsocketServer.start(ob11Config.ws.port, ob11Config.ws.host);
|
||
}
|
||
}
|
||
if (ob11Config.reverseWs.enable) {
|
||
ob11ReverseWebsockets.start();
|
||
}
|
||
if (ob11Config.http.enableHeart) {
|
||
// 启动http心跳
|
||
httpHeart.start();
|
||
}
|
||
// Create MsgListener
|
||
const msgListener = new MsgListener();
|
||
msgListener.onInputStatusPush = async (data: {
|
||
chatType: number;
|
||
eventType: number;
|
||
fromUin: string;
|
||
interval: string;
|
||
showTime: string;
|
||
statusText: string;
|
||
timestamp: string;
|
||
toUin: string;
|
||
}
|
||
) => {
|
||
let uin = await NTQQUserApi.getUinByUid(data.fromUin);
|
||
logNotice(`[输入状态] ${uin} ${data.statusText}`);
|
||
postOB11Event(new OB11InputStatusEvent(parseInt(uin), data.eventType, data.statusText));
|
||
}
|
||
msgListener.onRecvSysMsg = async (protobufData: number[]) => {
|
||
// function buf2hex(buffer: Buffer) {
|
||
// return [...new Uint8Array(buffer)]
|
||
// .map(x => x.toString(16).padStart(2, '0'))
|
||
// .join('');
|
||
// }
|
||
// const hex = buf2hex(Buffer.from(protobufData));
|
||
// console.log(hex);
|
||
// // let Data: Data = {
|
||
// // header: {
|
||
// // GroupNumber: 0,
|
||
// // GroupString: '',
|
||
// // QQ: 0,
|
||
// // Uid: '',
|
||
// // },
|
||
// // Body: {
|
||
// // MsgType: 0,
|
||
// // SubType_0: 0,
|
||
// // SubType_1: 0,
|
||
// // MsgSeq: 0,
|
||
// // Time: 0,
|
||
// // MsgID: 0,
|
||
// // Other: 0,
|
||
// // }
|
||
// // };
|
||
// try {
|
||
// // 生产环境会自己去掉
|
||
// const hex = buf2hex(Buffer.from(protobufData));
|
||
// //console.log(hex);
|
||
// const sysMsg = SysData.fromBinary(Buffer.from(protobufData));
|
||
// const peeruin = sysMsg.header[0].peerNumber;
|
||
// const peeruid = sysMsg.header[0].peerString;
|
||
// const MsgType = sysMsg.body[0].msgType;
|
||
// const subType0 = sysMsg.body[0].subType0;
|
||
// const subType1 = sysMsg.body[0].subType1;
|
||
// // let pokeEvent: OB11FriendPokeEvent | OB11GroupPokeEvent;
|
||
// // //console.log(peeruid);
|
||
// // if (MsgType == 528 && subType0 == 290 && hex.length < 250 && hex.endsWith('04')) {
|
||
// // // 防止上报两次 私聊戳一戳
|
||
// // if (PokeCache.has(peeruid)) {
|
||
// // //log('[私聊] 用户 ', peeruin, ' 对你戳一戳');
|
||
// // pokeEvent = new OB11FriendPokeEvent(parseInt(selfInfo.uin), peeruin);
|
||
// // postOB11Event(pokeEvent);
|
||
// // }
|
||
// // PokeCache.set(peeruid, false);
|
||
// // setTimeout(() => {
|
||
// // PokeCache.delete(peeruid);
|
||
// // }, 1000);
|
||
// // }
|
||
// // if (MsgType == 732 && subType0 == 20 && hex.length < 150 && hex.endsWith('04')) {
|
||
// // // 防止上报两次 群聊戳一戳
|
||
// // if (PokeCache.has(peeruid)) {
|
||
// // log('[群聊] 群组 ', peeruin, ' 戳一戳');
|
||
// // pokeEvent = new OB11GroupPokeEvent(peeruin);
|
||
// // postOB11Event(pokeEvent);
|
||
// // }
|
||
// // PokeCache.set(peeruid, false);
|
||
// // setTimeout(() => {
|
||
// // PokeCache.delete(peeruid);
|
||
// // }, 1000);
|
||
// // }
|
||
// if (MsgType == 528 && subType0 == 349) {
|
||
// const sysDeviceMsg = DeviceData.fromBinary(Buffer.from(protobufData));
|
||
// DeviceList = [];
|
||
// sysDeviceMsg.event[0].content[0].devices.forEach(device => {
|
||
// DeviceList.push({
|
||
// app_id: '0',
|
||
// device_name: device.deviceName,
|
||
// device_kind: 'none'
|
||
// });
|
||
// // log('[设备列表] 设备名称: ' + device.deviceName);
|
||
// });
|
||
// }
|
||
// // 未区分增加与减少
|
||
// // if (MsgType == 34 && subType0 == 0) {
|
||
// // const role = (await getGroupMember(peeruin, selfInfo.uin))?.role;
|
||
// // const isPrivilege = role === 3 || role === 4;
|
||
// // if (!isPrivilege) {
|
||
// // const leaveUin =
|
||
// // log('[群聊] 群组 ', peeruin, ' 成员' + leaveUin + '退出');
|
||
// // const groupDecreaseEvent = new OB11GroupDecreaseEvent(peeruin, parseInt(leaveUin), 0, 'leave');// 不知道怎么出去的
|
||
// // postOB11Event(groupDecreaseEvent, true);
|
||
// // }
|
||
// // }
|
||
// // MsgType (SubType) EventName
|
||
// // 33 GroupMemIncreased
|
||
// // 34 GroupMemberDecreased
|
||
// // 44 GroupAdminChange
|
||
// // 82 GroupMessage
|
||
// // 84 GroupApply
|
||
// // 87 InviteGroup
|
||
// // 528 35 FriendApply
|
||
// // 528 39 CardChange
|
||
// // 528 68 GroupApply
|
||
// // 528 138 C2CRecall
|
||
// // 528 290 C2CPoke
|
||
// // 528 349 DeviceChange
|
||
// // 732 12 GroupBan
|
||
// // 732 16 GroupUniqueTitleChange
|
||
// // 732 17 GroupRecall
|
||
// // 732 20 GroupCommonTips
|
||
// // 732 21 EssenceMessage
|
||
// // 732 16 16 GrayTips ->Busi->GroupEmjioLike
|
||
// } catch (e) {
|
||
// log('解析SysMsg异常', e);
|
||
// // console.log(e);
|
||
// }
|
||
};
|
||
msgListener.onKickedOffLine = (Info: KickedOffLineInfo) => {
|
||
// 下线通知
|
||
//postOB11Event
|
||
selfInfo.online = false;
|
||
};
|
||
msgListener.onTempChatInfoUpdate = (tempChatInfo: TempOnRecvParams) => {
|
||
if (tempChatInfo.sessionType == 1 && tempChatInfo.chatType == ChatType.temp) {
|
||
tempGroupCodeMap[tempChatInfo.peerUid] = tempChatInfo.groupCode;
|
||
}
|
||
// 临时会话更新 tempGroupCodeMap uid -> source/GroupCode
|
||
};
|
||
msgListener.onRecvMsg = async (msg) => {
|
||
|
||
//console.log('ob11 onRecvMsg', JSON.stringify(msg, null, 2));
|
||
// logDebug('收到消息', msg);
|
||
for (const m of msg) {
|
||
// try: 减掉3s 试图修复消息半天收不到(不减了不减了 会出大问题)
|
||
if (this.bootTime > parseInt(m.msgTime)) {
|
||
logDebug(`消息时间${m.msgTime}早于启动时间${this.bootTime},忽略上报`);
|
||
continue;
|
||
}
|
||
// 调用应该必须带 chatInfo 不然不行 想不通想不通
|
||
// let ret = await napCatCore.session.getMsgService().queryMsgsWithFilterEx(m.msgId, '0', '0', {
|
||
// chatInfo: {
|
||
// peerUid: '',
|
||
// chatType: 0,
|
||
// },
|
||
// filterMsgType: [],
|
||
// filterSendersUid: [],
|
||
// filterMsgToTime: '0',
|
||
// filterMsgFromTime: '0',
|
||
// isReverseOrder: false,
|
||
// isIncludeCurrent: true,
|
||
// pageLimit: 2,
|
||
// });
|
||
// console.log(ret);
|
||
new Promise((resolve) => {
|
||
m.id = MessageUnique.createMsg({ chatType: m.chatType, peerUid: m.peerUid, guildId: '' }, m.msgId);
|
||
this.postReceiveMsg([m]).then().catch(logError);
|
||
}).then();
|
||
}
|
||
};
|
||
msgListener.onMsgInfoListUpdate = (msgList) => {
|
||
this.postRecallMsg(msgList).then().catch(logError);
|
||
for (const msg of msgList.filter(e => e.senderUin == selfInfo.uin)) {
|
||
// console.log(msg);
|
||
if (msg.sendStatus == 2) {
|
||
//完成后再post
|
||
OB11Constructor.message(msg).then((_msg) => {
|
||
_msg.target_id = parseInt(msg.peerUin);
|
||
if (ob11Config.reportSelfMessage) {
|
||
msg.id = MessageUnique.createMsg({ chatType: msg.chatType, peerUid: msg.peerUid, guildId: '' }, msg.msgId);
|
||
this.postReceiveMsg([msg]).then().catch(logError);
|
||
} else {
|
||
logMessage(_msg as OB11Message).then().catch(logError);
|
||
}
|
||
}).catch(logError);
|
||
}
|
||
|
||
}
|
||
};
|
||
msgListener.onAddSendMsg = (msg) => {
|
||
|
||
};
|
||
napCatCore.addListener(msgListener);
|
||
logDebug('ob11 msg listener added');
|
||
|
||
// BuddyListener
|
||
const buddyListener = new BuddyListener();
|
||
buddyListener.onBuddyReqChange = ((req) => {
|
||
//从这里获取?好友请求
|
||
this.postFriendRequest(req.buddyReqs).then().catch(logError);
|
||
});
|
||
napCatCore.addListener(buddyListener);
|
||
logDebug('ob11 buddy listener added');
|
||
|
||
// GroupListener
|
||
const groupListener = new GroupListener();
|
||
// groupListener.onMemberListChange = async (arg: {
|
||
// sceneId: string,
|
||
// ids: string[],
|
||
// infos: Map<string, GroupMember>, // uid -> GroupMember
|
||
// finish: boolean,
|
||
// hasRobot: boolean
|
||
// }) => {
|
||
|
||
// }
|
||
groupListener.onGroupNotifiesUpdated = async (doubt, notifies) => {
|
||
//console.log('ob11 onGroupNotifiesUpdated', notifies[0]);
|
||
if (![GroupNotifyTypes.ADMIN_SET, GroupNotifyTypes.ADMIN_UNSET, GroupNotifyTypes.ADMIN_UNSET_OTHER].includes(notifies[0].type)) {
|
||
this.postGroupNotifies(notifies).then().catch(e => logError('postGroupNotifies error: ', e));
|
||
}
|
||
};
|
||
groupListener.onMemberInfoChange = async (groupCode: string, changeType: number, members: Map<string, GroupMember>) => {
|
||
// console.log("ob11 onMemberInfoChange", groupCode, changeType, members)
|
||
if (changeType === 1) {
|
||
let member;
|
||
for (const [key, value] of members) {
|
||
member = value;
|
||
break;
|
||
}
|
||
if (member) {
|
||
const existMembers = groupMembers.get(groupCode);
|
||
if (existMembers) {
|
||
const existMember = existMembers.get(member.uid);
|
||
if (existMember) {
|
||
if (existMember.isChangeRole) {
|
||
//console.log("ob11 onMemberInfoChange:eventMember:localMember", member, existMember)
|
||
const notify: GroupNotify[] = [
|
||
{
|
||
time: Date.now(),
|
||
seq: (Date.now() * 1000 * 1000).toString(),
|
||
type: member.role === GroupMemberRole.admin ? GroupNotifyTypes.ADMIN_SET : GroupNotifyTypes.ADMIN_UNSET_OTHER, // 8 设置; 13 取消
|
||
status: 0,
|
||
group: { groupCode: groupCode, groupName: '' },
|
||
user1: { uid: member.uid, nickName: member.nick },
|
||
user2: { uid: member.uid, nickName: member.nick },
|
||
actionUser: { uid: '', nickName: '' },
|
||
actionTime: '0',
|
||
invitationExt: { srcType: 0, groupCode: '0', waitStatus: 0 },
|
||
postscript: '',
|
||
repeatSeqs: [],
|
||
warningTips: ''
|
||
}
|
||
];
|
||
this.postGroupNotifies(notify).then().catch(e => logError('postGroupNotifies error: ', e));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// 如果自身是非管理员也许要从这里获取Delete 成员变动 待测试与验证
|
||
const role = (await getGroupMember(groupCode, selfInfo.uin))?.role;
|
||
const isPrivilege = role === 3 || role === 4;
|
||
for (const member of members.values()) {
|
||
//console.log(member?.isDelete, role, isPrivilege);
|
||
// Develop Mlikiowa Taged: 暂时屏蔽这个方案 考虑onMemberListChange
|
||
// if (member?.isDelete && !isPrivilege && selfInfo.uin !== member.uin) {
|
||
// log('[群聊] 群组 ', groupCode, ' 成员' + member.uin + '退出');
|
||
// const groupDecreaseEvent = new OB11GroupDecreaseEvent(parseInt(groupCode), parseInt(member.uin), 0, 'leave');// 不知道怎么出去的
|
||
// postOB11Event(groupDecreaseEvent, true);
|
||
// }
|
||
}
|
||
};
|
||
groupListener.onJoinGroupNotify = (...notify) => {
|
||
// console.log('ob11 onJoinGroupNotify', notify);
|
||
};
|
||
groupListener.onGroupListUpdate = (updateType, groupList) => {
|
||
// console.log('ob11 onGroupListUpdate', updateType, groupList);
|
||
// this.postGroupMemberChange(groupList).then();
|
||
};
|
||
|
||
napCatCore.addListener(groupListener);
|
||
logDebug('ob11 group listener added');
|
||
}
|
||
|
||
async postReceiveMsg(msgList: RawMessage[]) {
|
||
const { debug, reportSelfMessage } = ob11Config;
|
||
for (const message of msgList) {
|
||
logDebug('收到新消息', message);
|
||
OB11Constructor.message(message).then((msg) => {
|
||
logDebug('收到消息: ', msg);
|
||
if (debug) {
|
||
msg.raw = message;
|
||
} else {
|
||
if (msg.message.length === 0) {
|
||
return;
|
||
}
|
||
}
|
||
if (msg.post_type === 'message') {
|
||
logMessage(msg as OB11Message).then().catch(logError);
|
||
} else if (msg.post_type === 'notice') {
|
||
logNotice(msg).then().catch(logError);
|
||
} else if (msg.post_type === 'request') {
|
||
logRequest(msg).then().catch(logError);
|
||
}
|
||
const isSelfMsg = msg.user_id.toString() == selfInfo.uin;
|
||
if (isSelfMsg && !reportSelfMessage) {
|
||
return;
|
||
}
|
||
if (isSelfMsg) {
|
||
msg.target_id = parseInt(message.peerUin);
|
||
}
|
||
postOB11Event(msg);
|
||
// log("post msg", msg)
|
||
}).catch(e => logError('constructMessage error: ', e));
|
||
OB11Constructor.GroupEvent(message).then(groupEvent => {
|
||
if (groupEvent) {
|
||
// log("post group event", groupEvent);
|
||
postOB11Event(groupEvent);
|
||
}
|
||
}).catch(e => logError('constructGroupEvent error: ', e));
|
||
|
||
OB11Constructor.PrivateEvent(message).then(privateEvent => {
|
||
if (privateEvent) {
|
||
// log("post private event", privateEvent);
|
||
postOB11Event(privateEvent);
|
||
}
|
||
});
|
||
|
||
}
|
||
}
|
||
async SetConfig(NewOb11: OB11Config) {
|
||
try {
|
||
// if (!NewOb11 || typeof NewOb11 !== 'object') {
|
||
// throw new Error('Invalid configuration object');
|
||
// }
|
||
const OldConfig = JSON.parse(JSON.stringify(ob11Config)); //进行深拷贝
|
||
ob11Config.save(NewOb11, true);//保存新配置
|
||
|
||
const isHttpChanged = !isEqual(NewOb11.http.enable, OldConfig.http.enable) ||
|
||
!isEqual(NewOb11.http.host, OldConfig.http.host) ||
|
||
!isEqual(NewOb11.http.port, OldConfig.http.port);
|
||
|
||
// const isHttpPostChanged = !isEqual(NewOb11.http.postUrls, OldConfig.http.postUrls);
|
||
// const isEnanleHttpPostChanged = !isEqual(NewOb11.http.enablePost, OldConfig.http.enablePost);
|
||
|
||
const isWsChanged = !isEqual(NewOb11.ws.enable, OldConfig.ws.enable) ||
|
||
!isEqual(NewOb11.ws.host, OldConfig.ws.host) ||
|
||
!isEqual(NewOb11.ws.port, OldConfig.ws.port);
|
||
|
||
const isWsReverseChanged = !isEqual(NewOb11.reverseWs.enable, OldConfig.reverseWs.enable) ||
|
||
!isEqual(NewOb11.reverseWs.urls, OldConfig.reverseWs.urls);
|
||
|
||
//const isEnableHeartBeatChanged = !isEqual(NewOb11.heartInterval, OldConfig.heartInterval);
|
||
|
||
if (check_http_ws_equal(NewOb11) || check_http_ws_equal(OldConfig)) {
|
||
// http与ws共站 需要同步重启
|
||
if (isHttpChanged || isWsChanged) {
|
||
log('http与ws进行热重载');
|
||
ob11WebsocketServer.stop();
|
||
ob11HTTPServer.stop();
|
||
if (NewOb11.http.enable) {
|
||
ob11HTTPServer.start(NewOb11.http.port, NewOb11.http.host);
|
||
}
|
||
if (NewOb11.ws.enable) {
|
||
if (check_http_ws_equal(NewOb11) && ob11HTTPServer.server) {
|
||
ob11WebsocketServer.start(ob11HTTPServer.server);
|
||
} else {
|
||
ob11WebsocketServer.start(NewOb11.ws.port, NewOb11.ws.host);
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
// http重启逻辑
|
||
if (isHttpChanged) {
|
||
log('http进行热重载');
|
||
ob11HTTPServer.stop();
|
||
if (NewOb11.http.enable) {
|
||
ob11HTTPServer.start(NewOb11.http.port, NewOb11.http.host);
|
||
}
|
||
}
|
||
|
||
// ws重启逻辑
|
||
if (isWsChanged) {
|
||
log('ws进行热重载');
|
||
ob11WebsocketServer.stop();
|
||
if (NewOb11.ws.enable) {
|
||
ob11WebsocketServer.start(NewOb11.ws.port, NewOb11.ws.host);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 反向ws重启逻辑
|
||
if (isWsReverseChanged) {
|
||
log('反向ws进行热重载');
|
||
ob11ReverseWebsockets.stop();
|
||
if (NewOb11.reverseWs.enable) {
|
||
ob11ReverseWebsockets.start();
|
||
}
|
||
}
|
||
|
||
} catch (e) {
|
||
logError('热重载配置失败', e);
|
||
}
|
||
|
||
}
|
||
async postGroupNotifies(notifies: GroupNotify[]) {
|
||
for (const notify of notifies) {
|
||
try {
|
||
notify.time = Date.now();
|
||
const notifyTime = parseInt(notify.seq) / 1000 / 1000;
|
||
// log(`群通知时间${notifyTime}`, `启动时间${this.bootTime}`);
|
||
if (notifyTime < this.bootTime) {
|
||
continue;
|
||
}
|
||
const flag = notify.group.groupCode + '|' + notify.seq + '|' + notify.type;
|
||
logDebug('收到群通知', notify);
|
||
// let member2: GroupMember;
|
||
// if (notify.user2.uid) {
|
||
// member2 = await getGroupMember(notify.group.groupCode, null, notify.user2.uid);
|
||
// }
|
||
|
||
if ([GroupNotifyTypes.ADMIN_SET, GroupNotifyTypes.ADMIN_UNSET, GroupNotifyTypes.ADMIN_UNSET_OTHER].includes(notify.type)) {
|
||
const member1 = await getGroupMember(notify.group.groupCode, notify.user1.uid);
|
||
logDebug('有管理员变动通知');
|
||
// refreshGroupMembers(notify.group.groupCode).then();
|
||
const groupAdminNoticeEvent = new OB11GroupAdminNoticeEvent();
|
||
groupAdminNoticeEvent.group_id = parseInt(notify.group.groupCode);
|
||
logDebug('开始获取变动的管理员');
|
||
if (member1) {
|
||
logDebug('变动管理员获取成功');
|
||
groupAdminNoticeEvent.user_id = parseInt(member1.uin);
|
||
groupAdminNoticeEvent.sub_type = [GroupNotifyTypes.ADMIN_UNSET, GroupNotifyTypes.ADMIN_UNSET_OTHER].includes(notify.type) ? 'unset' : 'set';
|
||
// member1.role = notify.type == GroupNotifyTypes.ADMIN_SET ? GroupMemberRole.admin : GroupMemberRole.normal;
|
||
postOB11Event(groupAdminNoticeEvent, true);
|
||
} else {
|
||
logDebug('获取群通知的成员信息失败', notify, getGroup(notify.group.groupCode));
|
||
}
|
||
} else if (notify.type == GroupNotifyTypes.MEMBER_EXIT || notify.type == GroupNotifyTypes.KICK_MEMBER) {
|
||
logDebug('有成员退出通知', notify);
|
||
try {
|
||
const member1Uin = (await NTQQUserApi.getUinByUid(notify.user1.uid))!;
|
||
let operatorId = member1Uin;
|
||
let subType: GroupDecreaseSubType = 'leave';
|
||
if (notify.user2.uid) {
|
||
// 是被踢的
|
||
const member2Uin = await NTQQUserApi.getUinByUid(notify.user2.uid);
|
||
if (member2Uin) {
|
||
operatorId = member2Uin;
|
||
}
|
||
subType = 'kick';
|
||
}
|
||
const groupDecreaseEvent = new OB11GroupDecreaseEvent(parseInt(notify.group.groupCode), parseInt(member1Uin), parseInt(operatorId), subType);
|
||
postOB11Event(groupDecreaseEvent, true);
|
||
} catch (e: any) {
|
||
logError('获取群通知的成员信息失败', notify, e.stack.toString());
|
||
}
|
||
//notify.status == 1 表示未处理 2表示处理完成
|
||
} else if ([GroupNotifyTypes.JOIN_REQUEST].includes(notify.type) && notify.status == 1) {
|
||
logDebug('有加群请求');
|
||
const groupRequestEvent = new OB11GroupRequestEvent();
|
||
groupRequestEvent.group_id = parseInt(notify.group.groupCode);
|
||
let requestQQ = '';
|
||
try {
|
||
// uid-->uin
|
||
requestQQ = (await NTQQUserApi.getUinByUid(notify.user1.uid))!;
|
||
if (isNaN(parseInt(requestQQ))) {
|
||
requestQQ = (await NTQQUserApi.getUserDetailInfo(notify.user1.uid)).uin;
|
||
}
|
||
} catch (e) {
|
||
logError('获取加群人QQ号失败 Uid:', notify.user1.uid, e);
|
||
}
|
||
groupRequestEvent.user_id = parseInt(requestQQ) || 0;
|
||
groupRequestEvent.sub_type = 'add';
|
||
groupRequestEvent.comment = notify.postscript;
|
||
groupRequestEvent.flag = flag;
|
||
postOB11Event(groupRequestEvent);
|
||
} else if (notify.type == GroupNotifyTypes.INVITE_ME) {
|
||
logDebug(`收到邀请我加群通知:${notify}`);
|
||
const groupInviteEvent = new OB11GroupRequestEvent();
|
||
groupInviteEvent.group_id = parseInt(notify.group.groupCode);
|
||
const user_id = (await NTQQUserApi.getUinByUid(notify.user2.uid)) || '';
|
||
groupInviteEvent.user_id = parseInt(user_id);
|
||
groupInviteEvent.sub_type = 'invite';
|
||
groupInviteEvent.flag = flag;
|
||
postOB11Event(groupInviteEvent);
|
||
}
|
||
} catch (e: any) {
|
||
logDebug('解析群通知失败', e.stack.toString());
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
async postRecallMsg(msgList: RawMessage[]) {
|
||
for (const message of msgList) {
|
||
// log("message update", message.sendStatus, message.msgId, message.msgSeq)
|
||
if (message.recallTime != '0') { //todo: 这个判断方法不太好,应该使用灰色消息元素来判断?
|
||
// 撤回消息上报
|
||
const oriMessageId = await MessageUnique.getShortIdByMsgId(message.msgId);
|
||
if (!oriMessageId) {
|
||
continue;
|
||
}
|
||
if (message.chatType == ChatType.friend) {
|
||
const friendRecallEvent = new OB11FriendRecallNoticeEvent(parseInt(message!.senderUin), oriMessageId);
|
||
postOB11Event(friendRecallEvent);
|
||
} else if (message.chatType == ChatType.group) {
|
||
let operatorId = message.senderUin;
|
||
for (const element of message.elements) {
|
||
const operatorUid = element.grayTipElement?.revokeElement.operatorUid;
|
||
const operator = await getGroupMember(message.peerUin, operatorUid);
|
||
operatorId = operator?.uin || message.senderUin;
|
||
}
|
||
const groupRecallEvent = new OB11GroupRecallNoticeEvent(
|
||
parseInt(message.peerUin),
|
||
parseInt(message.senderUin),
|
||
parseInt(operatorId),
|
||
oriMessageId
|
||
);
|
||
postOB11Event(groupRecallEvent);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
async postFriendRequest(reqs: FriendRequest[]) {
|
||
for (const req of reqs) {
|
||
if (!!req.isInitiator || (req.isDecide && req.reqType !== BuddyReqType.KMEINITIATORWAITPEERCONFIRM)) {
|
||
continue;
|
||
}
|
||
const friendRequestEvent = new OB11FriendRequestEvent();
|
||
try {
|
||
const requesterUin = await NTQQUserApi.getUinByUid(req.friendUid);
|
||
friendRequestEvent.user_id = parseInt(requesterUin!);
|
||
} catch (e) {
|
||
logDebug('获取加好友者QQ号失败', e);
|
||
}
|
||
friendRequestEvent.flag = req.friendUid + '|' + req.reqTime;
|
||
friendRequestEvent.comment = req.extWords;
|
||
postOB11Event(friendRequestEvent);
|
||
}
|
||
}
|
||
|
||
// async postGroupMemberChange(groupList: Group[]) {
|
||
// // todo: 有无更好的方法判断群成员变动
|
||
// const newGroupList = groupList;
|
||
// for (const group of newGroupList) {
|
||
// const existGroup = await getGroup(group.groupCode);
|
||
// if (existGroup) {
|
||
// if (existGroup.memberCount > group.memberCount) {
|
||
// log(`群(${group.groupCode})成员数量减少${existGroup.memberCount} -> ${group.memberCount}`);
|
||
// const oldMembers = existGroup.members;
|
||
// const newMembers = await NTQQGroupApi.getGroupMembers(group.groupCode);
|
||
// group.members = newMembers;
|
||
// const newMembersSet = new Set<string>(); // 建立索引降低时间复杂度
|
||
//
|
||
// for (const member of newMembers) {
|
||
// newMembersSet.add(member.uin);
|
||
// }
|
||
//
|
||
// // 判断bot是否是管理员,如果是管理员不需要从这里得知有人退群,这里的退群无法得知是主动退群还是被踢
|
||
// const bot = await getGroupMember(group.groupCode, selfInfo.uin);
|
||
// if (bot!.role == GroupMemberRole.admin || bot!.role == GroupMemberRole.owner) {
|
||
// continue;
|
||
// }
|
||
// for (const member of oldMembers) {
|
||
// if (!newMembersSet.has(member.uin) && member.uin != selfInfo.uin) {
|
||
// postOB11Event(new OB11GroupDecreaseEvent(parseInt(group.groupCode), parseInt(member.uin), parseInt(member.uin), 'leave'));
|
||
// break;
|
||
// }
|
||
// }
|
||
// }
|
||
// }
|
||
// }
|
||
// }
|
||
}
|
||
|
||
// export const napCatOneBot11 = new NapCatOnebot11();
|
||
// setTimeout(async () => {
|
||
// let ret = await MiniAppUtil.RunMiniAppWithGUI();
|
||
// console.log(ret);
|
||
// }, 20000);
|
||
// setTimeout(async () => {
|
||
// await SignMusicWrapper('429450678');
|
||
// }, 15000)
|