2
0
mirror of https://github.com/ctrlcvs/xiaoyao-cvs-plugin.git synced 2024-12-23 11:40:51 +08:00
xiaoyao-cvs-plugin/model/mys/mihoyoApi.js

464 lines
13 KiB
JavaScript
Raw Normal View History

2022-10-12 16:51:51 +08:00
import utils from './utils.js';
import md5 from 'md5';
import _ from 'lodash';
import fs from "fs";
import YAML from 'yaml'
import {
Data
} from "../../components/index.js";
import gsCfg from '../gsCfg.js'
import {
isV3
} from '../../components/Changelog.js';
import fetch from "node-fetch"
import mys from "./mysTool.js"
const _path = process.cwd();
const DEVICE_ID = utils.randomString(32).toUpperCase();
const DEVICE_NAME = utils.randomString(_.random(1, 10));
const yamlDataUrl = `${_path}/plugins/xiaoyao-cvs-plugin/data/yaml`;
let HttpsProxyAgent = ''
// 米游社的版块
export default class miHoYoApi {
constructor(e) {
if (e) {
this.e = e
this.cookie = e.cookie
this.userId = String(e.user_id)
this.yuntoken = e.yuntoken
this.devId = e.devId
this.isOs = false;
if (this.e?.uid) {
this.isOs = this.e?.uid[0] * 1 > 5
}
2022-10-12 21:16:44 +08:00
this.apiMap = {
apiWeb: mys.web_api,
saltweb: mys.saltWeb,
saltSign: mys.salt
2022-10-12 16:51:51 +08:00
}
2022-10-12 21:16:44 +08:00
if (this.isOs) {
this.apiMap = {
apiWeb: mys.os_web_api,
saltweb: mys.saltWeb, //os websalt待定中
saltSign: mys.salt
2022-10-12 16:51:51 +08:00
}
}
// //初始化配置文件
let data = this.getStoken(this.e.user_id);
if (data) {
this.cookies = `stuid=${data.stuid};stoken=${data.stoken};ltoken=${data.ltoken};`;
2022-12-10 18:05:04 +08:00
if (data?.mid) {
2022-12-10 15:29:21 +08:00
this.cookies = `stuid=${data.stuid};stoken=${data.stoken};mid=${data.mid};`;
}
2022-10-12 16:51:51 +08:00
this.e.cookies = this.cookies
}
}
Data.createDir("", yamlDataUrl, false);
}
getBody(name) {
for (let item in mys.boards) {
if (mys.boards[item].name === name) {
return mys.boards[item]
}
}
}
async getData(type, data = {}) {
let gameBody = this.getBody(data.name);
let {
url,
headers,
body
} = this.getUrl(type, gameBody, data)
if (!url) return false
if (data.headers) {
headers = {
...headers,
...data.headers
}
delete data.headers
}
let param = {
headers,
agent: await this.getAgent(),
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.toString())
return false
}
if (!response.ok) {
Bot.logger.error(`[接口][${type}][${this.e.uid}] ${response.status} ${response.statusText}`)
return false
}
2022-10-12 21:16:44 +08:00
let res = await response.text();
2022-12-10 18:05:04 +08:00
// Bot.logger.mark(`[接口][${type}][${this.e.uid}] ${Date.now() - start}ms\n${res}`)
2022-10-12 21:16:44 +08:00
if (res.startsWith('(')) {
res = JSON.parse((res).replace(/\(|\)/g, ""))
} else {
res = JSON.parse(res)
}
2022-10-12 16:51:51 +08:00
if (!res) {
Bot.logger.mark('mys接口没有返回')
return false
}
if (res.retcode !== 0) {
Bot.logger.debug(`[米游社接口][请求参数] ${url} ${JSON.stringify(param)}`)
}
res.api = type
2022-10-12 21:16:44 +08:00
2022-10-12 16:51:51 +08:00
return res
}
getUrl(type, board, data) {
let urlMap = {
userGameInfo: { //通用查询
url: `${this.apiMap.apiWeb}/binding/api/getUserGameRolesByCookie`,
2022-12-03 23:52:06 +08:00
query: `game_biz=${this.isOs ? board?.osbiz : board?.biz}`,
2022-10-12 16:51:51 +08:00
types: 'sign'
},
2022-10-12 21:16:44 +08:00
isSign: board?.signUrl(data, "isSign", this.apiMap.apiWeb) || {},
sign: board?.signUrl(data, "sign", this.apiMap.apiWeb) || {},
home: board?.signUrl(data, "home", this.apiMap.apiWeb) || {},
2022-10-12 16:51:51 +08:00
//bbs接口 hoyolab那边不是很需要 这边不进行优化处理
bbsisSign: { //bbs 签到 (状态查询 米游币查询)
url: `${mys.bbs_api}/apihub/sapi/getUserMissionsState`,
types: 'bbs'
},
bbsSign: { //bbs讨论区签到
url: `${mys.bbs_api}/apihub/app/api/signIn`,
body: {
2022-10-12 21:16:44 +08:00
gids: data.forumId * 1
2022-10-12 16:51:51 +08:00
},
sign: true,
types: 'bbs'
},
2022-10-12 21:16:44 +08:00
bbsGetCaptcha: {
url: `${mys.bbs_api}/misc/api/createVerification`,
2022-11-24 23:12:36 +08:00
query: `is_high=false`,
2022-10-12 21:16:44 +08:00
types: 'bbs'
2022-10-12 16:51:51 +08:00
},
2022-10-12 21:16:44 +08:00
bbsValidate: {
url: `https://apiv6.geetest.com/ajax.php`,
query: `gt=${data.gt}&challenge=${data.challenge}&lang=zh-cn&pt=3&client_type=web_mobile`,
2022-10-12 16:51:51 +08:00
},
2022-10-12 21:16:44 +08:00
bbsCaptchaVerify: {
2022-11-24 23:12:36 +08:00
url: `${mys.bbs_api}/misc/api/verifyVerification`,
2022-12-03 23:52:06 +08:00
types: 'bbs'
2022-10-12 16:51:51 +08:00
},
bbsCaptchaVerify: {
url: `https://api.geetest.com/gettype.php`,
2022-12-03 23:52:06 +08:00
query: ``
},
2022-10-12 21:16:44 +08:00
//待定接口 用于获取用户米游社顶部的模块栏
bbs_Businesses_url: {
url: `${mys.bbs_api}/user/api/getUserBusinesses`,
query: `uid={}` //????
2022-10-12 16:51:51 +08:00
},
bbsPostList: { //bbs讨论区签到
url: `${mys.bbs_api}/post/api/getForumPostList`,
query: `forum_id=${data.forumId}&is_good=false&is_hot=false&page_size=20&sort_type=1`,
types: 'bbs'
},
bbsPostFull: { //bbs讨论区签到
url: `${mys.bbs_api}/post/api/getPostFull`,
query: `post_id=${data.postId}`,
types: 'bbs'
},
bbsShareConf: { //bbs讨论区签到
url: `${mys.bbs_api}/apihub/api/getShareConf`,
query: `entity_id=${data.postId}&entity_type=1`,
types: 'bbs'
},
bbsVotePost: { //bbs讨论区签到
url: `${mys.bbs_api}/apihub/sapi/upvotePost`,
body: {
"post_id": data.postId,
"is_cancel": false
},
types: 'bbs'
},
bbsGetCookie: {
url: `${this.apiMap.apiWeb}/auth/api/getCookieAccountInfoBySToken`,
query: `game_biz=hk4e_cn&${data.cookies}`,
types: ''
},
bbsStoken: {
url: `${this.apiMap.apiWeb}/auth/api/getMultiTokenByLoginTicket`,
query: `login_ticket=${data.loginTicket}&token_types=3&uid=${data.loginUid}`,
types: 'stoken'
},
validate: {
2022-11-24 23:12:36 +08:00
url: ``,
query: ``
},
2022-10-12 16:51:51 +08:00
cloudLogin: {
url: `${mys.cloud_api}/hk4e_cg_cn/gamer/api/login`,
types: 'cloud'
},
cloudReward: {
url: `${mys.cloud_api}/hk4e_cg_cn/gamer/api/listNotifications`,
query: `status=NotificationStatusUnread&type=NotificationTypePopup&is_sort=true`,
types: 'cloud'
},
cloudGamer: {
url: `${mys.cloud_api}/hk4e_cg_cn/gamer/api/ackNotification`,
body: {
id: data.reward_id
},
2022-10-12 16:51:51 +08:00
types: 'cloud'
},
cloudGet: {
url: `${mys.cloud_api}/hk4e_cg_cn/wallet/wallet/get`,
types: 'cloud'
},
authKey: {
///account/auth/api/genAuthKey
2022-10-12 16:51:51 +08:00
url: `${this.apiMap.apiWeb}/binding/api/genAuthKey`,
2022-10-12 21:16:44 +08:00
body: {
2022-10-12 16:51:51 +08:00
'auth_appid': 'webview_gacha',
2022-10-12 21:16:44 +08:00
'game_biz': this.isOs ? 'hk4e_global' : 'hk4e_cn',
2022-10-12 16:51:51 +08:00
'game_uid': this.e.uid * 1,
'region': this.e.region,
},
types: 'authKey'
},
2022-11-24 23:12:36 +08:00
getLtoken: {
url: `${mys.pass_api}/account/auth/api/getLTokenBySToken`,
query: `${data.cookies}`,
},
2022-12-10 18:05:04 +08:00
getByStokenV2: {
url: `${mys.pass_api}/account/ma-cn-session/app/getTokenBySToken`,
body: {},
types: 'pass'
},
2022-10-12 16:51:51 +08:00
}
if (!urlMap[type]) return false
let {
url,
query = '',
2022-10-12 21:16:44 +08:00
body = '',
2022-10-12 16:51:51 +08:00
types = '',
sign = ''
} = urlMap[type]
if (query) url += `?${query}`
if (body) body = JSON.stringify(body)
let headers = this.getHeaders(board, types, sign)
return {
url,
headers,
body
}
}
// 签到的 headers
getHeaders(board, type = "bbs", sign) {
let header = {};
switch (type) {
case "bbs":
header = {
'Cookie': this.cookies,
"x-rpc-channel": "miyousheluodi",
"x-rpc-auto_test": true,
2022-10-12 16:51:51 +08:00
'x-rpc-device_id': DEVICE_ID,
'x-rpc-app_version': mys.APP_VERSION,
"x-rpc-device_model": "Mi 10",
'x-rpc-device_name': DEVICE_NAME,
'x-rpc-client_type': '2', // 1 - iOS, 2 - Android, 4 - Web
'DS': (sign ? this.getDs2("", JSON.stringify({
2022-10-12 21:16:44 +08:00
gids: board.forumid * 1
2022-10-12 16:51:51 +08:00
}), mys.salt2) : this.getDs(mys.salt)),
"Referer": "https://app.mihoyo.com",
"x-rpc-sys_version": "12",
"Host": "bbs-api.mihoyo.com",
"User-Agent": "okhttp/4.8.0",
}
break;
case "sign":
header = {
'accept-language': 'zh-CN,zh;q=0.9,ja-JP;q=0.8,ja;q=0.7,en-US;q=0.6,en;q=0.5',
'x-rpc-device_id': DEVICE_ID,
'User-Agent': `Mozilla/5.0 (iPhone; CPU iPhone OS 14_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/${mys.APP_VERSION}`,
Referer: board.getReferer(),
Host: 'api-takumi.mihoyo.com',
'x-rpc-channel': 'appstore',
'x-rpc-app_version': mys.APP_VERSION,
'x-requested-with': 'com.mihoyo.hyperion',
'x-rpc-client_type': '5',
'Content-Type': 'application/json;charset=UTF-8',
DS: this.getDs(),
'Cookie': this.cookie
}
2022-10-12 21:16:44 +08:00
if (this.isOs) {
let os_Header = {
2022-10-12 16:51:51 +08:00
app_version: '2.9.0',
User_Agent: `Mozilla/5.0 (Linux; Android 9.0; SAMSUNG SM-F900U Build/PPR1.180610.011) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.73 Mobile Safari/537.36 miHoYoBBSOversea/2.9.0`,
client_type: '2',
'x-rpc-app_version': '2.9.0',
2022-10-12 16:51:51 +08:00
Origin: 'https://webstatic-sea.hoyolab.com',
X_Requested_With: 'com.mihoyo.hoyolab',
Referer: 'https://webstatic-sea.hoyolab.com',
DS: this.getDs(),
'Cookie': this.cookie
2022-10-12 16:51:51 +08:00
}
header = os_Header
2022-10-12 16:51:51 +08:00
}
break;
case "cloud":
header = {
"x-rpc-combo_token": this.yuntoken, //云原神签到ck
"x-rpc-client_type": "2",
"x-rpc-app_version": "1.3.0",
"x-rpc-sys_version": "11",
"x-rpc-channel": "mihoyo",
"x-rpc-device_id": this.devId, //设备Id
"x-rpc-device_name": "Xiaomi Mi 10 Pro",
"x-rpc-device_model": "Mi 10 Pro",
"x-rpc-app_id": "1953439974",
"Referer": "https://app.mihoyo.com",
"Content-Length": "0",
"Host": "api-cloudgame.mihoyo.com",
"Connection": "Keep-Alive",
"Accept-Encoding": "gzip",
"User-Agent": "okhttp/3.14.9"
}
break;
case "authKey":
header = {
'x-rpc-app_version': mys.APP_VERSION,
'User-Agent': 'okhttp/4.8.0',
'x-rpc-client_type': '5',
Referer: 'https://app.mihoyo.com',
Origin: 'https://webstatic.mihoyo.com',
Cookie: this.cookies,
DS: this.getDs(this.isOs ? mys.osSalt : mys.saltWeb),
2022-10-12 16:51:51 +08:00
'x-rpc-sys_version': '12',
'x-rpc-channel': 'mihoyo',
'x-rpc-device_id': DEVICE_ID,
'x-rpc-device_name': DEVICE_NAME,
2022-10-12 16:51:51 +08:00
'x-rpc-device_model': 'Mi 10',
Host: 'api-takumi.mihoyo.com'
}
if (this.isOs) {
let os_Header = {
'x-rpc-app_version': '2.18.1',
app_version: '2.18.1',
client_type: '2',
'x-rpc-client_type': '2',
Origin: 'https://app.hoyolab.com',
X_Requested_With: 'com.mihoyo.hoyolab',
Referer: 'https://app.hoyolab.com',
Host: 'api-os-takumi.mihoyo.com',
'x-rpc-channel': 'hoyolab'
}
header = Object.assign({}, header, os_Header)
}
2022-10-12 16:51:51 +08:00
break;
case "stoken":
header = {
"x-rpc-device_id": "zxcvbnmasadfghjk123456",
"Content-Type": "application/json;charset=UTF-8",
"x-rpc-client_type": "",
"x-rpc-app_version": "",
"DS": "",
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) miHoYoBBS/%s",
"Referer": "cors",
"Accept-Encoding": "gzip, deflate, br",
"x-rpc-channel": "appstore",
}
break;
2022-12-10 18:05:04 +08:00
case "pass":
header = {
'x-rpc-device_id': DEVICE_ID,
'x-rpc-app_id': "bll8iq97cem8",
'x-rpc-device_name': DEVICE_NAME,
'x-rpc-app_version': mys.APP_VERSION,
'x-rpc-game_biz': 'bbs_cn',
"Content-Type": "application/json;",
"x-rpc-client_type": "2",
"DS": this.getDs2('', {}, mys.passSalt),
"x-rpc-sdk_version": '1.3.1.2',
"User-Agent": "okhttp/4.9.3",
"Referer": "cors",
'Host': 'passport-api.mihoyo.com',
"Connection": 'Keep-Alive',
"Accept-Encoding": "gzip, deflate, br",
"x-rpc-channel": "appstore",
Cookie: this.cookies,
}
break;
2022-10-12 16:51:51 +08:00
default:
header = {}
break;
}
return header;
}
getStoken(userId) {
let file = `${yamlDataUrl}/${userId}.yaml`
try {
let ck = fs.readFileSync(file, 'utf-8')
ck = YAML.parse(ck)
if (ck?.uid) {
let datalist = {};
ck.userId = this.e.user_id
datalist[ck.uid] = ck;
ck = datalist
gsCfg.saveBingStoken(this.e.user_id, datalist)
}
return ck[this.e.uid] || {}
} catch (error) {
return {}
}
}
//社区签到ds
getDs2(q = "", b, salt) {
let i = Math.floor(Date.now() / 1000)
let r = _.random(100001, 200000)
let add = `&b=${b}&q=${q}`
let c = md5("salt=" + salt + "&t=" + i + "&r=" + r + add)
return `${i},${r},${c}`
}
getDs(salt = mys.saltWeb) {
const randomStr = utils.randomString(6);
const timestamp = Math.floor(Date.now() / 1000)
let sign = md5(`salt=${salt}&t=${timestamp}&r=${randomStr}`);
return `${timestamp},${randomStr},${sign}`
}
async getAgent() {
if (isV3) {
let cfg = await import(`file://${_path}/lib/config/config.js`);
let proxyAddress = cfg.default.bot.proxyAddress
if (!proxyAddress) return null
if (proxyAddress === 'http://0.0.0.0:0') return null
if (!this.isOs) return null
if (HttpsProxyAgent === '') {
HttpsProxyAgent = await import('https-proxy-agent').catch((err) => {
logger.error(err)
})
HttpsProxyAgent = HttpsProxyAgent ? HttpsProxyAgent.default : undefined
}
if (HttpsProxyAgent) {
return new HttpsProxyAgent(proxyAddress)
}
}
return null
}
}