mirror of
https://github.com/LLOneBot/LLOneBot.git
synced 2024-11-22 01:56:33 +00:00
commit
67d3dfb3cf
@ -5,7 +5,7 @@ LiteLoaderQQNT 插件,实现 OneBot 11 协议,用于 QQ 机器人开发
|
||||
> [!CAUTION]\
|
||||
> **请不要在 QQ 官方群聊和任何影响力较大的简中互联网平台(包括但不限于: 哔哩哔哩,微博,知乎,抖音等)发布和讨论*任何*与本插件存在相关性的信息**
|
||||
|
||||
TG群:<https://t.me/+nLZEnpne-pQ1OWFl>
|
||||
TG 群:<https://t.me/+nLZEnpne-pQ1OWFl>
|
||||
|
||||
## 安装方法
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
"name": "LLOneBot",
|
||||
"slug": "LLOneBot",
|
||||
"description": "实现 OneBot 11 协议,用于 QQ 机器人开发",
|
||||
"version": "3.30.4",
|
||||
"version": "3.30.5",
|
||||
"icon": "./icon.webp",
|
||||
"authors": [
|
||||
{
|
||||
|
@ -25,7 +25,7 @@
|
||||
"fast-xml-parser": "^4.4.1",
|
||||
"file-type": "^19.4.1",
|
||||
"fluent-ffmpeg": "^2.1.3",
|
||||
"minato": "^3.5.0",
|
||||
"minato": "^3.5.1",
|
||||
"silk-wasm": "^3.6.1",
|
||||
"ws": "^8.18.0"
|
||||
},
|
||||
@ -41,5 +41,5 @@
|
||||
"vite": "^5.4.2",
|
||||
"vite-plugin-cp": "^4.0.8"
|
||||
},
|
||||
"packageManager": "yarn@4.4.0"
|
||||
"packageManager": "yarn@4.4.1"
|
||||
}
|
||||
|
@ -5,8 +5,6 @@ import path from 'node:path'
|
||||
import { getSelfUin } from './data'
|
||||
import { DATA_DIR } from './utils'
|
||||
|
||||
//export const HOOK_LOG = false
|
||||
|
||||
export class ConfigUtil {
|
||||
private readonly configPath: string
|
||||
private config: Config | null = null
|
||||
|
@ -1,45 +1,24 @@
|
||||
import {
|
||||
type Friend,
|
||||
type GroupMember,
|
||||
type SelfInfo,
|
||||
} from '../ntqqapi/types'
|
||||
import { type LLOneBotError } from './types'
|
||||
import { NTQQGroupApi } from '../ntqqapi/api/group'
|
||||
import { log } from './utils/log'
|
||||
import { isNumeric } from './utils/helper'
|
||||
import { NTQQFriendApi, NTQQUserApi } from '../ntqqapi/api'
|
||||
import { NTQQUserApi } from '../ntqqapi/api'
|
||||
import { RawMessage } from '../ntqqapi/types'
|
||||
import { getConfigUtil } from './config'
|
||||
import { getBuildVersion } from './utils/QQBasicInfo'
|
||||
|
||||
export let friends: Friend[] = []
|
||||
export const llonebotError: LLOneBotError = {
|
||||
ffmpegError: '',
|
||||
httpServerError: '',
|
||||
wsServerError: '',
|
||||
otherError: 'LLOneBot 未能正常启动,请检查日志查看错误',
|
||||
}
|
||||
|
||||
// 群号 -> 群成员map(uid=>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) {
|
||||
const groupCodeStr = groupCode.toString()
|
||||
const memberUinOrUidStr = memberUinOrUid.toString()
|
||||
|
@ -12,10 +12,12 @@ export interface OB11Config {
|
||||
enableHttpHeart?: boolean
|
||||
enableQOAutoQuote: boolean // 快速操作回复自动引用原消息
|
||||
}
|
||||
|
||||
export interface CheckVersion {
|
||||
result: boolean
|
||||
version: string
|
||||
}
|
||||
|
||||
export interface Config {
|
||||
enableLLOB: boolean
|
||||
ob11: OB11Config
|
||||
|
@ -18,14 +18,14 @@ export class NTQQFriendApi {
|
||||
buddyList: Friend[]
|
||||
}[]
|
||||
}>({
|
||||
methodName: NTMethod.FRIENDS,
|
||||
args: [{ force_update: forced }, undefined],
|
||||
className: NTClass.NODE_STORE_API,
|
||||
methodName: 'getBuddyList',
|
||||
cbCmd: ReceiveCmdS.FRIENDS,
|
||||
afterFirstCmd: false,
|
||||
})
|
||||
let _friends: Friend[] = []
|
||||
for (const fData of data.data) {
|
||||
_friends.push(...fData.buddyList)
|
||||
const _friends: Friend[] = []
|
||||
for (const item of data.data) {
|
||||
_friends.push(...item.buddyList)
|
||||
}
|
||||
return _friends
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { invoke, NTMethod } from '../ntcall'
|
||||
import { GeneralCallResult } from '../services'
|
||||
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 { getSession } from '@/ntqqapi/wrapper'
|
||||
import { RequestUtil } from '@/common/utils/request'
|
||||
@ -177,14 +177,6 @@ export class NTQQUserApi {
|
||||
const session = getSession()
|
||||
// 通用转换开始尝试
|
||||
let uid = (await session?.getUixConvertService().getUid([Uin]))?.uidInfo.get(Uin)
|
||||
// Uid 好友转
|
||||
if (!uid) {
|
||||
friends.forEach((t) => {
|
||||
if (t.uin == Uin) {
|
||||
uid = t.uid
|
||||
}
|
||||
})
|
||||
}
|
||||
//Uid 群友列表转
|
||||
if (!uid) {
|
||||
for (let groupMembersList of groupMembers.values()) {
|
||||
@ -289,14 +281,6 @@ export class NTQQUserApi {
|
||||
[Uid]
|
||||
)
|
||||
let uin = ret.uinInfo.get(Uid)
|
||||
if (!uin) {
|
||||
//从Buddy缓存获取Uin
|
||||
friends.forEach((t) => {
|
||||
if (t.uid == Uid) {
|
||||
uin = t.uin
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!uin) {
|
||||
uin = (await NTQQUserApi.getUserDetailInfo(Uid)).uin //从QQ Native 转换
|
||||
}
|
||||
|
@ -1,17 +1,16 @@
|
||||
import type { BrowserWindow } from 'electron'
|
||||
import { NTClass, NTMethod } from './ntcall'
|
||||
import { NTQQMsgApi } from './api/msg'
|
||||
import { NTQQMsgApi, NTQQFriendApi } from './api'
|
||||
import {
|
||||
CategoryFriend,
|
||||
ChatType,
|
||||
GroupMember,
|
||||
GroupMemberRole,
|
||||
RawMessage,
|
||||
SimpleInfo, User,
|
||||
SimpleInfo,
|
||||
User
|
||||
} from './types'
|
||||
import {
|
||||
friends,
|
||||
getFriend,
|
||||
getGroupMember,
|
||||
setSelfInfo
|
||||
} from '@/common/data'
|
||||
@ -224,116 +223,7 @@ export function removeReceiveHook(id: string) {
|
||||
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() {
|
||||
|
||||
// 群列表变动
|
||||
/*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<{
|
||||
groupCode: string
|
||||
dataSource: number
|
||||
@ -402,13 +292,6 @@ export async function startHook() {
|
||||
log('好友列表变动', friendList.length)
|
||||
for (let friend of friendList) {
|
||||
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,11 +389,8 @@ export async function startHook() {
|
||||
if (isNumeric(peerUid)) {
|
||||
chatType = ChatType.group
|
||||
}
|
||||
else {
|
||||
// 检查是否好友
|
||||
if (!(await getFriend(peerUid))) {
|
||||
chatType = ChatType.temp
|
||||
}
|
||||
else if (!(await NTQQFriendApi.isBuddy(peerUid))) {
|
||||
chatType = ChatType.temp
|
||||
}
|
||||
const peer = { peerUid, chatType }
|
||||
await sleep(1000)
|
||||
|
@ -1,7 +1,6 @@
|
||||
import BaseAction from '../BaseAction'
|
||||
import { OB11User } from '../../types'
|
||||
import { OB11Constructor } from '../../constructor'
|
||||
import { friends } from '@/common/data'
|
||||
import { ActionName } from '../types'
|
||||
import { NTQQFriendApi } from '@/ntqqapi/api'
|
||||
import { getBuildVersion } from '@/common/utils/QQBasicInfo'
|
||||
@ -14,24 +13,17 @@ export class GetFriendList extends BaseAction<Payload, OB11User[]> {
|
||||
actionName = ActionName.GetFriendList
|
||||
|
||||
protected async _handle(payload: Payload) {
|
||||
const refresh = payload?.no_cache === true || payload?.no_cache === 'true'
|
||||
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') {
|
||||
const _friends = await NTQQFriendApi.getFriends(true)
|
||||
// log('强制刷新好友列表,结果: ', _friends)
|
||||
if (_friends.length > 0) {
|
||||
friends.length = 0
|
||||
friends.push(..._friends)
|
||||
}
|
||||
}
|
||||
return OB11Constructor.friends(friends)
|
||||
return OB11Constructor.friends(await NTQQFriendApi.getFriends(refresh))
|
||||
}
|
||||
}
|
||||
|
||||
// extend
|
||||
export class GetFriendWithCategory extends BaseAction<void, any> {
|
||||
actionName = ActionName.GetFriendsWithCategory;
|
||||
actionName = ActionName.GetFriendsWithCategory
|
||||
|
||||
protected async _handle(payload: void) {
|
||||
if (getBuildVersion() >= 26702) {
|
||||
|
@ -1 +1 @@
|
||||
export const version = '3.30.4'
|
||||
export const version = '3.30.5'
|
||||
|
Loading…
x
Reference in New Issue
Block a user