2024-08-11 19:42:44 +08:00

313 lines
10 KiB
TypeScript

import { callNTQQApi, GeneralCallResult, NTQQApiClass, NTQQApiMethod } from '../ntcall'
import { SelfInfo, User, UserDetailInfoByUin, UserDetailInfoByUinV2 } from '../types'
import { ReceiveCmdS } from '../hook'
import { friends, groupMembers, getSelfUin } from '@/common/data'
import { CacheClassFuncAsync, log, getBuildVersion } from '@/common/utils'
import { getSession } from '@/ntqqapi/wrapper'
import { RequestUtil } from '@/common/utils/request'
import { NodeIKernelProfileService, UserDetailSource, ProfileBizType } from '../services'
import { NodeIKernelProfileListener } from '../listeners'
import { NTEventDispatch } from '@/common/utils/EventTask'
import { NTQQFriendApi } from './friend'
export class NTQQUserApi {
static async setQQAvatar(filePath: string) {
return await callNTQQApi<GeneralCallResult>({
methodName: NTQQApiMethod.SET_QQ_AVATAR,
args: [
{
path: filePath,
},
null,
],
timeoutSecond: 10, // 10秒不一定够
})
}
static async getSelfInfo() {
return await callNTQQApi<SelfInfo>({
className: NTQQApiClass.GLOBAL_DATA,
methodName: NTQQApiMethod.SELF_INFO,
timeoutSecond: 2,
})
}
static async getUserInfo(uid: string) {
const result = await callNTQQApi<{ profiles: Map<string, User> }>({
methodName: NTQQApiMethod.USER_INFO,
args: [{ force: true, uids: [uid] }, undefined],
cbCmd: ReceiveCmdS.USER_INFO,
})
return result.profiles.get(uid)
}
/** 26702 */
static async fetchUserDetailInfo(uid: string) {
type EventService = NodeIKernelProfileService['fetchUserDetailInfo']
type EventListener = NodeIKernelProfileListener['onUserDetailInfoChanged']
const [_retData, profile] = await NTEventDispatch.CallNormalEvent
<EventService, EventListener>
(
'NodeIKernelProfileService/fetchUserDetailInfo',
'NodeIKernelProfileListener/onUserDetailInfoChanged',
1,
5000,
(profile) => {
if (profile.uid === uid) {
return true
}
return false
},
'BuddyProfileStore',
[
uid
],
UserDetailSource.KSERVER,
[
ProfileBizType.KALL
]
)
const RetUser: User = {
...profile.simpleInfo.coreInfo,
...profile.simpleInfo.status,
...profile.simpleInfo.vasInfo,
...profile.commonExt,
...profile.simpleInfo.baseInfo,
qqLevel: profile.commonExt.qqLevel,
pendantId: ''
}
return RetUser
}
static async getUserDetailInfo(uid: string, getLevel = false, withBizInfo = true) {
if (getBuildVersion() >= 26702) {
return this.fetchUserDetailInfo(uid)
}
type EventService = NodeIKernelProfileService['getUserDetailInfoWithBizInfo']
type EventListener = NodeIKernelProfileListener['onProfileDetailInfoChanged']
const [_retData, profile] = await NTEventDispatch.CallNormalEvent
<EventService, EventListener>
(
'NodeIKernelProfileService/getUserDetailInfoWithBizInfo',
'NodeIKernelProfileListener/onProfileDetailInfoChanged',
2,
5000,
(profile: User) => {
if (profile.uid === uid) {
return true
}
return false
},
uid,
[0]
)
return profile
}
// return 'p_uin=o0xxx; p_skey=orXDssiGF8axxxxxxxxxxxxxx_; skey='
static async getCookieWithoutSkey() {
return await callNTQQApi<string>({
className: NTQQApiClass.GROUP_HOME_WORK,
methodName: NTQQApiMethod.UPDATE_SKEY,
args: [
{
domain: 'qun.qq.com',
},
],
})
}
static async getQzoneCookies() {
const uin = getSelfUin()
const requestUrl = 'https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=' + uin + '&clientkey=' + (await this.getClientKey()).clientKey + '&u1=https%3A%2F%2Fuser.qzone.qq.com%2F' + uin + '%2Finfocenter&keyindex=19%27'
let cookies: { [key: string]: string } = {}
try {
cookies = await RequestUtil.HttpsGetCookies(requestUrl)
} catch (e: any) {
log('获取QZone Cookies失败', e)
cookies = {}
}
return cookies
}
static async getSkey(): Promise<string> {
const clientKeyData = await this.getClientKey()
if (clientKeyData.result !== 0) {
throw new Error('获取clientKey失败')
}
const url = 'https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=' + getSelfUin()
+ '&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
}
@CacheClassFuncAsync(1800 * 1000)
static async getCookies(domain: string) {
const ClientKeyData = await NTQQUserApi.forceFetchClientKey()
const uin = getSelfUin()
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
}
static 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()
}
static async getPSkey(domains: string[]): Promise<Map<string, string>> {
const session = getSession()
const res = await session?.getTipOffService().getPskey(domains, true)
if (res?.result !== 0) {
throw new Error(`获取Pskey失败: ${res?.errMsg}`)
}
return res.domainPskeyMap
}
static async getClientKey() {
const session = getSession()
return await session?.getTicketService().forceFetchClientKey('')!
}
static async like(uid: string, count = 1): Promise<{ result: number, errMsg: string, succCounts: number }> {
const session = getSession()
return session?.getProfileLikeService().setBuddyProfileLike({
friendUid: uid,
sourceId: 71,
doLikeCount: count,
doLikeTollCount: 0
})!
}
static async getUidByUinV1(Uin: string) {
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()) {
for (let GroupMember of groupMembersList.values()) {
if (GroupMember.uin == Uin) {
uid = GroupMember.uid
}
}
}
}
if (!uid) {
let unveifyUid = (await NTQQUserApi.getUserDetailInfoByUin(Uin)).info.uid;//从QQ Native 特殊转换 方法三
if (unveifyUid.indexOf('*') == -1) {
uid = unveifyUid
}
}
return uid
}
static async getUidByUinV2(Uin: string) {
const session = getSession()
let uid = (await session?.getProfileService().getUidByUin('FriendsServiceImpl', [Uin]))?.get(Uin)
if (uid) return uid
uid = (await session?.getGroupService().getUidByUins([Uin]))?.uids.get(Uin)
if (uid) return uid
uid = (await session?.getUixConvertService().getUid([Uin]))?.uidInfo.get(Uin)
if (uid) return uid
console.log((await NTQQFriendApi.getBuddyIdMapCache(true)))
uid = (await NTQQFriendApi.getBuddyIdMapCache(true)).getValue(Uin)//从Buddy缓存获取Uid
if (uid) return uid
uid = (await NTQQFriendApi.getBuddyIdMap(true)).getValue(Uin)
if (uid) return uid
let unveifyUid = (await NTQQUserApi.getUserDetailInfoByUinV2(Uin)).detail.uid//从QQ Native 特殊转换
if (unveifyUid.indexOf('*') == -1) uid = unveifyUid
//if (uid) return uid
return uid
}
static async getUidByUin(Uin: string) {
if (getBuildVersion() >= 26702) {
return await NTQQUserApi.getUidByUinV2(Uin)
}
return await NTQQUserApi.getUidByUinV1(Uin)
}
static async getUserDetailInfoByUinV2(Uin: string) {
return await NTEventDispatch.CallNoListenerEvent
<(Uin: string) => Promise<UserDetailInfoByUinV2>>(
'NodeIKernelProfileService/getUserDetailInfoByUin',
5000,
Uin
)
}
static async getUserDetailInfoByUin(Uin: string) {
return NTEventDispatch.CallNoListenerEvent
<(Uin: string) => Promise<UserDetailInfoByUin>>(
'NodeIKernelProfileService/getUserDetailInfoByUin',
5000,
Uin
)
}
static 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) {
//从Buddy缓存获取Uin
friends.forEach((t) => {
if (t.uid == Uid) {
uin = t.uin
}
})
}
if (!uin) {
uin = (await NTQQUserApi.getUserDetailInfo(Uid)).uin //从QQ Native 转换
}
return uin
}
static async getUinByUidV2(Uid: string) {
const session = getSession()
let uin = (await session?.getProfileService().getUinByUid('FriendsServiceImpl', [Uid]))?.get(Uid)
if (uin) return uin
uin = (await session?.getGroupService().getUinByUids([Uid]))?.uins.get(Uid)
if (uin) return uin
uin = (await session?.getUixConvertService().getUin([Uid]))?.uinInfo.get(Uid)
if (uin) return uin
uin = (await NTQQFriendApi.getBuddyIdMapCache(true)).getKey(Uid) //从Buddy缓存获取Uin
if (uin) return uin
uin = (await NTQQFriendApi.getBuddyIdMap(true)).getKey(Uid)
if (uin) return uin
uin = (await NTQQUserApi.getUserDetailInfo(Uid)).uin //从QQ Native 转换
return uin
}
static async getUinByUid(Uid: string) {
if (getBuildVersion() >= 26702) {
return await NTQQUserApi.getUinByUidV2(Uid)
}
return await NTQQUserApi.getUinByUidV1(Uid)
}
@CacheClassFuncAsync(3600 * 1000, 'ClientKey')
static async forceFetchClientKey() {
const session = getSession()
return await session?.getTicketService().forceFetchClientKey('')!
}
}