mirror of
https://github.com/yoimiya-kokomi/miao-plugin.git
synced 2024-11-29 10:36:25 +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; //事件结束不再往下
|
|||
|
}
|