miao-plugin/components/Profile.js

254 lines
7.1 KiB
JavaScript
Raw Normal View History

2022-04-14 20:53:22 +00:00
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";
2022-04-14 20:53:22 +00:00
import Data from "./data/enka.js";
2022-04-14 20:53:22 +00:00
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;
2022-04-14 20:53:22 +00:00
}
}
const userPath = `${_path}/data/UserData/`;
if (!fs.existsSync(userPath)) {
fs.mkdirSync(userPath);
}
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
2022-04-14 20:53:22 +00:00
let Profile = {
2022-04-15 22:05:31 +00:00
async request(uid, e) {
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("距上次请求刷新成功间隔小于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;
}
2022-04-14 20:53:22 +00:00
},
save(uid, ds, dataSource = 'enka') {
2022-04-14 20:53:22 +00:00
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);
2022-04-14 20:53:22 +00:00
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), "", " ");
2022-04-15 22:05:31 +00:00
return data;
2022-04-14 20:53:22 +00:00
},
2022-04-14 20:53:22 +00:00
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 [];
}
2022-04-15 22:05:31 +00:00
if (/伤害加成/.test(title) && val < 1) {
val = Format.pct(val * 100);
} else if (/伤害加成|大|暴|充能|治疗/.test(title)) {
val = Format.pct(val);
} else {
2022-04-15 22:05:31 +00:00
val = Format.comma(val, 1);
}
2022-04-15 22:05:31 +00:00
if (/元素伤害加成/.test(title)) {
title = title.replace("元素伤害", "伤");
} else if (title === "物理伤害加成") {
title = "物伤加成";
}
return [title, val];
2022-04-15 22:05:31 +00:00
},
2022-04-15 22:05:31 +00:00
getArtiMark(data, ds) {
Reliquaries.getMark(data)
2022-04-15 22:05:31 +00:00
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;
2022-04-14 20:53:22 +00:00
}
};
export default Profile;