mirror of
https://github.com/ctrlcvs/xiaoyao-cvs-plugin.git
synced 2024-12-23 20:00:51 +08:00
220 lines
5.7 KiB
JavaScript
220 lines
5.7 KiB
JavaScript
import md5 from 'md5'
|
|
import lodash from 'lodash'
|
|
import fetch from 'node-fetch'
|
|
|
|
export default class MysApi {
|
|
/**
|
|
* @param uid 游戏uid
|
|
* @param cookie 米游社cookie
|
|
* @param option 其他参数
|
|
* @param option.log 是否显示日志
|
|
*/
|
|
constructor (uid, cookie, option = {}) {
|
|
this.uid = uid
|
|
this.cookie = cookie
|
|
this.server = this.getServer()
|
|
|
|
let op = {
|
|
log: true,
|
|
...option
|
|
}
|
|
this.option = op
|
|
}
|
|
|
|
getUrl (type, data = {}) {
|
|
let host, hostRecord
|
|
if (['cn_gf01', 'cn_qd01'].includes(this.server)) {
|
|
host = 'https://api-takumi.mihoyo.com/'
|
|
hostRecord = 'https://api-takumi-record.mihoyo.com/'
|
|
}
|
|
|
|
let urlMap = {
|
|
/** 首页宝箱 */
|
|
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}`
|
|
},
|
|
/** 签到信息 */
|
|
bbs_sign_info: {
|
|
url: `${host}event/bbs_sign_reward/info`,
|
|
query: `act_id=e202009291139501®ion=${this.server}&uid=${this.uid}`,
|
|
sign: true
|
|
},
|
|
/** 签到奖励 */
|
|
bbs_sign_home: {
|
|
url: `${host}event/bbs_sign_reward/home`,
|
|
query: `act_id=e202009291139501®ion=${this.server}&uid=${this.uid}`,
|
|
sign: true
|
|
},
|
|
/** 签到 */
|
|
bbs_sign: {
|
|
url: `${host}event/bbs_sign_reward/sign`,
|
|
body: { act_id: 'e202009291139501', region: this.server, uid: this.uid },
|
|
sign: true
|
|
},
|
|
/** 详情 */
|
|
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
|
|
},
|
|
/** 角色技能 */
|
|
avatarSkill: {
|
|
url: `${host}event/e20200928calculate/v1/avatarSkill/list`,
|
|
query: `avatar_id=${data.avatar_id}`
|
|
}
|
|
}
|
|
|
|
if (!urlMap[type]) return false
|
|
|
|
let { url, query = '', body = '', sign = '' } = urlMap[type]
|
|
|
|
if (query) url += `?${query}`
|
|
if (body) body = JSON.stringify(body)
|
|
|
|
let headers = this.getHeaders(query, body, sign)
|
|
|
|
return { url, headers, body }
|
|
}
|
|
|
|
getServer () {
|
|
let uid = this.uid
|
|
switch (String(uid)[0]) {
|
|
case '1':
|
|
case '2':
|
|
return 'cn_gf01' // 官服
|
|
case '5':
|
|
return 'cn_qd01' // B服
|
|
}
|
|
return 'cn_gf01'
|
|
}
|
|
|
|
async getData (type, data = {}, isForce = true) {
|
|
let { url, headers, body } = this.getUrl(type, data)
|
|
|
|
if (!url) return false
|
|
|
|
let cahce = await redis.get(`Yz:genshin:mys:cache:${type}:${this.uid}`)
|
|
if (cahce && !isForce) return JSON.parse(cahce)
|
|
|
|
headers.Cookie = this.cookie
|
|
let param = {
|
|
headers,
|
|
timeout: 10000
|
|
}
|
|
|
|
if (body) {
|
|
param.method = 'post'
|
|
param.body = body
|
|
} else {
|
|
param.method = 'get'
|
|
}
|
|
let response = {}
|
|
let start = Date.now()
|
|
try {
|
|
response = await fetch(url, param)
|
|
} catch (error) {
|
|
logger.error(error)
|
|
return false
|
|
}
|
|
|
|
if (!response.ok) {
|
|
logger.error(response)
|
|
return false
|
|
}
|
|
if (this.option.log) {
|
|
logger.mark(`[米游社接口][${type}][${this.uid}] ${Date.now() - start}ms`)
|
|
}
|
|
const res = await response.json()
|
|
|
|
if (!res) {
|
|
logger.mark('mys接口没有返回')
|
|
return false
|
|
}
|
|
|
|
if (res.retcode !== 0) {
|
|
logger.debug(`[米游社接口][请求参数] ${url} ${JSON.stringify(param)}`)
|
|
}
|
|
|
|
res.api = type
|
|
|
|
this.cache(res, type)
|
|
|
|
return res
|
|
}
|
|
|
|
getHeaders (query = '', body = '', sign = false) {
|
|
if (sign) {
|
|
return {
|
|
'x-rpc-app_version': '2.3.0',
|
|
'x-rpc-client_type': 5,
|
|
'x-rpc-device_id': this.getGuid(),
|
|
'User-Agent': ' miHoYoBBS/2.3.0',
|
|
DS: this.getDsSign()
|
|
}
|
|
}
|
|
return {
|
|
'x-rpc-app_version': '2.31.1',
|
|
'x-rpc-client_type': 5,
|
|
DS: this.getDs(query, body)
|
|
}
|
|
}
|
|
|
|
getDs (q = '', b = '') {
|
|
let n = ''
|
|
if (['cn_gf01', 'cn_qd01'].includes(this.server)) {
|
|
n = 'xV8v4Qu54lUKrEYFZkJhB8cuOh9Asafs'
|
|
}
|
|
let t = Math.round(new Date().getTime() / 1000)
|
|
let r = Math.floor(Math.random() * 900000 + 100000)
|
|
let DS = md5(`salt=${n}&t=${t}&r=${r}&b=${b}&q=${q}`)
|
|
return `${t},${r},${DS}`
|
|
}
|
|
|
|
/** 签到ds */
|
|
getDsSign () {
|
|
const n = 'h8w582wxwgqvahcdkpvdhbh2w9casgfl'
|
|
const t = Math.round(new Date().getTime() / 1000)
|
|
const r = lodash.sampleSize('abcdefghijklmnopqrstuvwxyz0123456789', 6).join('')
|
|
const DS = md5(`salt=${n}&t=${t}&r=${r}`)
|
|
return `${t},${r},${DS}`
|
|
}
|
|
|
|
getGuid () {
|
|
function S4 () {
|
|
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
|
|
}
|
|
|
|
return (S4() + S4() + '-' + S4() + '-' + S4() + '-' + S4() + '-' + S4() + S4() + S4())
|
|
}
|
|
|
|
async cache (res, type) {
|
|
if (!res || res.retcode !== 0) return
|
|
redis.setEx(`Yz:genshin:mys:cache:${type}:${this.uid}`, 300, JSON.stringify(res))
|
|
}
|
|
}
|