mirror of
https://github.com/yoimiya-kokomi/miao-plugin.git
synced 2024-11-22 06:58:24 +00:00
components及models重构
This commit is contained in:
parent
a75ed26a8a
commit
af816f17e8
@ -1,5 +1,5 @@
|
|||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import Data from '../components/Data.js'
|
import {Data} from '../components/index.js'
|
||||||
import puppeteer from '../../../lib/puppeteer/puppeteer.js'
|
import puppeteer from '../../../lib/puppeteer/puppeteer.js'
|
||||||
|
|
||||||
const plugin = 'miao-plugin'
|
const plugin = 'miao-plugin'
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import { exec } from 'child_process'
|
import { exec } from 'child_process'
|
||||||
import { Cfg } from '../components/index.js'
|
import { Cfg, Common } from '../components/index.js'
|
||||||
import Common from '../components/Common.js'
|
|
||||||
|
|
||||||
let cfgMap = {
|
let cfgMap = {
|
||||||
角色: 'char.char',
|
角色: 'char.char',
|
||||||
面板: 'char.profile-data',
|
面板: 'char.profile',
|
||||||
老婆: 'char.wife',
|
老婆: 'char.wife',
|
||||||
戳一戳: 'char.poke',
|
戳一戳: 'char.poke',
|
||||||
小清新: 'char.se',
|
小清新: 'char.se',
|
||||||
@ -84,7 +83,7 @@ export async function sysCfg (e, { render }) {
|
|||||||
|
|
||||||
let cfg = {
|
let cfg = {
|
||||||
chars: getStatus('char.char'),
|
chars: getStatus('char.char'),
|
||||||
profile: getStatus('char.profile-data'),
|
profile: getStatus('char.profile'),
|
||||||
wife: getStatus('char.wife'),
|
wife: getStatus('char.wife'),
|
||||||
poke: getStatus('char.poke'),
|
poke: getStatus('char.poke'),
|
||||||
se: getStatus('char.se', false),
|
se: getStatus('char.se', false),
|
||||||
@ -243,7 +242,7 @@ export async function profileCfg (e, { render }) {
|
|||||||
cfg[key] = getStatus(`profile.${key}.status`, true)
|
cfg[key] = getStatus(`profile.${key}.status`, true)
|
||||||
})
|
})
|
||||||
|
|
||||||
let groups = Cfg.get('profile-data.groups', {})
|
let groups = Cfg.get('profile.groups', {})
|
||||||
lodash.forEach(lodash.keys(groups), (group, idx) => {
|
lodash.forEach(lodash.keys(groups), (group, idx) => {
|
||||||
if (lodash.isUndefined(groups[group])) {
|
if (lodash.isUndefined(groups[group])) {
|
||||||
return
|
return
|
||||||
|
@ -3,7 +3,7 @@ import { renderAvatar } from './character/avatar-card.js'
|
|||||||
import { getTargetUid, getProfile, profileHelp, getProfileAll, inputProfile } from './character/profile-common.js'
|
import { getTargetUid, getProfile, profileHelp, getProfileAll, inputProfile } from './character/profile-common.js'
|
||||||
import { profileArtis } from './character/profile-artis.js'
|
import { profileArtis } from './character/profile-artis.js'
|
||||||
import { renderProfile } from './character/profile-detail.js'
|
import { renderProfile } from './character/profile-detail.js'
|
||||||
import { Character } from '../components/models.js'
|
import { Character } from '../models/index.js'
|
||||||
//
|
//
|
||||||
export { getProfileAll, getProfile, profileHelp }
|
export { getProfileAll, getProfile, profileHelp }
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Artifact, Character } from '../../components/models.js'
|
import { Artifact, Character } from '../../models/index.js'
|
||||||
import { Cfg, Data, Common, Profile } from '../../components/index.js'
|
import { Cfg, Data, Common, Profile } from '../../components/index.js'
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import { segment } from 'oicq'
|
import { segment } from 'oicq'
|
||||||
@ -29,7 +29,7 @@ export async function renderAvatar (e, avatar, render, renderType = 'card') {
|
|||||||
if (char.isCustom) {
|
if (char.isCustom) {
|
||||||
avatar = { id: char.id, name: char.name, detail: false }
|
avatar = { id: char.id, name: char.name, detail: false }
|
||||||
} else {
|
} else {
|
||||||
let profile = await Profile.get(uid, char.id, true)
|
let profile = Profile.get(uid, char.id, true)
|
||||||
if (profile) {
|
if (profile) {
|
||||||
// 优先使用Profile数据
|
// 优先使用Profile数据
|
||||||
avatar = profile
|
avatar = profile
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// #老婆
|
// #老婆
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import { Cfg } from '../../components/index.js'
|
import { Cfg } from '../../components/index.js'
|
||||||
import { Character } from '../../components/models.js'
|
import { Character } from '../../models/index.js'
|
||||||
import { getAvatarList, renderAvatar } from './avatar-card.js'
|
import { getAvatarList, renderAvatar } from './avatar-card.js'
|
||||||
|
|
||||||
const relationMap = {
|
const relationMap = {
|
||||||
|
@ -5,8 +5,8 @@ import { segment } from 'oicq'
|
|||||||
import MD5 from 'md5'
|
import MD5 from 'md5'
|
||||||
import fetch from 'node-fetch'
|
import fetch from 'node-fetch'
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import Data from '../../components/Data.js'
|
import { Data } from '../../components/index.js'
|
||||||
import { Character } from '../../components/models.js'
|
import { Character } from '../../models/index.js'
|
||||||
|
|
||||||
const resPath = process.cwd() + '/plugins/miao-plugin/resources/'
|
const resPath = process.cwd() + '/plugins/miao-plugin/resources/'
|
||||||
let regex = /^#?\s*(?:喵喵)?(?:上传|添加)(.+)(?:照片|写真|图片|图像)\s*$/
|
let regex = /^#?\s*(?:喵喵)?(?:上传|添加)(.+)(?:照片|写真|图片|图像)\s*$/
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
*
|
*
|
||||||
* */
|
* */
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import { Profile, Common, Format } from '../../components/index.js'
|
import { Profile, Common } from '../../components/index.js'
|
||||||
import { getTargetUid, profileHelp, autoGetProfile } from './profile-common.js'
|
import { getTargetUid, profileHelp, autoGetProfile } from './profile-common.js'
|
||||||
import { Artifact } from '../../components/models.js'
|
import { Artifact } from '../../models/index.js'
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 角色圣遗物面板
|
* 角色圣遗物面板
|
||||||
@ -21,14 +21,14 @@ export async function profileArtis (e, { render }) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let charCfg = Artifact.getCharCfg(profile.name)
|
if (!profile.hasArtis()) {
|
||||||
let { artis, totalMark, totalMarkClass, usefulMark } = getArtis(profile.name, profile.artis)
|
|
||||||
|
|
||||||
if (!profile.artis || profile.artis.length === 0) {
|
|
||||||
e.reply('未能获得圣遗物详情,请重新获取面板信息后查看')
|
e.reply('未能获得圣遗物详情,请重新获取面板信息后查看')
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let charCfg = profile.getCharCfg()
|
||||||
|
let { artis, mark: totalMark, markClass: totalMarkClass, usefulMark } = profile.getArtisMark()
|
||||||
|
|
||||||
let { attrMap } = Artifact.getMeta()
|
let { attrMap } = Artifact.getMeta()
|
||||||
|
|
||||||
// 渲染图像
|
// 渲染图像
|
||||||
@ -62,37 +62,17 @@ export async function profileArtisList (e, { render }) {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
lodash.forEach(profiles || [], (ds) => {
|
lodash.forEach(profiles || [], (profile) => {
|
||||||
let name = ds.name
|
let name = profile.name
|
||||||
if (!name || name === '空' || name === '荧') {
|
if (!profile.hasData || !profile.hasArtis()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
let profileArtis = profile.getArtisMark()
|
||||||
let usefulMark
|
lodash.forEach(profileArtis.artis, (arti, idx) => {
|
||||||
|
arti.usefulMark = profileArtis.usefulMark
|
||||||
let charCfg = Artifact.getCharCfg(name)
|
arti.avatar = name
|
||||||
usefulMark = charCfg.titleWeight
|
artis.push(arti)
|
||||||
|
})
|
||||||
/* 处理圣遗物 */
|
|
||||||
if (ds.artis) {
|
|
||||||
let newScore = Artifact.getArtisMark(name, ds.artis)
|
|
||||||
|
|
||||||
lodash.forEach(ds.artis, (arti, idx) => {
|
|
||||||
if (!arti.name) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
idx = idx.replace('arti', '')
|
|
||||||
let mark = newScore[idx]
|
|
||||||
arti.mark = Format.comma(mark, 1)
|
|
||||||
arti._mark = mark
|
|
||||||
arti.markClass = Artifact.getMarkClass(mark)
|
|
||||||
arti.main = Artifact.formatArti(arti.main)
|
|
||||||
arti.attrs = Artifact.formatArti(arti.attrs)
|
|
||||||
arti.usefulMark = usefulMark
|
|
||||||
arti.avatar = name
|
|
||||||
artis.push(arti)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if (artis.length === 0) {
|
if (artis.length === 0) {
|
||||||
@ -111,32 +91,3 @@ export async function profileArtisList (e, { render }) {
|
|||||||
artis
|
artis
|
||||||
}, { e, render, scale: 1.4 })
|
}, { e, render, scale: 1.4 })
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* 获取圣遗物评分及详情
|
|
||||||
* */
|
|
||||||
export function getArtis (char, artisData) {
|
|
||||||
let charCfg = Artifact.getCharCfg(char)
|
|
||||||
let newScore = Artifact.getArtisMark(char, artisData)
|
|
||||||
let totalMark = 0
|
|
||||||
let artis = []
|
|
||||||
|
|
||||||
lodash.forEach(artisData, (arti, idx) => {
|
|
||||||
idx = idx.replace('arti', '')
|
|
||||||
let ds = arti
|
|
||||||
let mark = newScore[idx]
|
|
||||||
totalMark += mark
|
|
||||||
ds.mark = Format.comma(mark, 1)
|
|
||||||
ds.markClass = Artifact.getMarkClass(mark)
|
|
||||||
ds.main = Artifact.formatArti(arti.main, charCfg.mark, true)
|
|
||||||
ds.attrs = Artifact.formatArti(arti.attrs, charCfg.mark, false)
|
|
||||||
artis[idx * 1 - 1] = ds
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
artis,
|
|
||||||
totalMark,
|
|
||||||
totalMarkClass: Artifact.getMarkClass(totalMark / 5),
|
|
||||||
usefulMark: charCfg.titleWeight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -3,10 +3,9 @@
|
|||||||
* */
|
* */
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import { segment } from 'oicq'
|
import { segment } from 'oicq'
|
||||||
import { profileList } from './profile-list.js';
|
import { profileList } from './profile-list.js'
|
||||||
import Profile from '../../components/Profile.js'
|
import { Profile, Version } from '../../components/index.js'
|
||||||
import { Character } from '../../components/models.js'
|
import { Character } from '../../models/index.js'
|
||||||
import { isV3 } from '../../components/Changelog.js'
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 获取面板查询的 目标uid
|
* 获取面板查询的 目标uid
|
||||||
@ -36,7 +35,7 @@ export async function getTargetUid (e) {
|
|||||||
return uid
|
return uid
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!isV3) {
|
if (!Version.isV3) {
|
||||||
let botQQ = global.BotConfig ? global.BotConfig.account.qq : false
|
let botQQ = global.BotConfig ? global.BotConfig.account.qq : false
|
||||||
if (e.at && e.at !== botQQ) {
|
if (e.at && e.at !== botQQ) {
|
||||||
uid = await getUid(e.at)
|
uid = await getUid(e.at)
|
||||||
@ -133,7 +132,7 @@ export async function autoGetProfile (e, uid, avatar, callback) {
|
|||||||
return { err: true }
|
return { err: true }
|
||||||
}
|
}
|
||||||
|
|
||||||
let profile = await Profile.get(uid, char.id)
|
let profile = Profile.get(uid, char.id)
|
||||||
if (!profile) {
|
if (!profile) {
|
||||||
if (await refresh()) {
|
if (await refresh()) {
|
||||||
return { err: true }
|
return { err: true }
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import { autoRefresh } from './profile-common.js'
|
import { autoRefresh } from './profile-common.js'
|
||||||
import { Calc, Common, Format, Profile } from '../../components/index.js'
|
import { Common, Format, Profile } from '../../components/index.js'
|
||||||
import { getArtis } from './profile-artis.js'
|
|
||||||
|
|
||||||
export async function renderProfile (e, char, render, mode = 'profile', params = {}) {
|
export async function renderProfile (e, char, render, mode = 'profile', params = {}) {
|
||||||
let selfUser = await e.checkAuth({
|
let selfUser = await e.checkAuth({
|
||||||
@ -27,7 +26,7 @@ export async function renderProfile (e, char, render, mode = 'profile', params =
|
|||||||
return refreshRet
|
return refreshRet
|
||||||
}
|
}
|
||||||
|
|
||||||
let profile = await Profile.get(uid, char.id)
|
let profile = Profile.get(uid, char.id)
|
||||||
|
|
||||||
if (!profile) {
|
if (!profile) {
|
||||||
if (await refresh()) {
|
if (await refresh()) {
|
||||||
@ -58,21 +57,19 @@ export async function renderProfile (e, char, render, mode = 'profile', params =
|
|||||||
atkPlus: c(a.atk - a.atkBase),
|
atkPlus: c(a.atk - a.atkBase),
|
||||||
def: c(a.def),
|
def: c(a.def),
|
||||||
defPlus: c(a.def - a.defBase),
|
defPlus: c(a.def - a.defBase),
|
||||||
cRate: p(a.cRate),
|
cpct: p(a.cpct),
|
||||||
cDmg: p(a.cDmg),
|
cdmg: p(a.cdmg),
|
||||||
mastery: c(a.mastery),
|
mastery: c(a.mastery),
|
||||||
recharge: p(a.recharge),
|
recharge: p(a.recharge),
|
||||||
dmgBonus: p(Math.max(a.dmgBonus * 1 || 0, a.phyBonus * 1 || 0))
|
dmg: p(Math.max(a.dmg * 1 || 0, a.phy * 1 || 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
let { artis, totalMark, totalMarkClass, usefulMark } = getArtis(char.name, profile.artis)
|
let { artis, mark: totalMark, markClass: totalMarkClass, usefulMark } = profile.getArtisMark()
|
||||||
|
|
||||||
let enemyLv = await selfUser.getCfg('char.enemyLv', 91)
|
let enemyLv = await selfUser.getCfg('char.enemyLv', 91)
|
||||||
let dmgMsg = []
|
let dmgMsg = []
|
||||||
let dmgData = []
|
let dmgData = []
|
||||||
let dmgCalc = await Calc.calcData({
|
let dmgCalc = await profile.calcDmg({
|
||||||
profile,
|
|
||||||
char,
|
|
||||||
enemyLv,
|
enemyLv,
|
||||||
mode,
|
mode,
|
||||||
...params
|
...params
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import { autoRefresh, getTargetUid } from './profile-common.js'
|
import { autoRefresh, getTargetUid } from './profile-common.js'
|
||||||
import { Common, Profile } from '../../components/index.js'
|
import { Common, Profile } from '../../components/index.js'
|
||||||
import { Character } from '../../components/models.js'
|
|
||||||
|
|
||||||
export async function profileList (e, { render }) {
|
export async function profileList (e, { render }) {
|
||||||
let uid = await getTargetUid(e)
|
let uid = await getTargetUid(e)
|
||||||
@ -21,18 +20,14 @@ export async function profileList (e, { render }) {
|
|||||||
msg = '获取角色面板数据成功'
|
msg = '获取角色面板数据成功'
|
||||||
newChar = e.newChar
|
newChar = e.newChar
|
||||||
}
|
}
|
||||||
lodash.forEach(profiles || [], (ds) => {
|
lodash.forEach(profiles || {}, (profile) => {
|
||||||
if (!['enka', 'input2', 'miao'].includes(ds.dataSource)) {
|
if (!profile.hasData) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let { id } = ds
|
let char = profile.char
|
||||||
let char = Character.get(id)
|
|
||||||
let tmp = char.getData('id,name,abbr,element,star')
|
let tmp = char.getData('id,name,abbr,element,star')
|
||||||
if (tmp.name === '荧' || tmp.name === '空') {
|
tmp.source = profile.dataSource
|
||||||
return
|
tmp.level = profile.level || 1
|
||||||
}
|
|
||||||
tmp.source = ds.dataSource
|
|
||||||
tmp.level = ds.lv || 1
|
|
||||||
tmp.isNew = 0
|
tmp.isNew = 0
|
||||||
if (newChar[char.name]) {
|
if (newChar[char.name]) {
|
||||||
tmp.isNew = 1
|
tmp.isNew = 1
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import { Common, Profile } from '../../components/index.js'
|
import { Common, Profile, Data } from '../../components/index.js'
|
||||||
import { Artifact, Avatars } from '../../components/models.js'
|
import { Avatars } from '../../models/index.js'
|
||||||
|
|
||||||
export async function profileStat (e, { render }) {
|
export async function profileStat (e, { render }) {
|
||||||
// 缓存时间,单位小时
|
// 缓存时间,单位小时
|
||||||
@ -40,11 +40,12 @@ export async function profileStat (e, { render }) {
|
|||||||
|
|
||||||
let avatarRet = []
|
let avatarRet = []
|
||||||
lodash.forEach(talentData, (avatar) => {
|
lodash.forEach(talentData, (avatar) => {
|
||||||
let { talent, id, name } = avatar
|
let { talent, id } = avatar
|
||||||
avatar.aeq = talent?.a?.original + talent?.e?.original + talent?.q?.original || 3
|
avatar.aeq = talent?.a?.original + talent?.e?.original + talent?.q?.original || 3
|
||||||
avatarRet.push(avatar)
|
avatarRet.push(avatar)
|
||||||
if (profiles[id]?.artis) {
|
if (profiles[id]) {
|
||||||
avatar.artisMark = Artifact.getTotalMark(name, profiles[id].artis)
|
let mark = profiles[id].getArtisMark(false)
|
||||||
|
avatar.artisMark = Data.getData(mark, 'mark,markClass,names')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
14
apps/help.js
14
apps/help.js
@ -1,8 +1,6 @@
|
|||||||
import { Cfg } from '../components/index.js'
|
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import { currentVersion, changelogs } from '../components/Changelog.js'
|
|
||||||
import Common from '../components/Common.js'
|
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
|
import { Cfg, Version, Common } from '../components/index.js'
|
||||||
|
|
||||||
const _path = process.cwd()
|
const _path = process.cwd()
|
||||||
const helpPath = `${_path}/plugins/miao-plugin/resources/help`
|
const helpPath = `${_path}/plugins/miao-plugin/resources/help`
|
||||||
@ -12,7 +10,8 @@ export async function help (e, { render }) {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
let custom = {}; let help = {}
|
let custom = {};
|
||||||
|
let help = {}
|
||||||
if (fs.existsSync(`${helpPath}/help-cfg.js`)) {
|
if (fs.existsSync(`${helpPath}/help-cfg.js`)) {
|
||||||
help = await import(`file://${helpPath}/help-cfg.js?version=${new Date().getTime()}`)
|
help = await import(`file://${helpPath}/help-cfg.js?version=${new Date().getTime()}`)
|
||||||
} else if (fs.existsSync(`${helpPath}/help-list.js`)) {
|
} else if (fs.existsSync(`${helpPath}/help-list.js`)) {
|
||||||
@ -46,7 +45,8 @@ export async function help (e, { render }) {
|
|||||||
if (!icon) {
|
if (!icon) {
|
||||||
help.css = 'display:none'
|
help.css = 'display:none'
|
||||||
} else {
|
} else {
|
||||||
let x = (icon - 1) % 10; let y = (icon - x - 1) / 10
|
let x = (icon - 1) % 10;
|
||||||
|
let y = (icon - x - 1) / 10
|
||||||
help.css = `background-position:-${x * 50}px -${y * 50}px`
|
help.css = `background-position:-${x * 50}px -${y * 50}px`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -63,8 +63,8 @@ export async function help (e, { render }) {
|
|||||||
|
|
||||||
export async function versionInfo (e, { render }) {
|
export async function versionInfo (e, { render }) {
|
||||||
return await Common.render('help/version-info', {
|
return await Common.render('help/version-info', {
|
||||||
currentVersion,
|
currentVersion: Version.version,
|
||||||
changelogs,
|
changelogs: Version.changelogs,
|
||||||
elem: 'cryo'
|
elem: 'cryo'
|
||||||
}, { e, render, scale: 1.2 })
|
}, { e, render, scale: 1.2 })
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,11 @@
|
|||||||
* 胡桃数据库的统计
|
* 胡桃数据库的统计
|
||||||
*
|
*
|
||||||
* */
|
* */
|
||||||
import { HutaoApi, Character } from '../components/models.js'
|
|
||||||
import { Cfg } from '../components/index.js'
|
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import Common from '../components/Common.js'
|
import { Cfg, Common } from '../components/index.js'
|
||||||
import Abyss from '../components/models/Abyss.js'
|
import { Abyss, Avatars, Character } from '../models/index.js'
|
||||||
import Avatars from '../components/models/Avatars.js'
|
import HutaoApi from './stat/HutaoApi.js'
|
||||||
|
|
||||||
export async function consStat (e, { render }) {
|
export async function consStat (e, { render }) {
|
||||||
if (Cfg.isDisable(e, 'wiki.stat')) {
|
if (Cfg.isDisable(e, 'wiki.stat')) {
|
||||||
|
10
apps/wiki.js
10
apps/wiki.js
@ -1,9 +1,8 @@
|
|||||||
import { segment } from 'oicq'
|
import { segment } from 'oicq'
|
||||||
import { Character } from '../components/models.js'
|
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import Calendar from '../components/Calendar.js'
|
import Calendar from './wiki/calendar.js'
|
||||||
import Common from '../components/Common.js'
|
import { Cfg, Common } from '../components/index.js'
|
||||||
import { Cfg } from '../components/index.js'
|
import { Character } from '../models/index.js'
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
let action = {
|
let action = {
|
||||||
@ -17,7 +16,8 @@ export async function wiki (e, { render }) {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
let reg = /#?(.+)(命座|命之座|天赋|技能|资料|照片|写真|图片|图像)$/; let msg = e.msg
|
let reg = /#?(.+)(命座|命之座|天赋|技能|资料|照片|写真|图片|图像)$/;
|
||||||
|
let msg = e.msg
|
||||||
let ret = reg.exec(msg)
|
let ret = reg.exec(msg)
|
||||||
|
|
||||||
if (!ret || !ret[1] || !ret[2]) {
|
if (!ret || !ret[1] || !ret[2]) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import fetch from 'node-fetch'
|
import fetch from 'node-fetch'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import { Character } from './models.js'
|
import { Character } from '../../models/index.js'
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
|
|
||||||
const ignoreIds = [495, // 有奖问卷调查开启!
|
const ignoreIds = [495, // 有奖问卷调查开启!
|
@ -1,6 +1,6 @@
|
|||||||
import { Cfg } from './index.js'
|
import Cfg from './Cfg.js'
|
||||||
|
import { Version } from './index.js'
|
||||||
import { segment } from 'oicq'
|
import { segment } from 'oicq'
|
||||||
import { currentVersion, yunzaiVersion, isV3 } from './Changelog.js'
|
|
||||||
|
|
||||||
export const render = async function (path, params, cfg) {
|
export const render = async function (path, params, cfg) {
|
||||||
let paths = path.split('/')
|
let paths = path.split('/')
|
||||||
@ -14,19 +14,19 @@ export const render = async function (path, params, cfg) {
|
|||||||
elemLayout: layoutPath + 'elem.html',
|
elemLayout: layoutPath + 'elem.html',
|
||||||
sys: {
|
sys: {
|
||||||
scale: Cfg.scale(cfg.scale || 1),
|
scale: Cfg.scale(cfg.scale || 1),
|
||||||
copyright: `Created By Yunzai-Bot<span class="version">${yunzaiVersion}</span> & Miao-Plugin<span class="version">${currentVersion}</span>`
|
copyright: `Created By Yunzai-Bot<span class="version">${Version.yunzai}</span> & Miao-Plugin<span class="version">${Version.version}</span>`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
let ret = true
|
let ret = true
|
||||||
if (base64) {
|
if (base64) {
|
||||||
ret = isV3 ? await e.reply(base64) : await e.reply(segment.image(`base64://${base64}`))
|
ret = Version.isV3 ? await e.reply(base64) : await e.reply(segment.image(`base64://${base64}`))
|
||||||
}
|
}
|
||||||
return cfg.retMsgId ? ret : true
|
return cfg.retMsgId ? ret : true
|
||||||
}
|
}
|
||||||
|
|
||||||
export const todoV3 = function (e) {
|
export const todoV3 = function (e) {
|
||||||
if (isV3) {
|
if (Version.isV3) {
|
||||||
e.reply('本功能暂时不支持V3版Yunzai...')
|
e.reply('本功能暂时不支持V3版Yunzai...')
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,24 @@ let Data = {
|
|||||||
return {}
|
return {}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async import (name) {
|
||||||
|
return await Data.importModule('plugins/miao-plugin/components/optional-lib/', `${name}.js`)
|
||||||
|
},
|
||||||
|
|
||||||
|
async importCfg (key) {
|
||||||
|
let sysCfg = await Data.importModule('plugins/miao-plugin/config/system', `${key}.js`)
|
||||||
|
let diyCfg = await Data.importModule('plugins/miao-plugin/config/', `${key}.js`)
|
||||||
|
if (diyCfg.isSys) {
|
||||||
|
console.error(`miao-plugin: config/${key}.js无效,已忽略`)
|
||||||
|
console.error(`如需配置请复制config/${key}_default.js为config/${key}.js,请勿复制config/system下的系统文件`)
|
||||||
|
diyCfg = {}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
sysCfg,
|
||||||
|
diyCfg
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 返回一个从 target 中选中的属性的对象
|
* 返回一个从 target 中选中的属性的对象
|
||||||
*
|
*
|
||||||
@ -173,6 +191,7 @@ let Data = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
eachStr: (arr, fn) => {
|
eachStr: (arr, fn) => {
|
||||||
if (lodash.isString(arr)) {
|
if (lodash.isString(arr)) {
|
||||||
arr = arr.replace(/\s*(;|;|、|,)\s*/, ',')
|
arr = arr.replace(/\s*(;|;|、|,)\s*/, ',')
|
||||||
|
@ -1,62 +1,30 @@
|
|||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import Format from './Format.js'
|
|
||||||
import Character from './models/Character.js'
|
|
||||||
import Miao from './profile-data/miao.js'
|
import Miao from './profile-data/miao.js'
|
||||||
import Enka from './profile-data/enka.js'
|
import Enka from './profile-data/enka.js'
|
||||||
import Data from './Data.js'
|
import { Character, ProfileReq, ProfileData } from '../models/index.js'
|
||||||
|
|
||||||
const _path = process.cwd()
|
const _path = process.cwd()
|
||||||
|
|
||||||
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)) {
|
if (!fs.existsSync(userPath)) {
|
||||||
fs.mkdirSync(userPath)
|
fs.mkdirSync(userPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
function sleep (ms) {
|
ProfileReq.regServ({ Miao, Enka })
|
||||||
return new Promise((resolve) => setTimeout(resolve, ms))
|
|
||||||
}
|
|
||||||
|
|
||||||
function getServ (uid) {
|
|
||||||
return (diyCfg.profileApi || sysCfg.profileApi)({ uid, Miao, Enka, diyCfg })
|
|
||||||
}
|
|
||||||
|
|
||||||
const requestInterval = diyCfg.requestInterval || sysCfg.requestInterval || 5
|
|
||||||
|
|
||||||
let Profile = {
|
let Profile = {
|
||||||
async request (uid, e) {
|
async request (uid, e) {
|
||||||
if (uid.toString().length !== 9) {
|
if (uid.toString().length !== 9) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
let Serv = getServ(uid)
|
let req = new ProfileReq({ e, uid })
|
||||||
|
|
||||||
let cdTime = await Profile.inCd(uid)
|
|
||||||
if (cdTime) {
|
|
||||||
e.reply(`请求过快,请${cdTime}秒后重试..`)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
await Profile.setCd(uid, 20) // 发起请求设置20s cd
|
|
||||||
e.reply('开始获取数据,可能会需要一定时间~')
|
|
||||||
await sleep(500)
|
|
||||||
let data
|
let data
|
||||||
try {
|
try {
|
||||||
data = await Serv.request({ uid, e, sysCfg, diyCfg, setCd: Profile.setCd })
|
data = await req.request()
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// enka服务测冷却时间5分钟
|
return Profile.save(uid, data)
|
||||||
let cdTime = requestInterval * 60
|
|
||||||
if (data.ttl) {
|
|
||||||
cdTime = Math.max(cdTime, data.ttl * 1)
|
|
||||||
delete data.ttl
|
|
||||||
}
|
|
||||||
await Profile.setCd(uid, cdTime) // 根据设置设置cd
|
|
||||||
return Profile.save(uid, data, Serv.key)
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
e.reply('请求失败')
|
e.reply('请求失败')
|
||||||
@ -64,24 +32,7 @@ let Profile = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async setCd (uid, cdTime = 5 * 60) {
|
save (uid, data) {
|
||||||
let ext = new Date() * 1 + cdTime * 1000
|
|
||||||
await redis.set(`miao:role-all:${uid}`, ext + '', { EX: cdTime })
|
|
||||||
},
|
|
||||||
|
|
||||||
async inCd (uid) {
|
|
||||||
let ext = await redis.get(`miao:role-all:${uid}`)
|
|
||||||
if (!ext || isNaN(ext)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
let cd = new Date() * 1 - ext
|
|
||||||
if (cd < 0) {
|
|
||||||
return Math.ceil(0 - cd / 1000)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
|
|
||||||
save (uid, data, dataSource = 'enka') {
|
|
||||||
let userData = {}
|
let userData = {}
|
||||||
const userFile = `${userPath}/${uid}.json`
|
const userFile = `${userPath}/${uid}.json`
|
||||||
if (fs.existsSync(userFile)) {
|
if (fs.existsSync(userFile)) {
|
||||||
@ -101,21 +52,6 @@ let Profile = {
|
|||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
|
|
||||||
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) {
|
_get (uid, charId) {
|
||||||
const userFile = `${userPath}/${uid}.json`
|
const userFile = `${userPath}/${uid}.json`
|
||||||
let userData = {}
|
let userData = {}
|
||||||
@ -128,21 +64,17 @@ let Profile = {
|
|||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
|
|
||||||
async get (uid, charId, onlyAvailable = false) {
|
get (uid, charId, onlyHasData = false) {
|
||||||
if (onlyAvailable) {
|
let data = Profile._get(uid, charId)
|
||||||
let data = await Profile.get(uid, charId)
|
if (data) {
|
||||||
if (data && data.dataSource && data.dataSource !== 'input') {
|
let profile = new ProfileData(data)
|
||||||
return data
|
if (onlyHasData && !profile.hasData) {
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
return profile
|
||||||
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = Profile._get(uid, charId)
|
|
||||||
let Serv = getServ(uid)
|
|
||||||
if (Serv.getCharData && data && data.id) {
|
|
||||||
return await Serv.getCharData(uid, data, Profile.saveCharData, { sysCfg, diyCfg })
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getAll (uid) {
|
getAll (uid) {
|
||||||
@ -152,48 +84,13 @@ let Profile = {
|
|||||||
userData = JSON.parse(fs.readFileSync(userFile, 'utf8')) || {}
|
userData = JSON.parse(fs.readFileSync(userFile, 'utf8')) || {}
|
||||||
}
|
}
|
||||||
if (userData && userData.chars) {
|
if (userData && userData.chars) {
|
||||||
return userData.chars
|
let ret = {}
|
||||||
}
|
lodash.forEach(userData.chars, (ds, id) => {
|
||||||
return false
|
ret[id] = new ProfileData(ds)
|
||||||
},
|
|
||||||
|
|
||||||
formatArti (ds, markCfg = false, isMain = false) {
|
|
||||||
if (lodash.isArray(ds[0])) {
|
|
||||||
let ret = []
|
|
||||||
lodash.forEach(ds, (d) => {
|
|
||||||
ret.push(Profile.formatArti(d, markCfg, isMain))
|
|
||||||
})
|
})
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
let title = ds[0]
|
return false
|
||||||
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
|
|
||||||
} else if (/伤害加成|大|暴|充能|治疗/.test(title)) {
|
|
||||||
val = Format.pct(val)
|
|
||||||
} else {
|
|
||||||
val = Format.comma(val, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (/元素伤害加成/.test(title)) {
|
|
||||||
title = title.replace('元素伤害', '伤')
|
|
||||||
} else if (title === '物理伤害加成') {
|
|
||||||
title = '物伤加成'
|
|
||||||
}
|
|
||||||
|
|
||||||
let mark = 0
|
|
||||||
if (markCfg) {
|
|
||||||
mark = Format.comma(markCfg[title] * num || 0)
|
|
||||||
if (isMain) {
|
|
||||||
mark = mark / 4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return { title, val, mark }
|
|
||||||
},
|
},
|
||||||
|
|
||||||
inputProfile (uid, e) {
|
inputProfile (uid, e) {
|
||||||
@ -286,8 +183,8 @@ let Profile = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
getServName (uid) {
|
getServName (uid) {
|
||||||
let Serv = getServ(uid)
|
let Serv = ProfileReq.getServ(uid)
|
||||||
return Serv.getName({ uid, diyCfg, sysCfg })
|
return Serv.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default Profile
|
export default Profile
|
||||||
|
@ -73,4 +73,17 @@ try {
|
|||||||
const yunzaiVersion = packageJson.version
|
const yunzaiVersion = packageJson.version
|
||||||
const isV3 = yunzaiVersion[0] === '3'
|
const isV3 = yunzaiVersion[0] === '3'
|
||||||
|
|
||||||
export { currentVersion, yunzaiVersion, isV3, changelogs }
|
let Version = {
|
||||||
|
isV3,
|
||||||
|
get version () {
|
||||||
|
return currentVersion
|
||||||
|
},
|
||||||
|
get yunzai () {
|
||||||
|
return yunzaiVersion
|
||||||
|
},
|
||||||
|
get changelogs () {
|
||||||
|
return changelogs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Version
|
@ -1,10 +1,8 @@
|
|||||||
import Data from './Data.js'
|
import Data from './Data.js'
|
||||||
import Cfg from './Cfg.js'
|
|
||||||
import Profile from './Profile.js'
|
|
||||||
import Common from './Common.js'
|
|
||||||
import Format from './Format.js'
|
import Format from './Format.js'
|
||||||
import Calc from './Calc.js'
|
import Common from './Common.js'
|
||||||
|
import Cfg from './Cfg.js'
|
||||||
|
import Version from './Version.js'
|
||||||
|
import Profile from './Profile.js'
|
||||||
|
|
||||||
import * as Models from './models.js'
|
export { Data, Cfg, Format, Common, Version, Profile }
|
||||||
|
|
||||||
export { Data, Cfg, Profile, Common, Format, Models, Calc }
|
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
import Character from './models/Character.js'
|
|
||||||
import HutaoApi from './models/HutaoApi.js'
|
|
||||||
import Artifact from './models/Artifact.js'
|
|
||||||
import Avatars from './models/Avatars.js'
|
|
||||||
|
|
||||||
export { Character, HutaoApi, Artifact, Avatars }
|
|
@ -1,273 +0,0 @@
|
|||||||
import { attrValue, attrNameMap, attrMap, mainAttr, subAttr, usefulAttr }
|
|
||||||
from '../../resources/meta/reliquaries/reliquaries-mark-new.js'
|
|
||||||
import { Character } from '../models.js'
|
|
||||||
import lodash from 'lodash'
|
|
||||||
import Format from '../Format.js'
|
|
||||||
import _Data from '../Data.js'
|
|
||||||
import Data from '../Data.js';
|
|
||||||
|
|
||||||
let _path = process.cwd()
|
|
||||||
let artis = _Data.readJSON(`${_path}/plugins/miao-plugin/resources/meta/reliquaries/`, 'data.json') || {}
|
|
||||||
|
|
||||||
let artisMap = {}
|
|
||||||
|
|
||||||
lodash.forEach(artis, (ds) => {
|
|
||||||
artisMap[ds.name] = ds
|
|
||||||
})
|
|
||||||
|
|
||||||
let charCfg = {}
|
|
||||||
let Artifact = {
|
|
||||||
getCharCfg (name) {
|
|
||||||
if (charCfg[name]) {
|
|
||||||
return charCfg[name]
|
|
||||||
}
|
|
||||||
let attrWeight = usefulAttr[name] || { atk: 75, cp: 100, cd: 100 }
|
|
||||||
let attrMark = {}
|
|
||||||
|
|
||||||
let char = Character.get(name)
|
|
||||||
let baseAttr = char?.lvStat?.detail['90'] || [400, 500, 300]
|
|
||||||
lodash.forEach(attrWeight, (weight, attr) => {
|
|
||||||
attrMark[attr] = weight / attrValue[attr]
|
|
||||||
})
|
|
||||||
|
|
||||||
// let baseAttr = [400, 500, 300];
|
|
||||||
if (attrMark.hp) {
|
|
||||||
attrMark.hpPlus = attrMark.hp / baseAttr[0] * 100
|
|
||||||
}
|
|
||||||
if (attrMark.atk) {
|
|
||||||
// 以520作为武器白值均值计算
|
|
||||||
attrMark.atkPlus = attrMark.atk / (baseAttr[1] * 1 + 520) * 100
|
|
||||||
}
|
|
||||||
if (attrMark.def) {
|
|
||||||
attrMark.defPlus = attrMark.def / baseAttr[2] * 100
|
|
||||||
}
|
|
||||||
let maxMark = Artifact.getMaxMark(attrWeight)
|
|
||||||
let titleMark = {}
|
|
||||||
let titleWeight = {}
|
|
||||||
lodash.forEach(attrMark, (mark, attr) => {
|
|
||||||
let aTitle = attrMap[attr].title
|
|
||||||
if (/小/.test(aTitle)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
titleMark[aTitle] = mark
|
|
||||||
titleWeight[aTitle] = attrWeight[attr] || 0
|
|
||||||
if (/大/.test(aTitle)) {
|
|
||||||
let sTitle = aTitle.replace('大', '小')
|
|
||||||
titleWeight[sTitle] = titleWeight[aTitle]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
charCfg[name] = {
|
|
||||||
weight: attrWeight,
|
|
||||||
mark: attrMark,
|
|
||||||
titleMap: titleMark,
|
|
||||||
titleWeight,
|
|
||||||
maxMark
|
|
||||||
}
|
|
||||||
return charCfg[name]
|
|
||||||
},
|
|
||||||
|
|
||||||
getMaxAttr (charAttr = {}, list2 = [], maxLen = 1, banAttr = '') {
|
|
||||||
let tmp = []
|
|
||||||
lodash.forEach(list2, (attr) => {
|
|
||||||
if (attr === banAttr) return
|
|
||||||
if (!charAttr[attr]) return
|
|
||||||
tmp.push({ attr, mark: charAttr[attr] })
|
|
||||||
})
|
|
||||||
tmp = lodash.sortBy(tmp, 'mark')
|
|
||||||
tmp = tmp.reverse()
|
|
||||||
let ret = []
|
|
||||||
lodash.forEach(tmp, (ds) => ret.push(ds.attr))
|
|
||||||
return ret.slice(0, maxLen)
|
|
||||||
},
|
|
||||||
|
|
||||||
getMaxMark (attrWeight) {
|
|
||||||
let ret = {}
|
|
||||||
for (let idx = 1; idx <= 5; idx++) {
|
|
||||||
let totalMark = 0;
|
|
||||||
let mMark = 0
|
|
||||||
let mAttr = ''
|
|
||||||
if (idx === 1) {
|
|
||||||
mAttr = 'hpPlus'
|
|
||||||
} else if (idx === 2) {
|
|
||||||
mAttr = 'atkPlus'
|
|
||||||
} else if (idx >= 3) {
|
|
||||||
mAttr = Artifact.getMaxAttr(attrWeight, mainAttr[idx])[0]
|
|
||||||
mMark = attrWeight[mAttr]
|
|
||||||
totalMark += attrWeight[mAttr] * 2
|
|
||||||
}
|
|
||||||
|
|
||||||
let sAttr = Artifact.getMaxAttr(attrWeight, subAttr, 4, mAttr)
|
|
||||||
lodash.forEach(sAttr, (attr, aIdx) => {
|
|
||||||
totalMark += attrWeight[attr] * (aIdx === 0 ? 6 : 1)
|
|
||||||
})
|
|
||||||
ret[idx] = totalMark
|
|
||||||
ret['m' + idx] = mMark
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
},
|
|
||||||
|
|
||||||
getAttr (ds) {
|
|
||||||
let title = ds[0]
|
|
||||||
let attr = attrNameMap[title]
|
|
||||||
if (/元素伤害/.test(title)) {
|
|
||||||
attr = 'dmg'
|
|
||||||
} else if (/物理|物伤/.test(title)) {
|
|
||||||
attr = 'phy'
|
|
||||||
}
|
|
||||||
return attr
|
|
||||||
},
|
|
||||||
|
|
||||||
getAttrMark (attrMark, ds) {
|
|
||||||
if (!ds || !ds[1]) {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
let attr = Artifact.getAttr(ds)
|
|
||||||
let val = ds[1]
|
|
||||||
return (attrMark[attr] || 0) * val
|
|
||||||
},
|
|
||||||
|
|
||||||
getMark (charCfg, posIdx, mainAttr, subAttr) {
|
|
||||||
let ret = 0
|
|
||||||
let { mark, maxMark, weight } = charCfg
|
|
||||||
let mAttr = Artifact.getAttr(mainAttr)
|
|
||||||
|
|
||||||
let fixPct = 1
|
|
||||||
if (posIdx >= 3) {
|
|
||||||
fixPct = Math.max(0, Math.min(1, (weight[mAttr] || 0) / (maxMark['m' + posIdx])))
|
|
||||||
ret += Artifact.getAttrMark(mark, mainAttr) / 4
|
|
||||||
}
|
|
||||||
|
|
||||||
lodash.forEach(subAttr, (ds) => {
|
|
||||||
ret += Artifact.getAttrMark(mark, ds)
|
|
||||||
})
|
|
||||||
|
|
||||||
return ret * (1 + fixPct) / 2 / maxMark[posIdx] * 66
|
|
||||||
},
|
|
||||||
|
|
||||||
getArtisMark (charName = '', artis = {}) {
|
|
||||||
let charCfg = Artifact.getCharCfg(charName)
|
|
||||||
let ret = {}
|
|
||||||
lodash.forEach(artis, (ds, idx) => {
|
|
||||||
idx = idx.replace('arti', '')
|
|
||||||
ret[idx] = Artifact.getMark(charCfg, idx, ds.main, ds.attrs)
|
|
||||||
})
|
|
||||||
return ret
|
|
||||||
},
|
|
||||||
|
|
||||||
getTotalMark (charName = '', artis) {
|
|
||||||
let artisMark = Artifact.getArtisMark(charName, artis)
|
|
||||||
let mark = 0
|
|
||||||
for (let k in artisMark) {
|
|
||||||
if (artisMark[k]) {
|
|
||||||
mark += artisMark[k]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let sets = {}
|
|
||||||
let setMap = {}
|
|
||||||
lodash.forEach(artis, (arti) => {
|
|
||||||
let setName = Artifact.getSetByArti(arti.name)?.name || 'N/A'
|
|
||||||
if (setName) {
|
|
||||||
sets[setName] = (sets[setName] || 0) + 1
|
|
||||||
}
|
|
||||||
})
|
|
||||||
for (let set in sets) {
|
|
||||||
if (sets[set] >= 4) {
|
|
||||||
setMap[set] = 4
|
|
||||||
} else if (sets[set] >= 2) {
|
|
||||||
setMap[set] = 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let setsRet = []
|
|
||||||
lodash.forEach(setMap, (v, k) => {
|
|
||||||
let name = Artifact.getArtiBySet(k)
|
|
||||||
if (name) {
|
|
||||||
setsRet.push(name)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return {
|
|
||||||
mark: (mark || 0).toFixed(1),
|
|
||||||
markClass: Artifact.getMarkClass(mark / 5),
|
|
||||||
sets: setsRet
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getMarkClass (mark) {
|
|
||||||
let pct = mark
|
|
||||||
let scoreMap = [['D', 10], ['C', 16.5], ['B', 23.1], ['A', 29.7], ['S', 36.3], ['SS', 42.9], ['SSS', 49.5], ['ACE', 56.1], ['ACE²', 66]]
|
|
||||||
for (let idx = 0; idx < scoreMap.length; idx++) {
|
|
||||||
if (pct < scoreMap[idx][1]) {
|
|
||||||
return scoreMap[idx][0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getSetByArti (name) {
|
|
||||||
for (let idx in artisMap) {
|
|
||||||
for (let idx2 in artisMap[idx].sets) {
|
|
||||||
if (artisMap[idx].sets[idx2].name === name) {
|
|
||||||
return artisMap[idx]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
|
|
||||||
getArtiBySet (name, idx = 1) {
|
|
||||||
let set = artisMap[name]
|
|
||||||
if (!set) {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
return set.sets[`arti${idx}`].name
|
|
||||||
},
|
|
||||||
|
|
||||||
getMeta () {
|
|
||||||
return {
|
|
||||||
attrMap
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
formatArti (ds, markCfg = false, isMain = false) {
|
|
||||||
if (lodash.isArray(ds[0])) {
|
|
||||||
let ret = []
|
|
||||||
lodash.forEach(ds, (d) => {
|
|
||||||
ret.push(Artifact.formatArti(d, markCfg, isMain))
|
|
||||||
})
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
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
|
|
||||||
} else if (/伤害加成|大|暴|充能|治疗/.test(title)) {
|
|
||||||
val = Format.pct(val)
|
|
||||||
} else {
|
|
||||||
val = Format.comma(val, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (/元素伤害加成/.test(title)) {
|
|
||||||
title = title.replace('元素伤害', '伤')
|
|
||||||
key = 'dmg'
|
|
||||||
} else if (title === '物理伤害加成') {
|
|
||||||
title = '物伤加成'
|
|
||||||
key = 'phy'
|
|
||||||
}
|
|
||||||
|
|
||||||
key = key || attrNameMap[title]
|
|
||||||
|
|
||||||
let mark = markCfg[key] * num
|
|
||||||
if (markCfg) {
|
|
||||||
if (isMain) {
|
|
||||||
mark = mark / 4 + 0.01
|
|
||||||
}
|
|
||||||
mark = Format.comma(mark || 0)
|
|
||||||
}
|
|
||||||
return { title, val, mark }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export default Artifact
|
|
@ -1,7 +0,0 @@
|
|||||||
import Base from './Base.js'
|
|
||||||
|
|
||||||
export default class ProfileData extends Base {
|
|
||||||
constructor (data) {
|
|
||||||
super()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,94 +0,0 @@
|
|||||||
import { attrMark, maxMark, attrMap, usefulAttr } from '../../resources/meta/reliquaries/reliquaries-mark.js'
|
|
||||||
import lodash from 'lodash'
|
|
||||||
|
|
||||||
// let meta = Data.readJSON("../../resources/meta/reliquaries", "data.json");
|
|
||||||
let meta = {}
|
|
||||||
|
|
||||||
let Reliquaries = {
|
|
||||||
getUseful (char) {
|
|
||||||
let attrKey = usefulAttr[char] || ''
|
|
||||||
attrKey = attrKey.split(',')
|
|
||||||
let attrTitles = []; let retMap = {}
|
|
||||||
lodash.forEach(attrKey, (key) => {
|
|
||||||
let attr = attrMap[key]
|
|
||||||
if (attr) {
|
|
||||||
attrTitles.push(attr.title)
|
|
||||||
lodash.forEach(attr.attr.split(','), (k) => {
|
|
||||||
retMap[k] = attrMark[k]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return {
|
|
||||||
titles: attrTitles,
|
|
||||||
mark: retMap
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getMaxMark (char, banTitle = '') {
|
|
||||||
let markMap = Reliquaries.getUseful(char).mark
|
|
||||||
|
|
||||||
let markList = []
|
|
||||||
|
|
||||||
lodash.forEach(markMap, (m, title) => {
|
|
||||||
if (title !== banTitle) {
|
|
||||||
markList.push(maxMark[title])
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
markList = markList.sort((a, b) => b - a)
|
|
||||||
let retMaxMark = markList[0]
|
|
||||||
lodash.forEach(markList, (mark, idx) => {
|
|
||||||
if (idx > 0 && idx < 4) {
|
|
||||||
retMaxMark += mark / 6
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return retMaxMark
|
|
||||||
},
|
|
||||||
|
|
||||||
getMark (char = '', data = []) {
|
|
||||||
let total = 0
|
|
||||||
let markMap = Reliquaries.getUseful(char).mark
|
|
||||||
lodash.forEach(data, (ret) => {
|
|
||||||
ret = ret || []
|
|
||||||
let title = ret[0]; let val = ret[1]
|
|
||||||
if (title && val) {
|
|
||||||
if (markMap[title]) {
|
|
||||||
total += markMap[title] * val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return total
|
|
||||||
},
|
|
||||||
|
|
||||||
getMarkScore (mark, maxMark) {
|
|
||||||
let pct = mark / maxMark
|
|
||||||
let scoreMap = [
|
|
||||||
['D', 0.15],
|
|
||||||
['C', 0.25],
|
|
||||||
['B', 0.35],
|
|
||||||
['A', 0.45],
|
|
||||||
['S', 0.55],
|
|
||||||
['SS', 0.65],
|
|
||||||
['SSS', 0.75],
|
|
||||||
['ACE', 0.85],
|
|
||||||
['ACE²', 1]
|
|
||||||
]
|
|
||||||
|
|
||||||
for (let idx = 0; idx < scoreMap.length; idx++) {
|
|
||||||
if (pct < scoreMap[idx][1]) {
|
|
||||||
return scoreMap[idx][0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getSet (name) {
|
|
||||||
for (let idx in meta) {
|
|
||||||
if (meta[idx].name === name) {
|
|
||||||
return meta[idx]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Reliquaries
|
|
@ -1,19 +1,10 @@
|
|||||||
import lodash from 'lodash'
|
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 moment from 'moment'
|
||||||
|
import enkaMeta from './enka-meta.js'
|
||||||
|
import charMeta from './enka-char.js'
|
||||||
|
import { Character, Artifact, ProfileData } from '../../models/index.js'
|
||||||
|
|
||||||
moment.locale('zh-cn')
|
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
|
|
||||||
})
|
|
||||||
|
|
||||||
const artiIdx = {
|
const artiIdx = {
|
||||||
EQUIP_BRACER: 1,
|
EQUIP_BRACER: 1,
|
||||||
@ -44,7 +35,7 @@ const attrMap = {
|
|||||||
CHARGE_EFFICIENCY: '充能效率'
|
CHARGE_EFFICIENCY: '充能效率'
|
||||||
}
|
}
|
||||||
|
|
||||||
let Data = {
|
let EnkaData = {
|
||||||
getData (uid, data) {
|
getData (uid, data) {
|
||||||
let ret = {
|
let ret = {
|
||||||
uid,
|
uid,
|
||||||
@ -60,8 +51,8 @@ let Data = {
|
|||||||
})
|
})
|
||||||
|
|
||||||
lodash.forEach(data.avatarInfoList, (ds) => {
|
lodash.forEach(data.avatarInfoList, (ds) => {
|
||||||
let char = Data.getAvatar(ds)
|
let char = EnkaData.getAvatar(ds)
|
||||||
ret.chars[char.id] = char
|
ret.chars[char.id] = char // .toData()
|
||||||
})
|
})
|
||||||
|
|
||||||
if (data.ttl) {
|
if (data.ttl) {
|
||||||
@ -72,21 +63,18 @@ let Data = {
|
|||||||
},
|
},
|
||||||
getAvatar (data) {
|
getAvatar (data) {
|
||||||
let char = Character.get(data.avatarId)
|
let char = Character.get(data.avatarId)
|
||||||
let now = moment()
|
let profile = new ProfileData({ id: char.id })
|
||||||
let ret = {
|
profile.setBasic({
|
||||||
id: data.avatarId,
|
level: data.propMap['4001'].val * 1,
|
||||||
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),
|
|
||||||
weapon: Data.getWeapon(data.equipList),
|
|
||||||
artis: Data.getArtifact(data.equipList),
|
|
||||||
cons: data.talentIdList ? data.talentIdList.length : 0,
|
cons: data.talentIdList ? data.talentIdList.length : 0,
|
||||||
talent: Data.getTalent(char.id, data.skillLevelMap, data.proudSkillExtraLevelMap || {})
|
fetter: data.fetterInfo.expLevel,
|
||||||
}
|
dataSource: 'enka'
|
||||||
return Data.dataFix(ret)
|
})
|
||||||
|
profile.setAttr(EnkaData.getAttr(data.fightPropMap))
|
||||||
|
profile.setWeapon(EnkaData.getWeapon(data.equipList))
|
||||||
|
profile.setArtis(EnkaData.getArtifact(data.equipList))
|
||||||
|
profile.setTalent(EnkaData.getTalent(char.id, data.skillLevelMap), 'original')
|
||||||
|
return EnkaData.dataFix(profile)
|
||||||
},
|
},
|
||||||
getAttr (data) {
|
getAttr (data) {
|
||||||
let ret = {}
|
let ret = {}
|
||||||
@ -98,15 +86,15 @@ let Data = {
|
|||||||
hp: 2000,
|
hp: 2000,
|
||||||
hpBase: 1,
|
hpBase: 1,
|
||||||
mastery: 28,
|
mastery: 28,
|
||||||
cRate: {
|
cpct: {
|
||||||
src: 20,
|
src: 20,
|
||||||
pct: true
|
pct: true
|
||||||
},
|
},
|
||||||
cDmg: {
|
cdmg: {
|
||||||
src: 22,
|
src: 22,
|
||||||
pct: true
|
pct: true
|
||||||
},
|
},
|
||||||
hInc: {
|
heal: {
|
||||||
src: 26,
|
src: 26,
|
||||||
pct: true
|
pct: true
|
||||||
},
|
},
|
||||||
@ -133,8 +121,8 @@ let Data = {
|
|||||||
maxDmg = Math.max(data[key] * 1, maxDmg)
|
maxDmg = Math.max(data[key] * 1, maxDmg)
|
||||||
})
|
})
|
||||||
// phy 30
|
// phy 30
|
||||||
ret.dmgBonus = maxDmg * 100
|
ret.dmg = maxDmg * 100
|
||||||
ret.phyBonus = data['30'] * 100
|
ret.phy = data['30'] * 100
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
},
|
},
|
||||||
@ -154,19 +142,18 @@ let Data = {
|
|||||||
return [attrMap[id], d.statValue]
|
return [attrMap[id], d.statValue]
|
||||||
}
|
}
|
||||||
lodash.forEach(data, (ds) => {
|
lodash.forEach(data, (ds) => {
|
||||||
let flat = ds.flat || {}; let sub = flat.reliquarySubstats || []
|
let flat = ds.flat || {}
|
||||||
|
let sub = flat.reliquarySubstats || []
|
||||||
let idx = artiIdx[flat.equipType]
|
let idx = artiIdx[flat.equipType]
|
||||||
if (!idx) {
|
if (!idx) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let setName = meta[flat.setNameTextMapHash] || ''
|
let setName = enkaMeta[flat.setNameTextMapHash] || ''
|
||||||
let setCfg = relisMap[setName] || { name: '', sets: {} }
|
|
||||||
let artiCfg = setCfg.sets[`arti${idx}`] || { name: '' }
|
|
||||||
|
|
||||||
ret[`arti${idx}`] = {
|
ret[`arti${idx}`] = {
|
||||||
name: artiCfg.name,
|
name: Artifact.getArtiBySet(setName, idx),
|
||||||
set: setCfg.name,
|
set: setName,
|
||||||
level: Math.min(20, ((ds.reliquary && ds.reliquary.level) || 1) - 1),
|
level: Math.min(20, ((ds.reliquary && ds.reliquary.level) || 1) - 1),
|
||||||
main: get(flat.reliquaryMainstat),
|
main: get(flat.reliquaryMainstat),
|
||||||
attrs: [
|
attrs: [
|
||||||
@ -189,16 +176,17 @@ let Data = {
|
|||||||
})
|
})
|
||||||
let { weapon, flat } = ds
|
let { weapon, flat } = ds
|
||||||
return {
|
return {
|
||||||
name: meta[flat.nameTextMapHash],
|
name: enkaMeta[flat.nameTextMapHash],
|
||||||
star: flat.rankLevel,
|
star: flat.rankLevel,
|
||||||
level: weapon.level,
|
level: weapon.level,
|
||||||
promote: weapon.promoteLevel,
|
promote: weapon.promoteLevel,
|
||||||
affix: (lodash.values(weapon.affixMap)[0] || 0) + 1
|
affix: (lodash.values(weapon.affixMap)[0] || 0) + 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getTalent (charid, ds = {}, ext = {}) {
|
getTalent (charid, ds = {}) {
|
||||||
let cm = cmeta[charid] || {}
|
let cm = charMeta[charid] || {}
|
||||||
let cn = cm.Skills || {}; let ce = cm.ProudMap
|
let cn = cm.Skills || {}
|
||||||
|
let ce = cm.ProudMap
|
||||||
let idx = 1
|
let idx = 1
|
||||||
let idxMap = { 1: 'a', 2: 'e', 3: 'q', a: 'a', s: 'e', e: 'q' }
|
let idxMap = { 1: 'a', 2: 'e', 3: 'q', a: 'a', s: 'e', e: 'q' }
|
||||||
lodash.forEach(cn, (n, id) => {
|
lodash.forEach(cn, (n, id) => {
|
||||||
@ -213,45 +201,30 @@ let Data = {
|
|||||||
lodash.forEach(ds, (lv, id) => {
|
lodash.forEach(ds, (lv, id) => {
|
||||||
let key = idxMap[id]
|
let key = idxMap[id]
|
||||||
ret[key] = {
|
ret[key] = {
|
||||||
level_original: lv,
|
original: lv
|
||||||
level_current: lv
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
lodash.forEach(ext, (lv, id) => {
|
|
||||||
let key = idxMap[id]
|
|
||||||
if (ret[key]) {
|
|
||||||
ret[key].level_current = ret[key].level_current + lv
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
},
|
},
|
||||||
dataFix (ret) {
|
dataFix (ret) {
|
||||||
if (ret._fix) {
|
if (ret._fix) {
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
let { attr, talent, id } = ret
|
let { attr, id } = ret
|
||||||
id = id * 1
|
id = id * 1
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case 10000052:
|
case 10000052:
|
||||||
// 雷神被动加成fix
|
// 雷神被动加成fix
|
||||||
attr.dmgBonus = Math.max(0, attr.dmgBonus - (attr.recharge - 100) * 0.4)
|
attr.dmg = Math.max(0, attr.dmg - (attr.recharge - 100) * 0.4)
|
||||||
break
|
break
|
||||||
case 10000041:
|
case 10000041:
|
||||||
// 莫娜被动fix
|
// 莫娜被动fix
|
||||||
attr.dmgBonus = Math.max(0, attr.dmgBonus - attr.recharge * 0.2)
|
attr.dmg = Math.max(0, attr.dmg - attr.recharge * 0.2)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if (id !== 10000033) {
|
|
||||||
let a = talent.a || {}
|
|
||||||
if (a.level_current > 10) {
|
|
||||||
a.level_current = 10
|
|
||||||
a.level_original = 10
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ret._fix = true
|
ret._fix = true
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Data
|
export default EnkaData
|
||||||
|
@ -1,41 +1,31 @@
|
|||||||
import fetch from 'node-fetch'
|
|
||||||
import EnkaData from './enka-data.js'
|
import EnkaData from './enka-data.js'
|
||||||
import Data from '../Data.js'
|
import { Data } from '../index.js'
|
||||||
|
import { ProfileServ } from '../../models/index.js'
|
||||||
|
|
||||||
let Enka = {
|
export default new ProfileServ({
|
||||||
key: 'enka',
|
id: 'enka',
|
||||||
cd: 5,
|
cfgKey: 'enkaApi',
|
||||||
async request ({ e, uid, avatar, diyCfg, sysCfg, setCd }) {
|
|
||||||
let url = diyCfg?.enkaApi?.url || sysCfg.enkaApi.url
|
// 处理请求参数
|
||||||
let profileApi = diyCfg?.enkaApi?.listApi || sysCfg.enkaApi.listApi
|
async request (api) {
|
||||||
let api = profileApi({ url, uid, avatar })
|
let params = { headers: { 'User-Agent': this.getCfg('userAgent') } }
|
||||||
if (diyCfg?.enkaApi?.apiKey) {
|
let proxy = this.getCfg('proxyAgent')
|
||||||
api += '?key=' + diyCfg.enkaApi.apiKey
|
if (proxy) {
|
||||||
|
let { HttpsProxyAgent } = await Data.import('https-proxy-agent')
|
||||||
|
params.agent = new HttpsProxyAgent(proxy)
|
||||||
}
|
}
|
||||||
let config = { headers: { 'User-Agent': diyCfg?.enkaApi?.userAgent || sysCfg.enkaApi.userAgent } }
|
return { api, params }
|
||||||
if (diyCfg?.enkaApi?.proxyAgent) {
|
},
|
||||||
let { HttpsProxyAgent } = await Data.importModule('./plugins/miao-plugin/components/profile-data/', 'enka-proxy.js')
|
|
||||||
config.agent = new HttpsProxyAgent(diyCfg.enkaApi.proxyAgent)
|
// 处理服务返回
|
||||||
}
|
async response (data, req) {
|
||||||
let req = await fetch(api, config)
|
|
||||||
let data = await req.json()
|
|
||||||
if (!data.playerInfo) {
|
if (!data.playerInfo) {
|
||||||
e.reply(`请求失败:${data.msg || '可能是面板服务并发过高,请稍后重试'}`)
|
return req.err(`请求失败:${data.msg}` || 'error', 60)
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
let details = data.avatarInfoList
|
let details = data.avatarInfoList
|
||||||
if (!details || details.length === 0 || !details[0].propMap) {
|
if (!details || details.length === 0 || !details[0].propMap) {
|
||||||
e.reply('请打开游戏内角色展柜的【显示详情】后,等待5分钟重新获取面板')
|
return req.err('no-avatar', 5 * 60)
|
||||||
await setCd(uid, 5 * 60)
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
return EnkaData.getData(uid, data)
|
return EnkaData.getData(req.uid, data)
|
||||||
},
|
|
||||||
getName ({ uid, diyCfg, sysCfg }) {
|
|
||||||
let url = diyCfg?.enkaApi?.url || sysCfg.enkaApi.url
|
|
||||||
url = url.replace('https://', '').replace('/', '').trim()
|
|
||||||
return url
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
|
||||||
export default Enka
|
|
||||||
|
2
components/profile-data/miao-data.js
Normal file
2
components/profile-data/miao-data.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
let MiaoData = {}
|
||||||
|
export default MiaoData
|
@ -1,4 +1,4 @@
|
|||||||
import _Data from '../Data.js'
|
import { Data } from '../index.js'
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
|
|
||||||
const _path = process.cwd()
|
const _path = process.cwd()
|
||||||
@ -11,7 +11,7 @@ export const artiIdx = {
|
|||||||
理之冠: 5
|
理之冠: 5
|
||||||
}
|
}
|
||||||
|
|
||||||
let relis = _Data.readJSON(`${_path}/plugins/miao-plugin/resources/meta/reliquaries/`, 'data.json') || {}
|
let relis = Data.readJSON(`${_path}/plugins/miao-plugin/resources/meta/reliquaries/`, 'data.json') || {}
|
||||||
let setMap = {}
|
let setMap = {}
|
||||||
|
|
||||||
lodash.forEach(relis, (ds) => {
|
lodash.forEach(relis, (ds) => {
|
||||||
|
@ -1,32 +1,12 @@
|
|||||||
import fetch from 'node-fetch'
|
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import Character from '../models/Character.js'
|
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import { artiIdx, artiSetMap, attrMap } from './miao-meta.js'
|
import { Character, ProfileServ } from '../../models/index.js'
|
||||||
import cmeta from './enka-char.js'
|
import cmeta from './enka-char.js'
|
||||||
|
import { artiIdx, artiSetMap, attrMap } from './miao-meta.js'
|
||||||
|
|
||||||
let Miao = {
|
let Miao = {
|
||||||
key: 'miao',
|
key: 'miao',
|
||||||
cd: 1,
|
name: 'MiaoApi',
|
||||||
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
|
|
||||||
}
|
|
||||||
data = data.data
|
|
||||||
if (!data.showAvatarInfoList || data.showAvatarInfoList.length === 0) {
|
|
||||||
e.reply('请打开游戏内角色展柜的“显示详情”后,等待5分钟重新获取面板')
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return Miao.getData(uid, data)
|
|
||||||
},
|
|
||||||
|
|
||||||
getData (uid, data) {
|
getData (uid, data) {
|
||||||
let ret = {
|
let ret = {
|
||||||
@ -93,15 +73,15 @@ let Miao = {
|
|||||||
def: 'defense',
|
def: 'defense',
|
||||||
defBase: 'baseDEF',
|
defBase: 'baseDEF',
|
||||||
mastery: 'elementMastery',
|
mastery: 'elementMastery',
|
||||||
cRate: {
|
cpct: {
|
||||||
src: 'critRate',
|
src: 'critRate',
|
||||||
pct: true
|
pct: true
|
||||||
},
|
},
|
||||||
cDmg: {
|
cdmg: {
|
||||||
src: 'critDamage',
|
src: 'critDamage',
|
||||||
pct: true
|
pct: true
|
||||||
},
|
},
|
||||||
hInc: {
|
heal: {
|
||||||
src: 'heal',
|
src: 'heal',
|
||||||
pct: true
|
pct: true
|
||||||
},
|
},
|
||||||
@ -124,8 +104,8 @@ let Miao = {
|
|||||||
lodash.forEach('fire,elec,water,grass,wind,rock,ice'.split(','), (key) => {
|
lodash.forEach('fire,elec,water,grass,wind,rock,ice'.split(','), (key) => {
|
||||||
maxDmg = Math.max(hurt[key] * 100, maxDmg)
|
maxDmg = Math.max(hurt[key] * 100, maxDmg)
|
||||||
})
|
})
|
||||||
ret.dmgBonus = maxDmg
|
ret.dmg = maxDmg
|
||||||
ret.phyBonus = hurt.physical * 100
|
ret.phy = hurt.physical * 100
|
||||||
return ret
|
return ret
|
||||||
},
|
},
|
||||||
getWeapon (weapon) {
|
getWeapon (weapon) {
|
||||||
@ -216,4 +196,18 @@ let Miao = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Miao
|
export default new ProfileServ({
|
||||||
|
key: 'miao',
|
||||||
|
name: 'MiaoApi',
|
||||||
|
cfgKey: 'miaoApi',
|
||||||
|
async response (data, req) {
|
||||||
|
if (data.status !== 0) {
|
||||||
|
return req.err(data.msg || 'error', 60)
|
||||||
|
}
|
||||||
|
data = data.data
|
||||||
|
if (!data.showAvatarInfoList || data.showAvatarInfoList.length === 0) {
|
||||||
|
return req.err('empty', 5 * 60)
|
||||||
|
}
|
||||||
|
return Miao.getData(req.uid, data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
@ -172,3 +172,5 @@ export const abbr = {
|
|||||||
渡过烈火的贤人: '渡火贤人',
|
渡过烈火的贤人: '渡火贤人',
|
||||||
冰风迷途的勇士: '冰风勇士'
|
冰风迷途的勇士: '冰风勇士'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const isSys = true
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
* 如需自定义配置请复制修改上一级profile_default.js
|
* 如需自定义配置请复制修改上一级profile_default.js
|
||||||
* */
|
* */
|
||||||
|
|
||||||
export const profileApi = ({ uid, Miao, Enka, diyCfg }) => {
|
export const getProfileServ = ({ uid, serv, diyCfg }) => {
|
||||||
|
let { Miao, Enka } = serv
|
||||||
let token = diyCfg?.miaoApi?.token
|
let token = diyCfg?.miaoApi?.token
|
||||||
if (token && token.length === 32) {
|
if (token && token.length === 32) {
|
||||||
return Miao
|
return Miao
|
||||||
@ -13,19 +14,24 @@ export const profileApi = ({ uid, Miao, Enka, diyCfg }) => {
|
|||||||
|
|
||||||
export const miaoApi = {
|
export const miaoApi = {
|
||||||
url: 'http://49.232.91.210/profile',
|
url: 'http://49.232.91.210/profile',
|
||||||
token: 'miao-token',
|
listApi: ({ url, uid, diyCfg }) => {
|
||||||
listApi: ({ url, uid, token }) => {
|
return `${url}/data?uid=${uid}&token=${diyCfg.token}`
|
||||||
return `${url}/data?uid=${uid}&token=${token}`
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enkaApi = {
|
export const enkaApi = {
|
||||||
url: 'https://enka.network/',
|
url: 'https://enka.network/',
|
||||||
userAgent: 'Miao-Plugin/3.0',
|
userAgent: 'Miao-Plugin/3.0',
|
||||||
listApi: ({ url, uid }) => {
|
listApi: ({ url, uid, diyCfg }) => {
|
||||||
return `${url}u/${uid}/__data.json`
|
let api = `${url}u/${uid}/__data.json`
|
||||||
|
if (diyCfg?.apiKey) {
|
||||||
|
api += '?key=' + diyCfg.apiKey
|
||||||
|
}
|
||||||
|
return api
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 请求面板的冷却时间,单位分钟 */
|
/* 请求面板的冷却时间,单位分钟 */
|
||||||
export const requestInterval = 5
|
export const requestInterval = 5
|
||||||
|
|
||||||
|
export const isSys = true
|
||||||
|
13
index.js
13
index.js
@ -1,25 +1,24 @@
|
|||||||
// 适配V3 Yunzai,将index.js移至app/index.js
|
// 适配V3 Yunzai,将index.js移至app/index.js
|
||||||
import { currentVersion, isV3 } from './components/Changelog.js'
|
import { Data, Version } from './components/index.js'
|
||||||
import Data from './components/Data.js'
|
|
||||||
|
|
||||||
export * from './apps/index.js'
|
export * from './apps/index.js'
|
||||||
let index = { miao: {} }
|
let index = { miao: {} }
|
||||||
if (isV3) {
|
if (Version.isV3) {
|
||||||
index = await Data.importModule('/plugins/miao-plugin/adapter', 'index.js')
|
index = await Data.importModule('/plugins/miao-plugin/adapter', 'index.js')
|
||||||
}
|
}
|
||||||
export const miao = index.miao || {}
|
export const miao = index.miao || {}
|
||||||
if (Bot?.logger?.info) {
|
if (Bot?.logger?.info) {
|
||||||
Bot.logger.info(`---------^_^---------`)
|
Bot.logger.info(`---------^_^---------`)
|
||||||
Bot.logger.info(`喵喵插件${currentVersion}初始化~`)
|
Bot.logger.info(`喵喵插件${Version.version}初始化~`)
|
||||||
} else {
|
} else {
|
||||||
console.log(`喵喵插件${currentVersion}初始化~`)
|
console.log(`喵喵插件${Version.version}初始化~`)
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(async function () {
|
setTimeout(async function () {
|
||||||
let msgStr = await redis.get('miao:restart-msg')
|
let msgStr = await redis.get('miao:restart-msg')
|
||||||
let relpyPrivate = async function () {
|
let relpyPrivate = async function () {
|
||||||
}
|
}
|
||||||
if (!isV3) {
|
if (!Version.isV3) {
|
||||||
let common = await Data.importModule('/lib', 'common.js')
|
let common = await Data.importModule('/lib', 'common.js')
|
||||||
if (common && common.default && common.default.relpyPrivate) {
|
if (common && common.default && common.default.relpyPrivate) {
|
||||||
relpyPrivate = common.default.relpyPrivate
|
relpyPrivate = common.default.relpyPrivate
|
||||||
@ -29,7 +28,7 @@ setTimeout(async function () {
|
|||||||
let msg = JSON.parse(msgStr)
|
let msg = JSON.parse(msgStr)
|
||||||
await relpyPrivate(msg.qq, msg.msg)
|
await relpyPrivate(msg.qq, msg.msg)
|
||||||
await redis.del('miao:restart-msg')
|
await redis.del('miao:restart-msg')
|
||||||
let msgs = [`当前喵喵版本: ${currentVersion}`, '您可使用 #喵喵版本 命令查看更新信息']
|
let msgs = [`当前喵喵版本: ${Version.version}`, '您可使用 #喵喵版本 命令查看更新信息']
|
||||||
await relpyPrivate(msg.qq, msgs.join('\n'))
|
await relpyPrivate(msg.qq, msgs.join('\n'))
|
||||||
}
|
}
|
||||||
}, 1000)
|
}, 1000)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Base from '../models/Base.js'
|
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import Data from '../Data.js'
|
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
|
import Base from '../models/Base.js'
|
||||||
|
import { Data } from '../components/index.js'
|
||||||
|
|
||||||
moment.locale('zh-cn')
|
moment.locale('zh-cn')
|
||||||
|
|
||||||
@ -67,12 +67,12 @@ export default class Abyss extends Base {
|
|||||||
getAvatars () {
|
getAvatars () {
|
||||||
let ret = {}
|
let ret = {}
|
||||||
lodash.forEach(this.reveral, (ds) => {
|
lodash.forEach(this.reveral, (ds) => {
|
||||||
if(ds.id) {
|
if (ds.id) {
|
||||||
ret[ds.id] = true
|
ret[ds.id] = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
lodash.forEach(this.stat, (ds) => {
|
lodash.forEach(this.stat, (ds) => {
|
||||||
if(ds.id) {
|
if (ds.id) {
|
||||||
ret[ds.id] = true
|
ret[ds.id] = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -80,12 +80,12 @@ export default class Abyss extends Base {
|
|||||||
let levels = floor?.levels || {}
|
let levels = floor?.levels || {}
|
||||||
lodash.forEach(levels, (level) => {
|
lodash.forEach(levels, (level) => {
|
||||||
lodash.forEach(level.up?.avatars || [], (id) => {
|
lodash.forEach(level.up?.avatars || [], (id) => {
|
||||||
if(id){
|
if (id) {
|
||||||
ret[id] = true
|
ret[id] = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
lodash.forEach(level.down?.avatars || [], (id) => {
|
lodash.forEach(level.down?.avatars || [], (id) => {
|
||||||
if(id){
|
if (id) {
|
||||||
ret[id] = true
|
ret[id] = true
|
||||||
}
|
}
|
||||||
})
|
})
|
48
models/Artifact.js
Normal file
48
models/Artifact.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import { attrMap }
|
||||||
|
from '../resources/meta/reliquaries/reliquaries-mark-new.js'
|
||||||
|
import lodash from 'lodash'
|
||||||
|
import { Data } from '../components/index.js'
|
||||||
|
|
||||||
|
let artisMap = {}
|
||||||
|
|
||||||
|
async function init () {
|
||||||
|
let _path = process.cwd()
|
||||||
|
let artis = Data.readJSON(`${_path}/plugins/miao-plugin/resources/meta/reliquaries/`, 'data.json') || {}
|
||||||
|
|
||||||
|
lodash.forEach(artis, (ds) => {
|
||||||
|
artisMap[ds.name] = ds
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
await init()
|
||||||
|
|
||||||
|
let Artifact = {
|
||||||
|
|
||||||
|
// 根据圣遗物名称获取套装
|
||||||
|
getSetByArti (name) {
|
||||||
|
for (let idx in artisMap) {
|
||||||
|
for (let idx2 in artisMap[idx].sets) {
|
||||||
|
if (artisMap[idx].sets[idx2].name === name) {
|
||||||
|
return artisMap[idx]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取指定圣遗物套装指定位置的名字
|
||||||
|
getArtiBySet (name, idx = 1) {
|
||||||
|
let set = artisMap[name]
|
||||||
|
if (!set) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
return set.sets[`arti${idx}`].name
|
||||||
|
},
|
||||||
|
|
||||||
|
getMeta () {
|
||||||
|
return {
|
||||||
|
attrMap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default Artifact
|
@ -1,9 +1,7 @@
|
|||||||
import Base from './Base.js'
|
import Base from './Base.js'
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import Data from '../Data.js'
|
import { Data, Common } from '../components/index.js'
|
||||||
import Artifact from './Artifact.js'
|
import { Artifact, Character } from './index.js'
|
||||||
import Character from './Character.js'
|
|
||||||
import Common from '../Common.js'
|
|
||||||
|
|
||||||
export default class Avatars extends Base {
|
export default class Avatars extends Base {
|
||||||
constructor (uid, datas = []) {
|
constructor (uid, datas = []) {
|
||||||
@ -24,27 +22,20 @@ export default class Avatars extends Base {
|
|||||||
data.star = 5
|
data.star = 5
|
||||||
}
|
}
|
||||||
let artis = {}
|
let artis = {}
|
||||||
let sets = {}
|
let setCount = {}
|
||||||
lodash.forEach(avatar.reliquaries, (arti) => {
|
lodash.forEach(avatar.reliquaries, (arti) => {
|
||||||
artis[arti.pos] = Data.getData(arti, 'name,level,set:set.name')
|
artis[arti.pos] = Data.getData(arti, 'name,level,set:set.name')
|
||||||
sets[arti.set.name] = (sets[arti.set.name] || 0) + 1
|
setCount[arti.set.name] = (setCount[arti.set.name] || 0) + 1
|
||||||
})
|
})
|
||||||
data.artis = artis
|
data.artis = artis
|
||||||
data.set = {}
|
data.sets = {}
|
||||||
for (let set in sets) {
|
data.names = []
|
||||||
if (sets[set] >= 4) {
|
for (let set in setCount) {
|
||||||
data.set[set] = 4
|
if (setCount[set] >= 2) {
|
||||||
} else if (sets[set] >= 2) {
|
data.sets[set] = setCount[set] >= 4 ? 4 : 2
|
||||||
data.set[set] = 2
|
data.names.push(Artifact.getArtiBySet(set))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data.sets = []
|
|
||||||
lodash.forEach(data.set, (v, k) => {
|
|
||||||
let name = Artifact.getArtiBySet(k)
|
|
||||||
if (name) {
|
|
||||||
data.sets.push(name)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
avatars[data.id] = data
|
avatars[data.id] = data
|
||||||
})
|
})
|
||||||
this.avatars = avatars
|
this.avatars = avatars
|
@ -1,15 +1,13 @@
|
|||||||
import { Data } from '../index.js'
|
import { Data } from '../components/index.js'
|
||||||
|
|
||||||
export default class Base {
|
export default class Base {
|
||||||
constructor () {
|
|
||||||
this.name = ''
|
|
||||||
}
|
|
||||||
|
|
||||||
toString () {
|
toString () {
|
||||||
return this.name
|
return this?.name || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
getData (arrList = '', cfg = {}) {
|
getData (arrList = '', cfg = {}) {
|
||||||
|
arrList = arrList || this._dataKey || ''
|
||||||
return Data.getData(this, arrList, cfg)
|
return Data.getData(this, arrList, cfg)
|
||||||
}
|
}
|
||||||
|
|
@ -1,8 +1,8 @@
|
|||||||
import Base from './Base.js'
|
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import Data from '../Data.js'
|
|
||||||
import sizeOf from 'image-size'
|
import sizeOf from 'image-size'
|
||||||
|
import Base from './Base.js'
|
||||||
|
import { Data } from '../components/index.js'
|
||||||
|
|
||||||
let aliasMap = {}
|
let aliasMap = {}
|
||||||
let idMap = {}
|
let idMap = {}
|
||||||
@ -12,10 +12,8 @@ const _path = process.cwd()
|
|||||||
const metaPath = `${_path}/plugins/miao-plugin/resources/meta/character/`
|
const metaPath = `${_path}/plugins/miao-plugin/resources/meta/character/`
|
||||||
|
|
||||||
async function init () {
|
async function init () {
|
||||||
let sysCfg = await Data.importModule('plugins/miao-plugin/config/system', 'character.js')
|
let { sysCfg, diyCfg } = await Data.importCfg('character')
|
||||||
let custom = await Data.importModule('plugins/miao-plugin/config', 'character.js')
|
lodash.forEach([diyCfg.customCharacters, sysCfg.characters], (roleIds) => {
|
||||||
|
|
||||||
lodash.forEach([custom.customCharacters, sysCfg.characters], (roleIds) => {
|
|
||||||
lodash.forEach(roleIds || {}, (aliases, id) => {
|
lodash.forEach(roleIds || {}, (aliases, id) => {
|
||||||
aliases = aliases || []
|
aliases = aliases || []
|
||||||
if (aliases.length === 0) {
|
if (aliases.length === 0) {
|
||||||
@ -31,7 +29,7 @@ async function init () {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
lodash.forEach([sysCfg.wifeData, custom.wifeData], (wifeData) => {
|
lodash.forEach([sysCfg.wifeData, diyCfg.wifeData], (wifeData) => {
|
||||||
lodash.forEach(wifeData || {}, (ids, type) => {
|
lodash.forEach(wifeData || {}, (ids, type) => {
|
||||||
type = Data.def({ girlfriend: 0, boyfriend: 1, daughter: 2, son: 3 }[type], type)
|
type = Data.def({ girlfriend: 0, boyfriend: 1, daughter: 2, son: 3 }[type], type)
|
||||||
if (!wifeMap[type]) {
|
if (!wifeMap[type]) {
|
181
models/ProfileArtis.js
Normal file
181
models/ProfileArtis.js
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
/*
|
||||||
|
* 面板圣遗物
|
||||||
|
* */
|
||||||
|
import lodash from 'lodash'
|
||||||
|
import Base from './Base.js'
|
||||||
|
import { Artifact, Character } from './index.js'
|
||||||
|
import { Format } from '../components/index.js'
|
||||||
|
import ArtisMark from './profile-lib/ArtisMark.js'
|
||||||
|
import { attrMap, attrValue, usefulAttr } from '../resources/meta/reliquaries/reliquaries-mark-new.js'
|
||||||
|
|
||||||
|
let charCfg = {}
|
||||||
|
|
||||||
|
export default class ProfileArtis extends Base {
|
||||||
|
constructor (charid = 0, ds = false) {
|
||||||
|
super()
|
||||||
|
this.charid = charid
|
||||||
|
this.artis = {}
|
||||||
|
if (ds) {
|
||||||
|
this.setArtisSet(ds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setArtisSet (ds) {
|
||||||
|
for (let key in ds) {
|
||||||
|
this.setArtis(key, ds[key] || {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setArtis (idx = 1, ds = {}) {
|
||||||
|
idx = idx.toString().replace('arti', '')
|
||||||
|
let ret = {}
|
||||||
|
ret.name = ds.name || Artifact.getArtiBySet(ds.set, idx) || ''
|
||||||
|
ret.set = ds.set || Artifact.getSetByArti(ret.title) || ''
|
||||||
|
ret.level = ds.level || 1
|
||||||
|
ret.main = ArtisMark.formatAttr(ds.main || {})
|
||||||
|
ret.attrs = []
|
||||||
|
for (let attrIdx in ds.attrs || []) {
|
||||||
|
if (ds.attrs[attrIdx]) {
|
||||||
|
ret.attrs.push(ArtisMark.formatAttr(ds.attrs[attrIdx]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.artis[idx] = ret
|
||||||
|
}
|
||||||
|
|
||||||
|
forEach (fn) {
|
||||||
|
lodash.forEach(this.artis, (ds, idx) => {
|
||||||
|
if (ds.name) {
|
||||||
|
fn(ds, idx)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
get 1 () {
|
||||||
|
return this.artis[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
get 2 () {
|
||||||
|
return this.artis[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
get 3 () {
|
||||||
|
return this.artis[3]
|
||||||
|
}
|
||||||
|
|
||||||
|
get 4 () {
|
||||||
|
return this.artis[4]
|
||||||
|
}
|
||||||
|
|
||||||
|
get 5 () {
|
||||||
|
return this.artis[5]
|
||||||
|
}
|
||||||
|
|
||||||
|
get length () {
|
||||||
|
return lodash.keys(this.artis).length
|
||||||
|
}
|
||||||
|
|
||||||
|
toJSON () {
|
||||||
|
return this.getData('1,2,3,4,5')
|
||||||
|
}
|
||||||
|
|
||||||
|
getMarkDetail (withDetail = true) {
|
||||||
|
let charCfg = this.getCharCfg()
|
||||||
|
let artis = {}
|
||||||
|
let setCount = {}
|
||||||
|
let usefulMark = charCfg.titleWeight
|
||||||
|
let totalMark = 0
|
||||||
|
this.forEach((arti, idx) => {
|
||||||
|
let mark = ArtisMark.getMark(charCfg, idx, arti.main, arti.attrs)
|
||||||
|
totalMark += mark
|
||||||
|
setCount[arti.set] = (setCount[arti.set] || 0) + 1
|
||||||
|
if (!withDetail) {
|
||||||
|
artis[idx] = {
|
||||||
|
_mark: mark,
|
||||||
|
mark: Format.comma(mark, 1),
|
||||||
|
markClass: ArtisMark.getMarkClass(mark)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
artis[idx] = {
|
||||||
|
name: arti.name,
|
||||||
|
set: arti.set,
|
||||||
|
level: arti.level,
|
||||||
|
_mark: mark,
|
||||||
|
mark: Format.comma(mark, 1),
|
||||||
|
markClass: ArtisMark.getMarkClass(mark),
|
||||||
|
main: ArtisMark.formatArti(arti.main, charCfg.mark, true),
|
||||||
|
attrs: ArtisMark.formatArti(arti.attrs, charCfg.mark)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let sets = {}
|
||||||
|
let names = []
|
||||||
|
for (let set in setCount) {
|
||||||
|
if (setCount[set] >= 2) {
|
||||||
|
sets[set] = setCount[set] >= 4 ? 4 : 2
|
||||||
|
names.push(Artifact.getArtiBySet(set))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let ret = {
|
||||||
|
mark: Format.comma(totalMark, 1),
|
||||||
|
_mark: totalMark,
|
||||||
|
markClass: ArtisMark.getMarkClass(totalMark / 5),
|
||||||
|
artis,
|
||||||
|
sets,
|
||||||
|
names
|
||||||
|
}
|
||||||
|
if (withDetail) {
|
||||||
|
ret.usefulMark = usefulMark
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
getCharCfg () {
|
||||||
|
let char = Character.get(this.charid)
|
||||||
|
let name = char.name
|
||||||
|
if (charCfg[name]) {
|
||||||
|
return charCfg[name]
|
||||||
|
}
|
||||||
|
let attrWeight = usefulAttr[name] || { atk: 75, cp: 100, cd: 100 }
|
||||||
|
let attrMark = {}
|
||||||
|
|
||||||
|
let baseAttr = char?.lvStat?.detail['90'] || [400, 500, 300]
|
||||||
|
lodash.forEach(attrWeight, (weight, attr) => {
|
||||||
|
attrMark[attr] = weight / attrValue[attr]
|
||||||
|
})
|
||||||
|
|
||||||
|
// let baseAttr = [400, 500, 300];
|
||||||
|
if (attrMark.hp) {
|
||||||
|
attrMark.hpPlus = attrMark.hp / baseAttr[0] * 100
|
||||||
|
}
|
||||||
|
if (attrMark.atk) {
|
||||||
|
// 以520作为武器白值均值计算
|
||||||
|
attrMark.atkPlus = attrMark.atk / (baseAttr[1] * 1 + 520) * 100
|
||||||
|
}
|
||||||
|
if (attrMark.def) {
|
||||||
|
attrMark.defPlus = attrMark.def / baseAttr[2] * 100
|
||||||
|
}
|
||||||
|
let maxMark = ArtisMark.getMaxMark(attrWeight)
|
||||||
|
let titleMark = {}
|
||||||
|
let titleWeight = {}
|
||||||
|
lodash.forEach(attrMark, (mark, attr) => {
|
||||||
|
let aTitle = attrMap[attr].title
|
||||||
|
if (/小/.test(aTitle)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
titleMark[aTitle] = mark
|
||||||
|
titleWeight[aTitle] = attrWeight[attr] || 0
|
||||||
|
if (/大/.test(aTitle)) {
|
||||||
|
let sTitle = aTitle.replace('大', '小')
|
||||||
|
titleWeight[sTitle] = titleWeight[aTitle]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
charCfg[name] = {
|
||||||
|
weight: attrWeight,
|
||||||
|
mark: attrMark,
|
||||||
|
titleMap: titleMark,
|
||||||
|
titleWeight,
|
||||||
|
maxMark
|
||||||
|
}
|
||||||
|
return charCfg[name]
|
||||||
|
}
|
||||||
|
}
|
94
models/ProfileData.js
Normal file
94
models/ProfileData.js
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import lodash from 'lodash'
|
||||||
|
import Base from './Base.js'
|
||||||
|
import { Data } from '../components/index.js'
|
||||||
|
import { Character, ProfileArtis, ProfileDmg } from './index.js'
|
||||||
|
|
||||||
|
export default class ProfileData extends Base {
|
||||||
|
constructor (ds = {}) {
|
||||||
|
super()
|
||||||
|
let char = Character.get(ds.id)
|
||||||
|
if (!char) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
this.id = char.id
|
||||||
|
this.char = char
|
||||||
|
|
||||||
|
this.setBasic(ds)
|
||||||
|
ds.attr && this.setAttr(ds.attr)
|
||||||
|
ds.weapon && this.setWeapon(ds.weapon)
|
||||||
|
this.artis = new ProfileArtis(this.id)
|
||||||
|
ds.artis && this.setArtis(ds.artis)
|
||||||
|
ds.talent && this.setTalent(ds.talent)
|
||||||
|
}
|
||||||
|
|
||||||
|
setBasic (ds = {}) {
|
||||||
|
this.level = ds.lv || ds.level || 1
|
||||||
|
this.cons = ds.cons || 0
|
||||||
|
this.fetter = ds.fetter || 0
|
||||||
|
this.dataSource = ds.dataSource || 'enka'
|
||||||
|
this.updateTime = ds.updateTime || new Date() * 1
|
||||||
|
}
|
||||||
|
|
||||||
|
setAttr (ds) {
|
||||||
|
this.attr = lodash.extend(Data.getData(ds, 'atk,atkBase,def,defBase,hp,hpBase,mastery,recharge'), {
|
||||||
|
heal: ds.heal || ds.hInc || 0,
|
||||||
|
cpct: ds.cpct || ds.cRate,
|
||||||
|
cdmg: ds.cdmg || ds.cDmg,
|
||||||
|
dmg: ds.dmg || ds.dmgBonus || 0,
|
||||||
|
phy: ds.phy || ds.phyBonus || 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
setWeapon (ds = {}) {
|
||||||
|
this.weapon = {
|
||||||
|
name: ds.name,
|
||||||
|
star: ds.rank || ds.star || 1,
|
||||||
|
level: ds.level || ds.lv || 1,
|
||||||
|
promote: ds.promote || 1,
|
||||||
|
affix: ds.affix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setArtis (ds = false) {
|
||||||
|
if (ds) {
|
||||||
|
this.artis.setArtisSet(ds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setTalent (ds = {}, mode = 'level') {
|
||||||
|
this.talent = this.char.getAvatarTalent(ds, this.cons, mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
get name () {
|
||||||
|
return this.char?.name || ''
|
||||||
|
}
|
||||||
|
|
||||||
|
get hasData () {
|
||||||
|
if (!['enka', 'input2', 'miao'].includes(this.dataSource)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (['空', '荧'].includes(this.name)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
hasArtis () {
|
||||||
|
return this.hasData && this.artis.length > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
toJSON () {
|
||||||
|
return this.getData('id,name,level,cons,fetter,attr,weapon,talent,artis,updateTime,dataSource')
|
||||||
|
}
|
||||||
|
|
||||||
|
getArtisMark (withDetail = true) {
|
||||||
|
return this.artis.getMarkDetail(withDetail)
|
||||||
|
}
|
||||||
|
|
||||||
|
async calcDmg ({ enemyLv = 91, mode = 'profile', dmgIdx = 0 }) {
|
||||||
|
if (!this.dmg) {
|
||||||
|
this.dmg = new ProfileDmg(this)
|
||||||
|
}
|
||||||
|
return await this.dmg.calcData({ enemyLv, mode, dmgIdx })
|
||||||
|
}
|
||||||
|
}
|
146
models/ProfileDmg.js
Normal file
146
models/ProfileDmg.js
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
import Base from './Base.js'
|
||||||
|
import { Character } from './index.js'
|
||||||
|
import lodash from 'lodash'
|
||||||
|
import { attrMap } from './profile-lib/calc-meta.js'
|
||||||
|
import Calc from './profile-lib/Calc.js'
|
||||||
|
|
||||||
|
export default class ProfileDmg extends Base {
|
||||||
|
constructor (profile = false) {
|
||||||
|
super()
|
||||||
|
this.profile = profile
|
||||||
|
if (profile && profile.id) {
|
||||||
|
let { id } = profile
|
||||||
|
this.char = Character.get(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async calcData ({ enemyLv = 91, mode = 'profile', dmgIdx = 0 }) {
|
||||||
|
if (!this.char || !this.profile) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
let { profile, char } = this
|
||||||
|
let charCalcData = await Calc.getCharCalcRule(this.char.name)
|
||||||
|
|
||||||
|
if (!charCalcData) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
let talent = Calc.talent(profile, char)
|
||||||
|
|
||||||
|
let meta = {
|
||||||
|
cons: profile.cons * 1,
|
||||||
|
talent
|
||||||
|
}
|
||||||
|
|
||||||
|
let { buffs, details, defParams, mainAttr, defDmgIdx, enemyName } = charCalcData
|
||||||
|
|
||||||
|
defParams = defParams || {}
|
||||||
|
|
||||||
|
let originalAttr = Calc.attr(profile)
|
||||||
|
|
||||||
|
let weaponBuffs = await Calc.weapon(profile.weapon.name)
|
||||||
|
let reliBuffs = await Calc.reliquaries(profile.artis)
|
||||||
|
buffs = lodash.concat(buffs, weaponBuffs, reliBuffs)
|
||||||
|
|
||||||
|
lodash.forEach(buffs, (buff) => {
|
||||||
|
buff.sort = lodash.isUndefined(buff.sort) ? 1 : buff.sort
|
||||||
|
})
|
||||||
|
|
||||||
|
buffs = lodash.sortBy(buffs, ['sort'])
|
||||||
|
|
||||||
|
let { msg } = Calc.calcAttr({ originalAttr, buffs, meta, params: defParams || {} })
|
||||||
|
|
||||||
|
let ret = []
|
||||||
|
let detailMap = []
|
||||||
|
let dmgRet = []
|
||||||
|
let dmgDetail = {}
|
||||||
|
|
||||||
|
lodash.forEach(details, (detail, detailSysIdx) => {
|
||||||
|
if (lodash.isFunction(detail)) {
|
||||||
|
let { attr } = Calc.calcAttr({ originalAttr, buffs, meta })
|
||||||
|
let ds = lodash.merge({ talent }, Calc.getDs(attr, meta))
|
||||||
|
detail = detail({ ...ds, attr, profile })
|
||||||
|
}
|
||||||
|
let params = lodash.merge({}, defParams, detail.params || {})
|
||||||
|
let { attr } = Calc.calcAttr({ originalAttr, buffs, meta, params, talent: detail.talent || '' })
|
||||||
|
if (detail.check && !detail.check(Calc.getDs(attr, meta, params))) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (detail.cons && meta.cons < detail.cons * 1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let ds = lodash.merge({ talent }, Calc.getDs(attr, meta, params))
|
||||||
|
|
||||||
|
let dmg = Calc.getDmgFn({ ds, attr, profile, enemyLv, showDetail: detail.showDetail })
|
||||||
|
let basicDmgRet
|
||||||
|
|
||||||
|
if (detail.dmg) {
|
||||||
|
basicDmgRet = detail.dmg(ds, dmg)
|
||||||
|
detail.userIdx = detailMap.length
|
||||||
|
detailMap.push(detail)
|
||||||
|
ret.push({
|
||||||
|
title: detail.title,
|
||||||
|
...basicDmgRet
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (mode === 'dmg') {
|
||||||
|
let detail
|
||||||
|
if (dmgIdx && detailMap[dmgIdx - 1]) {
|
||||||
|
detail = detailMap[dmgIdx - 1]
|
||||||
|
} else if (!lodash.isUndefined(defDmgIdx) && details[defDmgIdx]) {
|
||||||
|
detail = details[defDmgIdx]
|
||||||
|
} else {
|
||||||
|
detail = detailMap[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
dmgDetail = {
|
||||||
|
title: detail.title,
|
||||||
|
userIdx: detail.userIdx,
|
||||||
|
basicRet: lodash.merge({}, ret[detail.userIdx]),
|
||||||
|
attr: []
|
||||||
|
}
|
||||||
|
|
||||||
|
mainAttr = mainAttr.split(',')
|
||||||
|
let params = lodash.merge({}, defParams, detail.params || {})
|
||||||
|
let basicDmg = dmgDetail.basicRet
|
||||||
|
lodash.forEach(mainAttr, (reduceAttr) => {
|
||||||
|
dmgDetail.attr.push(attrMap[reduceAttr])
|
||||||
|
let rowData = []
|
||||||
|
lodash.forEach(mainAttr, (incAttr) => {
|
||||||
|
if (incAttr === reduceAttr) {
|
||||||
|
rowData.push({ type: 'na' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let { attr } = Calc.calcAttr({
|
||||||
|
originalAttr,
|
||||||
|
buffs,
|
||||||
|
meta,
|
||||||
|
params,
|
||||||
|
incAttr,
|
||||||
|
reduceAttr,
|
||||||
|
talent: detail.talent || ''
|
||||||
|
})
|
||||||
|
let ds = lodash.merge({ talent }, Calc.getDs(attr, meta, params))
|
||||||
|
let dmg = Calc.getDmgFn({ ds, attr, profile, enemyLv })
|
||||||
|
if (detail.dmg) {
|
||||||
|
let dmgCalcRet = detail.dmg(ds, dmg)
|
||||||
|
rowData.push({
|
||||||
|
type: dmgCalcRet.avg === basicDmg.avg ? 'avg' : (dmgCalcRet.avg > basicDmg.avg ? 'gt' : 'lt'),
|
||||||
|
...dmgCalcRet
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
dmgRet.push(rowData)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
ret,
|
||||||
|
msg,
|
||||||
|
dmgRet,
|
||||||
|
enemyName,
|
||||||
|
dmgCfg: dmgDetail
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
88
models/ProfileReq.js
Normal file
88
models/ProfileReq.js
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import Base from './Base.js'
|
||||||
|
import ProfileServ from './ProfileServ.js'
|
||||||
|
import fetch from 'node-fetch'
|
||||||
|
|
||||||
|
function sleep (ms) {
|
||||||
|
return new Promise((resolve) => setTimeout(resolve, ms))
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class ProfileReq extends Base {
|
||||||
|
constructor ({ e, uid }) {
|
||||||
|
super()
|
||||||
|
this.e = e
|
||||||
|
this.uid = uid
|
||||||
|
}
|
||||||
|
|
||||||
|
async setCd (seconds = 60) {
|
||||||
|
let ext = new Date() * 1 + seconds * 1000
|
||||||
|
await redis.set(`miao:profile-req:${this.uid}`, ext + '', { EX: seconds })
|
||||||
|
}
|
||||||
|
|
||||||
|
async inCd () {
|
||||||
|
let ext = await redis.get(`miao:role-all:${this.uid}`)
|
||||||
|
if (!ext || isNaN(ext)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
let cd = new Date() * 1 - ext
|
||||||
|
if (cd < 0) {
|
||||||
|
return Math.ceil(0 - cd / 1000)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
err (msg = '', cd = 0) {
|
||||||
|
const msgs = {
|
||||||
|
error: '请求失败,可能是服务负载较高,请稍后重试...',
|
||||||
|
empty: '请将角色放置在【游戏内】角色展柜,并打开【显示详情】,等待5分钟重新获取面板'
|
||||||
|
}
|
||||||
|
msg = msgs[msg] || msg
|
||||||
|
if (msg) {
|
||||||
|
this.e.reply(msg)
|
||||||
|
}
|
||||||
|
// 设置CD
|
||||||
|
if (cd) {
|
||||||
|
this.setCd(cd)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
msg (msg) {
|
||||||
|
this.e.reply(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
async request () {
|
||||||
|
let Serv = ProfileReq.getServ(this.uid)
|
||||||
|
let reqParam = await Serv.getReqParam(this.uid)
|
||||||
|
|
||||||
|
let cdTime = await this.inCd()
|
||||||
|
if (cdTime) {
|
||||||
|
return this.err(`请求过快,请${cdTime}秒后重试..`)
|
||||||
|
}
|
||||||
|
await this.setCd(20)
|
||||||
|
this.msg('开始获取数据,可能会需要一定时间~')
|
||||||
|
await sleep(100)
|
||||||
|
// 发起请求
|
||||||
|
console.log('reqParam', reqParam)
|
||||||
|
let req = await fetch(reqParam.url, reqParam.params || {})
|
||||||
|
let data = await req.json()
|
||||||
|
data = await Serv.response(data, this)
|
||||||
|
|
||||||
|
console.log(data)
|
||||||
|
// 设置CD
|
||||||
|
cdTime = Serv.getCdTime(data)
|
||||||
|
if (cdTime) {
|
||||||
|
await this.setCd(cdTime)
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ProfileReq.serv = {}
|
||||||
|
ProfileReq.regServ = function (serv) {
|
||||||
|
for (let key in serv) {
|
||||||
|
ProfileReq.serv[key] = serv[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ProfileReq.getServ = function (uid) {
|
||||||
|
return ProfileServ.getServ({ uid, serv: ProfileReq.serv })
|
||||||
|
}
|
78
models/ProfileServ.js
Normal file
78
models/ProfileServ.js
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import lodash from 'lodash'
|
||||||
|
import Base from './Base.js'
|
||||||
|
import { Data } from '../components/index.js'
|
||||||
|
|
||||||
|
let { sysCfg, diyCfg } = await Data.importCfg('profile')
|
||||||
|
|
||||||
|
export default class ProfileServ extends Base {
|
||||||
|
constructor (cfg) {
|
||||||
|
super()
|
||||||
|
this._name = cfg.name
|
||||||
|
this.cfgKey = cfg.cfgKey || cfg.id
|
||||||
|
this.diyCfg = diyCfg[this.cfgKey]
|
||||||
|
this.sysCfg = sysCfg[this.cfgKey]
|
||||||
|
this._cfg = cfg
|
||||||
|
}
|
||||||
|
|
||||||
|
get name () {
|
||||||
|
let url = this.getCfg('url')
|
||||||
|
return this._name || url.replace('https://', '').replace('/', '').trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前面板服务配置
|
||||||
|
getCfg (key, def = '') {
|
||||||
|
if (!lodash.isUndefined(this.diyCfg[key])) {
|
||||||
|
return this.diyCfg[key]
|
||||||
|
}
|
||||||
|
if (!lodash.isUndefined(this.sysCfg[key])) {
|
||||||
|
return this.sysCfg[key]
|
||||||
|
}
|
||||||
|
return def
|
||||||
|
}
|
||||||
|
|
||||||
|
// 请求当前面板服务
|
||||||
|
async getReqParam (uid) {
|
||||||
|
let url = this.getCfg('url')
|
||||||
|
let profileApi = this.getCfg('listApi')
|
||||||
|
let cfg = this._cfg
|
||||||
|
let api = profileApi({
|
||||||
|
url,
|
||||||
|
uid: uid,
|
||||||
|
diyCfg: this.diyCfg
|
||||||
|
})
|
||||||
|
let param = {}
|
||||||
|
|
||||||
|
// 获取请求参数
|
||||||
|
if (cfg.request) {
|
||||||
|
param = await cfg.request.call(this, api)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
url: param.api || api,
|
||||||
|
param: param.config || {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async response (data, req) {
|
||||||
|
// 处理返回
|
||||||
|
let cfg = this._cfg
|
||||||
|
if (cfg.response) {
|
||||||
|
return await cfg.response.call(this, data, req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getCdTime (data) {
|
||||||
|
const requestInterval = diyCfg.requestInterval || sysCfg.requestInterval || 5
|
||||||
|
let cdTime = requestInterval * 60
|
||||||
|
if (data.ttl) {
|
||||||
|
cdTime = Math.max(cdTime, data.ttl * 1)
|
||||||
|
delete data.ttl
|
||||||
|
}
|
||||||
|
return cdTime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ProfileServ.getServ = function ({ uid, serv }) {
|
||||||
|
console.log(diyCfg)
|
||||||
|
return (diyCfg.getProfileServ || sysCfg.getProfileServ)({ uid, serv, diyCfg })
|
||||||
|
}
|
11
models/index.js
Normal file
11
models/index.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import Character from './Character.js'
|
||||||
|
import Artifact from './Artifact.js'
|
||||||
|
import Avatars from './Avatars.js'
|
||||||
|
import Abyss from './Abyss.js'
|
||||||
|
import ProfileServ from './ProfileServ.js'
|
||||||
|
import ProfileReq from './ProfileReq.js'
|
||||||
|
import ProfileData from './ProfileData.js'
|
||||||
|
import ProfileArtis from './ProfileArtis.js'
|
||||||
|
import ProfileDmg from './ProfileDmg.js'
|
||||||
|
|
||||||
|
export { Abyss, Character, Artifact, Avatars, ProfileServ, ProfileReq, ProfileData, ProfileArtis, ProfileDmg }
|
160
models/profile-lib/ArtisMark.js
Normal file
160
models/profile-lib/ArtisMark.js
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
import lodash from 'lodash'
|
||||||
|
import { Format } from '../../components/index.js'
|
||||||
|
import { attrNameMap, mainAttr, subAttr } from '../../resources/meta/reliquaries/reliquaries-mark-new.js'
|
||||||
|
|
||||||
|
let ArtisMark = {
|
||||||
|
formatAttr (ds) {
|
||||||
|
if (!ds) {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
if (lodash.isArray(ds) && ds[0] && ds[1]) {
|
||||||
|
return {
|
||||||
|
title: ds[0],
|
||||||
|
value: ds[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!ds.value) {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
title: ds.title || ds.name || ds.key || ds.id || '',
|
||||||
|
value: ds.value || ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
formatArti (ds, markCfg = false, isMain = false) {
|
||||||
|
if (ds[0] && ds[0].title) {
|
||||||
|
let ret = []
|
||||||
|
lodash.forEach(ds, (d) => {
|
||||||
|
ret.push(ArtisMark.formatArti(d, markCfg, isMain))
|
||||||
|
})
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
let title = ds.title || ds[0]
|
||||||
|
let key = ''
|
||||||
|
let val = ds.value || ds[1]
|
||||||
|
let num = ds.value || ds[1]
|
||||||
|
if (!title || title === 'undefined') {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
if (/伤害加成/.test(title) && val < 1) {
|
||||||
|
val = Format.pct(val * 100)
|
||||||
|
num = num * 100
|
||||||
|
} else if (/伤害加成|大|暴|充能|治疗/.test(title)) {
|
||||||
|
val = Format.pct(val)
|
||||||
|
} else {
|
||||||
|
val = Format.comma(val, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/元素伤害加成/.test(title)) {
|
||||||
|
title = title.replace('元素伤害', '伤')
|
||||||
|
key = 'dmg'
|
||||||
|
} else if (title === '物理伤害加成') {
|
||||||
|
title = '物伤加成'
|
||||||
|
key = 'phy'
|
||||||
|
}
|
||||||
|
|
||||||
|
key = key || attrNameMap[title]
|
||||||
|
|
||||||
|
let ret = { title, value: val }
|
||||||
|
|
||||||
|
if (markCfg) {
|
||||||
|
let mark = markCfg[key] * num
|
||||||
|
if (isMain) {
|
||||||
|
mark = mark / 4 + 0.01
|
||||||
|
}
|
||||||
|
ret.mark = Format.comma(mark || 0)
|
||||||
|
ret._mark = mark || 0
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
},
|
||||||
|
|
||||||
|
getMarkClass (mark) {
|
||||||
|
let pct = mark
|
||||||
|
let scoreMap = [['D', 10], ['C', 16.5], ['B', 23.1], ['A', 29.7], ['S', 36.3], ['SS', 42.9], ['SSS', 49.5], ['ACE', 56.1], ['ACE²', 66]]
|
||||||
|
for (let idx = 0; idx < scoreMap.length; idx++) {
|
||||||
|
if (pct < scoreMap[idx][1]) {
|
||||||
|
return scoreMap[idx][0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getMark (charCfg, posIdx, mainAttr, subAttr) {
|
||||||
|
let ret = 0
|
||||||
|
let { mark, maxMark, weight } = charCfg
|
||||||
|
let mAttr = ArtisMark.getAttr(mainAttr)
|
||||||
|
|
||||||
|
let fixPct = 1
|
||||||
|
if (posIdx >= 3) {
|
||||||
|
fixPct = Math.max(0, Math.min(1, (weight[mAttr] || 0) / (maxMark['m' + posIdx])))
|
||||||
|
ret += ArtisMark.getAttrMark(mark, mainAttr) / 4
|
||||||
|
}
|
||||||
|
|
||||||
|
lodash.forEach(subAttr, (ds) => {
|
||||||
|
ret += ArtisMark.getAttrMark(mark, ds)
|
||||||
|
})
|
||||||
|
|
||||||
|
return ret * (1 + fixPct) / 2 / maxMark[posIdx] * 66
|
||||||
|
},
|
||||||
|
getAttr (ds) {
|
||||||
|
let title = ds.title || ds[0] || ''
|
||||||
|
let attr = attrNameMap[title]
|
||||||
|
if (/元素伤害/.test(title)) {
|
||||||
|
attr = 'dmg'
|
||||||
|
} else if (/物理|物伤/.test(title)) {
|
||||||
|
attr = 'phy'
|
||||||
|
}
|
||||||
|
return attr
|
||||||
|
},
|
||||||
|
getAttrMark (attrMark, ds) {
|
||||||
|
if (!ds) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
let attr = ArtisMark.getAttr(ds)
|
||||||
|
if (!attr) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
let val = ds.value || ds[1]
|
||||||
|
return (attrMark[attr] || 0) * val
|
||||||
|
},
|
||||||
|
getMaxMark (attrWeight) {
|
||||||
|
let ret = {}
|
||||||
|
for (let idx = 1; idx <= 5; idx++) {
|
||||||
|
let totalMark = 0
|
||||||
|
let mMark = 0
|
||||||
|
let mAttr = ''
|
||||||
|
if (idx === 1) {
|
||||||
|
mAttr = 'hpPlus'
|
||||||
|
} else if (idx === 2) {
|
||||||
|
mAttr = 'atkPlus'
|
||||||
|
} else if (idx >= 3) {
|
||||||
|
mAttr = ArtisMark.getMaxAttr(attrWeight, mainAttr[idx])[0]
|
||||||
|
mMark = attrWeight[mAttr]
|
||||||
|
totalMark += attrWeight[mAttr] * 2
|
||||||
|
}
|
||||||
|
|
||||||
|
let sAttr = ArtisMark.getMaxAttr(attrWeight, subAttr, 4, mAttr)
|
||||||
|
lodash.forEach(sAttr, (attr, aIdx) => {
|
||||||
|
totalMark += attrWeight[attr] * (aIdx === 0 ? 6 : 1)
|
||||||
|
})
|
||||||
|
ret[idx] = totalMark
|
||||||
|
ret['m' + idx] = mMark
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
},
|
||||||
|
getMaxAttr (charAttr = {}, list2 = [], maxLen = 1, banAttr = '') {
|
||||||
|
let tmp = []
|
||||||
|
lodash.forEach(list2, (attr) => {
|
||||||
|
if (attr === banAttr) return
|
||||||
|
if (!charAttr[attr]) return
|
||||||
|
tmp.push({ attr, mark: charAttr[attr] })
|
||||||
|
})
|
||||||
|
tmp = lodash.sortBy(tmp, 'mark')
|
||||||
|
tmp = tmp.reverse()
|
||||||
|
let ret = []
|
||||||
|
lodash.forEach(tmp, (ds) => ret.push(ds.attr))
|
||||||
|
return ret.slice(0, maxLen)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ArtisMark
|
@ -1,10 +1,9 @@
|
|||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import Format from './Format.js'
|
import { Format } from '../../components/index.js'
|
||||||
import { Character } from './models.js'
|
import { Character } from '../index.js'
|
||||||
|
import { eleBaseDmg, eleMap, attrMap } from './calc-meta.js'
|
||||||
import { eleBaseDmg, eleMap, attrMap } from './calc/calc-meta.js'
|
import Mastery from './Mastery.js'
|
||||||
import { Mastery } from './calc/mastery.js'
|
|
||||||
|
|
||||||
let Calc = {
|
let Calc = {
|
||||||
|
|
||||||
@ -45,8 +44,6 @@ let Calc = {
|
|||||||
let ret = {}
|
let ret = {}
|
||||||
let { attr } = profile
|
let { attr } = profile
|
||||||
|
|
||||||
ret.dataSource = profile.dataSource || 'miao'
|
|
||||||
|
|
||||||
// 基础属性
|
// 基础属性
|
||||||
lodash.forEach('atk,def,hp'.split(','), (key) => {
|
lodash.forEach('atk,def,hp'.split(','), (key) => {
|
||||||
ret[key] = {
|
ret[key] = {
|
||||||
@ -56,28 +53,12 @@ let Calc = {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
lodash.forEach('mastery,recharge'.split(','), (key) => {
|
lodash.forEach('mastery,recharge,cpct,cdmg,heal,dmg,phy'.split(','), (key) => {
|
||||||
ret[key] = {
|
ret[key] = {
|
||||||
base: attr[key] * 1 || 0,
|
|
||||||
plus: 0,
|
|
||||||
pct: 0
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
lodash.forEach({ cRate: 'cpct', cDmg: 'cdmg', hInc: 'heal' }, (val, key) => {
|
|
||||||
ret[val] = {
|
|
||||||
base: attr[key] * 1 || 0,
|
base: attr[key] * 1 || 0,
|
||||||
plus: 0,
|
plus: 0,
|
||||||
pct: 0,
|
pct: 0,
|
||||||
inc: 0
|
inc: 0 // 护盾增效&治疗增效
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
lodash.forEach('dmg,phy'.split(','), (key) => {
|
|
||||||
ret[key] = {
|
|
||||||
base: attr[key + 'Bonus'] * 1 || 0,
|
|
||||||
plus: 0,
|
|
||||||
pct: 0
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -136,7 +117,7 @@ let Calc = {
|
|||||||
|
|
||||||
lodash.forEach(['a', 'e', 'q'], (key) => {
|
lodash.forEach(['a', 'e', 'q'], (key) => {
|
||||||
let td = talentData[key] || {}
|
let td = talentData[key] || {}
|
||||||
let lv = td.level || td.level_current * 1 || 1
|
let lv = (td.level || td.level_current || 1) * 1
|
||||||
|
|
||||||
let map = {}
|
let map = {}
|
||||||
|
|
||||||
@ -367,7 +348,7 @@ let Calc = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 防御区
|
// 防御区
|
||||||
let lv = profile.lv
|
let lv = profile.lv || profile.level
|
||||||
let defNum = (lv + 100) / ((lv + 100) + (enemyLv + 100) * (1 - enemyDef) * (1 - enemyIgnore))
|
let defNum = (lv + 100) / ((lv + 100) + (enemyLv + 100) * (1 - enemyDef) * (1 - enemyIgnore))
|
||||||
|
|
||||||
// 抗性区
|
// 抗性区
|
||||||
@ -503,7 +484,7 @@ let Calc = {
|
|||||||
if (detail.check && !detail.check(Calc.getDs(attr, meta, params))) {
|
if (detail.check && !detail.check(Calc.getDs(attr, meta, params))) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (detail.cons && meta.cons * 1 < detail.cons * 1) {
|
if (detail.cons && meta.cons < detail.cons * 1) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let ds = lodash.merge({ talent }, Calc.getDs(attr, meta, params))
|
let ds = lodash.merge({ talent }, Calc.getDs(attr, meta, params))
|
@ -1,6 +1,6 @@
|
|||||||
import { erType } from './calc-meta.js'
|
import { erType } from './calc-meta.js'
|
||||||
|
|
||||||
export const Mastery = {
|
let Mastery = {
|
||||||
|
|
||||||
getType () {
|
getType () {
|
||||||
|
|
||||||
@ -22,3 +22,4 @@ export const Mastery = {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
export default Mastery
|
2
models/profile-lib/ProfileInput.js
Normal file
2
models/profile-lib/ProfileInput.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
let ProfileInput = {}
|
||||||
|
export default ProfileInput
|
@ -21,7 +21,7 @@
|
|||||||
<div class="cont">
|
<div class="cont">
|
||||||
<div class="item arti-stat">
|
<div class="item arti-stat">
|
||||||
<div><strong class="mark-{{totalMarkClass}}">{{totalMarkClass}}</strong><span>圣遗物评级</span></div>
|
<div><strong class="mark-{{totalMarkClass}}">{{totalMarkClass}}</strong><span>圣遗物评级</span></div>
|
||||||
<div><strong>{{(totalMark).toFixed(1)}}</strong><span>圣遗物总分</span></div>
|
<div><strong>{{totalMark}}</strong><span>圣遗物总分</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -29,13 +29,13 @@
|
|||||||
|
|
||||||
|
|
||||||
<div class="artis">
|
<div class="artis">
|
||||||
<% for(let idx = 0; idx<5; idx++) {
|
<% for(let idx = 1; idx<=5; idx++) {
|
||||||
let ds = artis[idx]
|
let ds = artis[idx]
|
||||||
%>
|
%>
|
||||||
{{if idx === 0 }}
|
{{if idx === 1 }}
|
||||||
<div class="item no-bg"></div>
|
<div class="item no-bg"></div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<div class="item arti">
|
<div class="item arti {{idx}}">
|
||||||
{{if ds && ds.name && ds.main && ds.main.title && ds.main.title!="undefined"}}
|
{{if ds && ds.name && ds.main && ds.main.title && ds.main.title!="undefined"}}
|
||||||
<div class="arti-icon">
|
<div class="arti-icon">
|
||||||
<img src="{{_res_path}}/meta/reliquaries/icon/{{ds.name}}.png"/>
|
<img src="{{_res_path}}/meta/reliquaries/icon/{{ds.name}}.png"/>
|
||||||
@ -48,7 +48,7 @@
|
|||||||
<ul class="detail attr">
|
<ul class="detail attr">
|
||||||
<li class="arti-main">
|
<li class="arti-main">
|
||||||
<span class="title">{{ds.main.title}}</span>
|
<span class="title">{{ds.main.title}}</span>
|
||||||
<span class="val">+{{ds.main.val}}</span>
|
<span class="val">+{{ds.main.value}}</span>
|
||||||
{{if idx >1 }}
|
{{if idx >1 }}
|
||||||
<span class="mark">{{ mark( ds.main.mark / 6 ) }}</span>
|
<span class="mark">{{ mark( ds.main.mark / 6 ) }}</span>
|
||||||
{{else}}
|
{{else}}
|
||||||
@ -59,8 +59,8 @@
|
|||||||
{{if attr.title}}
|
{{if attr.title}}
|
||||||
<li class="{{usefulMark[attr.title]*1 > 79.9 ?`great`:(usefulMark[attr.title]*1>0 ? `useful`:`nouse`)}}"><span
|
<li class="{{usefulMark[attr.title]*1 > 79.9 ?`great`:(usefulMark[attr.title]*1>0 ? `useful`:`nouse`)}}"><span
|
||||||
class="title">{{attr.title}} </span><span
|
class="title">{{attr.title}} </span><span
|
||||||
class="val">+{{attr.val}}</span>
|
class="val">+{{attr.value}}</span>
|
||||||
<span class="mark">{{ ( 46.6 / 6 / 100 * attr.mark ).toFixed(1) }}</span>
|
<span class="mark">{{ ( 46.6 / 6 / 100 * attr._mark ).toFixed(1) }}</span>
|
||||||
</li>
|
</li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
@ -24,12 +24,12 @@
|
|||||||
<span class="mark mark-{{ds.markClass}}"><span>{{ds.mark}}分</span> - {{ds.markClass}}</span>
|
<span class="mark mark-{{ds.markClass}}"><span>{{ds.mark}}分</span> - {{ds.markClass}}</span>
|
||||||
</div>
|
</div>
|
||||||
<ul class="detail attr">
|
<ul class="detail attr">
|
||||||
<li class="arti-main"><span class="title">{{ds.main.title}}</span><span class="val">+{{ds.main.val}}</span></li>
|
<li class="arti-main"><span class="title">{{ds.main.title}}</span><span class="val">+{{ds.main.value}}</span></li>
|
||||||
{{each ds.attrs attr}}
|
{{each ds.attrs attr}}
|
||||||
{{if attr.title}}
|
{{if attr.title}}
|
||||||
<li class="{{ds.usefulMark[attr.title]*1 > 79.9 ?`great`:(ds.usefulMark[attr.title]*1>0 ? `useful`:`nouse`)}}">
|
<li class="{{ds.usefulMark[attr.title]*1 > 79.9 ?`great`:(ds.usefulMark[attr.title]*1>0 ? `useful`:`nouse`)}}">
|
||||||
<span class="title">{{attr.title}}</span><span
|
<span class="title">{{attr.title}}</span><span
|
||||||
class="val">+{{attr.val}}</span></li>
|
class="val">+{{attr.value}}</span></li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -34,10 +34,10 @@
|
|||||||
<li><i class="i-atk"></i>攻击力<strong>{{attr.atk}}</strong><span>(+{{attr.atkPlus}})</span></li>
|
<li><i class="i-atk"></i>攻击力<strong>{{attr.atk}}</strong><span>(+{{attr.atkPlus}})</span></li>
|
||||||
<li><i class="i-def"></i>防御力<strong>{{attr.def}}</strong><span>(+{{attr.defPlus}})</span></li>
|
<li><i class="i-def"></i>防御力<strong>{{attr.def}}</strong><span>(+{{attr.defPlus}})</span></li>
|
||||||
<li><i class="i-mastery"></i>元素精通<strong>{{attr.mastery}}</strong></li>
|
<li><i class="i-mastery"></i>元素精通<strong>{{attr.mastery}}</strong></li>
|
||||||
<li><i class="i-cr"></i>暴击率<strong>{{attr.cRate}}</strong></li>
|
<li><i class="i-cr"></i>暴击率<strong>{{attr.cpct}}</strong></li>
|
||||||
<li><i class="i-cd"></i>暴击伤害<strong>{{attr.cDmg}}</strong></li>
|
<li><i class="i-cd"></i>暴击伤害<strong>{{attr.cdmg}}</strong></li>
|
||||||
<li><i class="i-re"></i>元素充能<strong>{{attr.recharge}}</strong></li>
|
<li><i class="i-re"></i>元素充能<strong>{{attr.recharge}}</strong></li>
|
||||||
<li><i class="i-dmg"></i>伤害加成<strong>{{attr.dmgBonus}}</strong></li>
|
<li><i class="i-dmg"></i>伤害加成<strong>{{attr.dmg}}</strong></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="char-cons">
|
<div class="char-cons">
|
||||||
@ -69,7 +69,7 @@
|
|||||||
<div><strong>{{totalMark}}</strong><span>圣遗物总分</span></div>
|
<div><strong>{{totalMark}}</strong><span>圣遗物总分</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{each artis ds}}
|
{{each artis ds idx}}
|
||||||
<div class="item arti">
|
<div class="item arti">
|
||||||
{{if ds && ds.name && ds.main && ds.main.title && ds.main.title!="undefined"}}
|
{{if ds && ds.name && ds.main && ds.main.title && ds.main.title!="undefined"}}
|
||||||
<div class="arti-icon">
|
<div class="arti-icon">
|
||||||
@ -81,12 +81,12 @@
|
|||||||
<span class="mark mark-{{ds.markClass}}"><span>{{ds.mark}}分</span> - {{ds.markClass}}</span>
|
<span class="mark mark-{{ds.markClass}}"><span>{{ds.mark}}分</span> - {{ds.markClass}}</span>
|
||||||
</div>
|
</div>
|
||||||
<ul class="detail attr">
|
<ul class="detail attr">
|
||||||
<li class="arti-main"><span class="title">{{ds.main.title}}</span><span class="val">+{{ds.main.val}}</span></li>
|
<li class="arti-main"><span class="title">{{ds.main.title}}</span><span class="val">+{{ds.main.value}}</span></li>
|
||||||
{{each ds.attrs attr}}
|
{{each ds.attrs attr}}
|
||||||
{{if attr.title}}
|
{{if attr.title}}
|
||||||
<li class="{{usefulMark[attr.title]*1 > 79.9 ?`great`:(usefulMark[attr.title]*1>0 ? `useful`:`nouse`)}}"><span
|
<li class="{{usefulMark[attr.title]*1 > 79.9 ?`great`:(usefulMark[attr.title]*1>0 ? `useful`:`nouse`)}}"><span
|
||||||
class="title">{{attr.title}} </span><span
|
class="title">{{attr.title}} </span><span
|
||||||
class="val">+{{attr.val}}</span></li>
|
class="val">+{{attr.value}}</span></li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -329,4 +329,4 @@
|
|||||||
text-align: right;
|
text-align: right;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
}
|
}
|
||||||
/*# sourceMappingURL=profile-stat.css.map */
|
/*# sourceMappingURL=profile-lib-stat.css.map */
|
@ -67,9 +67,9 @@
|
|||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
<div class="td-artis">
|
<div class="td-artis">
|
||||||
<div class="item item-banner avatar-artis artis{{avatar?.artisMark?.sets?.length||avatar.sets.length}}">
|
<div class="item item-banner avatar-artis artis{{avatar?.artisMark?.names?.length||avatar.names.length}}">
|
||||||
<div class="artis item-icon">
|
<div class="artis item-icon">
|
||||||
{{each avatar?.artisMark?.sets || avatar?.sets || [] name}}
|
{{each avatar?.artisMark?.names || avatar?.names || [] name}}
|
||||||
<span class="img"
|
<span class="img"
|
||||||
style="background-image:url({{_res_path}}/meta/reliquaries/icon/{{name}}.png)"></span>
|
style="background-image:url({{_res_path}}/meta/reliquaries/icon/{{name}}.png)"></span>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
@ -30,9 +30,9 @@
|
|||||||
<span class="cons cons-{{weapon.affix}}">{{weapon.affix}}</span>
|
<span class="cons cons-{{weapon.affix}}">{{weapon.affix}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="item avatar-artis artis{{avatar.sets.length}}">
|
<div class="item avatar-artis artis{{avatar.names.length}}">
|
||||||
<div class="artis item-icon">
|
<div class="artis item-icon">
|
||||||
{{each avatar.sets name}}
|
{{each avatar.names name}}
|
||||||
<span class="img"
|
<span class="img"
|
||||||
style="background-image:url({{_res_path}}/meta/reliquaries/icon/{{name}}.png)"></span>
|
style="background-image:url({{_res_path}}/meta/reliquaries/icon/{{name}}.png)"></span>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
@ -17,10 +17,9 @@ export const details = [{
|
|||||||
export const mainAttr = 'atk,hp,cpct,recharge'
|
export const mainAttr = 'atk,hp,cpct,recharge'
|
||||||
|
|
||||||
export const buffs = [{
|
export const buffs = [{
|
||||||
title: '莫娜被动:基于元素充能效率获得水元素伤害[_dmg]%',
|
title: '莫娜被动:基于元素充能效率获得水元素伤害[dmg]%',
|
||||||
data: {
|
data: {
|
||||||
_dmg: ({ calc, attr }) => calc(attr.recharge) * 0.2,
|
dmg: ({ calc, attr }) => calc(attr.recharge) * 0.2
|
||||||
dmg: ({ calc, attr }) => attr.dataSource === 'shin' ? 0 : calc(attr.recharge) * 0.2
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
title: '莫娜1命:命中星异状态下的敌人水元素相关反应效果提升15%',
|
title: '莫娜1命:命中星异状态下的敌人水元素相关反应效果提升15%',
|
||||||
|
@ -47,10 +47,8 @@ export const buffs = [
|
|||||||
qIgnore: 60
|
qIgnore: 60
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
title: '雷神被动:基于元素充能获得[_dmg]%雷伤加成',
|
title: '雷神被动:基于元素充能获得[dmg]%雷伤加成',
|
||||||
data: {
|
data: {
|
||||||
_dmg: ({ attr }) => Math.max(attr.recharge.base + attr.recharge.plus - 100, 0) * 0.4,
|
dmg: ({ attr }) => Math.max(attr.recharge.base + attr.recharge.plus - 100, 0) * 0.4
|
||||||
dmg: ({ attr }) =>
|
|
||||||
attr.dataSource === 'shin' ? 0 : Math.max(attr.recharge.base + attr.recharge.plus - 100, 0) * 0.4
|
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
|
@ -40,7 +40,7 @@ lodash.forEach(readDir, (c) => {
|
|||||||
// 正面
|
// 正面
|
||||||
|
|
||||||
// 角色条
|
// 角色条
|
||||||
img(char, char.imgs.profile, "profile-data.png");
|
img(char, char.imgs.profile, "profile.png");
|
||||||
// 名片
|
// 名片
|
||||||
img(char, char.imgs.party, "party.png");
|
img(char, char.imgs.party, "party.png");
|
||||||
// img(char, char.imgs.char, "char.png");
|
// img(char, char.imgs.char, "char.png");
|
||||||
|
@ -1,148 +1,146 @@
|
|||||||
import Data from "../components/Data.js";
|
import lodash from 'lodash'
|
||||||
import lodash from "lodash";
|
import { Character } from '../models/index.js'
|
||||||
import { Character } from "../components/models.js";
|
import { Data } from '../components/index.js'
|
||||||
import fs from "fs";
|
import fs from 'fs'
|
||||||
|
|
||||||
import { roleId, abbr } from "../../../config/genshin/roleId.js";
|
import { roleId, abbr } from '../../../config/genshin/roleId.js'
|
||||||
|
|
||||||
let roleIdMap = {};
|
let roleIdMap = {}
|
||||||
lodash.forEach(roleId, (names, id) => {
|
lodash.forEach(roleId, (names, id) => {
|
||||||
roleIdMap[names[0]] = id;
|
roleIdMap[names[0]] = id
|
||||||
})
|
})
|
||||||
|
|
||||||
let _root = process.cwd();
|
let _root = process.cwd()
|
||||||
let characterMeta = [];//Data.readJSON("./plugins/miao-plugin/components/meta", "characters.json");
|
let characterMeta = []// Data.readJSON("./plugins/miao-plugin/components/meta", "characters.json");
|
||||||
let characters = {};
|
let characters = {}
|
||||||
let pathName = process.cwd() + "/plugins/miao-plugin/resources/meta/character/";
|
let pathName = process.cwd() + '/plugins/miao-plugin/resources/meta/character/'
|
||||||
|
|
||||||
// 获取指定角色的Meta信息
|
// 获取指定角色的Meta信息
|
||||||
const getMetaData = function (name) {
|
const getMetaData = function (name) {
|
||||||
if (!characterMeta[name]) {
|
if (!characterMeta[name]) {
|
||||||
return {};
|
return {}
|
||||||
}
|
}
|
||||||
const metaCfg = { lowerFirstKey: true },
|
const metaCfg = { lowerFirstKey: true }
|
||||||
meta = characterMeta[name];
|
const meta = characterMeta[name]
|
||||||
|
|
||||||
// 处理基础信息
|
// 处理基础信息
|
||||||
let ret = Data.getData(meta, "Name,Key,Title,desc:Description,astro:AstrolabeName", metaCfg);
|
let ret = Data.getData(meta, 'Name,Key,Title,desc:Description,astro:AstrolabeName', metaCfg)
|
||||||
|
|
||||||
ret.star = /4star/.test(meta.Star) ? 4 : 5;
|
ret.star = /4star/.test(meta.Star) ? 4 : 5
|
||||||
|
|
||||||
let weaponid = /s_(\d*).png$/.exec(meta.Weapon);
|
let weaponid = /s_(\d*).png$/.exec(meta.Weapon)
|
||||||
if (weaponid) {
|
if (weaponid) {
|
||||||
ret.weapon = {
|
ret.weapon = {
|
||||||
233101: "长柄武器",
|
233101: '长柄武器',
|
||||||
33101: "单手剑",
|
33101: '单手剑',
|
||||||
43101: "法器",
|
43101: '法器',
|
||||||
163101: "双手剑",
|
163101: '双手剑',
|
||||||
213101: "弓"
|
213101: '弓'
|
||||||
}[weaponid[1]]
|
}[weaponid[1]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 处理图像信息
|
// 处理图像信息
|
||||||
//ret.img = Data.getData(meta, "Weapon,Element,City,Profile,GachaCard,GachaSplash,Source", metaCfg);
|
// ret.img = Data.getData(meta, "Weapon,Element,City,Profile,GachaCard,GachaSplash,Source", metaCfg);
|
||||||
|
|
||||||
// 处理元素
|
// 处理元素
|
||||||
let elemRet = /([^\/]*).png$/.exec(meta.Element);
|
let elemRet = /([^\/]*).png$/.exec(meta.Element)
|
||||||
console.log(elemRet[1]);
|
console.log(elemRet[1])
|
||||||
if (elemRet && elemRet[1]) {
|
if (elemRet && elemRet[1]) {
|
||||||
ret.elem = elemRet[1];
|
ret.elem = elemRet[1]
|
||||||
ret.element = elemName[ret.elem];
|
ret.element = elemName[ret.elem]
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理属性
|
// 处理属性
|
||||||
ret.stat = Data.getData(meta, "hp:BaseHP,atk:BaseATK,def:BaseDEF,growStat:AscensionStat,growValue:AscensionStatValue", metaCfg);
|
ret.stat = Data.getData(meta, 'hp:BaseHP,atk:BaseATK,def:BaseDEF,growStat:AscensionStat,growValue:AscensionStatValue', metaCfg)
|
||||||
ret.lvStat = lodash.map(meta.CharStat, (d) => Data.getData(d, "Name,Values", metaCfg));
|
ret.lvStat = lodash.map(meta.CharStat, (d) => Data.getData(d, 'Name,Values', metaCfg))
|
||||||
|
|
||||||
if (/Mende/.test(meta.City)) {
|
if (/Mende/.test(meta.City)) {
|
||||||
ret.city = "蒙德"
|
ret.city = '蒙德'
|
||||||
} else if (/Liyue/.test(meta.City)) {
|
} else if (/Liyue/.test(meta.City)) {
|
||||||
ret.city = "璃月";
|
ret.city = '璃月'
|
||||||
} else if (/Daoqi/.test(meta.City)) {
|
} else if (/Daoqi/.test(meta.City)) {
|
||||||
ret.city = "稻妻";
|
ret.city = '稻妻'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理材料
|
// 处理材料
|
||||||
let itemKey = lodash.map("talent,boss,gemStone,Local,monster,weekly".split(","), (a) => `${a}:${lodash.upperFirst(a)}.Name`);
|
let itemKey = lodash.map('talent,boss,gemStone,Local,monster,weekly'.split(','), (a) => `${a}:${lodash.upperFirst(a)}.Name`)
|
||||||
ret.item = Data.getData(meta, itemKey, metaCfg)
|
ret.item = Data.getData(meta, itemKey, metaCfg)
|
||||||
|
|
||||||
// 处理天赋
|
// 处理天赋
|
||||||
ret.talent = {
|
ret.talent = {
|
||||||
a: getTalentData(meta.NormalAttack),
|
a: getTalentData(meta.NormalAttack),
|
||||||
e: getTalentData(meta.TalentE),
|
e: getTalentData(meta.TalentE),
|
||||||
q: getTalentData(meta.TalentQ),
|
q: getTalentData(meta.TalentQ)
|
||||||
};
|
}
|
||||||
|
|
||||||
// 处理其他天赋
|
// 处理其他天赋
|
||||||
ret.passive = lodash.map(meta.PassiveTalents, (d) => Data.getData(d, "Name,desc:Description", metaCfg))
|
ret.passive = lodash.map(meta.PassiveTalents, (d) => Data.getData(d, 'Name,desc:Description', metaCfg))
|
||||||
|
|
||||||
// 处理命座信息
|
// 处理命座信息
|
||||||
let cons = {};
|
let cons = {}
|
||||||
lodash.forEach(meta.Constellation, (data, key) => {
|
lodash.forEach(meta.Constellation, (data, key) => {
|
||||||
cons[key.replace("Constellation", "")] = Data.getData(data, "Name,desc:Description", metaCfg);
|
cons[key.replace('Constellation', '')] = Data.getData(data, 'Name,desc:Description', metaCfg)
|
||||||
})
|
})
|
||||||
ret.cons = cons;
|
ret.cons = cons
|
||||||
return ret;
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取Meta中的天赋信息
|
// 获取Meta中的天赋信息
|
||||||
const getTalentData = function (data) {
|
const getTalentData = function (data) {
|
||||||
let ret = Data.getData(data, "Name,desc:Description", { lowerFirstKey: true });
|
let ret = Data.getData(data, 'Name,desc:Description', { lowerFirstKey: true })
|
||||||
let attr = [], table = [], tableKeys;
|
let attr = []; let table = []; let tableKeys
|
||||||
|
|
||||||
lodash.forEach(data.Table, (tr) => {
|
lodash.forEach(data.Table, (tr) => {
|
||||||
let tmp = { name: tr.Name }, isTable = true, isDef = false, lastVal;
|
let tmp = { name: tr.Name }; let isTable = true; let isDef = false; let lastVal
|
||||||
|
|
||||||
// 检查当前行是否是表格数据
|
// 检查当前行是否是表格数据
|
||||||
lodash.forEach(tr.Values, (v) => {
|
lodash.forEach(tr.Values, (v) => {
|
||||||
// 如果为空则退出循环
|
// 如果为空则退出循环
|
||||||
if (v === "") {
|
if (v === '') {
|
||||||
isTable = false;
|
isTable = false
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof (lastVal) === "undefined") {
|
if (typeof (lastVal) === 'undefined') {
|
||||||
// 设定初始值
|
// 设定初始值
|
||||||
lastVal = v;
|
lastVal = v
|
||||||
} else if (lastVal != v) {
|
} else if (lastVal != v) {
|
||||||
// 如果与初始值不一样,则标记退出循环
|
// 如果与初始值不一样,则标记退出循环
|
||||||
isDef = true;
|
isDef = true
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
if (isTable && isDef) {
|
if (isTable && isDef) {
|
||||||
if (!tableKeys) {
|
if (!tableKeys) {
|
||||||
tableKeys = lodash.keys(tr.Values);
|
tableKeys = lodash.keys(tr.Values)
|
||||||
}
|
}
|
||||||
tmp.value = lodash.map(tableKeys, (k) => tr.Values[k])
|
tmp.value = lodash.map(tableKeys, (k) => tr.Values[k])
|
||||||
table.push(tmp);
|
table.push(tmp)
|
||||||
} else {
|
} else {
|
||||||
tmp.value = lastVal;
|
tmp.value = lastVal
|
||||||
attr.push(tmp)
|
attr.push(tmp)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
ret.attr = attr;
|
ret.attr = attr
|
||||||
ret.table = table;
|
ret.table = table
|
||||||
ret.tableKeys = tableKeys;
|
ret.tableKeys = tableKeys
|
||||||
return ret;
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
lodash.forEach(characterMeta, (c) => {
|
lodash.forEach(characterMeta, (c) => {
|
||||||
let meta = Character.getMetaData(c.Name);
|
let meta = Character.getMetaData(c.Name)
|
||||||
let data = {
|
let data = {
|
||||||
id: roleIdMap[meta.name],
|
id: roleIdMap[meta.name],
|
||||||
key: meta.key,
|
key: meta.key,
|
||||||
name: meta.name,
|
name: meta.name,
|
||||||
abbr: abbr[meta.name] || meta.name,
|
abbr: abbr[meta.name] || meta.name,
|
||||||
city: meta.city
|
city: meta.city
|
||||||
};
|
}
|
||||||
lodash.defaults(data, meta)
|
lodash.defaults(data, meta)
|
||||||
Data.createDir(pathName, data.name)
|
Data.createDir(pathName, data.name)
|
||||||
fs.writeFileSync(`${pathName}${data.name}/data.json`, JSON.stringify(data, "", "\t"));
|
fs.writeFileSync(`${pathName}${data.name}/data.json`, JSON.stringify(data, '', '\t'))
|
||||||
characters[data.id] = { id: data.id, key: data.key, name: meta.name };
|
characters[data.id] = { id: data.id, key: data.key, name: meta.name }
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
fs.writeFileSync(`${pathName}index.json`, JSON.stringify(characters, "", "\t"));
|
fs.writeFileSync(`${pathName}index.json`, JSON.stringify(characters, '', '\t'))
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import Profile from '../components/Profile.js'
|
import Calc from '../models/profile-lib/Calc.js'
|
||||||
import Calc from '../components/Calc.js'
|
import { Character } from '../models/index.js'
|
||||||
import { Character } from '../components/models.js'
|
|
||||||
import Miao from '../components/profile-data/miao.js'
|
import Miao from '../components/profile-data/miao.js'
|
||||||
|
|
||||||
export async function calcDmg (inputData, enemyLv = 86) {
|
export async function calcDmg (inputData, enemyLv = 86) {
|
||||||
|
@ -27,7 +27,7 @@ lodash.forEach(readDir, (c) => {
|
|||||||
// 正面
|
// 正面
|
||||||
|
|
||||||
// 角色条
|
// 角色条
|
||||||
img(char, char.imgs.profile, "profile-data.png");
|
img(char, char.imgs.profile, "profile.png");
|
||||||
// 名片
|
// 名片
|
||||||
img(char, char.imgs.party, "party.png");
|
img(char, char.imgs.party, "party.png");
|
||||||
// img(char, char.imgs.char, "char.png");
|
// img(char, char.imgs.char, "char.png");
|
||||||
|
Loading…
Reference in New Issue
Block a user