chore: improve code quality

chore: improve code quality

chore: improve code quality
This commit is contained in:
idranme 2024-09-05 19:11:15 +08:00
parent eae6e09e22
commit e185e700b7
No known key found for this signature in database
GPG Key ID: 926F7B5B668E495F
9 changed files with 202 additions and 354 deletions

View File

@ -53,15 +53,15 @@ function onLoad() {
fs.mkdirSync(LOG_DIR) fs.mkdirSync(LOG_DIR)
} }
ipcMain.handle(CHANNEL_CHECK_VERSION, async (event, arg) => { ipcMain.handle(CHANNEL_CHECK_VERSION, async () => {
return checkNewVersion() return checkNewVersion()
}) })
ipcMain.handle(CHANNEL_UPDATE, async (event, arg) => { ipcMain.handle(CHANNEL_UPDATE, async () => {
return upgradeLLOneBot() return upgradeLLOneBot()
}) })
ipcMain.handle(CHANNEL_SELECT_FILE, async (event, arg) => { ipcMain.handle(CHANNEL_SELECT_FILE, async () => {
const selectPath = new Promise<string>((resolve, reject) => { const selectPath = new Promise<string>((resolve, reject) => {
dialog dialog
.showOpenDialog({ .showOpenDialog({
@ -90,10 +90,10 @@ function onLoad() {
} }
}) })
ipcMain.handle(CHANNEL_ERROR, async (event, arg) => { ipcMain.handle(CHANNEL_ERROR, async () => {
const ffmpegOk = await checkFfmpeg(getConfigUtil().getConfig().ffmpeg) const ffmpegOk = await checkFfmpeg(getConfigUtil().getConfig().ffmpeg)
llonebotError.ffmpegError = ffmpegOk ? '' : '没有找到 FFmpeg, 音频只能发送 WAV 和 SILK, 视频尺寸可能异常' llonebotError.ffmpegError = ffmpegOk ? '' : '没有找到 FFmpeg, 音频只能发送 WAV 和 SILK, 视频尺寸可能异常'
let { httpServerError, wsServerError, otherError, ffmpegError } = llonebotError const { httpServerError, wsServerError, otherError, ffmpegError } = llonebotError
let error = `${otherError}\n${httpServerError}\n${wsServerError}\n${ffmpegError}` let error = `${otherError}\n${httpServerError}\n${wsServerError}\n${ffmpegError}`
error = error.replace('\n\n', '\n') error = error.replace('\n\n', '\n')
error = error.trim() error = error.trim()
@ -101,12 +101,12 @@ function onLoad() {
return error return error
}) })
ipcMain.handle(CHANNEL_GET_CONFIG, async (event, arg) => { ipcMain.handle(CHANNEL_GET_CONFIG, async () => {
const config = getConfigUtil().getConfig() const config = getConfigUtil().getConfig()
return config return config
}) })
ipcMain.handle(CHANNEL_SET_CONFIG, (event, ask: boolean, config: LLOBConfig) => { ipcMain.handle(CHANNEL_SET_CONFIG, (_event, ask: boolean, config: LLOBConfig) => {
return new Promise<boolean>(resolve => { return new Promise<boolean>(resolve => {
if (!ask) { if (!ask) {
getConfigUtil().setConfig(config) getConfigUtil().setConfig(config)
@ -139,7 +139,7 @@ function onLoad() {
}) })
}) })
ipcMain.on(CHANNEL_LOG, (event, arg) => { ipcMain.on(CHANNEL_LOG, (_event, arg) => {
log(arg) log(arg)
}) })
@ -212,15 +212,15 @@ function onBrowserWindowCreated(window: BrowserWindow) {
try { try {
hookNTQQApiCall(window, window.id !== 2) hookNTQQApiCall(window, window.id !== 2)
hookNTQQApiReceive(window, window.id !== 2) hookNTQQApiReceive(window, window.id !== 2)
} catch (e: any) { } catch (e) {
log('LLOneBot hook error: ', e.toString()) log('LLOneBot hook error: ', String(e))
} }
} }
try { try {
onLoad() onLoad()
} catch (e: any) { } catch (e) {
console.log(e.toString()) console.log(e)
} }
// 这两个函数都是可选的 // 这两个函数都是可选的

View File

@ -26,34 +26,19 @@ export class NTQQGroupApi extends Service {
} }
async getGroups(forced = false): Promise<Group[]> { async getGroups(forced = false): Promise<Group[]> {
if (NTEventDispatch.initialised) { const result = await invoke<{
type ListenerType = NodeIKernelGroupListener['onGroupListUpdate'] updateType: number
const [, , groupList] = await NTEventDispatch.CallNormalEvent groupList: Group[]
<(force: boolean) => Promise<any>, ListenerType> }>(
( 'getGroupList',
'NodeIKernelGroupService/getGroupList', [],
'NodeIKernelGroupListener/onGroupListUpdate', {
1, className: NTClass.NODE_STORE_API,
5000, cbCmd: ReceiveCmdS.GROUPS_STORE,
() => true, afterFirstCmd: false,
forced }
) )
return groupList return result.groupList
} else {
const result = await invoke<{
updateType: number
groupList: Group[]
}>(
'getGroupList',
[],
{
className: NTClass.NODE_STORE_API,
cbCmd: ReceiveCmdS.GROUPS_STORE,
afterFirstCmd: false,
}
)
return result.groupList
}
} }
async getGroupMembers(groupCode: string, num = 3000): Promise<Map<string, GroupMember>> { async getGroupMembers(groupCode: string, num = 3000): Promise<Map<string, GroupMember>> {
@ -114,32 +99,16 @@ export class NTQQGroupApi extends Service {
} }
async getSingleScreenNotifies(num: number) { async getSingleScreenNotifies(num: number) {
if (NTEventDispatch.initialised) { invoke(ReceiveCmdS.GROUP_NOTIFY, [], { classNameIsRegister: true })
const [_retData, _doubt, _seq, notifies] = await NTEventDispatch.CallNormalEvent return (await invoke<GroupNotifies>(
<(arg1: boolean, arg2: string, arg3: number) => Promise<any>, (doubt: boolean, seq: string, notifies: GroupNotify[]) => void> 'nodeIKernelGroupService/getSingleScreenNotifies',
( [{ doubt: false, startSeq: '', number: num }, null],
'NodeIKernelGroupService/getSingleScreenNotifies', {
'NodeIKernelGroupListener/onGroupSingleScreenNotifies',
1,
5000,
() => true,
false,
'',
num,
)
return notifies
} else {
invoke(ReceiveCmdS.GROUP_NOTIFY, [], { classNameIsRegister: true })
return (await invoke<GroupNotifies>(
'nodeIKernelGroupService/getSingleScreenNotifies',
[{ doubt: false, startSeq: '', number: num }, null],
{
cbCmd: ReceiveCmdS.GROUP_NOTIFY, cbCmd: ReceiveCmdS.GROUP_NOTIFY,
afterFirstCmd: false, afterFirstCmd: false,
} }
)).notifies )).notifies
}
} }
async handleGroupRequest(flag: string, operateType: GroupRequestOperateTypes, reason?: string) { async handleGroupRequest(flag: string, operateType: GroupRequestOperateTypes, reason?: string) {
@ -260,30 +229,30 @@ export class NTQQGroupApi extends Service {
} }
/** 27187 TODO */ /** 27187 TODO */
async removeGroupEssence(GroupCode: string, msgId: string) { async removeGroupEssence(groupCode: string, msgId: string) {
const session = getSession() const session = getSession()
// 代码没测过 // 代码没测过
// 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom // 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom
let MsgData = await session?.getMsgService().getMsgsIncludeSelf({ chatType: 2, guildId: '', peerUid: GroupCode }, msgId, 1, false) const data = await session?.getMsgService().getMsgsIncludeSelf({ chatType: 2, guildId: '', peerUid: groupCode }, msgId, 1, false)
let param = { const param = {
groupCode: GroupCode, groupCode: groupCode,
msgRandom: parseInt(MsgData?.msgList[0].msgRandom!), msgRandom: Number(data?.msgList[0].msgRandom),
msgSeq: parseInt(MsgData?.msgList[0].msgSeq!) msgSeq: Number(data?.msgList[0].msgSeq)
} }
// GetMsgByShoretID(ShoretID) -> MsgService.getMsgs(Peer,MsgId,1,false) -> 组出参数 // GetMsgByShoretID(ShoretID) -> MsgService.getMsgs(Peer,MsgId,1,false) -> 组出参数
return session?.getGroupService().removeGroupEssence(param) return session?.getGroupService().removeGroupEssence(param)
} }
/** 27187 TODO */ /** 27187 TODO */
async addGroupEssence(GroupCode: string, msgId: string) { async addGroupEssence(groupCode: string, msgId: string) {
const session = getSession() const session = getSession()
// 代码没测过 // 代码没测过
// 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom // 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom
let MsgData = await session?.getMsgService().getMsgsIncludeSelf({ chatType: 2, guildId: '', peerUid: GroupCode }, msgId, 1, false) const data = await session?.getMsgService().getMsgsIncludeSelf({ chatType: 2, guildId: '', peerUid: groupCode }, msgId, 1, false)
let param = { const param = {
groupCode: GroupCode, groupCode: groupCode,
msgRandom: parseInt(MsgData?.msgList[0].msgRandom!), msgRandom: Number(data?.msgList[0].msgRandom),
msgSeq: parseInt(MsgData?.msgList[0].msgSeq!) msgSeq: Number(data?.msgList[0].msgSeq)
} }
// GetMsgByShoretID(ShoretID) -> MsgService.getMsgs(Peer,MsgId,1,false) -> 组出参数 // GetMsgByShoretID(ShoretID) -> MsgService.getMsgs(Peer,MsgId,1,false) -> 组出参数
return session?.getGroupService().addGroupEssence(param) return session?.getGroupService().addGroupEssence(param)

View File

@ -102,62 +102,35 @@ export class NTQQMsgApi extends Service {
} }
} }
async sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) { async sendMsg(peer: Peer, msgElements: SendMessageElement[], timeout = 10000) {
const msgId = generateMsgId() const msgId = generateMsgId()
peer.guildId = msgId peer.guildId = msgId
let msgList: RawMessage[] const data = await invoke<{ msgList: RawMessage[] }>(
if (NTEventDispatch.initialised) { 'nodeIKernelMsgService/sendMsg',
const data = await NTEventDispatch.CallNormalEvent< [
(msgId: string, peer: Peer, msgElements: SendMessageElement[], map: Map<any, any>) => Promise<unknown>, {
(msgList: RawMessage[]) => void msgId: '0',
>( peer,
'NodeIKernelMsgService/sendMsg', msgElements,
'NodeIKernelMsgListener/onMsgInfoListUpdate', msgAttributeInfos: new Map()
1, },
timeout, null
(msgRecords: RawMessage[]) => { ],
for (const msgRecord of msgRecords) { {
cbCmd: 'nodeIKernelMsgListener/onMsgInfoListUpdate',
afterFirstCmd: false,
cmdCB: payload => {
for (const msgRecord of payload.msgList) {
if (msgRecord.guildId === msgId && msgRecord.sendStatus === 2) { if (msgRecord.guildId === msgId && msgRecord.sendStatus === 2) {
return true return true
} }
} }
return false return false
}, },
'0', timeout
peer, }
msgElements, )
new Map() return data.msgList.find(msgRecord => msgRecord.guildId === msgId)
)
msgList = data[1]
} else {
const data = await invoke<{ msgList: RawMessage[] }>(
'nodeIKernelMsgService/sendMsg',
[
{
msgId: '0',
peer,
msgElements,
msgAttributeInfos: new Map()
},
null
],
{
cbCmd: 'nodeIKernelMsgListener/onMsgInfoListUpdate',
afterFirstCmd: false,
cmdCB: payload => {
for (const msgRecord of payload.msgList) {
if (msgRecord.guildId === msgId && msgRecord.sendStatus === 2) {
return true
}
}
return false
},
timeout
}
)
msgList = data.msgList
}
return msgList.find(msgRecord => msgRecord.guildId === msgId)
} }
async forwardMsg(srcPeer: Peer, destPeer: Peer, msgIds: string[]) { async forwardMsg(srcPeer: Peer, destPeer: Peer, msgIds: string[]) {
@ -181,65 +154,37 @@ export class NTQQMsgApi extends Service {
return { msgId: id, senderShowName } return { msgId: id, senderShowName }
}) })
const selfUid = selfInfo.uid const selfUid = selfInfo.uid
let msgList: RawMessage[] const data = await invoke<{ msgList: RawMessage[] }>(
if (NTEventDispatch.initialised) { 'nodeIKernelMsgService/multiForwardMsgWithComment',
const data = await NTEventDispatch.CallNormalEvent< [
(msgInfo: typeof msgInfos, srcPeer: Peer, destPeer: Peer, comment: Array<any>, attr: Map<any, any>,) => Promise<unknown>, {
(msgList: RawMessage[]) => void msgInfos,
>( srcContact: srcPeer,
'NodeIKernelMsgService/multiForwardMsgWithComment', dstContact: destPeer,
'NodeIKernelMsgListener/onMsgInfoListUpdate', commentElements: [],
1, msgAttributeInfos: new Map(),
5000, },
(msgRecords: RawMessage[]) => { null,
for (let msgRecord of msgRecords) { ],
{
cbCmd: 'nodeIKernelMsgListener/onMsgInfoListUpdate',
afterFirstCmd: false,
cmdCB: payload => {
for (const msgRecord of payload.msgList) {
if (msgRecord.peerUid == destPeer.peerUid && msgRecord.senderUid == selfUid) { if (msgRecord.peerUid == destPeer.peerUid && msgRecord.senderUid == selfUid) {
return true return true
} }
} }
return false return false
}, },
msgInfos, }
srcPeer, )
destPeer, for (const msg of data.msgList) {
[],
new Map()
)
msgList = data[1]
} else {
const data = await invoke<{ msgList: RawMessage[] }>(
'nodeIKernelMsgService/multiForwardMsgWithComment',
[
{
msgInfos,
srcContact: srcPeer,
dstContact: destPeer,
commentElements: [],
msgAttributeInfos: new Map(),
},
null,
],
{
cbCmd: 'nodeIKernelMsgListener/onMsgInfoListUpdate',
afterFirstCmd: false,
cmdCB: payload => {
for (const msgRecord of payload.msgList) {
if (msgRecord.peerUid == destPeer.peerUid && msgRecord.senderUid == selfUid) {
return true
}
}
return false
},
}
)
msgList = data.msgList
}
for (const msg of msgList) {
const arkElement = msg.elements.find(ele => ele.arkElement) const arkElement = msg.elements.find(ele => ele.arkElement)
if (!arkElement) { if (!arkElement) {
continue continue
} }
const forwardData: any = JSON.parse(arkElement.arkElement.bytesData) const forwardData = JSON.parse(arkElement.arkElement.bytesData)
if (forwardData.app != 'com.tencent.multimsg') { if (forwardData.app != 'com.tencent.multimsg') {
continue continue
} }

View File

@ -37,44 +37,24 @@ export class NTQQUserApi extends Service {
} }
async fetchUserDetailInfo(uid: string) { async fetchUserDetailInfo(uid: string) {
let info: UserDetailInfoListenerArg const result = await invoke<{ info: UserDetailInfoListenerArg }>(
if (NTEventDispatch.initialised) { 'nodeIKernelProfileService/fetchUserDetailInfo',
type EventService = NodeIKernelProfileService['fetchUserDetailInfo'] [
type EventListener = NodeIKernelProfileListener['onUserDetailInfoChanged']
const [_retData, profile] = await NTEventDispatch.CallNormalEvent
<EventService, EventListener>
(
'NodeIKernelProfileService/fetchUserDetailInfo',
'NodeIKernelProfileListener/onUserDetailInfoChanged',
1,
5000,
(profile) => profile.uid === uid,
'BuddyProfileStore',
[uid],
UserDetailSource.KSERVER,
[ProfileBizType.KALL]
)
info = profile
} else {
const result = await invoke<{ info: UserDetailInfoListenerArg }>(
'nodeIKernelProfileService/fetchUserDetailInfo',
[
{
callFrom: 'BuddyProfileStore',
uid: [uid],
source: UserDetailSource.KSERVER,
bizList: [ProfileBizType.KALL]
},
null
],
{ {
cbCmd: 'nodeIKernelProfileListener/onUserDetailInfoChanged', callFrom: 'BuddyProfileStore',
afterFirstCmd: false, uid: [uid],
cmdCB: payload => payload.info.uid === uid, source: UserDetailSource.KSERVER,
} bizList: [ProfileBizType.KALL]
) },
info = result.info null
} ],
{
cbCmd: 'nodeIKernelProfileListener/onUserDetailInfoChanged',
afterFirstCmd: false,
cmdCB: payload => payload.info.uid === uid,
}
)
const { info } = result
const ret: User = { const ret: User = {
...info.simpleInfo.coreInfo, ...info.simpleInfo.coreInfo,
...info.simpleInfo.status, ...info.simpleInfo.status,
@ -87,43 +67,26 @@ export class NTQQUserApi extends Service {
return ret return ret
} }
async getUserDetailInfo(uid: string, getLevel = false, withBizInfo = true) { async getUserDetailInfo(uid: string, _getLevel = false) {
if (getBuildVersion() >= 26702) { if (getBuildVersion() >= 26702) {
return this.fetchUserDetailInfo(uid) return this.fetchUserDetailInfo(uid)
} }
if (NTEventDispatch.initialised) { const result = await invoke<{ info: User }>(
type EventService = NodeIKernelProfileService['getUserDetailInfoWithBizInfo'] 'nodeIKernelProfileService/getUserDetailInfoWithBizInfo',
type EventListener = NodeIKernelProfileListener['onProfileDetailInfoChanged'] [
const [_retData, profile] = await NTEventDispatch.CallNormalEvent
<EventService, EventListener>
(
'NodeIKernelProfileService/getUserDetailInfoWithBizInfo',
'NodeIKernelProfileListener/onProfileDetailInfoChanged',
2,
5000,
(profile) => profile.uid === uid,
uid,
[0]
)
return profile
} else {
const result = await invoke<{ info: User }>(
'nodeIKernelProfileService/getUserDetailInfoWithBizInfo',
[
{
uid,
bizList: [0]
},
null,
],
{ {
cbCmd: 'nodeIKernelProfileListener/onProfileDetailInfoChanged', uid,
afterFirstCmd: false, bizList: [0]
cmdCB: (payload) => payload.info.uid === uid, },
} null,
) ],
return result.info {
} cbCmd: 'nodeIKernelProfileListener/onProfileDetailInfoChanged',
afterFirstCmd: false,
cmdCB: (payload) => payload.info.uid === uid,
}
)
return result.info
} }
async getSkey(): Promise<string> { async getSkey(): Promise<string> {
@ -244,40 +207,27 @@ export class NTQQUserApi extends Service {
} }
async getUserDetailInfoByUinV2(uin: string) { async getUserDetailInfoByUinV2(uin: string) {
if (NTEventDispatch.initialised) { return await invoke<UserDetailInfoByUinV2>(
return await NTEventDispatch.CallNoListenerEvent 'nodeIKernelProfileService/getUserDetailInfoByUin',
<(Uin: string) => Promise<UserDetailInfoByUinV2>>( [
'NodeIKernelProfileService/getUserDetailInfoByUin', { uin },
5000, null,
uin ],
) )
} else {
return await invoke<UserDetailInfoByUinV2>(
'nodeIKernelProfileService/getUserDetailInfoByUin',
[
{ uin },
null,
],
)
}
} }
async getUserDetailInfoByUin(uin: string) { async getUserDetailInfoByUin(uin: string) {
return NTEventDispatch.CallNoListenerEvent return await invoke<UserDetailInfoByUin>(
<(Uin: string) => Promise<UserDetailInfoByUin>>( 'nodeIKernelProfileService/getUserDetailInfoByUin',
'NodeIKernelProfileService/getUserDetailInfoByUin', [
5000, { uin },
uin null,
) ],
)
} }
async getUinByUidV1(uid: string) { async getUinByUidV1(uid: string) {
const ret = await NTEventDispatch.CallNoListenerEvent const ret = await invoke('nodeIKernelUixConvertService/getUin', [{ uids: [uid] }])
<(Uin: string[]) => Promise<{ uinInfo: Map<string, string> }>>(
'NodeIKernelUixConvertService/getUin',
5000,
[uid]
)
let uin = ret.uinInfo.get(uid) let uin = ret.uinInfo.get(uid)
if (!uin) { if (!uin) {
uin = (await this.getUserDetailInfo(uid)).uin //从QQ Native 转换 uin = (await this.getUserDetailInfo(uid)).uin //从QQ Native 转换

View File

@ -2,8 +2,9 @@ import type { BrowserWindow } from 'electron'
import { NTClass, NTMethod } from './ntcall' import { NTClass, NTMethod } from './ntcall'
import { log } from '@/common/utils' import { log } from '@/common/utils'
import { randomUUID } from 'node:crypto' import { randomUUID } from 'node:crypto'
import { Dict } from 'cosmokit'
export const hookApiCallbacks: Record<string, (apiReturn: any) => void> = {} export const hookApiCallbacks: Record<string, (res: any) => void> = {}
export const ReceiveCmdS = { export const ReceiveCmdS = {
RECENT_CONTACT: 'nodeIKernelRecentContactListener/onRecentContactListChangedVer2', RECENT_CONTACT: 'nodeIKernelRecentContactListener/onRecentContactListChangedVer2',
@ -30,7 +31,7 @@ export const ReceiveCmdS = {
export type ReceiveCmd = string export type ReceiveCmd = string
interface NTQQApiReturnData<Payload = unknown> extends Array<any> { interface NTQQApiReturnData extends Array<unknown> {
0: { 0: {
type: 'request' type: 'request'
eventName: NTClass eventName: NTClass
@ -39,7 +40,7 @@ interface NTQQApiReturnData<Payload = unknown> extends Array<any> {
1: { 1: {
cmdName: ReceiveCmd cmdName: ReceiveCmd
cmdType: 'event' cmdType: 'event'
payload: Payload payload: unknown
}[] }[]
} }
@ -67,16 +68,16 @@ export function hookNTQQApiReceive(window: BrowserWindow, onlyLog: boolean) {
} catch { } } catch { }
if (!onlyLog) { if (!onlyLog) {
if (args?.[1] instanceof Array) { if (args?.[1] instanceof Array) {
for (const receiveData of args?.[1]) { for (const receiveData of args[1]) {
const ntQQApiMethodName = receiveData.cmdName const ntQQApiMethodName = receiveData.cmdName
// log(`received ntqq api message: ${channel} ${ntQQApiMethodName}`, JSON.stringify(receiveData)) // log(`received ntqq api message: ${channel} ${ntQQApiMethodName}`, JSON.stringify(receiveData))
for (const hook of receiveHooks) { for (const hook of receiveHooks) {
if (hook.method.includes(ntQQApiMethodName)) { if (hook.method.includes(ntQQApiMethodName)) {
new Promise((resolve, reject) => { new Promise(resolve => {
try { try {
hook.hookFunc(receiveData.payload) hook.hookFunc(receiveData.payload)
} catch (e: any) { } catch (e) {
log('hook error', ntQQApiMethodName, e.stack.toString()) log('hook error', ntQQApiMethodName, (e as Error).stack?.toString())
} }
resolve(undefined) resolve(undefined)
}).then() }).then()
@ -88,8 +89,7 @@ export function hookNTQQApiReceive(window: BrowserWindow, onlyLog: boolean) {
// log("hookApiCallback", hookApiCallbacks, args) // log("hookApiCallback", hookApiCallbacks, args)
const callbackId = args[0].callbackId const callbackId = args[0].callbackId
if (hookApiCallbacks[callbackId]) { if (hookApiCallbacks[callbackId]) {
// log("callback found") new Promise(resolve => {
new Promise((resolve, reject) => {
hookApiCallbacks[callbackId](args[1]) hookApiCallbacks[callbackId](args[1])
resolve(undefined) resolve(undefined)
}).then() }).then()
@ -104,7 +104,7 @@ export function hookNTQQApiReceive(window: BrowserWindow, onlyLog: boolean) {
export function hookNTQQApiCall(window: BrowserWindow, onlyLog: boolean) { export function hookNTQQApiCall(window: BrowserWindow, onlyLog: boolean) {
// 监听调用NTQQApi // 监听调用NTQQApi
let webContents = window.webContents as any const webContents = window.webContents as Dict
const ipc_message_proxy = webContents._events['-ipc-message']?.[0] || webContents._events['-ipc-message'] const ipc_message_proxy = webContents._events['-ipc-message']?.[0] || webContents._events['-ipc-message']
const proxyIpcMsg = new Proxy(ipc_message_proxy, { const proxyIpcMsg = new Proxy(ipc_message_proxy, {
@ -125,10 +125,10 @@ export function hookNTQQApiCall(window: BrowserWindow, onlyLog: boolean) {
const callParams = _args.slice(1) const callParams = _args.slice(1)
callHooks.forEach((hook) => { callHooks.forEach((hook) => {
if (hook.method.includes(cmdName)) { if (hook.method.includes(cmdName)) {
new Promise((resolve, reject) => { new Promise(resolve => {
try { try {
hook.hookFunc(callParams) hook.hookFunc(callParams)
} catch (e: any) { } catch (e) {
log('hook call error', e, _args) log('hook call error', e, _args)
} }
resolve(undefined) resolve(undefined)
@ -150,14 +150,13 @@ export function hookNTQQApiCall(window: BrowserWindow, onlyLog: boolean) {
const ipc_invoke_proxy = webContents._events['-ipc-invoke']?.[0] || webContents._events['-ipc-invoke'] const ipc_invoke_proxy = webContents._events['-ipc-invoke']?.[0] || webContents._events['-ipc-invoke']
const proxyIpcInvoke = new Proxy(ipc_invoke_proxy, { const proxyIpcInvoke = new Proxy(ipc_invoke_proxy, {
apply(target, thisArg, args) { apply(target, thisArg, args) {
// console.log(args);
//HOOK_LOG && log('call NTQQ invoke api', thisArg, args) //HOOK_LOG && log('call NTQQ invoke api', thisArg, args)
args[0]['_replyChannel']['sendReply'] = new Proxy(args[0]['_replyChannel']['sendReply'], { args[0]['_replyChannel']['sendReply'] = new Proxy(args[0]['_replyChannel']['sendReply'], {
apply(sendtarget, sendthisArg, sendargs) { apply(sendtarget, sendthisArg, sendargs) {
sendtarget.apply(sendthisArg, sendargs) sendtarget.apply(sendthisArg, sendargs)
}, },
}) })
let ret = target.apply(thisArg, args) const ret = target.apply(thisArg, args)
/*try { /*try {
HOOK_LOG && log('call NTQQ invoke api return', ret) HOOK_LOG && log('call NTQQ invoke api return', ret)
} catch (e) { }*/ } catch (e) { }*/

View File

@ -352,7 +352,7 @@ export interface VideoElement {
thumbHeight?: number thumbHeight?: number
busiType?: 0 // 未知 busiType?: 0 // 未知
subBusiType?: 0 // 未知 subBusiType?: 0 // 未知
thumbPath?: Map<number, any> thumbPath?: Map<number, string>
transferStatus?: 0 // 未知 transferStatus?: 0 // 未知
progress?: 0 // 下载进度? progress?: 0 // 下载进度?
invalidState?: 0 // 未知 invalidState?: 0 // 未知
@ -523,22 +523,22 @@ export interface MessageElement {
grayTipElement?: GrayTipElement grayTipElement?: GrayTipElement
arkElement?: ArkElement arkElement?: ArkElement
fileElement?: FileElement fileElement?: FileElement
liveGiftElement?: null liveGiftElement?: unknown
markdownElement?: MarkdownElement markdownElement?: MarkdownElement
structLongMsgElement?: any structLongMsgElement?: unknown
multiForwardMsgElement?: MultiForwardMsgElement multiForwardMsgElement?: MultiForwardMsgElement
giphyElement?: any giphyElement?: unknown
walletElement?: null walletElement?: unknown
inlineKeyboardElement?: InlineKeyboardElement inlineKeyboardElement?: InlineKeyboardElement
textGiftElement?: null //???? textGiftElement?: unknown //????
calendarElement?: any calendarElement?: unknown
yoloGameResultElement?: any yoloGameResultElement?: unknown
avRecordElement?: any avRecordElement?: unknown
structMsgElement?: null structMsgElement?: unknown
faceBubbleElement?: any faceBubbleElement?: unknown
shareLocationElement?: any shareLocationElement?: unknown
tofuRecordElement?: any tofuRecordElement?: unknown
taskTopMsgElement?: any taskTopMsgElement?: unknown
recommendedMsgElement?: any recommendedMsgElement?: unknown
actionBarElement?: any actionBarElement?: unknown
} }

View File

@ -45,8 +45,6 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnData> {
message: '音乐消息不可以和其他消息混在一起发送', message: '音乐消息不可以和其他消息混在一起发送',
} }
} }
if (payload.user_id && payload.message_type !== 'group') {
}
return { return {
valid: true, valid: true,
} }
@ -67,9 +65,9 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnData> {
if (this.getSpecialMsgNum(messages, OB11MessageDataType.node)) { if (this.getSpecialMsgNum(messages, OB11MessageDataType.node)) {
try { try {
const returnMsg = await this.handleForwardNode(peer, messages as OB11MessageNode[]) const returnMsg = await this.handleForwardNode(peer, messages as OB11MessageNode[])
return { message_id: returnMsg?.msgShortId! } return { message_id: returnMsg.msgShortId! }
} catch (e: any) { } catch (e) {
throw '发送转发消息失败 ' + e.toString() throw '发送转发消息失败 ' + e
} }
} }
else if (this.getSpecialMsgNum(messages, OB11MessageDataType.music)) { else if (this.getSpecialMsgNum(messages, OB11MessageDataType.music)) {
@ -144,26 +142,20 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnData> {
private async cloneMsg(msg: RawMessage): Promise<RawMessage | undefined> { private async cloneMsg(msg: RawMessage): Promise<RawMessage | undefined> {
this.ctx.logger.info('克隆的目标消息', msg) this.ctx.logger.info('克隆的目标消息', msg)
let sendElements: SendMessageElement[] = [] const sendElements: SendMessageElement[] = []
for (const ele of msg.elements) { for (const ele of msg.elements) {
sendElements.push(ele as SendMessageElement) sendElements.push(ele as SendMessageElement)
// Object.keys(ele).forEach((eleKey) => {
// if (eleKey.endsWith("Element")) {
// }
} }
if (sendElements.length === 0) { if (sendElements.length === 0) {
this.ctx.logger.warn('需要clone的消息无法解析将会忽略掉', msg) this.ctx.logger.warn('需要clone的消息无法解析将会忽略掉', msg)
} }
this.ctx.logger.info('克隆消息', sendElements) this.ctx.logger.info('克隆消息', sendElements)
try { try {
const nodeMsg = await this.ctx.ntMsgApi.sendMsg( const peer = {
{ chatType: ChatType.friend,
chatType: ChatType.friend, peerUid: selfInfo.uid
peerUid: selfInfo.uid, }
}, const nodeMsg = await this.ctx.ntMsgApi.sendMsg(peer, sendElements)
sendElements,
true,
)
await this.ctx.sleep(400) await this.ctx.sleep(400)
return nodeMsg return nodeMsg
} catch (e) { } catch (e) {
@ -181,7 +173,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnData> {
// 先判断一遍是不是id和自定义混用 // 先判断一遍是不是id和自定义混用
for (const messageNode of messageNodes) { for (const messageNode of messageNodes) {
// 一个node表示一个人的消息 // 一个node表示一个人的消息
let nodeId = messageNode.data.id const nodeId = messageNode.data.id
// 有nodeId表示一个子转发消息卡片 // 有nodeId表示一个子转发消息卡片
if (nodeId) { if (nodeId) {
const nodeMsg = await MessageUnique.getMsgIdAndPeerByShortId(+nodeId) || await MessageUnique.getPeerByMsgId(nodeId) const nodeMsg = await MessageUnique.getMsgIdAndPeerByShortId(+nodeId) || await MessageUnique.getPeerByMsgId(nodeId)
@ -201,7 +193,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnData> {
destPeer destPeer
) )
this.ctx.logger.info('开始生成转发节点', sendElements) this.ctx.logger.info('开始生成转发节点', sendElements)
let sendElementsSplit: SendMessageElement[][] = [] const sendElementsSplit: SendMessageElement[][] = []
let splitIndex = 0 let splitIndex = 0
for (const ele of sendElements) { for (const ele of sendElements) {
if (!sendElementsSplit[splitIndex]) { if (!sendElementsSplit[splitIndex]) {

View File

@ -42,7 +42,7 @@ import { OB11GroupRecallNoticeEvent } from './event/notice/OB11GroupRecallNotice
import { OB11FriendPokeEvent, OB11GroupPokeEvent } from './event/notice/OB11PokeEvent' import { OB11FriendPokeEvent, OB11GroupPokeEvent } from './event/notice/OB11PokeEvent'
import { OB11BaseNoticeEvent } from './event/notice/OB11BaseNoticeEvent' import { OB11BaseNoticeEvent } from './event/notice/OB11BaseNoticeEvent'
import { OB11GroupEssenceEvent } from './event/notice/OB11GroupEssenceEvent' import { OB11GroupEssenceEvent } from './event/notice/OB11GroupEssenceEvent'
import { omit, isNullable, pick } from 'cosmokit' import { omit, isNullable, pick, Dict } from 'cosmokit'
import { Context } from 'cordis' import { Context } from 'cordis'
import { selfInfo } from '@/common/globalVars' import { selfInfo } from '@/common/globalVars'
import { pathToFileURL } from 'node:url' import { pathToFileURL } from 'node:url'
@ -96,14 +96,14 @@ export namespace OB11Entities {
const ret = await ctx.ntMsgApi.getTempChatInfo(ChatType2.KCHATTYPETEMPC2CFROMGROUP, msg.senderUid) const ret = await ctx.ntMsgApi.getTempChatInfo(ChatType2.KCHATTYPETEMPC2CFROMGROUP, msg.senderUid)
if (ret?.result === 0) { if (ret?.result === 0) {
resMsg.temp_source = Number(ret.tmpChatInfo?.groupCode) resMsg.temp_source = Number(ret.tmpChatInfo?.groupCode)
resMsg.sender.nickname = ret.tmpChatInfo?.fromNick! resMsg.sender.nickname = ret.tmpChatInfo!.fromNick
} else { } else {
resMsg.temp_source = 284840486 //兜底数据 resMsg.temp_source = 284840486 //兜底数据
resMsg.sender.nickname = '临时会话' resMsg.sender.nickname = '临时会话'
} }
} }
for (let element of msg.elements) { for (const element of msg.elements) {
let messageSegment: OB11MessageData | undefined let messageSegment: OB11MessageData | undefined
if (element.textElement && element.textElement?.atType !== AtType.notAt) { if (element.textElement && element.textElement?.atType !== AtType.notAt) {
let qq: string let qq: string
@ -404,7 +404,7 @@ export namespace OB11Entities {
return return
} }
if (msg.senderUin) { if (msg.senderUin) {
let member = await ctx.ntGroupApi.getGroupMember(msg.peerUid, msg.senderUin) const member = await ctx.ntGroupApi.getGroupMember(msg.peerUid, msg.senderUin)
if (member && member.cardName !== msg.sendMemberName) { if (member && member.cardName !== msg.sendMemberName) {
const event = new OB11GroupCardEvent( const event = new OB11GroupCardEvent(
parseInt(msg.peerUid), parseInt(msg.peerUid),
@ -416,12 +416,10 @@ export namespace OB11Entities {
return event return event
} }
} }
// log("group msg", msg) for (const element of msg.elements) {
for (let element of msg.elements) {
const grayTipElement = element.grayTipElement const grayTipElement = element.grayTipElement
const groupElement = grayTipElement?.groupElement const groupElement = grayTipElement?.groupElement
if (groupElement) { if (groupElement) {
// log("收到群提示消息", groupElement)
if (groupElement.type === TipGroupElementType.memberIncrease) { if (groupElement.type === TipGroupElementType.memberIncrease) {
ctx.logger.info('收到群成员增加消息', groupElement) ctx.logger.info('收到群成员增加消息', groupElement)
await ctx.sleep(1000) await ctx.sleep(1000)
@ -430,14 +428,10 @@ export namespace OB11Entities {
if (!memberUin) { if (!memberUin) {
memberUin = (await ctx.ntUserApi.getUserDetailInfo(groupElement.memberUid)).uin memberUin = (await ctx.ntUserApi.getUserDetailInfo(groupElement.memberUid)).uin
} }
// log("获取新群成员QQ", memberUin)
const adminMember = await ctx.ntGroupApi.getGroupMember(msg.peerUid, groupElement.adminUid) const adminMember = await ctx.ntGroupApi.getGroupMember(msg.peerUid, groupElement.adminUid)
// log("获取同意新成员入群的管理员", adminMember)
if (memberUin) { if (memberUin) {
const operatorUin = adminMember?.uin || memberUin const operatorUin = adminMember?.uin || memberUin
let event = new OB11GroupIncreaseEvent(parseInt(msg.peerUid), parseInt(memberUin), parseInt(operatorUin)) return new OB11GroupIncreaseEvent(parseInt(msg.peerUid), parseInt(memberUin), parseInt(operatorUin))
// log("构造群增加事件", event)
return event
} }
} }
else if (groupElement.type === TipGroupElementType.ban) { else if (groupElement.type === TipGroupElementType.ban) {
@ -445,8 +439,8 @@ export namespace OB11Entities {
const memberUid = groupElement.shutUp?.member.uid const memberUid = groupElement.shutUp?.member.uid
const adminUid = groupElement.shutUp?.admin.uid const adminUid = groupElement.shutUp?.admin.uid
let memberUin: string = '' let memberUin: string = ''
let duration = parseInt(groupElement.shutUp?.duration!) let duration = Number(groupElement.shutUp?.duration)
let sub_type: 'ban' | 'lift_ban' = duration > 0 ? 'ban' : 'lift_ban' const subType = duration > 0 ? 'ban' : 'lift_ban'
if (memberUid) { if (memberUid) {
memberUin = memberUin =
(await ctx.ntGroupApi.getGroupMember(msg.peerUid, memberUid))?.uin || (await ctx.ntGroupApi.getGroupMember(msg.peerUid, memberUid))?.uin ||
@ -466,7 +460,7 @@ export namespace OB11Entities {
parseInt(memberUin), parseInt(memberUin),
parseInt(adminUin), parseInt(adminUin),
duration, duration,
sub_type, subType,
) )
} }
} }
@ -542,8 +536,8 @@ export namespace OB11Entities {
count: 1, count: 1,
}] }]
) )
} catch (e: any) { } catch (e) {
ctx.logger.error('解析表情回应消息失败', e.stack) ctx.logger.error('解析表情回应消息失败', (e as Error).stack)
} }
} }
@ -597,7 +591,7 @@ export namespace OB11Entities {
if (grayTipElement.jsonGrayTipElement.busiId == 1061) { if (grayTipElement.jsonGrayTipElement.busiId == 1061) {
//判断业务类型 //判断业务类型
//Poke事件 //Poke事件
const pokedetail: any[] = json.items const pokedetail: Dict[] = json.items
//筛选item带有uid的元素 //筛选item带有uid的元素
const poke_uid = pokedetail.filter(item => item.uid) const poke_uid = pokedetail.filter(item => item.uid)
if (poke_uid.length == 2) { if (poke_uid.length == 2) {

View File

@ -1,7 +1,7 @@
import { CheckVersion, Config } from '../common/types' import { CheckVersion, Config } from '../common/types'
import { SettingButton, SettingItem, SettingList, SettingSwitch, SettingSelect } from './components' import { SettingButton, SettingItem, SettingList, SettingSwitch, SettingSelect } from './components'
import { version } from '../version' import { version } from '../version'
// @ts-ignore // @ts-expect-error
import StyleRaw from './style.css?raw' import StyleRaw from './style.css?raw'
type HostsType = 'httpHosts' | 'wsHosts' type HostsType = 'httpHosts' | 'wsHosts'
@ -15,7 +15,7 @@ async function onSettingWindowCreated(view: Element) {
const config = await window.llonebot.getConfig() const config = await window.llonebot.getConfig()
const ob11Config = { ...config.ob11 } const ob11Config = { ...config.ob11 }
const setConfig = (key: string, value: any) => { const setConfig = (key: string, value: unknown) => {
const configKey = key.split('.') const configKey = key.split('.')
if (key.startsWith('ob11')) { if (key.startsWith('ob11')) {
if (configKey.length === 2) Object.assign(ob11Config, { [configKey[1]]: value }) if (configKey.length === 2) Object.assign(ob11Config, { [configKey[1]]: value })
@ -87,9 +87,8 @@ async function onSettingWindowCreated(view: Element) {
<setting-text>HTTP </setting-text> <setting-text>HTTP </setting-text>
</div> </div>
<div class="q-input"> <div class="q-input">
<input id="config-ob11-httpSecret" class="q-input__inner" data-config-key="ob11.httpSecret" type="text" value="${ <input id="config-ob11-httpSecret" class="q-input__inner" data-config-key="ob11.httpSecret" type="text" value="${config.ob11.httpSecret
config.ob11.httpSecret }" placeholder="" />
}" placeholder="" />
</div> </div>
</setting-item> </setting-item>
<setting-item data-direction="row"> <setting-item data-direction="row">
@ -152,8 +151,7 @@ async function onSettingWindowCreated(view: Element) {
), ),
SettingItem( SettingItem(
'FFmpeg 路径,发送语音、视频需要', 'FFmpeg 路径,发送语音、视频需要',
`<a href="javascript:LiteLoader.api.openExternal(\'https://llonebot.github.io/zh-CN/guide/ffmpeg\');">可点此下载</a>, 路径: <span id="config-ffmpeg-path-text">${ `<a href="javascript:LiteLoader.api.openExternal(\'https://llonebot.github.io/zh-CN/guide/ffmpeg\');">可点此下载</a>, 路径: <span id="config-ffmpeg-path-text">${!isEmpty(config.ffmpeg) ? config.ffmpeg : '未指定'
!isEmpty(config.ffmpeg) ? config.ffmpeg : '未指定'
}</span>, FFprobe FFmpeg `, }</span>, FFprobe FFmpeg `,
SettingButton('选择 FFmpeg', 'config-ffmpeg-select'), SettingButton('选择 FFmpeg', 'config-ffmpeg-select'),
), ),
@ -254,7 +252,7 @@ async function onSettingWindowCreated(view: Element) {
window.LiteLoader.api.openExternal('https://llonebot.github.io/') window.LiteLoader.api.openExternal('https://llonebot.github.io/')
}) })
// 生成反向地址列表 // 生成反向地址列表
const buildHostListItem = (type: HostsType, host: string, index: number, inputAttrs: any = {}) => { const buildHostListItem = (type: HostsType, host: string, index: number, inputAttrs = {}) => {
const dom = { const dom = {
container: document.createElement('setting-item'), container: document.createElement('setting-item'),
input: document.createElement('input'), input: document.createElement('input'),
@ -286,7 +284,7 @@ async function onSettingWindowCreated(view: Element) {
return dom.container return dom.container
} }
const buildHostList = (hosts: string[], type: HostsType, inputAttr: any = {}) => { const buildHostList = (hosts: string[], type: HostsType, inputAttr = {}) => {
const result: HTMLElement[] = [] const result: HTMLElement[] = []
hosts.forEach((host, index) => { hosts.forEach((host, index) => {
@ -295,14 +293,15 @@ async function onSettingWindowCreated(view: Element) {
return result return result
} }
const addReverseHost = (type: HostsType, doc: Document = document, inputAttr: any = {}) => { const addReverseHost = (type: HostsType, doc: Document = document, inputAttr = {}) => {
const hostContainerDom = doc.body.querySelector(`#config-ob11-${type}-list`) const hostContainerDom = doc.body.querySelector(`#config-ob11-${type}-list`)
hostContainerDom?.appendChild(buildHostListItem(type, '', ob11Config[type].length, inputAttr)) hostContainerDom?.appendChild(buildHostListItem(type, '', ob11Config[type].length, inputAttr))
ob11Config[type].push('') ob11Config[type].push('')
} }
const initReverseHost = (type: HostsType, doc: Document = document) => { const initReverseHost = (type: HostsType, doc: Document = document) => {
const hostContainerDom = doc.body.querySelector(`#config-ob11-${type}-list`) const hostContainerDom = doc.body.querySelector(`#config-ob11-${type}-list`)!
;[...hostContainerDom?.childNodes!].forEach((dom) => dom.remove()) const nodes = [...hostContainerDom.childNodes]
nodes.forEach((dom) => dom.remove())
buildHostList(ob11Config[type], type).forEach((dom) => { buildHostList(ob11Config[type], type).forEach((dom) => {
hostContainerDom?.appendChild(dom) hostContainerDom?.appendChild(dom)
}) })
@ -427,14 +426,14 @@ async function onSettingWindowCreated(view: Element) {
} }
} }
window.llonebot.checkVersion().then(checkVersionFunc) window.llonebot.checkVersion().then(checkVersionFunc)
window.addEventListener('beforeunload', (event) => { window.addEventListener('beforeunload', () => {
if (JSON.stringify(ob11Config) === JSON.stringify(config.ob11)) return if (JSON.stringify(ob11Config) === JSON.stringify(config.ob11)) return
config.ob11 = ob11Config config.ob11 = ob11Config
window.llonebot.setConfig(true, config) window.llonebot.setConfig(true, config)
}) })
} }
function init() { /**function init() {
const hash = location.hash const hash = location.hash
if (hash === '#/blank') { if (hash === '#/blank') {
} }
@ -444,6 +443,6 @@ if (location.hash === '#/blank') {
globalThis.navigation?.addEventListener('navigatesuccess', init, { once: true }) globalThis.navigation?.addEventListener('navigatesuccess', init, { once: true })
} else { } else {
init() init()
} }*/
export { onSettingWindowCreated } export { onSettingWindowCreated }