调整ck绑定及uid切换逻辑

This commit is contained in:
Kokomi 2023-06-01 03:28:35 +08:00
parent 8d6efa7666
commit d29e0137c3
12 changed files with 361 additions and 201 deletions

View File

@ -89,10 +89,6 @@ export default class Runtime {
return await MysInfo.getUid(this.e)
}
async getSelfUid () {
return await MysInfo.getSelfUid(this.e)
}
/**
* 获取MysApi实例
*

View File

@ -46,7 +46,8 @@ app.get('/', function (req, res) {
})
app.get('/:page', function (req, res) {
let [plugin, app, page] = req.params.page.split('_')
let [plugin, app, ...page] = req.params.page.split('_')
page = page.join('_')
if (plugin == 'favicon.ico') {
return res.send('')
}
@ -60,12 +61,9 @@ app.get('/:page', function (req, res) {
data.pluResPath = data._res_path
}
let htmlPath = ''
if (data._plugin === 'genshin') {
htmlPath = 'html/'
}
let tplPath = `${app}/${htmlPath}${page}/${page}.html`
if (data._plugin) {
tplPath = `../plugins/${data._plugin}/resources/${htmlPath}/${app}/${page}.html`
tplPath = `../plugins/${data._plugin}/resources/${htmlPath}/${app}/${page.split('_').join('/')}.html`
} else if (data._no_type_path) {
tplPath = `${app}/${page}.html`
}

View File

@ -149,7 +149,7 @@ export class payLog extends plugin {
/** 判断主uid若没有则返回false,有则返回主uid */
async isMain (id, game = 'gs') {
let user = await NoteUser.create(id)
return user.getSelfUid(game)
return user.getCkUid(game)
}
/** 存储数据 */

View File

