2
0
mirror of https://github.com/ctrlcvs/xiaoyao-cvs-plugin.git synced 2024-12-23 03:20:52 +08:00

增加#原神充值 需要绑定cookie

This commit is contained in:
Ctrlcvs 2023-03-09 23:45:55 +08:00
parent 1cfc99e2fd
commit fa9dce99d7
5 changed files with 146 additions and 60 deletions

View File

@ -1,3 +1,6 @@
# 1.2.8
* 增加`#原神充值` 原神离线充值
* 增加`#商品列表`
# 1.2.7 # 1.2.7
* 增加`#扫码登录`支持扫码获取sk以及ck * 增加`#扫码登录`支持扫码获取sk以及ck
* 增加`#账号密码登录`支持获取sk以及ck * 增加`#账号密码登录`支持获取sk以及ck

View File

@ -5,7 +5,7 @@ import mys from "../model/mhyTopUpLogin.js"
import Common from "../components/Common.js"; import Common from "../components/Common.js";
import { bindStoken } from './user.js' import { bindStoken } from './user.js'
import utils from '../model/mys/utils.js'; import utils from '../model/mys/utils.js';
import {segment} from 'oicq' import { segment } from 'oicq'
const _path = process.cwd(); const _path = process.cwd();
export const rule = { export const rule = {
qrCodeLogin: { qrCodeLogin: {
@ -22,27 +22,23 @@ export const rule = {
}, },
payOrder: { payOrder: {
/** 命令正则匹配 */ /** 命令正则匹配 */
reg: '^#?原神(微信)?充值(微信)?(.*)$', reg: '^#?((原神(微信)?充值(微信)?(.*))|(#?商品列表)|(#?订单查询))$',
/** 执行方法 */ /** 执行方法 */
describe: '原神充值(离线)' describe: '原神充值(离线)'
}, payOrder: {
reg: "^#?商品列表",
describe: '原神充值商品列表'
},payOrder:{
reg:'^#?订单查询',
describe:'充值订单查询'
} }
} }
export async function payOrder(e){ export async function payOrder(e, { render }) {
let Mys = new mys(e) let Mys = new mys(e)
if(/商品列表/.test(e.msg)){ if (/商品列表/.test(e.msg)) {
return await Mys.showgoods() return await Mys.showgoods()
}else if (/订单查询/.test(e.msg)) { } else if (/订单查询/.test(e.msg)) {
return await Mys.checkOrder() //容我摆烂会
}else if(e.msg.includes('充值')){ e.reply('作者还在咕咕咕~~~~')
return await Mys.GetCode() //return await Mys.checkOrder()
} else if (e.msg.includes('充值')) {
return await Mys.GetCode({ render })
} }
return false; return false;
} }
@ -51,9 +47,9 @@ export async function qrCodeLogin(e, { render }) {
let Mys = new mys(e) let Mys = new mys(e)
let res = await Mys.qrCodeLogin() let res = await Mys.qrCodeLogin()
if (!res?.data) return false; if (!res?.data) return false;
e._reply=e.reply e._reply = e.reply
let sendMsg=[segment.at(e.user_id),'\n请扫码以完成绑定\n'] let sendMsg = [segment.at(e.user_id), '\n请扫码以完成绑定\n']
e.reply=(msg)=>{ e.reply = (msg) => {
sendMsg.push(msg) sendMsg.push(msg)
} }
await Common.render(`qrCode/index`, { await Common.render(`qrCode/index`, {
@ -61,14 +57,14 @@ export async function qrCodeLogin(e, { render }) {
}, { }, {
e, e,
render, render,
scale: 1.2,retMsgId: true scale: 1.2, retMsgId: true
}) })
let r= await e._reply(sendMsg) let r = await e._reply(sendMsg)
utils.recallMsg(e,r,30) //默认30有需要请自行修改 utils.recallMsg(e, r, 30) //默认30有需要请自行修改
e.reply=e._reply e.reply = e._reply
res = await Mys.GetQrCode(res.data.ticket) res = await Mys.GetQrCode(res.data.ticket)
if (!res) return true; if (!res) return true;
await bindSkCK(e,res) await bindSkCK(e, res)
return true; return true;
} }

View File

@ -1,6 +1,7 @@
import User from "./user.js"; import User from "./user.js";
import utils from './mys/utils.js'; import utils from './mys/utils.js';
import { segment } from 'oicq' import { segment } from 'oicq'
import Common from "../components/Common.js";
export default class mysTopLogin { export default class mysTopLogin {
constructor(e) { constructor(e) {
this.e = e; this.e = e;
@ -14,9 +15,9 @@ export default class mysTopLogin {
} }
// //
async qrCodeLogin() { async qrCodeLogin() {
let RedisData=await utils.redisGet(this.e.user_id,"GetQrCode") let RedisData = await utils.redisGet(this.e.user_id, "GetQrCode")
if(RedisData){ if (RedisData) {
this.e.reply([segment.at(this.e.user_id),`前置二维码未扫描,请勿重复触发指令`]) this.e.reply([segment.at(this.e.user_id), `前置二维码未扫描,请勿重复触发指令`])
return false; return false;
} }
this.device = await utils.randomString(64) this.device = await utils.randomString(64)
@ -31,15 +32,15 @@ export default class mysTopLogin {
return res return res
} }
async GetQrCode(ticket) { async GetQrCode(ticket) {
await utils.redisSet(this.e.user_id,"GetQrCode",{GetQrCode:1},60*5) //设置5分钟缓存避免重复触发 await utils.redisSet(this.e.user_id, "GetQrCode", { GetQrCode: 1 }, 60 * 5) //设置5分钟缓存避免重复触发
let res; let res;
let RedisData=await utils.redisGet(this.e.user_id,"GetQrCode") let RedisData = await utils.redisGet(this.e.user_id, "GetQrCode")
for (let n = 1; n < 60; n++) { for (let n = 1; n < 60; n++) {
await utils.sleepAsync(5000) await utils.sleepAsync(5000)
res = await this.user.getData("qrCodeQuery", { res = await this.user.getData("qrCodeQuery", {
device: this.device, ticket device: this.device, ticket
}) })
if (res?.data?.stat == "Scanned"&&RedisData.GetQrCode==1) { if (res?.data?.stat == "Scanned" && RedisData.GetQrCode == 1) {
Bot.logger.mark(`[米哈游登录] ${Bot.logger.blue(JSON.stringify(res))}`) Bot.logger.mark(`[米哈游登录] ${Bot.logger.blue(JSON.stringify(res))}`)
await this.e.reply("二维码已扫描,请确认登录", true) await this.e.reply("二维码已扫描,请确认登录", true)
RedisData.GetQrCode++; RedisData.GetQrCode++;
@ -49,7 +50,7 @@ export default class mysTopLogin {
break break
} }
} }
await utils.redisDel(this.e.user_id,'GetQrCode') await utils.redisDel(this.e.user_id, 'GetQrCode')
if (!res?.data?.payload?.raw) { if (!res?.data?.payload?.raw) {
await this.e.reply("验证超时", true) await this.e.reply("验证超时", true)
return false return false
@ -89,7 +90,7 @@ export default class mysTopLogin {
this.e.reply('接口效验失败,请重新尝试~') this.e.reply('接口效验失败,请重新尝试~')
return false return false
} }
let validate =vlData?.data?.geetest_seccode.replace("|jordan",'') let validate = vlData?.data?.geetest_seccode.replace("|jordan", '')
let aigis = res.aigis_data.session_id + ";" + Buffer.from(JSON.stringify({ let aigis = res.aigis_data.session_id + ";" + Buffer.from(JSON.stringify({
geetest_challenge: vlData?.data?.geetest_challenge, geetest_challenge: vlData?.data?.geetest_challenge,
geetest_seccode: validate + "|jordan", geetest_seccode: validate + "|jordan",
@ -103,12 +104,12 @@ export default class mysTopLogin {
} }
if (res.retcode == 0) { if (res.retcode == 0) {
let cookies = `stoken=${res.data.token.token}&mid=${res.data.user_info.mid}` let cookies = `stoken=${res.data.token.token}&mid=${res.data.user_info.mid}`
let cookie_token =await this.user.getData("bbsGetCookie", { cookies }) let cookie_token = await this.user.getData("bbsGetCookie", { cookies })
let ltoken = await this.user.getData('getLtoken', { cookies: `${cookies}` }, false) let ltoken = await this.user.getData('getLtoken', { cookies: `${cookies}` }, false)
Bot.logger.mark(`[米哈游登录] ${Bot.logger.blue(JSON.stringify(cookie_token))}`) Bot.logger.mark(`[米哈游登录] ${Bot.logger.blue(JSON.stringify(cookie_token))}`)
return { return {
cookie: `ltoken=${ltoken?.data?.ltoken};ltuid=${res.data.user_info.aid};cookie_token=${cookie_token?.data?.cookie_token};`, cookie: `ltoken=${ltoken?.data?.ltoken};ltuid=${res.data.user_info.aid};cookie_token=${cookie_token?.data?.cookie_token};`,
stoken: `${cookies.replace('&',';')};stuid=${res.data.user_info.aid};` stoken: `${cookies.replace('&', ';')};stuid=${res.data.user_info.aid};`
} }
} else { } else {
await this.e.reply(`错误:${JSON.stringify(res)}`, true) await this.e.reply(`错误:${JSON.stringify(res)}`, true)
@ -116,7 +117,7 @@ export default class mysTopLogin {
} }
} }
async crack_geetest() { async crack_geetest() {
let res =""; //await this.user.getData("microgg", this.aigis_captcha_data, false) let res = ""; //await this.user.getData("microgg", this.aigis_captcha_data, false)
Bot.logger.mark(`[米哈游登录] ${Bot.logger.blue(JSON.stringify(res))}`) Bot.logger.mark(`[米哈游登录] ${Bot.logger.blue(JSON.stringify(res))}`)
await this.e.reply(`请完成验证https://challenge.minigg.cn/manual/index.html?gt=${this.aigis_captcha_data.gt}&challenge=${this.aigis_captcha_data.challenge}`, true) await this.e.reply(`请完成验证https://challenge.minigg.cn/manual/index.html?gt=${this.aigis_captcha_data.gt}&challenge=${this.aigis_captcha_data.challenge}`, true)
for (let n = 1; n < 60; n++) { for (let n = 1; n < 60; n++) {
@ -148,25 +149,64 @@ export default class mysTopLogin {
return true; return true;
} }
async GetCode() { async GetCode({render}) {
try { try {
let msg = this.e.msg.replace(/,||\|/g, ' ').split(' ') let msg = this.e.msg.replace(/,||\|/g, ' ').split(' ')
if (msg.length != 3) { if (msg.length != 2) {
this.e.reply(`格式参考:#原神充值 6(商品ID) 120065390(uid)\n 可通过【#商品列表】获取可操作商品`) this.e.reply(`格式参考:#原神充值 6(商品ID) 120065390(uid)\n 可通过【#商品列表】获取可操作商品`)
return true; return true;
} }
let iswx = msg[0].includes('微信') ? 'weixin' : 'alipay' let iswx = msg[0].includes('微信') ? 'weixin' : 'alipay'
if (msg[2].length != 9) { // if (msg[2].length != 9) {
this.e.reply('uid格式不对!') // this.e.reply('uid格式不对!')
return true; // return true;
// }
let goods = (await this.goodsList())[msg[1]]
// let ckData=this.e.user.ckData
let device_id = utils.randomString(4)
let order = {
"account": "196576671",
"region": utils.getServer(this.e.uid),
"uid": this.e.uid,
"delivery_url": "",
"device": device_id,
"channel_id": 1,
"client_ip": "",
"client_type": 4,
"game": this.e.uid[0] * 1 > 5 ? 'hk4e_global' : "hk4e_cn",
"amount": goods.price,
"goods_num": 1,
"goods_id": goods?.goods_id,
"goods_title": goods?.goods_name + (Number(goods.goods_unit) > 0 ? "×" + goods.goods_unit : ""),
"price_tier": goods?.tier_id,
"currency": "CNY",
"pay_plat": iswx,
} }
let res = await this.user.getData('GetCode', { msg: this.e.msg.replace('#', '') }) if (iswx != 'weixin') {
order["pay_type"] = iswx
order["pay_vendor"] = iswx
}
let res = await this.user.getData('createOrder', { order, headers: { "x-rpc-device_id": device_id } })
if (!res) return false; if (!res) return false;
if (res?.code != 200 && res?.retcode != 0) { if (res?.code != 200 && res?.retcode != 0) {
this.e.reply('生成充值订单失败:' + res.message)
return true return true
} }
this.e.reply([`uid:${res.data.uid},请使用${iswx == 'weixin' ? '微信' : "支付宝"}扫码支付:`, segment.image(res.data.base64.replace("data:image/png;base64,", "base64://")), `\n订单号:${res['data']['order_no']}\n 价格:${(res['data']['amount']) / 100}`]) //记录操作日志
logger.mark(`当前操作用户:${this.e.user_id},操作uid:${this.e.uid},操作商品id:${goods?.goods_id},操作商品:${goods?.goods_name + (Number(goods.goods_unit) > 0 ? "×" + goods.goods_unit : "")}`)
logger.mark(`支付链接:${res['data']['encode_order']}\n订单号:${res['data']['order_no']}\n 价格:${(res['data']['amount']) / 100}`)
let r= await Common.render(`pay/index`, {
url: res.data.encode_order,
data:res.data,uid:this.e.uid,
goods,
}, {
e:this.e,
render,
scale: 1.2, retMsgId: true
})
return true
} catch (error) { } catch (error) {
console.log(error)
this.e.reply('出问题了捏') this.e.reply('出问题了捏')
} }
return true; return true;
@ -174,8 +214,11 @@ export default class mysTopLogin {
async goodsList() { async goodsList() {
let goods = await this.user.getData("goodsList") let goods = await this.user.getData("goodsList")
if (!goods) return false; if (goods?.retcode != 0) {
return goods; this.e.reply(goods.message)
return false;
}
return goods?.data?.goods_list;
} }
async checkOrder() { async checkOrder() {
let msg, uid, order_no let msg, uid, order_no

View File

@ -241,8 +241,9 @@ export default class miHoYoApi {
authKey: { authKey: {
///account/auth/api/genAuthKey ///account/auth/api/genAuthKey
url: `${this.apiMap.apiWeb}/binding/api/genAuthKey`, url: `${this.apiMap.apiWeb}/binding/api/genAuthKey`,
// url:`https://gameapi-account.mihoyo.com/binding/api/genAuthKey`,
body: { body: {
'auth_appid': 'webview_gacha', 'auth_appid':'webview_gacha',//'apicdkey',// 'webview_gacha',
'game_biz': this.isOs ? 'hk4e_global' : 'hk4e_cn', 'game_biz': this.isOs ? 'hk4e_global' : 'hk4e_cn',
'game_uid': this.e.uid * 1, 'game_uid': this.e.uid * 1,
'region': this.e.region, 'region': this.e.region,
@ -297,17 +298,30 @@ export default class miHoYoApi {
url: `${mys.web_api}/auth/api/getCookieAccountInfoByGameToken`, url: `${mys.web_api}/auth/api/getCookieAccountInfoByGameToken`,
query: `account_id=${data.uid}&game_token=${data.token}` query: `account_id=${data.uid}&game_token=${data.token}`
}, },
GetCode:{ createOrder:{
url:``, url:`https://hk4e-sdk.mihoyo.com/hk4e_cn/mdk/atropos/api/createOrder`,
query:`` body: {
// "special_info": "topup_center",
"order": data.order,
"sign": this.gen_sign(data.order)
},
types:'web'
}, },
goodsList:{ goodsList:{
url:``, url:`https://hk4e-sdk.mihoyo.com/hk4e_cn/mdk/shopwindow/shopwindow/fetchGoods`,
query:`` body:{
"released_flag": true,
"game": "hk4e_cn",
"region": "cn_gf01",
"uid": "1",
"account": "1"
},
types:'web'
}, },
checkOrder:{ checkOrder:{
url:``, url:`https://hk4e-sdk.mihoyo.com/hk4e_cn/mdk/atropos/api/checkOrder`,
body:{} query:`game=hk4e_cn&region=${utils.getServer(data.uid)}&order_no=${data.order_no}&uid=${data.uid}`,
types:'web'
} }
} }
if (!urlMap[type]) return false if (!urlMap[type]) return false
@ -473,11 +487,45 @@ export default class miHoYoApi {
Cookie: this.cookies, Cookie: this.cookies,
} }
break; break;
case "web":
header={
"Accept": "application/json, text/plain, */*",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"Content-Type": "application/json;charset=UTF-8",
"Pragma": "no-cache",
"Referer": "https://webstatic.mihoyo.com/",
"sec-ch-ua": '"Not?A_Brand";v="8", "Chromium";v="108", "Microsoft Edge";v="108"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-site",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.54",
"x-rpc-client_type": "4",
"x-rpc-device_id": "3b401c79-e221-46b9-8ca5-2e072e367333",
"x-rpc-language": "zh-cn",
Cookie: this.cookie,
}
break
default: default:
header = {} header = {}
break; break;
} }
return header; return header;
}
gen_sign(data) {
if(!data) return ''
let d = Object.keys(data).sort()
let news = {}
for (const item of d) {
news[item] = data[item]
}
// let sign = this.HMCASHA256(Object.values(news).join(''))
let sign = crypto.createHmac('sha256','6bdc3982c25f3f3c38668a32d287d16b').update(Object.values(news).join('')).digest('hex')
return sign
} }
getStoken(userId) { getStoken(userId) {
let file = `${yamlDataUrl}/${userId}.yaml` let file = `${yamlDataUrl}/${userId}.yaml`

View File

@ -126,15 +126,11 @@ export default class user {
} }
message += `${item.nickname}-${item.game_uid}:今日已签到~\n`; message += `${item.nickname}-${item.game_uid}:今日已签到~\n`;
} else { } else {
let isgt = false
let signMsg = ''; let signMsg = '';
for (let i = 0; i < 2; i++) { //循环请求 for (let i = 0; i < 2; i++) { //循环请求
await utils.sleepAsync(2000) await utils.sleepAsync(2000)
res = await this.getData("sign", data, false) res = await this.getData("sign", data, false)
if (res?.data?.gt) { if (res?.data?.gt) {
if (!isgt) {
isgt = true;
}
let validate = await this.geetest(res.data) let validate = await this.geetest(res.data)
if (validate) { if (validate) {
let header = {} let header = {}
@ -144,14 +140,14 @@ export default class user {
data.headers = header data.headers = header
res = await this.getData("sign", data, false) res = await this.getData("sign", data, false)
if (!res?.data?.gt) { if (!res?.data?.gt) {
if (this.allSign && !isgt) { if (this.allSign) {
this.allSign[forum.name].sign++; this.allSign[forum.name].sign++;
} }
signMsg = `${item.nickname}-${item.game_uid}:验证码签到成功~\n` signMsg = `${item.nickname}-${item.game_uid}:验证码签到成功~\n`
item.total_sign_day++; item.total_sign_day++;
break; break;
} else { } else {
if (this.allSign && !isgt) { if (this.allSign) {
this.allSign[forum.name].error++; this.allSign[forum.name].error++;
} }
item.is_sign = false; item.is_sign = false;
@ -159,7 +155,7 @@ export default class user {
`${item.nickname}-${item.game_uid}:签到出现验证码~\n请晚点后重试,或者手动上米游社签到\n`; `${item.nickname}-${item.game_uid}:签到出现验证码~\n请晚点后重试,或者手动上米游社签到\n`;
} }
} else { } else {
if (this.allSign && !isgt) { if (this.allSign ) {
this.allSign[forum.name].error++; this.allSign[forum.name].error++;
} }
signMsg = `${item.nickname}-${item.game_uid}:验证码失败~\n` signMsg = `${item.nickname}-${item.game_uid}:验证码失败~\n`
@ -344,7 +340,7 @@ export default class user {
if (res?.message && res?.retcode == 0) { if (res?.message && res?.retcode == 0) {
Share++; Share++;
} }
message += `共读取帖子记录${20 * sumcount}\n浏览成功:${trueDetail}\n点赞成功:${Vote}\n分享成功${Share}`; message += `共读取帖子记录${20 * sumcount}\n浏览${trueDetail} 点赞:${Vote} 分享${Share}`;
Bot.logger.mark(`\n用户${this.e.user_id}:\n${message}`) Bot.logger.mark(`\n用户${this.e.user_id}:\n${message}`)
await utils.randomSleepAsync(3); await utils.randomSleepAsync(3);
} }
@ -787,7 +783,7 @@ export default class user {
if (res?.retcode != 0) { if (res?.retcode != 0) {
return false; return false;
} }
console.log(res,this.e.sk) // console.log(res,this.e.sk)
let uids = [] let uids = []
for (let s of res.data.list) { for (let s of res.data.list) {
let datalist = {} let datalist = {}