2
0
mirror of https://github.com/ctrlcvs/xiaoyao-cvs-plugin.git synced 2024-12-22 19:10:53 +08:00

V3改为直接调用文件获取数据,去除mysInfo.js文件依赖

This commit is contained in:
ctrlcvs 2022-08-07 00:20:05 +08:00
parent c496c4bc8b
commit 658e2470f7
3 changed files with 5 additions and 689 deletions

View File

@ -7,7 +7,7 @@ import fs from "fs";
import {
isV3
} from '../components/Changelog.js'
import MysInfo from '../model/mys/mysInfo.js'
// import MysInfo from '../model/mys/mysInfo.js'
// import { MysUser } from "../../../lib/components/Models.js";
// import common from "../../../lib/common.js";
import lodash from "lodash";
@ -45,7 +45,8 @@ export async function Note(e, {
}
let cookie, uid, res;
if (isV3) {
res = await MysInfo.get(e, 'dailyNote')
let MysInfo =await import(`file://${_path}/plugins/genshin/model/mys/mysInfo.js`);
res = await MysInfo.default.get(e, 'dailyNote')
if (!res || res.retcode !== 0) return true
uid = e.uid;
} else {
@ -103,7 +104,6 @@ export async function Note(e, {
saveJson();
}
}
let data = res.data;
//推送任务
if (e.isTask && data.current_resin < e.sendResin) {

View File

@ -6,7 +6,6 @@ import {
Data
} from "../components/index.js";
import moment from 'moment';
import MysInfo from '../model/mys/mysInfo.js'
import {
isV3
} from '../components/Changelog.js';
@ -319,7 +318,7 @@ export async function allMysSign() {
await mysSign(e);
await utils.sleepAsync(10000);
}
Bot.logger.mark(`签到任务完成`);
Bot.logger.mark(`米社米币签到任务完成`);
return true
}
@ -360,7 +359,7 @@ export async function allSign() {
await sign(e);
await utils.sleepAsync(10000);
}
Bot.logger.mark(`签到任务完成`);
Bot.logger.mark(`米社签到任务完成`);
}
const checkAuth = async function(e) {
return await e.checkAuth({

View File

@ -1,683 +0,0 @@
import MysApi from './mysApi.js'
import GsCfg from '../gsCfg.js'
import lodash from 'lodash'
import moment from 'moment'
/** 公共ck */
let pubCk = {}
/** 绑定ck */
let bingCkUid = {}
let bingCkQQ = {}
let bingCkLtuid = {}
let tmpCk = {}
export default class MysInfo {
/** redis key */
static keyPre = 'Yz:genshin:mys:'
static key = {
/** ck使用次数统计 */
count: `${MysInfo.keyPre}ck:count`,
/** ck使用详情 */
detail: `${MysInfo.keyPre}ck:detail`,
/** 单个ck使用次数 */
ckNum: `${MysInfo.keyPre}ckNum:`,
/** 已失效的ck使用详情 */
delDetail: `${MysInfo.keyPre}ck:delDetail`,
/** qq-uid */
qqUid: `${MysInfo.keyPre}qq-uid:`
}
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: ''
}
this.auth = ['dailyNote', 'bbs_sign_info', 'bbs_sign_home', 'bbs_sign']
}
static async init (e, api) {
let mysInfo = new MysInfo(e)
/** 检查时间 */
if (!mysInfo.checkTime()) return false
/** 初始化绑定ck */
await mysInfo.initBingCk()
/** 初始化公共ck */
await mysInfo.initPubCk()
if (mysInfo.checkAuth(api)) {
/** 获取ck绑定uid */
mysInfo.uid = (await MysInfo.getSelfUid(e))
} else {
/** 获取uid */
mysInfo.uid = await MysInfo.getUid(e)
}
if (!mysInfo.uid) {
e.noTips = true
return false
}
mysInfo.e.uid = mysInfo.uid
/** 获取ck */
await mysInfo.getCookie()
/** 判断回复 */
await mysInfo.checkReply()
return mysInfo
}
/** 获取uid */
static async getUid (e) {
if (e.uid) {
/** 没有绑定的自动绑定 */
MysInfo.uidBingQQ(e, e.uid)
return String(e.uid)
}
let { msg = '', at = '' } = e
if (!msg) return false
let uid = false
/** at用户 */
if (at) {
uid = await redis.get(`${MysInfo.key.qqUid}${at}`)
if (uid) return String(uid)
if (e.noTips !== true) e.reply('尚未绑定uid', false, { at })
return false
}
let matchUid = (msg = '') => {
let ret = /[1|2|5][0-9]{8}/g.exec(msg)
if (!ret) return false
return ret[0]
}
/** 命令消息携带 */
uid = matchUid(msg)
if (uid) {
/** 没有绑定的自动绑定 */
MysInfo.uidBingQQ(e, uid)
return String(uid)
}
/** 绑定的uid */
uid = await redis.get(`${MysInfo.key.qqUid}${e.user_id}`)
if (uid) return String(uid)
/** 群名片 */
uid = matchUid(e.sender.card)
if (uid) return String(uid)
if (e.noTips !== true) e.reply('请先#绑定uid', false, { at })
return false
}
/** 获取ck绑定uid */
static async getSelfUid (e) {
// if (e.uid) return e.uid
let { msg = '', at = '' } = e
if (!msg) return false
/** at用户 */
if (at && (!bingCkQQ[at] || !bingCkQQ[at].uid)) {
if (e.noTips !== true) e.reply('尚未绑定cookie', false, { at })
return false
}
if (!e.user_id || !bingCkQQ[e.user_id] || !bingCkQQ[e.user_id].uid) {
if (e.noTips !== true) e.reply(MysInfo.tips, false, { at })
return false
}
/** 当前查询uid不是绑定的uid */
if (e.uid && e.uid != bingCkQQ[e.user_id].uid) return false
return bingCkQQ[e.user_id].uid
}
/** 没有绑定的自动绑定 */
static async uidBingQQ (e, uid) {
if (!await redis.get(`${MysInfo.key.qqUid}${e.user_id}`)) {
await redis.setEx(`${MysInfo.key.qqUid}${e.user_id}`, 3600 * 24 * 30, String(uid))
}
}
/** 判断绑定ck才能查询 */
checkAuth (api) {
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
}
/**
* @param api
* * `index` 米游社原神首页宝箱等数据
* * `spiralAbyss` 原神深渊
* * `character` 原神角色详情
* * `dailyNote` 原神树脂
* * `bbs_sign` 米游社原神签到
* * `detail` 详情
* * `ys_ledger` 札记
* * `compute` 养成计算器
* * `avatarSkill` 角色技能
*/
static async get (e, api, data = {}) {
let mysInfo = await MysInfo.init(e, api)
if (!mysInfo.uid || !mysInfo.ckInfo.ck) return false
e.uid = mysInfo.uid
let mysApi = new MysApi(mysInfo.uid, mysInfo.ckInfo.ck)
let res
if (lodash.isObject(api)) {
let all = []
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)
if (res[i].retcode === 0) continue
break
}
} else {
res = await mysApi.getData(api, data)
if (!res) return false
res = await mysInfo.checkCode(res, api)
}
return res
}
async checkReply () {
if (!this.uid) {
this.e.reply('请先#绑定uid')
}
if (!this.ckInfo.ck) {
if (lodash.isEmpty(pubCk)) {
this.e.reply('请先配置公共查询ck')
} else {
this.e.reply('公共ck查询次数已用完暂无法查询新uid')
}
}
}
async getCookie () {
if (tmpCk[this.uid]) {
this.ckInfo = tmpCk[this.uid]
return this.ckInfo.ck
}
if (this.ckInfo.ck) return this.ckInfo.ck
// 使用用户uid绑定的ck
await this.getBingCK() ||
// 使用uid已查询的ck
await this.getCheckCK() ||
// 使用用户绑定的ck
await this.getBingCKqq() ||
// 使用公共ck
await this.getPublicCK()
tmpCk[this.uid] = this.ckInfo
setTimeout(() => {
delete tmpCk[this.uid]
}, 1000 * 30)
return this.ckInfo.ck
}
async getBingCK () {
if (!bingCkUid[this.uid]) return false
this.isSelf = true
let ck = bingCkUid[this.uid]
this.ckInfo = ck
this.ckInfo.type = 'self'
logger.mark(`[米游社查询][uid${this.uid}]${logger.green(`[使用已绑定ck${ck.ltuid}]`)}`)
return ck.ck
}
async getCheckCK () {
let ltuid = await redis.zScore(MysInfo.key.detail, this.uid)
if (!ltuid) return false
this.ckInfo.ltuid = ltuid
this.ckInfo.type = 'public'
/** 使用用户绑定ck */
if (bingCkLtuid[ltuid]) {
logger.mark(`[米游社查询][uid${this.uid}]${logger.blue(`[已查询][使用用户ck${ltuid}]`)}`)
this.ckInfo = bingCkLtuid[ltuid]
this.ckInfo.type = 'self'
return this.ckInfo.ck
}
/** 公共ck */
if (pubCk[ltuid]) {
logger.mark(`[米游社查询][uid${this.uid}]${logger.cyan(`[已查询][使用公共ck${ltuid}]`)}`)
this.ckInfo.ck = pubCk[ltuid]
return this.ckInfo.ck
}
return false
}
/** 使用用户绑定的ck */
async getBingCKqq () {
/** 用户没有绑定ck */
if (!bingCkQQ[this.userId]) return false
let ck = bingCkQQ[this.userId]
/** 判断用户ck使用次数 */
let num = await redis.get(`${MysInfo.key.ckNum}${ck.ltuid}`)
if (num && num >= 27) {
logger.mark(`[米游社查询][uid${this.uid}] 绑定用户ck次数已用完`)
return
}
if (!num) num = 0
this.ckInfo = ck
this.ckInfo.type = 'bing'
/** 插入查询详情 */
await redis.zAdd(MysInfo.key.detail, { score: ck.ltuid, value: this.uid })
/** 获取ck查询详情 */
let count = await redis.zRangeByScore(MysInfo.key.detail, ck.ltuid, ck.ltuid)
/** 用户ck也配置公共ck */
if (pubCk[ck.ltuid]) {
/** 统计ck查询次数 */
redis.zAdd(MysInfo.key.count, { score: count.length || 1, value: String(ck.ltuid) })
}
this.expire(MysInfo.key.detail)
/** 插入单个查询次数 */
redis.setEx(`${MysInfo.key.ckNum}${ck.ltuid}`, this.getEnd(), String(count.length))
logger.mark(`[米游社查询][uid${this.uid}]${logger.blue(`[使用用户ck${ck.ltuid}]`)}[次数:${++num}次]`)
return ck.ck
}
async getPublicCK () {
if (lodash.isEmpty(pubCk)) {
logger.mark('请先配置公共查询ck')
return false
}
/** 获取使用次数最少的ck */
let list = await redis.zRangeByScore(MysInfo.key.count, 0, 27, true)
if (lodash.isEmpty(list)) {
logger.mark('公共查询ck已用完')
return false
}
let ltuid = list[0]
if (!pubCk[ltuid]) {
logger.mark(`公共查询ck错误[ltuid:${ltuid}]`)
await redis.zAdd(MysInfo.key.count, { score: 99, value: ltuid })
return false
}
this.ckInfo.ck = pubCk[ltuid]
this.ckInfo.ltuid = ltuid
this.ckInfo.type = 'public'
/** 非原子操作,可能存在误差 */
/** 插入查询详情 */
await redis.zAdd(MysInfo.key.detail, { score: ltuid, value: this.uid })
/** 获取ck查询详情 */
let count = await redis.zRangeByScore(MysInfo.key.detail, ltuid, ltuid)
/** 统计ck查询次数 */
redis.zAdd(MysInfo.key.count, { score: count.length, value: ltuid })
/** 插入单个查询次数 */
redis.setEx(`${MysInfo.key.ckNum}${ltuid}`, this.getEnd(), String(count.length))
this.expire(MysInfo.key.detail)
logger.mark(`[米游社查询][uid${this.uid}]${logger.yellow(`[使用公共ck${ltuid}][次数:${count.length}]`)}`)
return pubCk[ltuid]
}
/** 初始化公共查询ck */
async initPubCk () {
/** 没配置每次都会初始化 */
if (!lodash.isEmpty(pubCk)) return
let ckList = await redis.zRangeByScore(MysInfo.key.count, 0, 100)
await this.addPubCk(ckList)
/** 使用用户ck当公共查询 */
let set = GsCfg.getConfig('mys', 'set')
let userNum = 0
if (set.allowUseCookie == 1) {
lodash.forEach(bingCkUid, async v => {
if (pubCk[v.ltuid]) return
pubCk[v.ltuid] = v.ck
userNum++
/** 加入redis统计 */
if (!ckList.includes(v.ltuid)) {
await redis.zAdd(MysInfo.key.count, { score: 0, value: String(v.ltuid) })
}
})
}
this.expire(MysInfo.key.count)
if (userNum > 0) logger.mark(`加载用户ck${userNum}`)
}
/** 加入公共ck池 */
async addPubCk (ckList = '') {
let ckArr = GsCfg.getConfig('mys', 'pubCk')
if (!ckList) {
ckList = await redis.zRangeByScore(MysInfo.key.count, 0, 100)
}
let pubNum = 0
for (let v of ckArr) {
let [ltuid = ''] = v.match(/ltuid=(\w{0,9})/g)
if (!ltuid) return
ltuid = String(lodash.trim(ltuid, 'ltuid='))
if (isNaN(ltuid)) return
pubCk[ltuid] = v
pubNum++
/** 加入redis统计 */
if (!ckList.includes(ltuid)) {
await redis.zAdd(MysInfo.key.count, { score: 0, value: ltuid })
}
}
if (pubNum > 0) logger.mark(`加载公共ck${pubNum}`)
}
async initBingCk () {
if (!lodash.isEmpty(bingCkUid)) return
let res = await GsCfg.getBingCk()
bingCkUid = res.ck
bingCkQQ = res.ckQQ
bingCkLtuid = lodash.keyBy(bingCkUid, 'ltuid')
}
async checkCode (res, type) {
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) {
this.e.reply(`UID:${this.ckInfo.uid}米游社cookie已失效请重新绑定cookie`)
} else {
this.e.reply(`ltuid:${this.ckInfo.ltuid}米游社cookie已失效`)
}
await this.delCk()
} else {
this.e.reply(`米游社接口报错,暂时无法查询:${res.message}`)
}
break
case 1008:
this.e.reply('\n请先去米游社绑定角色', false, { at: this.userId })
break
case 10101:
this.disableToday()
this.e.reply('查询已达今日上限')
break
case 10102:
if (res.message == 'Data is not public for the user') {
this.e.reply(`\nUID:${this.ckInfo.uid},米游社数据未公开`, false, { at: this.userId })
} else {
this.e.reply(`uid:${this.uid},请先去米游社绑定角色`)
}
break
// 伙伴不存在~
case -1002:
if (res.api == 'detail') res.retcode = 0
break
default:
this.e.reply(`米游社接口报错,暂时无法查询:${res.message || 'error'}`)
break
}
if (res.retcode !== 0) {
logger.mark(`mys接口报错:${JSON.stringify(res)}uid${this.uid}`)
}
return res
}
/** 删除失效ck */
async delCk () {
let ltuid = this.ckInfo.ltuid
/** 记录公共ck失效 */
if (this.ckInfo.type == 'public') {
if (bingCkLtuid[ltuid]) {
this.ckInfo = bingCkLtuid[ltuid]
this.ckInfo.type = 'self'
} else {
logger.mark(`删除失效ck[ltuid:${ltuid}]`)
}
}
if (this.ckInfo.type == 'self' || this.ckInfo.type == 'bing') {
/** 获取用户绑定ck */
let ck = GsCfg.getBingCkSingle(this.userId)
let tmp = ck[this.ckInfo.uid]
if (tmp) {
ltuid = tmp.ltuid
logger.mark(`删除失效绑定ck[qq:${this.userId}]`)
/** 删除文件保存ck */
delete ck[this.ckInfo.uid]
GsCfg.saveBingCk(this.userId, ck)
this.redisDel(ltuid)
delete pubCk[ltuid]
delete bingCkUid[tmp.uid]
delete bingCkQQ[tmp.qq]
}
}
delete pubCk[ltuid]
await this.redisDel(ltuid)
}
async redisDel (ltuid) {
/** 统计次数设为超限 */
await redis.zRem(MysInfo.key.count, String(ltuid))
// await redis.setEx(`${MysInfo.key.ckNum}${ltuid}`, this.getEnd(), '99')
/** 将当前查询记录移入回收站 */
await this.detailDel(ltuid)
}
/** 将当前查询记录移入回收站 */
async detailDel (ltuid) {
let detail = await redis.zRangeByScore(MysInfo.key.detail, ltuid, ltuid)
if (!lodash.isEmpty(detail)) {
let delDetail = []
detail.forEach((v) => {
delDetail.push({ score: ltuid, value: String(v) })
})
await redis.zAdd(MysInfo.key.delDetail, delDetail)
this.expire(MysInfo.key.delDetail)
}
/** 删除当前ck查询记录 */
await redis.zRemRangeByScore(MysInfo.key.detail, ltuid, ltuid)
}
async disableToday () {
/** 统计次数设为超限 */
await redis.zAdd(MysInfo.key.count, { score: 99, value: String(this.ckInfo.ltuid) })
await redis.setEx(`${MysInfo.key.ckNum}${this.ckInfo.ltuid}`, this.getEnd(), '99')
}
async expire (key) {
return await redis.expire(key, this.getEnd())
}
getEnd () {
let end = moment().endOf('day').format('X')
return end - moment().format('X')
}
/** 处理用户绑定ck */
async addBingCk (ck) {
/** 加入缓存 */
bingCkUid[ck.uid] = ck
bingCkQQ[ck.qq] = ck
bingCkLtuid[ck.ltuid] = ck
let set = GsCfg.getConfig('mys', 'set')
/** qq-uid */
await redis.setEx(`${MysInfo.key.qqUid}${ck.qq}`, 3600 * 24 * 30, String(ck.uid))
/** 恢复回收站查询记录,会覆盖原来记录 */
let detail = await redis.zRangeByScore(MysInfo.key.delDetail, ck.ltuid, ck.ltuid)
if (!lodash.isEmpty(detail)) {
let delDetail = []
detail.forEach((v) => {
delDetail.push({ score: ck.ltuid, value: String(v) })
})
await redis.zAdd(MysInfo.key.detail, delDetail)
this.expire(MysInfo.key.detail)
}
/** 删除回收站记录 */
await redis.zRemRangeByScore(MysInfo.key.delDetail, ck.ltuid, ck.ltuid)
/** 获取ck查询详情 */
let count = await redis.zRangeByScore(MysInfo.key.detail, ck.ltuid, ck.ltuid)
/** 开启了用户ck查询 */
if (set.allowUseCookie == 1) {
pubCk[ck.ltuid] = ck
let ckList = await redis.zRangeByScore(MysInfo.key.count, 0, 100)
if (!ckList.includes(ck.ltuid)) {
await redis.zAdd(MysInfo.key.count, { score: count.length, value: String(ck.ltuid) })
}
}
}
async delBingCk (ck) {
delete bingCkUid[ck.uid]
delete bingCkQQ[ck.qq]
delete bingCkLtuid[ck.ltuid]
this.detailDel(ck.ltuid)
}
async resetCk () {
return await redis.del(MysInfo.key.count)
}
static async initCk () {
if (lodash.isEmpty(bingCkUid)) {
let mysInfo = new MysInfo()
await mysInfo.initBingCk()
}
}
static async getBingCkUid () {
await MysInfo.initCk()
return bingCkUid
}
/** 切换uid */
static toggleUid (qq, ck) {
bingCkQQ[qq] = ck
}
static async checkUidBing (uid) {
await MysInfo.initCk()
if (bingCkUid[uid]) return true
return false
}
/** 数据更新中,请稍后再试 */
checkTime () {
let hour = moment().hour()
let min = moment().minute()
let second = moment().second()
if (hour == 23 && min == 59 && second >= 58) {
this.e.reply('数据更新中,请稍后再试')
return false
}
if (hour == 0 && min == 0 && second <= 3) {
this.e.reply('数据更新中,请稍后再试')
return false
}
return true
}
}