@ -58,18 +58,10 @@ class UserDB extends BaseModel {
})
db.ltuids = ltuids.join(',')
let games = []
await MysUtil.eachGame(async (key) => {
MysUtil.eachGame((key) => {
let game = user.games[key]
if (!game && (user.mainUid[key] || !lodash.isEmpty(user.uidMap[key]))) {
game = await db.createGame({
game: key
})
}
if (game) {
game.uid = user.mainUid[key]
game.data = user.uidMap[key]
games.push(game)
await game.save()
}
})
if (games.length > 0) {

View File

@ -257,6 +257,24 @@ export default class MysUser extends BaseModel {
}
}
getUidData (uid, game = 'gs') {
game = this.gameKey(game)
if (!this.hasUid(uid, game)) {
return false
}
return {
uid,
type: 'ck',
ltuid: this.ltuid,
game
}
}
hasUid (uid, game = 'gs') {
game = this.gameKey(game)
return this.uids[game].includes(uid + '')
}
getUid (game = 'gs') {
return this.getUids(game)[0]
}
@ -266,13 +284,15 @@ export default class MysUser extends BaseModel {
return this.uids[gameKey] || []
}
getMainUid () {
let ret = {}
let uids = this.uids
MysUtil.eachGame((gameKey) => {
ret[gameKey] = uids[gameKey]?.[0] || ''
getUidInfo () {
let ret = []
MysUtil.eachGame((game, gameDs) => {
let uids = this.getUids(game)
if (uids && uids.length > 0) {
ret.push(`${gameDs.name}】:${uids.join(', ')}`)
}
})
return ret
return ret.join('\n')
}
/**
@ -417,7 +437,8 @@ export default class MysUser extends BaseModel {
}
hasGame (game = 'gs') {
return (this.isGs(game) ? this.gsUids : this.srUids).length > 0
game = this.gameKey(game)
return this.uids[game]?.length > 0
}
// 初始化当前MysUser缓存记录

View File

@ -1,6 +1,6 @@
import { Data } from '#miao'
const games = ['gs', 'sr']
const games = [{ key: 'gs', name: '原神' }, { key: 'sr', name: '星穹铁道' }]
const MysUtil = {
// 获取标准ltuid
@ -8,10 +8,10 @@ const MysUtil = {
if (!data) {
return false
}
if (/^\d{4,9}$/.test(data)) {
if (/^\d{4,10}$/.test(data)) {
return data
}
let testRet = /ltuid=(\d{4,9})/g.exec(data.ck || data)
let testRet = /ltuid=(\d{4,10})/g.exec(data.ck || data)
if (testRet && testRet[1]) {
return testRet[1]
}
@ -38,7 +38,9 @@ const MysUtil = {
// 循环game
async eachGame (fn) {
await Data.forEach(games, fn)
await Data.forEach(games, (ds) => {
return fn(ds.key, ds)
})
},
// 循环server

View File

@ -24,27 +24,20 @@ export default class NoteUser extends BaseModel {
return this._cacheThis()
}
/**
* OLD Func {{
*/
get uid () {
console.log('NoteUser.uid 默认返回原神UID可更改为 user.getUid(game)')
console.warn('NoteUser.uid 默认返回原神UID可更改为 user.getUid(game)')
return this.getUid()
}
/**
* 当前用户是否具备CK
*/
get hasCk () {
return !lodash.isEmpty(this.mysUsers)
}
/**
* 获取绑定CK的UID列表如未绑定CK则返回空数组
*/
// 获取绑定CK的UID列表如未绑定CK则返回空数组
get ckUids () {
if (!this.hasCk) {
return []
}
let ret = []
return lodash.map(this.ckData, 'uid')
console.warn('NoteUser.ckUids 默认返回原神UID可更改为 user.getCkUidList(game)')
let uids = this.getCkUidList('gs')
return lodash.map(uids, (ds) => ds.uid)
}
/**
@ -52,7 +45,7 @@ export default class NoteUser extends BaseModel {
* @returns { {ltuid:{ckData, ck, uids}} }
*/
get cks () {
console.log('NoteUser.cks 即将废弃')
console.warn('NoteUser.cks 即将废弃')
let game = 'gs'
let cks = {}
if (!this.hasCk) {
@ -71,6 +64,16 @@ export default class NoteUser extends BaseModel {
return cks
}
/**
* End OLD Func }}
*/
// 当前用户是否具备CK
get hasCk () {
return !lodash.isEmpty(this.mysUsers)
}
/**
* 创建NoteUser实例
* @param qq NoterUser对应idqq
@ -108,10 +111,13 @@ export default class NoteUser extends BaseModel {
if (this.db && !db) {
return
}
// 为后续多类型用户兼容
this.db = db && db !== true ? db : await UserDB.find(this.qq, 'qq')
if (db && db !== true) {
this.db = db
} else {
this.db = await UserDB.find(this.qq, 'qq')
}
await this.initMysUser()
this.initUids()
await this.initGameDs()
await this.save()
}
@ -128,149 +134,156 @@ export default class NoteUser extends BaseModel {
}
// 初始化Uid
initUids (setMainUid = {}) {
async initGameDs () {
let self = this
self.mainUid = self.mainUid || {}
self.uidList = {}
self.uidMap = self.uidMap || {}
self.games = {}
const { db, mainUid, uidList, games, uidMap, mysUsers } = self
self.games = self.games || {}
const { db, games } = self
let hasChange = false
let gameDBs = {}
lodash.forEach(db?.games, (gameDB) => {
gameDBs[gameDB.game] = gameDB
})
MysUtil.eachGame((key) => {
await MysUtil.eachGame(async (key) => {
let gameDB = gameDBs[key]
uidMap[key] = {}
uidList[key] = []
if (!gameDB) {
gameDB = await db.createGame({
game: key
})
await gameDB.save()
hasChange = true
}
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] || ''
}
})
if (hasChange) {
await this.save()
}
}
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
getUidMapList (game = 'gs', type = 'all') {
if (this._map?.[game]?.[type]) {
return this._map[game][type]
}
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])
game = this.gameKey(game)
let uidMap = {}
let uidList = []
lodash.forEach(this.mysUsers, (mys) => {
if (!mys) {
return
}
lodash.forEach(mys.uids[game] || [], (uid) => {
uid = uid + ''
if (uid && !uidMap[uid]) {
uidMap[uid] = mys.getUidData(uid, game)
uidList.push(uidMap[uid])
}
})
})
return ret
if (type === 'all') {
let gameDs = this.getGameDs(game)
lodash.forEach(gameDs.data, (ds) => {
if (ds.uid && !uidMap[ds.uid]) {
uidMap[ds.uid] = ds
uidList.push(ds)
}
})
}
this._map = this._map || {}
this._map[game] = this._map[game] || {}
this._map[game][type] = {
map: uidMap,
list: uidList
}
return this._map[game][type]
}
// 获取当前UID数据
getUidData (game = 'gs') {
let gameKey = this.gameKey(game)
getUidData (uid = '', game = 'gs') {
if (!uid) {
uid = this.getUid(game)
}
return this.getUidMapList(game, 'all').map[uid]
}
/** 有Uid */
hasUid (uid = '', game = '') {
if (!uid) {
return this.getUidMapList(game, 'all').list?.length > 0
}
return !!this.getUidData(uid, game)
}
/** 获取CK-Uid */
getCkUid (game = 'gs') {
let uid = this.getUid(game)
return this.uidMap[gameKey]?.[uid]
let { map, list } = this.getUidMapList(game, 'ck')
return (map[uid] ? uid : list[0]?.uid) || ''
}
// 获取当前的MysUser对象
/** 获取CK-Uid列表 */
getCkUidList (game = 'gs') {
return this.getUidMapList(game, 'ck').list
}
/** 获取当前UID */
getUid (game = 'gs') {
// todo 刷新uid
return this.getGameDs(game).uid || ''
}
/** 获取UID列表 */
getUidList (game = 'gs') {
return this.getUidMapList(game, 'all').list
}
/** 获取当前的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
let uid = this.getCkUid(game)
if (!uid) {
return false
}
return this.mysUsers[ltuid]
let uidData = this.getUidData(uid, game)
return this.mysUsers[uidData.ltuid]
}
// 添加UID
async addRegUid (uid, game = 'gs') {
let gameKey = this.gameKey(game)
addRegUid (uid, game = 'gs') {
game = this.gameKey(game)
uid = uid + ''
if (!this.uidMap[gameKey][uid]) {
this.uidMap[gameKey][uid] = { uid, type: 'reg' }
let gameDs = this.getGameDs(game)
if (!this.hasUid(uid, game)) {
let dsData = gameDs.data
dsData[uid] = { uid, type: 'reg' }
gameDs.data = dsData
this._map = false
}
await this.save()
this.setMainUid(uid, game)
// todo 优化保存
await this.save()
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]
if (this.mainUid[gameKey] === uid) {
this.mainUid[gameKey] = ''
}
}
await this.save()
if (this.mainUid[gameKey] === '') {
this.setMainUid(this.uidList[gameKey][0], game)
await this.save()
delRegUid (uid, game = 'gs') {
game = this.gameKey(game)
let gameDs = this.getGameDs(game)
let dsData = gameDs.data
delete dsData[uid]
gameDs.data = dsData
this._map = false
if (gameDs.uid === uid) {
this.setMainUid('', game)
}
this.save()
}
/**
@ -279,59 +292,70 @@ export default class NoteUser extends BaseModel {
* @returns {Promise<*>}
*/
async getRegUid (game = 'gs') {
let gameKey = this.gameKey(game)
return this.mainUid[gameKey] || ''
let gameDs = this.getGameDs(game)
return gameDs.uid || ''
}
getGameDs (game = 'gs') {
return this.games[this.gameKey(game)]
}
/**
* 设置当前用户的绑定uid
* @param uid 要绑定的uid
* @param game
* @param force 若已存在绑定uid关系是否强制更新
*/
async setRegUid (uid = '', game = 'gs', force = false) {
if (this.getRegUid(game) && !force) {
autoRegUid (uid = '', game = 'gs') {
if (this.getUid(game)) {
return uid
}
await this.addRegUid(uid, game)
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]
this._map = false
game = this.gameKey(game)
if (uid < 100 || !uid) {
let uids = this.getUidList(game)
uid = (uids[uid] || uids[0]).uid
}
if (this.uidMap[gameKey][uid]) {
this.mainUid[gameKey] = uid
if (this.hasUid(uid, game)) {
let gameDs = this.getGameDs(game)
gameDs.uid = uid
gameDs.save()
}
let mainUid = {}
mainUid[gameKey] = uid
this.initUids(mainUid)
}
// 添加MysUser
addMysUser (mysUser) {
async addMysUser (mysUser) {
this.mysUsers[mysUser.ltuid] = mysUser
this.initUids(mysUser.getMainUid())
this._map = false
MysUtil.eachGame((game) => {
let uid = mysUser.getUid(game)
if (uid) {
this.setMainUid(uid, game)
}
})
await this.save()
}
// 删除当前用户绑定CK
async delCk (ltuid = '') {
console.log('delCk即将废弃')
console.warn('delCk即将废弃')
return await this.delMysUser(ltuid)
}
async delMysUser (ltuid = '') {
async delMysUser (mysUser = '') {
let ltuid = mysUser.ltuid || mysUser
if (ltuid && this.mysUsers[ltuid]) {
let mys = this.mysUsers[ltuid]
delete this.mysUsers[ltuid]
this.mysUsers[ltuid] = false
this._map = false
await mys.del()
}
this.initUids(false)
this._map = false
await this.save()
}

View File

@ -74,8 +74,6 @@ export default class MysInfo {
await MysInfo.initCache()
let user = await NoteUser.create(e)
if (user) {
// 强制读取一次ck防止一些问题
user.initDB(true)
return user
}
return false
@ -91,7 +89,7 @@ export default class MysInfo {
let user = await NoteUser.create(e)
if (e.uid && matchMsgUid) {
/** 没有绑定的自动绑定 */
return await user.setRegUid(e.uid, e, false)
return user.autoRegUid(e.uid, e)
}
let { msg = '', at = '' } = e
@ -118,7 +116,7 @@ export default class MysInfo {
if (!matchMsgUid) uid = user.getUid(e)
if (uid) {
/** 没有绑定的自动绑定 */
return await user.setRegUid(uid, e, false)
return user.autoRegUid(uid, e)
}
if (e.noTips !== true) e.reply('请先#绑定uid', false, { at })

View File

@ -9,6 +9,7 @@ import MysUser from './mys/MysUser.js'
import { promisify } from 'node:util'
import YAML from 'yaml'
import { Data } from '#miao'
import { Player } from '#miao.models'
export default class User extends base {
constructor (e) {
@ -62,7 +63,11 @@ export default class User extends base {
}
// TODO独立的mys数据不走缓存ltuid
let mys = await MysUser.create(param.ltuid)
let mys = await MysUser.create(param.ltuid || param.ltuid_v2 || param.ltmid_v2)
if (!mys) {
await this.e.reply('发送cookie不完整或数据错误')
return
}
let data = {}
data.ck = `ltoken=${param.ltoken};ltuid=${param.ltuid || param.login_uid};cookie_token=${param.cookie_token || param.cookie_token_v2}; account_id=${param.ltuid || param.login_uid};`
let flagV2 = false
@ -97,8 +102,8 @@ export default class User extends base {
let userFullInfo = await mys.getUserFullInfo()
if (userFullInfo?.data?.user_info) {
let userInfo = userFullInfo?.data?.user_info
// this.ltuid = userInfo.uid
// this.ck = `${this.ck}ltuid=${this.ltuid};`
this.ltuid = userInfo.uid || this.ltuid
this.ck = `${this.ck}ltuid=${this.ltuid};`
} else {
logger.mark(`绑定cookie错误2${userFullInfo.message || 'cookie错误'}`)
return await this.e.reply(`绑定cookie失败${userFullInfo.message || 'cookie错误'}`)
@ -113,27 +118,31 @@ export default class User extends base {
logger.mark(`${this.e.logFnc} 保存cookie成功 [ltuid:${mys.ltuid}]`)
let uidMsg = [`绑定cookie成功`]
let uidMsg = [`绑定cookie成功`, mys.getUidInfo()]
await this.e.reply(uidMsg.join('\n'))
let msg = ''
let msg = []
if (mys.hasGame('gs')) {
msg += '原神模块支持:\n【#体力】查询当前树脂'
msg += '\n【#签到】米游社原神自动签到'
msg += '\n【#关闭签到】开启或关闭原神自动签到'
msg += '\n【#原石】查看原石札记'
msg += '\n【#原石统计】原石统计数据'
msg += '\n【#练度统计】技能统计列表'
msg += '\n【#uid】当前绑定ck uid列表'
msg += '\n【#ck】检查当前用户ck是否有效'
msg += '\n【#我的ck】查看当前绑定ck'
msg += '\n【#删除ck】删除当前绑定ck'
msg.push(
'原神模块支持:',
'【#uid】当前绑定ck uid列表',
'【#我的ck】查看当前绑定ck',
'【#删除ck】删除当前绑定ck',
'【#体力】查询当前树脂',
'【#原石】查看原石札记',
'【#原石统计】原石统计数据',
'【#练度统计】技能统计列表',
'【#面板】【#更新面板】面板信息'
)
}
if (mys.hasGame('sr')) {
msg += '\n星穹铁道支持\n功能还在咕咕咕~'
msg.push(
'星穹铁道支持:',
'【*uid】当前绑定ck uid列表',
'【*体力】体力信息',
'【*面板】【*更新面板】面板信息'
)
}
msg += '\n 支持绑定多个ck'
msg = await common.makeForwardMsg(this.e, ['使用命令说明', msg], '绑定成功:使用命令说明')
msg = await common.makeForwardMsg(this.e, ['使用命令说明', msg.join('\n')], '绑定成功:使用命令说明')
await this.e.reply(msg)
}
@ -141,12 +150,17 @@ export default class User extends base {
async delCk () {
let user = await this.user()
// 获取当前uid
let uidData = user.getUidData(this.e)
let uidData = user.getUidData('', this.e)
if (!uidData || uidData.type !== 'ck' || !uidData.ltuid) {
return `删除失败当前的UID${uidData.uid}无CK信息`
return `删除失败当前的UID${uidData?.uid}无CK信息`
}
let mys = await MysUser.create(uidData.ltuid)
if (!mys) {
return `删除失败当前的UID${uidData?.uid}无CK信息`
}
let msg = [`绑定cookie已删除`, mys.getUidInfo()]
await user.delMysUser(uidData.ltuid)
return `绑定cookie已删除`
return msg.join('\n')
}
/** 绑定uid若有ck的话优先使用ck-uid */
@ -200,6 +214,33 @@ export default class User extends base {
await this.e.reply(msg.join('\n'))
}
/** #uid */
async showUid2 () {
let user = await this.user()
let uids = [{
key: 'gs',
name: '原神'
}, {
key: 'sr',
name: '星穹铁道'
}]
lodash.forEach(uids, (ds) => {
ds.uidList = user.getUidList(ds.key)
ds.uid = user.getUid(ds.key)
lodash.forEach(ds.uidList, (uidDs) => {
let player = Player.create(uidDs.uid, ds.key)
if (player) {
uidDs.name = player.name
uidDs.level = player.level
}
})
})
let e = this.e
return e.runtime.render('genshin', 'html/user/uid-list', {
uids
})
}
/** 切换uid */
async toggleUid (index) {
let user = await this.user()

View File

@ -0,0 +1,21 @@
.uid-list {
display: flex;
}
.uid-list .cont {
background: rgba(0, 0, 0, 0.5);
margin: 5px;
width: 50%;
}
.uid-list .cont .cont-body {
background: none;
padding: 0;
}
.uid-list li {
list-style: none;
display: flex;
height: 30px;
line-height: 30px;
margin: 0;
border-radius: 5px;
}
/*# sourceMappingURL=uid-list.css.map */

View File

@ -0,0 +1,39 @@
{{extend elemLayout}}
{{block 'css'}}
<link rel="stylesheet" type="text/css" href="{{_res_path}}/html/user/uid-list.css"/>
{{/block}}
{{block 'main'}}
{{ set gameMap = {
gs:{mark:'#'},
sr:{mark:'*'}
}; }}
<div class="head-box">
<div class="label">111</div>
</div>
<div class="uid-list">
{{each uids game}}
{{set mark = game.key==='gs'? '#':'*'}}
<div class="cont">
<div class="cont-title">{{game.name}}<span><nobr>{{mark}}uid+序号</nobr>切换</span></div>
<div class="cont-body">
{{each game.uidList uid idx}}
<div class="{{game.uid === uid.uid ? 'active':''}}">
<div class="idx">{{idx+1}}</div>
{{if uid.name && uid.level}}
<div>{{uid.name}} (Lv.{{uid.level}})</div>
{{/if}}
<div>
<span class="{{uid.type}}">{{uid.type==='ck'?'CK':'绑定'}}</span>
<span>{{uid.uid}}</span>
</div>
</div>
{{/each}}
</ul>
</div>
</div>
{{/each}}
</div>
{{/block}}

View File

@ -0,0 +1,28 @@
.uid-list {
display: flex;
.cont {
background: rgba(0, 0, 0, 0.5);
margin: 5px;
width: 50%;
.cont-body {
background: none;
padding: 0;
}
}
li {
list-style: none;
display: flex;
height: 30px;
line-height: 30px;
margin: 0;
border-radius: 5px;
strong {
}
}
}