mirror of
https://github.com/LLOneBot/LLOneBot.git
synced 2024-11-22 01:56:33 +00:00
@@ -4,7 +4,7 @@
|
|||||||
"name": "LLOneBot",
|
"name": "LLOneBot",
|
||||||
"slug": "LLOneBot",
|
"slug": "LLOneBot",
|
||||||
"description": "实现 OneBot 11 协议,用于 QQ 机器人开发",
|
"description": "实现 OneBot 11 协议,用于 QQ 机器人开发",
|
||||||
"version": "3.31.2",
|
"version": "3.31.3",
|
||||||
"icon": "./icon.webp",
|
"icon": "./icon.webp",
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
|
@@ -82,7 +82,7 @@ class MessageUniqueWrapper {
|
|||||||
return ret.map((t) => t?.MsgId).filter((t) => t !== undefined)
|
return ret.map((t) => t?.MsgId).filter((t) => t !== undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
createMsg(peer: Peer, msgId: string): number | undefined {
|
createMsg(peer: Peer, msgId: string): number {
|
||||||
const key = `${msgId}|${peer.chatType}|${peer.peerUid}`
|
const key = `${msgId}|${peer.chatType}|${peer.peerUid}`
|
||||||
const hash = createHash('md5').update(key).digest()
|
const hash = createHash('md5').update(key).digest()
|
||||||
//设置第一个bit为0 保证shortId为正数
|
//设置第一个bit为0 保证shortId为正数
|
||||||
|
5
src/global.d.ts
vendored
5
src/global.d.ts
vendored
@@ -2,9 +2,6 @@ import type { LLOneBot } from './preload'
|
|||||||
import { Dict } from 'cosmokit'
|
import { Dict } from 'cosmokit'
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
var llonebot: LLOneBot
|
||||||
llonebot: LLOneBot
|
|
||||||
LiteLoader: Dict
|
|
||||||
}
|
|
||||||
var LiteLoader: Dict
|
var LiteLoader: Dict
|
||||||
}
|
}
|
@@ -4,7 +4,6 @@ import { invoke, NTMethod, NTClass } from '../ntcall'
|
|||||||
import { getSession } from '@/ntqqapi/wrapper'
|
import { getSession } from '@/ntqqapi/wrapper'
|
||||||
import { BuddyListReqType, NodeIKernelProfileService } from '../services'
|
import { BuddyListReqType, NodeIKernelProfileService } from '../services'
|
||||||
import { NTEventDispatch } from '@/common/utils/eventTask'
|
import { NTEventDispatch } from '@/common/utils/eventTask'
|
||||||
import { LimitedHashTable } from '@/common/utils/table'
|
|
||||||
import { pick } from 'cosmokit'
|
import { pick } from 'cosmokit'
|
||||||
import { Service, Context } from 'cordis'
|
import { Service, Context } from 'cordis'
|
||||||
|
|
||||||
@@ -101,8 +100,9 @@ export class NTQQFriendApi extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBuddyIdMap(refresh = false): Promise<LimitedHashTable<string, string>> {
|
/** uid => uin */
|
||||||
const retMap: LimitedHashTable<string, string> = new LimitedHashTable<string, string>(5000)
|
async getBuddyIdMap(refresh = false): Promise<Map<string, string>> {
|
||||||
|
const retMap: Map<string, string> = new Map()
|
||||||
const session = getSession()
|
const session = getSession()
|
||||||
if (session) {
|
if (session) {
|
||||||
const uids: string[] = []
|
const uids: string[] = []
|
||||||
@@ -112,9 +112,12 @@ export class NTQQFriendApi extends Service {
|
|||||||
const data = await NTEventDispatch.CallNoListenerEvent<NodeIKernelProfileService['getCoreAndBaseInfo']>(
|
const data = await NTEventDispatch.CallNoListenerEvent<NodeIKernelProfileService['getCoreAndBaseInfo']>(
|
||||||
'NodeIKernelProfileService/getCoreAndBaseInfo', 5000, 'nodeStore', uids
|
'NodeIKernelProfileService/getCoreAndBaseInfo', 5000, 'nodeStore', uids
|
||||||
)
|
)
|
||||||
data.forEach((value, key) => {
|
for (const [, item] of data) {
|
||||||
retMap.set(value.uin!, value.uid!)
|
if (retMap.size > 5000) {
|
||||||
})
|
break
|
||||||
|
}
|
||||||
|
retMap.set(item.uid!, item.uin!)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const data = await invoke<{
|
const data = await invoke<{
|
||||||
buddyCategory: CategoryFriend[]
|
buddyCategory: CategoryFriend[]
|
||||||
@@ -129,7 +132,10 @@ export class NTQQFriendApi extends Service {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
for (const item of Object.values(data.userSimpleInfos)) {
|
for (const item of Object.values(data.userSimpleInfos)) {
|
||||||
retMap.set(item.uin!, item.uid!)
|
if (retMap.size > 5000) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
retMap.set(item.uid!, item.uin!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return retMap
|
return retMap
|
||||||
|
@@ -144,7 +144,7 @@ export class NTQQUserApi extends Service {
|
|||||||
}
|
}
|
||||||
const uin = selfInfo.uin
|
const uin = selfInfo.uin
|
||||||
const requestUrl = 'https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=' + uin + '&clientkey=' + clientKeyData.clientKey + '&u1=https%3A%2F%2F' + domain + '%2F' + uin + '%2Finfocenter&keyindex=19%27'
|
const requestUrl = 'https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=' + uin + '&clientkey=' + clientKeyData.clientKey + '&u1=https%3A%2F%2F' + domain + '%2F' + uin + '%2Finfocenter&keyindex=19%27'
|
||||||
const cookies: { [key: string]: string; } = await RequestUtil.HttpsGetCookies(requestUrl)
|
const cookies: { [key: string]: string } = await RequestUtil.HttpsGetCookies(requestUrl)
|
||||||
return cookies
|
return cookies
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,7 +192,7 @@ export class NTQQUserApi extends Service {
|
|||||||
// 通用转换开始尝试
|
// 通用转换开始尝试
|
||||||
let uid = (await session?.getUixConvertService().getUid([Uin]))?.uidInfo.get(Uin)
|
let uid = (await session?.getUixConvertService().getUid([Uin]))?.uidInfo.get(Uin)
|
||||||
if (!uid) {
|
if (!uid) {
|
||||||
let unveifyUid = (await this.getUserDetailInfoByUin(Uin)).info.uid;//从QQ Native 特殊转换 方法三
|
let unveifyUid = (await this.getUserDetailInfoByUin(Uin)).info.uid //从QQ Native 特殊转换 方法三
|
||||||
if (unveifyUid.indexOf('*') == -1) {
|
if (unveifyUid.indexOf('*') == -1) {
|
||||||
uid = unveifyUid
|
uid = unveifyUid
|
||||||
}
|
}
|
||||||
@@ -210,11 +210,11 @@ export class NTQQUserApi extends Service {
|
|||||||
uid = (await session.getUixConvertService().getUid([uin])).uidInfo.get(uin)
|
uid = (await session.getUixConvertService().getUid([uin])).uidInfo.get(uin)
|
||||||
if (uid) return uid
|
if (uid) return uid
|
||||||
} else {
|
} else {
|
||||||
let uid = (await invoke('nodeIKernelGroupService/getUidByUins', [{ uin: [uin] }, null])).uids.get(uin)
|
let uid = (await invoke('nodeIKernelGroupService/getUidByUins', [{ uin: [uin] }])).uids.get(uin)
|
||||||
if (uid) return uid
|
if (uid) return uid
|
||||||
uid = (await invoke('nodeIKernelProfileService/getUidByUin', [{ callFrom: 'FriendsServiceImpl', uin: [uin] }, null])).get(uin)
|
uid = (await invoke('nodeIKernelProfileService/getUidByUin', [{ callFrom: 'FriendsServiceImpl', uin: [uin] }])).get(uin)
|
||||||
if (uid) return uid
|
if (uid) return uid
|
||||||
uid = (await invoke('nodeIKernelUixConvertService/getUid', [{ uin: [uin] }, null])).uidInfo.get(uin)
|
uid = (await invoke('nodeIKernelUixConvertService/getUid', [{ uins: [uin] }])).uidInfo.get(uin)
|
||||||
if (uid) return uid
|
if (uid) return uid
|
||||||
}
|
}
|
||||||
const unveifyUid = (await this.getUserDetailInfoByUinV2(uin)).detail.uid //从QQ Native 特殊转换
|
const unveifyUid = (await this.getUserDetailInfoByUinV2(uin)).detail.uid //从QQ Native 特殊转换
|
||||||
@@ -280,14 +280,14 @@ export class NTQQUserApi extends Service {
|
|||||||
uin = (await session.getUixConvertService().getUin([uid])).uinInfo.get(uid)
|
uin = (await session.getUixConvertService().getUin([uid])).uinInfo.get(uid)
|
||||||
if (uin) return uin
|
if (uin) return uin
|
||||||
} else {
|
} else {
|
||||||
let uin = (await invoke('nodeIKernelGroupService/getUinByUids', [{ uid: [uid] }, null])).uins.get(uid)
|
let uin = (await invoke('nodeIKernelGroupService/getUinByUids', [{ uid: [uid] }])).uins.get(uid)
|
||||||
if (uin) return uin
|
if (uin) return uin
|
||||||
uin = (await invoke('nodeIKernelProfileService/getUinByUid', [{ callFrom: 'FriendsServiceImpl', uid: [uid] }, null])).get(uid)
|
uin = (await invoke('nodeIKernelProfileService/getUinByUid', [{ callFrom: 'FriendsServiceImpl', uid: [uid] }])).get(uid)
|
||||||
if (uin) return uin
|
if (uin) return uin
|
||||||
uin = (await invoke('nodeIKernelUixConvertService/getUin', [{ uid: [uid] }, null])).uinInfo.get(uid)
|
uin = (await invoke('nodeIKernelUixConvertService/getUin', [{ uids: [uid] }])).uinInfo.get(uid)
|
||||||
if (uin) return uin
|
if (uin) return uin
|
||||||
}
|
}
|
||||||
let uin = (await this.ctx.ntFriendApi.getBuddyIdMap(true)).getKey(uid)
|
let uin = (await this.ctx.ntFriendApi.getBuddyIdMap(true)).get(uid)
|
||||||
if (uin) return uin
|
if (uin) return uin
|
||||||
uin = (await this.getUserDetailInfo(uid)).uin //从QQ Native 转换
|
uin = (await this.getUserDetailInfo(uid)).uin //从QQ Native 转换
|
||||||
return uin
|
return uin
|
||||||
|
@@ -136,25 +136,24 @@ export function invoke<
|
|||||||
R extends Awaited<ReturnType<NTService[S][M] extends (...args: any) => any ? NTService[S][M] : any>>,
|
R extends Awaited<ReturnType<NTService[S][M] extends (...args: any) => any ? NTService[S][M] : any>>,
|
||||||
S extends keyof NTService = any,
|
S extends keyof NTService = any,
|
||||||
M extends keyof NTService[S] & string = any
|
M extends keyof NTService[S] & string = any
|
||||||
>(method: `${unknown extends `${S}/${M}` ? `${S}/${M}` : string}`, args?: unknown[], options: InvokeOptions<R> = {}) {
|
>(method: `${unknown extends `${S}/${M}` ? `${S}/${M}` : string}`, args: unknown[], options: InvokeOptions<R> = {}) {
|
||||||
const className = options.className ?? NTClass.NT_API
|
const className = options.className ?? NTClass.NT_API
|
||||||
const channel = options.channel ?? NTChannel.IPC_UP_2
|
const channel = options.channel ?? NTChannel.IPC_UP_2
|
||||||
const timeout = options.timeout ?? 5000
|
const timeout = options.timeout ?? 5000
|
||||||
const afterFirstCmd = options.afterFirstCmd ?? true
|
const afterFirstCmd = options.afterFirstCmd ?? true
|
||||||
const uuid = randomUUID()
|
|
||||||
let eventName = className + '-' + channel[channel.length - 1]
|
let eventName = className + '-' + channel[channel.length - 1]
|
||||||
if (options.classNameIsRegister) {
|
if (options.classNameIsRegister) {
|
||||||
eventName += '-register'
|
eventName += '-register'
|
||||||
}
|
}
|
||||||
const apiArgs = [method, ...(args ?? [])]
|
return new Promise<R>((resolve, reject) => {
|
||||||
//log('callNTQQApi', channel, eventName, apiArgs, uuid)
|
const apiArgs = [method, ...args]
|
||||||
return new Promise((resolve: (data: R) => void, reject) => {
|
const callbackId = randomUUID()
|
||||||
let success = false
|
let success = false
|
||||||
if (!options.cbCmd) {
|
if (!options.cbCmd) {
|
||||||
// QQ后端会返回结果,并且可以根据uuid识别
|
// QQ后端会返回结果,并且可以根据uuid识别
|
||||||
hookApiCallbacks[uuid] = (r: R) => {
|
hookApiCallbacks[callbackId] = res => {
|
||||||
success = true
|
success = true
|
||||||
resolve(r)
|
resolve(res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -177,7 +176,7 @@ export function invoke<
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
!afterFirstCmd && secondCallback()
|
!afterFirstCmd && secondCallback()
|
||||||
hookApiCallbacks[uuid] = (result: GeneralCallResult) => {
|
hookApiCallbacks[callbackId] = (result: GeneralCallResult) => {
|
||||||
if (result?.result === 0 || result === undefined) {
|
if (result?.result === 0 || result === undefined) {
|
||||||
//log(`${params.methodName} callback`, result)
|
//log(`${params.methodName} callback`, result)
|
||||||
afterFirstCmd && secondCallback()
|
afterFirstCmd && secondCallback()
|
||||||
@@ -203,7 +202,7 @@ export function invoke<
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ type: 'request', callbackId: uuid, eventName },
|
{ type: 'request', callbackId, eventName },
|
||||||
apiArgs,
|
apiArgs,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@@ -177,8 +177,6 @@ export interface NodeIKernelRichMediaService {
|
|||||||
|
|
||||||
renameGroupFolder(arg1: unknown, arg2: unknown, arg3: unknown): unknown
|
renameGroupFolder(arg1: unknown, arg2: unknown, arg3: unknown): unknown
|
||||||
|
|
||||||
deleteGroupFolder(arg1: unknown, arg2: unknown): unknown
|
|
||||||
|
|
||||||
deleteTransferInfo(arg1: unknown, arg2: unknown): unknown
|
deleteTransferInfo(arg1: unknown, arg2: unknown): unknown
|
||||||
|
|
||||||
cancelTransferTask(arg1: unknown, arg2: unknown, arg3: unknown): unknown
|
cancelTransferTask(arg1: unknown, arg2: unknown, arg3: unknown): unknown
|
||||||
|
@@ -146,34 +146,31 @@ export namespace OB11Entities {
|
|||||||
message_data['data']['text'] = text
|
message_data['data']['text'] = text
|
||||||
}
|
}
|
||||||
else if (element.replyElement) {
|
else if (element.replyElement) {
|
||||||
message_data['type'] = OB11MessageDataType.reply
|
const { replyElement } = element
|
||||||
|
const peer = {
|
||||||
|
chatType: msg.chatType,
|
||||||
|
peerUid: msg.peerUid,
|
||||||
|
guildId: ''
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const records = msg.records.find(msgRecord => msgRecord.msgId === element.replyElement.sourceMsgIdInRecords)
|
const records = msg.records.find(msgRecord => msgRecord.msgId === replyElement.sourceMsgIdInRecords)
|
||||||
if (!records) throw new Error('找不到回复消息')
|
if (!records) throw new Error('找不到回复消息')
|
||||||
let replyMsg = (await ctx.ntMsgApi.getMsgsBySeqAndCount({
|
let replyMsg = (await ctx.ntMsgApi.getMsgsBySeqAndCount(peer, replyElement.replayMsgSeq, 1, true, true)).msgList[0]
|
||||||
peerUid: msg.peerUid,
|
|
||||||
guildId: '',
|
|
||||||
chatType: msg.chatType,
|
|
||||||
}, element.replyElement.replayMsgSeq, 1, true, true))?.msgList[0]
|
|
||||||
if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) {
|
if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) {
|
||||||
const peer = {
|
replyMsg = (await ctx.ntMsgApi.getSingleMsg(peer, replyElement.replayMsgSeq)).msgList[0]
|
||||||
chatType: msg.chatType,
|
|
||||||
peerUid: msg.peerUid,
|
|
||||||
guildId: '',
|
|
||||||
}
|
|
||||||
replyMsg = (await ctx.ntMsgApi.getSingleMsg(peer, element.replyElement.replayMsgSeq))?.msgList[0]
|
|
||||||
}
|
}
|
||||||
// 284840486: 合并消息内侧 消息具体定位不到
|
// 284840486: 合并消息内侧 消息具体定位不到
|
||||||
if ((!replyMsg || records.msgRandom !== replyMsg.msgRandom) && msg.peerUin !== '284840486') {
|
if ((!replyMsg || records.msgRandom !== replyMsg.msgRandom) && msg.peerUin !== '284840486') {
|
||||||
throw new Error('回复消息消息验证失败')
|
throw new Error('回复消息消息验证失败')
|
||||||
}
|
}
|
||||||
message_data['data']['id'] = replyMsg && MessageUnique.createMsg({
|
message_data = {
|
||||||
peerUid: msg.peerUid,
|
type: OB11MessageDataType.reply,
|
||||||
guildId: '',
|
data: {
|
||||||
chatType: msg.chatType,
|
id: MessageUnique.createMsg(peer, replyMsg ? replyMsg.msgId : records.msgId).toString()
|
||||||
}, replyMsg.msgId)?.toString()
|
}
|
||||||
|
}
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
ctx.logger.error('获取不到引用的消息', e.stack, element.replyElement.replayMsgSeq)
|
ctx.logger.error('获取不到引用的消息', replyElement.replayMsgSeq, e.stack)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1 +1 @@
|
|||||||
export const version = '3.31.2'
|
export const version = '3.31.3'
|
||||||
|
Reference in New Issue
Block a user