diff --git a/.gitignore b/.gitignore index 1b80c388..2fd0122e 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,6 @@ *.css.map /resources/character-img/*/upload/ /resources/help/help-list.js -/resources/help/help-cfg.js \ No newline at end of file +/resources/help/help-cfg.js +/config/character.js +/config/profile.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b113da4..466388d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.9.1 + +* `#更新面板`支持配置更新API + * 若面板更新失败可尝试在**config/profile.js**文件中配置切换更新API +* 修正部分V3Yunzai下的适配问题 + # 1.9.0 * 初步适配Yunzai V3 diff --git a/apps/character/profile-common.js b/apps/character/profile-common.js index eea3a247..1ca1f2f5 100644 --- a/apps/character/profile-common.js +++ b/apps/character/profile-common.js @@ -5,6 +5,7 @@ import lodash from 'lodash' import { segment } from 'oicq' import Profile from '../../components/Profile.js' import { Character } from '../../components/models.js' +import { isV3 } from '../../components/Changelog.js' /* * 获取面板查询的 目标uid @@ -34,19 +35,21 @@ export async function getTargetUid (e) { return uid } } - let botQQ = global.BotConfig ? global.BotConfig.account.qq : false - if (e.at && e.at !== botQQ) { - uid = await getUid(e.at) + if (!isV3) { + let botQQ = global.BotConfig ? global.BotConfig.account.qq : false + if (e.at && e.at !== botQQ) { + uid = await getUid(e.at) + if (uid) { + return uid + } + } + + uid = await getUid(e.user_id) if (uid) { return uid } } - uid = await getUid(e.user_id) - if (uid) { - return uid - } - try { let MysApi = await e.getMysApi({ auth: 'all', diff --git a/components/Format.js b/components/Format.js index 3052ce25..9bf1f90f 100644 --- a/components/Format.js +++ b/components/Format.js @@ -1,19 +1,19 @@ let Format = { int: function (d) { - return parseInt(d); + return parseInt(d) }, comma: function (num, fix = 0) { - num = parseFloat((num * 1).toFixed(fix)); - let [integer, decimal] = String.prototype.split.call(num, '.'); - integer = integer.replace(/\d(?=(\d{3})+$)/g, '$&,'); // 正则先行断言 - return `${integer}${decimal ? '.' + decimal : ''}`; + num = parseFloat((num * 1).toFixed(fix)) + let [integer, decimal] = String.prototype.split.call(num, '.') + integer = integer.replace(/\d(?=(\d{3})+$)/g, '$&,') // 正则先行断言 + return `${integer}${decimal ? '.' + decimal : ''}` }, pct: function (num, fix = 1) { - return (num * 1).toFixed(fix) + "%"; + return (num * 1).toFixed(fix) + '%' }, percent: function (num, fix = 1) { - return Format.pct(num * 100, fix); + return Format.pct(num * 100, fix) } } -export default Format; \ No newline at end of file +export default Format diff --git a/components/Profile.js b/components/Profile.js index 152b6a77..6a8a346f 100644 --- a/components/Profile.js +++ b/components/Profile.js @@ -1,215 +1,207 @@ -import fs from "fs"; -import lodash from "lodash"; -import Format from "./Format.js"; -import Character from "./models/Character.js"; -import Reliquaries from "./models/Reliquaries.js"; -import Miao from "./profile-data/miao.js"; -import Enka from "./profile-data/enka.js"; +import fs from 'fs' +import lodash from 'lodash' +import Format from './Format.js' +import Character from './models/Character.js' +import Reliquaries from './models/Reliquaries.js' +import Miao from './profile-data/miao.js' +import Enka from './profile-data/enka.js' +import Data from './Data.js' -const _path = process.cwd(); -const cfgPath = `${_path}/plugins/miao-plugin/config.js`; -let config = {}; +const _path = process.cwd() -if (fs.existsSync(cfgPath)) { - let fileData = await import (`file://${cfgPath}`); - if (fileData && fileData.config) { - config = fileData.config; - } -} +let sysCfg = await Data.importModule('plugins/miao-plugin/config/system', 'profile.js') +let diyCfg = await Data.importModule('plugins/miao-plugin/config/', 'profile.js') -const userPath = `${_path}/data/UserData/`; +const userPath = `${_path}/data/UserData/` if (!fs.existsSync(userPath)) { - fs.mkdirSync(userPath); + fs.mkdirSync(userPath) } -function sleep(ms) { - return new Promise((resolve) => setTimeout(resolve, ms)); +function sleep (ms) { + return new Promise((resolve) => setTimeout(resolve, ms)) } -function getServ(uid) { - if (config.profileApi) { - return config.profileApi({ Enka, Miao }) - } - if ((uid + '')[0] === '5') { - return Miao; - } - return Enka; +function getServ (uid) { + return (diyCfg.profileApi || sysCfg.profileApi)({ uid, Miao, Enka }) } let Profile = { - async request(uid, e) { + async request (uid, e) { if (uid.toString().length !== 9) { - return false; + return false } - let Serv = getServ(uid); + let Serv = getServ(uid) - let inCd = await redis.get(`miao:role-all:${uid}`); + let inCd = await redis.get(`miao:role-all:${uid}`) if (inCd === 'loading') { - e.reply("请求过快,请稍后重试.."); - return false; + e.reply('请求过快,请稍后重试..') + return false } else if (inCd === 'pending' && false) { - e.reply(`距上次请求刷新成功间隔小于${Serv.cd}分钟,请稍后重试..`); - return false; + e.reply(`距上次请求刷新成功间隔小于${Serv.cd}分钟,请稍后重试..`) + return false } - await redis.set(`miao:role-all:${uid}`, 'loading', { EX: 20 }); - e.reply("开始获取数据,可能会需要一定时间~"); - await sleep(1000); - let data; + await redis.set(`miao:role-all:${uid}`, 'loading', { EX: 20 }) + e.reply('开始获取数据,可能会需要一定时间~') + await sleep(1000) + let data try { - data = await Serv.request({ uid, e, config }); + data = await Serv.request({ uid, e, sysCfg, diyCfg }) // enka服务测冷却时间5分钟 - await redis.set(`miao:role-all:${uid}`, 'pending', { EX: Serv.cd * 60 }); - return Profile.save(uid, data, Serv.key); + await redis.set(`miao:role-all:${uid}`, 'pending', { EX: Serv.cd * 60 }) + return Profile.save(uid, data, Serv.key) } catch (err) { - console.log(err); - e.reply(`请求失败`); - return false; + console.log(err) + e.reply('请求失败') + return false } }, - save(uid, data, dataSource = 'enka') { - let userData = {}; - const userFile = `${userPath}/${uid}.json`; + save (uid, data, dataSource = 'enka') { + let userData = {} + const userFile = `${userPath}/${uid}.json` if (fs.existsSync(userFile)) { - userData = JSON.parse(fs.readFileSync(userFile, "utf8")) || {}; + userData = JSON.parse(fs.readFileSync(userFile, 'utf8')) || {} } - lodash.assignIn(userData, lodash.pick(data, "uid,name,lv,avatar".split(","))); - userData.chars = userData.chars || {}; + lodash.assignIn(userData, lodash.pick(data, 'uid,name,lv,avatar'.split(','))) + userData.chars = userData.chars || {} lodash.forEach(data.chars, (char, charId) => { - let original = userData.chars[charId] || {}; - if (char.dataSource === "miao-pre" && original && original.dataSource) { - original.dataSource = char.dataSource; + let original = userData.chars[charId] || {} + if (char.dataSource === 'miao-pre' && original && original.dataSource) { + original.dataSource = char.dataSource } else { - userData.chars[charId] = char; + userData.chars[charId] = char } - }); - fs.writeFileSync(userFile, JSON.stringify(userData), "", " "); - return data; + }) + fs.writeFileSync(userFile, JSON.stringify(userData), '', ' ') + return data }, - saveCharData(uid, ds) { + saveCharData (uid, ds) { if (!uid || !ds.id) { - return; + return } - let userData = {}; - const userFile = `${userPath}/${uid}.json`; + let userData = {} + const userFile = `${userPath}/${uid}.json` if (fs.existsSync(userFile)) { - userData = JSON.parse(fs.readFileSync(userFile, "utf8")) || {}; + userData = JSON.parse(fs.readFileSync(userFile, 'utf8')) || {} } - userData.chars = userData.chars || {}; - userData.chars[ds.id] = ds; - fs.writeFileSync(userFile, JSON.stringify(userData), "", " "); - return ds; + userData.chars = userData.chars || {} + userData.chars[ds.id] = ds + fs.writeFileSync(userFile, JSON.stringify(userData), '', ' ') + return ds }, - _get(uid, charId) { - const userFile = `${userPath}/${uid}.json`; - let userData = {}; + _get (uid, charId) { + const userFile = `${userPath}/${uid}.json` + let userData = {} if (fs.existsSync(userFile)) { - userData = JSON.parse(fs.readFileSync(userFile, "utf8")) || {}; + userData = JSON.parse(fs.readFileSync(userFile, 'utf8')) || {} } if (userData && userData.chars && userData.chars[charId]) { - return userData.chars[charId]; + return userData.chars[charId] } - return false; + return false }, - async get(uid, charId, onlyAvailable = false) { + async get (uid, charId, onlyAvailable = false) { if (onlyAvailable) { - let data = await Profile.get(uid, charId); - if (data && data.dataSource && data.dataSource !== "input") { - return data; + let data = await Profile.get(uid, charId) + if (data && data.dataSource && data.dataSource !== 'input') { + return data } - return false; + return false } - let data = Profile._get(uid, charId); - let Serv = getServ(uid); + let data = Profile._get(uid, charId) + let Serv = getServ(uid) if (Serv.getCharData && data && data.id) { - return await Serv.getCharData(uid, data, Profile.saveCharData, { config }); + return await Serv.getCharData(uid, data, Profile.saveCharData, { sysCfg, diyCfg }) } - return data; + return data }, - getAll(uid) { - const userFile = `${userPath}/${uid}.json`; - let userData = {}; + getAll (uid) { + const userFile = `${userPath}/${uid}.json` + let userData = {} if (fs.existsSync(userFile)) { - userData = JSON.parse(fs.readFileSync(userFile, "utf8")) || {}; + userData = JSON.parse(fs.readFileSync(userFile, 'utf8')) || {} } if (userData && userData.chars) { - return userData.chars; + return userData.chars } - return false; + return false }, - formatArti(ds, markCfg = false, isMain = false) { + formatArti (ds, markCfg = false, isMain = false) { if (lodash.isArray(ds[0])) { - let ret = []; + let ret = [] lodash.forEach(ds, (d) => { - ret.push(Profile.formatArti(d, markCfg, isMain)); + ret.push(Profile.formatArti(d, markCfg, isMain)) }) - return ret; + return ret } - let title = ds[0], key = "", val = ds[1], num = ds[1]; - if (!title || title === "undefined") { - return []; + let title = ds[0] + let key = '' + let val = ds[1] + let num = ds[1] + if (!title || title === 'undefined') { + return [] } if (/伤害加成/.test(title) && val < 1) { - val = Format.pct(val * 100); - num = num * 100; + val = Format.pct(val * 100) + num = num * 100 } else if (/伤害加成|大|暴|充能|治疗/.test(title)) { - val = Format.pct(val); + val = Format.pct(val) } else { - val = Format.comma(val, 1); + val = Format.comma(val, 1) } if (/元素伤害加成/.test(title)) { - title = title.replace("元素伤害", "伤"); - key = "dmg"; - } else if (title === "物理伤害加成") { - title = "物伤加成"; - key = "phy"; + title = title.replace('元素伤害', '伤') + key = 'dmg' + } else if (title === '物理伤害加成') { + title = '物伤加成' + key = 'phy' } - key = key || keyMap[title]; + key = key || keyMap[title] - let mark = 0; + let mark = 0 if (markCfg) { - mark = Format.comma(markCfg[title] * num || 0); + mark = Format.comma(markCfg[title] * num || 0) if (isMain) { - mark = mark / 4; + mark = mark / 4 } } - return { title, val, mark }; + return { title, val, mark } }, - getArtiMark(data, ds) { + getArtiMark (data, ds) { Reliquaries.getMark(data) - let total = 0; + let total = 0 lodash.forEach(data, (ret) => { if (ret[0] && ret[1]) { - total += mark[ret[0]] * ret[1]; + total += mark[ret[0]] * ret[1] } }) if (ds && /暴/.test(ds[0])) { - total += 20; + total += 20 } - return total; + return total }, - inputProfile(uid, e) { - let { avatar, inputData } = e; - let char = Character.get(avatar); - let originalData = Profile._get(uid, char.id); + inputProfile (uid, e) { + let { avatar, inputData } = e + let char = Character.get(avatar) + let originalData = Profile._get(uid, char.id) if (!originalData || !['enka', 'input2'].includes(originalData.dataSource)) { - return `请先获取${char.name}的面板数据后,再进行面板数据更新`; + return `请先获取${char.name}的面板数据后,再进行面板数据更新` } - inputData = inputData.replace("#", ""); - inputData = inputData.replace(/,|;|、|\n|\t/g, ","); - let attr = originalData.attr || {}; + inputData = inputData.replace('#', '') + inputData = inputData.replace(/,|;|、|\n|\t/g, ',') + let attr = originalData.attr || {} let attrMap = { hp: /生命/, def: /防御/, @@ -222,71 +214,71 @@ let Profile = { dmgBonus: /[火|水|雷|草|风|岩|冰|素|^]伤/, phyBonus: /(物理|物伤)/ } - lodash.forEach(inputData.split(","), (ds, idx) => { - ds = ds.trim(); + lodash.forEach(inputData.split(','), (ds, idx) => { + ds = ds.trim() if (!ds) { - return; + return } - let dRet = /(.*?)([0-9\.\+\s]+)/.exec(ds); + let dRet = /(.*?)([0-9\.\+\s]+)/.exec(ds) if (!dRet || !dRet[1] || !dRet[2]) { - return; + return } - let name = dRet[1].trim(), - data = dRet[2].trim(); - name = name.replace("爆", "暴"); - let range = (src, min = 0, max = 1200) => Math.max(min, Math.min(max, src * 1 || 0)); + let name = dRet[1].trim() + let data = dRet[2].trim() + name = name.replace('爆', '暴') + 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("+"); + 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; + 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; + return false } - originalData.dataSource = "input2"; - originalData.attr = attr; + originalData.dataSource = 'input2' + originalData.attr = attr - let userData = {}; - const userFile = `${userPath}/${uid}.json`; + let userData = {} + const userFile = `${userPath}/${uid}.json` if (fs.existsSync(userFile)) { - userData = JSON.parse(fs.readFileSync(userFile, "utf8")) || {}; + userData = JSON.parse(fs.readFileSync(userFile, 'utf8')) || {} } - userData.chars = userData.chars || {}; - userData.chars[avatar] = originalData; - fs.writeFileSync(userFile, JSON.stringify(userData), "", " "); - return true; + userData.chars = userData.chars || {} + userData.chars[avatar] = originalData + fs.writeFileSync(userFile, JSON.stringify(userData), '', ' ') + return true } -}; -export default Profile; +} +export default Profile diff --git a/components/profile-data/enka-data.js b/components/profile-data/enka-data.js index 94c1eb28..d135cbd2 100644 --- a/components/profile-data/enka-data.js +++ b/components/profile-data/enka-data.js @@ -1,81 +1,79 @@ -import lodash from "lodash"; -import Character from "../models/Character.js"; -import meta from "./enka-meta.js"; -import cmeta from "./enka-char.js"; -import _Data from "../Data.js"; -import moment from "moment"; +import lodash from 'lodash' +import Character from '../models/Character.js' +import meta from './enka-meta.js' +import cmeta from './enka-char.js' +import _Data from '../Data.js' +import moment from 'moment' -moment.locale("zh-cn"); -let _path = process.cwd(); -let relis = _Data.readJSON(`${_path}/plugins/miao-plugin/resources/meta/reliquaries/`, "data.json") || {}; +moment.locale('zh-cn') +let _path = process.cwd() +let relis = _Data.readJSON(`${_path}/plugins/miao-plugin/resources/meta/reliquaries/`, 'data.json') || {} let relisMap = {} lodash.forEach(relis, (ds) => { - relisMap[ds.name] = ds; + relisMap[ds.name] = ds }) - const artiIdx = { EQUIP_BRACER: 1, EQUIP_NECKLACE: 2, EQUIP_SHOES: 3, EQUIP_RING: 4, EQUIP_DRESS: 5 -}; +} const attrMap = { - HP: "小生命", - HP_PERCENT: "大生命", - ATTACK: "小攻击", - ATTACK_PERCENT: "大攻击", - DEFENSE: "小防御", - DEFENSE_PERCENT: "大防御", - FIRE_ADD_HURT: "火元素伤害加成", - ICE_ADD_HURT: "冰元素伤害加成", - ROCK_ADD_HURT: "岩元素伤害加成", - ELEC_ADD_HURT: "雷元素伤害加成", - WIND_ADD_HURT: "风元素伤害加成", - WATER_ADD_HURT: "水元素伤害加成", - PHYSICAL_ADD_HURT: "物理伤害加成", - HEAL_ADD: "治疗加成", - ELEMENT_MASTERY: "元素精通", - CRITICAL: "暴击率", - CRITICAL_HURT: "暴击伤害", - CHARGE_EFFICIENCY: "充能效率", -}; + HP: '小生命', + HP_PERCENT: '大生命', + ATTACK: '小攻击', + ATTACK_PERCENT: '大攻击', + DEFENSE: '小防御', + DEFENSE_PERCENT: '大防御', + FIRE_ADD_HURT: '火元素伤害加成', + ICE_ADD_HURT: '冰元素伤害加成', + ROCK_ADD_HURT: '岩元素伤害加成', + ELEC_ADD_HURT: '雷元素伤害加成', + WIND_ADD_HURT: '风元素伤害加成', + WATER_ADD_HURT: '水元素伤害加成', + PHYSICAL_ADD_HURT: '物理伤害加成', + HEAL_ADD: '治疗加成', + ELEMENT_MASTERY: '元素精通', + CRITICAL: '暴击率', + CRITICAL_HURT: '暴击伤害', + CHARGE_EFFICIENCY: '充能效率' +} let Data = { - getData(uid, data) { + getData (uid, data) { let ret = { uid, chars: {} } lodash.forEach({ - name: "nickname", - avatar: "profilePicture.avatarId", - lv: "level" + name: 'nickname', + avatar: 'profilePicture.avatarId', + lv: 'level' }, (src, key) => { - ret[key] = lodash.get(data.playerInfo, src, ""); + ret[key] = lodash.get(data.playerInfo, src, '') }) lodash.forEach(data.avatarInfoList, (ds) => { - let char = Data.getAvatar(ds); - ret.chars[char.id] = char; + let char = Data.getAvatar(ds) + ret.chars[char.id] = char }) - return ret; - + return ret }, - getAvatar(data) { - let char = Character.get(data.avatarId); - let now = moment(); + getAvatar (data) { + let char = Character.get(data.avatarId) + let now = moment() let ret = { - id: data["avatarId"], - name: char ? char.name : "", - dataSource: "enka", - updateTime: now.format("YYYY-MM-DD HH:mm:ss"), + id: data.avatarId, + name: char ? char.name : '', + dataSource: 'enka', + updateTime: now.format('YYYY-MM-DD HH:mm:ss'), lv: data.propMap['4001'].val * 1, fetter: data.fetterInfo.expLevel, attr: Data.getAttr(data.fightPropMap), @@ -83,11 +81,11 @@ let Data = { artis: Data.getArtifact(data.equipList), cons: data.talentIdList ? data.talentIdList.length : 0, talent: Data.getTalent(char.id, data.skillLevelMap, data.proudSkillExtraLevelMap || {}) - }; - return Data.dataFix(ret); + } + return Data.dataFix(ret) }, - getAttr(data) { - let ret = {}; + getAttr (data) { + let ret = {} let attrKey = { // atk: 2001, atkBase: 4, @@ -112,56 +110,55 @@ let Data = { src: 23, pct: true } - }; + } lodash.forEach(attrKey, (cfg, key) => { if (!lodash.isObject(cfg)) { - cfg = { src: cfg }; + cfg = { src: cfg } } - let val = data[cfg.src] || 0; + let val = data[cfg.src] || 0 if (cfg.pct) { val = val * 100 } - ret[key] = val; - }); - ret.atk = data['4'] * (1 + (data['6'] || 0)) + (data['5'] || 0); - let maxDmg = 0; + ret[key] = val + }) + ret.atk = data['4'] * (1 + (data['6'] || 0)) + (data['5'] || 0) + let maxDmg = 0 // 火40 水42 风44 岩45 冰46 雷46 // 41 雷 - lodash.forEach("40,41,42,43,44,45,45,46".split(","), (key) => { - maxDmg = Math.max(data[key] * 1, maxDmg); - }); + lodash.forEach('40,41,42,43,44,45,45,46'.split(','), (key) => { + maxDmg = Math.max(data[key] * 1, maxDmg) + }) // phy 30 - ret.dmgBonus = maxDmg * 100; - ret.phyBonus = data['30'] * 100; + ret.dmgBonus = maxDmg * 100 + ret.phyBonus = data['30'] * 100 - return ret; + return ret }, - getArtifact(data) { - let ret = {}; + getArtifact (data) { + let ret = {} let get = function (d) { if (!d) { - return []; + return [] } - let id = d.appendPropId || d.mainPropId || ""; - id = id.replace("FIGHT_PROP_", ""); + let id = d.appendPropId || d.mainPropId || '' + id = id.replace('FIGHT_PROP_', '') if (!attrMap[id]) { - return []; + return [] } - return [attrMap[id], d.statValue]; - + return [attrMap[id], d.statValue] } lodash.forEach(data, (ds) => { - let flat = ds.flat || {}, sub = flat.reliquarySubstats || []; - let idx = artiIdx[flat.equipType]; + let flat = ds.flat || {}; let sub = flat.reliquarySubstats || [] + let idx = artiIdx[flat.equipType] if (!idx) { - return; + return } - let setName = meta[flat.setNameTextMapHash] || ""; - let setCfg = relisMap[setName] || { name: "", sets: {} }, - artiCfg = setCfg.sets[`arti${idx}`] || { name: "" }; + let setName = meta[flat.setNameTextMapHash] || '' + let setCfg = relisMap[setName] || { name: '', sets: {} } + let artiCfg = setCfg.sets[`arti${idx}`] || { name: '' } ret[`arti${idx}`] = { name: artiCfg.name, @@ -176,17 +173,17 @@ let Data = { ] } }) - return ret; + return ret }, - getWeapon(data) { + getWeapon (data) { let ds = {} lodash.forEach(data, (temp) => { - if (temp.flat && temp.flat.itemType === "ITEM_WEAPON") { - ds = temp; - return false; + if (temp.flat && temp.flat.itemType === 'ITEM_WEAPON') { + ds = temp + return false } }) - let { weapon, flat } = ds; + let { weapon, flat } = ds return { name: meta[flat.nameTextMapHash], star: flat.rankLevel, @@ -195,62 +192,61 @@ let Data = { affix: (lodash.values(weapon.affixMap)[0] || 0) + 1 } }, - getTalent(charid, ds = {}, ext = {}) { - let cm = cmeta[charid] || {}; - let cn = cm.Skills || {}, ce = cm.ProudMap; - let idx = 1; - let idxMap = { 1: 'a', 2: 'e', 3: 'q', 'a': 'a', 's': 'e', 'e': 'q' }; + getTalent (charid, ds = {}, ext = {}) { + let cm = cmeta[charid] || {} + let cn = cm.Skills || {}; let ce = cm.ProudMap + let idx = 1 + let idxMap = { 1: 'a', 2: 'e', 3: 'q', a: 'a', s: 'e', e: 'q' } lodash.forEach(cn, (n, id) => { - let nRet = /skill_(\w)/.exec(n.toLowerCase()); - idxMap[id] = nRet && nRet[1] ? idxMap[nRet[1]] : idxMap[idx]; - idx++; - }); - lodash.forEach(ce, (n, id) => { - idxMap[n] = idxMap[id]; + let nRet = /skill_(\w)/.exec(n.toLowerCase()) + idxMap[id] = nRet && nRet[1] ? idxMap[nRet[1]] : idxMap[idx] + idx++ }) - let ret = {}; + lodash.forEach(ce, (n, id) => { + idxMap[n] = idxMap[id] + }) + let ret = {} lodash.forEach(ds, (lv, id) => { - let key = idxMap[id]; + let key = idxMap[id] ret[key] = { level_original: lv, level_current: lv } }) lodash.forEach(ext, (lv, id) => { - let key = idxMap[id]; + let key = idxMap[id] if (ret[key]) { - ret[key].level_current = ret[key].level_current + lv; + ret[key].level_current = ret[key].level_current + lv } }) - return ret; + return ret }, - dataFix(ret) { + dataFix (ret) { if (ret._fix) { - return ret; + return ret } - let { attr, id } = ret; - id = id * 1; + let { attr, id } = ret + id = id * 1 switch (id) { case 10000052: // 雷神被动加成fix attr.dmgBonus = Math.max(0, attr.dmgBonus - (attr.recharge - 100) * 0.4) - break; + break case 10000041: // 莫娜被动fix attr.dmgBonus = Math.max(0, attr.dmgBonus - attr.recharge * 0.2) - break; + break /* case 10000060: // 夜兰被动fix attr.hp = attr.hp - attr.hpBase * 0.3 break; */ - } - ret._fix = true; - return ret; + ret._fix = true + return ret } -}; +} -export default Data; \ No newline at end of file +export default Data diff --git a/components/profile-data/enka.js b/components/profile-data/enka.js index ab3e31a6..de8cb570 100644 --- a/components/profile-data/enka.js +++ b/components/profile-data/enka.js @@ -1,28 +1,27 @@ -import fetch from "node-fetch"; -import Data from "./enka-data.js"; +import fetch from 'node-fetch' +import EnkaData from './enka-data.js' +import Data from '../Data.js' let Enka = { - key: "enka", + key: 'enka', cd: 5, - async request({ e, uid, avatar, config }) { - let profileApi = config.enkaApi || function ({ uid }) { - return `https://enka.shinshin.moe/u/${uid}/__data.json` - }; - let api = profileApi({ uid, avatar }); - - let req = await fetch(api); - let data = await req.json(); + async request ({ e, uid, avatar, diyCfg, sysCfg }) { + let url = diyCfg?.enkaApi?.url || sysCfg.enkaApi.url + let profileApi = diyCfg?.enkaApi?.listApi || sysCfg.enkaApi.listApi + let api = profileApi({ url, uid, avatar }) + let req = await fetch(api) + let data = await req.json() if (!data.playerInfo) { - e.reply(`请求失败:${data.msg || "可能是面板服务并发过高,请稍后重试"}`); - return false; + e.reply(`请求失败:${data.msg || '可能是面板服务并发过高,请稍后重试'}`) + return false } - let details = data.avatarInfoList; + let details = data.avatarInfoList if (!details || details.length === 0 || !details[0].propMap) { - e.reply(`请打开游戏内角色展柜的“显示详情”后,等待5分钟重新获取面板`); - return false; + e.reply('请打开游戏内角色展柜的“显示详情”后,等待5分钟重新获取面板') + return false } - return Data.getData(uid, data); + return EnkaData.getData(uid, data) } } -export default Enka; \ No newline at end of file +export default Enka diff --git a/components/profile-data/miao.js b/components/profile-data/miao.js index b2801e46..5ab58eb1 100644 --- a/components/profile-data/miao.js +++ b/components/profile-data/miao.js @@ -1,104 +1,98 @@ -import fetch from "node-fetch"; -import lodash from "lodash"; -import Character from "../models/Character.js"; -import moment from "moment"; -import { artiIdx, artiSetMap, attrMap } from "./miao-meta.js"; -import cmeta from "./enka-char.js"; - -const url = "http://49.232.91.210/profile/detail?token=kokomi"; +import fetch from 'node-fetch' +import lodash from 'lodash' +import Character from '../models/Character.js' +import moment from 'moment' +import { artiIdx, artiSetMap, attrMap } from './miao-meta.js' +import cmeta from './enka-char.js' let Miao = { - key: "miao", + key: 'miao', cd: 1, - async request({ e, uid, avatar = '', config }) { - let profileApi = config.miaoApi && lodash.isFunction(config.miaoApi) ? config.miaoApi : function ({ uid }) { - return `http://49.232.91.210/profile/list?uid=${uid}` - }; - let api = profileApi({ uid, avatar }); - let data; - let req = await fetch(api); - data = await req.json(); + async request ({ e, uid, avatar = '', diyCfg, sysCfg }) { + let url = diyCfg?.miaoApi?.url || sysCfg.miaoApi.url + let token = diyCfg?.miaoApi?.token || sysCfg.miaoApi.token + let profileApi = diyCfg?.miaoApi?.listApi || sysCfg.miaoApi.listApi + let api = profileApi({ url, uid, avatar, token }) + let data + let req = await fetch(api) + data = await req.json() if (data.status !== 0) { - e.reply(data.msg || "请求失败"); - return false; + e.reply(data.msg || '请求失败') + return false } if (!data.uidListData || data.uidListData.length === 0) { - e.reply(`请打开游戏内角色展柜的“显示详情”后,等待5分钟重新获取面板`); - return false; + e.reply('请打开游戏内角色展柜的“显示详情”后,等待5分钟重新获取面板') + return false } - return Miao.getData(uid, data); - + return Miao.getData(uid, data) }, - getData(uid, data) { + getData (uid, data) { let ret = { uid, chars: {} } lodash.forEach({ - name: "nickname", - //avatar: "profilePicture.avatarId", - lv: "level" + name: 'nickname', + // avatar: "profilePicture.avatarId", + lv: 'level' }, (src, key) => { - ret[key] = lodash.get(data, src, ""); + ret[key] = lodash.get(data, src, '') }) lodash.forEach(data.uidListData, (ds) => { - let char = Miao.getAvatar(ds); - ret.chars[char.id] = char; + let char = Miao.getAvatar(ds) + ret.chars[char.id] = char }) - return ret; + return ret }, - getAvatar(ds) { - let char = Character.get(ds.usernameid); - let now = moment(); + getAvatar (ds) { + let char = Character.get(ds.usernameid) + let now = moment() return { id: ds.usernameid, - name: char ? char.name : "", - dataSource: "miao-pre", - updateTime: now.format("YYYY-MM-DD HH:mm:ss"), + name: char ? char.name : '', + dataSource: 'miao-pre', + updateTime: now.format('YYYY-MM-DD HH:mm:ss'), lv: ds.level - }; + } }, - async getCharData(uid, ds, saveCharData, { config = {} }) { - if (ds.dataSource !== "miao-pre" || !ds.id) { - return ds; + async getCharData (uid, ds, saveCharData, { diyCfg = {}, sysCfg = {} }) { + if (ds.dataSource !== 'miao-pre' || !ds.id) { + return ds } try { - let profileApi = function ({ uid, avatar }) { - return `http://49.232.91.210/profile/detail?uid=${uid}&avatar=${avatar}` - }; - if (config.miaoApi && lodash.isFunction(config.miaoApi)) { - profileApi = config.miaoApi; - } - let api = profileApi({ uid, avatar: ds.id }); - let req = await fetch(api); - let data = await req.json(); + let url = diyCfg?.miaoApi?.url || sysCfg.miaoApi.url + let token = diyCfg?.miaoApi?.token || sysCfg.miaoApi.token + let profileApi = diyCfg?.miaoApi?.detailApi || sysCfg.miaoApi.detailApi + let api = profileApi({ url, token, uid, avatar: ds.id }) + let req = await fetch(api) + let data = await req.json() if (data.status === 0 && data.uidData) { - data = Miao.getAvatarDetail(data); + data = Miao.getAvatarDetail(data) if (data) { - saveCharData(uid, data); - return data; + saveCharData(uid, data) + return data } } - return ds; + return ds } catch (err) { - console.log(err); - return ds; + console.log(err) + return ds } }, - getAvatarDetail(data) { - let ds = data.uidData; - let char = Character.get(ds.id); - let now = moment(); + getAvatarDetail (data) { + let ds = data.uidData + let char = Character.get(ds.id) + let now = moment() return { id: ds.id, - name: char ? char.name : "", - dataSource: "miao", - updateTime: now.format("YYYY-MM-DD HH:mm:ss"), + name: char ? char.name : '', + dataSource: 'miao', + updateTime: now.format('YYYY-MM-DD HH:mm:ss'), lv: ds.level, fetter: ds.fetterLevel, attr: Miao.getAttr(data.uidDataCombatValue), @@ -107,53 +101,54 @@ let Miao = { cons: ds.constellationNum, talent: Miao.getTalent(char.id, ds.skill), _priority: 10 - }; + } }, - getAttr(data) { - let ret = {}; + getAttr (data) { + let ret = {} lodash.forEach({ - atk: "attack", - atkBase: "baseATK", - hp: "health", - hpBase: "baseHP", - def: "defense", - defBase: "baseDEF", - mastery: "elementMastery", + atk: 'attack', + atkBase: 'baseATK', + hp: 'health', + hpBase: 'baseHP', + def: 'defense', + defBase: 'baseDEF', + mastery: 'elementMastery', cRate: { - src: "critRate", + src: 'critRate', pct: true }, cDmg: { - src: "critDamage", + src: 'critDamage', pct: true }, hInc: { - src: "heal", + src: 'heal', pct: true }, recharge: { - src: "recharge", + src: 'recharge', pct: true } }, (cfg, key) => { if (!lodash.isObject(cfg)) { - cfg = { src: cfg }; + cfg = { src: cfg } } - let val = data[cfg.src] || 0; + let val = data[cfg.src] || 0 if (cfg.pct) { val = val * 100 } - ret[key] = val; + ret[key] = val }) - let maxDmg = 0, hurt = data.addHurt || {}; - lodash.forEach("fire,elec,water,grass,wind,rock,ice".split(","), (key) => { - maxDmg = Math.max(hurt[key] * 100, maxDmg); - }); - ret.dmgBonus = maxDmg; - ret.phyBonus = hurt.physical * 100; - return ret; + let maxDmg = 0; + let hurt = data.addHurt || {} + lodash.forEach('fire,elec,water,grass,wind,rock,ice'.split(','), (key) => { + maxDmg = Math.max(hurt[key] * 100, maxDmg) + }) + ret.dmgBonus = maxDmg + ret.phyBonus = hurt.physical * 100 + return ret }, - getWeapon(weapon) { + getWeapon (weapon) { return { name: weapon.name, star: weapon.rank, @@ -162,33 +157,33 @@ let Miao = { affix: (weapon.affixLevel || 0) + 1 } }, - getArtifact(data) { - let ret = {}; + getArtifact (data) { + let ret = {} let get = function (d) { if (!d) { - return []; + return [] } - let name = d.name; - name = name.replace("FIGHT_PROP_", ""); + let name = d.name + name = name.replace('FIGHT_PROP_', '') if (!attrMap[name]) { - return []; + return [] } - let value = d.value; + let value = d.value if (value && value < 1) { - value = value * 100; + value = value * 100 } - return [attrMap[name], value]; + return [attrMap[name], value] } lodash.forEach(data, (ds) => { - let sub = ds.appendAffix || []; - let idx = artiIdx[ds.type]; + let sub = ds.appendAffix || [] + let idx = artiIdx[ds.type] if (!idx) { - return; + return } ret[`arti${idx}`] = { name: ds.name, - set: artiSetMap[ds.name] || "", + set: artiSetMap[ds.name] || '', level: ds.level, main: get(ds.mainAffix), attrs: [ @@ -199,29 +194,29 @@ let Miao = { ] } }) - return ret; + return ret }, - getTalent(charid, data = {}) { - let cm = cmeta[charid] || {}; - let cn = cm.Skills || {}; - let idx = 1; - let idxMap = { 0: 'a', 1: 'e', 2: 'q', 'a': 'a', 's': 'e', 'e': 'q' }; + getTalent (charid, data = {}) { + let cm = cmeta[charid] || {} + let cn = cm.Skills || {} + let idx = 1 + let idxMap = { 0: 'a', 1: 'e', 2: 'q', a: 'a', s: 'e', e: 'q' } lodash.forEach(cn, (n, id) => { - let nRet = /skill_(\w)/.exec(n.toLowerCase()); - idxMap[id] = nRet && nRet[1] ? idxMap[nRet[1]] : idxMap[idx]; - idx++; - }); + let nRet = /skill_(\w)/.exec(n.toLowerCase()) + idxMap[id] = nRet && nRet[1] ? idxMap[nRet[1]] : idxMap[idx] + idx++ + }) - let ret = {}; + let ret = {} lodash.forEach(data, (ds) => { - let key = idxMap[ds.id]; + let key = idxMap[ds.id] ret[key] = { level_original: ds.level, level_current: ds.level } }) - return ret; - }, + return ret + } } -export default Miao; \ No newline at end of file +export default Miao diff --git a/config/character_default.js b/config/character_default.js index 6ddb0dbf..808422a9 100644 --- a/config/character_default.js +++ b/config/character_default.js @@ -1,8 +1,6 @@ /* -* 请不要直接修改此或删除此文件,防止后续更新冲突 * 如需新增自定义角色可【复制】此文件,改名为character.js * 复制的character.js中可按格式及自己需求进行配置 -* 最终character.js character_default.js两份配置会叠加生效 * * 暂未做热更新,修改完毕请重启yunzai * */ @@ -22,7 +20,7 @@ export const customCharacters = { } /* -* 追加设置每个关系的可选角色,会与yunzai的设置同时起作用 +* 追加设置每个关系的可选角色,会与原有设置同时起作用 * 一个角色可以在多个关系中 * */ export const wifeData = { diff --git a/config/profile_default.js b/config/profile_default.js new file mode 100644 index 00000000..17526c43 --- /dev/null +++ b/config/profile_default.js @@ -0,0 +1,26 @@ +/* +* 如需配置【复制】此文件,改名为profile.js +* +* 暂未做热更新,修改完毕请重启yunzai +* */ + +/* +* Enka面板服务API配置 +* * +* 若enka服务无法正常访问,可尝试修改下配置文件中的地址 +* 默认地址:https://enka.shinshin.moe/ +* 国内服务:https://enka.microgg.cn/ +* */ + +export const enkaApi = { + url: 'https://enka.shinshin.moe/' +} + +/* +* MiaoApi面板更新地址,暂时只支持B服角色 +* */ + +export const miaoApi = { + url: 'http://49.232.91.210/profile', + token: 'miao-token' +} diff --git a/config/system/character.js b/config/system/character.js index 4b384a85..98abdf01 100644 --- a/config/system/character.js +++ b/config/system/character.js @@ -76,8 +76,8 @@ export const characters = { // 以下为Miao新增自定义角色 paimon: ['派蒙', '应急食物', '应急食品', '吉祥物', '宠物', '外置器官', '会说话的动物', '矮堇瓜', '飞行矮堇瓜', '最好的伙伴'], - sb: ['散兵', '国崩', '雷电国崩', '大炮', '雷电大炮', '雷大炮', '伞兵'], - nvshi: ['女士', '炽热的炎之魔女', '炎之魔女'], + sb: ['散兵', '国崩', '雷电国崩', '大炮', '雷电大炮', '雷大炮', '伞兵', '斯卡拉姆齐'], + nvshi: ['女士', '炽热的炎之魔女', '炎之魔女', '罗莎琳'], baizhu: ['白术', '长生'], yaoyao: ['瑶瑶', '遥遥', '遥遥无期'], fanan: ['伐难', '水夜叉'], @@ -89,7 +89,7 @@ export const characters = { boshi: ['多托雷', '博士'], muou: ['桑多涅', '木偶', '人偶'], choujue: ['皮耶罗', '丑角', '老爷子'], - gongji: ['普契涅拉', '公鸡'], + gongji: ['普契涅拉', '公鸡', '鸽子'], duizhang: ['卡皮塔诺', '队长'], nilu: ['妮露'], nahida: ['纳西妲', '草神'] diff --git a/config/system/profile.js b/config/system/profile.js new file mode 100644 index 00000000..87c81c24 --- /dev/null +++ b/config/system/profile.js @@ -0,0 +1,29 @@ +/* +* 此配置文件为系统使用,请勿修改,否则可能无法正常使用 +* 如需自定义配置请复制修改上一级profile_detail.js +* */ + +export const profileApi = ({ uid, Miao, Enka }) => { + if ((uid + '')[0] === '5') { + return Miao + } + return Enka +} + +export const miaoApi = { + url: 'http://49.232.91.210/profile', + token: 'miao-token', + listApi: ({ url, uid, token }) => { + return `${url}/list?uid=${uid}&token=${token}` + }, + detailApi: ({ url, uid, avatar, token }) => { + return `${url}/detail?uid=${uid}&avatar=${avatar}&token=${token}` + } +} + +export const enkaApi = { + url: 'https://enka.shinshin.moe/', + listApi: ({ url, uid }) => { + return `${url}u/${uid}/__data.json` + } +}