面板数据结构变更

This commit is contained in:
Kokomi 2023-02-10 00:57:25 +08:00
parent cf5b2253ba
commit a76b7d98a9
24 changed files with 379 additions and 1127 deletions

View File

@ -1,4 +1,4 @@
import { Character, Avatar, MysApi, Player } from '../../models/index.js'
import { Character, MysApi, Player } from '../../models/index.js'
import { Cfg, Common } from '../../components/index.js'
import lodash from 'lodash'
import { segment } from 'oicq'
@ -6,7 +6,6 @@ import moment from 'moment'
export async function renderAvatar (e, avatar, renderType = 'card') {
// 如果传递的是名字,则获取
let uid = e.uid
if (typeof (avatar) === 'string') {
// 检查角色
let char = Character.get(avatar)
@ -15,7 +14,6 @@ export async function renderAvatar (e, avatar, renderType = 'card') {
}
let mys = await MysApi.init(e)
if (!mys) return true
uid = mys.uid
if (!char.isRelease) {
avatar = { id: char.id, name: char.name, detail: false }
} else {

View File

@ -10,7 +10,7 @@ import { Character, MysApi, Player } from '../../models/index.js'
/*
* 获取面板查询的 目标uid
* */
export async function getTargetUid (e) {
const _getTargetUid = async function (e) {
let uidReg = /[1-9][0-9]{8}/
if (e.uid && uidReg.test(e.uid)) {
@ -67,6 +67,14 @@ export async function getTargetUid (e) {
return uid || false
}
export async function getTargetUid (e) {
let uid = await _getTargetUid(e)
if (uid) {
e.uid = uid
}
return uid
}
/*
* 自动更新面板数据
* */
@ -87,8 +95,8 @@ export async function autoRefresh (e) {
e.isRefreshed = true
// 数据更新
let player = Player.create(uid)
let data = await player.refreshProfile(e)
let player = Player.create(e)
let data = await player.refreshProfile()
if (!data) {
return false
}
@ -128,7 +136,8 @@ export async function autoGetProfile (e, uid, avatar, callback) {
return { err: true }
}
let profile = Player.getAvatar(uid, char.id)
let player = Player.create(e)
let profile = player.getProfile(char.id)
if (!profile || !profile.hasData) {
if (await refresh()) {
return { err: true }
@ -136,13 +145,7 @@ export async function autoGetProfile (e, uid, avatar, callback) {
e.reply(`请确认${char.name}已展示在【游戏内】的角色展柜中,并打开了“显示角色详情”。然后请使用 #更新面板\n命令来获取${char.name}的面板详情`)
}
return { err: true }
} else if (!['enka', 'miao'].includes(profile.dataSource)) {
if (!await refresh()) {
e.reply('缓存数据错误,请重新获取面板信息后查看')
}
return { err: true }
}
return { profile, char, refresh }
}
@ -156,8 +159,8 @@ export async function getProfile (e) {
}
// 数据更新
let player = Player.create(uid)
let ret = await player.refreshProfile(e)
let player = Player.create(e)
let ret = await player.refreshProfile()
if (!ret) {
return true
}

View File

@ -1,7 +1,7 @@
import lodash from 'lodash'
import { autoRefresh } from './ProfileCommon.js'
import { Common, Format } from '../../components/index.js'
import { MysApi, Avatar, ProfileRank, ProfileArtis, Player } from '../../models/index.js'
import { MysApi, ProfileRank, ProfileArtis, Player } from '../../models/index.js'
export async function renderProfile (e, char, mode = 'profile', params = {}) {
let selfUser = await MysApi.initUser(e)
@ -19,7 +19,8 @@ export async function renderProfile (e, char, mode = 'profile', params = {}) {
}
let player = Player.create(uid)
let profile = e._profile || player.getProfile(char.id)
let avatar = player.getAvatar(char.id)
let profile = e._profile || avatar.getProfile(char.id)
let refresh = async () => {
let refreshRet = await autoRefresh(e)
@ -37,7 +38,6 @@ export async function renderProfile (e, char, mode = 'profile', params = {}) {
}
return true
}
let avatar = new Avatar(profile)
char = profile.char || char
let a = profile.attr
let c = Format.comma

View File

@ -47,7 +47,6 @@ export async function profileList (e) {
let char = profile.char
let tmp = char.getData('id,face,name,abbr,element,star')
tmp.face = char.getImgs(profile.costume).face
tmp.source = profile.dataSource
tmp.level = profile.level || 1
tmp.cons = profile.cons
tmp.isNew = 0

View File

@ -1,4 +1,4 @@
import { Character, ProfileRank, ProfileDmg, Avatar, Player } from '../../models/index.js'
import { Character, ProfileRank, ProfileDmg, Player } from '../../models/index.js'
import { renderProfile } from './ProfileDetail.js'
import { Data, Common, Format } from '../../components/index.js'
import lodash from 'lodash'

View File

@ -1,210 +0,0 @@
/*
* 用户角色封装
* 兼容处理面板 Profile Data Mys Avatar 数据
* */
import Base from './Base.js'
import lodash from 'lodash'
import { Artifact, Character, Weapon, ArtifactSet, Player } from './index.js'
import moment from 'moment'
const charKey = 'name,abbr,sName,star,imgs,face,side,gacha,weaponTypeName,elem'.split(',')
export default class Avatar extends Base {
constructor (data = {}, pd = false, hasCk = true) {
super()
if (!data.name) {
return false
}
let char = Character.get(data.name)
if (!char || char.isCustom) {
return false
}
this.meta = data
this.char = char
let isProfile = data.isProfile
this.dataType = isProfile ? 'profile' : 'avatar'
this.hasCk = hasCk
let profile
let uid
if (isProfile) {
profile = data
} else if (pd) {
if (pd.isProfile) {
profile = pd
} else if (/\d{9}/.test(pd)) {
uid = pd
profile = Player.getAvatar(pd, char.id, true)
}
}
if (profile && profile.isProfile && profile.hasData) {
this.profile = profile
}
this.elem = ((profile && profile.elem) || data.element || data.elem || char.elem || 'anemo').toLowerCase()
if (char.isTraveler) {
this.char = Character.get({ id: data.id || char.id, elem: this.elem })
uid && char.setTraveler(uid)
}
}
_get (key) {
if (charKey.includes(key)) {
return this.char[key]
}
return this.meta[key]
}
get dataSourceName () {
if (!this.hasCk && this.profile) {
return this.profile.dataSourceName
}
return this.meta.dataSourceName || '米游社'
}
get updateTime () {
if ((!this.hasCk || this.isProfile) && this.profile) {
return this.profile.updateTime
}
return moment(new Date()).format('MM-DD HH:mm')
}
get isProfile () {
return this.dataType === 'profile'
}
get isAvatar () {
return this.dataType === 'avatar'
}
get artis () {
let ret = {}
if (!this.isProfile) {
lodash.forEach(this.meta.reliquaries, (ds) => {
let arti = Artifact.get(ds.name)
ret[arti.idx] = {
name: arti.name,
set: arti.setName,
img: arti.img,
level: ds.level
}
})
return ret
}
if (this.profile && this.profile?.artis) {
return this.profile.artis.getArtisData()
}
return false
}
get cons () {
let data = this.meta
let profile = this.profile
return data?.cons || data?.actived_constellation_num || profile?.cons || 0
}
get weapon () {
let wd = this.meta?.weapon || this.profile?.weapon
if (!wd || !wd.name) {
return {}
}
let weapon = Weapon.get(wd.name)
return {
name: wd.name,
abbr: weapon.abbr,
star: weapon.star,
level: wd.level || 1,
affix: wd.affix || wd.affix_level || 0,
type: weapon.type,
img: weapon.img
}
}
async getTalent (mys) {
if (!this.isProfile && mys && mys.isSelfCookie) {
let char = this.char
let id = char.id
let talent = {}
let talentRes = await mys.getDetail(id)
// { data: null, message: '请先登录', retcode: -100, api: 'detail' }
let avatar = this.meta
if (!char || !avatar) {
return false
}
if (talentRes && talentRes.skill_list) {
let talentList = lodash.orderBy(talentRes.skill_list, ['id'], ['asc'])
for (let val of talentList) {
let { max_level: maxLv, level_current: lv } = val
if (val.name.includes('普通攻击')) {
talent.a = lv
continue
}
if (maxLv >= 10 && !talent.e) {
talent.e = lv
continue
}
if (maxLv >= 10 && !talent.q) {
talent.q = lv
continue
}
}
}
let ret = char.getAvatarTalent(talent, this.cons, 'original')
if (ret) {
ret.id = id
}
return ret
}
if (this.profile) {
let profile = this.profile
let talent = profile.talent
talent.id = profile.id
return talent
}
return false
}
get artisSet () {
if (this._artisSet) {
return this._artisSet
}
this._artisSet = false
if (!this.isProfile) {
let artis = this.artis
let setCount = {}
lodash.forEach(artis, (arti, idx) => {
let set = arti?.set
if (set) {
setCount[set] = (setCount[set] || 0) + 1
}
})
let sets = {}
let names = []
let abbrs = []
let abbrs2 = []
let imgs = []
for (let set in setCount) {
if (setCount[set] >= 2) {
let value = setCount[set] >= 4 ? 4 : 2
sets[set] = value
let artiSet = ArtifactSet.get(set)
names.push(artiSet.name)
abbrs.push(artiSet.abbr + value)
abbrs2.push(artiSet.name + value)
imgs.push(artiSet.img)
}
}
this._artisSet = {
sets,
names,
abbrs: [...abbrs, ...abbrs2],
imgs,
name: (abbrs.length > 1 || abbrs2[0]?.length > 7) ? abbrs.join('+') : abbrs2[0],
sName: abbrs.join('+')
}
}
if (this.profile) {
let profile = this.profile
this._artisSet = profile.artis ? profile.artis.getSetData() : false
}
return this._artisSet || {}
}
}

View File

@ -27,7 +27,7 @@ export default class AvatarArtis extends Base {
return ret
}
setArtisData (ds = {}, dataSource) {
setArtisData (ds = {}, source) {
if (!this.hasArtis || AvatarArtis.isProfileArtis(ds) || !AvatarArtis.isProfileArtis(this.artis)) {
for (let idx = 1; idx <= 5; idx++) {
if (ds[idx]) {
@ -204,7 +204,7 @@ export default class AvatarArtis extends Base {
* name: '组合名字' 若为4件套会使用套装完整名
* sName: '简写名字'若为4件套也会使用简写
*/
geSetData () {
getSetData () {
let setCount = {}
this.forEach((arti, idx) => {
setCount[arti.set] = (setCount[arti.set] || 0) + 1

View File

@ -8,19 +8,23 @@ import AttrCalc from './profile-lib/AttrCalc.js'
const charKey = 'name,abbr,sName,star,imgs,face,side,gacha,weaponTypeName'.split(',')
export default class AvatarData extends Base {
constructor (ds = {}, dataSource) {
constructor (ds = {}, source) {
super()
let char = Character.get({ id: ds.id, elem: ds.elem })
if (!char) {
return false
return
}
this.id = char.id
this.char = char
this.artis = new AvatarArtis(this.id)
this.setAvatar(ds, dataSource)
this.initArtis()
this.setAvatar(ds, source)
}
static create (ds, dataSource) {
initArtis () {
this.artis = new AvatarArtis(this.id)
}
static create (ds, source) {
let avatar = new AvatarData(ds)
if (!avatar) {
return false
@ -38,7 +42,7 @@ export default class AvatarData extends Base {
this._now = new Date() * 1
this.setBasic(ds, source)
ds.weapon && this.setWeapon(ds.weapon)
ds.talent && this.setTalent(ds.talent, source)
ds.talent && this.setTalent(ds.talent, 'original', source)
ds.artis && this.setArtis(ds)
delete this._now
}
@ -88,7 +92,7 @@ export default class AvatarData extends Base {
}
}
setTalent (ds = {}, source = '', mode = 'original') {
setTalent (ds = {}, mode = 'original', source = '') {
const now = this._now || (new Date()) * 1
let ret = this.char.getAvatarTalent(ds, this.cons, mode)
this.talent = ret || this.talent
@ -141,7 +145,7 @@ export default class AvatarData extends Base {
}
let ret = char.getAvatarTalent(talent, this.cons, 'original')
if (ret) {
this.setTalent(ret, 'mys')
this.setTalent(ret, 'original', 'mys')
}
return true
}
@ -188,7 +192,7 @@ export default class AvatarData extends Base {
// 判断当前profileData是否具备有效圣遗物信息
hasArtis () {
return this.hasData && this.artis.length > 0
return this.isProfile && this.artis.length > 0
}
get costume () {
@ -216,6 +220,26 @@ export default class AvatarData extends Base {
return this.getData(keys || 'id,name,level,star,cons,fetter,elem,face,side,gacha,abbr,weapon,talent,artisSet') || {}
}
/**
* 获取圣遗物套装属性
* @returns {boolean|*|{imgs: *[], names: *[], sets: {}, abbrs: *[], sName: string, name: (string|*)}|{}}
*/
get artisSet () {
return this.artis.getSetData()
}
getArtisDetail () {
return this.artis.getDetail()
}
get dataSource () {
return {
enka: 'Enka.Network',
miao: '喵喵Api',
mys: '米游社'
}[this._source] || this._source
}
get updateTime () {
let time = this._time
if (!time) {
@ -229,16 +253,4 @@ export default class AvatarData extends Base {
}
return ''
}
/**
* 获取圣遗物套装属性
* @returns {boolean|*|{imgs: *[], names: *[], sets: {}, abbrs: *[], sName: string, name: (string|*)}|{}}
*/
get artisSet () {
return this.artis.geSetData()
}
getArtisDetail () {
return this.artis.getDetail()
}
}

View File

@ -1,135 +0,0 @@
/*
* 用户角色列表
*
* 批量管理及天赋等数据获取
* 使用 Avatar Model实现兼容处理面板数据及Mys角色数据
* */
import Base from './Base.js'
import lodash from 'lodash'
import { Data, Common } from '../components/index.js'
import { Avatar, MysApi, Player } from './index.js'
export default class AvatarList extends Base {
constructor (uid, datas = [], withProfile = false) {
super()
if (!uid) {
return false
}
this.uid = uid
let avatars = {}
let profiles = {}
let player = Player.create(uid)
if (withProfile) {
// TODO
}
lodash.forEach(datas, (ds) => {
let avatar = new Avatar(ds, profiles[ds.id] || false)
if (avatar) {
avatars[avatar.id] = avatar
}
})
// 使用面板数据补全
lodash.forEach(profiles, (profile) => {
if (!avatars[profile.id]) {
let avatar = new Avatar(profile)
if (avatar) {
avatars[avatar.id] = avatar
}
}
})
this.avatars = avatars
}
getData (ids, keys = '') {
let rets = {}
keys = keys || 'id,name,level,star,cons,fetter,elem,face,side,gacha,abbr,weapon,artisSet'
let avatars = this.avatars
lodash.forEach(ids, (id) => {
rets[id] = avatars[id].getData(keys) || {}
})
return rets
}
getAvatar (id) {
return this.avatars[id]
}
getProfile (id) {
return this.avatars[id]?.profile
}
getIds () {
let rets = []
lodash.forEach(this.avatars, (ds) => {
rets.push(ds.id)
})
return rets
}
async getTalentData (ids = '', mys = false, keys = '') {
if (!ids) {
ids = this.getIds()
}
mys = mys || this._mys
let avatarTalent = await Data.getCacheJSON(`miao:avatar-talent:${this.uid}`)
let needReq = {}
lodash.forEach(ids, (id) => {
if (!avatarTalent[id] || !avatarTalent[id]?.a) {
needReq[id] = true
}
})
let avatars = this.avatars
let needReqIds = lodash.keys(needReq)
if (needReqIds.length > 0) {
if (needReqIds.length > 8) {
this.e && this.e.reply('正在获取角色信息,请稍候...')
}
let num = 10
let ms = 100
let skillRet = []
let avatarArr = lodash.chunk(needReqIds, num)
for (let val of avatarArr) {
for (let id of val) {
let avatar = avatars[id]
skillRet.push(await avatar.getTalent(mys))
}
skillRet = await Promise.all(skillRet)
skillRet = skillRet.filter(item => item.id)
await Common.sleep(ms)
}
lodash.forEach(skillRet, (talent) => {
avatarTalent[talent.id] = talent
})
await Data.setCacheJSON(`miao:avatar-talent:${this.uid}`, avatarTalent, 3600 * 2)
}
let ret = this.getData(ids, keys)
lodash.forEach(ret, (avatar, id) => {
avatar.talent = avatarTalent[id] || {}
})
return ret
}
get isSelfCookie () {
return !!this._mys?.isSelfCookie
}
}
AvatarList.hasTalentCache = async function (uid) {
return !!await redis.get(`miao:avatar-talent:${uid}`)
}
AvatarList.getAll = async function (e, mys = false) {
if (!mys) {
mys = await MysApi.init(e)
}
if (!mys || !mys.uid) return false
let uid = mys.uid
let data = await mys.getCharacter()
if (!data) {
return false
}
let ret = new AvatarList(uid, data.avatars, true)
ret.e = e
ret._mys = mys
return ret
}

View File

@ -1,24 +1,20 @@
/**
* 用户数据文件
*/
import lodash from 'lodash'
import Base from './Base.js'
import { Data } from '../components/index.js'
import fs from 'fs'
import { ProfileReq, AvatarData } from './index.js'
import Profile from './player-lib/profile.js'
import lodash from 'lodash'
import { AvatarData } from './index.js'
import MysAvatar from './player-lib/MysAvatar.js'
import Profile from './player-lib/Profile.js'
const _path = process.cwd()
const userPath = `${_path}/data/UserData/`
if (!fs.existsSync(userPath)) {
fs.mkdirSync(userPath)
}
Data.createDir('/data/userData', 'root')
export default class Player extends Base {
constructor (uid) {
super()
uid = uid?._mys?.uid || uid?.uid || uid
if (!uid) {
return false
}
@ -32,9 +28,9 @@ export default class Player extends Base {
}
static create (e) {
if (e?._mys?.uid) {
if (e?._mys?.uid || e.uid) {
// 传入为e
let player = new Player(e?._mys?.uid)
let player = new Player(e?._mys?.uid || e.uid)
player.e = e
return player
} else {
@ -87,31 +83,20 @@ export default class Player extends Base {
this._mys = ds._mys || this._mys
}
/**
* 设置角色列表
* @param ds
*/
// 设置角色列表
setAvatars (ds) {
lodash.forEach(ds, (avatar) => {
this.setAvatar(avatar)
})
}
/**
* 设置角色
* @param ds
* @param dataSource
*/
setAvatar (ds, source) {
// 设置角色数据
setAvatar (ds, source = '') {
let avatar = this.getAvatar(ds.id)
avatar.setAvatar(ds, source)
}
/**
* 获取角色
* @param id
* @returns {*}
*/
// 获取Avatar角色
getAvatar (id) {
if (!this._avatars[id]) {
this._avatars[id] = AvatarData.create({ id })
@ -119,11 +104,7 @@ export default class Player extends Base {
return this._avatars[id]
}
/**
* 循环角色
* @param fn
* @returns {Promise<boolean>}
*/
// 异步循环角色
async forEachAvatarAsync (fn) {
for (let id in this._avatars) {
let ret = await fn(this._avatars[id], id)
@ -133,6 +114,7 @@ export default class Player extends Base {
}
}
// 循环Avatar
forEachAvatar (fn) {
for (let id in this._avatars) {
let ret = fn(this._avatars[id], id)
@ -142,6 +124,7 @@ export default class Player extends Base {
}
}
// 获取所有Avatar数据
getAvatarData (ids = '') {
let ret = {}
if (!ids) {
@ -156,20 +139,13 @@ export default class Player extends Base {
return ret
}
/**
* 获取当前用户指定charid面板数据
* @param id
* @returns {*}
*/
// 获取指定角色的面板数据
getProfile (id) {
let avatar = this.getAvatar(id)
return avatar.getProfile()
}
/**
* 获取当前用户所有面板数据
* @returns {{}}
*/
// 获取所有面板数据
getProfiles () {
let ret = {}
lodash.forEach(this._avatars, (avatar) => {
@ -181,28 +157,9 @@ export default class Player extends Base {
return ret
}
/**
* 更新面板
* @param e
* @returns {Promise<boolean|*|undefined>}
*/
async refreshProfile (e, force = true) {
this._update = []
let { uid } = this
if (uid.toString().length !== 9) {
return false
}
let req = new ProfileReq({ e, uid })
try {
await req.request(this)
this._profile = new Date() * 1
this.save()
return this._update.length
} catch (err) {
console.log(err)
e.reply('请求失败')
return false
}
// 更新面板
async refreshProfile (force = true) {
return await Profile.refreshProfile(this, force)
}
// 更新米游社数据
@ -220,17 +177,9 @@ export default class Player extends Base {
return await MysAvatar.refreshTalent(this, ids, force)
}
/**
* 获取面板更新服务名
* @param uid
* @returns {*}
*/
// 获取面板更新服务名
static getProfileServName (uid) {
let Serv = ProfileReq.getServ(uid)
let Serv = Profile.getServ(uid)
return Serv.name
}
static getAvatar (uid, charId, onlyHasData = false) {
return Profile.get(uid, charId, onlyHasData)
}
}

View File

@ -2,187 +2,26 @@
* 面板圣遗物
*/
import lodash from 'lodash'
import Base from './Base.js'
import AvatarArtis from './AvatarArtis.js'
import { Artifact, ArtifactSet, Character } from './index.js'
import { Format, Data } from '../components/index.js'
import { Format } from '../components/index.js'
import ArtisMark from './profile-lib/ArtisMark.js'
import { attrMap, attrValue } from '../resources/meta/artifact/index.js'
import CharArtis from './profile-lib/CharArtis.js'
export default class ProfileArtis extends Base {
export default class ProfileArtis extends AvatarArtis {
constructor (charid = 0, elem = '') {
super()
this.charid = charid
super(charid)
this.elem = elem
this.artis = {}
}
setProfile (profile, artis) {
this.profile = profile
if (artis) {
this.setArtisSet(artis)
this.setArtisData(artis)
}
}
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 || ArtifactSet.getArtiNameBySet(ds.set, idx) || ''
ret.set = ds.set || Artifact.getSetNameByArti(ret.name) || ''
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 (key) {
let artis = this.artis
switch (key) {
case 'length':
return lodash.keys(artis).length
}
if (artis[key]) {
return artis[key]
}
}
toJSON () {
return this.getData('1,2,3,4,5')
}
get sets () {
return this.getSetData().sets || {}
}
get names () {
return this.getSetData().names || []
}
get hasArtis () {
return !lodash.isEmpty(this.artis)
}
mainAttr (idx = '') {
if (!idx) {
let ret = {}
for (let i = 1; i <= 5; i++) {
ret[i] = this.mainAttr(i)
}
return ret
}
let main = this.artis[idx]?.main
if (!main) {
return ''
}
return main.key || ''
}
is (check, pos = '') {
if (pos) {
return this.isAttr(check, pos)
}
let sets = this.getSetData()?.abbrs || []
let ret = false
Data.eachStr(check, (s) => {
if (sets.includes(s)) {
ret = true
return false
}
})
return ret
}
isAttr (attr, pos = '3,4,5') {
let mainAttr = this.mainAttr()
let check = true
Data.eachStr(pos.toString(), (p) => {
let attrs = attr.split(',')
if (!attrs.includes(mainAttr[p]) && (p === '4' && !attrs.includes('dmg') && Format.isElem(mainAttr[p]))) {
check = false
return false
}
})
return check
}
// 获取圣遗物数据
getArtisData () {
let ret = {}
this.forEach((ds, idx) => {
let arti = Artifact.get(ds.name)
ret[idx] = {
...ds,
name: arti.name,
img: arti.img
}
})
return ret
}
/**
* 获取圣遗物套装数据
* @returns {*|{imgs: *[], names: *[], sets: {}, abbrs: *[], sName: string, name: (string|*)}}
* sets: 套装名:2/4
* names: [套装名]
* imgs: [img]
* abbrs[别名]
* name: '组合名字' 若为4件套会使用套装完整名
* sName: '简写名字'若为4件套也会使用简写
*/
getSetData () {
if (this._setData) {
return this._setData
}
let setCount = {}
this.forEach((arti, idx) => {
setCount[arti.set] = (setCount[arti.set] || 0) + 1
})
let sets = {}
let names = []
let imgs = []
let abbrs = []
let abbrs2 = []
for (let set in setCount) {
if (setCount[set] >= 2) {
let count = setCount[set] >= 4 ? 4 : 2
sets[set] = count
let artiSet = ArtifactSet.get(set)
names.push(artiSet.name)
imgs.push(artiSet.img)
abbrs.push(artiSet.abbr + count)
abbrs2.push(artiSet.name + count)
}
}
this._setData = {
sets,
names,
imgs,
abbrs: [...abbrs, ...abbrs2],
name: (abbrs.length > 1 || abbrs2[0]?.length > 7) ? abbrs.join('+') : abbrs2[0],
sName: abbrs.join('+')
}
return this._setData
}
/**
* 获取角色配置
* @returns {{classTitle: *, weight: *, posMaxMark: {}, mark: {}, attrs: {}}}
@ -280,24 +119,4 @@ export default class ProfileArtis extends Base {
}
return ret
}
static _eachArtisSet (sets, fn) {
lodash.forEach(sets || [], (v, k) => {
let artisSet = ArtifactSet.get(k)
if (artisSet) {
if (v >= 4) {
fn(artisSet, 2)
}
fn(artisSet, v)
}
})
}
eachArtisSet (fn) {
ProfileArtis._eachArtisSet(this.sets, fn)
}
static getArtisKeyTitle () {
return ArtisMark.getKeyTitleMap()
}
}

View File

@ -1,27 +1,19 @@
import lodash from 'lodash'
import Base from './Base.js'
import moment from 'moment'
import AvatarData from './AvatarData.js'
import { Data } from '../components/index.js'
import { Character, ProfileArtis, ProfileDmg } from './index.js'
import { ProfileArtis, ProfileDmg } from './index.js'
import AttrCalc from './profile-lib/AttrCalc.js'
export default class ProfileData extends Base {
export default class ProfileData extends AvatarData {
constructor (ds = {}) {
super()
let char = Character.get({ id: ds.id, elem: ds.elem })
if (!char) {
return false
}
this.id = char.id
this.char = char
this.setBasic(ds)
ds.weapon && this.setWeapon(ds.weapon)
ds.talent && this.setTalent(ds.talent)
this.artis = new ProfileArtis(this.id, this.elem)
ds.artis && this.setArtis(ds.artis)
super(ds)
this.calcAttr()
}
initArtis () {
this.artis = new ProfileArtis(this.id, this.elem)
}
static create (ds) {
let profile = new ProfileData(ds)
if (!profile) {
@ -30,71 +22,31 @@ export default class ProfileData extends Base {
return profile
}
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
})
}
calcAttr () {
this._attr = AttrCalc.create(this)
this.attr = this._attr.calc()
}
setBasic (ds = {}) {
this.level = ds.lv || ds.level || 1
this.cons = ds.cons || 0
this.fetter = ds.fetter || 0
this._costume = ds.costume || 0
this.elem = ds.elem || this.char.elem || ''
this.dataSource = ds.dataSource || 'enka'
this.promote = lodash.isUndefined(ds.promote) ? AttrCalc.calcPromote(this.level) : (ds.promote || 0)
this._time = ds._time || ds.updateTime || new Date() * 1
}
setWeapon (ds = {}) {
this.weapon = {
name: ds.name,
star: ds.rank || ds.star || 1,
level: ds.level || ds.lv || 1,
promote: lodash.isUndefined(ds.promote) ? AttrCalc.calcPromote(ds.level || ds.lv || 1) : (ds.promote || 0),
affix: ds.affix
}
let w = this.weapon
if (w.level < 20) {
w.promote = 0
}
}
setArtis (ds = false) {
this.artis.setProfile(this, ds.artis || ds)
}
setTalent (ds = {}, mode = 'original') {
this.talent = this.char.getAvatarTalent(ds, this.cons, mode)
}
get name () {
return this.char?.name || ''
this.artis?.setProfile(this, ds.artis?.artis || ds.artis || ds)
}
// 判断当前profileData是否具有有效数据
get hasData () {
// 检查数据源
if (!this.dataSource || !['enka', 'change', 'miao'].includes(this.dataSource)) {
return false
}
// 检查属性
if (!this.weapon || !this.talent || !this.artis) {
return false
}
// 检查旅行者
if (['空', '荧'].includes(this.name)) {
return !!this.elem
}
return true
return this.isProfile
}
// 判断当前profileData是否具备有效圣遗物信息
hasArtis () {
return this.hasData && this.artis.length > 0
}
get costume () {
get splashCostume () {
let costume = this._costume
if (lodash.isArray(costume)) {
costume = costume[0]
@ -106,46 +58,6 @@ export default class ProfileData extends Base {
return [costume, 'normal']
}
get originalTalent () {
return lodash.mapValues(this.talent, (ds) => ds.original)
}
// toJSON 供保存使用
toJSON () {
let ret = {
...this.getData('id,name,elem,level,promote,fetter,costume,cons,talent,attr,weapon,artis,dataSource,_time')
}
ret.talent = lodash.mapValues(this.talent, (ds) => ds.original)
ret.costume = this.costume[0] || 0
return ret
}
get updateTime () {
let time = this._time
if (!time) {
return ''
}
if (lodash.isString(time)) {
return moment(time).format('MM-DD HH:mm')
}
if (lodash.isNumber(time)) {
return moment(new Date(time)).format('MM-DD HH:mm')
}
return ''
}
get dataSourceName () {
return {
enka: 'Enka.Network',
miao: '喵喵Api',
input: 'Input'
}[this.dataSource] || 'Enka.NetWork'
}
get isProfile () {
return true
}
// 获取当前profileData的圣遗物评分withDetail=false仅返回简略信息
getArtisMark (withDetail = true) {
if (this.hasData) {

View File

@ -8,10 +8,17 @@ function sleep (ms) {
}
export default class ProfileReq extends Base {
constructor ({ e, uid }) {
constructor (e) {
super()
this.e = e
this.uid = uid
this.uid = e.uid
}
static create (e) {
if (!e || !e.uid) {
return false
}
return new ProfileReq(e)
}
async setCd (seconds = 60) {
@ -51,16 +58,14 @@ export default class ProfileReq extends Base {
this.e.reply(msg)
}
async request (player) {
let Serv = ProfileReq.getServ(this.uid)
let reqParam = await Serv.getReqParam(this.uid)
async requestProfile (player, serv) {
let reqParam = await serv.getReqParam(this.uid)
let cdTime = await this.inCd()
if (cdTime) {
// return this.err(`请求过快,请${cdTime}秒后重试..`)
// return this.err(`请求过快,请${cdTime}秒后重试..`)
}
await this.setCd(20)
// this.msg(`开始获取uid:${this.uid}的数据,可能会需要一定时间~`)
this.msg(`开始获取uid:${this.uid}的数据,可能会需要一定时间~`)
await sleep(100)
// 发起请求
let data = {}
@ -83,30 +88,20 @@ export default class ProfileReq extends Base {
console.log('面板请求错误', e)
data = {}
}
data = await Serv.response(data, this)
data = await serv.response(data, this)
// 设置CD
cdTime = Serv.getCdTime(data)
cdTime = serv.getCdTime(data)
if (cdTime) {
await this.setCd(cdTime)
}
if (data === false) {
return false
}
Serv.updatePlayer(player, data)
cdTime = Serv.getCdTime(data)
serv.updatePlayer(player, data)
cdTime = serv.getCdTime(data)
if (cdTime) {
await this.setCd(cdTime)
}
return player
}
}
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 })
}

View File

@ -79,14 +79,3 @@ export default class ProfileServ extends Base {
return this.execFn('updatePlayer', [player, data], {})
}
}
ProfileServ.getServ = function ({ uid, serv }) {
let { Miao, Enka } = serv
let token = diyCfg?.miaoApi?.token
let qq = diyCfg?.miaoApi?.qq
if (qq && token && token.length === 32 && !/^test/.test(token) && Cfg.get('profileServ') === 1) {
return Miao
}
return Enka
}

View File

@ -2,10 +2,8 @@ import Base from './Base.js'
import Character from './Character.js'
import Artifact from './Artifact.js'
import ArtifactSet from './ArtifactSet.js'
import Avatar from './Avatar.js'
import AvatarData from './AvatarData.js'
import AvatarArtis from './AvatarArtis.js'
import AvatarList from './AvatarList.js'
import Abyss from './Abyss.js'
import Player from './Player.js'
import ProfileServ from './ProfileServ.js'
@ -26,9 +24,7 @@ export {
Character,
Artifact,
ArtifactSet,
Avatar,
AvatarData,
AvatarList,
AvatarArtis,
ProfileServ,
ProfileReq,

View File

@ -1,14 +1,13 @@
import lodash from 'lodash'
import { Data } from '../../components/index.js'
import { ProfileServ } from '../index.js'
import EnkaData from './enka-data.js'
import EnkaData from './EnkaData.js'
import MiaoData from './MiaoData.js'
let HttpsProxyAgent = ''
export default new ProfileServ({
export default {
id: 'enka',
cfgKey: 'enkaApi',
// 处理请求参数
async request (api) {
let params = {
@ -16,7 +15,6 @@ export default new ProfileServ({
}
let proxy = this.getCfg('proxyAgent')
if (proxy) {
if (HttpsProxyAgent === '') {
HttpsProxyAgent = await import('https-proxy-agent').catch((err) => {
logger.error(err)
@ -45,8 +43,14 @@ export default new ProfileServ({
return data
},
userData (data) {
return Data.getData(data, 'name:nickname,avatar:profilePicture.avatarId,level,signature')
updatePlayer (player, data) {
player.setBasicData(Data.getData(data, 'name:nickname,face:profilePicture.avatarID,card:nameCardID,level,word:worldLevel,sign:signature'))
lodash.forEach(data.avatarInfoList, (ds) => {
let ret = EnkaData.setAvatar(player, ds)
if (ret) {
player._update.push(ret.id)
}
})
},
profileData (data) {
@ -64,4 +68,4 @@ export default new ProfileServ({
cdTime (data) {
return data.ttl || 60
}
})
}

View File

@ -0,0 +1,105 @@
import lodash from 'lodash'
import { attrMap, idsMap, artisIdxMap } from './ProfileMeta.js'
import { Character, ArtifactSet } from '../index.js'
let EnkaData = {
setAvatar (player, data) {
let char = Character.get(data.avatarId)
if (!char) {
return
}
let avatar = player.getAvatar(char.id)
let talentRet = EnkaData.getTalent(char.id, data.skillLevelMap)
avatar.setAvatar({
level: data.propMap['4001'].val * 1,
promote: data.propMap['1002'].val * 1,
cons: data.talentIdList ? data.talentIdList.length : 0,
fetter: data.fetterInfo.expLevel,
costume: char.checkCostume(data.costumeId) ? data.costumeId : 0,
elem: talentRet.elem,
weapon: EnkaData.getWeapon(data.equipList),
talent: talentRet.talent,
artis: EnkaData.getArtifact(data.equipList)
}, 'enka')
return avatar
},
getWeapon (data) {
let ds = {}
lodash.forEach(data, (temp) => {
if (temp.flat && temp.flat.itemType === 'ITEM_WEAPON') {
ds = temp
return false
}
})
let { weapon, flat } = ds
return {
name: idsMap[flat.nameTextMapHash],
level: weapon.level,
promote: weapon.promoteLevel,
affix: (lodash.values(weapon.affixMap)[0] || 0) + 1
}
},
getTalent (charid, ds = {}) {
let char = Character.get(charid)
let { talentId = {}, talentElem = {}, talentKey = {} } = char.meta
let elem = ''
let idx = 0
let ret = {}
lodash.forEach(ds, (lv, id) => {
let key
if (talentId[id]) {
let tid = talentId[id]
key = talentKey[tid]
elem = elem || talentElem[tid]
ret[key] = lv
} else {
key = ['a', 'e', 'q'][idx++]
ret[key] = ret[key] || lv
}
})
return {
elem: elem,
talent: ret
}
},
getArtifact (data) {
let ret = {}
let get = function (d) {
if (!d) {
return {}
}
let id = d.appendPropId || d.mainPropId || ''
id = id.replace('FIGHT_PROP_', '')
if (!attrMap[id]) {
return {}
}
return { key: attrMap[id], value: d.statValue }
}
lodash.forEach(data, (ds) => {
let flat = ds.flat || {}
let sub = flat.reliquarySubstats || []
let idx = artisIdxMap[flat.equipType]
if (!idx) {
return
}
let setName = idsMap[flat.setNameTextMapHash] || ''
ret[idx] = {
name: ArtifactSet.getArtiNameBySet(setName, idx),
level: Math.min(20, ((ds.reliquary && ds.reliquary.level) || 1) - 1),
main: get(flat.reliquaryMainstat),
attrs: [
get(sub[0]),
get(sub[1]),
get(sub[2]),
get(sub[3])
]
}
})
return ret
}
}
export default EnkaData

View File

@ -1,9 +1,8 @@
import lodash from 'lodash'
import { Data } from '../../components/index.js'
import { ProfileServ } from '../index.js'
import MiaoData from './miao-data.js'
import MiaoData from './MiaoData.js'
export default new ProfileServ({
export default {
key: 'miao',
name: '喵喵Api',
cfgKey: 'miaoApi',
@ -36,4 +35,4 @@ export default new ProfileServ({
}
return 60
}
})
}

View File

@ -1,54 +1,9 @@
import { Character, Artifact } from '../index.js'
import lodash from 'lodash'
const attrMap = {
HP: 'hpPlus',
HP_PERCENT: 'hp',
ATTACK: 'atkPlus',
ATTACK_PERCENT: 'atk',
DEFENSE: 'defPlus',
DEFENSE_PERCENT: 'def',
FIRE_ADD_HURT: '',
ICE_ADD_HURT: 'cryo',
ROCK_ADD_HURT: 'geo',
ELEC_ADD_HURT: 'electro',
WIND_ADD_HURT: 'anemo',
WATER_ADD_HURT: 'hydro',
PHYSICAL_ADD_HURT: 'phy',
GRASS_ADD_HURT: 'dendro',
HEAL_ADD: 'heal',
ELEMENT_MASTERY: 'mastery',
CRITICAL: 'cpct',
CRITICAL_HURT: 'cdmg',
CHARGE_EFFICIENCY: 'recharge'
}
import { attrMap, artisIdxMap } from './ProfileMeta.js'
let MiaoData = {
key: 'miao',
name: '喵喵Api',
getData (uid, data) {
let ret = {
uid,
chars: {}
}
if (data.cacheExpireAt) {
let exp = Math.max(0, Math.round(data.cacheExpireAt - (new Date() / 1000)))
ret.ttl = Math.max(60, exp)
}
return ret
},
getAvatar (ds) {
let char = Character.get(ds.id)
return {
id: ds.id,
name: char ? char.name : '',
dataSource: 'miao',
level: ds.level
}
},
setAvatar (player, ds) {
let char = Character.get(ds.id)
let avatar = player.getAvatar(ds.id)
@ -65,59 +20,16 @@ let MiaoData = {
}, 'miao')
return avatar
},
getWeapon (weapon) {
return {
name: weapon.name,
star: weapon.rank,
level: weapon.level,
promote: weapon.promoteLevel,
affix: (weapon.affixLevel || 0) + 1
}
},
getArtifact (data) {
let ret = {}
let get = function (d) {
if (!d) {
return []
}
let name = d.name
name = name.replace('FIGHT_PROP_', '')
if (!attrMap[name]) {
return []
}
let value = d.value
if (value && value < 1) {
value = value * 100
}
return { key: attrMap[name], value }
}
lodash.forEach(data, (ds) => {
let sub = ds.appendAffix || []
let idx = {
生之花: 1,
死之羽: 2,
时之沙: 3,
空之杯: 4,
理之冠: 5
}[ds.type]
if (!idx) {
return
}
ret[idx] = {
name: ds.name,
set: Artifact.getSetNameByArti(ds.name) || '',
level: ds.level,
main: get(ds.mainAffix),
attrs: [
get(sub[0]),
get(sub[1]),
get(sub[2]),
get(sub[3])
]
}
})
return ret
},
getTalent (charid, data = {}) {
let char = Character.get(charid)
let { talentId = {}, talentElem = {}, talentKey = {} } = char.meta
@ -144,6 +56,44 @@ let MiaoData = {
talent: ret,
elem
}
},
getArtifact (data) {
let ret = {}
let get = function (d) {
if (!d) {
return []
}
let name = d.name
name = name.replace('FIGHT_PROP_', '')
if (!attrMap[name]) {
return []
}
let value = d.value
if (value && value < 1) {
value = value * 100
}
return { key: attrMap[name], value }
}
lodash.forEach(data, (ds) => {
let sub = ds.appendAffix || []
let idx = artisIdxMap[ds.type]
if (!idx) {
return
}
ret[idx] = {
name: ds.name,
level: ds.level,
main: get(ds.mainAffix),
attrs: [
get(sub[0]),
get(sub[1]),
get(sub[2]),
get(sub[3])
]
}
})
return ret
}
}
export default MiaoData

View File

@ -0,0 +1,60 @@
import { ProfileReq, ProfileServ } from '../index.js'
import { Cfg, Data } from '../../components/index.js'
import enkaCfg from './EnkaApi.js'
import MiaoApi from './MiaoApi.js'
let { diyCfg } = await Data.importCfg('profile')
const Profile = {
/**
* 根据UID分配请求服务器
* @param uid
* @returns {ProfileServ}
*/
getServ (uid) {
let token = diyCfg?.miaoApi?.token
let qq = diyCfg?.miaoApi?.qq
if (qq && token && token.length === 32 && !/^test/.test(token) && Cfg.get('profileServ') === 1) {
if (!Profile.Miao) {
Profile.Miao = new ProfileServ(MiaoApi)
}
return Profile.Miao
}
if (!Profile.Enka) {
Profile.Enka = new ProfileServ(enkaCfg)
}
return Profile.Enka
},
/**
* 更新面板数据
* @param player
* @param force
* @returns {Promise<boolean|number>}
*/
async refreshProfile (player, force = true) {
player._update = []
let { uid, e } = player
if (uid.toString().length !== 9 || !e) {
return false
}
let req = ProfileReq.create(e)
if (!req) {
return false
}
let serv = Profile.getServ(uid)
try {
await req.requestProfile(player, serv)
player._profile = new Date() * 1
player.save()
return player._update.length
} catch (err) {
e.reply(`UID:${uid}更新面板失败,更新服务:${serv.name}`)
return false
}
}
}
export default Profile

View File

@ -1,4 +1,4 @@
export default {
export const idsMap = {
20848859: '黑岩斩刀',
33330467: '元素熟练',
37147251: '匣里日月',
@ -473,3 +473,40 @@ export default {
FIGHT_PROP_WIND_SUB_HURT: '风元素抗性',
level: '等级'
}
// 圣遗物词条映射
export const attrMap = {
HP: 'hpPlus',
HP_PERCENT: 'hp',
ATTACK: 'atkPlus',
ATTACK_PERCENT: 'atk',
DEFENSE: 'defPlus',
DEFENSE_PERCENT: 'def',
FIRE_ADD_HURT: '',
ICE_ADD_HURT: 'cryo',
ROCK_ADD_HURT: 'geo',
ELEC_ADD_HURT: 'electro',
WIND_ADD_HURT: 'anemo',
WATER_ADD_HURT: 'hydro',
PHYSICAL_ADD_HURT: 'phy',
GRASS_ADD_HURT: 'dendro',
HEAL_ADD: 'heal',
ELEMENT_MASTERY: 'mastery',
CRITICAL: 'cpct',
CRITICAL_HURT: 'cdmg',
CHARGE_EFFICIENCY: 'recharge'
}
// 圣遗物位置映射
export const artisIdxMap = {
EQUIP_BRACER: 1,
EQUIP_NECKLACE: 2,
EQUIP_SHOES: 3,
EQUIP_RING: 4,
EQUIP_DRESS: 5,
生之花: 1,
死之羽: 2,
时之沙: 3,
空之杯: 4,
理之冠: 5
}

View File

@ -1,227 +0,0 @@
import lodash from 'lodash'
import enkaMeta from './enka-meta.js'
import { Character, ArtifactSet, ProfileData } from '../index.js'
const artiIdx = {
EQUIP_BRACER: 1,
EQUIP_NECKLACE: 2,
EQUIP_SHOES: 3,
EQUIP_RING: 4,
EQUIP_DRESS: 5
}
const attrMap = {
HP: '小生命',
HP_PERCENT: '大生命',
ATTACK: '小攻击',
ATTACK_PERCENT: '大攻击',
DEFENSE: '小防御',
DEFENSE_PERCENT: '大防御',
FIRE_ADD_HURT: '火元素伤害加成',
ICE_ADD_HURT: '冰元素伤害加成',
ROCK_ADD_HURT: '岩元素伤害加成',
ELEC_ADD_HURT: '雷元素伤害加成',
WIND_ADD_HURT: '风元素伤害加成',
WATER_ADD_HURT: '水元素伤害加成',
PHYSICAL_ADD_HURT: '物理伤害加成',
GRASS_ADD_HURT: '草元素伤害加成',
HEAL_ADD: '治疗加成',
ELEMENT_MASTERY: '元素精通',
CRITICAL: '暴击率',
CRITICAL_HURT: '暴击伤害',
CHARGE_EFFICIENCY: '充能效率'
}
let EnkaData = {
getProfile (data) {
let char = Character.get(data.avatarId)
let profile = new ProfileData({ id: char.id })
profile.setBasic({
level: data.propMap['4001'].val * 1,
promote: data.propMap['1002'].val * 1,
cons: data.talentIdList ? data.talentIdList.length : 0,
fetter: data.fetterInfo.expLevel,
costume: char.checkCostume(data.costumeId) ? data.costumeId : 0,
dataSource: 'enka'
})
profile.setAttr(EnkaData.getAttr(data.fightPropMap))
profile.setWeapon(EnkaData.getWeapon(data.equipList))
profile.setArtis(EnkaData.getArtifact(data.equipList))
let talentRet = EnkaData.getTalent(char.id, data.skillLevelMap)
profile.setTalent(talentRet.talent, 'original')
// 为旅行者增加elem
if (talentRet.elem) {
profile.elem = talentRet.elem
}
return EnkaData.dataFix(profile)
},
getAttr (data) {
let ret = {}
let attrKey = {
// atk: 2001,
atkBase: 4,
def: 2002,
defBase: 7,
hp: 2000,
hpBase: 1,
mastery: 28,
cpct: {
src: 20,
pct: true
},
cdmg: {
src: 22,
pct: true
},
heal: {
src: 26,
pct: true
},
recharge: {
src: 23,
pct: true
}
}
lodash.forEach(attrKey, (cfg, key) => {
if (!lodash.isObject(cfg)) {
cfg = { src: cfg }
}
let val = data[cfg.src] || 0
if (cfg.pct) {
val = val * 100
}
ret[key] = val
})
ret.atk = data['4'] * (1 + (data['6'] || 0)) + (data['5'] || 0)
let maxDmg = 0
// 火40 水42 风44 岩45 冰46 雷46
// 41 雷
lodash.forEach('40,41,42,43,44,45,45,46'.split(','), (key) => {
maxDmg = Math.max(data[key] * 1, maxDmg)
})
// phy 30
ret.dmg = maxDmg * 100
ret.phy = data['30'] * 100
return ret
},
getArtifact (data) {
let ret = {}
let get = function (d) {
if (!d) {
return []
}
let id = d.appendPropId || d.mainPropId || ''
id = id.replace('FIGHT_PROP_', '')
if (!attrMap[id]) {
return []
}
return [attrMap[id], d.statValue]
}
lodash.forEach(data, (ds) => {
let flat = ds.flat || {}
let sub = flat.reliquarySubstats || []
let idx = artiIdx[flat.equipType]
if (!idx) {
return
}
let setName = enkaMeta[flat.setNameTextMapHash] || ''
ret[idx] = {
name: ArtifactSet.getArtiNameBySet(setName, idx),
set: setName,
level: Math.min(20, ((ds.reliquary && ds.reliquary.level) || 1) - 1),
main: get(flat.reliquaryMainstat),
attrs: [
get(sub[0]),
get(sub[1]),
get(sub[2]),
get(sub[3])
]
}
})
return ret
},
getWeapon (data) {
let ds = {}
lodash.forEach(data, (temp) => {
if (temp.flat && temp.flat.itemType === 'ITEM_WEAPON') {
ds = temp
return false
}
})
let { weapon, flat } = ds
return {
name: enkaMeta[flat.nameTextMapHash],
star: flat.rankLevel,
level: weapon.level,
promote: weapon.promoteLevel,
affix: (lodash.values(weapon.affixMap)[0] || 0) + 1
}
},
getTalent (charid, ds = {}) {
let char = Character.get(charid)
let { talentId = {}, talentElem = {}, talentKey = {} } = char.meta
let elem = ''
let idx = 0
let ret = {}
lodash.forEach(ds, (lv, id) => {
let key
if (talentId[id]) {
let tid = talentId[id]
key = talentKey[tid]
elem = elem || talentElem[tid]
ret[key] = lv
} else {
key = ['a', 'e', 'q'][idx++]
ret[key] = ret[key] || lv
}
})
return {
elem: elem,
talent: ret
}
},
dataFix (ret) {
if (ret._fix) {
return ret
}
let { attr, id, weapon } = ret
let count = 0
id = id * 1
switch (id) {
case 10000052:
// 雷神被动加成fix
attr.dmg = Math.max(0, attr.dmg - (attr.recharge - 100) * 0.4)
break
case 10000041:
// 莫娜被动fix
attr.dmg = Math.max(0, attr.dmg - attr.recharge * 0.2)
break
case 10000070:
// 妮露满命效果fix
if (ret.cons === 6) {
count = Math.floor(attr.hp / 1000)
attr.cpct = Math.max(5, attr.cpct - Math.min(30, count * 0.6))
attr.cdmg = Math.max(50, attr.cdmg - Math.min(60, count * 1.2))
}
break
}
let wDmg = {
息灾: 12,
波乱月白经津: 12,
雾切之回光: 12,
猎人之径: 12
}
let { name, affix } = weapon
// 修正武器的加伤
if (wDmg[name]) {
attr.dmg = Math.max(0, attr.dmg - wDmg[name] - wDmg[name] * (affix - 1) / 4)
}
ret._fix = true
return ret
}
}
export default EnkaData

View File

@ -37,9 +37,6 @@ class AttrCalc {
this.setCharAttr()
this.setWeaponAttr()
this.setArtisAttr()
if (process.argv.includes('web-debug')) {
// console.log(this.attr, this.attr.getAttr())
}
return this.attr.getAttr()
}

View File

@ -56,7 +56,7 @@
<div class="data-info">
{{if data.dataSource}}
<span>数据源:{{ {miao:"喵喵Api",enka:"Enka.Network",change:"面板变换"}[data.dataSource]||data.dataSource }}</span>
<span>数据源:{{ {change:"面板变换"}[data.dataSource]||data.dataSource }}</span>
{{/if}}
{{if data.updateTime}}
<span class="time">{{data.updateTime}}</span>