Miao-Yunzai/plugins/genshin/model/mys/NoteUser.js

373 lines
9.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Bot实际User用户类
* 主键QQ
*
* User可以注册UID通过 getRegUid / setRegUid
* 一个User可以绑定多个MysUser CK绑定MysUser
*/
import BaseModel from './BaseModel.js'
import lodash from 'lodash'
import MysUser from './MysUser.js'
import MysUtil from './MysUtil.js'
import { UserDB } from '../db/index.js'
import { Data } from '#miao'
export default class NoteUser extends BaseModel {
constructor (qq) {
super()
// 检查实例缓存
let cacheObj = this._getThis('user', qq)
if (cacheObj) {
return cacheObj
}
this.qq = qq
return this._cacheThis()
}
get uid () {
console.log('NoteUser.uid 默认返回原神UID可更改为 user.getUid(game)')
return this.getUid()
}
/**
* 当前用户是否具备CK
*/
get hasCk () {
return !lodash.isEmpty(this.mysUsers)
}
/**
* 获取绑定CK的UID列表如未绑定CK则返回空数组
*/
get ckUids () {
if (!this.hasCk) {
return []
}
let ret = []
return lodash.map(this.ckData, 'uid')
}
/**
* 获取当前用户的所有ck
* @returns { {ltuid:{ckData, ck, uids}} }
*/
get cks () {
console.log('NoteUser.cks 即将废弃')
let game = 'gs'
let cks = {}
if (!this.hasCk) {
return cks
}
for (let ltuid in this.mysUsers) {
let mys = this.mysUsers[ltuid]
if (mys && mys.ltuid && mys.uid) {
cks[ltuid] = cks[ltuid] || {
ckData: mys.getCkInfo(game),
ck: mys.ck,
uids: mys.getUids(game)
}
}
}
return cks
}
/**
* 创建NoteUser实例
* @param qq NoterUser对应idqq
* @param db
* * 若传入e对象则会识别e.user_id并将user对象添加至e.user
* @param data 用户对应MysCookie数据为空则自动读取
* @returns {Promise<NoteUser|*>}
*/
static async create (qq, db = false) {
// 兼容处理传入e
if (qq && qq.user_id) {
let e = qq
let user = await NoteUser.create(e.user_id)
e.user = user
return user
}
let user = new NoteUser(qq)
await user.initDB(db)
// 传入data则使用否则读取
return user
}
static async forEach (fn) {
let dbs = await UserDB.findAll()
await Data.forEach(users, async (db) => {
let user = await NoteUser.create(db.id, db)
return await fn(user)
})
}
// 初始化数据
async initDB (db = false) {
if (this.db && !db) {
return
}
// 为后续多类型用户兼容
this.db = db && db !== true ? db : await UserDB.find(this.qq, 'qq')
await this.initMysUser()
this.initUids()
await this.save()
}
// 初始化MysUser对象
async initMysUser () {
let ltuids = this.db?.ltuids || ''
this.mysUsers = {}
for (let ltuid of ltuids.split(',')) {
let mys = await MysUser.create(ltuid)
if (mys) {
this.mysUsers[ltuid] = mys
}
}
}
// 初始化Uid
initUids (setMainUid = {}) {
let self = this
self.mainUid = self.mainUid || {}
self.uidList = {}
self.uidMap = self.uidMap || {}
self.games = {}
const { db, mainUid, uidList, games, uidMap, mysUsers } = self
let gameDBs = {}
lodash.forEach(db?.games, (gameDB) => {
gameDBs[gameDB.game] = gameDB
})
MysUtil.eachGame((key) => {
let gameDB = gameDBs[key]
uidMap[key] = {}
uidList[key] = []
games[key] = gameDB
// 优先设置CK UID
lodash.forEach(mysUsers, (mys) => {
lodash.forEach(mys.uids[key] || [], (uid) => {
uid = uid + ''
if (uid && !uidMap[key][uid]) {
uidMap[key][uid] = { uid, type: 'ck', ltuid: mys.ltuid }
uidList[key].push(uid)
}
})
})
let uidReg = /\d{9}/
let regUidCount = 0
// 存在数据库记录则进行设置
if (gameDB) {
let regUids = gameDB.data
// 依次设置verify、reg uid数据
lodash.forEach(['verify', 'reg'], (uidType) => {
lodash.forEach(regUids, (ds, uid) => {
uid = uid + ''
if (regUidCount <= 5 && uid && uidReg.test(uid) && ds.type === uidType && !uidMap[key][uid]) {
uidMap[key][uid] = { uid, type: ds.type }
uidList[key].push(uid)
regUidCount++
}
})
})
// 如果当前选中uid未在记录中则补充为reg数据
let uid = gameDB.uid
if (uid && !uidMap[key][uid]) {
uid = uid + ''
uidMap[key][uid] = { uid, type: 'reg' }
uidList[key].push(uid)
}
}
// 设置选中uid
if (setMainUid === false || setMainUid[key] === false) {
mainUid[key] = uidList[key]?.[0] || ''
} else {
mainUid[key] = setMainUid[key] || mainUid[key] || gameDB?.uid || uidList[key]?.[0] || ''
}
})
}
async save () {
await this.db.saveDB(this)
}
// 获取当前UID
getUid (game = 'gs') {
let gameKey = this.gameKey(game)
return this.mainUid[gameKey] || this.uidList[gameKey][0] || ''
}
getSelfUid (game = 'gs') {
let gameKey = this.gameKey(game)
let uidList = this.uidMap[gameKey].filter((v) => v.type === 'ck')
if (uidList.length === 0) {
return false
}
let find = lodash.find(uidList, (v) => v.uid + '' === uid + '', 0)
return find ? find.uid : uidList[0].uid
}
// 获取UID列表
getUidList (game = 'gs') {
let ret = []
let gameKey = this.gameKey(game)
lodash.forEach(this.uidList[gameKey], (uid) => {
ret.push(this.uidMap[gameKey][uid])
})
return ret
}
// 获取当前UID数据
getUidData (game = 'gs') {
let gameKey = this.gameKey(game)
let uid = this.getUid(game)
return this.uidMap[gameKey]?.[uid]
}
// 获取当前的MysUser对象
getMysUser (game = 'gs') {
if (lodash.isEmpty(this.mysUsers)) {
return false
}
let uidData = this.getUidData(game)
let ltuid = lodash.keys(this.mysUsers)[0]
if (uidData.type === 'ck') {
ltuid = uidData.ltuid
}
return this.mysUsers[ltuid]
}
// 添加UID
async addRegUid (uid, game = 'gs') {
let gameKey = this.gameKey(game)
uid = uid + ''
if (!this.uidMap[gameKey][uid]) {
this.uidMap[gameKey][uid] = { uid, type: 'reg' }
}
await this.save()
this.setMainUid(uid, game)
// todo 优化保存
await this.save()
}
// 删除UID
async delRegUid (uid, game = 'gs') {
let gameKey = this.gameKey(game)
if (this.uidMap[gameKey][uid] && this.uidMap[gameKey][uid].type !== 'ck') {
lodash.remove(this.uidList[gameKey], (u) => u + '' === uid + '')
delete this.uidMap[gameKey][uid]
}
await this.save()
if (this.mainUid[gameKey] === uid) {
this.setMainUid(this.uidList[gameKey][0], game)
await this.save()
}
}
/**
* 获取当前用户的绑定UID
* 主要供内部调用,建议使用 user.uid 获取用户uid
* @returns {Promise<*>}
*/
async getRegUid (game = 'gs') {
let gameKey = this.gameKey(game)
return this.mainUid[gameKey] || ''
}
/**
* 设置当前用户的绑定uid
* @param uid 要绑定的uid
* @param game
* @param force 若已存在绑定uid关系是否强制更新
*/
async setRegUid (uid = '', game = 'gs', force = false) {
if (this.getRegUid(game) && !force) {
return uid
}
await this.addRegUid(uid, game)
return uid
}
// 切换绑定CK生效的UID
setMainUid (uid = '', game = 'gs') {
let gameKey = this.gameKey(game)
// 兼容传入index
if (uid < 100 && this.uidList[gameKey][uid]) {
uid = this.uidList[gameKey][uid]
}
if (this.uidMap[gameKey][uid]) {
this.mainUid[gameKey] = uid
}
let mainUid = {}
mainUid[gameKey] = uid
this.initUids(mainUid)
}
// 添加MysUser
addMysUser (mysUser) {
this.mysUsers[mysUser.ltuid] = mysUser
this.initUids(mysUser.getMainUid())
}
// 删除当前用户绑定CK
async delCk (ltuid = '') {
console.log('delCk即将废弃')
return await this.delMysUser(ltuid)
}
async delMysUser (ltuid = '') {
if (ltuid && this.mysUsers[ltuid]) {
let mys = this.mysUsers[ltuid]
delete this.mysUsers[ltuid]
await mys.del()
}
this.initUids(false)
await this.save()
}
/**
* 检查当前用户绑定的CK状态
*/
async checkCk () {
// TODO:待完善文案
let cks = this.cks
let ret = []
for (let ltuid in cks) {
let ck = cks[ltuid].ck
if (!ltuid || !ck) {
continue
}
let checkRet = await MysUser.checkCkStatus(ck)
// TODO: 若checkRet中返回了不同的uid进行CK保存更新
// 失效
let mysUser = await MysUser.create(ck)
if (mysUser) {
let status = checkRet.status
if (status === 0 || status === 1) {
// status为1时无法查询天赋但仍可查询角色保留CK
await mysUser.initCache()
} else if (status === 2) {
// status为2时无法查询角色删除ck cache
// 因仍能查询体力故保留ck记录不直接删除
await mysUser.del()
} else if (status === 3) {
// status为3时CK完全失效用户删除此CK
await this.delCk(ltuid)
}
}
ret.push({
ltuid,
...checkRet
})
}
return ret
}
}