diff --git a/adapter/render.js b/adapter/render.js index 3ee70c2..4963368 100644 --- a/adapter/render.js +++ b/adapter/render.js @@ -9,10 +9,13 @@ const _path = process.cwd() export async function render (app = '', tpl = '', data = {}, imgType = 'jpeg') { // 在data中保存plugin信息 data._plugin = plugin - if (lodash.isUndefined(data._res_path)) { data._res_path = `../../../../../plugins/${plugin}/resources/` } + if(imgType == "png"){ + data.omitBackground=true; + } + data.imgType=imgType; Data.createDir(_path + '/data/', `html/${plugin}/${app}/${tpl}`) data.saveId = data.saveId || data.save_id || tpl data.tplFile = `./plugins/${plugin}/resources/${app}/${tpl}.html` diff --git a/apps/Note.js b/apps/Note.js index ec60edb..92e8302 100644 --- a/apps/Note.js +++ b/apps/Note.js @@ -358,16 +358,16 @@ export async function DailyNoteTask() { redis.set(sendkey, "1", { EX: sendCD }); - await Note(e, getPluginRender("xiaoyao-cvs-plugin")); + // await Note(e, getPluginRender("xiaoyao-cvs-plugin")); } } } -export async function pokeNote(e) { +export async function pokeNote(e,{render}) { if (!Cfg.get("note.poke")) { return false; } - return await Note(e, getPluginRender("xiaoyao-cvs-plugin"), "poke"); + return await Note(e,{render}, "poke"); } diff --git a/apps/sign.js b/apps/sign.js index 0b41d8c..c8144eb 100644 --- a/apps/sign.js +++ b/apps/sign.js @@ -122,7 +122,8 @@ export async function mysSign(e) { } let iscount = ""; let miHoYoApi = new MihoYoApi(e); - if (Object.keys((await miHoYoApi.getStoken(e.user_id))).length == 0) { + let stokens=await miHoYoApi.getStoken(e.user_id) + if (Object.keys(stokens).length==0) { e.reply("未读取到stoken请检查cookies是否包含login_ticket、以及云崽是否为最新版本V3、V2兼容") return true; } @@ -231,7 +232,8 @@ export async function bbsSeach(e){ return true; } let miHoYoApi = new MihoYoApi(e); - if (Object.keys((await miHoYoApi.getStoken(e.user_id))).length == 0) { + let stokens=await miHoYoApi.getStoken(e.user_id) + if (Object.keys(stokens).length==0) { let cookiesDoc = await getcookiesDoc() await replyMsg(e, "未读取到stoken请检查cookies是否包含login_ticket,请先绑定stoken再查询~\n"+cookiesDoc); return true; @@ -286,13 +288,12 @@ async function cookie(e) { } = await getCookie(e); let miHoYoApi = new MihoYoApi(e); let cookiesDoc = await getcookiesDoc(); - if (!cookie) { e.reply("cookie失效请重新绑定~【教程】\n" + cookiesDoc) return false; } - - if (Object.keys((await miHoYoApi.getStoken(e.user_id))).length != 0) { + let stokens=miHoYoApi.getStoken(e.user_id) + if (Object.keys(stokens).length>0) { return true; } if (!cookie.includes("login_ticket") && (isV3 && !skuid?.login_ticket)) { @@ -300,7 +301,6 @@ async function cookie(e) { return false; } let flot = (await miHoYoApi.stoken(cookie, e)); - // console.log(flot) await utils.sleepAsync(1000); //延迟加载防止文件未生成 if (!flot) { e.reply("登录失效请重新登录获取cookie发送机器人~") @@ -347,8 +347,10 @@ export async function allMysSign() { let stoken = await gsCfg.getBingStoken(); let isPushSign = await gsCfg.getfileYaml(`${_path}/plugins/xiaoyao-cvs-plugin/config/`, "config").isPushSign //获取需要签到的用户 - for (let data of stoken) { - let user_id = data.qq; + for (let dataUid of stoken) { + for(let uuId in dataUid){ + let data=dataUid[uuId] + let user_id = data.userId*1; let e = { user_id, isTask: true @@ -363,11 +365,12 @@ export async function allMysSign() { } if (msg.includes("OK")) { //签到成功并且不是已签到的才推送 // msg = msg.replace("签到成功", "自动签到成功"); - utils.relpyPrivate(user_id, msg + "\n自动签到成功"); + utils.relpyPrivate(user_id, msg + "uid:"+uuId+"\n自动签到成功"); } }; await mysSign(e); await utils.sleepAsync(10000); + } } Bot.logger.mark(`米社米币签到任务完成`); return true diff --git a/apps/xiaoyao_image.js b/apps/xiaoyao_image.js index d94638b..5365d4d 100644 --- a/apps/xiaoyao_image.js +++ b/apps/xiaoyao_image.js @@ -16,7 +16,7 @@ const _path = process.cwd(); const __dirname = path.resolve(); const list = ["wuqi_tujian", "shiwu_tujian", "yuanmo_tujian", "mijin_tujian", "shengyiwu_tujian", "daoju_tujian"] -const reglist=["(#|专武|武器|图鉴|突破)","(#|食物|特殊料理|特色|料理|食材)","(#|原魔|怪物|图鉴|信息)","(#|秘境|信息|图鉴)","(#|圣遗物|图鉴)","(#|图鉴|道具)"] +const reglist=["(#|专武|武器|图鉴|突破)","(#|食物|特殊料理|特色|料理|食材|图鉴)","(#|原魔|怪物|图鉴|信息)","(#|秘境|信息|图鉴)","(#|圣遗物|图鉴)","(#|图鉴|道具)"] export async function AtlasAlias(e) { if (!Cfg.get("Atlas.all")) { return false; diff --git a/components/Common.js b/components/Common.js index 55e37a0..c2238e0 100644 --- a/components/Common.js +++ b/components/Common.js @@ -1,15 +1,15 @@ import { Cfg } from "./index.js"; import { segment } from "oicq"; -import { currentVersion, yunzaiVersion } from "./Changelog.js"; -import {render1} from "../apps/render.js"; +import { currentVersion, yunzaiVersion,isV3 } from "./Changelog.js"; export const render = async function (path, params, cfg) { let paths = path.split("/"); let { render, e } = cfg; let _layout_path = process.cwd() + "/plugins/xiaoyao-cvs-plugin/resources/"; let layout_path= process.cwd() + "/plugins/xiaoyao-cvs-plugin/resources/common/layout/"; - let base64 = await render1(paths[0], paths[1], { + let base64 = await render(paths[0], paths[1], { ...params, _layout_path, + _tpl_path: process.cwd() + '/plugins/xiaoyao-cvs-plugin/resources/common/tpl/', defaultLayout: layout_path + "default.html", elemLayout: layout_path + "elem.html", sys: { @@ -17,21 +17,21 @@ export const render = async function (path, params, cfg) { copyright: `Created By Yunzai-Bot${yunzaiVersion} & xiaoyao-cvs-Plugin${currentVersion}` } },"png"); - + let ret = true if (base64) { - e.reply(segment.image(`base64://${base64}`)); + ret = isV3 ? await e.reply(base64) : await e.reply(segment.image(`base64://${base64}`)) } - - return true; + return cfg.retMsgId ? ret : true } export const render_path = async function (path, params, cfg,path_) { let paths = path.split("/"); let { render, e } = cfg; let _layout_path = process.cwd() + path_; - let base64 = await render1(paths[0], paths[1], { + let base64 = await render(paths[0], paths[1], { ...params, _layout_path, + _tpl_path: process.cwd() + '/plugins/xiaoyao-cvs-plugin/resources/common/tpl/', defaultLayout: _layout_path + "default.html", elemLayout: _layout_path + "elem.html", sys: { @@ -39,12 +39,11 @@ export const render_path = async function (path, params, cfg,path_) { copyright: `Created By Yunzai-Bot${yunzaiVersion} & xiaoyao-cvs-Plugin${currentVersion}` } }); - + let ret = true if (base64) { - e.reply(segment.image(`base64://${base64}`)); + ret = isV3 ? await e.reply(base64) : await e.reply(segment.image(`base64://${base64}`)) } - - return true; + return cfg.retMsgId ? ret : true } diff --git a/model/gsCfg.js b/model/gsCfg.js index 51641df..5d38268 100644 --- a/model/gsCfg.js +++ b/model/gsCfg.js @@ -5,7 +5,9 @@ import { promisify } from 'node:util' import lodash from 'lodash' - +import { + Data +} from "../components/index.js"; const plugin = "xiaoyao-cvs-plugin" /** 配置文件 */ class GsCfg { @@ -47,9 +49,9 @@ class GsCfg { } } /** 通用yaml读取*/ - getfileYaml(path,name){ + getfileYaml(path, name) { return YAML.parse( - fs.readFileSync(path+name+".yaml", 'utf8') + fs.readFileSync(path + name + ".yaml", 'utf8') ) } /** @@ -133,7 +135,7 @@ class GsCfg { ckQQ } } - /** 读取所有用户绑定的stoken */ + /** 读取所有用户绑定的stoken */ async getBingStoken() { let ck = [] let ckQQ = {} @@ -146,11 +148,9 @@ class GsCfg { files.forEach((v) => promises.push(readFile(`${dir}${v}`, 'utf8'))) const res = await Promise.all(promises) - res.forEach((v,index) => { + res.forEach((v, index) => { let tmp = YAML.parse(v) - tmp["qq"]=files[index].split(".")[0]*1 ck.push(tmp) - }) return ck } @@ -169,10 +169,18 @@ class GsCfg { try { let ck = fs.readFileSync(file, 'utf-8') ck = YAML.parse(ck) - for(let item in ck){ - let login_ticket=ck[item]?.login_ticket - ck=ck[item].ck - return {ck,item,login_ticket}; + for (let item in ck) { + let login_ticket; + if (!ck[item].isMain) { + continue; + } + login_ticket = ck[item]?.login_ticket + ck = ck[item].ck + return { + ck, + item, + login_ticket + }; } } catch (error) { return {} @@ -187,7 +195,27 @@ class GsCfg { fs.writeFileSync(file, yaml, 'utf8') } } - + saveBingStoken(userId, data) { + let file = `./plugins/${plugin}/data/yaml/${userId}.yaml` + if (lodash.isEmpty(data)) { + fs.existsSync(file) && fs.unlinkSync(file) + } else { + fs.exists(file, (exists) => { + if (!exists) { + fs.writeFileSync(file, "", 'utf8') + } + let ck = fs.readFileSync(file, 'utf-8') + let yaml = YAML.stringify(data) + ck = YAML.parse(ck) + if (!ck) { + fs.writeFileSync(file, yaml, 'utf8') + } else { + ck = YAML.stringify(ck) + fs.writeFileSync(file, yaml + ck, 'utf8') + } + }) + } + } /** * 原神角色id转换角色名字 */ diff --git a/model/mys/mihoyo-api.js b/model/mys/mihoyo-api.js index d9bc1c5..2afb4dd 100644 --- a/model/mys/mihoyo-api.js +++ b/model/mys/mihoyo-api.js @@ -12,8 +12,10 @@ import { isV3 } from '../../components/Changelog.js'; import fetch from "node-fetch" -const APP_VERSION = "2.34.1"; -const salt = "z8DRIUjNDT7IT5IZXvrUAxyupA1peND9"; +const APP_VERSION = "2.35.2"; +const salt = "ZSHlXeQUBis52qD1kEgKt5lUYed4b7Bb"; +const salt2="t0qEgfub6cvueAPgR5m9aQWWVciEer7v"; +const saltWeb="N50pqm7FSy2AkFz2B3TqtuZMJ5TOl3Ep"; //b253c83ab2609b1b600eddfe974df47b const DEVICE_ID = utils.randomString(32).toUpperCase(); const DEVICE_NAME = utils.randomString(_.random(1, 10)); @@ -156,8 +158,9 @@ export default class MihoYoApi { } } async forumSign(forumId) { - const url = `https://api-takumi.mihoyo.com/apihub/sapi/signIn?gids=${forumId}`; - let res = await superagent.post(url).set(this._getHeader()).timeout(10000); + const url = `https://bbs-api.mihoyo.com/apihub/app/api/signIn`; + this.forumId=forumId; + let res = await superagent.post(url).set(this._getHeader()).send(JSON.stringify({gids:forumId*1})).timeout(10000); let resObj = JSON.parse(res.text); // Bot.logger.mark(`ForumSign: ${res.text}`); return resObj; @@ -264,7 +267,8 @@ export default class MihoYoApi { async stoken(cookie, e) { this.e = e; - if (Object.keys(this.getStoken(e.user_id)).length != 0) { + let datalist=this.getStoken(e.user_id) || {} + if (Object.keys(datalist).length>0){ return true; } const map = this.getCookieMap(cookie); @@ -294,18 +298,18 @@ export default class MihoYoApi { return false; } response.json().then(function(data) { - // console.log(data); if (!data.data) { return false; } - let datalist = { + datalist[e.uid] = { stuid: map.get("account_id"), stoken: data.data.list[0].token, ltoken: data.data.list[1].token, - uid: e.uid + uid: e.uid, + userId:e.user_id, + is_sign:true } - let yamlStr = YAML.stringify(datalist); - fs.writeFileSync(`${YamlDataUrl}/${e.user_id}.yaml`, yamlStr, 'utf8'); + gsCfg.saveBingStoken(e.user_id,datalist) return true; }); } @@ -319,7 +323,7 @@ export default class MihoYoApi { getpubHeaders(board) { const randomStr = utils.randomString(6); const timestamp = Math.floor(Date.now() / 1000) - let sign = md5(`salt=9nQiU3AV0rJSIBWgdynfoGMGKaklfbM7&t=${timestamp}&r=${randomStr}`); + let sign = md5(`salt=${saltWeb}&t=${timestamp}&r=${randomStr}`); return { '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, @@ -327,7 +331,7 @@ export default class MihoYoApi { Referer: board.getReferer(), Host: 'api-takumi.mihoyo.com', 'x-rpc-channel': 'appstore', - 'x-rpc-app_version': '2.34.1', + 'x-rpc-app_version': APP_VERSION, 'x-requested-with': 'com.mihoyo.hyperion', 'x-rpc-client_type': '5', 'Content-Type': 'application/json;charset=UTF-8', @@ -335,24 +339,39 @@ export default class MihoYoApi { 'Cookie': this.cookie } } + //社区签到ds + get_ds2(q="",b){ + let n = salt2 + let i = Math.floor(Date.now() / 1000) + let r = _.random(100001,200000) + let add = `&b=${b}&q=${q}` + let c= md5("salt=" + n + "&t=" + i + "&r=" + r + add) + return `${i},${r},${c}` + } + // 米游币任务的 headers _getHeader() { const randomStr = utils.randomString(6); const timestamp = Math.floor(Date.now() / 1000) let sign = md5(`salt=${salt}&t=${timestamp}&r=${randomStr}`); + let ds=`${timestamp},${randomStr},${sign}` + if(this.forumId){ + ds = this.get_ds2("",JSON.stringify({gids:this.forumId*1})); + this.forumId=""; + } return { 'Cookie': this.cookies, - "Referer": "https://app.mihoyo.com", - "x-rpc-sys_version": "6.0.1", - "Host": "bbs-api.mihoyo.com", - "User-Agent": "okhttp/4.8.0", - 'x-rpc-channel': 'appstore', + "x-rpc-channel": "miyousheluodi", 'x-rpc-device_id': DEVICE_ID, 'x-rpc-app_version': 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': `${timestamp},${randomStr},${sign}` + 'DS': ds, + "Referer": "https://app.mihoyo.com", + "x-rpc-sys_version": "12", + "Host": "bbs-api.mihoyo.com", + "User-Agent": "okhttp/4.8.0", // 'DS': `1602569298,k0xfEh,07f4545f5d88eac59cb1257aef74a570` } } @@ -393,7 +412,14 @@ export default class MihoYoApi { try { let ck = fs.readFileSync(file, 'utf-8') ck = YAML.parse(ck) - return 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 {} } diff --git a/model/user.js b/model/user.js index 239bb51..fdf97fb 100644 --- a/model/user.js +++ b/model/user.js @@ -16,69 +16,57 @@ const RETRY_OPTIONS = { minTimeout: 5000, maxTimeout: 10000 }; -const nameData=["原神","崩坏3","崩坏2","未定事件簿"]; +const nameData = ["原神", "崩坏3", "崩坏2", "未定事件簿"]; /** 配置文件 */ export default class user { constructor(e) { - this.e=e; - this.stokenPath=`./plugins/${plugin}/data/yaml/` - this.yunPath=`./plugins/${plugin}/data/yunToken/`; + this.e = e; + this.stokenPath = `./plugins/${plugin}/data/yaml/` + this.yunPath = `./plugins/${plugin}/data/yunToken/`; this.getyunToken(this.e) } - async getCkData(){ - let sumData={}; + async getCkData() { + let sumData = {}; await this.cookie(this.e) this.miHoYoApi = new MihoYoApi(this.e); - if(this.e.yuntoken){ - let yunres = await promiseRetry((retry, number) => { - return this.miHoYoApi.logyunGenshen().catch((e) => { - return retry(e); - }); - }, RETRY_OPTIONS); - + if (this.e.yuntoken) { + let yunres = await this.miHoYoApi.logyunGenshen(); let yundata = yunres.data - if(yunres.retcode===0){ - sumData["云原神"]={ - "今日可获取":yundata?.coin?.coin_num, - "免费时长":yundata?.free_time?.free_time, - "总时长":yundata.total_time + if (yunres.retcode === 0) { + sumData["云原神"] = { + "今日可获取": yundata?.coin?.coin_num, + "免费时长": yundata?.free_time?.free_time, + "总时长": yundata.total_time } } } - if(this.e.cookies){ - let mysres = await promiseRetry((retry, number) => { - return this.miHoYoApi.getTasksList().catch((e) => { - return retry(e); - }); - }, RETRY_OPTIONS); - if(mysres.retcode===0){ - sumData["米游社"]={ - "米游币任务":mysres.data.can_get_points!=0?"未完成":"已完成", - "米游币余额":mysres.data.total_points, - "今日剩余可获取":mysres.data.can_get_points + if (this.e.cookies) { + let mysres = await this.miHoYoApi.getTasksList(); + if (mysres.retcode === 0) { + sumData["米游社"] = { + "米游币任务": mysres.data.can_get_points != 0 ? "未完成" : "已完成", + "米游币余额": mysres.data.total_points, + "今日剩余可获取": mysres.data.can_get_points } } - + } - if(this.e.cookie){ - for(let name of nameData){ - let resSign = await promiseRetry((retry, number) => { - return this.miHoYoApi.honkai3rdSignTask(name).catch((e) => { - return retry(e); - }); - }, RETRY_OPTIONS); - if(resSign?.upData){ + if (this.e.cookie) { + for (let name of nameData) { + let resSign = await this.miHoYoApi.honkai3rdSignTask(name); + if (resSign?.upData) { // console.log(resSign?.upData) - for(let item of resSign?.upData){ - let num= lodash.random(0, 9999); - item.upName=item.upName=="原神"?"ys":item.upName=="崩坏3"?"bh3":item.upName=="崩坏2"?"bh2":item.upName=="未定事件簿"?"wdy":"" - sumData[item.upName+""+num]={ - "uid":item.game_uid, - "游戏昵称":item.nickname, - "等级":item.level, - "今日签到":item.is_sign?"已签到":"未签到", - "累计签到":item.total_sign_day+"天", - "今天奖励":item.awards + for (let item of resSign?.upData) { + let num = lodash.random(0, 9999); + item.upName = item.upName == "原神" ? "ys" : item.upName == "崩坏3" ? "bh3" : item.upName == + "崩坏2" ? "bh2" : item.upName == "未定事件簿" ? "wdy" : "" + sumData[item.upName + "" + num] = { + "uid": item.game_uid, + "游戏昵称": item.nickname, + "等级": item.level, + "今日签到": item.is_sign ? "已签到" : "未签到", + "累计签到": item.total_sign_day + "天", + "今天奖励": item.awards } } } @@ -112,16 +100,17 @@ export default class user { async cookie(e) { let { cookie, - uid,skuid + uid, + skuid } = await this.getCookie(e); let cookiesDoc = await this.getcookiesDoc(); - let miHoYoApi = new MihoYoApi(this.e); + let miHoYoApi = new MihoYoApi(this.e); if (!cookie) { e.reply("请先#绑定cookie\n发送【体力帮助】查看配置教程") return false; } - - if (Object.keys((await miHoYoApi.getStoken(e.user_id))).length != 0) { + let stokens = miHoYoApi.getStoken(e.user_id) + if (!stokens) { return true; } if (!cookie.includes("login_ticket") && (isV3 && !skuid?.login_ticket)) { @@ -137,7 +126,7 @@ export default class user { } return true; } - async getcookiesDoc() { + async getcookiesDoc() { return await gsCfg.getfileYaml(`${_path}/plugins/xiaoyao-cvs-plugin/config/`, "config").cookiesDoc } async getCookie(e) {