update plugins/genshin/model/mys/apiTool.js.
Signed-off-by: hbj白夜 <hei_bai_jun@163.com>
This commit is contained in:
		
							parent
							
								
									388cd7659f
								
							
						
					
					
						commit
						8893df2ee4
					
				|  | @ -1,472 +1,244 @@ | |||
| import MysApi from './mysApi.js' | ||||
| import GsCfg from '../gsCfg.js' | ||||
| import lodash from 'lodash' | ||||
| import fetch from 'node-fetch' | ||||
| import NoteUser from './NoteUser.js' | ||||
| import MysUser from './MysUser.js' | ||||
| import DailyCache from './DailyCache.js' | ||||
| import common from '../../../../lib/common/common.js' | ||||
| 
 | ||||
| export default class MysInfo { | ||||
|   static tips = '请先#绑定cookie\n发送【体力帮助】查看配置教程' | ||||
| 
 | ||||
|   constructor(e) { | ||||
|     if (e) { | ||||
|       this.e = e | ||||
|       this.userId = String(e.user_id) | ||||
|     } | ||||
|     /** 当前查询原神uid */ | ||||
|     this.uid = '' | ||||
|     /** 当前ck信息 */ | ||||
|     this.ckInfo = { | ||||
|       ck: '', | ||||
|       uid: '', | ||||
|       qq: '', | ||||
|       ltuid: '', | ||||
|       type: '' | ||||
|     } | ||||
|     // 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'] | ||||
|   } | ||||
| 
 | ||||
|   static async init(e, api) { | ||||
|     await MysInfo.initCache() | ||||
| 
 | ||||
|     let mysInfo = new MysInfo(e) | ||||
| 
 | ||||
|     let onlySelfCk = false | ||||
| 
 | ||||
|     if (mysInfo.checkAuth(api)) { | ||||
|       /** 获取ck绑定uid */ | ||||
|       mysInfo.uid = await MysInfo.getSelfUid(e) | ||||
|       // 标记需要自身ck
 | ||||
|       onlySelfCk = true | ||||
|     } else { | ||||
|       /** 获取uid */ | ||||
|       mysInfo.uid = await MysInfo.getUid(e) | ||||
|     } | ||||
| 
 | ||||
|     if (!mysInfo.uid) { | ||||
|       e.noTips = true | ||||
|       return false | ||||
|     } | ||||
| 
 | ||||
|     if (!['1', '2', '5', '6', '7', '8', '9'].includes(String(mysInfo.uid)[0])) { | ||||
|       // e.reply('只支持查询国服uid')
 | ||||
|       return false | ||||
|     } | ||||
|     if (!['6', '7', '8', '9'].includes(String(mysInfo.uid)[0]) && api === 'useCdk') { | ||||
|       e.reply('兑换码使用只支持国际服uid') | ||||
|       return false | ||||
|     } | ||||
| 
 | ||||
|     mysInfo.e.uid = mysInfo.uid | ||||
| 
 | ||||
|     /** 获取ck */ | ||||
|     await mysInfo.getCookie(e, onlySelfCk) | ||||
| 
 | ||||
|     /** 判断回复 */ | ||||
|     await mysInfo.checkReply() | ||||
|     return mysInfo | ||||
|   } | ||||
| 
 | ||||
| /** | ||||
|  * 整合接口用于查询数据 | ||||
|  * 方便后续用于解耦 | ||||
|  * 临时处理,后续大概率重写 主要原因(懒) | ||||
|  */ | ||||
| export default class apiTool { | ||||
|   /** | ||||
|    * 获取UID | ||||
|    * @param e | ||||
|    * @param matchMsgUid 用于判断消息是否为uid数据 | ||||
|    * @returns {Promise<string|boolean|*|string>} | ||||
|    * | ||||
|    * @param {用户uid} uid | ||||
|    * @param {区服} server | ||||
|    * @param {是否为星穹铁道或其他游戏? type(bool or string)} isSr | ||||
|    */ | ||||
|   static async getUid(e, matchMsgUid = true) { | ||||
|     let user = await NoteUser.create(e) | ||||
|     if (e.uid && matchMsgUid) { | ||||
|       /** 没有绑定的自动绑定 */ | ||||
|       return user.autoRegUid(e.uid, e) | ||||
|   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 | ||||
|     } | ||||
| 
 | ||||
|     let { msg = '', at = '' } = e | ||||
|     if (!msg) return false | ||||
| 
 | ||||
|     let uid | ||||
|     /** at用户 */ | ||||
|     if (at) { | ||||
|       let atUser = await NoteUser.create(at) | ||||
|       uid = atUser.getUid(e) | ||||
|       if (uid) return String(uid) | ||||
|       if (e.noTips !== true) e.reply('尚未绑定uid', false, { at }) | ||||
|       return false | ||||
|     } | ||||
| 
 | ||||
|     let matchUid = (msg = '') => { | ||||
|       let ret = /[125-9][0-9]{8}/g.exec(msg) | ||||
|       if (!ret) return false | ||||
|       return ret[0] | ||||
|     } | ||||
| 
 | ||||
|     // 消息携带UID、当前用户UID、群名片携带UID 依次获取
 | ||||
|     uid = matchUid(msg) || user.getUid(e) || matchUid(e.sender.card) | ||||
|     if (!matchMsgUid) uid = user.getUid(e) | ||||
|     if (uid) { | ||||
|       /** 没有绑定的自动绑定 */ | ||||
|       return user.autoRegUid(uid, e) | ||||
|     } | ||||
| 
 | ||||
|     if (e.noTips !== true) e.reply('请先#绑定uid', false, { at }) | ||||
| 
 | ||||
|     return false | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * 获取ck绑定uid | ||||
|    * @param e | ||||
|    * @returns {Promise<boolean|*>} | ||||
|    */ | ||||
|   static async getSelfUid(e) { | ||||
|     let { msg = '', at = '' } = e | ||||
|     if (!msg) return false | ||||
| 
 | ||||
|     let user = await NoteUser.create(e) | ||||
|     let selfUser = at ? await NoteUser.create(at) : user | ||||
| 
 | ||||
|     if (!selfUser.hasCk) { | ||||
|       if (e.noTips !== true) e.reply('尚未绑定cookie', false, { at: selfUser.qq }) | ||||
|       return false | ||||
|   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/' | ||||
|     } | ||||
| 
 | ||||
|     return selfUser.getUid(e) | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * @param e | ||||
|    * @param e.apiSync 多个请求时是否同步请求 | ||||
|    * @param e.noTips  是否回复提示,用于第一次调用才提示,后续不再提示 | ||||
|    * @param api | ||||
|    * * `index` 米游社原神首页宝箱等数据 | ||||
|    * * `spiralAbyss` 原神深渊 | ||||
|    * * `character` 原神角色详情 | ||||
|    * * `dailyNote` 原神树脂 | ||||
|    * * `bbs_sign` 米游社原神签到 | ||||
|    * * `detail` 详情 | ||||
|    * * `ys_ledger` 札记 | ||||
|    * * `compute` 养成计算器 | ||||
|    * * `avatarSkill` 角色技能 | ||||
|    * @param data 查询数据data | ||||
|    * @param option 配置 | ||||
|    * @param option.log 是否显示请求日志 | ||||
|    */ | ||||
|   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 res | ||||
|     if (lodash.isObject(api)) { | ||||
|       let all = [] | ||||
|       /** 同步请求 */ | ||||
|       if (e.apiSync) { | ||||
|         res = [] | ||||
|         for (let i in api) { | ||||
|           res.push(await mysApi.getData(i, api[i])) | ||||
|     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}` | ||||
|         }, | ||||
|         /**七圣牌组 */ | ||||
|         deckList: { | ||||
|           url: `${hostRecord}game_record/app/genshin/api/gcg/deckList`, | ||||
|           query: `role_id=${this.uid}&server=${this.server}` | ||||
|         }, | ||||
|         /** 七圣召唤角色牌数据 */ | ||||
|         avatar_cardList: { | ||||
|           url: `${hostRecord}game_record/app/genshin/api/gcg/cardList`, | ||||
|           query: `limit=999&need_action=false&need_avatar=true&need_stats=true&offset=0&role_id=${this.uid}&server=${this.server}` | ||||
|         }, | ||||
|         /** 七圣召唤行动牌数据 */ | ||||
|         action_cardList: { | ||||
|           url: `${hostRecord}game_record/app/genshin/api/gcg/cardList`, | ||||
|           query: `limit=999&need_action=true&need_avatar=false&need_stats=true&offset=0&role_id=${this.uid}&server=${this.server}` | ||||
|         }, | ||||
|         /**使用兑换码 目前仅限国际服,来自于国服的uid请求已在myinfo.js的init方法提前拦截 */ | ||||
|         useCdk: { | ||||
|           url: 'PLACE_HOLDER', | ||||
|           query: null | ||||
|         }, | ||||
|         /** 米游社验证 */ | ||||
|         createVerification: { | ||||
|           url: `${hostRecord}game_record/app/card/wapi/createVerification`, | ||||
|           query: 'is_high=true' | ||||
|         }, | ||||
|         /** 米游社验证 */ | ||||
|         verifyVerification: { | ||||
|           url: `${hostRecord}game_record/app/card/wapi/verifyVerification`, | ||||
|           body: data | ||||
|         }, | ||||
|         /** 体力接口fp参数用于避开验证码 */ | ||||
|         getFp: { | ||||
|           url: `https://public-data-api.mihoyo.com/device-fp/api/getFp`, | ||||
|           body: { | ||||
|             seed_id: data.seed_id, | ||||
|             device_id: data.deviceId, | ||||
|             platform: '1', | ||||
|             seed_time: new Date().getTime() + '', | ||||
|             ext_fields: '{"proxyStatus":"0","accelerometer":"-0.159515x-0.830887x-0.682495","ramCapacity":"3746","IDFV":"8F4E403B-4C28-4F7F-B740-2DD317948B8A","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' | ||||
|           }, | ||||
|         } | ||||
|       } else { | ||||
|         lodash.forEach(api, (v, i) => { | ||||
|           all.push(mysApi.getData(i, v)) | ||||
|         }) | ||||
|         res = await Promise.all(all) | ||||
|       } | ||||
| 
 | ||||
|       for (let i in res) { | ||||
|         res[i] = await mysInfo.checkCode(res[i], res[i].api, mysApi, api[res[i].api]) | ||||
| 
 | ||||
|         if (res[i]?.retcode === 0) continue | ||||
| 
 | ||||
|         break | ||||
|       } | ||||
|     } else { | ||||
|       res = await mysApi.getData(api, data) | ||||
|       res = await mysInfo.checkCode(res, api, mysApi, data) | ||||
|       if (res === 'repeat') { | ||||
|         res = await mysApi.getData(api, data) | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     return res | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * 初始化公共CK | ||||
|    * @returns {Promise<void>} | ||||
|    */ | ||||
|   static async initPubCk() { | ||||
|     // 初始化公共CK
 | ||||
|     let pubCount = 0 | ||||
|     let pubCks = GsCfg.getConfig('mys', 'pubCk') || [] | ||||
|     for (let ck of pubCks) { | ||||
|       let pubUser = await MysUser.create(ck) | ||||
|       if (pubUser) { | ||||
|         let ret = await pubUser.initCache({ qq: 'pub' }) | ||||
|         if (ret) { | ||||
|           pubCount++ | ||||
|         } | ||||
|         if (pubCount >= 20) { | ||||
|           break | ||||
|       }, | ||||
|       honkaisr: { | ||||
|         /** 首页宝箱 */ | ||||
|         index: { | ||||
|           url: `${hostRecord}game_record/app/hkrpg/api/index`, | ||||
|           query: `role_id=${this.uid}&server=${this.server}` | ||||
|         }, | ||||
|         basicInfo: { | ||||
|           url: `${hostRecord}game_record/app/hkrpg/api/role/basicInfo`, | ||||
|           query: `role_id=${this.uid}&server=${this.server}` | ||||
|         }, | ||||
|         UserGame: { | ||||
|           url: `${host}binding/api/getUserGameRolesByCookie`, | ||||
|           query: `game_biz=hkrpg_cn` | ||||
|         }, | ||||
|         /** 深渊 (混沌回忆) */ | ||||
|         spiralAbyss: { | ||||
|           url: `${hostRecord}game_record/app/hkrpg/api/challenge`, | ||||
|           query: `role_id=${this.uid}&schedule_type=${data.schedule_type || 1}&server=${this.server}` | ||||
|         }, | ||||
|         avatarInfo: { | ||||
|           url: `${hostRecord}game_record/app/hkrpg/api/avatar/info`, | ||||
|           query: `need_wiki=true&role_id=${this.uid}&server=${this.server}` | ||||
|         }, | ||||
|         /** 体力接口fp参数用于避开验证码 */ | ||||
|         getFp: { | ||||
|           url: `https://public-data-api.mihoyo.com/device-fp/api/getFp`, | ||||
|           body: { | ||||
|             seed_id: data.seed_id, | ||||
|             device_id: data.deviceId, | ||||
|             platform: '5', | ||||
|             seed_time: new Date().getTime() + '', | ||||
|             ext_fields: '{"userAgent":"Mozilla/5.0 (iPhone; CPU iPhone OS 16_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/2.40.1","browserScreenSize":281520,"maxTouchPoints":5,"isTouchSupported":true,"browserLanguage":"zh-CN","browserPlat":"iPhone","browserTimeZone":"Asia/Shanghai","webGlRender":"Apple GPU","webGlVendor":"Apple Inc.","numOfPlugins":0,"listOfPlugins":"unknown","screenRatio":3,"deviceMemory":"unknown","hardwareConcurrency":"4","cpuClass":"unknown","ifNotTrack":"unknown","ifAdBlock":0,"hasLiedResolution":1,"hasLiedOs":0,"hasLiedBrowser":0}', | ||||
|             app_name: 'account_cn', | ||||
|             device_fp: '38d7ee834d1e9' | ||||
|           }, | ||||
|         }, | ||||
|         /** | ||||
|          * 开拓阅历接口 | ||||
|          */ | ||||
|         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/basic`, | ||||
|           query: `role_id=${this.uid}&server=${this.server}` | ||||
|         }, | ||||
|         /** 树脂 */ | ||||
|         dailyNote: { | ||||
|           url: `${hostRecord}game_record/app/hkrpg/api/note`, | ||||
|           query: `role_id=${this.uid}&server=${this.server}` | ||||
|         }, | ||||
|         /** 养成计算器 */ | ||||
|         compute: { | ||||
|           url: `${host}event/rpgcalc/compute?`, | ||||
|           query:`game=hkrpg`, | ||||
|           body: data | ||||
|         }, | ||||
|         /** 米游社验证 */ | ||||
|         createVerification: { | ||||
|         url: 'https://bbs-api.mihoyo.com/misc/api/createVerification', | ||||
|         query: 'is_high=true', | ||||
|         sign: true | ||||
|         }, | ||||
|         /** 米游社验证 */ | ||||
|         verifyVerification: { | ||||
|         url: 'https://bbs-api.mihoyo.com/misc/api/verifyVerification', | ||||
|         body: data | ||||
|         }, | ||||
|         /** 详情 */ | ||||
|         detail: { | ||||
|           url: `${host}event/rpgcalc/avatar/detail`, | ||||
|           query: `game=hkrpg&lang=zh-cn&item_id=${data.avatar_id}&tab_from=${data.tab_from}&change_target_level=0&uid=${this.uid}®ion=${this.server}` | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     logger.mark(`加载公共ck:${pubCount}个`) | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * 初始化用户CK | ||||
|    * 默认会将用户CK加入查询池 | ||||
|    * @returns {Promise<void>} | ||||
|    */ | ||||
|   static async initUserCk() { | ||||
|     // 初始化用户缓存
 | ||||
|     let userCount = 0 | ||||
|     await MysUser.forEach(async (mys) => { | ||||
|       let ret = await mys.initCache() | ||||
|       if (ret) { | ||||
|         userCount++ | ||||
|       } | ||||
|     }) | ||||
|     logger.mark(`加载用户UID:${userCount}个,加入查询池`) | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * 初始化缓存 | ||||
|    * @param force 若已经初始化是否强制初始化 | ||||
|    * @param clearData 强制初始化时是否清除已有数据 (刷新/重置) | ||||
|    * @returns {Promise<boolean>} | ||||
|    */ | ||||
|   static async initCache(force = false, clearData = false) { | ||||
|     // 检查缓存标记
 | ||||
|     let cache = DailyCache.create() | ||||
|     if (!force && await cache.get('cache-ready')) { | ||||
|       return true | ||||
|     if (this.server.startsWith('os')) { | ||||
|       urlMap.genshin.bbs_sign_info.url = 'https://hk4e-api-os.hoyoverse.com/event/sol/info' | ||||
|       urlMap.genshin.bbs_sign_info.query = `act_id=e202102251931481®ion=${this.server}&uid=${this.uid}` | ||||
|       urlMap.genshin.bbs_sign_home.url = 'https://hk4e-api-os.hoyoverse.com/event/sol/home' | ||||
|       urlMap.genshin.bbs_sign_home.query = `act_id=e202102251931481®ion=${this.server}&uid=${this.uid}` | ||||
|       urlMap.genshin.bbs_sign.url = 'https://hk4e-api-os.hoyoverse.com/event/sol/sign' | ||||
|       urlMap.genshin.bbs_sign.body = { act_id: 'e202102251931481', region: this.server, uid: this.uid } | ||||
|       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` | ||||
|     } | ||||
|     await DailyCache.clearOutdatedData() | ||||
|     if (this.isSr && this.server.includes('official')) { | ||||
|       urlMap.honkaisr.bbs_sign.url = 'https://sg-public-api.hoyolab.com/event/luna/os/sign' | ||||
|       urlMap.honkaisr.bbs_sign.body = { act_id: 'e202303301540311', lang: 'zh-cn' } | ||||
|       urlMap.honkaisr.bbs_sign_home.url = 'https://sg-public-api.hoyolab.com/event/luna/os/home' | ||||
|       urlMap.honkaisr.bbs_sign_home.query = `act_id=e202303301540311®ion=${this.server}&uid=${this.uid}&lang=zh-cn` | ||||
| 
 | ||||
|     if (clearData) { | ||||
|       await MysUser.clearCache() | ||||
|       urlMap.honkaisr.bbs_sign_info.url = 'https://sg-public-api.hoyolab.com/event/luna/os/info' | ||||
|       urlMap.honkaisr.bbs_sign_info.query = `act_id=e202303301540311®ion=${this.server}&uid=${this.uid}&lang=zh-cn` | ||||
|     } | ||||
| 
 | ||||
|     // 先初始化用户CK,减少一些公共CK中ltuid无法识别的情况
 | ||||
|     await MysInfo.initUserCk() | ||||
| 
 | ||||
|     await cache.set('cache-ready', new Date() * 1) | ||||
| 
 | ||||
|     // 初始化公共ck
 | ||||
|     await MysInfo.initPubCk() | ||||
| 
 | ||||
|     return true | ||||
|   } | ||||
| 
 | ||||
|   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(game) | ||||
|       } | ||||
|     } | ||||
|     return this.ckUser?.ck | ||||
|   } | ||||
| 
 | ||||
|   async checkCode(res, type, mysApi = {}, data = {}, isTask = false) { | ||||
|     if (!res) { | ||||
|       if (!isTask) this.e.reply('米游社接口请求失败,暂时无法查询') | ||||
|       return false | ||||
|     } | ||||
| 
 | ||||
|     res.retcode = Number(res.retcode) | ||||
|     if (type === 'bbs_sign') { | ||||
|       if ([-5003].includes(res.retcode)) { | ||||
|         res.retcode = 0 | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     switch (res.retcode) { | ||||
|       case 0: | ||||
|         break | ||||
|       case -1: | ||||
|       case -100: | ||||
|       case 1001: | ||||
|       case 10001: | ||||
|       case 10103: | ||||
|         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已失效`) | ||||
|           } else { | ||||
|             logger.mark(`[公共ck失效][ltuid:${this.ckInfo.ltuid}]`) | ||||
|             if (!isTask) this.e.reply('米游社查询失败,请稍后再试') | ||||
|           } | ||||
|           if (!isTask) await this.delCk() | ||||
|         } else { | ||||
|           if (!isTask) this.e.reply(`米游社接口报错,暂时无法查询:${res.message}`) | ||||
|         } | ||||
|         break | ||||
|       case 1008: | ||||
|         if (!isTask) this.e.reply('\n请先去米游社绑定角色', false, { at: this.userId }) | ||||
|         break | ||||
|       case 10101: | ||||
|         if (!isTask) { | ||||
|           await this.disableToday() | ||||
|           this.e.reply('查询已达今日上限') | ||||
|         } | ||||
|         break | ||||
|       case 10102: | ||||
|         if (res.message === 'Data is not public for the user') { | ||||
|           if (!isTask) this.e.reply(`\nUID:${this.uid},米游社数据未公开`, false, { at: this.userId }) | ||||
|         } else { | ||||
|           if (!isTask) this.e.reply(`uid:${this.uid},请先去米游社绑定角色`) | ||||
|         } | ||||
|         break | ||||
|       // 伙伴不存在~
 | ||||
|       case -1002: | ||||
|         if (res.api === 'detail') res.retcode = 0 | ||||
|         break | ||||
|       case 1034: | ||||
|         if (await this.bbsVerification()) { | ||||
|           return 'repeat' | ||||
|         } | ||||
|         logger.mark(`[米游社查询失败][uid:${this.uid}][qq:${this.userId}] 遇到验证码`) | ||||
|         if (!isTask) this.e.reply('米游社查询遇到验证码,请稍后再试') | ||||
|         break | ||||
|       default: | ||||
|         if (!isTask) this.e.reply(`米游社接口报错,暂时无法查询:${res.message || 'error'}`) | ||||
|         break | ||||
|     } | ||||
|     if (res.retcode !== 0) { | ||||
|       logger.mark(`[mys接口报错]${JSON.stringify(res)},uid:${this.uid}`) | ||||
|     } | ||||
|     // 添加请求记录
 | ||||
|     if (!isTask) await this.ckUser.addQueryUid(this.uid) | ||||
|     return res | ||||
|   } | ||||
|     /** 刷新米游社验证 */ | ||||
|     async bbsVerification () { | ||||
|       let create = await MysInfo.get(this.e, 'createVerification') | ||||
|       if (!create || create.retcode !== 0) return false | ||||
|    | ||||
|       let verify = await MysInfo.verify(this.e, { uid: this.uid, ...create.data }) | ||||
|       if (!verify) return false | ||||
|    | ||||
|       let submit = await MysInfo.get(this.e, 'verifyVerification', verify) | ||||
|       if (!submit || submit.retcode !== 0) return false | ||||
|    | ||||
|       return true | ||||
|     } | ||||
|    | ||||
|     /** 手动验证 */ | ||||
|     static async verify (e, data) { | ||||
|       if (!data.gt || !data.challenge || !e?.reply) return false | ||||
|       let cfg = { ...GsCfg.getdefSet('mys', 'set'), ...GsCfg.getYaml('mys', 'set', 'config') } | ||||
|       if (!cfg.verify || !cfg.verifyAddr) return false | ||||
|    | ||||
|       /** 传递gt、challenge参数,返回link、result地址 */ | ||||
|       let res = await fetch(cfg.verifyAddr, { | ||||
|         method: 'POST', | ||||
|         body: JSON.stringify(data) | ||||
|       }) | ||||
|       res = await res.json() | ||||
|       if (!res.data) return false | ||||
|    | ||||
|       await e.reply(`请打开地址并完成验证\n${res.data.link}`, true) | ||||
|       for (let i = 0; i < 60; i++) { | ||||
|         let validate = await fetch(res.data.result) | ||||
|         validate = await validate.json() | ||||
|         if (validate.data) { | ||||
|           logger.mark(`[米游社验证成功][uid:${e.uid || data.uid}][qq:${e.user_id}]`) | ||||
|           return validate.data | ||||
|         } | ||||
|         await common.sleep(2000) | ||||
|       } | ||||
|       return false | ||||
|     } | ||||
| 
 | ||||
|   /** 删除失效ck */ | ||||
|   async delCk() { | ||||
|     if (!this.ckUser) { | ||||
|       return false | ||||
|     } | ||||
|     let ckUser = this.ckUser | ||||
|     // 删除记录,并清除对应user ck记录
 | ||||
|     await ckUser.delWithUser() | ||||
|   } | ||||
| 
 | ||||
|   /** 查询次数满,今日内标记失效 */ | ||||
|   async disableToday(game = 'gs') { | ||||
|     /** 统计次数设为超限 */ | ||||
|     await this.ckUser.disable(game) | ||||
|     return urlMap[this.game] | ||||
|   } | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue