miao-plugin/apps/word-cloud.js
2022-04-10 05:33:21 +08:00

195 lines
6.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//技能列表配置了cookie能查
import fs from "fs";
import lodash from "lodash";
import common from "../../../lib/common.js";
import { segment } from "oicq";
export async function talentList(e, { render }) {
//缓存时间,单位小时
let cacheCd = 6;
let msg = e.msg.replace("#", "").trim();
if (msg === "角色统计" || msg === "武器统计") {
//暂时避让一下抽卡分析的关键词
return false;
}
let MysApi = await getMysApi(e);
if (!MysApi) return true;
let uid = MysApi.targetUid;
//禁止重复获取
if (skillLoading[e.user_id]) {
e.reply("角色数据获取中,请耐心等待...");
setTimeout(() => {
if (skillLoading[e.user_id]) delete skillLoading[e.user_id];
}, 60000);
return;
}
const displayMode = /(角色|武器|练度)/.test(e.msg) ? "weapon" : "talent";
//四星五星
let star = 0;
if (/(四|4)/.test(msg)) star = 4;
if (/(五|5)/.test(msg)) star = 5;
// 技能查询缓存
let cachePath = `./data/cache/`;
if (!fs.existsSync(cachePath)) {
fs.mkdirSync(cachePath);
}
cachePath += "talentList/";
if (!fs.existsSync(cachePath)) {
fs.mkdirSync(cachePath);
}
let avatarRet = [];
let hasCache = await redis.get(`cache:uid-talent-new:${uid}`); // 由于数据结构改变,临时修改一下键值,防止命中历史缓存导致展示错误
if (hasCache && !/force/.test(e.msg)) {
// 有缓存优先使用缓存
let jsonRet = fs.readFileSync(cachePath + `${uid}.json`, "utf8");
avatarRet = JSON.parse(jsonRet);
} else {
skillLoading[e.user_id] = true;
let resIndex = await MysApi.getCharacter();
if (!resIndex) {
delete skillLoading[e.user_id];
return true;
}
let avatarData = resIndex && resIndex.avatars || [];
// let skillRet = [], skill = [];
//配置了cookie的才去获取技能
// if (NoteCookie[e.user_id]) {
let skillRet = [], skill = [];
//配置了完整cookie的才去获取技能
if (NoteCookie[e.user_id] && NoteCookie[e.user_id].cookie.includes("cookie_token")) {
e.reply("角色数据获取中,请耐心等待...");
//批量获取技能数据分组10个id一次延迟100ms
let num = 10, ms = 100;
let avatarArr = lodash.chunk(avatarData, num);
for (let val of avatarArr) {
for (let avatar of val) {
skillRet.push(getSkill(e, uid, avatar, MysApi));
}
skillRet = await Promise.all(skillRet);
//过滤没有获取成功的
skillRet.filter(item => item.a);
skillRet = skillRet.filter(item => item.a);
await common.sleep(ms);
}
skill = lodash.keyBy(skillRet, "id");
}
// 天赋等级背景
const talentLvMap = '0,1,1,1,2,2,3,3,3,4,5'.split(',')
// 根据每日素材构建 角色->素材的映射关系
let charTalentMap = {};
daily.forEach((weekCfg, week) => {
lodash.forIn(weekCfg[0], (talentCfg, talentName) => {
talentCfg[1].forEach((charName) => {
charTalentMap[charName] = { name: talentName, week: [3, 1, 2][week] };
})
})
});
for (let idx in avatarData) {
let curr = avatarData[idx];
let avatar = lodash.pick(curr, "id,name,rarity,level,rarity,fetter".split(","));
// 埃洛伊rarity是105...
avatar.rarity = avatar.rarity > 5 ? 5 : avatar.rarity;
let weapon = curr.weapon || {};
"name,level,rarity,affix_level".split(",").forEach((idx) => {
avatar[`weapon_${idx}`] = curr.weapon[idx];
});
avatar.cons = curr.actived_constellation_num;
if (avatar.id == 10000007) {
avatar.name = "荧";
} else if (avatar.id == 10000005) {
avatar.name = "空";
} else {
let talent = charTalentMap[avatar.name] || {};
avatar.talent = talent.name;
avatar.talentWeek = talent.week; //`${talent.week}${talent.week + 3}`;
}
let skillRet = skill[avatar.id] || {};
const talentConsCfg = { a: 0, e: 3, q: 5 };
lodash.forIn(talentConsCfg, (consLevel, key) => {
let talent = skillRet[key] || {};
// 天赋等级
avatar[key] = talent.level_current || '-';
// 是否有命座加成
avatar[`${key}_plus`] = talent.level_current > talent.level_original;
// 天赋书星级
avatar[`${key}_lvl`] = talentLvMap[talent.level_original * 1];
avatar[`${key}_original`] = talent.level_original * 1;
})
avatar.aeq = avatar.a * 1 + avatar.e + avatar.q;
avatarRet.push(avatar);
}
fs.writeFileSync(cachePath + `${uid}.json`, JSON.stringify(avatarRet));
//缓存
await redis.set(`cache:uid-talent-new:${uid}`, uid, { EX: 3600 * cacheCd });
delete skillLoading[e.user_id];
// }
}
//超过八个角色才分类四星五星
if (star >= 4 && avatarRet.length > 8) {
avatarRet = avatarRet.filter(item => item.rarity == star);
}
let sortKey = ({
talent: "aeq,rarity,level,star,fetter,talentWeek",
weapon: "level,rarity,aeq,cons,weapon_level,weapon_rarity,weapon_affix_level,fetter"
})[displayMode].split(",");
avatarRet = lodash.orderBy(avatarRet, sortKey, lodash.repeat("desc,", sortKey.length).split(","));
let noTalent = avatarRet.length == 0 || /^\-+$/.test(avatarRet.map((d) => d.a).join(""));
let talentNotice = `技能列表每${cacheCd}小时更新一次`;
if (noTalent) {
talentNotice = "未绑定体力Cookie无法获取天赋列表。请回复 #体力 获取配置教程";
}
let week = new Date().getDay();
if (new Date().getHours() < 4) {
week--;
}
let base64 = await render("genshin", "talentList", {
save_id: uid,
uid: uid,
avatars: avatarRet,
bgType: Math.ceil(Math.random() * 3),
abbr: genshin.abbr,
displayMode,
isSelf: e.isSelf,
week: [3, 1, 2][week % 3],
talentNotice
});
if (base64) {
let msg = [];
if (e.isGroup) {
let name = lodash.truncate(e.sender.card, { length: 8 });
msg.push(segment.at(e.user_id, name));
}
msg.push(segment.image(`base64://${base64}`));
e.reply(msg);
}
return true; //事件结束不再往下
}