diff --git a/DEV.md b/DEV.md index 93550d4..e751e90 100644 --- a/DEV.md +++ b/DEV.md @@ -2,24 +2,35 @@ 该版本将支持TS、TSX环境,提供Miao-Yunzai完全的类型声明及其开发文档。 +- 提交 + +```ts +/** + * feature:新功能 + * update:更新某功能 + * fixbug:修补某功能的bug + * refactor:重构某个功能 + * optimize: 优化构建工具或运行时性能 + * style:仅样式改动 + * docs:仅文档新增/改动 + * chore:构建过程或辅助工具的变动 + */ +``` + ## 关于lib目录 lib目录将在未来逐渐放弃,在版本发布后,开发者需要有意识的对此变化做出调整. ```ts // 已废弃 --- lib/puppeteer +--lib / puppeteer // 无扩展性,计划废弃 --- lib/renderer +--lib / renderer // 非机器人框架的核心处理代码 // 消耗服务器内存,无扩展性,计划废弃 --- lib/tools - /web.js - /test.js - /log.js - /ksr.js +--lib / tools / web.js / test.js / log.js / ksr.js // 计划废弃 --- renderers +--renderers ``` ## 新版目录 @@ -41,6 +52,7 @@ src/mys src/utils ## 开发示例 + - 图片组件 ```tsx @@ -109,4 +121,4 @@ class Component { ) } } -``` \ No newline at end of file +``` diff --git a/README.md b/README.md index 50789af..fffbf94 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,8 @@ 如果你的系统不支持18.18.2版本,最低能下载16.14.0版本,这是最新的puppeteer版本限制。 - ## 使用教程 - + - 安装源码 ```sh diff --git a/src/core/runtime.ts b/src/core/runtime.ts index 05156ae..3e8a5d9 100644 --- a/src/core/runtime.ts +++ b/src/core/runtime.ts @@ -9,7 +9,6 @@ import cfg from '../../lib/config/config.js' import Handler from '../../lib/plugins/handler.js' import puppeteer from '../../lib/puppeteer/puppeteer.js' - /** * tudo * 不合理的调用逻辑 @@ -49,52 +48,52 @@ export default class Runtime { } } - get uid () { + get uid() { return this.user?.uid } - get hasCk () { + get hasCk() { return this.user?.hasCk } - get user () { + get user() { return this.e.user } - get cfg () { + get cfg() { return cfg } - get gsCfg () { + get gsCfg() { return gsCfg } - get common () { + get common() { return common } - get puppeteer () { + get puppeteer() { return puppeteer } - get MysInfo () { + get MysInfo() { return MysInfo } - get NoteUser () { + get NoteUser() { return NoteUser } - get MysUser () { + get MysUser() { return MysUser } /** - * - * @param e - * @returns + * + * @param e + * @returns */ - static async init (e) { + static async init(e) { await MysInfo.initCache() let runtime = new Runtime(e) e.runtime = runtime @@ -103,14 +102,14 @@ export default class Runtime { } /** - * + * */ - async initUser () { + async initUser() { let e = this.e let user = await NoteUser.create(e) if (user) { e.user = new Proxy(user, { - get (self, key, receiver) { + get(self, key, receiver) { let game = e.game let fnMap = { uid: 'getUid', @@ -124,13 +123,30 @@ export default class Runtime { if (key === 'uidData') { return self.getUidData('', game) } - if (['getUid', 'getUidList', 'getMysUser', 'getCkUidList', 'getUidMapList', 'getGameDs'].includes(key)) { + if ( + [ + 'getUid', + 'getUidList', + 'getMysUser', + 'getCkUidList', + 'getUidMapList', + 'getGameDs' + ].includes(key) + ) { return (_game, arg2) => { return self[key](_game || game, arg2) } } // 不能将类型“symbol”分配给类型“string”。 - if (['getUidData', 'hasUid', 'addRegUid', 'delRegUid', 'setMainUid'].includes(key)) { + if ( + [ + 'getUidData', + 'hasUid', + 'addRegUid', + 'delRegUid', + 'setMainUid' + ].includes(key) + ) { return (uid, _game = '') => { return self[key](uid, _game || game) } @@ -147,18 +163,21 @@ export default class Runtime { * @param targetType all: 所有用户均可, cookie:查询用户必须具备Cookie * @returns {Promise} */ - async getMysInfo (targetType = 'all') { + async getMysInfo(targetType = 'all') { if (!this._mysInfo[targetType]) { - this._mysInfo[targetType] = await MysInfo.init(this.e, targetType === 'cookie' ? 'detail' : 'roleIndex') + this._mysInfo[targetType] = await MysInfo.init( + this.e, + targetType === 'cookie' ? 'detail' : 'roleIndex' + ) } return this._mysInfo[targetType] } /** - * - * @returns + * + * @returns */ - async getUid () { + async getUid() { return await MysInfo.getUid(this.e) } @@ -170,7 +189,7 @@ export default class Runtime { * @param isSr 是否为星穹铁道 * @returns {Promise} */ - async getMysApi (targetType = 'all', option = {}, isSr = false) { + async getMysApi(targetType = 'all', option = {}, isSr = false) { let mys = await this.getMysInfo(targetType) if (mys.uid && mys?.ckInfo?.ck) { return new MysApi(mys.uid, mys.ckInfo.ck, option, isSr) @@ -186,7 +205,7 @@ export default class Runtime { * @param isSr 是否为星穹铁道 * @returns {Promise} */ - async createMysApi (uid, ck, option, isSr = false) { + async createMysApi(uid, ck, option, isSr = false) { return new MysApi(uid, ck, option, isSr) } @@ -203,13 +222,13 @@ export default class Runtime { * @param cfg.beforeRender({data}) 可改写渲染的data数据 * @returns {Promise} */ - async render (plugin, path, data = {}, cfg = {}) { + async render(plugin, path, data = {}, cfg = {}) { // 处理传入的path path = path.replace(/.html$/, '') - let paths = lodash.filter(path.split('/'), (p) => !!p) + let paths = lodash.filter(path.split('/'), p => !!p) path = paths.join('/') // 创建目录 - const mkdir = (check) => { + const mkdir = check => { let currDir = `${process.cwd()}/temp` for (let p of check.split('/')) { currDir = `${currDir}/${p}` @@ -223,14 +242,14 @@ export default class Runtime { // 自动计算pluResPath let pluResPath = `../../../${lodash.repeat('../', paths.length)}plugins/${plugin}/resources/` let miaoResPath = `../../../${lodash.repeat('../', paths.length)}plugins/miao-plugin/resources/` - const layoutPath = process.cwd() + '/plugins/miao-plugin/resources/common/layout/' + const layoutPath = + process.cwd() + '/plugins/miao-plugin/resources/common/layout/' /** * tudo * 不符合阅读习惯的,data重写data */ - // 渲染data data = { sys: { @@ -257,7 +276,6 @@ export default class Runtime { } } - // 处理beforeRender if (cfg.beforeRender) { data = cfg.beforeRender({ data }) || data @@ -285,4 +303,4 @@ export default class Runtime { } return cfg.retType === 'msgId' ? ret : true } -} \ No newline at end of file +} diff --git a/src/db/BaseModel.ts b/src/db/BaseModel.ts index ac2ea36..557c698 100644 --- a/src/db/BaseModel.ts +++ b/src/db/BaseModel.ts @@ -16,7 +16,7 @@ await sequelize.authenticate() export default class BaseModel extends Model { static Types = DataTypes - static initDB (model, columns) { + static initDB(model, columns) { let name = model.name name = name.replace(/DB$/, 's') model.init(columns, { sequelize, tableName: name }) diff --git a/src/db/MysUserDB.ts b/src/db/MysUserDB.ts index a5d1f81..43b14cd 100644 --- a/src/db/MysUserDB.ts +++ b/src/db/MysUserDB.ts @@ -21,7 +21,7 @@ const COLUMNS = { device: Types.STRING, uids: { type: Types.STRING, - get () { + get() { let data = this.getDataValue('uids') let ret = {} try { @@ -31,14 +31,14 @@ const COLUMNS = { } return ret }, - set (uids) { + set(uids) { this.setDataValue('uids', JSON.stringify(uids)) } } } class MysUserDB extends BaseModel { - static async find (ltuid = '', create = false) { + static async find(ltuid = '', create = false) { // DB查询 let mys = await MysUserDB.findByPk(ltuid) if (!mys && create) { @@ -49,7 +49,7 @@ class MysUserDB extends BaseModel { return mys || false } - async saveDB (mys) { + async saveDB(mys) { if (!mys.ck || !mys.device || !mys.db) { return false } diff --git a/src/db/UserDB.ts b/src/db/UserDB.ts index 64b2602..7b20321 100644 --- a/src/db/UserDB.ts +++ b/src/db/UserDB.ts @@ -1,6 +1,6 @@ import BaseModel from './BaseModel.js' -import lodash from 'lodash' -import MysUtil from '../mys/MysUtil.js' +import lodash from 'lodash' +import MysUtil from '../mys/MysUtil.js' const { Types } = BaseModel @@ -27,7 +27,7 @@ const COLUMNS = { ltuids: Types.STRING, games: { type: Types.STRING, - get () { + get() { let data = this.getDataValue('games') let ret = {} try { @@ -35,7 +35,7 @@ const COLUMNS = { } catch (e) { data = {} } - MysUtil.eachGame((game) => { + MysUtil.eachGame(game => { let ds = data[game] || {} ret[game] = { uid: ds.uid || '', @@ -44,7 +44,7 @@ const COLUMNS = { }) return ret }, - set (data) { + set(data) { this.setDataValue('games', JSON.stringify(data)) } }, @@ -52,7 +52,7 @@ const COLUMNS = { } class UserDB extends BaseModel { - static async find (id, type = 'qq') { + static async find(id, type = 'qq') { // user_id id = type === 'qq' ? '' + id : type + id // DB查询 @@ -66,10 +66,10 @@ class UserDB extends BaseModel { return user } - async saveDB (user) { + async saveDB(user) { let db = this let ltuids = [] - lodash.forEach(user.mysUsers, (mys) => { + lodash.forEach(user.mysUsers, mys => { if (mys.ck && mys.ltuid) { ltuids.push(mys.ltuid) } @@ -96,4 +96,4 @@ class UserDB extends BaseModel { BaseModel.initDB(UserDB, COLUMNS) await UserDB.sync() -export default UserDB \ No newline at end of file +export default UserDB diff --git a/src/db/UserGameDB.ts b/src/db/UserGameDB.ts index c29797b..fac8a98 100644 --- a/src/db/UserGameDB.ts +++ b/src/db/UserGameDB.ts @@ -12,7 +12,7 @@ const COLUMNS = { uid: Types.STRING, data: { type: Types.STRING, - get () { + get() { let data = this.getDataValue('data') let ret = {} try { @@ -20,24 +20,22 @@ const COLUMNS = { } catch (e) { data = [] } - lodash.forEach(data, (ds) => { + lodash.forEach(data, ds => { if (ds.uid) { ret[ds.uid] = ds } }) return ret }, - set (data) { + set(data) { this.setDataValue('data', JSON.stringify(lodash.values(data))) } } } -class UserGameDB extends BaseModel { - -} +class UserGameDB extends BaseModel {} BaseModel.initDB(UserGameDB, COLUMNS) await UserGameDB.sync() -export default UserGameDB \ No newline at end of file +export default UserGameDB diff --git a/src/db/index.ts b/src/db/index.ts index 5075d30..5a30eea 100644 --- a/src/db/index.ts +++ b/src/db/index.ts @@ -3,4 +3,4 @@ import MysUserDB from './MysUserDB.js' import UserGameDB from './UserGameDB.js' import { sequelize } from './BaseModel.js' -export { UserDB, MysUserDB, UserGameDB, sequelize } \ No newline at end of file +export { UserDB, MysUserDB, UserGameDB, sequelize } diff --git a/src/main.ts b/src/main.ts index ee3c7a8..a7f8398 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,2 +1,2 @@ import { Yunzai } from './bot.js' -await Yunzai.run() \ No newline at end of file +await Yunzai.run() diff --git a/src/mys/BaseModel.ts b/src/mys/BaseModel.ts index baa7433..5e7720c 100644 --- a/src/mys/BaseModel.ts +++ b/src/mys/BaseModel.ts @@ -7,12 +7,12 @@ let cacheMap = {} let reFn = {} export default class BaseModel { - constructor () { + constructor() { return this } // 获取缓存 - _getThis (model, id = '', time = 10 * 60) { + _getThis(model, id = '', time = 10 * 60) { const uuid = `${model}:${id}` this._uuid = uuid if (uuid && cacheMap[uuid]) { @@ -21,7 +21,7 @@ export default class BaseModel { } // 设置缓存 - _cacheThis (model, id, time = 10 * 60) { + _cacheThis(model, id, time = 10 * 60) { const uuid = this._uuid || `${model}:${id}` this._uuid = uuid if (uuid) { @@ -33,7 +33,7 @@ export default class BaseModel { } // 设置超时时间 - _expire (time = 10 * 60) { + _expire(time = 10 * 60) { let id = this._uuid reFn[id] && clearTimeout(reFn[id]) if (time > 0) { @@ -48,22 +48,22 @@ export default class BaseModel { } } - _delCache () { + _delCache() { let id = this._uuid reFn[id] && clearTimeout(reFn[id]) delete reFn[id] delete cacheMap[id] } - gameKey (game = 'gs') { + gameKey(game = 'gs') { return MysUtil.getGameKey(game) } - isGs (game = 'gs') { + isGs(game = 'gs') { return this.gameKey(game) === 'gs' } - isSr (game = 'gs') { + isSr(game = 'gs') { return this.gameKey(game) === 'sr' } } diff --git a/src/mys/DailyCache.ts b/src/mys/DailyCache.ts index abb4b03..7e998f7 100644 --- a/src/mys/DailyCache.ts +++ b/src/mys/DailyCache.ts @@ -8,7 +8,7 @@ const EX = 3600 * 24 const redisKeyRoot = 'Yz:cache:' export default class DailyCache extends BaseModel { - constructor (uid, game = 'config') { + constructor(uid, game = 'config') { super() const storeKey = DailyCache.getStoreKey(uid, game) // 检查实例缓存 @@ -29,12 +29,12 @@ export default class DailyCache extends BaseModel { * * 传入servKey (mys/hoyolab),会返回指定的servCache * @returns {DailyCache} */ - static create (uid, game = 'config') { + static create(uid, game = 'config') { return new DailyCache(uid, game) } // 内部方法:获取redis表前缀 - static getStoreKey (uid, game = 'config') { + static getStoreKey(uid, game = 'config') { let key if (!uid || game === 'config') { key = 'sys:config' @@ -52,7 +52,7 @@ export default class DailyCache extends BaseModel { * @param fn * @returns {Promise} */ - static async eachCache (fn) { + static async eachCache(fn) { for (const serv of servs) { let cache = DailyCache.create(serv) if (cache) { @@ -64,10 +64,12 @@ export default class DailyCache extends BaseModel { /** * 删除过期的DailyCache */ - static async clearOutdatedData () { + static async clearOutdatedData() { let keys = await redis.keys(`${redisKeyRoot}*`) const date = moment().format('MM-DD') - const testReg = new RegExp(`^${redisKeyRoot}(mys|hoyolab|config)-\\d{2}-\\d{2}`) + 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)) { @@ -77,7 +79,7 @@ export default class DailyCache extends BaseModel { } // 内部方法,用于decode value - static decodeValue (value, decode = false) { + static decodeValue(value, decode = false) { if (value && decode) { try { return JSON.parse(value) @@ -89,11 +91,11 @@ export default class DailyCache extends BaseModel { } // 内部方法,用于encode value - static encodeValue (value) { - if (typeof (value) === 'object') { + static encodeValue(value) { + if (typeof value === 'object') { return JSON.stringify(value) || '' } - if (typeof (value) === 'undefined') { + if (typeof value === 'undefined') { return '' } return '' + value @@ -101,7 +103,7 @@ export default class DailyCache extends BaseModel { /** ---- 基础方法 ---- **/ // 内部方法:获取redis表key键值 - getTableKey (key, sub = '') { + getTableKey(key, sub = '') { if (sub) { return `${this.keyPre}:${key}-${sub}` } else { @@ -123,7 +125,7 @@ export default class DailyCache extends BaseModel { * @param hasCount 是否具有count表(KeyList) * @returns {Promise} */ - async exTable (table, hasCount = false) { + async exTable(table, hasCount = false) { await redis.expire(this.getTableKey(table), EX) if (hasCount) { await redis.expire(this.getTableKey(table, 'count'), EX) @@ -135,7 +137,7 @@ export default class DailyCache extends BaseModel { * @param table * @returns {Promise} */ - async empty (table) { + async empty(table) { await redis.del(this.getTableKey(table)) await redis.del(this.getTableKey(table, 'count')) } @@ -147,7 +149,7 @@ export default class DailyCache extends BaseModel { * @param decode 是否对内容进行decode * @returns {Promise} */ - async kGet (table, key, decode = false) { + async kGet(table, key, decode = false) { let value = await redis.hGet(this.getTableKey(table), '' + key) return DailyCache.decodeValue(value, decode) } @@ -159,7 +161,7 @@ export default class DailyCache extends BaseModel { * @param value 数据,若传入对象或数组会自动encode * @returns {Promise} */ - async kSet (table, key, value) { + async kSet(table, key, value) { value = DailyCache.encodeValue(value) await redis.hSet(this.getTableKey(table), '' + key, value) await this.exTable(this.getTableKey(table)) @@ -171,7 +173,7 @@ export default class DailyCache extends BaseModel { * @param key 数据存储key * @returns {Promise} */ - async kDel (table, key) { + async kDel(table, key) { return await redis.hDel(this.getTableKey(table), '' + key) } @@ -181,7 +183,7 @@ export default class DailyCache extends BaseModel { * @param decode 是否对内容进行decode * @returns {Promise} */ - async get (table, decode = false) { + async get(table, decode = false) { const tableKey = this.getTableKey(table) let value = await redis.get(tableKey) return DailyCache.decodeValue(value, decode) @@ -193,7 +195,7 @@ export default class DailyCache extends BaseModel { * @param value 数据,若传入对象或数组会自动encode * @returns {Promise} */ - async set (table, value) { + async set(table, value) { value = DailyCache.encodeValue(value) return await redis.set(this.getTableKey(table), value, { EX }) } @@ -216,12 +218,12 @@ export default class DailyCache extends BaseModel { * @param item 添加的item * @returns {Promise} */ - async zAdd (table, key, item) { + async zAdd(table, key, item) { const tableKey = this.getTableKey(table) await redis.zAdd(tableKey, { score: key, value: item + '' }) // 同时更新数量,用于数量统计 - let count = await this.zCount(table, key) || 0 + let count = (await this.zCount(table, key)) || 0 const countKey = this.getTableKey(table, 'count') await redis.zAdd(countKey, { score: count, value: key + '' }) await this.exTable(this.getTableKey(table), true) @@ -234,7 +236,7 @@ export default class DailyCache extends BaseModel { * @param key key键值 * @returns {Promise>>} */ - async zList (table, key) { + async zList(table, key) { return await redis.zRangeByScore(this.getTableKey(table), key, key) } @@ -244,7 +246,7 @@ export default class DailyCache extends BaseModel { * @param item item * @returns {Promise} */ - async zKey (table, item) { + async zKey(table, item) { return await redis.zScore(this.getTableKey(table), item + '') } @@ -254,7 +256,7 @@ export default class DailyCache extends BaseModel { * @param key 需要获取长度的key * @returns {Promise} 长度值 */ - async zCount (table, key) { + async zCount(table, key) { return await redis.zCount(this.getTableKey(table), key, key) } @@ -264,8 +266,12 @@ export default class DailyCache extends BaseModel { * @param table * @returns {Promise} */ - async zMinKey (table) { - let keys = await redis.zRangeByScore(this.getTableKey(table, 'count'), 0, 60) + async zMinKey(table) { + let keys = await redis.zRangeByScore( + this.getTableKey(table, 'count'), + 0, + 60 + ) return keys[0] } @@ -278,7 +284,7 @@ export default class DailyCache extends BaseModel { * @param delCount 是否同时删除count记录,删除后不会被zGetDisableKey获取 * @returns {Promise} */ - async zDisableKey (table, key, delCount = false) { + async zDisableKey(table, key, delCount = false) { // 将count标记为99次,记录并防止被后续分配 const countKey = this.getTableKey(table, 'count') if (delCount) { @@ -293,7 +299,7 @@ export default class DailyCache extends BaseModel { * @param table * @returns {Promise>>} */ - async zGetDisableKey (table) { + async zGetDisableKey(table) { return await redis.zRangeByScore(this.getTableKey(table, 'count'), 99, 99) } @@ -309,7 +315,7 @@ export default class DailyCache extends BaseModel { * @param delCount 是否同时删除count记录,删除后不会被zGetDisableKey获取 * @returns {Promise} */ - async zDel (table, key, delCount = false) { + async zDel(table, key, delCount = false) { // 删除key对应list所有记录 key = key + '' let check = redis.zScore(this.getTableKey(table, 'count'), key) @@ -323,7 +329,7 @@ export default class DailyCache extends BaseModel { * @param table * @returns {Promise<{key:count}>} */ - async zStat (table) { + async zStat(table) { const countKey = this.getTableKey(table, 'count') return await redis.zRangeByScoreWithScores(countKey, 0, 100) } diff --git a/src/mys/MysUser.ts b/src/mys/MysUser.ts index 588980a..4416a54 100644 --- a/src/mys/MysUser.ts +++ b/src/mys/MysUser.ts @@ -15,7 +15,6 @@ import fetch from 'node-fetch' import { MysUserDB, UserDB } from '../db/index.js' - import { Data } from './local.js' const tables = { @@ -42,7 +41,6 @@ const tables = { } export default class MysUser extends BaseModel { - constructor(ltuid) { super() if (!ltuid) { @@ -76,7 +74,7 @@ export default class MysUser extends BaseModel { static async forEach(fn) { let dbs = await MysUserDB.findAll() - await Data.forEach(dbs, async (db) => { + await Data.forEach(dbs, async db => { let mys = await MysUser.create(db.ltuid, db) return await fn(mys) }) @@ -108,7 +106,9 @@ export default class MysUser extends BaseModel { // 根据uid检索已查询记录。包括公共CK/自己CK/已查询过 let ret = await create(await servCache.zKey(tables.detail, uid)) if (ret) { - logger.mark(`[米游社查询][uid:${uid}]${logger.green(`[使用已查询ck:${ret.ltuid}]`)}`) + logger.mark( + `[米游社查询][uid:${uid}]${logger.green(`[使用已查询ck:${ret.ltuid}]`)}` + ) return ret } @@ -118,7 +118,9 @@ export default class MysUser extends BaseModel { // 使用CK池内容,分配次数最少的一个ltuid ret = await create(await servCache.zMinKey(tables.detail)) if (ret) { - logger.mark(`[米游社查询][uid:${uid}]${logger.green(`[分配查询ck:${ret.ltuid}]`)}`) + logger.mark( + `[米游社查询][uid:${uid}]${logger.green(`[分配查询ck:${ret.ltuid}]`)}` + ) return ret } @@ -126,8 +128,8 @@ export default class MysUser extends BaseModel { } static async eachServ(fn) { - await MysUtil.eachServ(async (serv) => { - await MysUtil.eachGame(async (game) => { + await MysUtil.eachServ(async serv => { + await MysUtil.eachGame(async game => { let servCache = DailyCache.create(serv, game) await fn(servCache, serv, game) }) @@ -158,7 +160,7 @@ export default class MysUser extends BaseModel { count[type] = num totalCount[type] = (totalCount[type] || 0) + num } - lodash.forEach(data, (ds) => { + lodash.forEach(data, ds => { list.push({ ltuid: ds.value, num: ds.score @@ -174,7 +176,8 @@ export default class MysUser extends BaseModel { stat('last', count.normal * 30 - count.query) list = lodash.sortBy(list, ['num', 'ltuid']).reverse() ret.servs[serv] = { - list, count + list, + count } }) ret.count = totalCount @@ -246,7 +249,10 @@ export default class MysUser extends BaseModel { let detailRet = await mys.getData('detail', { avatar_id: 10000021 }) if (detailRet.retcode !== 0 || lodash.isEmpty(detailRet.data)) { let msg = noteRet.message !== 'OK' ? noteRet.message : 'CK失效' - return err(`${msg || 'CK失效'},当前CK仍可查询体力及角色,但无法查询角色详情数据`, 1) + return err( + `${msg || 'CK失效'},当前CK仍可查询体力及角色,但无法查询角色详情数据`, + 1 + ) } return { uids, @@ -331,7 +337,11 @@ export default class MysUser extends BaseModel { 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)) + playerList = playerList.filter(v => + ['hk4e_cn', 'hkrpg_cn', 'hk4e_global', 'hkrpg_global'].includes( + v.game_biz + ) + ) if (!playerList || playerList.length <= 0) { return err('该账号尚未绑定原神或星穹角色') } @@ -341,7 +351,10 @@ export default class MysUser extends BaseModel { /** 米游社默认展示的角色 */ for (let val of playerList) { - this.addUid(val.game_uid, ['hk4e_cn', 'hk4e_global'].includes(val.game_biz) ? 'gs' : 'sr') + this.addUid( + val.game_uid, + ['hk4e_cn', 'hk4e_global'].includes(val.game_biz) ? 'gs' : 'sr' + ) } await this.save() return { status: 0, msg: '' } @@ -351,7 +364,8 @@ export default class MysUser extends BaseModel { let ck = this.ck let url = { mys: 'https://api-takumi.mihoyo.com/binding/api/getUserGameRolesByCookie', - hoyolab: 'https://sg-public-api.hoyolab.com/binding/api/getUserGameRolesByCookie' + hoyolab: + 'https://sg-public-api.hoyolab.com/binding/api/getUserGameRolesByCookie' } let res = await fetch(url[serv], { method: 'get', headers: { Cookie: ck } }) @@ -415,7 +429,7 @@ export default class MysUser extends BaseModel { this.device = data.device || this.device || MysUtil.getDeviceGuid() this.uids = this.uids || {} let self = this - MysUtil.eachGame((game) => { + MysUtil.eachGame(game => { self.uids[game] = data?.uids?.[game] || self.uids[game] || [] }) } @@ -454,7 +468,7 @@ export default class MysUser extends BaseModel { return } let self = this - await MysUtil.eachGame(async (game) => { + await MysUtil.eachGame(async game => { let uids = self.uids[game] await this.addQueryUid(uids, game) let cache = self.getCache(game) @@ -463,7 +477,7 @@ export default class MysUser extends BaseModel { if (cacheSearchList && cacheSearchList.length > 0) { for (let searchedUid of cacheSearchList) { // 检查对应uid是否有新的查询记录 - if (!await this.getQueryLtuid(searchedUid, game)) { + if (!(await this.getQueryLtuid(searchedUid, game))) { await this.addQueryUid(searchedUid, game) } } @@ -487,7 +501,7 @@ export default class MysUser extends BaseModel { // TODO 检查一ltuid多绑定的情况 // 将查询过的uid缓存起来,以备后续重新绑定时恢复 let self = this - await MysUtil.eachGame(async (game) => { + await MysUtil.eachGame(async game => { let uids = await this.getQueryUids(game) let cache = self.getCache(game) await cache.set(tables.del, uids) @@ -551,4 +565,4 @@ export default class MysUser extends BaseModel { let uids = this.uids[gameKey] return uids.includes(uid + '') } -} \ No newline at end of file +} diff --git a/src/mys/MysUtil.ts b/src/mys/MysUtil.ts index ea9644f..88adffe 100644 --- a/src/mys/MysUtil.ts +++ b/src/mys/MysUtil.ts @@ -1,10 +1,13 @@ import { Data } from './local.js' -const games = [{ key: 'gs', name: '原神' }, { key: 'sr', name: '星穹铁道' }] +const games = [ + { key: 'gs', name: '原神' }, + { key: 'sr', name: '星穹铁道' } +] const MysUtil = { // 获取标准ltuid - getLtuid (data) { + getLtuid(data) { if (!data) { return false } @@ -19,7 +22,7 @@ const MysUtil = { }, // 获取标准gameKey - getGameKey (game) { + getGameKey(game) { // 兼容e的处理 if (game.user_id) { return game.isSr ? 'sr' : 'gs' @@ -28,23 +31,36 @@ const MysUtil = { }, // 生成设备guid - getDeviceGuid () { - function S4 () { + getDeviceGuid() { + function S4() { return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1) } - return (S4() + S4() + '-' + S4() + '-' + S4() + '-' + S4() + '-' + S4() + S4() + S4()) + return ( + S4() + + S4() + + '-' + + S4() + + '-' + + S4() + + '-' + + S4() + + '-' + + S4() + + S4() + + S4() + ) }, // 循环game - async eachGame (fn) { - await Data.forEach(games, (ds) => { + async eachGame(fn) { + await Data.forEach(games, ds => { return fn(ds.key, ds) }) }, // 循环server - async eachServ (fn) { + async eachServ(fn) { await Data.forEach(['mys', 'hoyolab'], fn) } } diff --git a/src/mys/NoteUser.ts b/src/mys/NoteUser.ts index 8bbe059..ce78f91 100644 --- a/src/mys/NoteUser.ts +++ b/src/mys/NoteUser.ts @@ -10,14 +10,13 @@ import lodash from 'lodash' import MysUser from './MysUser.js' import MysUtil from './MysUtil.js' - import { UserDB } from '../db/index.js' // import { Data } from './local.js' export default class NoteUser extends BaseModel { - constructor (qq) { + constructor(qq) { super() // 检查实例缓存 let cacheObj = this._getThis('user', qq) @@ -32,23 +31,25 @@ export default class NoteUser extends BaseModel { * OLD Func {{ */ - get uid () { + get uid() { console.warn('NoteUser.uid 默认返回原神UID,可更改为 user.getUid(game)') return this.getUid() } // 获取绑定CK的UID列表,如未绑定CK则返回空数组 - get ckUids () { - console.warn('NoteUser.ckUids 默认返回原神UID,可更改为 user.getCkUidList(game)') + get ckUids() { + console.warn( + 'NoteUser.ckUids 默认返回原神UID,可更改为 user.getCkUidList(game)' + ) let uids = this.getCkUidList('gs') - return lodash.map(uids, (ds) => ds.uid) + return lodash.map(uids, ds => ds.uid) } /** * 获取当前用户的所有ck * @returns { {ltuid:{ckData, ck, uids}} } */ - get cks () { + get cks() { console.warn('NoteUser.cks 即将废弃') let game = 'gs' let cks = {} @@ -68,13 +69,12 @@ export default class NoteUser extends BaseModel { return cks } - /** * End OLD Func }} */ // 当前用户是否具备CK - get hasCk () { + get hasCk() { return !lodash.isEmpty(this.mysUsers) } @@ -86,7 +86,7 @@ export default class NoteUser extends BaseModel { * @param data 用户对应MysCookie数据,为空则自动读取 * @returns {Promise} */ - static async create (qq, db = false) { + static async create(qq, db = false) { // 兼容处理传入e if (qq && qq.user_id) { let e = qq @@ -109,16 +109,16 @@ export default class NoteUser extends BaseModel { return user } - static async forEach (fn) { + static async forEach(fn) { let dbs = await UserDB.findAll() - await Data.forEach(dbs, async (db) => { + await Data.forEach(dbs, async db => { let user = await NoteUser.create(db.id, db) return await fn(user) }) } // 初始化数据 - async initDB (db = false) { + async initDB(db = false) { if (this.db && !db) { return } @@ -133,7 +133,7 @@ export default class NoteUser extends BaseModel { } // 初始化MysUser对象 - async initMysUser () { + async initMysUser() { let ltuids = this.db?.ltuids || '' this.mysUsers = {} for (let ltuid of ltuids.split(',')) { @@ -144,23 +144,22 @@ export default class NoteUser extends BaseModel { } } - async save () { + async save() { await this.db.saveDB(this) } - - getUidMapList (game = 'gs', type = 'all') { + getUidMapList(game = 'gs', type = 'all') { if (this._map?.[game]?.[type]) { return this._map[game][type] } game = this.gameKey(game) let uidMap = {} let uidList = [] - lodash.forEach(this.mysUsers, (mys) => { + lodash.forEach(this.mysUsers, mys => { if (!mys) { return } - lodash.forEach(mys.uids[game] || [], (uid) => { + lodash.forEach(mys.uids[game] || [], uid => { uid = uid + '' if (uid && !uidMap[uid]) { uidMap[uid] = mys.getUidData(uid, game) @@ -170,7 +169,7 @@ export default class NoteUser extends BaseModel { }) if (type === 'all') { let gameDs = this.getGameDs(game) - lodash.forEach(gameDs.data, (ds) => { + lodash.forEach(gameDs.data, ds => { if (ds.uid && !uidMap[ds.uid]) { uidMap[ds.uid] = ds uidList.push(ds) @@ -187,8 +186,7 @@ export default class NoteUser extends BaseModel { return this._map[game][type] } - - getUidData (uid = '', game = 'gs') { + getUidData(uid = '', game = 'gs') { if (!uid) { uid = this.getUid(game) } @@ -196,7 +194,7 @@ export default class NoteUser extends BaseModel { } /** 有Uid */ - hasUid (uid = '', game = '') { + hasUid(uid = '', game = '') { if (!uid) { return this.getUidMapList(game, 'all').list?.length > 0 } @@ -204,19 +202,19 @@ export default class NoteUser extends BaseModel { } /** 获取CK-Uid */ - getCkUid (game = 'gs') { + getCkUid(game = 'gs') { let uid = this.getUid(game) let { map, list } = this.getUidMapList(game, 'ck') return (map[uid] ? uid : list[0]?.uid) || '' } /** 获取CK-Uid列表 */ - getCkUidList (game = 'gs') { + getCkUidList(game = 'gs') { return this.getUidMapList(game, 'ck').list } /** 获取当前UID */ - getUid (game = 'gs') { + getUid(game = 'gs') { game = this.gameKey(game) // todo 刷新uid let ds = this.getGameDs(game) @@ -227,12 +225,12 @@ export default class NoteUser extends BaseModel { } /** 获取UID列表 */ - getUidList (game = 'gs') { + getUidList(game = 'gs') { return this.getUidMapList(game, 'all').list } /** 获取当前的MysUser对象 */ - getMysUser (game = 'gs') { + getMysUser(game = 'gs') { if (lodash.isEmpty(this.mysUsers)) { return false } @@ -245,7 +243,7 @@ export default class NoteUser extends BaseModel { } // 添加UID - addRegUid (uid, game = 'gs', save = true) { + addRegUid(uid, game = 'gs', save = true) { game = this.gameKey(game) uid = uid + '' let gameDs = this.getGameDs(game) @@ -258,7 +256,7 @@ export default class NoteUser extends BaseModel { } // 删除UID - delRegUid (uid, game = 'gs') { + delRegUid(uid, game = 'gs') { game = this.gameKey(game) let gameDs = this.getGameDs(game) let dsData = gameDs.data @@ -271,7 +269,7 @@ export default class NoteUser extends BaseModel { this.save() } - getGameDs (game = 'gs') { + getGameDs(game = 'gs') { game = this.gameKey(game) if (!this._games[game]) { this._games[game] = { @@ -282,13 +280,12 @@ export default class NoteUser extends BaseModel { return this._games[game] } - /** * 设置当前用户的绑定uid * @param uid 要绑定的uid * @param game */ - autoRegUid (uid = '', game = 'gs') { + autoRegUid(uid = '', game = 'gs') { if (this.getUid(game)) { return uid } @@ -297,7 +294,7 @@ export default class NoteUser extends BaseModel { } // 切换绑定CK生效的UID - setMainUid (uid = '', game = 'gs', save = true) { + setMainUid(uid = '', game = 'gs', save = true) { this._map = false game = this.gameKey(game) if (uid < 100 || !uid) { @@ -317,10 +314,10 @@ export default class NoteUser extends BaseModel { } // 添加MysUser - async addMysUser (mysUser) { + async addMysUser(mysUser) { this.mysUsers[mysUser.ltuid] = mysUser this._map = false - MysUtil.eachGame((game) => { + MysUtil.eachGame(game => { let uid = mysUser.getUid(game) if (uid && this.getUid(game) == '') { this.setMainUid(uid, game, false) @@ -330,12 +327,12 @@ export default class NoteUser extends BaseModel { } // 删除当前用户绑定CK - async delCk (ltuid = '') { + async delCk(ltuid = '') { console.warn('delCk即将废弃') return await this.delMysUser(ltuid) } - async delMysUser (mysUser = '') { + async delMysUser(mysUser = '') { let ltuid = mysUser.ltuid || mysUser if (ltuid && this.mysUsers[ltuid]) { let mys = this.mysUsers[ltuid] @@ -347,7 +344,7 @@ export default class NoteUser extends BaseModel { await this.save() } - async eachMysUser (fn) { + async eachMysUser(fn) { await Data.forEach(this.mysUsers, async (mys, ltuid) => { if (!mys) { return true @@ -356,14 +353,14 @@ export default class NoteUser extends BaseModel { }) } - async eachAllMysUser (fn) { + async eachAllMysUser(fn) { return MysUser.forEach(fn) } /** * 检查当前用户绑定的CK状态 */ - async checkCk () { + async checkCk() { // TODO:待完善文案 let cks = this.cks let ret = [] diff --git a/src/mys/apiTool.ts b/src/mys/apiTool.ts index b7008d1..d30f401 100644 --- a/src/mys/apiTool.ts +++ b/src/mys/apiTool.ts @@ -24,7 +24,9 @@ export default class apiTool { getUrlMap = (data = {}) => { let host, hostRecord, hostPublicData - if (['cn_gf01', 'cn_qd01', 'prod_gf_cn', 'prod_qd_cn'].includes(this.server)) { + 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/' hostPublicData = 'https://public-data-api.mihoyo.com/' @@ -36,33 +38,35 @@ export default class apiTool { let urlMap = { genshin: { /** 体力接口fp参数用于避开验证码 */ - ...(['cn_gf01', 'cn_qd01'].includes(this.server) ? { - getFp: { - url: `${hostPublicData}device-fp/api/getFp`, - body: { - seed_id: data.seed_id, - device_id: data.deviceId.toUpperCase(), - platform: '1', - seed_time: new Date().getTime() + '', - ext_fields: `{"proxyStatus":"0","accelerometer":"-0.159515x-0.830887x-0.682495","ramCapacity":"3746","IDFV":"${data.deviceId.toUpperCase()}","gyroscope":"-0.191951x-0.112927x0.632637","isJailBreak":"0","model":"iPhone12,5","ramRemain":"115","chargeStatus":"1","networkType":"WIFI","vendor":"--","osVersion":"17.0.2","batteryStatus":"50","screenSize":"414×896","cpuCores":"6","appMemory":"55","romCapacity":"488153","romRemain":"157348","cpuType":"CPU_TYPE_ARM64","magnetometer":"-84.426331x-89.708435x-37.117889"}`, - app_name: 'bbs_cn', - device_fp: '38d7ee834d1e9' + ...(['cn_gf01', 'cn_qd01'].includes(this.server) + ? { + getFp: { + url: `${hostPublicData}device-fp/api/getFp`, + body: { + seed_id: data.seed_id, + device_id: data.deviceId.toUpperCase(), + platform: '1', + seed_time: new Date().getTime() + '', + ext_fields: `{"proxyStatus":"0","accelerometer":"-0.159515x-0.830887x-0.682495","ramCapacity":"3746","IDFV":"${data.deviceId.toUpperCase()}","gyroscope":"-0.191951x-0.112927x0.632637","isJailBreak":"0","model":"iPhone12,5","ramRemain":"115","chargeStatus":"1","networkType":"WIFI","vendor":"--","osVersion":"17.0.2","batteryStatus":"50","screenSize":"414×896","cpuCores":"6","appMemory":"55","romCapacity":"488153","romRemain":"157348","cpuType":"CPU_TYPE_ARM64","magnetometer":"-84.426331x-89.708435x-37.117889"}`, + app_name: 'bbs_cn', + device_fp: '38d7ee834d1e9' + } + } } - } - } : { - getFp: { - url: `${hostPublicData}device-fp/api/getFp`, - body: { - seed_id: data.seed_id, - device_id: data.deviceId.toUpperCase(), - platform: '5', - seed_time: new Date().getTime() + '', - ext_fields: `{"userAgent":"Mozilla/5.0 (Linux; Android 11; J9110 Build/55.2.A.4.332; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/124.0.6367.179 Mobile Safari/537.36 miHoYoBBSOversea/2.55.0","browserScreenSize":"387904","maxTouchPoints":"5","isTouchSupported":"1","browserLanguage":"zh-CN","browserPlat":"Linux aarch64","browserTimeZone":"Asia/Shanghai","webGlRender":"Adreno (TM) 640","webGlVendor":"Qualcomm","numOfPlugins":"0","listOfPlugins":"unknown","screenRatio":"2.625","deviceMemory":"4","hardwareConcurrency":"8","cpuClass":"unknown","ifNotTrack":"unknown","ifAdBlock":"0","hasLiedLanguage":"0","hasLiedResolution":"1","hasLiedOs":"0","hasLiedBrowser":"0","canvas":"${randomRange()}","webDriver":"0","colorDepth":"24","pixelRatio":"2.625","packageName":"unknown","packageVersion":"2.27.0","webgl":"${randomRange()}"}`, - app_name: 'hk4e_global', - device_fp: '38d7f2364db95' - } - } - }), + : { + getFp: { + url: `${hostPublicData}device-fp/api/getFp`, + body: { + seed_id: data.seed_id, + device_id: data.deviceId.toUpperCase(), + platform: '5', + seed_time: new Date().getTime() + '', + ext_fields: `{"userAgent":"Mozilla/5.0 (Linux; Android 11; J9110 Build/55.2.A.4.332; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/124.0.6367.179 Mobile Safari/537.36 miHoYoBBSOversea/2.55.0","browserScreenSize":"387904","maxTouchPoints":"5","isTouchSupported":"1","browserLanguage":"zh-CN","browserPlat":"Linux aarch64","browserTimeZone":"Asia/Shanghai","webGlRender":"Adreno (TM) 640","webGlVendor":"Qualcomm","numOfPlugins":"0","listOfPlugins":"unknown","screenRatio":"2.625","deviceMemory":"4","hardwareConcurrency":"8","cpuClass":"unknown","ifNotTrack":"unknown","ifAdBlock":"0","hasLiedLanguage":"0","hasLiedResolution":"1","hasLiedOs":"0","hasLiedBrowser":"0","canvas":"${randomRange()}","webDriver":"0","colorDepth":"24","pixelRatio":"2.625","packageName":"unknown","packageVersion":"2.27.0","webgl":"${randomRange()}"}`, + app_name: 'hk4e_global', + device_fp: '38d7f2364db95' + } + } + }), /** 首页宝箱 */ index: { url: `${hostRecord}game_record/app/genshin/api/index`, @@ -139,43 +143,45 @@ export default class apiTool { } }, honkaisr: { - ...(['prod_gf_cn', 'prod_qd_cn'].includes(this.server) ? { - UserGame: { - url: `${host}binding/api/getUserGameRolesByCookie`, - query: `game_biz=hkrpg_cn®ion=${this.server}&game_uid=${this.uid}` - }, - /** 体力接口fp参数用于避开验证码 */ - getFp: { - url: `${hostPublicData}device-fp/api/getFp`, - body: { - seed_id: data.seed_id, - device_id: data.deviceId.toUpperCase(), - platform: '1', - seed_time: new Date().getTime() + '', - ext_fields: `{"proxyStatus":"0","accelerometer":"-0.159515x-0.830887x-0.682495","ramCapacity":"3746","IDFV":"${data.deviceId.toUpperCase()}","gyroscope":"-0.191951x-0.112927x0.632637","isJailBreak":"0","model":"iPhone12,5","ramRemain":"115","chargeStatus":"1","networkType":"WIFI","vendor":"--","osVersion":"17.0.2","batteryStatus":"50","screenSize":"414×896","cpuCores":"6","appMemory":"55","romCapacity":"488153","romRemain":"157348","cpuType":"CPU_TYPE_ARM64","magnetometer":"-84.426331x-89.708435x-37.117889"}`, - app_name: 'bbs_cn', - device_fp: '38d7ee834d1e9' + ...(['prod_gf_cn', 'prod_qd_cn'].includes(this.server) + ? { + UserGame: { + url: `${host}binding/api/getUserGameRolesByCookie`, + query: `game_biz=hkrpg_cn®ion=${this.server}&game_uid=${this.uid}` + }, + /** 体力接口fp参数用于避开验证码 */ + getFp: { + url: `${hostPublicData}device-fp/api/getFp`, + body: { + seed_id: data.seed_id, + device_id: data.deviceId.toUpperCase(), + platform: '1', + seed_time: new Date().getTime() + '', + ext_fields: `{"proxyStatus":"0","accelerometer":"-0.159515x-0.830887x-0.682495","ramCapacity":"3746","IDFV":"${data.deviceId.toUpperCase()}","gyroscope":"-0.191951x-0.112927x0.632637","isJailBreak":"0","model":"iPhone12,5","ramRemain":"115","chargeStatus":"1","networkType":"WIFI","vendor":"--","osVersion":"17.0.2","batteryStatus":"50","screenSize":"414×896","cpuCores":"6","appMemory":"55","romCapacity":"488153","romRemain":"157348","cpuType":"CPU_TYPE_ARM64","magnetometer":"-84.426331x-89.708435x-37.117889"}`, + app_name: 'bbs_cn', + device_fp: '38d7ee834d1e9' + } + } } - } - } : { - UserGame: { - url: `${host}binding/api/getUserGameRolesByCookie`, - query: `game_biz=hkrpg_global®ion=${this.server}&game_uid=${this.uid}` - }, - /** 体力接口fp参数用于避开验证码 */ - getFp: { - url: `${hostPublicData}device-fp/api/getFp`, - body: { - seed_id: data.seed_id, - device_id: data.deviceId.toUpperCase(), - platform: '5', - seed_time: new Date().getTime() + '', - ext_fields: `{"userAgent":"Mozilla/5.0 (Linux; Android 11; J9110 Build/55.2.A.4.332; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/124.0.6367.179 Mobile Safari/537.36 miHoYoBBSOversea/2.55.0","browserScreenSize":"387904","maxTouchPoints":"5","isTouchSupported":"1","browserLanguage":"zh-CN","browserPlat":"Linux aarch64","browserTimeZone":"Asia/Shanghai","webGlRender":"Adreno (TM) 640","webGlVendor":"Qualcomm","numOfPlugins":"0","listOfPlugins":"unknown","screenRatio":"2.625","deviceMemory":"4","hardwareConcurrency":"8","cpuClass":"unknown","ifNotTrack":"unknown","ifAdBlock":"0","hasLiedLanguage":"0","hasLiedResolution":"1","hasLiedOs":"0","hasLiedBrowser":"0","canvas":"${randomRange()}","webDriver":"0","colorDepth":"24","pixelRatio":"2.625","packageName":"unknown","packageVersion":"2.27.0","webgl":"${randomRange()}"}`, - app_name: 'hkrpg_global', - device_fp: '38d7f2364db95' - } - } - }), + : { + UserGame: { + url: `${host}binding/api/getUserGameRolesByCookie`, + query: `game_biz=hkrpg_global®ion=${this.server}&game_uid=${this.uid}` + }, + /** 体力接口fp参数用于避开验证码 */ + getFp: { + url: `${hostPublicData}device-fp/api/getFp`, + body: { + seed_id: data.seed_id, + device_id: data.deviceId.toUpperCase(), + platform: '5', + seed_time: new Date().getTime() + '', + ext_fields: `{"userAgent":"Mozilla/5.0 (Linux; Android 11; J9110 Build/55.2.A.4.332; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/124.0.6367.179 Mobile Safari/537.36 miHoYoBBSOversea/2.55.0","browserScreenSize":"387904","maxTouchPoints":"5","isTouchSupported":"1","browserLanguage":"zh-CN","browserPlat":"Linux aarch64","browserTimeZone":"Asia/Shanghai","webGlRender":"Adreno (TM) 640","webGlVendor":"Qualcomm","numOfPlugins":"0","listOfPlugins":"unknown","screenRatio":"2.625","deviceMemory":"4","hardwareConcurrency":"8","cpuClass":"unknown","ifNotTrack":"unknown","ifAdBlock":"0","hasLiedLanguage":"0","hasLiedResolution":"1","hasLiedOs":"0","hasLiedBrowser":"0","canvas":"${randomRange()}","webDriver":"0","colorDepth":"24","pixelRatio":"2.625","packageName":"unknown","packageVersion":"2.27.0","webgl":"${randomRange()}"}`, + app_name: 'hkrpg_global', + device_fp: '38d7f2364db95' + } + } + }), /** 首页宝箱 */ index: { url: `${hostRecord}game_record/app/hkrpg/api/index`, @@ -212,7 +218,7 @@ export default class apiTool { /** 养成计算器 */ compute: { url: `${host}event/rpgcalc/compute?`, - query:`game=hkrpg`, + query: `game=hkrpg`, body: data.body }, /** 详情 */ @@ -224,20 +230,27 @@ export default class apiTool { } if (this.server.startsWith('os')) { - urlMap.genshin.detail.url = 'https://sg-public-api.hoyolab.com/event/calculateos/sync/avatar/detail'// 角色天赋详情 + 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.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.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.url = + 'https://sg-public-api.hoyolab.com/event/calculateos/furniture/compute' urlMap.genshin.blueprintCompute.body = { lang: 'zh-cn', ...data.body } - urlMap.genshin.ys_ledger.url = 'https://sg-hk4e-api.hoyolab.com/event/ysledgeros/month_info'// 支持了国际服札记 + urlMap.genshin.ys_ledger.url = + 'https://sg-hk4e-api.hoyolab.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.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] } -} \ No newline at end of file +} diff --git a/src/mys/gsCfg.ts b/src/mys/gsCfg.ts index f4b7049..9bb192c 100644 --- a/src/mys/gsCfg.ts +++ b/src/mys/gsCfg.ts @@ -25,7 +25,10 @@ class GsCfg { } get element() { - return { ...this.getdefSet('element', 'role'), ...this.getdefSet('element', 'weapon') } + return { + ...this.getdefSet('element', 'role'), + ...this.getdefSet('element', 'weapon') + } } /** @@ -42,7 +45,10 @@ class GsCfg { return this.getYaml(app, name, 'config') } - return { ...this.getdefSet(app, name), ...this.getYaml(app, name, 'config') } + return { + ...this.getdefSet(app, name), + ...this.getYaml(app, name, 'config') + } } /** @@ -58,9 +64,7 @@ class GsCfg { if (this[type][key]) return this[type][key] try { - this[type][key] = YAML.parse( - fs.readFileSync(file, 'utf8') - ) + this[type][key] = YAML.parse(fs.readFileSync(file, 'utf8')) } catch (error) { logger.error(`[${app}][${name}] 格式错误 ${error}`) return false @@ -106,9 +110,9 @@ class GsCfg { await NoteUser.forEach(async function (user) { let qq = user.qq + '' let tmp = {} - lodash.forEach(user.mysUsers, (mys) => { + lodash.forEach(user.mysUsers, mys => { let uids = mys.getUids(game) - lodash.forEach(uids, (uid) => { + lodash.forEach(uids, uid => { let ckData = mys.getCkInfo(game) ckData.qq = qq if (!ck[uid]) { @@ -137,7 +141,6 @@ class GsCfg { return char?.id || false } - /** * 原神角色武器长名称缩写 * @param name 名称 @@ -203,7 +206,6 @@ class GsCfg { } } - cpCfg(app, name) { if (!fs.existsSync('./plugins/genshin/config')) { fs.mkdirSync('./plugins/genshin/config') @@ -248,7 +250,6 @@ class GsCfg { } } - // 仅供内部调用 _roleNameToID(keyword, isSr) { if (isSr) this.isSr = isSr @@ -321,7 +322,6 @@ class GsCfg { getAbbr() { console.log('gsCfg.getAbbr() 已经废弃') } - } export default new GsCfg() diff --git a/src/mys/local.js b/src/mys/local.js index 032ecd4..3dc5dae 100644 --- a/src/mys/local.js +++ b/src/mys/local.js @@ -1,2 +1,2 @@ -export * from '#miao'; -export { Character, Weapon } from '#miao.models'; \ No newline at end of file +export * from '#miao' +export { Character, Weapon } from '#miao.models' diff --git a/src/mys/mysApi.ts b/src/mys/mysApi.ts index 5aeaa03..8580eb9 100644 --- a/src/mys/mysApi.ts +++ b/src/mys/mysApi.ts @@ -70,7 +70,11 @@ export default class MysApi { } async getData(type, data = {}, cached = false) { - if (!this._device_fp && !data?.Getfp && !data?.headers?.['x-rpc-device_fp']) { + if ( + !this._device_fp && + !data?.Getfp && + !data?.headers?.['x-rpc-device_fp'] + ) { this._device_fp = await this.getData('getFp', { seed_id: this.generateSeed(16), Getfp: true @@ -92,7 +96,11 @@ export default class MysApi { headers = { ...headers, ...data.headers } } - if (type !== 'getFp' && !headers['x-rpc-device_fp'] && this._device_fp.data?.device_fp) { + if ( + type !== 'getFp' && + !headers['x-rpc-device_fp'] && + this._device_fp.data?.device_fp + ) { headers['x-rpc-device_fp'] = this._device_fp.data.device_fp } @@ -117,7 +125,9 @@ export default class MysApi { } if (!response.ok) { - logger.error(`[米游社接口][${type}][${this.uid}] ${response.status} ${response.statusText}`) + logger.error( + `[米游社接口][${type}][${this.uid}] ${response.status} ${response.statusText}` + ) return false } if (this.option.log) { @@ -148,7 +158,8 @@ export default class MysApi { } const os = { app_version: '2.55.0', - User_Agent: 'Mozilla/5.0 (Linux; Android 11; J9110 Build/55.2.A.4.332; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/124.0.6367.179 Mobile Safari/537.36 miHoYoBBSOversea/2.55.0', + User_Agent: + 'Mozilla/5.0 (Linux; Android 11; J9110 Build/55.2.A.4.332; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/124.0.6367.179 Mobile Safari/537.36 miHoYoBBSOversea/2.55.0', client_type: '2', Origin: 'https://act.hoyolab.com', X_Requested_With: 'com.mihoyo.hoyolab', @@ -164,14 +175,16 @@ export default class MysApi { 'x-rpc-app_version': client.app_version, 'x-rpc-client_type': client.client_type, 'User-Agent': client.User_Agent, - Referer: client.Referer, - DS: this.getDs(query, body) + 'Referer': client.Referer, + 'DS': this.getDs(query, body) } } getDs(q = '', b = '') { let n = '' - if (['cn_gf01', 'cn_qd01', 'prod_gf_cn', 'prod_qd_cn'].includes(this.server)) { + if ( + ['cn_gf01', 'cn_qd01', 'prod_gf_cn', 'prod_qd_cn'].includes(this.server) + ) { n = 'xV8v4Qu54lUKrEYFZkJhB8cuOh9Asafs' } else if (/os_|official/.test(this.server)) { n = 'okr4obncj8bw5a65hbnn5oo6ixjc3l9w' @@ -187,7 +200,20 @@ export default class MysApi { return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1) } - return (S4() + S4() + '-' + S4() + '-' + S4() + '-' + S4() + '-' + S4() + S4() + S4()) + return ( + S4() + + S4() + + '-' + + S4() + + '-' + + S4() + + '-' + + S4() + + '-' + + S4() + + S4() + + S4() + ) } cacheKey(type, data) { @@ -207,11 +233,13 @@ export default class MysApi { if (!/os_|official/.test(this.server)) return null if (HttpsProxyAgent === '') { - HttpsProxyAgent = await import('https-proxy-agent').catch((err) => { + HttpsProxyAgent = await import('https-proxy-agent').catch(err => { logger.error(err) }) - HttpsProxyAgent = HttpsProxyAgent ? HttpsProxyAgent.HttpsProxyAgent : undefined + HttpsProxyAgent = HttpsProxyAgent + ? HttpsProxyAgent.HttpsProxyAgent + : undefined } if (HttpsProxyAgent) { @@ -239,4 +267,4 @@ export function randomRange() { randomStr += charStr.substring(index, index + 1) } return randomStr -} \ No newline at end of file +} diff --git a/src/mys/mysInfo.ts b/src/mys/mysInfo.ts index f64b30f..9efd0dd 100644 --- a/src/mys/mysInfo.ts +++ b/src/mys/mysInfo.ts @@ -28,7 +28,22 @@ 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', 'UserGame', 'deckList', 'avatar_cardList', 'action_cardList', 'avatarInfo'] + this.auth = [ + 'dailyNote', + 'bbs_sign_info', + 'bbs_sign_home', + 'bbs_sign', + 'ys_ledger', + 'compute', + 'avatarSkill', + 'detail', + 'blueprint', + 'UserGame', + 'deckList', + 'avatar_cardList', + 'action_cardList', + 'avatarInfo' + ] this.gtest = false this.mysButton = segment.button([ @@ -36,7 +51,7 @@ export default class MysInfo { ]) } - static async init (e, api) { + static async init(e, api) { await MysInfo.initCache() let mysInfo = new MysInfo(e) @@ -58,11 +73,18 @@ export default class MysInfo { return false } - if (!['1', '2', '3', '5', '6', '7', '8', '18', '9'].includes(String(mysInfo.uid).slice(0, -8))) { + if ( + !['1', '2', '3', '5', '6', '7', '8', '18', '9'].includes( + String(mysInfo.uid).slice(0, -8) + ) + ) { // e.reply('只支持查询国服uid') return false } - if (!['6', '7', '8', '18', '9'].includes(String(mysInfo.uid).slice(0, -8)) && api === 'useCdk') { + if ( + !['6', '7', '8', '18', '9'].includes(String(mysInfo.uid).slice(0, -8)) && + api === 'useCdk' + ) { e.reply('兑换码使用只支持国际服uid') return false } @@ -83,7 +105,7 @@ export default class MysInfo { * @param matchMsgUid 用于判断消息是否为uid数据 * @returns {Promise} */ - static async getUid (e, matchMsgUid = true) { + static async getUid(e, matchMsgUid = true) { let user = await NoteUser.create(e) if (e.uid && matchMsgUid) { /** 没有绑定的自动绑定 */ @@ -100,9 +122,14 @@ export default class MysInfo { uid = atUser.getUid(e) if (uid) return String(uid) if (e.noTips !== true) { - e.reply(['尚未绑定uid', segment.button([ - { text: '绑定UID', input: '#绑定uid' } - ])], false, { at }) + e.reply( + [ + '尚未绑定uid', + segment.button([{ text: '绑定UID', input: '#绑定uid' }]) + ], + false, + { at } + ) } return false } @@ -122,9 +149,14 @@ export default class MysInfo { } if (e.noTips !== true) { - e.reply(['请先#绑定uid', segment.button([ - { text: '绑定UID', input: '#绑定uid' } - ])], false, { at: at || true }) + e.reply( + [ + '请先#绑定uid', + segment.button([{ text: '绑定UID', input: '#绑定uid' }]) + ], + false, + { at: at || true } + ) } return false @@ -135,7 +167,7 @@ export default class MysInfo { * @param e * @returns {Promise} */ - static async getSelfUid (e) { + static async getSelfUid(e) { let { msg = '', at = '' } = e if (!msg) return false @@ -144,9 +176,14 @@ export default class MysInfo { if (!selfUser.hasCk) { if (e.noTips !== true) { - e.reply(['尚未绑定Cookie', segment.button([ - { text: 'Cookie帮助', callback: '#Cookie帮助' } - ])], false, { at: selfUser.qq }) + e.reply( + [ + '尚未绑定Cookie', + segment.button([{ text: 'Cookie帮助', callback: '#Cookie帮助' }]) + ], + false, + { at: selfUser.qq } + ) } return false } @@ -172,14 +209,20 @@ export default class MysInfo { * @param option 配置 * @param option.log 是否显示请求日志 */ - static async get (e, api, data = {}, option = {}) { + static async get(e, api, data = {}, option = {}) { let mysInfo = await MysInfo.init(e, api) if (!mysInfo.uid || !mysInfo.ckInfo.ck) return false e.uid = mysInfo.uid let user = e.user?.getMysUser() - let mysApi = new MysApi(mysInfo.uid, mysInfo.ckInfo.ck, option, e.isSr, user.device) + let mysApi = new MysApi( + mysInfo.uid, + mysInfo.ckInfo.ck, + option, + e.isSr, + user.device + ) let res if (lodash.isObject(api)) { @@ -199,7 +242,12 @@ export default class MysInfo { } for (let i in res) { - res[i] = await mysInfo.checkCode(res[i], res[i].api, mysApi, api[res[i].api]) + res[i] = await mysInfo.checkCode( + res[i], + res[i].api, + mysApi, + api[res[i].api] + ) mysInfo.gtest = true if (res[i]?.retcode === 0) continue @@ -218,7 +266,7 @@ export default class MysInfo { * 初始化公共CK * @returns {Promise} */ - static async initPubCk () { + static async initPubCk() { // 初始化公共CK let pubCount = 0 let pubCks = GsCfg.getConfig('mys', 'pubCk') || [] @@ -242,10 +290,10 @@ export default class MysInfo { * 默认会将用户CK加入查询池 * @returns {Promise} */ - static async initUserCk () { + static async initUserCk() { // 初始化用户缓存 let userCount = 0 - await MysUser.forEach(async (mys) => { + await MysUser.forEach(async mys => { let ret = await mys.initCache() if (ret) { userCount++ @@ -260,16 +308,15 @@ export default class MysInfo { * @param clearData 强制初始化时是否清除已有数据 (刷新/重置) * @returns {Promise} */ - static async initCache (force = false, clearData = false) { + static async initCache(force = false, clearData = false) { // 检查缓存标记 const cache = DailyCache.create() - if (!force && await cache.get('cache-ready') || this.initing) + if ((!force && (await cache.get('cache-ready'))) || this.initing) return true this.initing = true await DailyCache.clearOutdatedData() - if (clearData) - await MysUser.clearCache() + if (clearData) await MysUser.clearCache() // 先初始化用户CK,减少一些公共CK中ltuid无法识别的情况 await MysInfo.initUserCk() @@ -281,13 +328,13 @@ export default class MysInfo { return true } - static async getBingCkUid () { + static async getBingCkUid() { let res = await GsCfg.getBingCk() return { ...res.ck } } // 获取uid绑定的ck信息 - static async checkUidBing (uid, game = 'gs') { + static async checkUidBing(uid, game = 'gs') { let ckUser = await MysUser.getByQueryUid(uid, game, true) if (ckUser && ckUser.ck) { return ckUser @@ -295,12 +342,12 @@ export default class MysInfo { return false } - static async delDisable () { + static async delDisable() { return await MysUser.delDisable() } /** 判断绑定ck才能查询 */ - checkAuth (api) { + checkAuth(api) { if (api === 'cookie') { return true } @@ -316,19 +363,25 @@ export default class MysInfo { return false } - async checkReply () { + async checkReply() { if (this.e.noTips === true) return if (!this.uid) { - this.e.reply(['请先#绑定uid', segment.button([ - { text: '绑定UID', input: '#绑定uid' } - ])], false, { at: true }) + this.e.reply( + [ + '请先#绑定uid', + segment.button([{ text: '绑定UID', input: '#绑定uid' }]) + ], + false, + { at: true } + ) } if (!this.ckInfo.ck) { - this.e.reply(['暂无可用CK,请绑定更多用户或设置公共ck..', segment.button([ - { text: 'Cookie帮助', callback: '#Cookie帮助' } - ])]) + this.e.reply([ + '暂无可用CK,请绑定更多用户或设置公共ck..', + segment.button([{ text: 'Cookie帮助', callback: '#Cookie帮助' }]) + ]) } this.e.noTips = true @@ -341,7 +394,7 @@ export default class MysInfo { * @param onlySelfCk 是否只获取uid自己对应的ck。为true则只获取uid对应ck,若无则返回为空 * @returns {Promise} 查询ck,获取失败则返回空 */ - async getCookie (game = 'gs', onlySelfCk = false) { + async getCookie(game = 'gs', onlySelfCk = false) { if (this.ckUser?.ck) return this.ckUser?.ck let mysUser = await MysUser.getByQueryUid(this.uid, game, onlySelfCk) @@ -360,9 +413,13 @@ export default class MysInfo { return this.ckUser?.ck } - async checkCode (res, type, mysApi = {}, data = {}, isTask = false) { + async checkCode(res, type, mysApi = {}, data = {}, isTask = false) { if (!res) { - if (!isTask) this.e.reply([`UID:${this.uid},米游社接口请求失败,暂时无法查询`, this.mysButton]) + if (!isTask) + this.e.reply([ + `UID:${this.uid},米游社接口请求失败,暂时无法查询`, + this.mysButton + ]) return false } @@ -384,18 +441,35 @@ export default class MysInfo { if (/(登录|login)/i.test(res.message)) { if (this.ckInfo.uid) { logger.mark(`[ck失效][uid:${this.uid}][qq:${this.userId}]`) - if (!isTask) this.e.reply([`UID:${this.ckInfo.uid},米游社Cookie已失效`, this.mysButton]) + if (!isTask) + this.e.reply([ + `UID:${this.ckInfo.uid},米游社Cookie已失效`, + this.mysButton + ]) } else { logger.mark(`[公共ck失效][ltuid:${this.ckInfo.ltuid}]`) - if (!isTask) this.e.reply([`UID:${this.uid},米游社查询失败,请稍后再试`, this.mysButton]) + if (!isTask) + this.e.reply([ + `UID:${this.uid},米游社查询失败,请稍后再试`, + this.mysButton + ]) } if (!isTask) await this.delCk() } else { - if (!isTask) this.e.reply([`UID:${this.uid},米游社接口报错,暂时无法查询:${res.message}`, this.mysButton]) + if (!isTask) + this.e.reply([ + `UID:${this.uid},米游社接口报错,暂时无法查询:${res.message}`, + this.mysButton + ]) } break case 1008: - if (!isTask) this.e.reply([`UID:${this.uid},请先去米游社绑定角色`, this.mysButton], false, { at: this.userId }) + if (!isTask) + this.e.reply( + [`UID:${this.uid},请先去米游社绑定角色`, this.mysButton], + false, + { at: this.userId } + ) break case 10101: if (!isTask) { @@ -405,9 +479,18 @@ export default class MysInfo { break case 10102: if (res.message === 'Data is not public for the user') { - if (!isTask) this.e.reply([`\nUID:${this.uid},米游社数据未公开`, this.mysButton], false, { at: this.userId }) + if (!isTask) + this.e.reply( + [`\nUID:${this.uid},米游社数据未公开`, this.mysButton], + false, + { at: this.userId } + ) } else { - if (!isTask) this.e.reply([`UID:${this.uid},请先去米游社绑定角色`, this.mysButton]) + if (!isTask) + this.e.reply([ + `UID:${this.uid},请先去米游社绑定角色`, + this.mysButton + ]) } break // 伙伴不存在~ @@ -416,7 +499,11 @@ export default class MysInfo { break case 5003: case 10041: - if (!isTask) this.e.reply([`UID:${this.uid},米游社账号异常,暂时无法查询`, this.mysButton]) + if (!isTask) + this.e.reply([ + `UID:${this.uid},米游社账号异常,暂时无法查询`, + this.mysButton + ]) break case 1034: case 10035: @@ -424,20 +511,43 @@ export default class MysInfo { // 如果有注册的mys.req.err,调用 if (handler.has('mys.req.err')) { - logger.mark(`[米游社查询][uid:${this.uid}][qq:${this.userId}] 遇到验证码,尝试调用 Handler mys.req.err`) - res = await handler.call('mys.req.err', this.e, { mysApi, type, res, data, mysInfo: this }) || res + logger.mark( + `[米游社查询][uid:${this.uid}][qq:${this.userId}] 遇到验证码,尝试调用 Handler mys.req.err` + ) + res = + (await handler.call('mys.req.err', this.e, { + mysApi, + type, + res, + data, + mysInfo: this + })) || res } if (!res || res?.retcode == 1034) { - logger.mark(`[米游社查询失败][uid:${this.uid}][qq:${this.userId}] 遇到验证码`) - if (!isTask) this.e.reply([`UID:${this.uid},米游社查询遇到验证码,请稍后再试`, this.mysButton]) + logger.mark( + `[米游社查询失败][uid:${this.uid}][qq:${this.userId}] 遇到验证码` + ) + if (!isTask) + this.e.reply([ + `UID:${this.uid},米游社查询遇到验证码,请稍后再试`, + this.mysButton + ]) } break case 10307: - if (!isTask) this.e.reply([`UID:${this.uid},版本更新期间,数据维护中`, this.mysButton]) + if (!isTask) + this.e.reply([ + `UID:${this.uid},版本更新期间,数据维护中`, + this.mysButton + ]) break default: - if (!isTask) this.e.reply([`UID:${this.uid},米游社接口报错,暂时无法查询:${res.message || 'error'}`, this.mysButton]) + if (!isTask) + this.e.reply([ + `UID:${this.uid},米游社接口报错,暂时无法查询:${res.message || 'error'}`, + this.mysButton + ]) break } if (res.retcode !== 0) { @@ -449,7 +559,7 @@ export default class MysInfo { } /** 删除失效ck */ - async delCk () { + async delCk() { if (!this.ckUser) { return false } @@ -459,8 +569,8 @@ export default class MysInfo { } /** 查询次数满,今日内标记失效 */ - async disableToday (game = 'gs') { + async disableToday(game = 'gs') { /** 统计次数设为超限 */ await this.ckUser.disable(game) } -} \ No newline at end of file +}