diff --git a/apps/Note.js b/apps/Note.js new file mode 100644 index 0000000..f7bb7d3 --- /dev/null +++ b/apps/Note.js @@ -0,0 +1,216 @@ +import { + segment +} from "oicq"; +import fetch from "node-fetch"; +import Common from "../components/Common.js"; +import fs from "fs"; +import format from "date-format"; +import puppeteer from "puppeteer"; +import common from "../../../lib/common.js"; +import lodash from "lodash"; +// import MysApi from "../components/MysApi.js" + +import { + getUrl, + getHeaders +} from "../../../lib/app/mysApi.js"; + +const _path = process.cwd(); + +//#体力 +export async function Note(e, { + render +}) { + let cookie, uid; + if (NoteCookie[e.user_id]) { + cookie = NoteCookie[e.user_id].cookie; + uid = NoteCookie[e.user_id].uid; + } else if (BotConfig.dailyNote && BotConfig.dailyNote[e.user_id]) { + cookie = BotConfig.dailyNote[e.user_id].cookie; + uid = BotConfig.dailyNote[e.user_id].uid; + } else { + e.reply(`尚未配置,无法查询体力\n配置教程:${BotConfig.cookieDoc}`); + return true; + } + + const response = await getDailyNote(uid, cookie); + if (!response.ok) { + e.reply("米游社接口错误"); + return true; + } + const res = await response.json(); + + if (res.retcode == 10102) { + if (!e.openDailyNote) { + e.openDailyNote = true; + await openDailyNote(cookie); //自动开启 + dailyNote(e); + } else { + e.reply("请先开启实时便笺数据展示"); + } + return true; + } + + if (res.retcode != 0) { + if (res.message == "Please login") { + Bot.logger.mark(`体力cookie已失效`); + e.reply(`体力cookie已失效,请重新配置\n注意:退出米游社登录cookie将会失效!`); + + if (NoteCookie[e.user_id]) { + await MysUser.delNote(NoteCookie[e.user_id]); + delete NoteCookie[e.user_id]; + saveJson(); + } + } else { + e.reply(`体力查询错误:${res.message}`); + Bot.logger.mark(`体力查询错误:${JSON.stringify(res)}`); + } + + return true; + } + + //redis保存uid + redis.set(`genshin:uid:${e.user_id}`, uid, { + EX: 2592000 + }); + + //更新 + if (NoteCookie[e.user_id]) { + NoteCookie[e.user_id].maxTime = new Date().getTime() + res.data.resin_recovery_time * 1000; + saveJson(); + } + + let data = res.data; + + //推送任务 + if (e.isTask && data.current_resin < e.sendResin) { + return; + } + + if (e.isTask) { + Bot.logger.mark(`体力推送:${e.user_id}`); + } + + let nowDay = format("dd", new Date()); + let resinMaxTime; + if (data.resin_recovery_time > 0) { + resinMaxTime = new Date().getTime() + data.resin_recovery_time * 1000; + let maxDate = new Date(resinMaxTime); + resinMaxTime = format("hh:mm", maxDate); + + if (format("dd", maxDate) != nowDay) { + resinMaxTime = `明天 ${resinMaxTime}`; + } else { + resinMaxTime = ` ${resinMaxTime}`; + } + } + + let remained_time = ""; + if (data.expeditions && data.expeditions.length >= 1) { + remained_time = lodash.map(data.expeditions, "remained_time"); + remained_time = lodash.min(remained_time); + if (remained_time > 0) { + for (let val of data.expeditions) { + val.remained_time = new Date().getTime() + val.remained_time * 1000; + let remainedDate = new Date(val.remained_time); + val.remained_time = format("hh:mm", remainedDate); + if (format("dd", remainedDate) != nowDay) { + val.remained_time = `明天 ${val.remained_time}`; + } else { + val.remained_time = ` ${val.remained_time}`; + } + } + remained_time = new Date().getTime() + remained_time * 1000; + let remainedDate = new Date(remained_time); + remained_time = format("hh:mm", remainedDate); + + if (format("dd", remainedDate) != nowDay) { + remained_time = `明天 ${remained_time}`; + } else { + remained_time = ` ${remained_time}`; + } + } + } + + let coinTime = ""; + if (data.home_coin_recovery_time > 0) { + let coinDay = Math.floor(data.home_coin_recovery_time / 3600 / 24); + let coinHour = Math.floor((data.home_coin_recovery_time / 3600) % 24); + let coinMin = Math.floor((data.home_coin_recovery_time / 60) % 60); + if (coinDay > 0) { + coinTime = `${coinDay}天${coinHour}小时${coinMin}分钟`; + } else { + let coinDate = new Date(new Date().getTime() + data.home_coin_recovery_time * 1000); + if (format("dd", coinDate) != nowDay) { + coinTime = `明天 ${format("hh:mm", coinDate)}`; + } else { + coinTime = format("hh:mm", coinDate); + } + } + } + + let day = format("MM-dd hh:mm", new Date()); + let week = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]; + day += " " + week[new Date().getDay()]; + + //参量质变仪 + if (data?.transformer?.obtained) { + data.transformer.reached = data.transformer.recovery_time.reached; + let recovery_time = ""; + + if (data.transformer.recovery_time.Day > 0) { + recovery_time += `${data.transformer.recovery_time.Day}天`; + } + if (data.transformer.recovery_time.Hour > 0) { + recovery_time += `${data.transformer.recovery_time.Hour}小时`; + } + if (data.transformer.recovery_time.Minute > 0) { + recovery_time += `${data.transformer.recovery_time.Minute}分钟`; + } + data.transformer.recovery_time = recovery_time; + } + var image= fs.readdirSync(`./plugins/xiaoyao-cvs-plugin/resources/dailyNote/background_image`); + var list_img=[]; + for (let val of image) { + list_img.push(val) + } + var imgs=list_img[lodash.random(0, list_img.length-1)]; + return await Common.render("dailyNote/dailyNote", { + save_id: uid, + uid: uid, + resinMaxTime, + remained_time, + coinTime, + imgs, + day, + ...data, + }, { + e, + render, + scale: 1.2 + }) + return true; +} + + +async function getDailyNote(uid, cookie) { + let { + url, + headers, + query, + body + } = getUrl("dailyNote", uid); + + headers.Cookie = cookie; + + const response = await fetch(url, { + method: "get", + headers + }); + return response; +} + +export async function saveJson() { + let path = "data/NoteCookie/NoteCookie.json"; + fs.writeFileSync(path, JSON.stringify(NoteCookie, "", "\t")); +} diff --git a/components/Common.js b/components/Common.js index b2baf03..2871027 100644 --- a/components/Common.js +++ b/components/Common.js @@ -5,7 +5,7 @@ import { currentVersion, yunzaiVersion } 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/miao-plugin/resources/common/layout/"; + let _layout_path = process.cwd() + "/plugins/xiaoyao-cvs-plugin/resources/"; let base64 = await render(paths[0], paths[1], { ...params, _layout_path, diff --git a/components/MysApi.js b/components/MysApi.js new file mode 100644 index 0000000..721cb90 --- /dev/null +++ b/components/MysApi.js @@ -0,0 +1,158 @@ +import md5 from "md5"; +import lodash from 'lodash'; +import fetch from "node-fetch"; + +let MysApi = { + getUrl(type, uid, data = {}) { + let url = "https://api-takumi.mihoyo.com"; + let game_record = "/game_record/app/genshin/api/"; + let server = MysApi.getServer(uid); + let query, body; + + switch (type) { + //首页宝箱 + case "index": + url += game_record + "index"; + query = `role_id=${uid}&server=${server}`; + break; + //深渊 + case "spiralAbyss": + url += game_record + "spiralAbyss"; + query = `role_id=${uid}&schedule_type=${data.schedule_type}&server=${server}`; + break; + //角色详情 + case "character": + url += game_record + "character"; + body = JSON.stringify(data); + break; + //树脂每日任务(只能当前id) + case "dailyNote": + url += game_record + "dailyNote"; + query = `role_id=${uid}&server=${server}`; + break; + case "detail": + url += "/event/e20200928calculate/v1/sync/avatar/detail"; + query = `uid=${uid}®ion=${server}&avatar_id=${data.avatar_id}`; + break; + case "getAnnouncement": + url += "/game_record/card/wapi/getAnnouncement"; + break; + case "getGameRecordCard": + url += "/game_record/card/wapi/getGameRecordCard"; + query = `uid=${uid}`;//米游社id + break; + case "bbs_sign_info": + url += "/event/bbs_sign_reward/info"; + query = `act_id=e202009291139501®ion=${server}&uid=${uid}`; + break; + case "bbs_sign_home": + url += "/event/bbs_sign_reward/home"; + query = `act_id=e202009291139501®ion=${server}&uid=${uid}`; + break; + case "bbs_sign": + url += "/event/bbs_sign_reward/sign"; + body = JSON.stringify({ act_id: "e202009291139501", region: server, uid: uid, }); + break; + case "ys_ledger": + url = "https://hk4e-api.mihoyo.com/event/ys_ledger/monthInfo"; + query = `month=${data.month}&bind_uid=${uid}&bind_region=${server}`; + break; + } + + if (query) { + url += "?" + query; + } + + let headers; + if (type === "bbs_sign") { + headers = MysApi.getHeaders_sign(); + } else { + headers = MysApi.getHeaders(query, body); + } + + return { url, headers, query, body }; + }, + + getServer(uid) { + switch (uid.toString()[0]) { + case "1": + case "2": + return "cn_gf01"; //官服 + case "5": + return "cn_qd01"; //B服 + } + return "cn_gf01"; //官服 + }, + +//# Github-@lulu666lulu + getDs(q = "", b = "") { + let 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 + getDS_sign() { + 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}`; + }, + + getHeaders(q = "", b = "") { + return { + "x-rpc-app_version": "2.20.1", + "x-rpc-client_type": 5, + DS: MysApi.getDs(q, b), + }; + }, + + getHeaders_sign() { + return { + "x-rpc-app_version": "2.3.0", + "x-rpc-client_type": 5, + "x-rpc-device_id": MysApi.guid(), + "User-Agent": " miHoYoBBS/2.3.0", + DS: MysApi.getDS_sign(), + }; + }, + + guid() { + function S4() { + return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1); + } + + return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4()); + }, + + // 按type请求 + request: async function (type, cfg) { + let { uid } = cfg; + let { url, headers } = MysApi.getUrl(type, uid); + return await MysApi.fetch(url, headers, cfg); + }, + + // 发送请求 + fetch: async function (url, cfg) { + let { cookie, error, success, headers, method } = cfg; + headers = headers || {}; + method = method || "get"; + headers.Cookie = cookie; + let response = await fetch(url, { method, headers }); + if (!response.ok) { + return await error(-1, { + msg: "米游社接口错误" + }) + } + let res = await response.json(); + if (res.retcode * 1 !== 0) { + return await error(res.retcode * 1, res) + } + return await success(res.data, res) + } +} + +export default MysApi; diff --git a/index.js b/index.js index 1a660ba..12c7d3a 100644 --- a/index.js +++ b/index.js @@ -2,18 +2,27 @@ import lodash from "lodash"; import { AtlasAlias } from "./apps/xiaoyao_image.js"; -import {versionInfo,calendar} from "./apps/help.js" +import { + versionInfo, + calendar +} from "./apps/help.js"; +import { + Note +} from "./apps/Note.js" import { rule as adminRule, updateRes, updateMiaoPlugin } from "./apps/admin.js"; export { - updateRes,updateMiaoPlugin,versionInfo,calendar, - AtlasAlias + updateRes, + updateMiaoPlugin, + versionInfo, + calendar, + AtlasAlias, + Note }; - let rule = { versionInfo: { reg: "^#图鉴版本$", @@ -23,10 +32,14 @@ let rule = { reg: "^#图鉴列表$", describe: "【#日历】 活动日历", }, - AtlasAlias:{ + AtlasAlias: { reg: "#*(.*)(信息|图鉴|命座|天赋|突破|材料|特色料理|特殊料理)$", //匹配消息正则,命令正则 describe: "【刻晴信息、刻晴图鉴、刻晴突破、刻晴命座】角色信息图鉴", //【命令】功能说明 }, + Note: { + reg: "^#*(体力|树脂|查询体力|便笺|便签)$", //匹配消息正则,命令正则 + describe: "体力", + }, ...adminRule }; diff --git a/resources/dailyNote/background_image/01.png b/resources/dailyNote/background_image/01.png new file mode 100644 index 0000000..ac37514 Binary files /dev/null and b/resources/dailyNote/background_image/01.png differ diff --git a/resources/dailyNote/background_image/background.png b/resources/dailyNote/background_image/background.png new file mode 100644 index 0000000..ed616f1 Binary files /dev/null and b/resources/dailyNote/background_image/background.png differ diff --git a/resources/dailyNote/dailyNote.css b/resources/dailyNote/dailyNote.css new file mode 100644 index 0000000..4678639 --- /dev/null +++ b/resources/dailyNote/dailyNote.css @@ -0,0 +1,91 @@ +@font-face { + font-family: HYWenHei-55W; + src: url('../font/HYWenHei-55W.ttf'); +} + +html { + width: 964px; + height: 100%; + font-family: HYWenHei-55W, monospace; +} +#container { + min-height: 900px; + height: auto; + width: 100%; + } + + .title { + position: absolute; + top: 64px; + left: 225px; + font-weight: bold; + font-size: 22px; + text-align: left; + } + + .item { + width: 228px; + left: 200px; + top: 350px; + color: #7b8386; + font-weight: bold; + font-size: 22px; + margin-left: 205px; + margin-bottom: 25px; + } + + .paiqian { + position: absolute; + width: 400px; + height: 26px; + left: 520px; + top: 80px; + text-align: center; + color: #7b8386; + font-weight: bold; + font-size: 20px; + } + + .icon { + width: 65px; + margin: 5px 0 4px 13px; + display: inline-block; + vertical-align: bottom; + } + + .icon_div { + display: inline-block; + vertical-align: super; + margin-top: -10px; + margin-left: 15px; + } + + .all_icon { + text-align: left; + position: relative; + top: -25px; + } + + .time { + position: relative; + top: -20px; + } + + .item .main .time { + font-size: 12px; + display: block; + position: initial; + } + + .item .main { + display: block; + } + + .item .top { + font-weight: bold; + font-size: 30px; + display: block; + } + .item:nth-last-child(2){ + margin-top: 35px; + } \ No newline at end of file diff --git a/resources/dailyNote/dailyNote.html b/resources/dailyNote/dailyNote.html new file mode 100644 index 0000000..6d31b91 --- /dev/null +++ b/resources/dailyNote/dailyNote.html @@ -0,0 +1,128 @@ + + +
+ + + + + + +