This commit is contained in:
idranme 2024-08-25 20:00:13 +08:00
parent 867a05c85a
commit c1f5c5cd58
No known key found for this signature in database
GPG Key ID: 926F7B5B668E495F
8 changed files with 21 additions and 186 deletions

View File

@ -25,7 +25,7 @@
"fast-xml-parser": "^4.4.1", "fast-xml-parser": "^4.4.1",
"file-type": "^19.4.1", "file-type": "^19.4.1",
"fluent-ffmpeg": "^2.1.3", "fluent-ffmpeg": "^2.1.3",
"minato": "^3.5.0", "minato": "^3.5.1",
"silk-wasm": "^3.6.1", "silk-wasm": "^3.6.1",
"ws": "^8.18.0" "ws": "^8.18.0"
}, },
@ -41,5 +41,5 @@
"vite": "^5.4.2", "vite": "^5.4.2",
"vite-plugin-cp": "^4.0.8" "vite-plugin-cp": "^4.0.8"
}, },
"packageManager": "yarn@4.4.0" "packageManager": "yarn@4.4.1"
} }

View File

@ -5,8 +5,6 @@ import path from 'node:path'
import { getSelfUin } from './data' import { getSelfUin } from './data'
import { DATA_DIR } from './utils' import { DATA_DIR } from './utils'
//export const HOOK_LOG = false
export class ConfigUtil { export class ConfigUtil {
private readonly configPath: string private readonly configPath: string
private config: Config | null = null private config: Config | null = null

View File

@ -1,45 +1,24 @@
import { import {
type Friend,
type GroupMember, type GroupMember,
type SelfInfo, type SelfInfo,
} from '../ntqqapi/types' } from '../ntqqapi/types'
import { type LLOneBotError } from './types' import { type LLOneBotError } from './types'
import { NTQQGroupApi } from '../ntqqapi/api/group' import { NTQQGroupApi } from '../ntqqapi/api/group'
import { log } from './utils/log'
import { isNumeric } from './utils/helper' import { isNumeric } from './utils/helper'
import { NTQQFriendApi, NTQQUserApi } from '../ntqqapi/api' import { NTQQUserApi } from '../ntqqapi/api'
import { RawMessage } from '../ntqqapi/types' import { RawMessage } from '../ntqqapi/types'
import { getConfigUtil } from './config' import { getConfigUtil } from './config'
import { getBuildVersion } from './utils/QQBasicInfo'
export let friends: Friend[] = []
export const llonebotError: LLOneBotError = { export const llonebotError: LLOneBotError = {
ffmpegError: '', ffmpegError: '',
httpServerError: '', httpServerError: '',
wsServerError: '', wsServerError: '',
otherError: 'LLOneBot 未能正常启动,请检查日志查看错误', otherError: 'LLOneBot 未能正常启动,请检查日志查看错误',
} }
// 群号 -> 群成员map(uid=>GroupMember) // 群号 -> 群成员map(uid=>GroupMember)
export const groupMembers: Map<string, Map<string, GroupMember>> = new Map<string, Map<string, GroupMember>>() export const groupMembers: Map<string, Map<string, GroupMember>> = new Map<string, Map<string, GroupMember>>()
export async function getFriend(uinOrUid: string): Promise<Friend | undefined> {
const filterKey: 'uin' | 'uid' = isNumeric(uinOrUid.toString()) ? 'uin' : 'uid'
const filterValue = uinOrUid
let friend = friends.find((friend) => friend[filterKey] === filterValue.toString())
if (!friend && getBuildVersion() < 26702) {
try {
const _friends = await NTQQFriendApi.getFriends(true)
friend = _friends.find((friend) => friend[filterKey] === filterValue.toString())
if (friend) {
friends.push(friend)
}
} catch (e: any) {
log('刷新好友列表失败', e.stack.toString())
}
}
return friend
}
export async function getGroupMember(groupCode: string | number, memberUinOrUid: string | number) { export async function getGroupMember(groupCode: string | number, memberUinOrUid: string | number) {
const groupCodeStr = groupCode.toString() const groupCodeStr = groupCode.toString()
const memberUinOrUidStr = memberUinOrUid.toString() const memberUinOrUidStr = memberUinOrUid.toString()

View File

@ -12,10 +12,12 @@ export interface OB11Config {
enableHttpHeart?: boolean enableHttpHeart?: boolean
enableQOAutoQuote: boolean // 快速操作回复自动引用原消息 enableQOAutoQuote: boolean // 快速操作回复自动引用原消息
} }
export interface CheckVersion { export interface CheckVersion {
result: boolean result: boolean
version: string version: string
} }
export interface Config { export interface Config {
enableLLOB: boolean enableLLOB: boolean
ob11: OB11Config ob11: OB11Config

View File

@ -18,14 +18,14 @@ export class NTQQFriendApi {
buddyList: Friend[] buddyList: Friend[]
}[] }[]
}>({ }>({
methodName: NTMethod.FRIENDS, className: NTClass.NODE_STORE_API,
args: [{ force_update: forced }, undefined], methodName: 'getBuddyList',
cbCmd: ReceiveCmdS.FRIENDS, cbCmd: ReceiveCmdS.FRIENDS,
afterFirstCmd: false, afterFirstCmd: false,
}) })
let _friends: Friend[] = [] const _friends: Friend[] = []
for (const fData of data.data) { for (const item of data.data) {
_friends.push(...fData.buddyList) _friends.push(...item.buddyList)
} }
return _friends return _friends
} }

