mirror of
https://github.com/LLOneBot/LLOneBot.git
synced 2024-11-22 01:56:33 +00:00
323 lines
10 KiB
TypeScript
323 lines
10 KiB
TypeScript
import { invoke, NTMethod } from '../ntcall'
|
|
import { User, UserDetailInfoByUin, UserDetailInfoByUinV2, UserDetailInfoListenerArg } from '../types'
|
|
import { getBuildVersion } from '@/common/utils'
|
|
import { getSession } from '@/ntqqapi/wrapper'
|
|
import { RequestUtil } from '@/common/utils/request'
|
|
import { NodeIKernelProfileService, UserDetailSource, ProfileBizType, forceFetchClientKeyRetType } from '../services'
|
|
import { NodeIKernelProfileListener } from '../listeners'
|
|
import { NTEventDispatch } from '@/common/utils/eventTask'
|
|
import { Time } from 'cosmokit'
|
|
import { Service, Context } from 'cordis'
|
|
import { selfInfo } from '@/common/globalVars'
|
|
|
|
declare module 'cordis' {
|
|
interface Context {
|
|
ntUserApi: NTQQUserApi
|
|
}
|
|
}
|
|
|
|
export class NTQQUserApi extends Service {
|
|
static inject = ['ntFriendApi']
|
|
|
|
constructor(protected ctx: Context) {
|
|
super(ctx, 'ntUserApi', true)
|
|
}
|
|
|
|
async setQQAvatar(path: string) {
|
|
return await invoke(
|
|
NTMethod.SET_QQ_AVATAR,
|
|
[
|
|
{ path },
|
|
null,
|
|
],
|
|
{
|
|
timeout: 10 * Time.second, // 10秒不一定够
|
|
}
|
|
)
|
|
}
|
|
|
|
async fetchUserDetailInfo(uid: string) {
|
|
let info: UserDetailInfoListenerArg
|
|
if (NTEventDispatch.initialised) {
|
|
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',
|
|
afterFirstCmd: false,
|
|
cmdCB: payload => payload.info.uid === uid,
|
|
}
|
|
)
|
|
info = result.info
|
|
}
|
|
const ret: User = {
|
|
...info.simpleInfo.coreInfo,
|
|
...info.simpleInfo.status,
|
|
...info.simpleInfo.vasInfo,
|
|
...info.commonExt,
|
|
...info.simpleInfo.baseInfo,
|
|
qqLevel: info.commonExt?.qqLevel,
|
|
pendantId: ''
|
|
}
|
|
return ret
|
|
}
|
|
|
|
async getUserDetailInfo(uid: string, getLevel = false, withBizInfo = true) {
|
|
if (getBuildVersion() >= 26702) {
|
|
return this.fetchUserDetailInfo(uid)
|
|
}
|
|
if (NTEventDispatch.initialised) {
|
|
type EventService = 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',
|
|
afterFirstCmd: false,
|
|
cmdCB: (payload) => payload.info.uid === uid,
|
|
}
|
|
)
|
|
return result.info
|
|
}
|
|
}
|
|
|
|
async getSkey(): Promise<string> {
|
|
const clientKeyData = await this.forceFetchClientKey()
|
|
if (clientKeyData?.result !== 0) {
|
|
throw new Error('获取clientKey失败')
|
|
}
|
|
const url = 'https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=' + selfInfo.uin
|
|
+ '&clientkey=' + clientKeyData.clientKey
|
|
+ '&u1=https%3A%2F%2Fh5.qzone.qq.com%2Fqqnt%2Fqzoneinpcqq%2Ffriend%3Frefresh%3D0%26clientuin%3D0%26darkMode%3D0&keyindex=' + clientKeyData.keyIndex
|
|
return (await RequestUtil.HttpsGetCookies(url))?.skey
|
|
}
|
|
|
|
async getCookies(domain: string) {
|
|
const clientKeyData = await this.forceFetchClientKey()
|
|
if (clientKeyData?.result !== 0) {
|
|
throw new Error('获取clientKey失败')
|
|
}
|
|
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 cookies: { [key: string]: string } = await RequestUtil.HttpsGetCookies(requestUrl)
|
|
return cookies
|
|
}
|
|
|
|
genBkn(sKey: string) {
|
|
sKey = sKey || ''
|
|
let hash = 5381
|
|
|
|
for (let i = 0; i < sKey.length; i++) {
|
|
const code = sKey.charCodeAt(i)
|
|
hash = hash + (hash << 5) + code
|
|
}
|
|
|
|
return (hash & 0x7fffffff).toString()
|
|
}
|
|
|
|
async like(uid: string, count = 1) {
|
|
const session = getSession()
|
|
if (session) {
|
|
return session.getProfileLikeService().setBuddyProfileLike({
|
|
friendUid: uid,
|
|
sourceId: 71,
|
|
doLikeCount: count,
|
|
doLikeTollCount: 0
|
|
})
|
|
} else {
|
|
return await invoke(
|
|
'nodeIKernelProfileLikeService/setBuddyProfileLike',
|
|
[
|
|
{
|
|
doLikeUserInfo: {
|
|
friendUid: uid,
|
|
sourceId: 71,
|
|
doLikeCount: count,
|
|
doLikeTollCount: 0
|
|
}
|
|
},
|
|
null,
|
|
],
|
|
)
|
|
}
|
|
}
|
|
|
|
async getUidByUinV1(uin: string) {
|
|
const session = getSession()
|
|
// 通用转换开始尝试
|
|
let uid = (await session?.getUixConvertService().getUid([uin]))?.uidInfo.get(uin)
|
|
if (!uid) {
|
|
let unveifyUid = (await this.getUserDetailInfoByUin(uin)).info.uid //从QQ Native 特殊转换 方法三
|
|
if (unveifyUid.indexOf('*') == -1) {
|
|
uid = unveifyUid
|
|
}
|
|
}
|
|
return uid
|
|
}
|
|
|
|
async getUidByUinV2(uin: string) {
|
|
const session = getSession()
|
|
if (session) {
|
|
let uid = (await session.getGroupService().getUidByUins([uin])).uids.get(uin)
|
|
if (uid) return uid
|
|
uid = (await session.getProfileService().getUidByUin('FriendsServiceImpl', [uin])).get(uin)
|
|
if (uid) return uid
|
|
uid = (await session.getUixConvertService().getUid([uin])).uidInfo.get(uin)
|
|
if (uid) return uid
|
|
} else {
|
|
let uid = (await invoke('nodeIKernelGroupService/getUidByUins', [{ uin: [uin] }])).uids.get(uin)
|
|
if (uid) return uid
|
|
uid = (await invoke('nodeIKernelProfileService/getUidByUin', [{ callFrom: 'FriendsServiceImpl', uin: [uin] }])).get(uin)
|
|
if (uid) return uid
|
|
uid = (await invoke('nodeIKernelUixConvertService/getUid', [{ uins: [uin] }])).uidInfo.get(uin)
|
|
if (uid) return uid
|
|
}
|
|
const unveifyUid = (await this.getUserDetailInfoByUinV2(uin)).detail.uid //从QQ Native 特殊转换
|
|
if (unveifyUid.indexOf('*') == -1) return unveifyUid
|
|
}
|
|
|
|
async getUidByUin(uin: string) {
|
|
if (getBuildVersion() >= 26702) {
|
|
return this.getUidByUinV2(uin)
|
|
}
|
|
return this.getUidByUinV1(uin)
|
|
}
|
|
|
|
async getUserDetailInfoByUinV2(uin: string) {
|
|
if (NTEventDispatch.initialised) {
|
|
return await NTEventDispatch.CallNoListenerEvent
|
|
<(Uin: string) => Promise<UserDetailInfoByUinV2>>(
|
|
'NodeIKernelProfileService/getUserDetailInfoByUin',
|
|
5000,
|
|
uin
|
|
)
|
|
} else {
|
|
return await invoke<UserDetailInfoByUinV2>(
|
|
'nodeIKernelProfileService/getUserDetailInfoByUin',
|
|
[
|
|
{ uin },
|
|
null,
|
|
],
|
|
)
|
|
}
|
|
}
|
|
|
|
async getUserDetailInfoByUin(uin: string) {
|
|
return NTEventDispatch.CallNoListenerEvent
|
|
<(Uin: string) => Promise<UserDetailInfoByUin>>(
|
|
'NodeIKernelProfileService/getUserDetailInfoByUin',
|
|
5000,
|
|
uin
|
|
)
|
|
}
|
|
|
|
async getUinByUidV1(uid: string) {
|
|
const ret = await NTEventDispatch.CallNoListenerEvent
|
|
<(Uin: string[]) => Promise<{ uinInfo: Map<string, string> }>>(
|
|
'NodeIKernelUixConvertService/getUin',
|
|
5000,
|
|
[uid]
|
|
)
|
|
let uin = ret.uinInfo.get(uid)
|
|
if (!uin) {
|
|
uin = (await this.getUserDetailInfo(uid)).uin //从QQ Native 转换
|
|
}
|
|
return uin
|
|
}
|
|
|
|
async getUinByUidV2(uid: string) {
|
|
const session = getSession()
|
|
if (session) {
|
|
let uin = (await session.getGroupService().getUinByUids([uid])).uins.get(uid)
|
|
if (uin) return uin
|
|
uin = (await session.getProfileService().getUinByUid('FriendsServiceImpl', [uid])).get(uid)
|
|
if (uin) return uin
|
|
uin = (await session.getUixConvertService().getUin([uid])).uinInfo.get(uid)
|
|
if (uin) return uin
|
|
} else {
|
|
let uin = (await invoke('nodeIKernelGroupService/getUinByUids', [{ uid: [uid] }])).uins.get(uid)
|
|
if (uin) return uin
|
|
uin = (await invoke('nodeIKernelProfileService/getUinByUid', [{ callFrom: 'FriendsServiceImpl', uid: [uid] }])).get(uid)
|
|
if (uin) return uin
|
|
uin = (await invoke('nodeIKernelUixConvertService/getUin', [{ uids: [uid] }])).uinInfo.get(uid)
|
|
if (uin) return uin
|
|
}
|
|
let uin = (await this.ctx.ntFriendApi.getBuddyIdMap(true)).get(uid)
|
|
if (uin) return uin
|
|
uin = (await this.getUserDetailInfo(uid)).uin //从QQ Native 转换
|
|
return uin
|
|
}
|
|
|
|
async getUinByUid(uid: string) {
|
|
if (getBuildVersion() >= 26702) {
|
|
return this.getUinByUidV2(uid)
|
|
}
|
|
return this.getUinByUidV1(uid)
|
|
}
|
|
|
|
async forceFetchClientKey() {
|
|
const session = getSession()
|
|
if (session) {
|
|
return await session.getTicketService().forceFetchClientKey('')
|
|
} else {
|
|
return await invoke('nodeIKernelTicketService/forceFetchClientKey', [{ domain: '' }, null])
|
|
}
|
|
}
|
|
|
|
async getSelfNick(refresh = false) {
|
|
if ((refresh || !selfInfo.nick) && selfInfo.uid) {
|
|
const userInfo = await this.getUserDetailInfo(selfInfo.uid)
|
|
if (userInfo) {
|
|
Object.assign(selfInfo, { nick: userInfo.nick })
|
|
return userInfo.nick
|
|
}
|
|
}
|
|
return selfInfo.nick
|
|
}
|
|
}
|