diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cbaa9cc..abec9fa4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,17 +1,10 @@ -# 1.10.5 +# 1.10.6 * 面板圣遗物评分初步增加流派判定能力 - * 实验性,尚未完全稳定,可能会导致一些角色圣遗物评分变化 + * 实验性,尚未完全稳定,可能会导致一些角色圣遗物评分变化,如遇问题请反馈 * 目前实验暴力芭芭拉、血牛钟离的判定 -* 其他一些已知Bug修复 -# 1.10.4 - -* 增加`#心海图鉴`功能,可查看突破材料及常用武器 - * 功能尚未完全稳定,信息还在继续补全中 - * 如无需使用,master可通过`#喵喵设置图鉴关闭`关闭,防止覆盖图鉴插件等图鉴功能 - -# 1.10.1~1.10.3 +# 1.10.1~1.10.5 * `#刻晴面板`、`#芭芭拉圣遗物`支持展示角色时装 * 如果角色装备了时装,面板的角色图会展示时装立绘 @@ -22,6 +15,9 @@ * `#雷主天赋`、`#草主命座`功能升级 * 页面样式微调,内部处理逻辑升级 * 支持旅行者天赋及命座信息查看 +* 增加`#心海图鉴`功能,可查看突破材料及常用武器 + * 功能尚未完全稳定,信息还在继续补全中 + * 如无需使用,master可通过`#喵喵设置图鉴关闭`关闭,防止覆盖图鉴插件等图鉴功能 * 框架底层角色相关逻辑重构,角色图像资源迁移为webp格式 * 若遇到图像资源无法正常展示,可联系喵喵反馈 diff --git a/apps/character/profile-common.js b/apps/character/profile-common.js index 3843d342..593ac939 100644 --- a/apps/character/profile-common.js +++ b/apps/character/profile-common.js @@ -142,7 +142,7 @@ export async function autoGetProfile (e, uid, avatar, callback) { return { err: true } } else if (!['enka', 'input2', 'miao'].includes(profile.dataSource)) { if (!await refresh()) { - e.reply('由于数据格式升级,请重新获取面板信息后查看') + e.reply('缓存数据错误,请重新获取面板信息后查看') } return { err: true } } diff --git a/apps/character/profile-detail.js b/apps/character/profile-detail.js index dc41daba..53344955 100644 --- a/apps/character/profile-detail.js +++ b/apps/character/profile-detail.js @@ -23,18 +23,13 @@ export async function renderProfile (e, char, mode = 'profile', params = {}) { } let profile = Profile.get(uid, char.id) - if (!profile) { + if (!profile || !profile.hasData) { if (await refresh()) { return true } else { e.reply(`请确认${char.name}已展示在【游戏内】的角色展柜中,并打开了“显示角色详情”。然后请使用 #更新面板\n命令来获取${char.name}的面板详情`) } return true - } else if (!profile.hasData) { - if (!await refresh()) { - e.reply('由于数据Api变更,请重新获取面板信息后查看') - } - return true } char = profile.char || char let a = profile.attr @@ -88,13 +83,11 @@ export async function renderProfile (e, char, mode = 'profile', params = {}) { basic.dmg = Format.comma(basic.dmg) basic.avg = Format.comma(basic.avg) } - const costume = profile.costume ? '2' : '' // 渲染图像 return await Common.render('character/profile-detail', { save_id: uid, uid, data: profile.getData('cons,level,weapon,dataSource,updateTime'), - costume, attr, name: char.name, elem: char.elem, @@ -112,7 +105,7 @@ export async function renderProfile (e, char, mode = 'profile', params = {}) { classTitle, usefulMark, talentMap: { a: '普攻', e: '战技', q: '爆发' }, - bodyClass: `char-${char.name}${costume}`, + bodyClass: `char-${char.name}`, mode }, { e, scale: 1.6 }) } diff --git a/apps/character/profile-list.js b/apps/character/profile-list.js index 4c0719df..198bfd3a 100644 --- a/apps/character/profile-list.js +++ b/apps/character/profile-list.js @@ -30,7 +30,6 @@ export async function profileList (e) { tmp.source = profile.dataSource tmp.level = profile.level || 1 tmp.isNew = 0 - tmp.costume = profile.costume ? '2' : '' if (newChar[char.name]) { tmp.isNew = 1 newCount++ diff --git a/components/profile-data/enka-data.js b/components/profile-data/enka-data.js index fac72f26..fb9d21ca 100644 --- a/components/profile-data/enka-data.js +++ b/components/profile-data/enka-data.js @@ -33,7 +33,7 @@ const attrMap = { } let EnkaData = { - getProfile(data) { + getProfile (data) { let char = Character.get(data.avatarId) let profile = new ProfileData({ id: char.id }) profile.setBasic({ @@ -54,7 +54,7 @@ let EnkaData = { } return EnkaData.dataFix(profile) }, - getAttr(data) { + getAttr (data) { let ret = {} let attrKey = { // atk: 2001, @@ -105,7 +105,7 @@ let EnkaData = { return ret }, - getArtifact(data) { + getArtifact (data) { let ret = {} let get = function (d) { @@ -144,7 +144,7 @@ let EnkaData = { }) return ret }, - getWeapon(data) { + getWeapon (data) { let ds = {} lodash.forEach(data, (temp) => { if (temp.flat && temp.flat.itemType === 'ITEM_WEAPON') { @@ -161,7 +161,7 @@ let EnkaData = { affix: (lodash.values(weapon.affixMap)[0] || 0) + 1 } }, - getTalent(charid, ds = {}) { + getTalent (charid, ds = {}) { let char = Character.get(charid) let { talentId = {}, talentElem = {}, talentKey = {} } = char.meta let elem = '' @@ -185,7 +185,7 @@ let EnkaData = { talent: ret } }, - dataFix(ret) { + dataFix (ret) { if (ret._fix) { return ret } diff --git a/models/Base.js b/models/Base.js index a9c900cb..09282764 100644 --- a/models/Base.js +++ b/models/Base.js @@ -4,6 +4,20 @@ let cacheMap = {} let reFn = {} export default class Base { + constructor () { + return new Proxy(this, { + get (self, key) { + if (key in self) { + return self[key] + } + if (self._get) { + return self._get(key) + } + return (self._meta || self._data || self.meta || {})[key] + } + }) + } + getData (arrList = '', cfg = {}) { arrList = arrList || this._dataKey || '' return Data.getData(this, arrList, cfg) @@ -25,9 +39,12 @@ export default class Base { // 设置缓存 _cache (time = 10 * 60) { let id = this._uuid - this._expire(time) - cacheMap[id] = this._proxy() - return cacheMap[id] + if (id) { + this._expire(time) + cacheMap[id] = this + return cacheMap[id] + } + return this } // 设置超时时间 @@ -58,21 +75,4 @@ export default class Base { } return ret } - - // 返回代理对象 - _proxy () { - return new Proxy(this, { - get (self, key) { - if (key in self) { - return self[key] - } - if (self._get) { - if (key in self) { - return self._get(key) - } - } - return (self._meta || self._data || self.meta || {})[key] - } - }) - } } diff --git a/models/Character.js b/models/Character.js index 35f486a0..55b063c3 100644 --- a/models/Character.js +++ b/models/Character.js @@ -5,7 +5,6 @@ import CharImg from './character-lib/CharImg.js' import CharTalent from './character-lib/CharTalent.js' import CharId from './character-lib/CharId.js' import CharMeta from './character-lib/CharMeta.js' -import CharArtis from './character-lib/CharArtis.js' let { abbrMap, wifeMap, idSort } = CharId @@ -23,9 +22,6 @@ class Character extends Base { if (!this.isCustom) { let meta = getMeta(name) this.meta = meta - for (let key of 'abbr,title,star,allegiance,weapon,astro,cncv,jpcv,ver,talentCons'.split(',')) { - this[key] = meta[key] - } this.elem = CharId.getElem(elem || meta.elem) || 'anemo' } else { this.meta = {} @@ -139,6 +135,9 @@ class Character extends Base { // 获取角色插画 getImgs (costume = '') { let costumeId = this.checkCostume(costume) ? '2' : '' + if (costume === 'super') { + costumeId = '0' + } let cacheId = `costume${costumeId}` if (!this._imgs) { this._imgs = {} @@ -211,10 +210,6 @@ class Character extends Base { } return await this.getTraveler(uid) } - - getArtisMarkCfg (profile, artis) { - return CharArtis.getCharArtisCfg(this, profile, artis) - } } let getMeta = function (name) { diff --git a/models/ProfileArtis.js b/models/ProfileArtis.js index f095f367..cbe3faf6 100644 --- a/models/ProfileArtis.js +++ b/models/ProfileArtis.js @@ -4,9 +4,10 @@ import lodash from 'lodash' import Base from './Base.js' import { Artifact, Character } from './index.js' -import { Format } from '../components/index.js' +import { Format, Data } from '../components/index.js' import ArtisMark from './profile-lib/ArtisMark.js' import { attrMap, attrNameMap, attrValue } from '../resources/meta/reliquaries/artis-mark.js' +import CharArtis from './profile-lib/CharArtis.js' export default class ProfileArtis extends Base { constructor (charid = 0, ds = false) { @@ -16,7 +17,6 @@ export default class ProfileArtis extends Base { if (ds) { this.setArtisSet(ds) } - return this._proxy() } setProfile (profile, artis) { @@ -54,30 +54,6 @@ export default class ProfileArtis extends Base { }) } - 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 - } - _get (key) { let artis = this.artis switch (key) { @@ -101,7 +77,14 @@ export default class ProfileArtis extends Base { return this.getSetData().names } - mainAttr (idx) { + 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 '' @@ -118,25 +101,63 @@ export default class ProfileArtis extends Base { return '' } + 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, (p) => { + if (!attr.split(',').includes(mainAttr[p])) { + check = false + return false + } + }) + console.log(attr, pos, mainAttr, check) + return check + } + 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 abbrs = [] for (let set in setCount) { if (setCount[set] >= 2) { sets[set] = setCount[set] >= 4 ? 4 : 2 names.push(Artifact.getArtiBySet(set)) } } - return { sets, names } + lodash.forEach(sets, (v, k) => { + abbrs.push(k + v) + abbrs.push(Artifact.getAbbrBySet(k) + v) + }) + this._setData = { sets, names, abbrs } + return this._setData } getCharCfg () { let char = Character.get(this.charid) - let { attrWeight, title } = char.getArtisMarkCfg(this.profile, this) + // let { attrWeight, title } = char.getArtisMarkCfg(this.profile, this) + let { attrWeight, title } = CharArtis.getCharArtisCfg(char, this.profile, this) let attrMark = {} let baseAttr = char.baseAttr || { hp: 14000, atk: 230, def: 700 } diff --git a/models/ProfileData.js b/models/ProfileData.js index 8014d070..223b23cd 100644 --- a/models/ProfileData.js +++ b/models/ProfileData.js @@ -92,15 +92,15 @@ export default class ProfileData extends Base { } get costume () { - let cMap = { - // 10000033: 900001, // 公子 - 10000052: 900002, // 雷神 - 10000030: 900003 // 钟离 - } + let cMap = [ + 10000022, // 温迪 + 10000030, // 钟离 + 10000052 // 雷神 + ] let talent = this.talent ? lodash.map(this.talent, (ds) => ds.original).join('') : '' - if (cMap[this.id]) { + if (cMap.includes(this.id)) { if (this.cons === 6 || ['ACE', 'ACE²'].includes(this.artis?.markClass) || talent === '101010') { - return cMap[this.id] + return 'super' } } return this._costume @@ -108,7 +108,7 @@ export default class ProfileData extends Base { // toJSON 供保存使用 toJSON () { - return this._proxy().getData('id,name,level,cons,fetter,attr,weapon,talent,artis,dataSource,costume,elem,_time') + return this.getData('id,name,level,cons,fetter,attr,weapon,talent,artis,dataSource,costume,elem,_time') } get updateTime () { diff --git a/models/character-lib/CharArtis.js b/models/character-lib/CharArtis.js deleted file mode 100644 index e3614872..00000000 --- a/models/character-lib/CharArtis.js +++ /dev/null @@ -1,50 +0,0 @@ -import { usefulAttr } from '../../resources/meta/reliquaries/artis-mark.js' - -const CharArtis = { - getCharArtisCfg (char, profile, artis) { - let { attr, weapon } = profile - let cn = '通用' - let check = true - - // 实验性实现,后期逐步迁移至配置文件 - switch (char.name) { - case '芭芭拉': - if (attr.cpct * 2 + attr.cdmg >= 180 && artis.mainAttr(4) === 'dmg') { - cn = '暴力' - } - break - case '钟离': - for (let idx = 3; idx <= 5; idx++) { - check = check && (artis.mainAttr(idx) === '大生命') - } - if (check) { - cn = '血牛' - } - break - case '雷电将军': - if (weapon.name === '薙草之稻光' && weapon.affix >= 3) { - cn = '高精' - } - break - } - - if (cn !== '通用' && usefulAttr[`${char.name}-${cn}`]) { - return { - title: `${char.abbr}-${cn}`, - attrWeight: usefulAttr[`${char.name}-${cn}`] - } - } else { - let artisSet = artis.getSetData()?.sets || {} - let weight = usefulAttr[char.name] || { atk: 75, cp: 100, cd: 100 } - if (artisSet['绝缘之旗印'] === 4 && weight.recharge < 75) { - weight.recharge = 75 - cn = '绝缘4' - } - return { - title: `${char.abbr}-${cn}`, - attrWeight: weight - } - } - } -} -export default CharArtis diff --git a/models/character-lib/CharImg.js b/models/character-lib/CharImg.js index c0174fc2..c9f7e2c8 100644 --- a/models/character-lib/CharImg.js +++ b/models/character-lib/CharImg.js @@ -56,18 +56,23 @@ const CharImg = { if (!['空', '荧', '旅行者'].includes(name)) { travelerElem = '' } + const rPath = `${process.cwd()}/plugins/miao-plugin/resources` const nPath = `/meta/character/${name}/` const tPath = `/meta/character/旅行者/${travelerElem}/` - let add = (key, path, traveler = false) => { - imgs[key] = `${traveler ? tPath : nPath}${path}.webp` + let add = (key, path, path2) => { + if (path2 && fs.existsSync(`${rPath}/${nPath}/${path2}.webp`)) { + imgs[key] = `${nPath}${path2}.webp` + } else { + imgs[key] = `${nPath}${path}.webp` + } } let tAdd = (key, path) => { - add(key, path, !!travelerElem) + imgs[key] = `${travelerElem ? tPath : nPath}${path}.webp` } - add('face', `imgs/face${costumeId}`) - add('side', `imgs/side${costumeId}`) + add('face', 'imgs/face', `imgs/face${costumeId}`) + add('side', 'imgs/side', `imgs/side${costumeId}`) add('gacha', 'imgs/gacha') - add('splash', `imgs/splash${costumeId}`) + add('splash', 'imgs/splash', `imgs/splash${costumeId}`) tAdd('card', 'imgs/card') tAdd('banner', 'imgs/banner') for (let i = 1; i <= 6; i++) { diff --git a/models/character-lib/CharMeta.js b/models/character-lib/CharMeta.js index 0f8b3a5c..de562e13 100644 --- a/models/character-lib/CharMeta.js +++ b/models/character-lib/CharMeta.js @@ -40,7 +40,7 @@ export const growAttrName = { const mKeys = [{ key: 'gem', - num: '1/9/6/6' + num: '1/9/9/6' }, { key: 'boss', num: '46', diff --git a/models/profile-lib/CharArtis.js b/models/profile-lib/CharArtis.js new file mode 100644 index 00000000..5d2b4683 --- /dev/null +++ b/models/profile-lib/CharArtis.js @@ -0,0 +1,51 @@ +import { usefulAttr } from '../../resources/meta/reliquaries/artis-mark.js' +import { Data } from '../../components/index.js' +import fs from 'fs' + +let charCfg = {} + +async function init () { + let charPath = process.cwd() + '/plugins/miao-plugin/resources/meta/character' + let chars = fs.readdirSync(charPath) + for (let char of chars) { + if (fs.existsSync(`${charPath}/${char}/artis.js`)) { + charCfg[char] = await Data.importModule(`resources/meta/character/${char}/artis.js`) + } + } +} + +await init() +const CharArtis = { + getCharArtisCfg (char, profile, artis) { + let { attr } = profile + + let rule = function (title, attrWeight) { + return { + title, + attrWeight + } + } + + let def = function (attrWeight) { + let title = '通用' + let weight = attrWeight || usefulAttr[char.name] || { atk: 75, cp: 100, cd: 100 } + if (artis.is('绝缘4') && weight.recharge < 75) { + weight.recharge = 75 + title = '绝缘4' + } + return { + title: `${char.abbr}-${title}`, + attrWeight: weight + } + } + + let charRule = charCfg[char.name]?.default || function ({ def }) { + return def(usefulAttr[char.name] || { atk: 75, cp: 100, cd: 100 }) + } + + if (charRule) { + return charRule({ attr, artis, rule, def, weapon: profile.weapon }) + } + } +} +export default CharArtis diff --git a/resources/meta/character/温迪/imgs/splash0.webp b/resources/meta/character/温迪/imgs/splash0.webp new file mode 100644 index 00000000..9d0e1dd0 Binary files /dev/null and b/resources/meta/character/温迪/imgs/splash0.webp differ diff --git a/resources/meta/character/芭芭拉/artis.js b/resources/meta/character/芭芭拉/artis.js new file mode 100644 index 00000000..8abf485c --- /dev/null +++ b/resources/meta/character/芭芭拉/artis.js @@ -0,0 +1,6 @@ +export default function ({ attr, artis, rule, def }) { + if (attr.cpct * 2 + attr.cdmg >= 180 && artis.mainAttr(4) === 'dmg') { + return rule('暴力芭芭拉', { hp: 50, atk: 75, cp: 100, cd: 100, mastery: 75, dmg: 100, recharge: 30, heal: 50 }) + } + return def({ hp: 100, atk: 50, cp: 50, cd: 50, dmg: 80, recharge: 55, heal: 100 }) +} diff --git a/resources/meta/character/钟离/artis.js b/resources/meta/character/钟离/artis.js new file mode 100644 index 00000000..fba1c929 --- /dev/null +++ b/resources/meta/character/钟离/artis.js @@ -0,0 +1,10 @@ +export default function ({ attr, artis, rule, def }) { + if (artis.is('hp', '4,5')) { + if (artis.is('绝缘4') && artis.is('hp,recharge', 3)) { + return rule('绝缘血牛钟离', { hp: 100, atk: 50, cp: 50, cd: 50, recharge: 100 }) + } else if (artis.is('hp', 3)) { + return rule('血牛钟离', { hp: 100, atk: 50, cp: 50, cd: 50, recharge: 50 }) + } + } + return def({ hp: 80, atk: 75, cp: 100, cd: 100, dmg: 100, phy: 50, recharge: 55 }) +} diff --git a/resources/meta/character/钟离/imgs/face2.webp b/resources/meta/character/钟离/imgs/face2.webp deleted file mode 100644 index f227785a..00000000 Binary files a/resources/meta/character/钟离/imgs/face2.webp and /dev/null differ diff --git a/resources/meta/character/钟离/imgs/side2.webp b/resources/meta/character/钟离/imgs/side2.webp deleted file mode 100644 index 749e8600..00000000 Binary files a/resources/meta/character/钟离/imgs/side2.webp and /dev/null differ diff --git a/resources/meta/character/钟离/imgs/splash0.webp b/resources/meta/character/钟离/imgs/splash0.webp new file mode 100644 index 00000000..5ecabc14 Binary files /dev/null and b/resources/meta/character/钟离/imgs/splash0.webp differ diff --git a/resources/meta/character/钟离/imgs/splash2.webp b/resources/meta/character/钟离/imgs/splash2.webp deleted file mode 100644 index d9e99fdb..00000000 Binary files a/resources/meta/character/钟离/imgs/splash2.webp and /dev/null differ diff --git a/resources/meta/character/雷电将军/artis.js b/resources/meta/character/雷电将军/artis.js new file mode 100644 index 00000000..ad09cfda --- /dev/null +++ b/resources/meta/character/雷电将军/artis.js @@ -0,0 +1,10 @@ +export default function ({ attr, weapon, rule, def }) { + // 辅助精通雷神,具体数值待定 + if (attr.mastery > 500) { + return rule('雷神-精通', { atk: 75, cp: 90, cd: 90, mastery: 100, dmg: 75, recharge: 90 }) + } + if (weapon.name === '薙草之稻光' && weapon.affix >= 3) { + return rule('雷神-高精', { atk: 90, cp: 100, cd: 100, dmg: 90, recharge: 90 }) + } + return def({ atk: 75, cp: 100, cd: 100, mastery: 0, dmg: 75, recharge: 90 }) +} diff --git a/resources/meta/character/雷电将军/imgs/face2.webp b/resources/meta/character/雷电将军/imgs/face0.webp similarity index 100% rename from resources/meta/character/雷电将军/imgs/face2.webp rename to resources/meta/character/雷电将军/imgs/face0.webp diff --git a/resources/meta/character/雷电将军/imgs/side2.webp b/resources/meta/character/雷电将军/imgs/side2.webp deleted file mode 100644 index f406c033..00000000 Binary files a/resources/meta/character/雷电将军/imgs/side2.webp and /dev/null differ diff --git a/resources/meta/character/雷电将军/imgs/splash2.webp b/resources/meta/character/雷电将军/imgs/splash0.webp similarity index 100% rename from resources/meta/character/雷电将军/imgs/splash2.webp rename to resources/meta/character/雷电将军/imgs/splash0.webp diff --git a/resources/meta/reliquaries/artis-mark.js b/resources/meta/reliquaries/artis-mark.js index 55604d69..8f7f7087 100644 --- a/resources/meta/reliquaries/artis-mark.js +++ b/resources/meta/reliquaries/artis-mark.js @@ -54,7 +54,6 @@ export const usefulAttr = { '雷电将军-高精': { hp: 0, atk: 90, def: 0, cp: 100, cd: 100, mastery: 0, dmg: 90, phy: 0, recharge: 90, heal: 0 }, 行秋: { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 0, dmg: 100, phy: 0, recharge: 75, heal: 0 }, 钟离: { hp: 80, atk: 75, def: 0, cp: 100, cd: 100, mastery: 0, dmg: 100, phy: 50, recharge: 55, heal: 0 }, - '钟离-血牛': { hp: 100, atk: 50, def: 0, cp: 50, cd: 50, mastery: 0, dmg: 0, phy: 0, recharge: 50, heal: 0 }, 神里绫华: { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 0, dmg: 100, phy: 0, recharge: 30, heal: 0 }, 香菱: { hp: 0, atk: 75, def: 0, cp: 100, cd: 100, mastery: 75, dmg: 100, phy: 0, recharge: 55, heal: 0 }, 胡桃: { hp: 80, atk: 50, def: 0, cp: 100, cd: 100, mastery: 75, dmg: 100, phy: 0, recharge: 0, heal: 0 },