2022-04-14 20:53:22 +00:00
|
|
|
|
import fs from "fs";
|
|
|
|
|
import lodash from "lodash";
|
2022-04-15 14:33:51 +00:00
|
|
|
|
import Format from "./Format.js";
|
2022-04-15 22:24:25 +00:00
|
|
|
|
import Character from "./models/Character.js";
|
2022-04-17 11:03:44 +00:00
|
|
|
|
import Reliquaries from "./models/Reliquaries.js";
|
2022-06-20 22:55:08 +00:00
|
|
|
|
import Miao from "./profile-data/miao.js";
|
|
|
|
|
import Enka from "./profile-data/enka.js";
|
2022-06-03 09:13:12 +00:00
|
|
|
|
|
2022-04-14 20:53:22 +00:00
|
|
|
|
const _path = process.cwd();
|
2022-04-16 09:40:30 +00:00
|
|
|
|
const cfgPath = `${_path}/plugins/miao-plugin/config.js`;
|
|
|
|
|
let config = {};
|
2022-06-03 09:13:12 +00:00
|
|
|
|
|
2022-04-16 09:40:30 +00:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-05 10:10:29 +00:00
|
|
|
|
function sleep(ms) {
|
|
|
|
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-14 22:07:24 +00:00
|
|
|
|
function getServ(uid) {
|
2022-06-27 20:46:49 +00:00
|
|
|
|
if (config.profileApi) {
|
|
|
|
|
return config.profileApi({ Enka, Miao })
|
|
|
|
|
}
|
2022-06-14 22:07:24 +00:00
|
|
|
|
if ((uid + '')[0] === '5') {
|
2022-06-14 22:14:58 +00:00
|
|
|
|
return Miao;
|
2022-06-14 22:07:24 +00:00
|
|
|
|
}
|
|
|
|
|
return Enka;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-14 20:53:22 +00:00
|
|
|
|
let Profile = {
|
2022-04-15 22:05:31 +00:00
|
|
|
|
async request(uid, e) {
|
2022-06-06 20:59:47 +00:00
|
|
|
|
if (uid.toString().length !== 9) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-06-14 22:07:24 +00:00
|
|
|
|
let Serv = getServ(uid);
|
|
|
|
|
|
2022-06-02 10:25:09 +00:00
|
|
|
|
let inCd = await redis.get(`miao:role-all:${uid}`);
|
|
|
|
|
if (inCd === 'loading') {
|
|
|
|
|
e.reply("请求过快,请稍后重试..");
|
|
|
|
|
return false;
|
2022-06-14 22:07:24 +00:00
|
|
|
|
} else if (inCd === 'pending' && false) {
|
|
|
|
|
e.reply(`距上次请求刷新成功间隔小于${Serv.cd}分钟,请稍后重试..`);
|
2022-06-02 10:25:09 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-06-14 22:07:24 +00:00
|
|
|
|
|
2022-06-03 19:00:23 +00:00
|
|
|
|
await redis.set(`miao:role-all:${uid}`, 'loading', { EX: 20 });
|
2022-06-02 10:25:09 +00:00
|
|
|
|
e.reply("开始获取数据,可能会需要一定时间~");
|
|
|
|
|
await sleep(1000);
|
|
|
|
|
let data;
|
|
|
|
|
try {
|
2022-06-14 22:07:24 +00:00
|
|
|
|
data = await Serv.request({ uid, e, config });
|
2022-06-03 09:13:12 +00:00
|
|
|
|
// enka服务测冷却时间5分钟
|
2022-06-14 22:07:24 +00:00
|
|
|
|
await redis.set(`miao:role-all:${uid}`, 'pending', { EX: Serv.cd * 60 });
|
|
|
|
|
return Profile.save(uid, data, Serv.key);
|
2022-06-02 10:25:09 +00:00
|
|
|
|
} catch (err) {
|
2022-06-03 09:13:12 +00:00
|
|
|
|
console.log(err);
|
2022-06-02 10:25:09 +00:00
|
|
|
|
e.reply(`请求失败`);
|
2022-04-16 09:40:30 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2022-04-14 20:53:22 +00:00
|
|
|
|
},
|
|
|
|
|
|
2022-06-14 22:07:24 +00:00
|
|
|
|
save(uid, data, 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")) || {};
|
|
|
|
|
}
|
|
|
|
|
lodash.assignIn(userData, lodash.pick(data, "uid,name,lv,avatar".split(",")));
|
|
|
|
|
userData.chars = userData.chars || {};
|
|
|
|
|
lodash.forEach(data.chars, (char, charId) => {
|
2022-06-14 22:07:24 +00:00
|
|
|
|
let original = userData.chars[charId] || {};
|
2022-06-14 22:14:58 +00:00
|
|
|
|
if (char.dataSource === "miao-pre" && original && original.dataSource) {
|
2022-06-14 22:07:24 +00:00
|
|
|
|
original.dataSource = char.dataSource;
|
|
|
|
|
} else {
|
|
|
|
|
userData.chars[charId] = char;
|
|
|
|
|
}
|
2022-04-14 20:53:22 +00:00
|
|
|
|
});
|
|
|
|
|
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-23 21:16:37 +00:00
|
|
|
|
|
2022-06-14 22:07:24 +00:00
|
|
|
|
saveCharData(uid, ds) {
|
|
|
|
|
if (!uid || !ds.id) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
let userData = {};
|
|
|
|
|
const userFile = `${userPath}/${uid}.json`;
|
|
|
|
|
if (fs.existsSync(userFile)) {
|
|
|
|
|
userData = JSON.parse(fs.readFileSync(userFile, "utf8")) || {};
|
|
|
|
|
}
|
|
|
|
|
userData.chars = userData.chars || {};
|
|
|
|
|
userData.chars[ds.id] = ds;
|
|
|
|
|
fs.writeFileSync(userFile, JSON.stringify(userData), "", " ");
|
|
|
|
|
return ds;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
_get(uid, charId) {
|
2022-04-14 20:53:22 +00:00
|
|
|
|
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;
|
2022-04-15 14:33:51 +00:00
|
|
|
|
},
|
2022-04-23 21:16:37 +00:00
|
|
|
|
|
2022-06-29 20:40:06 +00:00
|
|
|
|
async get(uid, charId, onlyAvailable = false) {
|
|
|
|
|
if (onlyAvailable) {
|
|
|
|
|
let data = await Profile.get(uid, charId);
|
|
|
|
|
if (data && data.dataSource && data.dataSource !== "input") {
|
|
|
|
|
return data;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-14 22:07:24 +00:00
|
|
|
|
let data = Profile._get(uid, charId);
|
|
|
|
|
let Serv = getServ(uid);
|
2022-06-15 21:09:39 +00:00
|
|
|
|
if (Serv.getCharData && data && data.id) {
|
2022-07-02 02:38:41 +00:00
|
|
|
|
return await Serv.getCharData(uid, data, Profile.saveCharData, { config });
|
2022-06-14 22:07:24 +00:00
|
|
|
|
}
|
|
|
|
|
return data;
|
|
|
|
|
},
|
|
|
|
|
|
2022-04-23 21:16:37 +00:00
|
|
|
|
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;
|
|
|
|
|
},
|
|
|
|
|
|
2022-06-25 23:45:43 +00:00
|
|
|
|
formatArti(ds, markCfg = false, isMain = false) {
|
2022-04-15 14:33:51 +00:00
|
|
|
|
if (lodash.isArray(ds[0])) {
|
|
|
|
|
let ret = [];
|
|
|
|
|
lodash.forEach(ds, (d) => {
|
2022-06-25 23:45:43 +00:00
|
|
|
|
ret.push(Profile.formatArti(d, markCfg, isMain));
|
2022-04-15 14:33:51 +00:00
|
|
|
|
})
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
2022-06-25 23:45:43 +00:00
|
|
|
|
let title = ds[0], key = "", val = ds[1], num = ds[1];
|
2022-04-16 19:39:45 +00:00
|
|
|
|
if (!title || title === "undefined") {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
2022-04-15 22:05:31 +00:00
|
|
|
|
if (/伤害加成/.test(title) && val < 1) {
|
|
|
|
|
val = Format.pct(val * 100);
|
2022-06-25 23:45:43 +00:00
|
|
|
|
num = num * 100;
|
2022-04-15 22:05:31 +00:00
|
|
|
|
} else if (/伤害加成|大|暴|充能|治疗/.test(title)) {
|
2022-04-15 14:33:51 +00:00
|
|
|
|
val = Format.pct(val);
|
|
|
|
|
} else {
|
2022-04-15 22:05:31 +00:00
|
|
|
|
val = Format.comma(val, 1);
|
2022-04-15 14:33:51 +00:00
|
|
|
|
}
|
2022-04-15 22:05:31 +00:00
|
|
|
|
|
2022-04-15 14:33:51 +00:00
|
|
|
|
if (/元素伤害加成/.test(title)) {
|
|
|
|
|
title = title.replace("元素伤害", "伤");
|
2022-06-25 23:45:43 +00:00
|
|
|
|
key = "dmg";
|
2022-04-15 22:30:19 +00:00
|
|
|
|
} else if (title === "物理伤害加成") {
|
|
|
|
|
title = "物伤加成";
|
2022-06-25 23:45:43 +00:00
|
|
|
|
key = "phy";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
key = key || keyMap[title];
|
|
|
|
|
|
|
|
|
|
let mark = 0;
|
|
|
|
|
if (markCfg) {
|
|
|
|
|
mark = Format.comma(markCfg[title] * num || 0);
|
|
|
|
|
if (isMain) {
|
|
|
|
|
mark = mark / 4;
|
|
|
|
|
}
|
2022-04-15 14:33:51 +00:00
|
|
|
|
}
|
2022-06-25 23:45:43 +00:00
|
|
|
|
return { title, val, mark };
|
2022-04-15 22:05:31 +00:00
|
|
|
|
},
|
2022-04-23 21:16:37 +00:00
|
|
|
|
|
2022-04-15 22:05:31 +00:00
|
|
|
|
getArtiMark(data, ds) {
|
2022-04-17 11:03:44 +00:00
|
|
|
|
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;
|
2022-04-23 21:16:37 +00:00
|
|
|
|
},
|
|
|
|
|
|
2022-05-31 21:16:10 +00:00
|
|
|
|
inputProfile(uid, e) {
|
2022-06-03 19:00:23 +00:00
|
|
|
|
let { avatar, inputData } = e;
|
2022-06-11 14:10:53 +00:00
|
|
|
|
let char = Character.get(avatar);
|
2022-06-14 22:07:24 +00:00
|
|
|
|
let originalData = Profile._get(uid, char.id);
|
2022-06-11 21:54:41 +00:00
|
|
|
|
if (!originalData || !['enka', 'input2'].includes(originalData.dataSource)) {
|
2022-06-11 14:10:53 +00:00
|
|
|
|
return `请先获取${char.name}的面板数据后,再进行面板数据更新`;
|
|
|
|
|
}
|
2022-05-31 21:25:38 +00:00
|
|
|
|
inputData = inputData.replace("#", "");
|
2022-05-31 21:16:10 +00:00
|
|
|
|
inputData = inputData.replace(/,|;|、|\n|\t/g, ",");
|
2022-06-11 14:10:53 +00:00
|
|
|
|
let attr = originalData.attr || {};
|
2022-05-31 21:16:10 +00:00
|
|
|
|
let attrMap = {
|
|
|
|
|
hp: /生命/,
|
|
|
|
|
def: /防御/,
|
|
|
|
|
atk: /攻击/,
|
|
|
|
|
mastery: /精通/,
|
2022-06-14 22:07:24 +00:00
|
|
|
|
cRate: /(暴击率|暴率|暴击$)/,
|
|
|
|
|
cDmg: /(暴伤|暴击伤害)/,
|
2022-05-31 21:16:10 +00:00
|
|
|
|
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();
|
2022-06-14 22:07:24 +00:00
|
|
|
|
name = name.replace("爆", "暴");
|
2022-06-04 21:29:24 +00:00
|
|
|
|
let range = (src, min = 0, max = 1200) => Math.max(min, Math.min(max, src * 1 || 0));
|
|
|
|
|
|
2022-05-31 21:16:10 +00:00
|
|
|
|
lodash.forEach(attrMap, (reg, key) => {
|
|
|
|
|
if (reg.test(name)) {
|
2022-06-04 21:29:24 +00:00
|
|
|
|
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;
|
2022-05-31 21:16:10 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
if (lodash.keys(attr) < 3) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-11 14:10:53 +00:00
|
|
|
|
originalData.dataSource = "input2";
|
|
|
|
|
originalData.attr = attr;
|
|
|
|
|
|
2022-05-31 21:16:10 +00:00
|
|
|
|
let userData = {};
|
|
|
|
|
const userFile = `${userPath}/${uid}.json`;
|
|
|
|
|
if (fs.existsSync(userFile)) {
|
|
|
|
|
userData = JSON.parse(fs.readFileSync(userFile, "utf8")) || {};
|
|
|
|
|
}
|
|
|
|
|
userData.chars = userData.chars || {};
|
2022-06-11 14:10:53 +00:00
|
|
|
|
userData.chars[avatar] = originalData;
|
2022-05-31 21:16:10 +00:00
|
|
|
|
fs.writeFileSync(userFile, JSON.stringify(userData), "", " ");
|
|
|
|
|
return true;
|
2022-04-14 20:53:22 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
export default Profile;
|