miao-plugin/components/Profile.js
yoimiya-kokomi e503488a7e #面板更新命令增加uid合法性校验
`#角色持有率`、`#深渊出场率` 页面细节样式调整
2022-06-07 04:59:47 +08:00

257 lines
7.2 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.

import fs from "fs";
import fetch from "node-fetch";
import lodash from "lodash";
import Format from "./Format.js";
import Character from "./models/Character.js";
import Reliquaries from "./models/Reliquaries.js";
import Data from "./data/enka.js";
const _path = process.cwd();
const cfgPath = `${_path}/plugins/miao-plugin/config.js`;
let config = {};
if (fs.existsSync(cfgPath)) {
let fileData = await import (`file://${cfgPath}`);
if (fileData && fileData.config) {
config = fileData.config;
}
}
const userPath = `${_path}/data/UserData/`;
if (!fs.existsSync(userPath)) {
fs.mkdirSync(userPath);
}
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
let Profile = {
async request(uid, e) {
if (uid.toString().length !== 9) {
return false;
}
let profileApi = config.profileApi || function (uid) {
return `https://enka.shinshin.moe/u/${uid}/__data.json`
};
let api = profileApi(uid);
let inCd = await redis.get(`miao:role-all:${uid}`);
if (inCd === 'loading') {
e.reply("请求过快,请稍后重试..");
return false;
} else if (inCd === 'pending') {
e.reply("#ref距上次请求刷新成功间隔小于5分钟请稍后重试..");
return false;
}
await redis.set(`miao:role-all:${uid}`, 'loading', { EX: 20 });
e.reply("开始获取数据,可能会需要一定时间~");
await sleep(1000);
let data;
try {
let req = await fetch(api);
data = await req.json();
if (!data.playerInfo) {
if ((uid + '')[0] === '2') {
e.reply(`请求失败:暂时不支持以2开头的UID角色面板更新请等待服务后续升级`);
} else if ((uid + '')[0] === '5') {
e.reply(`请求失败:暂时不支持B服角色面板更新请等待服务后续升级`);
} else {
e.reply(`请求失败:${data.msg || "请求错误,请稍后重试"}`);
}
return false;
}
let details = data.avatarInfoList;
if (!details || details.length === 0 || !details[0].propMap) {
e.reply(`请打开角色展柜的显示详情`);
return false;
}
// enka服务测冷却时间5分钟
await redis.set(`miao:role-all:${uid}`, 'pending', { EX: 300 });
let userData = {};
userData = Profile.save(uid, data, 'enka')
return userData;
} catch (err) {
console.log(err);
e.reply(`请求失败`);
return false;
}
},
save(uid, ds, dataSource = 'enka') {
let userData = {};
const userFile = `${userPath}/${uid}.json`;
if (fs.existsSync(userFile)) {
userData = JSON.parse(fs.readFileSync(userFile, "utf8")) || {};
}
let data;
data = Data.getData(uid, ds);
lodash.assignIn(userData, lodash.pick(data, "uid,name,lv,avatar".split(",")));
userData.chars = userData.chars || {};
lodash.forEach(data.chars, (char, charId) => {
userData.chars[charId] = char;
});
fs.writeFileSync(userFile, JSON.stringify(userData), "", " ");
return data;
},
get(uid, charId) {
const userFile = `${userPath}/${uid}.json`;
let userData = {};
if (fs.existsSync(userFile)) {
userData = JSON.parse(fs.readFileSync(userFile, "utf8")) || {};
}
if (userData && userData.chars && userData.chars[charId]) {
return userData.chars[charId];
}
return false;
},
getAll(uid) {
const userFile = `${userPath}/${uid}.json`;
let userData = {};
if (fs.existsSync(userFile)) {
userData = JSON.parse(fs.readFileSync(userFile, "utf8")) || {};
}
if (userData && userData.chars) {
return userData.chars;
}
return false;
},
formatArti(ds) {
if (lodash.isArray(ds[0])) {
let ret = [];
lodash.forEach(ds, (d) => {
ret.push(Profile.formatArti(d));
})
return ret;
}
let title = ds[0], val = ds[1];
if (!title || title === "undefined") {
return [];
}
if (/伤害加成/.test(title) && val < 1) {
val = Format.pct(val * 100);
} else if (/伤害加成|大|暴|充能|治疗/.test(title)) {
val = Format.pct(val);
} else {
val = Format.comma(val, 1);
}
if (/元素伤害加成/.test(title)) {
title = title.replace("元素伤害", "伤");
} else if (title === "物理伤害加成") {
title = "物伤加成";
}
return [title, val];
},
getArtiMark(data, ds) {
Reliquaries.getMark(data)
let total = 0;
lodash.forEach(data, (ret) => {
if (ret[0] && ret[1]) {
total += mark[ret[0]] * ret[1];
}
})
if (ds && /暴/.test(ds[0])) {
total += 20;
}
return total;
},
inputProfile(uid, e) {
let { avatar, inputData } = e;
inputData = inputData.replace("#", "");
inputData = inputData.replace(/||、|\n|\t/g, ",");
let attr = {};
let attrMap = {
hp: /生命/,
def: /防御/,
atk: /攻击/,
mastery: /精通/,
cRate: /(暴击率|爆率|暴击$)/,
cDmg: /(爆伤|暴击伤害)/,
hInc: /治疗/,
recharge: /充能/,
dmgBonus: /[火|水|雷|草|风|岩|冰|素|^]伤/,
phyBonus: /(物理|物伤)/
}
lodash.forEach(inputData.split(","), (ds, idx) => {
ds = ds.trim();
if (!ds) {
return;
}
let dRet = /(.*?)([0-9\.\+\s]+)/.exec(ds);
if (!dRet || !dRet[1] || !dRet[2]) {
return;
}
let name = dRet[1].trim(),
data = dRet[2].trim();
let range = (src, min = 0, max = 1200) => Math.max(min, Math.min(max, src * 1 || 0));
lodash.forEach(attrMap, (reg, key) => {
if (reg.test(name)) {
let tmp = data.split("+");
switch (key) {
case "hp":
attr[key + "Base"] = range(tmp[0].trim(), 0, 16000);
attr[key] = range(tmp[0].trim() * 1 + tmp[1].trim() * 1, attr[key + "Base"], 50000);
break;
case "def":
case "atk":
attr[key + "Base"] = range(tmp[0].trim(), 0, 1100);
attr[key] = range(tmp[0].trim() * 1 + tmp[1].trim() * 1, attr[key + "Base"], 4500);
break;
case "mastery":
attr[key] = range(data, 0, 1200);
break;
case "cRate":
attr[key] = range(data, -95, 120);
break;
case "cDmg":
attr[key] = range(data, 0, 320);
break;
case "recharge":
case "hInc":
attr[key] = range(data, 0, 400);
break;
case "dmgBonus":
case "phyBonus":
attr[key] = range(data, 0, 200);
break;
}
}
})
})
if (lodash.keys(attr) < 3) {
return false;
}
let char = Character.get(avatar);
let data = {
id: char.id,
name: char.name,
dataSource: "input",
attr
}
let userData = {};
const userFile = `${userPath}/${uid}.json`;
if (fs.existsSync(userFile)) {
userData = JSON.parse(fs.readFileSync(userFile, "utf8")) || {};
}
userData.chars = userData.chars || {};
userData.chars[avatar] = data;
fs.writeFileSync(userFile, JSON.stringify(userData), "", " ");
return true;
}
};
export default Profile;