merge dev (#143)
* 初步支持星铁CK绑定及多UID切换 * 重构CK与UID管理逻辑 * 修正user初始化时ltuid记录错误的问题 * 调整用户uid存储的数据库结构 * 修正无CK用户绑定UID无效的问题 * 删除ck、我的ck命令支持 * 在旧数据迁移时备份ck文件 * 修正uid切换无效的问题 * update plugins/genshin/defSet/pool/301.yaml. Signed-off-by: touchscale <11134128+touchscale_admin@user.noreply.gitee.com> * update plugins/genshin/defSet/pool/302.yaml. Signed-off-by: touchscale <11134128+touchscale_admin@user.noreply.gitee.com> * 增加#删除uid 功能,初步修正uid记录的一些问题 --------- Signed-off-by: touchscale <11134128+touchscale_admin@user.noreply.gitee.com> Co-authored-by: touchscale <11134128+touchscale_admin@user.noreply.gitee.com> Co-authored-by: Kokomi <4964418+yoimiya-kokomi@user.noreply.gitee.com>
This commit is contained in:
parent
1233964e78
commit
8488cbc7f2
|
@ -1,3 +1,9 @@
|
|||
# 3.1.0 Dev
|
||||
|
||||
* !!!暂未完成,会有很多错误,不建议升级!!!
|
||||
* 重构CK与UID管理逻辑
|
||||
* 底层对星铁查询进行支持
|
||||
|
||||
# 3.0.2
|
||||
|
||||
* 3.6卡池以及图像武器别名等数据更新 **@cvs**
|
||||
|
|
|
@ -361,7 +361,6 @@ class PluginsLoader {
|
|||
let srReg = /^#?(\*|星铁|星轨|穹轨|星穹|崩铁|星穹铁道|崩坏星穹铁道|铁道)+/
|
||||
let gclink = /\/common\//.test(msg)
|
||||
if (srReg.test(msg) || gclink) {
|
||||
console.log('sr test true')
|
||||
e.isSr = true
|
||||
msg = msg.replace(srReg, '#星铁')
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ export class user extends plugin {
|
|||
fnc: 'noLogin'
|
||||
},
|
||||
{
|
||||
reg: '^#?我的(ck|cookie)$',
|
||||
reg: '^#?(原神|星铁)?我的(ck|cookie)$',
|
||||
event: 'message',
|
||||
fnc: 'myCk'
|
||||
},
|
||||
|
@ -38,7 +38,11 @@ export class user extends plugin {
|
|||
fnc: 'delCk'
|
||||
},
|
||||
{
|
||||
reg: '^#绑定(uid|UID)?[1-9][0-9]{8}$',
|
||||
reg: '^#?(原神|星铁)?(删除|解绑)uid\\s*[0-9]{1,2}$',
|
||||
fnc: 'delUid'
|
||||
},
|
||||
{
|
||||
reg: '^#(原神|星铁)?绑定(uid|UID)?[1-9][0-9]{8}$',
|
||||
fnc: 'bingUid'
|
||||
},
|
||||
{
|
||||
|
@ -146,6 +150,15 @@ export class user extends plugin {
|
|||
}
|
||||
}
|
||||
|
||||
async delUid () {
|
||||
let index = this.e.msg.match(/[0-9]{1,2}$/g)
|
||||
let uidIdx = index && index[0]
|
||||
let game = this.e
|
||||
if (uidIdx) {
|
||||
await this.User.delUid(uidIdx, game)
|
||||
}
|
||||
}
|
||||
|
||||
/** 我的ck */
|
||||
async myCk () {
|
||||
if (this.e.isGroup) {
|
||||
|
@ -157,7 +170,8 @@ export class user extends plugin {
|
|||
|
||||
/** 加载旧的绑定ck json */
|
||||
loadOldData () {
|
||||
this.User.loadOldData()
|
||||
this.User.loadOldDataV2()
|
||||
this.User.loadOldDataV3()
|
||||
}
|
||||
|
||||
/** 检查用户CK状态 **/
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
- from: '2023-05-24 06:00:00'
|
||||
to: '2023-06-13 17:59:59'
|
||||
five:
|
||||
- 宵宫
|
||||
- 八重神子
|
||||
four:
|
||||
- 绮良良
|
||||
- 云堇
|
||||
- 重云
|
||||
name: 焰色天河|华紫樱绯
|
||||
- from: '2023-05-02 18:00:00'
|
||||
to: '2023-05-23 14:59:59'
|
||||
five:
|
||||
|
|
|
@ -1,3 +1,15 @@
|
|||
- from: '2023-05-24 06:00:00'
|
||||
to: '2023-06-13 17:59:59'
|
||||
five:
|
||||
- 飞雷之弦振
|
||||
- 神乐之真意
|
||||
four:
|
||||
- 恶王丸
|
||||
- 笛剑
|
||||
- 匣里灭辰
|
||||
- 流浪乐章
|
||||
- 弓藏
|
||||
name: 神铸赋形
|
||||
- from: '2023-05-02 18:00:00'
|
||||
to: '2023-05-23 14:59:59'
|
||||
five:
|
||||
|
|
|
@ -14,7 +14,7 @@ export default class blueprint extends base {
|
|||
let uid = await MysInfo.getUid(this.e, false)
|
||||
if (!uid) return false
|
||||
/** 判断是否绑定了ck */
|
||||
let ck = await MysInfo.checkUidBing(uid)
|
||||
let ck = await MysInfo.checkUidBing(uid, this.e)
|
||||
if (!ck) {
|
||||
await this.e.reply(MysInfo.tips)
|
||||
return false
|
||||
|
|
|
@ -18,7 +18,7 @@ export default class Calculator extends base {
|
|||
if (!uid) return false
|
||||
|
||||
/** 判断是否绑定了ck */
|
||||
let ck = await MysInfo.checkUidBing(uid)
|
||||
let ck = await MysInfo.checkUidBing(uid, this.e)
|
||||
if (!ck) {
|
||||
await this.e.reply(MysInfo.tips)
|
||||
return false
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
import { Sequelize, DataTypes, Model } from 'sequelize'
|
||||
import { Data } from '#miao'
|
||||
|
||||
Data.createDir('/data/db', 'root')
|
||||
let dbPath = process.cwd() + '/data/db/data.db'
|
||||
|
||||
// TODO DB自定义
|
||||
const sequelize = new Sequelize({
|
||||
dialect: 'sqlite',
|
||||
storage: dbPath,
|
||||
logging: false
|
||||
})
|
||||
|
||||
await sequelize.authenticate()
|
||||
|
||||
export default class BaseModel extends Model {
|
||||
static Types = DataTypes
|
||||
|
||||
static initDB (model, columns) {
|
||||
let name = model.name
|
||||
console.log('Model Name', name)
|
||||
name = name.replace(/DB$/, 's')
|
||||
model.init(columns, { sequelize, tableName: name })
|
||||
model.COLUMNS = columns
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
import BaseModel from './BaseModel.js'
|
||||
|
||||
const { Types } = BaseModel
|
||||
|
||||
const COLUMNS = {
|
||||
// 用户ID,qq为数字
|
||||
ltuid: {
|
||||
type: Types.INTEGER,
|
||||
primaryKey: true
|
||||
},
|
||||
|
||||
// MysUser类型,mys / hoyolab
|
||||
type: {
|
||||
type: Types.STRING,
|
||||
defaultValue: 'mys',
|
||||
notNull: true
|
||||
},
|
||||
|
||||
// CK
|
||||
ck: Types.STRING,
|
||||
device: Types.STRING,
|
||||
uids: {
|
||||
type: Types.STRING,
|
||||
get () {
|
||||
let data = this.getDataValue('uids')
|
||||
let ret = {}
|
||||
try {
|
||||
ret = JSON.parse(data)
|
||||
} catch (e) {
|
||||
ret = {}
|
||||
}
|
||||
return ret
|
||||
},
|
||||
set (uids) {
|
||||
this.setDataValue('uids', JSON.stringify(uids))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MysUserDB extends BaseModel {
|
||||
static async find (ltuid = '', create = false) {
|
||||
// DB查询
|
||||
let mys = await MysUserDB.findByPk(ltuid)
|
||||
if (!mys && create) {
|
||||
mys = await MysUserDB.build({
|
||||
ltuid
|
||||
})
|
||||
}
|
||||
return mys || false
|
||||
}
|
||||
|
||||
async saveDB (mys) {
|
||||
if (!mys.ck || !mys.device || !mys.db) {
|
||||
return false
|
||||
}
|
||||
let db = this
|
||||
this.ck = mys.ck
|
||||
this.type = mys.type
|
||||
this.device = mys.device
|
||||
this.uids = mys.uids
|
||||
await db.save()
|
||||
}
|
||||
}
|
||||
|
||||
BaseModel.initDB(MysUserDB, COLUMNS)
|
||||
await MysUserDB.sync()
|
||||
|
||||
export default MysUserDB
|
|
@ -0,0 +1,85 @@
|
|||
import BaseModel from './BaseModel.js'
|
||||
import lodash from 'lodash'
|
||||
import { UserGameDB } from './index.js'
|
||||
import MysUtil from '../mys/MysUtil.js'
|
||||
|
||||
const { Types } = BaseModel
|
||||
|
||||
const COLUMNS = {
|
||||
// 用户ID,qq为数字
|
||||
id: {
|
||||
type: Types.STRING,
|
||||
autoIncrement: false,
|
||||
primaryKey: true
|
||||
},
|
||||
|
||||
type: {
|
||||
type: Types.STRING,
|
||||
defaultValue: 'qq',
|
||||
notNull: true
|
||||
},
|
||||
|
||||
// 昵称
|
||||
name: Types.STRING,
|
||||
|
||||
// 头像
|
||||
face: Types.STRING,
|
||||
|
||||
ltuids: Types.STRING
|
||||
}
|
||||
|
||||
class UserDB extends BaseModel {
|
||||
static async find (id, type = 'qq') {
|
||||
// user_id
|
||||
id = type === 'qq' ? '' + id : type + id
|
||||
// DB查询
|
||||
let user = await UserDB.findByPk(id, {
|
||||
include: {
|
||||
model: UserGameDB,
|
||||
as: 'games'
|
||||
}
|
||||
})
|
||||
if (!user) {
|
||||
user = await UserDB.build({
|
||||
id,
|
||||
type
|
||||
})
|
||||
}
|
||||
return user
|
||||
}
|
||||
|
||||
async saveDB (user) {
|
||||
let db = this
|
||||
let ltuids = []
|
||||
lodash.forEach(user.mysUsers, (mys) => {
|
||||
if (mys.ck && mys.ltuid) {
|
||||
ltuids.push(mys.ltuid)
|
||||
}
|
||||
})
|
||||
db.ltuids = ltuids.join(',')
|
||||
let games = []
|
||||
await MysUtil.eachGame(async (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) {
|
||||
await this.setGames(games)
|
||||
}
|
||||
await this.save()
|
||||
}
|
||||
}
|
||||
|
||||
BaseModel.initDB(UserDB, COLUMNS)
|
||||
await UserDB.sync()
|
||||
|
||||
export default UserDB
|
|
@ -0,0 +1,43 @@
|
|||
import BaseModel from './BaseModel.js'
|
||||
import lodash from 'lodash'
|
||||
|
||||
const { Types } = BaseModel
|
||||
|
||||
const COLUMNS = {
|
||||
// 用户ID,qq为数字
|
||||
userId: {
|
||||
type: Types.STRING
|
||||
},
|
||||
game: Types.STRING,
|
||||
uid: Types.STRING,
|
||||
data: {
|
||||
type: Types.STRING,
|
||||
get () {
|
||||
let data = this.getDataValue('data')
|
||||
let ret = {}
|
||||
try {
|
||||
data = JSON.parse(data)
|
||||
} catch (e) {
|
||||
data = []
|
||||
}
|
||||
lodash.forEach(data, (ds) => {
|
||||
if (ds.uid) {
|
||||
ret[ds.uid] = ds
|
||||
}
|
||||
})
|
||||
return ret
|
||||
},
|
||||
set (data) {
|
||||
this.setDataValue('data', JSON.stringify(lodash.values(data)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class UserGameDB extends BaseModel {
|
||||
|
||||
}
|
||||
|
||||
BaseModel.initDB(UserGameDB, COLUMNS)
|
||||
await UserGameDB.sync()
|
||||
|
||||
export default UserGameDB
|
|
@ -0,0 +1,24 @@
|
|||
import UserDB from './UserDB.js'
|
||||
import MysUserDB from './MysUserDB.js'
|
||||
import UserGameDB from './UserGameDB.js'
|
||||
|
||||
|
||||
UserDB.belongsToMany(MysUserDB, {
|
||||
through: 'UserLtuids'
|
||||
})
|
||||
MysUserDB.belongsToMany(UserDB, {
|
||||
through: 'UserLtuids'
|
||||
})
|
||||
|
||||
UserDB.hasMany(UserGameDB, {
|
||||
onDelete: 'RESTRICT',
|
||||
onUpdate: 'RESTRICT',
|
||||
foreignKey: 'userId',
|
||||
as: 'games'
|
||||
})
|
||||
UserGameDB.belongsTo(UserDB, {
|
||||
foreignKey: 'userId',
|
||||
as: 'games'
|
||||
})
|
||||
|
||||
export { UserDB, MysUserDB, UserGameDB }
|
|
@ -1,6 +1,8 @@
|
|||
/**
|
||||
* 基础类,提供实例缓存等一些基础方法
|
||||
*/
|
||||
import MysUtil from './MysUtil.js'
|
||||
|
||||
let cacheMap = {}
|
||||
let reFn = {}
|
||||
|
||||
|
@ -12,19 +14,20 @@ export default class BaseModel {
|
|||
// 获取缓存
|
||||
_getThis (model, id = '', time = 10 * 60) {
|
||||
const uuid = `${model}:${id}`
|
||||
this._uuid = uuid
|
||||
if (uuid && cacheMap[uuid]) {
|
||||
return cacheMap[uuid]._expire(time)
|
||||
}
|
||||
this._uuid = uuid
|
||||
}
|
||||
|
||||
// 设置缓存
|
||||
_cacheThis (time = 10 * 60) {
|
||||
let id = this._uuid
|
||||
if (id) {
|
||||
_cacheThis (model, id, time = 10 * 60) {
|
||||
const uuid = this._uuid || `${model}:${id}`
|
||||
this._uuid = uuid
|
||||
if (uuid) {
|
||||
this._expire(time)
|
||||
cacheMap[id] = this
|
||||
return cacheMap[id]
|
||||
cacheMap[uuid] = this
|
||||
return cacheMap[uuid]
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
@ -44,4 +47,23 @@ export default class BaseModel {
|
|||
return cacheMap[id]
|
||||
}
|
||||
}
|
||||
|
||||
_delCache () {
|
||||
let id = this._uuid
|
||||
reFn[id] && clearTimeout(reFn[id])
|
||||
delete reFn[id]
|
||||
delete cacheMap[id]
|
||||
}
|
||||
|
||||
gameKey (game = 'gs') {
|
||||
return MysUtil.getGameKey(game)
|
||||
}
|
||||
|
||||
isGs (game = 'gs') {
|
||||
return this.gameKey(game) === 'gs'
|
||||
}
|
||||
|
||||
isSr (game = 'gs') {
|
||||
return this.gameKey(game) === 'sr'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
import moment from 'moment'
|
||||
import BaseModel from './BaseModel.js'
|
||||
import MysUtil from './MysUtil.js'
|
||||
|
||||
const servs = ['mys', 'hoyolab']
|
||||
// 超时时间不必精确,直接定24小时即可
|
||||
const EX = 3600 * 24
|
||||
const redisKeyRoot = 'Yz:genshin:mys:'
|
||||
const redisKeyRoot = 'Yz:cache:'
|
||||
|
||||
export default class DailyCache extends BaseModel {
|
||||
constructor (uid) {
|
||||
constructor (uid, game = 'config') {
|
||||
super()
|
||||
const storeKey = DailyCache.getStoreKey(uid)
|
||||
const storeKey = DailyCache.getStoreKey(uid, game)
|
||||
// 检查实例缓存
|
||||
let self = this._getThis('store', storeKey)
|
||||
if (self) {
|
||||
|
@ -22,40 +23,28 @@ export default class DailyCache extends BaseModel {
|
|||
/**
|
||||
* 传入UID或server标示,返回当日存储对象
|
||||
* @param uid
|
||||
* @param game
|
||||
* * 为空则返回与serv无关的dailyCache
|
||||
* * 传入UID,会返回UID对应serv的cache对象
|
||||
* * 传入servKey (mys/hoyolab),会返回指定的servCache
|
||||
* @returns {DailyCache}
|
||||
*/
|
||||
static create (uid) {
|
||||
return new DailyCache(uid)
|
||||
}
|
||||
|
||||
/** ---- 基础方法 ---- **/
|
||||
// 内部方法:获取redis表key键值
|
||||
getTableKey (key, sub = '') {
|
||||
if (sub) {
|
||||
return `${this.keyPre}:${key}-${sub}`
|
||||
} else {
|
||||
return `${this.keyPre}:${key}`
|
||||
}
|
||||
}
|
||||
|
||||
// 内部方法:获取server key
|
||||
static getServKey (uid) {
|
||||
// 不传入uid为默认cache
|
||||
if (!uid || uid === 'cache') {
|
||||
return 'cache'
|
||||
}
|
||||
// 传入uid或sever key,判断是mys还是hoyolab
|
||||
return /^[6-9]|^hoyo|^os/i.test(uid) ? servs[1] : servs[0]
|
||||
static create (uid, game = 'config') {
|
||||
return new DailyCache(uid, game)
|
||||
}
|
||||
|
||||
// 内部方法:获取redis表前缀
|
||||
static getStoreKey (uid) {
|
||||
const serv = DailyCache.getServKey(uid)
|
||||
static getStoreKey (uid, game = 'config') {
|
||||
let key
|
||||
if (!uid || game === 'config') {
|
||||
key = 'sys:config'
|
||||
} else {
|
||||
game = MysUtil.getGameKey(game)
|
||||
let serv = /^[6-9]|^hoyo|^os/i.test(uid) ? servs[1] : servs[0]
|
||||
key = `${game}:${serv}`
|
||||
}
|
||||
const date = moment().format('MM-DD')
|
||||
return `${serv}-${date}`
|
||||
return `${key}-${date}`
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -78,8 +67,8 @@ export default class DailyCache extends BaseModel {
|
|||
static async clearOutdatedData () {
|
||||
let keys = await redis.keys(`${redisKeyRoot}*`)
|
||||
const date = moment().format('MM-DD')
|
||||
const testReg = new RegExp(`^${redisKeyRoot}(mys|hoyo|hoyolab|cache)-\\d{2}-\\d{2}`)
|
||||
const todayReg = new RegExp(`^${redisKeyRoot}(mys|hoyo|hoyolab|cache)-${date}`)
|
||||
const testReg = new RegExp(`^${redisKeyRoot}(mys|hoyolab|config)-\\d{2}-\\d{2}`)
|
||||
const todayReg = new RegExp(`^${redisKeyRoot}(mys|hoyolab|config)-${date}`)
|
||||
for (let key of keys) {
|
||||
if (testReg.test(key) && !todayReg.test(key)) {
|
||||
await redis.del(key)
|
||||
|
@ -87,6 +76,47 @@ export default class DailyCache extends BaseModel {
|
|||
}
|
||||
}
|
||||
|
||||
// 内部方法,用于decode value
|
||||
static decodeValue (value, decode = false) {
|
||||
if (value && decode) {
|
||||
try {
|
||||
return JSON.parse(value)
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
// 内部方法,用于encode value
|
||||
static encodeValue (value) {
|
||||
if (typeof (value) === 'object') {
|
||||
return JSON.stringify(value) || ''
|
||||
}
|
||||
if (typeof (value) === 'undefined') {
|
||||
return ''
|
||||
}
|
||||
return '' + value
|
||||
}
|
||||
|
||||
/** ---- 基础方法 ---- **/
|
||||
// 内部方法:获取redis表key键值
|
||||
getTableKey (key, sub = '') {
|
||||
if (sub) {
|
||||
return `${this.keyPre}:${key}-${sub}`
|
||||
} else {
|
||||
return `${this.keyPre}:${key}`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 【基础数据结构】:Key-Value
|
||||
*
|
||||
* 每个key对应一个Value
|
||||
* 使用redis kv存储,所有操作需要指定表名
|
||||
*
|
||||
* **/
|
||||
|
||||
/**
|
||||
* 设置指定表的过期时间
|
||||
* @param table 表
|
||||
|
@ -110,14 +140,6 @@ export default class DailyCache extends BaseModel {
|
|||
await redis.del(this.getTableKey(table, 'count'))
|
||||
}
|
||||
|
||||
/**
|
||||
* 【基础数据结构】:Key-Value
|
||||
*
|
||||
* 每个key对应一个Value
|
||||
* 使用redis kv存储,所有操作需要指定表名
|
||||
*
|
||||
* **/
|
||||
|
||||
/**
|
||||
* 获取表指定key内容
|
||||
* @param table 表名
|
||||
|
@ -176,29 +198,6 @@ export default class DailyCache extends BaseModel {
|
|||
return await redis.set(this.getTableKey(table), value, { EX })
|
||||
}
|
||||
|
||||
// 内部方法,用于decode value
|
||||
static decodeValue (value, decode = false) {
|
||||
if (value && decode) {
|
||||
try {
|
||||
return JSON.parse(value)
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
// 内部方法,用于encode value
|
||||
static encodeValue (value) {
|
||||
if (typeof (value) === 'object') {
|
||||
return JSON.stringify(value) || ''
|
||||
}
|
||||
if (typeof (value) === 'undefined') {
|
||||
return ''
|
||||
}
|
||||
return '' + value
|
||||
}
|
||||
|
||||
/**
|
||||
* 【基础数据结构】:Key-List
|
||||
*
|
||||
|
|
|
@ -9,8 +9,11 @@ import DailyCache from './DailyCache.js'
|
|||
import BaseModel from './BaseModel.js'
|
||||
import NoteUser from './NoteUser.js'
|
||||
import MysApi from './mysApi.js'
|
||||
import MysUtil from './MysUtil.js'
|
||||
import lodash from 'lodash'
|
||||
import fetch from 'node-fetch'
|
||||
import { MysUserDB, UserDB } from '../db/index.js'
|
||||
import { Data } from '../../../miao-plugin/components/index.js'
|
||||
|
||||
const tables = {
|
||||
// ltuid-uid 查询表
|
||||
|
@ -36,9 +39,9 @@ const tables = {
|
|||
}
|
||||
|
||||
export default class MysUser extends BaseModel {
|
||||
constructor (data) {
|
||||
|
||||
constructor (ltuid) {
|
||||
super()
|
||||
let ltuid = data.ltuid
|
||||
if (!ltuid) {
|
||||
return false
|
||||
}
|
||||
|
@ -47,66 +50,33 @@ export default class MysUser extends BaseModel {
|
|||
if (!self) {
|
||||
self = this
|
||||
}
|
||||
// 单日有效缓存,不区分服务器
|
||||
self.cache = self.cache || DailyCache.create()
|
||||
self.uids = self.uids || []
|
||||
self.ltuid = data.ltuid
|
||||
self.ck = self.ck || data.ck
|
||||
self.qq = self.qq || data.qq || 'pub'
|
||||
if (data.uid || data.uids) {
|
||||
self.addUid(data.uid || data.uids)
|
||||
}
|
||||
if (data.ck && data.ltuid) {
|
||||
self.ckData = data
|
||||
}
|
||||
// 单日有效缓存,使用uid区分不同服务器
|
||||
self.servCache = self.servCache || DailyCache.create(self.uids[0] || 'mys')
|
||||
this.ltuid = ltuid
|
||||
return self._cacheThis()
|
||||
}
|
||||
|
||||
// 可传入ltuid、cookie、ck对象来创建MysUser实例
|
||||
// 在仅传入ltuid时,必须是之前传入过的才能被识别
|
||||
static async create (data) {
|
||||
if (!data) {
|
||||
static async create (ltuid, db = false) {
|
||||
ltuid = MysUtil.getLtuid(ltuid)
|
||||
if (!ltuid) {
|
||||
return false
|
||||
}
|
||||
if (lodash.isPlainObject(data)) {
|
||||
return new MysUser(data)
|
||||
}
|
||||
// 传入cookie
|
||||
let testRet = /ltuid=(\d{4,9})/g.exec(data)
|
||||
if (testRet && testRet[1]) {
|
||||
let ltuid = testRet[1]
|
||||
// 尝试使用ltuid创建
|
||||
let ckUser = await MysUser.create(ltuid)
|
||||
if (ckUser) {
|
||||
return ckUser
|
||||
}
|
||||
let uids = await MysUser.getCkUid(data)
|
||||
if (uids) {
|
||||
return new MysUser({
|
||||
ltuid,
|
||||
ck: data,
|
||||
type: 'ck',
|
||||
uids
|
||||
})
|
||||
}
|
||||
}
|
||||
// 传入ltuid
|
||||
if (/^\d{4,9}$/.test(data)) {
|
||||
// 查找ck记录
|
||||
let cache = DailyCache.create()
|
||||
let ckData = await cache.kGet(tables.ck, data, true)
|
||||
if (ckData && ckData.ltuid) {
|
||||
return new MysUser(ckData)
|
||||
}
|
||||
}
|
||||
return false
|
||||
let mys = new MysUser(ltuid)
|
||||
await mys.initDB(db)
|
||||
return mys
|
||||
}
|
||||
|
||||
static async forEach (fn) {
|
||||
let dbs = await MysUserDB.findAll()
|
||||
await Data.forEach(dbs, async (db) => {
|
||||
let mys = await MysUser.create(db.ltuid, db)
|
||||
return await fn(mys)
|
||||
})
|
||||
}
|
||||
|
||||
// 根据uid获取查询MysUser
|
||||
static async getByQueryUid (uid, onlySelfCk = false) {
|
||||
let servCache = DailyCache.create(uid)
|
||||
static async getByQueryUid (uid, game = 'gs', onlySelfCk = false) {
|
||||
let servCache = DailyCache.create(uid, game)
|
||||
// 查找已经查询过的ltuid || 分配最少查询的ltuid
|
||||
|
||||
// 根据ltuid获取mysUser 封装
|
||||
|
@ -120,7 +90,7 @@ export default class MysUser extends BaseModel {
|
|||
}
|
||||
|
||||
// 若声明只获取自己ck,则判断uid是否为本人所有
|
||||
if (onlySelfCk && !await ckUser.ownUid(uid)) {
|
||||
if (onlySelfCk && !ckUser.ownUid(uid, game)) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -148,11 +118,12 @@ export default class MysUser extends BaseModel {
|
|||
}
|
||||
|
||||
static async eachServ (fn) {
|
||||
let servs = ['mys', 'hoyolab']
|
||||
for (let serv of servs) {
|
||||
let servCache = DailyCache.create(serv)
|
||||
await fn(servCache, serv)
|
||||
}
|
||||
await MysUtil.eachServ(async (serv) => {
|
||||
await MysUtil.eachGame(async (game) => {
|
||||
let servCache = DailyCache.create(serv, game)
|
||||
await fn(servCache, serv, game)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 清除当日缓存
|
||||
|
@ -223,106 +194,6 @@ export default class MysUser extends BaseModel {
|
|||
return count
|
||||
}
|
||||
|
||||
static async getGameRole (ck, serv = 'mys') {
|
||||
let url = {
|
||||
mys: 'https://api-takumi.mihoyo.com/binding/api/getUserGameRolesByCookie',
|
||||
hoyolab: 'https://api-os-takumi.mihoyo.com/binding/api/getUserGameRolesByCookie?game_biz=hk4e_global'
|
||||
}
|
||||
|
||||
let res = await fetch(url[serv], { method: 'get', headers: { Cookie: ck } })
|
||||
if (!res.ok) return false
|
||||
res = await res.json()
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// 获取米游社通行证id
|
||||
static async getUserFullInfo (ck, serv = 'mys') {
|
||||
let url = {
|
||||
mys: 'https://bbs-api.mihoyo.com/user/wapi/getUserFullInfo?gids=2',
|
||||
hoyolab: ''
|
||||
}
|
||||
let res = await fetch(url[serv], {
|
||||
method: 'get',
|
||||
headers: {
|
||||
Cookie: ck,
|
||||
Accept: 'application/json, text/plain, */*',
|
||||
Connection: 'keep-alive',
|
||||
Host: 'bbs-api.mihoyo.com',
|
||||
Origin: 'https://m.bbs.mihoyo.com',
|
||||
Referer: ' https://m.bbs.mihoyo.com/'
|
||||
}
|
||||
})
|
||||
if (!res.ok) return res
|
||||
res = await res.json()
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取ck对应uid列表
|
||||
* @param ck 需要获取的ck
|
||||
* @param withMsg false:uids / true: {uids, msg}
|
||||
* @param force 忽略缓存,强制更新
|
||||
* @returns {Promise<{msg: *, uids}>}
|
||||
*/
|
||||
static async getCkUid (ck, withMsg = false, force = false) {
|
||||
let ltuid = ''
|
||||
let testRet = /ltuid=(\w{0,9})/g.exec(ck)
|
||||
if (testRet && testRet[1]) {
|
||||
ltuid = testRet[1]
|
||||
}
|
||||
let uids = []
|
||||
let ret = (msg, retUid) => {
|
||||
retUid = lodash.map(retUid, (a) => a + '')
|
||||
return withMsg ? { msg, uids: retUid } : retUid
|
||||
}
|
||||
if (!ltuid) {
|
||||
return ret('无ltuid', false)
|
||||
}
|
||||
|
||||
if (!force) {
|
||||
// 此处不使用DailyCache,做长期存储
|
||||
uids = await redis.get(`Yz:genshin:mys:ltuid-uids:${ltuid}`)
|
||||
if (uids) {
|
||||
uids = DailyCache.decodeValue(uids, true)
|
||||
if (uids && uids.length > 0) {
|
||||
return ret('', uids)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uids = []
|
||||
let res = null
|
||||
let msg = 'error'
|
||||
for (let serv of ['mys', 'hoyolab']) {
|
||||
let roleRes = await MysUser.getGameRole(ck, serv)
|
||||
if (roleRes?.retcode === 0) {
|
||||
res = roleRes
|
||||
break
|
||||
}
|
||||
if (roleRes.retcode * 1 === -100) {
|
||||
msg = '该ck已失效,请重新登录获取'
|
||||
}
|
||||
msg = roleRes.message || 'error'
|
||||
}
|
||||
if (!res) return ret(msg, false)
|
||||
if (!res.data.list || res.data.list.length <= 0) {
|
||||
return ret('该账号尚未绑定原神或星穹角色', false)
|
||||
}
|
||||
|
||||
for (let val of res.data.list) {
|
||||
if (/\d{9}/.test(val.game_uid) && val.game_biz === 'hk4e_cn') {
|
||||
uids.push(val.game_uid + '')
|
||||
}
|
||||
}
|
||||
if (uids.length > 0) {
|
||||
await redis.set(`Yz:genshin:mys:ltuid-uids:${ltuid}`, JSON.stringify(uids), { EX: 3600 * 24 * 90 })
|
||||
return ret('', uids)
|
||||
}
|
||||
return ret(msg, false)
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查CK状态
|
||||
* @param ck 需要检查的CK
|
||||
|
@ -376,108 +247,228 @@ export default class MysUser extends BaseModel {
|
|||
}
|
||||
}
|
||||
|
||||
// 不建议使用,为了兼容老数据格式,后续废弃
|
||||
getCkInfo (game = 'gs') {
|
||||
let gameKey = this.gameKey(game)
|
||||
return {
|
||||
ck: this.ck,
|
||||
uid: this.getUid(game),
|
||||
qq: '',
|
||||
ltuid: this.ltuid
|
||||
}
|
||||
}
|
||||
|
||||
getUid (game = 'gs') {
|
||||
return this.getUids(game)[0]
|
||||
}
|
||||
|
||||
getUids (game = 'gs') {
|
||||
let gameKey = this.gameKey(game)
|
||||
return this.uids[gameKey] || []
|
||||
}
|
||||
|
||||
getMainUid () {
|
||||
let ret = {}
|
||||
let uids = this.uids
|
||||
MysUtil.eachGame((gameKey) => {
|
||||
ret[gameKey] = uids[gameKey]?.[0] || ''
|
||||
})
|
||||
return ret
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新mysUser的UID列表
|
||||
* @returns {Promise<{msg: string, status: number}>}
|
||||
*/
|
||||
async reqMysUid () {
|
||||
let err = (msg = 'error', status = 1) => {
|
||||
return { status, msg }
|
||||
}
|
||||
|
||||
let res = null
|
||||
let msg = 'error'
|
||||
for (let serv of ['mys', 'hoyolab']) {
|
||||
let roleRes = await this.getGameRole(serv)
|
||||
if (roleRes?.retcode === 0) {
|
||||
res = roleRes
|
||||
if (serv === 'hoyolab') {
|
||||
this.type = 'hoyolab'
|
||||
}
|
||||
break
|
||||
}
|
||||
if (roleRes.retcode * 1 === -100) {
|
||||
msg = '该ck已失效,请重新登录获取'
|
||||
}
|
||||
msg = roleRes.message || 'error'
|
||||
}
|
||||
|
||||
if (!res) return err(msg)
|
||||
let playerList = res?.data?.list || []
|
||||
playerList = playerList.filter(v => ['hk4e_cn', 'hkrpg_cn', 'hk4e_global', 'hkrpg_global'].includes(v.game_biz))
|
||||
if (!playerList || playerList.length <= 0) {
|
||||
return err('该账号尚未绑定原神或星穹角色')
|
||||
}
|
||||
|
||||
this.gsUids = []
|
||||
this.srUids = []
|
||||
|
||||
/** 米游社默认展示的角色 */
|
||||
for (let val of playerList) {
|
||||
this.addUid(val.game_uid, ['hk4e_cn', 'hk4e_global'].includes(val.game_biz) ? 'gs' : 'sr')
|
||||
}
|
||||
await this.save()
|
||||
return { status: 0, msg: '' }
|
||||
}
|
||||
|
||||
async getGameRole (serv = 'mys') {
|
||||
let ck = this.ck
|
||||
let url = {
|
||||
mys: 'https://api-takumi.mihoyo.com/binding/api/getUserGameRolesByCookie',
|
||||
hoyolab: 'https://api-os-takumi.mihoyo.com/binding/api/getUserGameRolesByCookie'
|
||||
}
|
||||
|
||||
let res = await fetch(url[serv], { method: 'get', headers: { Cookie: ck } })
|
||||
if (!res.ok) return false
|
||||
res = await res.json()
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// 获取米游社通行证id
|
||||
async getUserFullInfo (serv = 'mys') {
|
||||
let ck = this.ck
|
||||
let url = {
|
||||
mys: 'https://bbs-api.mihoyo.com/user/wapi/getUserFullInfo?gids=2',
|
||||
hoyolab: ''
|
||||
}
|
||||
let res = await fetch(url[serv], {
|
||||
method: 'get',
|
||||
headers: {
|
||||
Cookie: ck,
|
||||
Accept: 'application/json, text/plain, */*',
|
||||
Connection: 'keep-alive',
|
||||
Host: 'bbs-api.mihoyo.com',
|
||||
Origin: 'https://m.bbs.mihoyo.com',
|
||||
Referer: ' https://m.bbs.mihoyo.com/'
|
||||
}
|
||||
})
|
||||
if (!res.ok) return res
|
||||
res = await res.json()
|
||||
return res
|
||||
}
|
||||
|
||||
getCache (game = 'gs') {
|
||||
if (!this.cache) {
|
||||
this.cache = {}
|
||||
}
|
||||
const { cache } = this
|
||||
if (game !== 'config') {
|
||||
game = this.gameKey(game)
|
||||
}
|
||||
if (!cache[game]) {
|
||||
cache[game] = DailyCache.create(this.type, game)
|
||||
}
|
||||
return cache[game]
|
||||
}
|
||||
|
||||
|
||||
// 初始化数据
|
||||
async initDB (db = false) {
|
||||
if (this.db && !db) {
|
||||
return
|
||||
}
|
||||
db = db && db !== true ? db : await MysUserDB.find(this.ltuid, true)
|
||||
this.db = db
|
||||
this.setCkData(db)
|
||||
}
|
||||
|
||||
// 设置ck数据
|
||||
setCkData (data = {}) {
|
||||
this.ck = data.ck || this.ck || ''
|
||||
this.type = data.type || this.type || 'mys'
|
||||
this.device = data.device || this.device || MysUtil.getDeviceGuid()
|
||||
this.uids = this.uids || {}
|
||||
let self = this
|
||||
MysUtil.eachGame((game) => {
|
||||
self.uids[game] = data?.uids?.[game] || self.uids[game] || []
|
||||
})
|
||||
}
|
||||
|
||||
async save () {
|
||||
await this.db.saveDB(this)
|
||||
}
|
||||
|
||||
// 为当前MysUser绑定uid
|
||||
addUid (uid) {
|
||||
addUid (uid, game = 'gs') {
|
||||
if (lodash.isArray(uid)) {
|
||||
for (let u of uid) {
|
||||
this.addUid(u)
|
||||
this.addUid(u, game)
|
||||
}
|
||||
return true
|
||||
}
|
||||
uid = '' + uid
|
||||
if (/\d{9}/.test(uid) || uid === 'pub') {
|
||||
if (!this.uids.includes(uid)) {
|
||||
this.uids.push(uid)
|
||||
if (/\d{9}/.test(uid)) {
|
||||
let gameKey = this.gameKey(game)
|
||||
let uids = this.uids[gameKey]
|
||||
if (!uids.includes(uid)) {
|
||||
uids.push(uid)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
hasGame (game = 'gs') {
|
||||
return (this.isGs(game) ? this.gsUids : this.srUids).length > 0
|
||||
}
|
||||
|
||||
// 初始化当前MysUser缓存记录
|
||||
async initCache (user) {
|
||||
if (!this.ltuid || !this.servCache || !this.ck) {
|
||||
async initCache () {
|
||||
if (!this.ltuid || !this.ck) {
|
||||
return
|
||||
}
|
||||
|
||||
// 为当前MysUser添加uid查询记录
|
||||
if (!lodash.isEmpty(this.uids)) {
|
||||
for (let uid of this.uids) {
|
||||
if (uid !== 'pub') {
|
||||
await this.addQueryUid(uid)
|
||||
// 添加ltuid-uid记录,用于判定ltuid绑定个数及自ltuid查询
|
||||
await this.cache.zAdd(tables.uid, this.ltuid, uid)
|
||||
let self = this
|
||||
await MysUtil.eachGame(async (game) => {
|
||||
let uids = self.uids[game]
|
||||
await this.addQueryUid(uids, game)
|
||||
let cache = self.getCache(game)
|
||||
let cacheSearchList = await cache.get(tables.del, this.ltuid, true)
|
||||
// 这里不直接插入,只插入当前查询记录中没有的值
|
||||
if (cacheSearchList && cacheSearchList.length > 0) {
|
||||
for (let searchedUid of cacheSearchList) {
|
||||
// 检查对应uid是否有新的查询记录
|
||||
if (!await this.getQueryLtuid(searchedUid, game)) {
|
||||
await this.addQueryUid(searchedUid, game)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log(`ltuid:${this.ltuid}暂无uid信息,请检查...`)
|
||||
// 公共ck暂无uid信息不添加
|
||||
if (user?.qq === 'pub') {
|
||||
return false
|
||||
}
|
||||
}
|
||||
// 缓存ckData,供后续缓存使用
|
||||
// ltuid关系存储到与server无关的cache中,方便后续检索
|
||||
if (this.ckData && this.ckData.ck) {
|
||||
await this.cache.kSet(tables.ck, this.ltuid, this.ckData)
|
||||
}
|
||||
|
||||
// 缓存qq,用于删除ltuid时查找
|
||||
if (user && user.qq) {
|
||||
let qq = user.qq === 'pub' ? 'pub' : user.qq * 1
|
||||
let qqArr = await this.cache.kGet(tables.qq, this.ltuid, true)
|
||||
if (!lodash.isArray(qqArr)) {
|
||||
qqArr = []
|
||||
}
|
||||
if (!qqArr.includes(qq)) {
|
||||
qqArr.push(qq)
|
||||
await this.cache.kSet(tables.qq, this.ltuid, qqArr)
|
||||
}
|
||||
}
|
||||
|
||||
// 从删除记录中查找并恢复查询记录
|
||||
let cacheSearchList = await this.servCache.get(tables.del, this.ltuid, true)
|
||||
// 这里不直接插入,只插入当前查询记录中没有的值
|
||||
if (cacheSearchList && cacheSearchList.length > 0) {
|
||||
for (let searchedUid of cacheSearchList) {
|
||||
// 检查对应uid是否有新的查询记录
|
||||
if (!await this.getQueryLtuid(searchedUid)) {
|
||||
await this.addQueryUid(searchedUid)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
async disable () {
|
||||
await this.servCache.zDel(tables.detail, this.ltuid)
|
||||
logger.mark(`[标记无效ck][ltuid:${this.ltuid}]`)
|
||||
async disable (game = 'gs') {
|
||||
let cache = this.getCache(game)
|
||||
await cache.zDel(tables.detail, this.ltuid)
|
||||
logger.mark(`[标记无效ck][game:${game}, ltuid:${this.ltuid}`)
|
||||
}
|
||||
|
||||
//
|
||||
/**
|
||||
* 删除缓存, 供User解绑CK时调用
|
||||
* @param user
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
async del (user) {
|
||||
if (user && user.qq) {
|
||||
let qqList = await this.cache.kGet(tables.qq, this.ltuid, true)
|
||||
let newList = lodash.pull(qqList, user.qq * 1)
|
||||
await this.cache.kSet(tables.qq, this.ltuid, newList)
|
||||
if (newList.length > 0) {
|
||||
// 如果数组还有其他元素,说明该ltuid还有其他绑定,不进行缓存删除
|
||||
return false
|
||||
}
|
||||
}
|
||||
async del () {
|
||||
// TODO 检查一ltuid多绑定的情况
|
||||
// 将查询过的uid缓存起来,以备后续重新绑定时恢复
|
||||
let uids = await this.getQueryUids()
|
||||
await this.servCache.set(tables.del, uids)
|
||||
|
||||
// 标记ltuid为失效
|
||||
await this.servCache.zDel(tables.detail, this.ltuid)
|
||||
await this.cache.zDel(tables.uid, this.ltuid)
|
||||
await this.cache.kDel(tables.ck, this.ltuid)
|
||||
await this.cache.kDel(tables.qq, this.ltuid)
|
||||
let self = this
|
||||
await MysUtil.eachGame(async (game) => {
|
||||
let uids = await this.getQueryUids(game)
|
||||
let cache = self.getCache(game)
|
||||
await cache.set(tables.del, uids)
|
||||
// 标记ltuid为失效
|
||||
await cache.zDel(tables.detail, this.ltuid)
|
||||
})
|
||||
await self.db.destroy()
|
||||
self._delCache()
|
||||
logger.mark(`[删除失效ck][ltuid:${this.ltuid}]`)
|
||||
}
|
||||
|
||||
|
@ -498,28 +489,38 @@ export default class MysUser extends BaseModel {
|
|||
}
|
||||
|
||||
// 为当前用户添加uid查询记录
|
||||
async addQueryUid (uid) {
|
||||
async addQueryUid (uid, game = 'gs') {
|
||||
if (lodash.isArray(uid)) {
|
||||
for (let u of uid) {
|
||||
await this.addQueryUid(u, game)
|
||||
}
|
||||
return
|
||||
}
|
||||
if (uid) {
|
||||
await this.servCache.zAdd(tables.detail, this.ltuid, uid)
|
||||
let cache = this.getCache(game)
|
||||
await cache.zAdd(tables.detail, this.ltuid, uid)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取当前用户已查询uid列表
|
||||
async getQueryUids () {
|
||||
return await this.servCache.zList(tables.detail, this.ltuid)
|
||||
async getQueryUids (game = 'gs') {
|
||||
let cache = this.getCache(game)
|
||||
return await cache.zList(tables.detail, this.ltuid)
|
||||
}
|
||||
|
||||
// 根据uid获取查询ltuid
|
||||
async getQueryLtuid (uid) {
|
||||
return await this.servCache.zKey(tables.detail, uid)
|
||||
async getQueryLtuid (uid, game = 'gs') {
|
||||
let cache = this.getCache(game)
|
||||
return await cache.zKey(tables.detail, uid)
|
||||
}
|
||||
|
||||
// 检查指定uid是否为当前MysUser所有
|
||||
async ownUid (uid) {
|
||||
ownUid (uid, game = 'gs') {
|
||||
if (!uid) {
|
||||
return false
|
||||
}
|
||||
let uidArr = await this.cache.zList(tables.uid, this.ltuid) || []
|
||||
return uid && uidArr.join(',').split(',').includes(uid + '')
|
||||
let gameKey = this.gameKey(game)
|
||||
let uids = this.uids[gameKey]
|
||||
return uids.includes(uid + '')
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
import { Data } from '#miao'
|
||||
|
||||
const games = ['gs', 'sr']
|
||||
|
||||
const MysUtil = {
|
||||
// 获取标准ltuid
|
||||
getLtuid (data) {
|
||||
if (!data) {
|
||||
return false
|
||||
}
|
||||
if (/^\d{4,9}$/.test(data)) {
|
||||
return data
|
||||
}
|
||||
let testRet = /ltuid=(\d{4,9})/g.exec(data.ck || data)
|
||||
if (testRet && testRet[1]) {
|
||||
return testRet[1]
|
||||
}
|
||||
return false
|
||||
},
|
||||
|
||||
// 获取标准gameKey
|
||||
getGameKey (game) {
|
||||
// 兼容e的处理
|
||||
if (game.user_id) {
|
||||
return game.isSr ? 'sr' : 'gs'
|
||||
}
|
||||
return ['sr', 'star'].includes(game) ? 'sr' : 'gs'
|
||||
},
|
||||
|
||||
// 生成设备guid
|
||||
getDeviceGuid () {
|
||||
function S4 () {
|
||||
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
|
||||
}
|
||||
|
||||
return (S4() + S4() + '-' + S4() + '-' + S4() + '-' + S4() + '-' + S4() + S4() + S4())
|
||||
},
|
||||
|
||||
// 循环game
|
||||
async eachGame (fn) {
|
||||
await Data.forEach(games, fn)
|
||||
},
|
||||
|
||||
// 循环server
|
||||
async eachServ (fn) {
|
||||
await Data.forEach(['mys', 'hoyolab'], fn)
|
||||
}
|
||||
}
|
||||
export default MysUtil
|
|
@ -8,10 +8,12 @@
|
|||
import BaseModel from './BaseModel.js'
|
||||
import lodash from 'lodash'
|
||||
import MysUser from './MysUser.js'
|
||||
import gsCfg from '../gsCfg.js'
|
||||
import MysUtil from './MysUtil.js'
|
||||
import { UserDB } from '../db/index.js'
|
||||
import { Data } from '#miao'
|
||||
|
||||
export default class NoteUser extends BaseModel {
|
||||
constructor (qq, data = null) {
|
||||
constructor (qq) {
|
||||
super()
|
||||
// 检查实例缓存
|
||||
let cacheObj = this._getThis('user', qq)
|
||||
|
@ -19,77 +21,19 @@ export default class NoteUser extends BaseModel {
|
|||
return cacheObj
|
||||
}
|
||||
this.qq = qq
|
||||
if (data) {
|
||||
this.ckData = this.ckData || {}
|
||||
for (let uid in data) {
|
||||
let ck = data[uid]
|
||||
if (uid && ck.uid) {
|
||||
this.ckData[uid] = ck
|
||||
}
|
||||
}
|
||||
} else if (!this.ckData) {
|
||||
this._getCkData()
|
||||
}
|
||||
// 缓存实例
|
||||
return this._cacheThis()
|
||||
}
|
||||
|
||||
// 初始化 user
|
||||
/**
|
||||
* 创建NoteUser实例
|
||||
* @param qq NoterUser对应id(qq)
|
||||
* * 若传入e对象则会识别e.user_id,并将user对象添加至e.user
|
||||
* @param data 用户对应MysCookie数据,为空则自动读取
|
||||
* @returns {Promise<NoteUser|*>}
|
||||
*/
|
||||
static async create (qq, data = null) {
|
||||
// 兼容处理传入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, data)
|
||||
// 检查绑定uid (regUid)
|
||||
await user.getRegUid()
|
||||
// 传入data则使用,否则读取
|
||||
return user
|
||||
}
|
||||
|
||||
static async forEach (fn) {
|
||||
// 初始化用户缓存
|
||||
let res = await gsCfg.getBingCk()
|
||||
for (let qq in res.noteCk) {
|
||||
let cks = res.noteCk[qq]
|
||||
if (!lodash.isEmpty(cks)) {
|
||||
let user = await NoteUser.create(qq, cks)
|
||||
if (user && fn) {
|
||||
if (await fn(user) === false) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户uid
|
||||
* 如果为绑定用户,优先获取ck对应uid,否则获取绑定uid
|
||||
*/
|
||||
get uid () {
|
||||
// 如果绑定有CK,则
|
||||
if (this.hasCk) {
|
||||
return this.mainCk?.uid
|
||||
}
|
||||
return this._regUid || ''
|
||||
console.log('NoteUser.uid 默认返回原神UID,可更改为 user.getUid(game)')
|
||||
return this.getUid()
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前用户是否具备CK
|
||||
*/
|
||||
get hasCk () {
|
||||
return this.ckData && !lodash.isEmpty(this.ckData)
|
||||
return !lodash.isEmpty(this.mysUsers)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -99,159 +43,293 @@ export default class NoteUser extends BaseModel {
|
|||
if (!this.hasCk) {
|
||||
return []
|
||||
}
|
||||
let ret = []
|
||||
return lodash.map(this.ckData, 'uid')
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前生效CK
|
||||
*
|
||||
* 返回isMain的uid,没有的话返回首位
|
||||
*/
|
||||
get mainCk () {
|
||||
if (this.hasCk) {
|
||||
return lodash.filter(this.ckData, (ck) => ck.isMain)[0] || lodash.values(this.ckData)[0]
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户的所有ck
|
||||
* @returns { {ltuid:{ckData, ck, uids}} }
|
||||
*/
|
||||
get cks () {
|
||||
console.log('NoteUser.cks 即将废弃')
|
||||
let game = 'gs'
|
||||
let cks = {}
|
||||
if (!this.hasCk) {
|
||||
return cks
|
||||
}
|
||||
for (let uid in this.ckData) {
|
||||
let ck = this.ckData[uid]
|
||||
if (ck && ck.ltuid && ck.uid) {
|
||||
cks[ck.ltuid] = cks[ck.ltuid] || {
|
||||
ckData: ck,
|
||||
ck: ck.ck,
|
||||
uids: []
|
||||
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)
|
||||
}
|
||||
cks[ck.ltuid].uids.push(ck.uid)
|
||||
}
|
||||
}
|
||||
return cks
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建NoteUser实例
|
||||
* @param qq NoterUser对应id(qq)
|
||||
* @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 (redisKey = `Yz:genshin:mys:qq-uid:${this.qq}`) {
|
||||
let uid = await redis.get(redisKey)
|
||||
if (uid) {
|
||||
await redis.setEx(redisKey, 3600 * 24 * 30, uid)
|
||||
}
|
||||
this._regUid = uid
|
||||
return this._regUid
|
||||
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 = '', force = false) {
|
||||
let redisKey = `Yz:genshin:mys:qq-uid:${this.qq}`
|
||||
if (uid && /[1|2|5-9][0-9]{8}/.test(uid)) {
|
||||
uid = String(uid)
|
||||
const oldUid = await this.getRegUid()
|
||||
// force true、不存在绑定UID,UID一致时存储并更新有效期
|
||||
if (force || !oldUid || oldUid === uid) {
|
||||
await redis.setEx(redisKey, 3600 * 24 * 30, uid)
|
||||
}
|
||||
this._regUid = uid
|
||||
return String(this._regUid) || ''
|
||||
async setRegUid (uid = '', game = 'gs', force = false) {
|
||||
if (this.getRegUid(game) && !force) {
|
||||
return uid
|
||||
}
|
||||
return ''
|
||||
await this.addRegUid(uid, game)
|
||||
return uid
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换绑定CK生效的UID
|
||||
* @param uid 要切换的UID
|
||||
*/
|
||||
async setMainUid (uid = '') {
|
||||
// 切换绑定CK生效的UID
|
||||
setMainUid (uid = '', game = 'gs') {
|
||||
let gameKey = this.gameKey(game)
|
||||
// 兼容传入index
|
||||
if (uid * 1 <= this.ckUids.length) uid = this.ckUids[uid]
|
||||
// 非法值,以及未传入时使用当前或首个有效uid
|
||||
uid = (uid || this.uid) * 1
|
||||
// 设置主uid
|
||||
lodash.forEach(this.ckData, (ck) => {
|
||||
ck.isMain = ck.uid * 1 === uid * 1
|
||||
})
|
||||
// 保存CK数据
|
||||
this._saveCkData()
|
||||
await this.setRegUid(uid, true)
|
||||
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)
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化或重置 当前用户缓存
|
||||
*/
|
||||
async initCache () {
|
||||
// 刷新绑定CK的缓存
|
||||
let count = 0
|
||||
let cks = this.cks
|
||||
for (let ltuid in cks) {
|
||||
let { ckData, uids } = cks[ltuid]
|
||||
let mysUser = await MysUser.create(ckData)
|
||||
for (let uid of uids) {
|
||||
mysUser.addUid(uid)
|
||||
}
|
||||
if (mysUser && await mysUser.initCache(this)) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
// 添加MysUser
|
||||
addMysUser (mysUser) {
|
||||
this.mysUsers[mysUser.ltuid] = mysUser
|
||||
this.initUids(mysUser.getMainUid())
|
||||
}
|
||||
|
||||
/**
|
||||
* 为当前用户增加CK
|
||||
* @param cks 绑定的ck
|
||||
*/
|
||||
async addCk (cks) {
|
||||
let ckData = this.ckData
|
||||
lodash.forEach(cks, (ck, uid) => {
|
||||
ckData[uid] = ck
|
||||
})
|
||||
this._saveCkData()
|
||||
await this.initCache()
|
||||
// 删除当前用户绑定CK
|
||||
async delCk (ltuid = '') {
|
||||
console.log('delCk即将废弃')
|
||||
return await this.delMysUser(ltuid)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除当前用户绑定CK
|
||||
* @param ltuid 根据ltuid删除,未传入则删除当前生效uid对应ltuid
|
||||
* @param needRefreshCache 是否需要刷新cache,默认刷新
|
||||
*/
|
||||
async delCk (ltuid = '', needRefreshCache = true) {
|
||||
if (!ltuid) {
|
||||
ltuid = this.mainCk.ltuid
|
||||
async delMysUser (ltuid = '') {
|
||||
if (ltuid && this.mysUsers[ltuid]) {
|
||||
let mys = this.mysUsers[ltuid]
|
||||
delete this.mysUsers[ltuid]
|
||||
await mys.del()
|
||||
}
|
||||
let ret = []
|
||||
ltuid = ltuid * 1
|
||||
let ckData = this.ckData
|
||||
for (let uid in ckData) {
|
||||
let ck = ckData[uid]
|
||||
if (ltuid && ck.ltuid * 1 === ltuid) {
|
||||
ret.push(uid)
|
||||
delete ckData[uid]
|
||||
}
|
||||
}
|
||||
// 刷新主ck并保存ckData
|
||||
await this.setMainUid()
|
||||
|
||||
// 刷新MysUser缓存
|
||||
if (needRefreshCache) {
|
||||
let ckUser = await MysUser.create(ltuid)
|
||||
if (ckUser) {
|
||||
await ckUser.del(this)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
this.initUids(false)
|
||||
await this.save()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -291,15 +369,4 @@ export default class NoteUser extends BaseModel {
|
|||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// 内部方法:读取CK数据
|
||||
_getCkData () {
|
||||
this.ckData = gsCfg.getBingCkSingle(this.qq)
|
||||
return this.ckData
|
||||
}
|
||||
|
||||
// 内部方法:写入CK数据
|
||||
_saveCkData () {
|
||||
gsCfg.saveBingCk(this.qq, this.ckData)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,140 +4,140 @@
|
|||
* 临时处理,后续大概率重写 主要原因(懒)
|
||||
*/
|
||||
export default class apiTool {
|
||||
/**
|
||||
*
|
||||
* @param {用户uid} uid
|
||||
* @param {区服} server
|
||||
* @param {是否为星穹铁道或其他游戏? type(bool or string)} isSr
|
||||
*/
|
||||
constructor(uid, server, isSr = false) {
|
||||
this.uid = uid
|
||||
this.isSr = isSr
|
||||
this.server = server
|
||||
this.game='genshin'
|
||||
if(isSr) this.game='honkaisr'
|
||||
if(typeof isSr !== 'boolean'){
|
||||
this.game=isSr
|
||||
/**
|
||||
*
|
||||
* @param {用户uid} uid
|
||||
* @param {区服} server
|
||||
* @param {是否为星穹铁道或其他游戏? type(bool or string)} isSr
|
||||
*/
|
||||
constructor (uid, server, isSr = false) {
|
||||
this.uid = uid
|
||||
this.isSr = isSr
|
||||
this.server = server
|
||||
this.game = 'genshin'
|
||||
if (isSr) this.game = 'honkaisr'
|
||||
if (typeof isSr !== 'boolean') {
|
||||
this.game = isSr
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
getUrlMap = (data = {}) => {
|
||||
let host, hostRecord
|
||||
if (['cn_gf01', 'cn_qd01', 'prod_gf_cn', 'prod_qd_cn'].includes(this.server)) {
|
||||
host = 'https://api-takumi.mihoyo.com/'
|
||||
hostRecord = 'https://api-takumi-record.mihoyo.com/'
|
||||
} else if (['os_usa', 'os_euro', 'os_asia', 'os_cht'].includes(this.server)) {
|
||||
host = 'https://api-os-takumi.mihoyo.com/'
|
||||
hostRecord = 'https://bbs-api-os.mihoyo.com/'
|
||||
}
|
||||
let urlMap = {
|
||||
genshin: {
|
||||
/** 首页宝箱 */
|
||||
index: {
|
||||
url: `${hostRecord}game_record/app/genshin/api/index`,
|
||||
query: `role_id=${this.uid}&server=${this.server}`
|
||||
},
|
||||
/** 深渊 */
|
||||
spiralAbyss: {
|
||||
url: `${hostRecord}game_record/app/genshin/api/spiralAbyss`,
|
||||
query: `role_id=${this.uid}&schedule_type=${data.schedule_type || 1}&server=${this.server}`
|
||||
},
|
||||
/** 角色详情 */
|
||||
character: {
|
||||
url: `${hostRecord}game_record/app/genshin/api/character`,
|
||||
body: { role_id: this.uid, server: this.server }
|
||||
},
|
||||
/** 树脂 */
|
||||
dailyNote: {
|
||||
url: `${hostRecord}game_record/app/genshin/api/dailyNote`,
|
||||
query: `role_id=${this.uid}&server=${this.server}`
|
||||
},
|
||||
/** 详情 */
|
||||
detail: {
|
||||
url: `${host}event/e20200928calculate/v1/sync/avatar/detail`,
|
||||
query: `uid=${this.uid}®ion=${this.server}&avatar_id=${data.avatar_id}`
|
||||
},
|
||||
/** 札记 */
|
||||
ys_ledger: {
|
||||
url: 'https://hk4e-api.mihoyo.com/event/ys_ledger/monthInfo',
|
||||
query: `month=${data.month}&bind_uid=${this.uid}&bind_region=${this.server}`
|
||||
},
|
||||
/** 养成计算器 */
|
||||
compute: {
|
||||
url: `${host}event/e20200928calculate/v2/compute`,
|
||||
body: data
|
||||
},
|
||||
blueprintCompute: {
|
||||
url: `${host}event/e20200928calculate/v1/furniture/compute`,
|
||||
body: data
|
||||
},
|
||||
/** 养成计算器 */
|
||||
blueprint: {
|
||||
url: `${host}event/e20200928calculate/v1/furniture/blueprint`,
|
||||
query: `share_code=${data.share_code}®ion=${this.server}`
|
||||
},
|
||||
/** 角色技能 */
|
||||
avatarSkill: {
|
||||
url: `${host}event/e20200928calculate/v1/avatarSkill/list`,
|
||||
query: `avatar_id=${data.avatar_id}`
|
||||
},
|
||||
/** 七圣召唤数据 */
|
||||
basicInfo: {
|
||||
url: `${hostRecord}game_record/app/genshin/api/gcg/basicInfo`,
|
||||
query: `role_id=${this.uid}&server=${this.server}`
|
||||
},
|
||||
/**使用兑换码 目前仅限国际服,来自于国服的uid请求已在myinfo.js的init方法提前拦截 */
|
||||
useCdk: {
|
||||
url: 'PLACE_HOLDER',
|
||||
query: null
|
||||
}
|
||||
},
|
||||
honkaisr: {
|
||||
/** 首页宝箱 */
|
||||
index: {
|
||||
url: `${hostRecord}game_record/app/hkrpg/api/index`,
|
||||
query: `role_id=${this.uid}&server=${this.server}`
|
||||
},
|
||||
UserGame: {
|
||||
url: `${host}common/badge/v1/login/account`,
|
||||
body: { uid: this.uid, region: this.server, lang: 'zh-cn', game_biz: 'hkrpg_cn' }
|
||||
},
|
||||
/**
|
||||
* 开拓阅历接口
|
||||
*/
|
||||
ys_ledger: {
|
||||
url: `${host}/event/srledger/month_info`,
|
||||
query: `region=${this.server}&uid=${this.uid}&month=${data.month}`
|
||||
},
|
||||
/** 角色详情 */
|
||||
character: {
|
||||
url: `${hostRecord}game_record/app/hkrpg/api/avatar/info`,
|
||||
body: { role_id: this.uid, server: this.server }
|
||||
},
|
||||
/** 树脂 */
|
||||
dailyNote: {
|
||||
url: `${hostRecord}game_record/app/hkrpg/api/note`,
|
||||
query: `role_id=${this.uid}&server=${this.server}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
getUrlMap = (data = {}) => {
|
||||
let host, hostRecord
|
||||
if (['cn_gf01', 'cn_qd01', 'prod_gf_cn','prod_qd_cn'].includes(this.server)) {
|
||||
host = 'https://api-takumi.mihoyo.com/'
|
||||
hostRecord = 'https://api-takumi-record.mihoyo.com/'
|
||||
} else if (['os_usa', 'os_euro', 'os_asia', 'os_cht'].includes(this.server)) {
|
||||
host = 'https://api-os-takumi.mihoyo.com/'
|
||||
hostRecord = 'https://bbs-api-os.mihoyo.com/'
|
||||
}
|
||||
let urlMap = {
|
||||
genshin: {
|
||||
/** 首页宝箱 */
|
||||
index: {
|
||||
url: `${hostRecord}game_record/app/genshin/api/index`,
|
||||
query: `role_id=${this.uid}&server=${this.server}`
|
||||
},
|
||||
/** 深渊 */
|
||||
spiralAbyss: {
|
||||
url: `${hostRecord}game_record/app/genshin/api/spiralAbyss`,
|
||||
query: `role_id=${this.uid}&schedule_type=${data.schedule_type || 1}&server=${this.server}`
|
||||
},
|
||||
/** 角色详情 */
|
||||
character: {
|
||||
url: `${hostRecord}game_record/app/genshin/api/character`,
|
||||
body: { role_id: this.uid, server: this.server }
|
||||
},
|
||||
/** 树脂 */
|
||||
dailyNote: {
|
||||
url: `${hostRecord}game_record/app/genshin/api/dailyNote`,
|
||||
query: `role_id=${this.uid}&server=${this.server}`
|
||||
},
|
||||
/** 详情 */
|
||||
detail: {
|
||||
url: `${host}event/e20200928calculate/v1/sync/avatar/detail`,
|
||||
query: `uid=${this.uid}®ion=${this.server}&avatar_id=${data.avatar_id}`
|
||||
},
|
||||
/** 札记 */
|
||||
ys_ledger: {
|
||||
url: 'https://hk4e-api.mihoyo.com/event/ys_ledger/monthInfo',
|
||||
query: `month=${data.month}&bind_uid=${this.uid}&bind_region=${this.server}`
|
||||
},
|
||||
/** 养成计算器 */
|
||||
compute: {
|
||||
url: `${host}event/e20200928calculate/v2/compute`,
|
||||
body: data
|
||||
},
|
||||
blueprintCompute: {
|
||||
url: `${host}event/e20200928calculate/v1/furniture/compute`,
|
||||
body: data
|
||||
},
|
||||
/** 养成计算器 */
|
||||
blueprint: {
|
||||
url: `${host}event/e20200928calculate/v1/furniture/blueprint`,
|
||||
query: `share_code=${data.share_code}®ion=${this.server}`
|
||||
},
|
||||
/** 角色技能 */
|
||||
avatarSkill: {
|
||||
url: `${host}event/e20200928calculate/v1/avatarSkill/list`,
|
||||
query: `avatar_id=${data.avatar_id}`
|
||||
},
|
||||
/** 七圣召唤数据 */
|
||||
basicInfo: {
|
||||
url: `${hostRecord}game_record/app/genshin/api/gcg/basicInfo`,
|
||||
query: `role_id=${this.uid}&server=${this.server}`
|
||||
},
|
||||
/**使用兑换码 目前仅限国际服,来自于国服的uid请求已在myinfo.js的init方法提前拦截 */
|
||||
useCdk: {
|
||||
url: 'PLACE_HOLDER',
|
||||
query: null
|
||||
}
|
||||
},
|
||||
honkaisr: {
|
||||
/** 首页宝箱 */
|
||||
index: {
|
||||
url: `${hostRecord}game_record/app/hkrpg/api/index`,
|
||||
query: `role_id=${this.uid}&server=${this.server}`
|
||||
},
|
||||
UserGame:{
|
||||
url:`${host}common/badge/v1/login/account`,
|
||||
body: { uid: this.uid, region: this.server,lang:'zh-cn',game_biz:'hkrpg_cn' }
|
||||
},
|
||||
/**
|
||||
* 开拓阅历接口
|
||||
*/
|
||||
ys_ledger:{
|
||||
url:`${host}/event/srledger/month_info`,
|
||||
query:`region=${this.server}&uid=${this.uid}&month=${data.month}`
|
||||
},
|
||||
/** 角色详情 */
|
||||
character: {
|
||||
url: `${hostRecord}game_record/app/hkrpg/api/avatar/info`,
|
||||
body: { role_id: this.uid, server: this.server }
|
||||
},
|
||||
/** 树脂 */
|
||||
dailyNote: {
|
||||
url: `${hostRecord}game_record/app/hkrpg/api/note`,
|
||||
query: `role_id=${this.uid}&server=${this.server}`
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if (this.server.startsWith('os')) {
|
||||
urlMap.genshin.detail.url = 'https://sg-public-api.hoyolab.com/event/calculateos/sync/avatar/detail'// 角色天赋详情
|
||||
urlMap.genshin.detail.query = `lang=zh-cn&uid=${this.uid}®ion=${this.server}&avatar_id=${data.avatar_id}`
|
||||
urlMap.genshin.avatarSkill.url = 'https://sg-public-api.hoyolab.com/event/calculateos/avatar/skill_list'// 查询未持有的角色天赋
|
||||
urlMap.genshin.avatarSkill.query = `lang=zh-cn&avatar_id=${data.avatar_id}`
|
||||
urlMap.genshin.compute.url = 'https://sg-public-api.hoyolab.com/event/calculateos/compute'// 已支持养成计算
|
||||
urlMap.genshin.blueprint.url = 'https://sg-public-api.hoyolab.com/event/calculateos/furniture/blueprint'
|
||||
urlMap.genshin.blueprint.query = `share_code=${data.share_code}®ion=${this.server}&lang=zh-cn`
|
||||
urlMap.genshin.blueprintCompute.url = 'https://sg-public-api.hoyolab.com/event/calculateos/furniture/compute'
|
||||
urlMap.genshin.blueprintCompute.body = { lang: 'zh-cn', ...data }
|
||||
urlMap.genshin.ys_ledger.url = 'https://hk4e-api-os.mihoyo.com/event/ysledgeros/month_info'// 支持了国际服札记
|
||||
urlMap.genshin.ys_ledger.query = `lang=zh-cn&month=${data.month}&uid=${this.uid}®ion=${this.server}`
|
||||
urlMap.genshin.useCdk.url = 'https://sg-hk4e-api.hoyoverse.com/common/apicdkey/api/webExchangeCdkey'
|
||||
urlMap.genshin.useCdk.query = `uid=${this.uid}®ion=${this.server}&lang=zh-cn&cdkey=${data.cdk}&game_biz=hk4e_global`
|
||||
}
|
||||
return urlMap[this.game]
|
||||
if (this.server.startsWith('os')) {
|
||||
urlMap.genshin.detail.url = 'https://sg-public-api.hoyolab.com/event/calculateos/sync/avatar/detail'// 角色天赋详情
|
||||
urlMap.genshin.detail.query = `lang=zh-cn&uid=${this.uid}®ion=${this.server}&avatar_id=${data.avatar_id}`
|
||||
urlMap.genshin.avatarSkill.url = 'https://sg-public-api.hoyolab.com/event/calculateos/avatar/skill_list'// 查询未持有的角色天赋
|
||||
urlMap.genshin.avatarSkill.query = `lang=zh-cn&avatar_id=${data.avatar_id}`
|
||||
urlMap.genshin.compute.url = 'https://sg-public-api.hoyolab.com/event/calculateos/compute'// 已支持养成计算
|
||||
urlMap.genshin.blueprint.url = 'https://sg-public-api.hoyolab.com/event/calculateos/furniture/blueprint'
|
||||
urlMap.genshin.blueprint.query = `share_code=${data.share_code}®ion=${this.server}&lang=zh-cn`
|
||||
urlMap.genshin.blueprintCompute.url = 'https://sg-public-api.hoyolab.com/event/calculateos/furniture/compute'
|
||||
urlMap.genshin.blueprintCompute.body = { lang: 'zh-cn', ...data }
|
||||
urlMap.genshin.ys_ledger.url = 'https://hk4e-api-os.mihoyo.com/event/ysledgeros/month_info'// 支持了国际服札记
|
||||
urlMap.genshin.ys_ledger.query = `lang=zh-cn&month=${data.month}&uid=${this.uid}®ion=${this.server}`
|
||||
urlMap.genshin.useCdk.url = 'https://sg-hk4e-api.hoyoverse.com/common/apicdkey/api/webExchangeCdkey'
|
||||
urlMap.genshin.useCdk.query = `uid=${this.uid}®ion=${this.server}&lang=zh-cn&cdkey=${data.cdk}&game_biz=hk4e_global`
|
||||
}
|
||||
return urlMap[this.game]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ export default class MysInfo {
|
|||
}
|
||||
// ck对应MysUser对象
|
||||
this.ckUser = null
|
||||
this.auth = ['dailyNote', 'bbs_sign_info', 'bbs_sign_home', 'bbs_sign', 'ys_ledger', 'compute', 'avatarSkill', 'detail', 'blueprint']
|
||||
this.auth = ['dailyNote', 'bbs_sign_info', 'bbs_sign_home', 'bbs_sign', 'ys_ledger', 'compute', 'avatarSkill', 'detail', 'blueprint', 'UserGame']
|
||||
}
|
||||
|
||||
static async init (e, api) {
|
||||
|
@ -62,7 +62,7 @@ export default class MysInfo {
|
|||
mysInfo.e.uid = mysInfo.uid
|
||||
|
||||
/** 获取ck */
|
||||
await mysInfo.getCookie(onlySelfCk)
|
||||
await mysInfo.getCookie(e, onlySelfCk)
|
||||
|
||||
/** 判断回复 */
|
||||
await mysInfo.checkReply()
|
||||
|
@ -75,7 +75,7 @@ export default class MysInfo {
|
|||
let user = await NoteUser.create(e)
|
||||
if (user) {
|
||||
// 强制读取一次ck,防止一些问题
|
||||
user._getCkData()
|
||||
user.initDB(true)
|
||||
return user
|
||||
}
|
||||
return false
|
||||
|
@ -91,7 +91,7 @@ export default class MysInfo {
|
|||
let user = await NoteUser.create(e)
|
||||
if (e.uid && matchMsgUid) {
|
||||
/** 没有绑定的自动绑定 */
|
||||
return await user.setRegUid(e.uid, false)
|
||||
return await user.setRegUid(e.uid, e, false)
|
||||
}
|
||||
|
||||
let { msg = '', at = '' } = e
|
||||
|
@ -101,7 +101,7 @@ export default class MysInfo {
|
|||
/** at用户 */
|
||||
if (at) {
|
||||
let atUser = await NoteUser.create(at)
|
||||
uid = atUser.uid
|
||||
uid = atUser.getUid(e)
|
||||
if (uid) return String(uid)
|
||||
if (e.noTips !== true) e.reply('尚未绑定uid', false, { at })
|
||||
return false
|
||||
|
@ -114,11 +114,11 @@ export default class MysInfo {
|
|||
}
|
||||
|
||||
// 消息携带UID、当前用户UID、群名片携带UID 依次获取
|
||||
uid = matchUid(msg) || user.uid || matchUid(e.sender.card)
|
||||
if (!matchMsgUid) uid = user.uid
|
||||
uid = matchUid(msg) || user.getUid(e) || matchUid(e.sender.card)
|
||||
if (!matchMsgUid) uid = user.getUid(e)
|
||||
if (uid) {
|
||||
/** 没有绑定的自动绑定 */
|
||||
return await user.setRegUid(uid, false)
|
||||
return await user.setRegUid(uid, e, false)
|
||||
}
|
||||
|
||||
if (e.noTips !== true) e.reply('请先#绑定uid', false, { at })
|
||||
|
@ -143,24 +143,7 @@ export default class MysInfo {
|
|||
return false
|
||||
}
|
||||
|
||||
return selfUser.uid
|
||||
}
|
||||
|
||||
/** 判断绑定ck才能查询 */
|
||||
checkAuth (api) {
|
||||
if (api === 'cookie') {
|
||||
return true
|
||||
}
|
||||
if (lodash.isObject(api)) {
|
||||
for (let i in api) {
|
||||
if (this.auth.includes(i)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
} else if (this.auth.includes(api)) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return selfUser.getUid(e)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -187,7 +170,7 @@ export default class MysInfo {
|
|||
if (!mysInfo.uid || !mysInfo.ckInfo.ck) return false
|
||||
e.uid = mysInfo.uid
|
||||
|
||||
let mysApi = new MysApi(mysInfo.uid, mysInfo.ckInfo.ck, option,e.isSr)
|
||||
let mysApi = new MysApi(mysInfo.uid, mysInfo.ckInfo.ck, option, e.isSr)
|
||||
|
||||
let res
|
||||
if (lodash.isObject(api)) {
|
||||
|
@ -220,50 +203,11 @@ export default class MysInfo {
|
|||
return res
|
||||
}
|
||||
|
||||
async checkReply () {
|
||||
if (this.e.noTips === true) return
|
||||
|
||||
if (!this.uid) {
|
||||
this.e.reply('请先#绑定uid')
|
||||
}
|
||||
|
||||
if (!this.ckInfo.ck) {
|
||||
this.e.reply('暂无可用CK,请绑定更多用户或设置公共ck..')
|
||||
}
|
||||
|
||||
this.e.noTips = true
|
||||
}
|
||||
|
||||
/* 获取请求所需ck */
|
||||
/**
|
||||
* 获取请求所需CK
|
||||
* @param onlySelfCk 是否只获取uid自己对应的ck。为true则只获取uid对应ck,若无则返回为空
|
||||
* @returns {Promise<string|string|*>} 查询ck,获取失败则返回空
|
||||
*/
|
||||
async getCookie(onlySelfCk = false) {
|
||||
if (this.ckInfo.ck) return this.ckInfo.ck
|
||||
|
||||
let mysUser = await MysUser.getByQueryUid(this.uid, onlySelfCk)
|
||||
if (mysUser) {
|
||||
if (mysUser.ckData?.ck) {
|
||||
this.ckInfo = mysUser.ckData
|
||||
this.ckUser = mysUser
|
||||
// 暂时直接记录请求uid,后期优化分析MysApi请求结果分状态记录结果
|
||||
await mysUser.addQueryUid(this.uid)
|
||||
} else {
|
||||
// 重新分配
|
||||
await mysUser.disable()
|
||||
return onlySelfCk ? '' : await this.getCookie()
|
||||
}
|
||||
}
|
||||
return this.ckInfo.ck
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化公共CK
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
static async initPubCk() {
|
||||
static async initPubCk () {
|
||||
// 初始化公共CK
|
||||
let pubCount = 0
|
||||
let pubCks = GsCfg.getConfig('mys', 'pubCk') || []
|
||||
|
@ -287,11 +231,14 @@ export default class MysInfo {
|
|||
* 默认会将用户CK加入查询池
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
static async initUserCk() {
|
||||
static async initUserCk () {
|
||||
// 初始化用户缓存
|
||||
let userCount = 0
|
||||
await NoteUser.forEach(async function (user) {
|
||||
userCount += await user.initCache(true)
|
||||
await MysUser.forEach(async (mys) => {
|
||||
let ret = await mys.initCache()
|
||||
if (ret) {
|
||||
userCount++
|
||||
}
|
||||
})
|
||||
logger.mark(`加载用户UID:${userCount}个,加入查询池`)
|
||||
}
|
||||
|
@ -302,7 +249,7 @@ export default class MysInfo {
|
|||
* @param clearData 强制初始化时是否清除已有数据 (刷新/重置)
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
static async initCache(force = false, clearData = false) {
|
||||
static async initCache (force = false, clearData = false) {
|
||||
// 检查缓存标记
|
||||
let cache = DailyCache.create()
|
||||
if (!force && await cache.get('cache-ready')) {
|
||||
|
@ -325,7 +272,82 @@ export default class MysInfo {
|
|||
return true
|
||||
}
|
||||
|
||||
async checkCode(res, type) {
|
||||
static async getBingCkUid () {
|
||||
let res = await GsCfg.getBingCk()
|
||||
return { ...res.ck }
|
||||
}
|
||||
|
||||
// 获取uid绑定的ck信息
|
||||
static async checkUidBing (uid, game = 'gs') {
|
||||
let ckUser = await MysUser.getByQueryUid(uid, game, true)
|
||||
if (ckUser && ckUser.ck) {
|
||||
return ckUser
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
static async delDisable () {
|
||||
return await MysUser.delDisable()
|
||||
}
|
||||
|
||||
/** 判断绑定ck才能查询 */
|
||||
checkAuth (api) {
|
||||
if (api === 'cookie') {
|
||||
return true
|
||||
}
|
||||
if (lodash.isObject(api)) {
|
||||
for (let i in api) {
|
||||
if (this.auth.includes(i)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
} else if (this.auth.includes(api)) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
async checkReply () {
|
||||
if (this.e.noTips === true) return
|
||||
|
||||
if (!this.uid) {
|
||||
this.e.reply('请先#绑定uid')
|
||||
}
|
||||
|
||||
if (!this.ckInfo.ck) {
|
||||
this.e.reply('暂无可用CK,请绑定更多用户或设置公共ck..')
|
||||
}
|
||||
|
||||
this.e.noTips = true
|
||||
}
|
||||
|
||||
/* 获取请求所需ck */
|
||||
/**
|
||||
* 获取请求所需CK
|
||||
* @param game 游戏
|
||||
* @param onlySelfCk 是否只获取uid自己对应的ck。为true则只获取uid对应ck,若无则返回为空
|
||||
* @returns {Promise<string|string|*>} 查询ck,获取失败则返回空
|
||||
*/
|
||||
async getCookie (game = 'gs', onlySelfCk = false) {
|
||||
if (this.ckUser?.ck) return this.ckUser?.ck
|
||||
|
||||
let mysUser = await MysUser.getByQueryUid(this.uid, game, onlySelfCk)
|
||||
if (mysUser) {
|
||||
if (mysUser.ck) {
|
||||
this.ckInfo = mysUser.getCkInfo()
|
||||
this.ckUser = mysUser
|
||||
// 暂时直接记录请求uid,后期优化分析MysApi请求结果分状态记录结果
|
||||
await mysUser.addQueryUid(this.uid, game)
|
||||
} else {
|
||||
// 重新分配
|
||||
await mysUser.disable(game)
|
||||
return onlySelfCk ? '' : await this.getCookie()
|
||||
}
|
||||
}
|
||||
return this.ckUser?.ck
|
||||
}
|
||||
|
||||
async checkCode (res, type) {
|
||||
if (!res) {
|
||||
this.e.reply('米游社接口请求失败,暂时无法查询')
|
||||
return false
|
||||
|
@ -394,7 +416,7 @@ export default class MysInfo {
|
|||
}
|
||||
|
||||
/** 删除失效ck */
|
||||
async delCk() {
|
||||
async delCk () {
|
||||
if (!this.ckUser) {
|
||||
return false
|
||||
}
|
||||
|
@ -404,26 +426,8 @@ export default class MysInfo {
|
|||
}
|
||||
|
||||
/** 查询次数满,今日内标记失效 */
|
||||
async disableToday() {
|
||||
async disableToday (game = 'gs') {
|
||||
/** 统计次数设为超限 */
|
||||
await this.ckUser.disable()
|
||||
}
|
||||
|
||||
static async getBingCkUid() {
|
||||
let res = await GsCfg.getBingCk()
|
||||
return { ...res.ck }
|
||||
}
|
||||
|
||||
// 获取uid绑定的ck信息
|
||||
static async checkUidBing(uid) {
|
||||
let ckUser = await MysUser.getByQueryUid(uid, true)
|
||||
if (ckUser && ckUser.ckData) {
|
||||
return ckUser.ckData
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
static async delDisable() {
|
||||
return await MysUser.delDisable()
|
||||
await this.ckUser.disable(game)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,182 +1,187 @@
|
|||
import moment from "moment";
|
||||
import lodash from "lodash";
|
||||
import base from "./base.js";
|
||||
import MysInfo from "./mys/mysInfo.js";
|
||||
import moment from 'moment'
|
||||
import lodash from 'lodash'
|
||||
import base from './base.js'
|
||||
import MysInfo from './mys/mysInfo.js'
|
||||
|
||||
export default class Note extends base {
|
||||
constructor(e) {
|
||||
super(e);
|
||||
this.model = "dailyNote";
|
||||
constructor (e) {
|
||||
super(e)
|
||||
this.model = 'dailyNote'
|
||||
}
|
||||
|
||||
/** 生成体力图片 */
|
||||
static async get(e) {
|
||||
let note = new Note(e);
|
||||
return await note.getData();
|
||||
static async get (e) {
|
||||
let note = new Note(e)
|
||||
return await note.getData()
|
||||
}
|
||||
|
||||
async getData() {
|
||||
let res = await MysInfo.get(this.e, "dailyNote");
|
||||
let resUser;
|
||||
if (!res || res.retcode !== 0) return false;
|
||||
async getData () {
|
||||
let res = await MysInfo.get(this.e, 'dailyNote')
|
||||
let resUser
|
||||
if (!res || res.retcode !== 0) return false
|
||||
console.log(this.e.isSr, res)
|
||||
/** 截图数据 */
|
||||
let data = this.e.isSr ? this.noteSr(res) : this.noteData(res);
|
||||
let screenData = this.screenData;
|
||||
let data = this.e.isSr ? this.noteSr(res) : this.noteData(res)
|
||||
console.log(data)
|
||||
let screenData = this.screenData
|
||||
if (this.e.isSr) {
|
||||
screenData.tplFile = "./plugins/genshin/resources/StarRail/html/dailyNote/dailyNote.html";
|
||||
resUser = await MysInfo.get(this.e,'UserGame')
|
||||
if (!resUser || resUser.retcode !== 0) return false;
|
||||
screenData.tplFile = './plugins/genshin/resources/StarRail/html/dailyNote/dailyNote.html'
|
||||
resUser = await MysInfo.get(this.e, 'UserGame')
|
||||
console.log('resUser', resUser)
|
||||
if (!resUser || resUser.retcode !== 0) return false
|
||||
}
|
||||
return {
|
||||
name: this.e.sender.card,
|
||||
quality: 80,
|
||||
...screenData,
|
||||
...data,...resUser?.data
|
||||
};
|
||||
...data, ...resUser?.data
|
||||
}
|
||||
}
|
||||
noteSr(res) {
|
||||
let { data } = res;
|
||||
let nowDay = moment().date();
|
||||
let nowUnix = Number(moment().format("X"));
|
||||
|
||||
noteSr (res) {
|
||||
let { data } = res
|
||||
let nowDay = moment().date()
|
||||
let nowUnix = Number(moment().format('X'))
|
||||
/** 树脂 */
|
||||
let resinMaxTime;
|
||||
let resinMaxTime
|
||||
if (data.stamina_recover_time > 0) {
|
||||
let d = moment.duration(data.stamina_recover_time, 'seconds');
|
||||
let day= Math.floor(d.asDays());
|
||||
let hours =d.hours()
|
||||
let minutes =d.minutes()
|
||||
let seconds =d.seconds()
|
||||
resinMaxTime = hours+'小时'+minutes+'分钟'+seconds+'秒'
|
||||
let d = moment.duration(data.stamina_recover_time, 'seconds')
|
||||
let day = Math.floor(d.asDays())
|
||||
let hours = d.hours()
|
||||
let minutes = d.minutes()
|
||||
let seconds = d.seconds()
|
||||
resinMaxTime = hours + '小时' + minutes + '分钟' + seconds + '秒'
|
||||
//精确到秒。。。。
|
||||
if(day>0){
|
||||
resinMaxTime =day+'天'+hours+'小时'+minutes+'分钟'+seconds+'秒'
|
||||
}else if(hours>0){
|
||||
resinMaxTime = hours+'小时'+minutes+'分钟'+seconds+'秒'
|
||||
}else if(minutes>0){
|
||||
resinMaxTime = minutes+'分钟'+seconds+'秒'
|
||||
}else if(seconds>0){
|
||||
resinMaxTime = seconds+'秒'
|
||||
if (day > 0) {
|
||||
resinMaxTime = day + '天' + hours + '小时' + minutes + '分钟' + seconds + '秒'
|
||||
} else if (hours > 0) {
|
||||
resinMaxTime = hours + '小时' + minutes + '分钟' + seconds + '秒'
|
||||
} else if (minutes > 0) {
|
||||
resinMaxTime = minutes + '分钟' + seconds + '秒'
|
||||
} else if (seconds > 0) {
|
||||
resinMaxTime = seconds + '秒'
|
||||
}
|
||||
}
|
||||
data.bfStamina = data.current_stamina / data.max_stamina * 100 +'%';
|
||||
data.bfStamina = data.current_stamina / data.max_stamina * 100 + '%'
|
||||
/** 派遣 */
|
||||
for(let item of data.expeditions){
|
||||
let d = moment.duration(item.remaining_time, 'seconds');
|
||||
let day= Math.floor(d.asDays());
|
||||
let hours =d.hours()
|
||||
let minutes =d.minutes()
|
||||
item.dateTime=([day+'天',hours+'时',minutes+'分'].filter(v => !['0天','0时','0分'].includes(v))).join('')
|
||||
item.bfTime=(72000-item.remaining_time)/72000 *100 +'%'
|
||||
if(item.avatars.length==1){
|
||||
for (let item of data.expeditions) {
|
||||
let d = moment.duration(item.remaining_time, 'seconds')
|
||||
let day = Math.floor(d.asDays())
|
||||
let hours = d.hours()
|
||||
let minutes = d.minutes()
|
||||
item.dateTime = ([day + '天', hours + '时', minutes + '分'].filter(v => !['0天', '0时', '0分'].includes(v))).join('')
|
||||
item.bfTime = (72000 - item.remaining_time) / 72000 * 100 + '%'
|
||||
if (item.avatars.length == 1) {
|
||||
item.avatars.push('派遣头像')
|
||||
}
|
||||
}
|
||||
// 标识属性图标~
|
||||
let icon = lodash.sample(['希儿','白露','艾丝妲','布洛妮娅','姬子','卡芙卡','克拉拉','停云','佩拉','黑塔','希露瓦','银狼'])
|
||||
let icon = lodash.sample(['希儿', '白露', '艾丝妲', '布洛妮娅', '姬子', '卡芙卡', '克拉拉', '停云', '佩拉', '黑塔', '希露瓦', '银狼'])
|
||||
let week = [
|
||||
"星期日",
|
||||
"星期一",
|
||||
"星期二",
|
||||
"星期三",
|
||||
"星期四",
|
||||
"星期五",
|
||||
"星期六",
|
||||
];
|
||||
let day = `${week[moment().day()]}`;
|
||||
'星期日',
|
||||
'星期一',
|
||||
'星期二',
|
||||
'星期三',
|
||||
'星期四',
|
||||
'星期五',
|
||||
'星期六'
|
||||
]
|
||||
let day = `${week[moment().day()]}`
|
||||
return {
|
||||
uid: this.e.uid,
|
||||
saveId: this.e.uid,icon,day,
|
||||
resinMaxTime,nowDay:moment(new Date()).format('YYYY年MM月DD日'),
|
||||
...data,
|
||||
};
|
||||
saveId: this.e.uid, icon, day,
|
||||
resinMaxTime, nowDay: moment(new Date()).format('YYYY年MM月DD日'),
|
||||
...data
|
||||
}
|
||||
}
|
||||
noteData(res) {
|
||||
let { data } = res;
|
||||
|
||||
let nowDay = moment().date();
|
||||
let nowUnix = Number(moment().format("X"));
|
||||
noteData (res) {
|
||||
let { data } = res
|
||||
|
||||
let nowDay = moment().date()
|
||||
let nowUnix = Number(moment().format('X'))
|
||||
|
||||
/** 树脂 */
|
||||
let resinMaxTime;
|
||||
let resinMaxTime
|
||||
if (data.resin_recovery_time > 0) {
|
||||
resinMaxTime = nowUnix + Number(data.resin_recovery_time);
|
||||
resinMaxTime = nowUnix + Number(data.resin_recovery_time)
|
||||
|
||||
let maxDate = moment.unix(resinMaxTime);
|
||||
resinMaxTime = maxDate.format("HH:mm");
|
||||
let maxDate = moment.unix(resinMaxTime)
|
||||
resinMaxTime = maxDate.format('HH:mm')
|
||||
|
||||
if (maxDate.date() != nowDay) {
|
||||
resinMaxTime = `明天 ${resinMaxTime}`;
|
||||
resinMaxTime = `明天 ${resinMaxTime}`
|
||||
} else {
|
||||
resinMaxTime = ` ${resinMaxTime}`;
|
||||
resinMaxTime = ` ${resinMaxTime}`
|
||||
}
|
||||
}
|
||||
|
||||
/** 派遣 */
|
||||
let remainedTime = "";
|
||||
let remainedTime = ''
|
||||
if (data.expeditions && data.expeditions.length >= 1) {
|
||||
remainedTime = lodash.map(data.expeditions, "remained_time");
|
||||
remainedTime = lodash.min(remainedTime);
|
||||
remainedTime = lodash.map(data.expeditions, 'remained_time')
|
||||
remainedTime = lodash.min(remainedTime)
|
||||
|
||||
if (remainedTime > 0) {
|
||||
remainedTime = nowUnix + Number(remainedTime);
|
||||
let remainedDate = moment.unix(remainedTime);
|
||||
remainedTime = remainedDate.format("HH:mm");
|
||||
remainedTime = nowUnix + Number(remainedTime)
|
||||
let remainedDate = moment.unix(remainedTime)
|
||||
remainedTime = remainedDate.format('HH:mm')
|
||||
|
||||
if (remainedDate.date() != nowDay) {
|
||||
remainedTime = `明天 ${remainedTime}`;
|
||||
remainedTime = `明天 ${remainedTime}`
|
||||
} else {
|
||||
remainedTime = ` ${remainedTime}`;
|
||||
remainedTime = ` ${remainedTime}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 宝钱 */
|
||||
let coinTime = "";
|
||||
let coinTime = ''
|
||||
if (data.home_coin_recovery_time > 0) {
|
||||
let coinDay = Math.floor(data.home_coin_recovery_time / 3600 / 24);
|
||||
let coinHour = Math.floor((data.home_coin_recovery_time / 3600) % 24);
|
||||
let coinMin = Math.floor((data.home_coin_recovery_time / 60) % 60);
|
||||
let coinDay = Math.floor(data.home_coin_recovery_time / 3600 / 24)
|
||||
let coinHour = Math.floor((data.home_coin_recovery_time / 3600) % 24)
|
||||
let coinMin = Math.floor((data.home_coin_recovery_time / 60) % 60)
|
||||
if (coinDay > 0) {
|
||||
coinTime = `${coinDay}天${coinHour}小时${coinMin}分钟`;
|
||||
coinTime = `${coinDay}天${coinHour}小时${coinMin}分钟`
|
||||
} else {
|
||||
let coinDate = moment.unix(
|
||||
nowUnix + Number(data.home_coin_recovery_time)
|
||||
);
|
||||
)
|
||||
|
||||
if (coinDate.date() != nowDay) {
|
||||
coinTime = `明天 ${coinDate.format("HH:mm")}`;
|
||||
coinTime = `明天 ${coinDate.format('HH:mm')}`
|
||||
} else {
|
||||
coinTime = coinDate.format("HH:mm");
|
||||
coinTime = coinDate.format('HH:mm')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let week = [
|
||||
"星期日",
|
||||
"星期一",
|
||||
"星期二",
|
||||
"星期三",
|
||||
"星期四",
|
||||
"星期五",
|
||||
"星期六",
|
||||
];
|
||||
let day = `${moment().format("MM-DD HH:mm")} ${week[moment().day()]}`;
|
||||
'星期日',
|
||||
'星期一',
|
||||
'星期二',
|
||||
'星期三',
|
||||
'星期四',
|
||||
'星期五',
|
||||
'星期六'
|
||||
]
|
||||
let day = `${moment().format('MM-DD HH:mm')} ${week[moment().day()]}`
|
||||
|
||||
/** 参量质变仪 */
|
||||
if (data?.transformer?.obtained) {
|
||||
data.transformer.reached = data.transformer.recovery_time.reached;
|
||||
let recoveryTime = "";
|
||||
data.transformer.reached = data.transformer.recovery_time.reached
|
||||
let recoveryTime = ''
|
||||
|
||||
if (data.transformer.recovery_time.Day > 0) {
|
||||
recoveryTime += `${data.transformer.recovery_time.Day}天`;
|
||||
recoveryTime += `${data.transformer.recovery_time.Day}天`
|
||||
}
|
||||
if (data.transformer.recovery_time.Hour > 0) {
|
||||
recoveryTime += `${data.transformer.recovery_time.Hour}小时`;
|
||||
recoveryTime += `${data.transformer.recovery_time.Hour}小时`
|
||||
}
|
||||
if (data.transformer.recovery_time.Minute > 0) {
|
||||
recoveryTime += `${data.transformer.recovery_time.Minute}分钟`;
|
||||
recoveryTime += `${data.transformer.recovery_time.Minute}分钟`
|
||||
}
|
||||
data.transformer.recovery_time = recoveryTime;
|
||||
data.transformer.recovery_time = recoveryTime
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -186,7 +191,7 @@ export default class Note extends base {
|
|||
remainedTime,
|
||||
coinTime,
|
||||
day,
|
||||
...data,
|
||||
};
|
||||
...data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ export default class RoleList extends base {
|
|||
if (avatars.length <= 0) return false
|
||||
|
||||
/** 判断是否绑定了ck */
|
||||
this.ck = await MysInfo.checkUidBing(uid)
|
||||
this.ck = await MysInfo.checkUidBing(uid, this.e)
|
||||
|
||||
let skill = []
|
||||
if (this.ck) {
|
||||
|
|
|
@ -145,7 +145,7 @@ export default class Today extends base {
|
|||
}
|
||||
|
||||
/** 判断是否绑定了ck */
|
||||
this.ck = await MysInfo.checkUidBing(this.e.uid)
|
||||
this.ck = await MysInfo.checkUidBing(this.e.uid, this.e)
|
||||
|
||||
let skill = {}
|
||||
if (this.ck) {
|
||||
|
|
|
@ -3,8 +3,12 @@ import gsCfg from './gsCfg.js'
|
|||
import lodash from 'lodash'
|
||||
import fs from 'node:fs'
|
||||
import common from '../../../lib/common/common.js'
|
||||
import MysUser from './mys/MysUser.js'
|
||||
import MysInfo from './mys/mysInfo.js'
|
||||
import NoteUser from './mys/NoteUser.js'
|
||||
import MysUser from './mys/MysUser.js'
|
||||
import { promisify } from 'node:util'
|
||||
import YAML from 'yaml'
|
||||
import { Data } from '#miao'
|
||||
|
||||
export default class User extends base {
|
||||
constructor (e) {
|
||||
|
@ -23,7 +27,7 @@ export default class User extends base {
|
|||
|
||||
// 获取当前user实例
|
||||
async user () {
|
||||
return await MysInfo.getNoteUser(this.e)
|
||||
return await NoteUser.create(this.e)
|
||||
}
|
||||
|
||||
async resetCk () {
|
||||
|
@ -41,9 +45,9 @@ export default class User extends base {
|
|||
return
|
||||
}
|
||||
|
||||
let ck = this.e.ck.replace(/#|'|"/g, '')
|
||||
let ckStr = this.e.ck.replace(/#|'|"/g, '')
|
||||
let param = {}
|
||||
ck.split(';').forEach((v) => {
|
||||
ckStr.split(';').forEach((v) => {
|
||||
// 处理分割特殊cookie_token
|
||||
let tmp = lodash.trim(v).replace('=', '~').split('~')
|
||||
param[tmp[0]] = tmp[1]
|
||||
|
@ -54,56 +58,62 @@ export default class User extends base {
|
|||
return
|
||||
}
|
||||
|
||||
this.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};`
|
||||
// TODO:独立的mys数据,不走缓存ltuid
|
||||
let mys = await MysUser.create(param.ltuid)
|
||||
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
|
||||
|
||||
if (param.cookie_token_v2 && (param.account_mid_v2 || param.ltmid_v2)) { //
|
||||
// account_mid_v2 为版本必须带的字段,不带的话会一直提示绑定cookie失败 请重新登录
|
||||
flagV2 = true
|
||||
this.ck = `account_mid_v2=${param.account_mid_v2};cookie_token_v2=${param.cookie_token_v2};ltoken_v2=${param.ltoken_v2};ltmid_v2=${param.ltmid_v2};`
|
||||
data.ck = `ltuid=${param.ltuid || param.login_uid};account_mid_v2=${param.account_mid_v2};cookie_token_v2=${param.cookie_token_v2};ltoken_v2=${param.ltoken_v2};ltmid_v2=${param.ltmid_v2};`
|
||||
}
|
||||
if (param.mi18nLang) {
|
||||
data.ck += ` mi18nLang=${param.mi18nLang};`
|
||||
}
|
||||
/** 拼接ck */
|
||||
this.ltuid = param.ltuid || param.ltmid_v2
|
||||
data.ltuid = param.ltuid || param.ltmid_v2
|
||||
|
||||
/** 米游币签到字段 */
|
||||
this.login_ticket = param.login_ticket ?? ''
|
||||
data.login_ticket = param.login_ticket ?? ''
|
||||
|
||||
mys.setCkData(data)
|
||||
|
||||
/** 检查ck是否失效 */
|
||||
if (!await this.checkCk(param)) {
|
||||
let uidRet = await mys.reqMysUid()
|
||||
if (uidRet.status !== 0) {
|
||||
logger.mark(`绑定cookie错误1:${this.checkMsg || 'cookie错误'}`)
|
||||
await this.e.reply(`绑定cookie失败:${this.checkMsg || 'cookie错误'}`)
|
||||
return
|
||||
// 清除mys数据
|
||||
mys._delCache()
|
||||
return await this.e.reply(`绑定cookie失败:${this.checkMsg || 'cookie错误'}`)
|
||||
}
|
||||
|
||||
if (flagV2) {
|
||||
// 获取米游社通行证id
|
||||
let userFullInfo = await this.getUserInfo()
|
||||
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.ck = `${this.ck}ltuid=${this.ltuid};`
|
||||
} else {
|
||||
logger.mark(`绑定cookie错误2:${userFullInfo.message || 'cookie错误'}`)
|
||||
await this.e.reply(`绑定cookie失败:${userFullInfo.message || 'cookie错误'}`)
|
||||
return
|
||||
return await this.e.reply(`绑定cookie失败:${userFullInfo.message || 'cookie错误'}`)
|
||||
}
|
||||
}
|
||||
|
||||
logger.mark(`${this.e.logFnc} 检查cookie正常 [uid:${this.uid}]`)
|
||||
logger.mark(`${this.e.logFnc} 检查cookie正常 [ltuid:${mys.ltuid}]`)
|
||||
|
||||
await user.addCk(this.getCk())
|
||||
await user.addMysUser(mys)
|
||||
await mys.initCache()
|
||||
await user.save()
|
||||
|
||||
logger.mark(`${this.e.logFnc} 保存cookie成功 [uid:${this.uid}] [ltuid:${this.ltuid}]`)
|
||||
logger.mark(`${this.e.logFnc} 保存cookie成功 [ltuid:${mys.ltuid}]`)
|
||||
|
||||
let uidMsg = [`绑定cookie成功\n${this.region_name}:${this.uid}`]
|
||||
if (!lodash.isEmpty(this.allUid)) {
|
||||
this.allUid.forEach(v => {
|
||||
uidMsg.push(`${v.region_name}:${v.uid}`)
|
||||
})
|
||||
}
|
||||
let uidMsg = [`绑定cookie成功`]
|
||||
await this.e.reply(uidMsg.join('\n'))
|
||||
let msg = ''
|
||||
this.region_name += lodash.map(this.allUid, 'region_name').join(',')
|
||||
if (/天空岛|世界树|America Server|Europe Server|Asia Server/.test(this.region_name)) {
|
||||
if (mys.hasGame('gs')) {
|
||||
msg += '原神模块支持:\n【#体力】查询当前树脂'
|
||||
msg += '\n【#签到】米游社原神自动签到'
|
||||
msg += '\n【#关闭签到】开启或关闭原神自动签到'
|
||||
|
@ -115,7 +125,7 @@ export default class User extends base {
|
|||
msg += '\n【#我的ck】查看当前绑定ck'
|
||||
msg += '\n【#删除ck】删除当前绑定ck'
|
||||
}
|
||||
if (/星穹列车/.test(this.region_name)) {
|
||||
if (mys.hasGame('sr')) {
|
||||
msg += '\n星穹铁道支持:\n功能还在咕咕咕~'
|
||||
}
|
||||
msg += '\n 支持绑定多个ck'
|
||||
|
@ -124,110 +134,16 @@ export default class User extends base {
|
|||
await this.e.reply(msg)
|
||||
}
|
||||
|
||||
/** 检查ck是否可用 */
|
||||
async checkCk (param) {
|
||||
let res
|
||||
for (let type of ['mys', 'hoyolab']) {
|
||||
let roleRes = await this.getGameRoles(type)
|
||||
if (roleRes?.retcode === 0) {
|
||||
res = roleRes
|
||||
/** 国际服的标记 */
|
||||
if (type === 'hoyolab' && typeof (param.mi18nLang) === 'string') {
|
||||
this.ck += ` mi18nLang=${param.mi18nLang};`
|
||||
}
|
||||
break
|
||||
}
|
||||
if (roleRes.retcode === -100) {
|
||||
this.checkMsg = '该ck已失效,请重新登录获取'
|
||||
} else {
|
||||
this.checkMsg = roleRes.message || 'error'
|
||||
}
|
||||
}
|
||||
|
||||
if (!res) return false
|
||||
|
||||
if (!res.data.list || res.data.list.length <= 0) {
|
||||
this.checkMsg = '该账号尚未绑定原神或星穹角色!'
|
||||
return false
|
||||
} else {
|
||||
res.data.list = res.data.list.filter(v => ['hk4e_cn', 'hkrpg_cn', 'hk4e_global', 'hkrpg_global'].includes(v.game_biz))
|
||||
}
|
||||
|
||||
//避免同时多个默认展示角色时候只绑定一个
|
||||
let is_chosen = false
|
||||
/** 米游社默认展示的角色 */
|
||||
for (let val of res.data.list) {
|
||||
if (val.is_chosen && !is_chosen) {
|
||||
this.uid = val.game_uid
|
||||
this.region_name = val.region_name
|
||||
is_chosen = true
|
||||
} else {
|
||||
this.allUid.push({
|
||||
uid: val.game_uid,
|
||||
region_name: val.region_name
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!this.uid && res.data?.list?.length > 0) {
|
||||
this.uid = res.data.list[0].game_uid
|
||||
this.region_name = res.data.list[0].region_name
|
||||
if (this.allUid[0].uid == this.uid) delete this.allUid[0]
|
||||
}
|
||||
|
||||
return this.uid
|
||||
}
|
||||
|
||||
async getGameRoles (server = 'mys') {
|
||||
return await MysUser.getGameRole(this.ck, server)
|
||||
}
|
||||
|
||||
// 获取米游社通行证id
|
||||
async getUserInfo (server = 'mys') {
|
||||
return await MysUser.getUserFullInfo(this.ck, server)
|
||||
}
|
||||
|
||||
/** 保存ck */
|
||||
getCk () {
|
||||
let ck = gsCfg.getBingCkSingle(this.e.user_id)
|
||||
|
||||
lodash.map(ck, o => {
|
||||
o.isMain = false
|
||||
return o
|
||||
})
|
||||
|
||||
ck[this.uid] = {
|
||||
uid: this.uid,
|
||||
qq: this.e.user_id,
|
||||
ck: this.ck,
|
||||
ltuid: this.ltuid,
|
||||
login_ticket: this.login_ticket,
|
||||
region_name: this.region_name,
|
||||
device_id: this.getGuid(),
|
||||
isMain: true
|
||||
}
|
||||
|
||||
this.allUid.forEach((v) => {
|
||||
if (!v.uid) return
|
||||
ck[v.uid] = {
|
||||
uid: v.uid,
|
||||
qq: this.e.user_id,
|
||||
ck: this.ck,
|
||||
ltuid: this.ltuid,
|
||||
region_name: v.region_name,
|
||||
device_id: this.getGuid(),
|
||||
isMain: false
|
||||
}
|
||||
})
|
||||
return ck
|
||||
}
|
||||
|
||||
/** 删除绑定ck */
|
||||
async delCk (uid = '') {
|
||||
async delCk () {
|
||||
let user = await this.user()
|
||||
let uids = await user.delCk()
|
||||
return `绑定cookie已删除,uid:${uids.join(',')}`
|
||||
// 获取当前uid
|
||||
let uidData = user.getUidData(this.e)
|
||||
if (!uidData || uidData.type !== 'ck' || !uidData.ltuid) {
|
||||
return `删除失败:当前的UID${uidData.uid}无CK信息`
|
||||
}
|
||||
await user.delMysUser(uidData.ltuid)
|
||||
return `绑定cookie已删除`
|
||||
}
|
||||
|
||||
/** 绑定uid,若有ck的话优先使用ck-uid */
|
||||
|
@ -236,57 +152,69 @@ export default class User extends base {
|
|||
if (!uid) return
|
||||
uid = uid[0]
|
||||
let user = await this.user()
|
||||
await user.setRegUid(uid, true)
|
||||
return await this.e.reply(`绑定成功uid:${uid}`, false, { at: true })
|
||||
await user.addRegUid(uid, this.e)
|
||||
return await this.showUid()
|
||||
}
|
||||
|
||||
async delUid (index) {
|
||||
let user = await this.user()
|
||||
let game = this.e
|
||||
let uidList = user.getUidList(game)
|
||||
if (index > uidList.length) {
|
||||
return await this.e.reply('uid序号输入错误')
|
||||
}
|
||||
index = Number(index) - 1
|
||||
let uidObj = uidList[index]
|
||||
if (uidObj.type === 'ck') {
|
||||
return await this.e.reply('CK对应UID无法直接删除,请通过【#删除ck】命令来删除')
|
||||
}
|
||||
await user.delRegUid(uidObj.uid, game)
|
||||
return await this.showUid()
|
||||
}
|
||||
|
||||
/** #uid */
|
||||
async showUid () {
|
||||
let user = await this.user()
|
||||
if (!user.hasCk) {
|
||||
await this.e.reply(`当前绑定uid:${user.uid || '无'}`, false, { at: true })
|
||||
return
|
||||
}
|
||||
let uids = user.ckUids
|
||||
let ckData = user.ckData
|
||||
let uid = user.uid * 1
|
||||
let msg = [`当前uid:${uid}`, '当前绑定cookie Uid列表', '通过【#uid+序号】来切换uid']
|
||||
let region_name = []
|
||||
Object.keys(ckData).forEach((v) => {
|
||||
if (!region_name.includes(ckData[v].region_name)) {
|
||||
region_name.push(ckData[v].region_name)
|
||||
let msg = []
|
||||
lodash.forEach({ gs: '原神', sr: '星穹铁道' }, (gameName, game) => {
|
||||
let uidList = user.getUidList(game)
|
||||
let currUid = user.getUid(game)
|
||||
if (uidList.length === 0) {
|
||||
return true
|
||||
}
|
||||
})
|
||||
let count = 0
|
||||
for (let n of region_name) {
|
||||
msg.push(n)
|
||||
for (let i in uids) {
|
||||
if (ckData[uids[i]].region_name == n) {
|
||||
let tmp = `${++count}: ${uids[i]}`
|
||||
if (uids[i] * 1 === uid) {
|
||||
tmp += ' ☑'
|
||||
}
|
||||
msg.push(tmp)
|
||||
msg.push(`【${gameName}】`)
|
||||
lodash.forEach(uidList, (ds, idx) => {
|
||||
let tmp = `${++idx}: ${ds.uid} (${ds.type})`
|
||||
if (currUid * 1 === ds.uid * 1) {
|
||||
tmp += ' ☑'
|
||||
}
|
||||
}
|
||||
msg.push(tmp)
|
||||
})
|
||||
})
|
||||
if (msg.length > 0) {
|
||||
msg.unshift('通过【#uid+序号】来切换uid')
|
||||
await this.e.reply(msg.join('\n'))
|
||||
} else {
|
||||
await this.e.reply('尚未绑定UID,发送CK或通过【#绑定123456789】命令来绑定UID')
|
||||
}
|
||||
await this.e.reply(msg.join('\n'))
|
||||
}
|
||||
|
||||
/** 切换uid */
|
||||
async toggleUid (index) {
|
||||
let user = await this.user()
|
||||
let uidList = user.ckUids
|
||||
let game = this.e
|
||||
let uidList = user.getUidList(game)
|
||||
if (index > uidList.length) {
|
||||
return await this.e.reply('uid序号输入错误')
|
||||
}
|
||||
index = Number(index) - 1
|
||||
await user.setMainUid(index)
|
||||
return await this.e.reply(`切换成功,当前uid:${user.uid}`)
|
||||
user.setMainUid(index, game)
|
||||
await user.save()
|
||||
return await this.showUid()
|
||||
}
|
||||
|
||||
/** 加载旧ck */
|
||||
async loadOldData () {
|
||||
/** 加载V2ck */
|
||||
async loadOldDataV2 () {
|
||||
let file = [
|
||||
'./data/MysCookie/NoteCookie.json',
|
||||
'./data/NoteCookie/NoteCookie.json',
|
||||
|
@ -324,33 +252,105 @@ export default class User extends base {
|
|||
qq,
|
||||
ck: ck.cookie,
|
||||
ltuid,
|
||||
isMain,
|
||||
device_id: this.getGuid()
|
||||
isMain
|
||||
}
|
||||
})
|
||||
|
||||
lodash.forEach(arr, (ck, qq) => {
|
||||
let saveFile = `./data/MysCookie/${qq}.yaml`
|
||||
if (fs.existsSync(saveFile)) return
|
||||
gsCfg.saveBingCk(qq, ck)
|
||||
})
|
||||
|
||||
logger.mark(logger.green(`加载用户ck完成:${lodash.size(arr)}个`))
|
||||
|
||||
let count = await this.loadOldData(arr)
|
||||
if (count > 0) {
|
||||
logger.mark(logger.green(`DB导入V2用户ck${count}个`))
|
||||
}
|
||||
fs.unlinkSync(json)
|
||||
}
|
||||
|
||||
/** 加载V3ck */
|
||||
async loadOldDataV3 (data) {
|
||||
let dir = './data/MysCookie/'
|
||||
Data.createDir('./data/MysCookieBak')
|
||||
let files = fs.readdirSync(dir).filter(file => file.endsWith('.yaml'))
|
||||
const readFile = promisify(fs.readFile)
|
||||
let promises = []
|
||||
files.forEach((v) => promises.push(readFile(`${dir}${v}`, 'utf8')))
|
||||
const res = await Promise.all(promises)
|
||||
let ret = {}
|
||||
for (let v of res) {
|
||||
v = YAML.parse(v)
|
||||
let qq
|
||||
for (let k in v) {
|
||||
qq = qq || v[k]?.qq
|
||||
}
|
||||
if (qq) {
|
||||
ret[qq] = v
|
||||
}
|
||||
}
|
||||
let count = await this.loadOldData(ret)
|
||||
if (count > 0) {
|
||||
logger.mark(logger.green(`DB导入V3用户ck${count}个`))
|
||||
}
|
||||
}
|
||||
|
||||
async loadOldData (data) {
|
||||
let count = 0
|
||||
if (!lodash.isPlainObject(data)) {
|
||||
return
|
||||
}
|
||||
for (let u in data) {
|
||||
let ltuids = {}
|
||||
let v = data[u]
|
||||
let qq
|
||||
for (let k in v) {
|
||||
let data = v[k]
|
||||
qq = qq || data?.qq
|
||||
let { uid, ck, ltuid, region_name: region, device_id: device } = data
|
||||
ltuids[ltuid] = ltuids[ltuid] || {
|
||||
ck,
|
||||
device,
|
||||
ltuid,
|
||||
uids: {},
|
||||
type: /America Server|Europe Server|Asia Server/.test(region) ? 'hoyolab' : 'mys'
|
||||
}
|
||||
let tmp = ltuids[ltuid]
|
||||
let game = region === '星穹列车' ? 'sr' : 'gs'
|
||||
tmp.uids[game] = tmp.uids[game] || []
|
||||
let gameUids = tmp.uids[game]
|
||||
if (!gameUids.includes(uid + '')) {
|
||||
gameUids.push(uid + '')
|
||||
}
|
||||
}
|
||||
if (!qq) {
|
||||
continue
|
||||
}
|
||||
let user = await NoteUser.create(qq)
|
||||
for (let ltuid in ltuids) {
|
||||
let data = ltuids[ltuid]
|
||||
let mys = await MysUser.create(data.ltuid)
|
||||
if (mys) {
|
||||
mys.setCkData(data)
|
||||
await mys.save()
|
||||
user.addMysUser(mys)
|
||||
}
|
||||
}
|
||||
await user.save()
|
||||
if (fs.existsSync(`./data/MysCookie/${qq}.yaml`)) {
|
||||
fs.rename(`./data/MysCookie/${qq}.yaml`, `./data/MysCookieBak/${qq}.yaml`, (err) => {
|
||||
if (err) console.log(err)
|
||||
})
|
||||
}
|
||||
count++
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
/** 我的ck */
|
||||
async myCk () {
|
||||
let user = await this.user()
|
||||
if (!user.hasCk) {
|
||||
this.e.reply('当前尚未绑定cookie')
|
||||
}
|
||||
let ck = user.mainCk
|
||||
|
||||
if (!lodash.isEmpty(ck)) {
|
||||
await this.e.reply(`当前绑定cookie\nuid:${ck.uid}`)
|
||||
await this.e.reply(ck.ck)
|
||||
let mys = user.getMysUser(this.e)
|
||||
if (mys) {
|
||||
await this.e.reply(`当前绑定cookie\nuid:${mys.getUid(this.e)}`)
|
||||
await this.e.reply(mys.ck)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -386,14 +386,6 @@ export default class User extends base {
|
|||
await this.e.reply(cks.join('\n----\n'), false, { at: true })
|
||||
}
|
||||
|
||||
getGuid () {
|
||||
function S4 () {
|
||||
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
|
||||
}
|
||||
|
||||
return (S4() + S4() + '-' + S4() + '-' + S4() + '-' + S4() + '-' + S4() + S4() + S4())
|
||||
}
|
||||
|
||||
async userAdmin () {
|
||||
this.model = 'userAdmin'
|
||||
await MysInfo.initCache()
|
||||
|
|
Loading…
Reference in New Issue