mirror of
https://github.com/yoimiya-kokomi/miao-plugin.git
synced 2024-11-22 06:58:24 +00:00
195 lines
6.1 KiB
JavaScript
195 lines
6.1 KiB
JavaScript
//技能列表,配置了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; //事件结束不再往下
|
||
} |