View File

@ -1,7 +1,7 @@
import { invoke, NTMethod } from '../ntcall' import { invoke, NTMethod } from '../ntcall'
import { GeneralCallResult } from '../services' import { GeneralCallResult } from '../services'
import { User, UserDetailInfoByUin, UserDetailInfoByUinV2, UserDetailInfoListenerArg } from '../types' import { User, UserDetailInfoByUin, UserDetailInfoByUinV2, UserDetailInfoListenerArg } from '../types'
import { friends, groupMembers, getSelfUin } from '@/common/data' import { groupMembers, getSelfUin } from '@/common/data'
import { CacheClassFuncAsync, getBuildVersion } from '@/common/utils' import { CacheClassFuncAsync, getBuildVersion } from '@/common/utils'
import { getSession } from '@/ntqqapi/wrapper' import { getSession } from '@/ntqqapi/wrapper'
import { RequestUtil } from '@/common/utils/request' import { RequestUtil } from '@/common/utils/request'
@ -177,14 +177,6 @@ export class NTQQUserApi {
const session = getSession() const session = getSession()
// 通用转换开始尝试 // 通用转换开始尝试
let uid = (await session?.getUixConvertService().getUid([Uin]))?.uidInfo.get(Uin) let uid = (await session?.getUixConvertService().getUid([Uin]))?.uidInfo.get(Uin)
// Uid 好友转
if (!uid) {
friends.forEach((t) => {
if (t.uin == Uin) {
uid = t.uid
}
})
}
//Uid 群友列表转 //Uid 群友列表转
if (!uid) { if (!uid) {
for (let groupMembersList of groupMembers.values()) { for (let groupMembersList of groupMembers.values()) {
@ -289,14 +281,6 @@ export class NTQQUserApi {
[Uid] [Uid]
) )
let uin = ret.uinInfo.get(Uid) let uin = ret.uinInfo.get(Uid)
if (!uin) {
//从Buddy缓存获取Uin
friends.forEach((t) => {
if (t.uid == Uid) {
uin = t.uin
}
})
}
if (!uin) { if (!uin) {
uin = (await NTQQUserApi.getUserDetailInfo(Uid)).uin //从QQ Native 转换 uin = (await NTQQUserApi.getUserDetailInfo(Uid)).uin //从QQ Native 转换
} }

View File

@ -1,17 +1,16 @@
import type { BrowserWindow } from 'electron' import type { BrowserWindow } from 'electron'
import { NTClass, NTMethod } from './ntcall' import { NTClass, NTMethod } from './ntcall'
import { NTQQMsgApi } from './api/msg' import { NTQQMsgApi, NTQQFriendApi } from './api'
import { import {
CategoryFriend, CategoryFriend,
ChatType, ChatType,
GroupMember, GroupMember,
GroupMemberRole, GroupMemberRole,
RawMessage, RawMessage,
SimpleInfo, User, SimpleInfo,
User
} from './types' } from './types'
import { import {
friends,
getFriend,
getGroupMember, getGroupMember,
setSelfInfo setSelfInfo
} from '@/common/data' } from '@/common/data'
@ -224,116 +223,7 @@ export function removeReceiveHook(id: string) {
receiveHooks.splice(index, 1) receiveHooks.splice(index, 1)
} }
//let activatedGroups: string[] = []
/*async function updateGroups(_groups: Group[], needUpdate: boolean = true) {
for (let group of _groups) {
log('update group', group.groupCode)
if (group.privilegeFlag === 0) {
deleteGroup(group.groupCode)
continue
}
//log('update group', group)
NTQQMsgApi.activateChat({ peerUid: group.groupCode, chatType: ChatType.group }).then().catch(log)
let existGroup = groups.find((g) => g.groupCode == group.groupCode)
if (existGroup) {
Object.assign(existGroup, group)
} else {
groups.push(group)
existGroup = group
}
if (needUpdate) {
const members = await NTQQGroupApi.getGroupMembers(group.groupCode)
if (members) {
existGroup.members = Array.from(members.values())
}
}
}
}*/
/*async function processGroupEvent(payload: { groupList: Group[] }) {
try {
const newGroupList = payload.groupList
for (const group of newGroupList) {
let existGroup = groups.find((g) => g.groupCode == group.groupCode)
if (existGroup) {
if (existGroup.memberCount > group.memberCount) {
log(`群(${group.groupCode})成员数量减少${existGroup.memberCount} -> ${group.memberCount}`)
const oldMembers = existGroup.members
await sleep(200) // 如果请求QQ API的速度过快通常无法正确拉取到最新的群信息因此这里人为引入一个延时
const newMembers = await NTQQGroupApi.getGroupMembers(group.groupCode)
group.members = Array.from(newMembers.values())
const newMembersSet = new Set<string>() // 建立索引降低时间复杂度
for (const member of newMembers) {
newMembersSet.add(member[1].uin)
}
// 判断bot是否是管理员如果是管理员不需要从这里得知有人退群这里的退群无法得知是主动退群还是被踢
const selfUin = getSelfUin()
const bot = await getGroupMember(group.groupCode, selfUin)
if (bot?.role == GroupMemberRole.admin || bot?.role == GroupMemberRole.owner) {
continue
}
for (const member of oldMembers) {
if (!newMembersSet.has(member.uin) && member.uin != selfUin) {
postOb11Event(
new OB11GroupDecreaseEvent(
parseInt(group.groupCode),
parseInt(member.uin),
parseInt(member.uin),
'leave',
),
)
break
}
}
}
if (group.privilegeFlag === 0) {
deleteGroup(group.groupCode)
}
}
}
updateGroups(newGroupList, false).then()
} catch (e: any) {
updateGroups(payload.groupList).then()
log('更新群信息错误', e.stack.toString())
}
}*/
export async function startHook() { export async function startHook() {
// 群列表变动
/*registerReceiveHook<{ groupList: Group[]; updateType: number }>(ReceiveCmdS.GROUPS, (payload) => {
// updateType 3是群列表变动2是群成员变动
// log("群列表变动", payload.updateType, payload.groupList)
if (payload.updateType != 2) {
updateGroups(payload.groupList).then()
}
else {
if (process.platform == 'win32') {
processGroupEvent(payload).then()
}
}
})
registerReceiveHook<{ groupList: Group[]; updateType: number }>(ReceiveCmdS.GROUPS_STORE, (payload) => {
// updateType 3是群列表变动2是群成员变动
// log("群列表变动, store", payload.updateType, payload.groupList)
if (payload.updateType != 2) {
updateGroups(payload.groupList).then()
}
else {
if (process.platform != 'win32') {
processGroupEvent(payload).then()
}
}
})*/
registerReceiveHook<{ registerReceiveHook<{
groupCode: string groupCode: string
dataSource: number dataSource: number
@ -402,13 +292,6 @@ export async function startHook() {
log('好友列表变动', friendList.length) log('好友列表变动', friendList.length)
for (let friend of friendList) { for (let friend of friendList) {
NTQQMsgApi.activateChat({ peerUid: friend.uid, chatType: ChatType.friend }).then() NTQQMsgApi.activateChat({ peerUid: friend.uid, chatType: ChatType.friend }).then()
let existFriend = friends.find((f) => f.uin == friend.uin)
if (!existFriend) {
friends.push(friend)
}
else {
Object.assign(existFriend, friend)
}
} }
}) })
@ -506,12 +389,9 @@ export async function startHook() {
if (isNumeric(peerUid)) { if (isNumeric(peerUid)) {
chatType = ChatType.group chatType = ChatType.group
} }
else { else if (!(await NTQQFriendApi.isBuddy(peerUid))) {
// 检查是否好友
if (!(await getFriend(peerUid))) {
chatType = ChatType.temp chatType = ChatType.temp
} }
}
const peer = { peerUid, chatType } const peer = { peerUid, chatType }
await sleep(1000) await sleep(1000)
NTQQMsgApi.activateChat(peer).then((r) => { NTQQMsgApi.activateChat(peer).then((r) => {

View File

@ -1,7 +1,6 @@
import BaseAction from '../BaseAction' import BaseAction from '../BaseAction'
import { OB11User } from '../../types' import { OB11User } from '../../types'
import { OB11Constructor } from '../../constructor' import { OB11Constructor } from '../../constructor'
import { friends } from '@/common/data'
import { ActionName } from '../types' import { ActionName } from '../types'
import { NTQQFriendApi } from '@/ntqqapi/api' import { NTQQFriendApi } from '@/ntqqapi/api'
import { getBuildVersion } from '@/common/utils/QQBasicInfo' import { getBuildVersion } from '@/common/utils/QQBasicInfo'
@ -14,24 +13,17 @@ export class GetFriendList extends BaseAction<Payload, OB11User[]> {
actionName = ActionName.GetFriendList actionName = ActionName.GetFriendList
protected async _handle(payload: Payload) { protected async _handle(payload: Payload) {
const refresh = payload?.no_cache === true || payload?.no_cache === 'true'
if (getBuildVersion() >= 26702) { if (getBuildVersion() >= 26702) {
return OB11Constructor.friendsV2(await NTQQFriendApi.getBuddyV2(payload?.no_cache === true || payload?.no_cache === 'true')) return OB11Constructor.friendsV2(await NTQQFriendApi.getBuddyV2(refresh))
} }
if (friends.length === 0 || payload?.no_cache === true || payload?.no_cache === 'true') { return OB11Constructor.friends(await NTQQFriendApi.getFriends(refresh))
const _friends = await NTQQFriendApi.getFriends(true)
// log('强制刷新好友列表,结果: ', _friends)
if (_friends.length > 0) {
friends.length = 0
friends.push(..._friends)
}
}
return OB11Constructor.friends(friends)
} }
} }
// extend // extend
export class GetFriendWithCategory extends BaseAction<void, any> { export class GetFriendWithCategory extends BaseAction<void, any> {
actionName = ActionName.GetFriendsWithCategory; actionName = ActionName.GetFriendsWithCategory
protected async _handle(payload: void) { protected async _handle(payload: void) {
if (getBuildVersion() >= 26702) { if (getBuildVersion() >= 26702) {