diff --git a/apps/character/ProfileRank.js b/apps/character/ProfileRank.js new file mode 100644 index 00000000..f592e271 --- /dev/null +++ b/apps/character/ProfileRank.js @@ -0,0 +1,25 @@ +import { Character, ProfileRank } from '../../models/index.js' +import { renderProfile } from './ProfileDetail.js' + +export async function groupMaxProfile (e) { + let groupId = e.group_id + if (!groupId) { + return false + } + let msg = e.original_msg || e.msg + + if (!/(最强|最高|最高分|最牛|第一)/.test(msg)) { + return false + } + let mode = /(分|圣遗物|评分|ACE)/.test(msg) ? 'mark' : 'dmg' + let name = msg.replace(/(#|最强|最高分|第一|最高|最牛|圣遗物|评分|群|面板|面版|详情)/g, '') + let char = Character.get(name) + if (!char) { + return false + } + let uid = await ProfileRank.getGroupMaxUid(groupId, char.id, mode) + if (uid) { + e.uid = uid + return await renderProfile(e, char) + } +} diff --git a/apps/profile.js b/apps/profile.js index 70e00e61..8498d2b1 100644 --- a/apps/profile.js +++ b/apps/profile.js @@ -6,6 +6,7 @@ import { renderProfile } from './character/ProfileDetail.js' import { profileStat } from './character/ProfileStat.js' import { profileList } from './character/ProfileList.js' import { enemyLv } from './character/ProfileUtils.js' +import { groupMaxProfile } from './character/ProfileRank.js' let app = App.init({ id: 'profile', @@ -16,6 +17,11 @@ app.reg('profile-detail', profileDetail, { name: '角色面板' }) +app.reg('group-profile', groupMaxProfile, { + rule: /^#?(群|群内)?(最强|最高|最高分|最牛|第一)+.+/, + name: '群内最强' +}) + app.reg('artis-list', profileArtisList, { rule: /^#圣遗物列表\s*(\d{9})?$/, name: '面板圣遗物列表' @@ -66,6 +72,10 @@ export async function profileDetail (e) { msg = msg.replace('面版', '面板') let dmgRet = /伤害(\d?)$/.exec(name) let dmgIdx = 0 + if (/(最强|最高|最高分|最牛|第一)/.test(msg)) { + mode = /(分|圣遗物|评分|ACE)/.test(msg) ? 'rank-mark' : 'rank-dmg' + name = name.replace(/(最强|最高分|第一|最高|最牛|圣遗物|评分|群)/g, '') + } if (/(详情|详细|面板|面版)\s*$/.test(msg) && !/更新|录入|输入/.test(msg)) { mode = 'profile' name = name.replace(/(详情|详细|面板)/, '').trim() @@ -98,7 +108,7 @@ export async function profileDetail (e) { } if (e.isPrivate) { if ((e.sub_type === 'friend' && Cfg.get('profile.friend.status') === false) || - (e.sub_type === 'group' && Cfg.get('profile.stranger.status') === false)) { + (e.sub_type === 'group' && Cfg.get('profile.stranger.status') === false)) { return false } } else if (e.isGroup) { diff --git a/models/ProfileData.js b/models/ProfileData.js index 98b9d391..7c3c47d1 100644 --- a/models/ProfileData.js +++ b/models/ProfileData.js @@ -146,6 +146,10 @@ export default class ProfileData extends Base { return {} } + get hasDmg () { + return this.hasData && !!ProfileDmg.dmgRulePath(this.name) + } + // 计算当前profileData的伤害信息 async calcDmg ({ enemyLv = 91, mode = 'profile', dmgIdx = 0 }) { if (!this.dmg) { diff --git a/models/ProfileDmg.js b/models/ProfileDmg.js index 588c173a..67ac2a78 100644 --- a/models/ProfileDmg.js +++ b/models/ProfileDmg.js @@ -17,6 +17,15 @@ export default class ProfileDmg extends Base { } } + static dmgRulePath (name) { + const _path = process.cwd() + let path = `${_path}/plugins/miao-plugin/resources/meta/character/${name}/calc.js` + if (fs.existsSync(path)) { + return path + } + return false + } + // 获取天赋数据 talent () { let char = this.char @@ -65,16 +74,16 @@ export default class ProfileDmg extends Base { } async getCalcRule () { - const _path = process.cwd() - const cfgPath = `${_path}/plugins/miao-plugin/resources/meta/character/${this.char?.name}/calc.js` + const cfgPath = ProfileDmg.dmgRulePath(this.char?.name) let cfg = {} - if (fs.existsSync(cfgPath)) { + if (cfgPath) { cfg = await import(`file://${cfgPath}`) return { details: cfg.details || false, // 计算详情 buffs: cfg.buffs || [], // 角色buff defParams: cfg.defParams || {}, // 默认参数,一般为空 defDmgIdx: cfg.defDmgIdx || -1, // 默认详情index + defDmgKey: cfg.defDmgKey || '', mainAttr: cfg.mainAttr || 'atk,cpct,cdmg', // 伤害属性 enemyName: cfg.enemyName || '小宝' // 敌人名称 } @@ -92,7 +101,7 @@ export default class ProfileDmg extends Base { if (!charCalcData) { return false } - let { buffs, details, defParams, mainAttr, defDmgIdx, enemyName } = charCalcData + let { buffs, details, defParams, mainAttr, defDmgIdx, defDmgKey, enemyName } = charCalcData let talent = this.talent() @@ -115,7 +124,21 @@ export default class ProfileDmg extends Base { let dmgRet = [] let dmgDetail = {} + if (mode === 'single') { + dmgIdx = defDmgIdx > -1 ? defDmgIdx : 0 + } + lodash.forEach(details, (detail, detailSysIdx) => { + if (mode === 'single') { + if (defDmgKey) { + if (detail.dmgKey !== defDmgKey) { + return true + } + } else if (detailSysIdx !== dmgIdx) { + return true + } + } + if (lodash.isFunction(detail)) { let { attr } = DmgAttr.calcAttr({ originalAttr, buffs, meta }) let ds = lodash.merge({ talent }, DmgAttr.getDs(attr, meta)) @@ -196,6 +219,10 @@ export default class ProfileDmg extends Base { }) } + if (mode === 'single') { + return ret[0] + } + return { ret, msg, diff --git a/models/ProfileRank.js b/models/ProfileRank.js index 7a2223d3..b04d4491 100644 --- a/models/ProfileRank.js +++ b/models/ProfileRank.js @@ -20,26 +20,51 @@ export default class ProfileRank { if (!profile.hasData) { return false } - const key = this.key(profile, 'mark') - let rank = await redis.zRevRank(key, this.uid) - if (!lodash.isNumber(rank) || force) { + let ret = {} + const markKey = this.key(profile, 'mark') + let markRank = await redis.zRevRank(markKey, this.uid) + if (!lodash.isNumber(markRank) || force) { let mark = profile.getArtisMark(false) if (mark) { - await redis.zAdd(key, { score: mark._mark, value: this.uid }) - rank = await redis.zRevRank(key, this.uid) + await redis.zAdd(markKey, { score: mark._mark, value: this.uid }) + markRank = await redis.zRevRank(markKey, this.uid) } } - if (lodash.isNumber(rank)) { - let count = await redis.zCard(key) - let mark = await redis.zScore(key, this.uid) - return { - rank: rank + 1, - count, - value: Format.comma(mark, 1), - _value: mark, - pct: Format.percent(Math.max(0.01, Math.min(0.999, (count - rank) / count))) + if (lodash.isNumber(markRank)) { + let markCount = await redis.zCard(markKey) + ret.markRank = markRank + 1 + ret.markCount = markCount + } + if (profile.hasDmg) { + const dmgKey = this.key(profile, 'dmg') + let dmgRank = await redis.zRevRank(dmgKey, this.uid) + if (!lodash.isNumber(dmgRank) || force) { + let dmg = await profile.calcDmg({ mode: 'single' }) + if (dmg) { + await redis.zAdd(dmgKey, { score: dmg.avg, value: this.uid }) + dmgRank = await redis.zRevRank(dmgKey, this.uid) + } + } + if (lodash.isNumber(dmgRank)) { + let dmgCount = await redis.zCard(dmgKey) + ret.dmgRank = dmgRank + 1 + ret.dmgCount = dmgCount } } - return false + if (lodash.isEmpty(ret)) { + return false + } + if (!ret.dmgRank || ret.markRank < ret.dmgRank) { + ret.rank = ret.markRank + ret.rankType = 'mark' + } else { + ret.rank = ret.dmgRank + ret.rankType = 'dmg' + } + return ret + } + + static async getGroupMaxUid (groupId, charId, type = 'mark') { + return await redis.zRange(`miao:rank:${groupId}:${type}:${charId}`, -1, -1) } } diff --git a/resources/character/imgs/dmg-rank-bg.png b/resources/character/imgs/dmg-rank-bg.png new file mode 100644 index 00000000..32491dcd Binary files /dev/null and b/resources/character/imgs/dmg-rank-bg.png differ diff --git a/resources/character/imgs/mark-icon.png b/resources/character/imgs/mark-icon.png new file mode 100644 index 00000000..330bbc28 Binary files /dev/null and b/resources/character/imgs/mark-icon.png differ diff --git a/resources/character/imgs/mark-rank-bg.png b/resources/character/imgs/mark-rank-bg.png new file mode 100644 index 00000000..118e8d35 Binary files /dev/null and b/resources/character/imgs/mark-rank-bg.png differ diff --git a/resources/character/imgs/rank-bg.png b/resources/character/imgs/rank-bg.png deleted file mode 100644 index d4598f59..00000000 Binary files a/resources/character/imgs/rank-bg.png and /dev/null differ diff --git a/resources/character/profile-list.css b/resources/character/profile-list.css index 5e715c14..5b5b495f 100644 --- a/resources/character/profile-list.css +++ b/resources/character/profile-list.css @@ -47,7 +47,7 @@ body, } .char-item .group-rank { position: absolute; - background: url('./imgs/rank-bg.png') left top no-repeat; + background: url('./imgs/dmg-rank-bg.png') left top no-repeat; background-size: auto 100%; left: 0; top: 0; @@ -55,6 +55,9 @@ body, width: 74px; height: 74px; } +.char-item .group-rank.rank-type-mark { + background-image: url('./imgs/mark-rank-bg.png'); +} .char-item .group-rank span { position: absolute; font-size: 12px; @@ -117,7 +120,20 @@ body, border-radius: 50%; margin-right: 3px; } -.no-rank .group-rank { +.group-rank-icon { + width: 16px; + height: 16px; + background: url("./imgs/mark-icon.png"); + background-size: auto 100%; + display: inline-block; + vertical-align: middle; + margin-right: 2px; +} +.group-rank-icon.mark-icon { + background-position: 100% 0; +} +.no-rank .group-rank, +.no-rank .group-rank-tip { display: none; } /*# sourceMappingURL=profile-list.css.map */ \ No newline at end of file diff --git a/resources/character/profile-list.html b/resources/character/profile-list.html index 7cda2d14..997fd538 100644 --- a/resources/character/profile-list.html +++ b/resources/character/profile-list.html @@ -27,7 +27,7 @@ {{if char.groupRank}} {{set gr = char.groupRank}} {{set rank = gr.rank > 9 ? 10:(gr.rank <=3 ? gr.rank : 4)}} -
+
{{gr.rank}}
{{/if}} @@ -38,7 +38,10 @@ {{if hasNew}} 本次更新角色 {{else}} - + 群内排名: + 综合练度 + 圣遗物评分 + {{/if}} 当前更新服务:{{servName}}
diff --git a/resources/character/profile-list.less b/resources/character/profile-list.less index 8d4f6ea5..b9afc812 100644 --- a/resources/character/profile-list.less +++ b/resources/character/profile-list.less @@ -56,7 +56,7 @@ body, .container { .group-rank { position: absolute; - background: url('./imgs/rank-bg.png') left top no-repeat; + background: url('./imgs/dmg-rank-bg.png') left top no-repeat; background-size: auto 100%; left: 0; top: 0; @@ -64,6 +64,10 @@ body, .container { width: 74px; height: 74px; + &.rank-type-mark { + background-image: url('./imgs/mark-rank-bg.png'); + } + span { position: absolute; font-size: 12px; @@ -141,6 +145,21 @@ body, .container { } } -.no-rank .group-rank { +.group-rank-icon { + width: 16px; + height: 16px; + background: url("./imgs/mark-icon.png"); + background-size: auto 100%; + display: inline-block; + vertical-align: middle; + margin-right: 2px; + + &.mark-icon { + background-position: 100% 0; + } +} + +.no-rank .group-rank, +.no-rank .group-rank-tip { display: none; } \ No newline at end of file diff --git a/resources/meta/character/优菈/calc.js b/resources/meta/character/优菈/calc.js index e4dce22f..86d1cc79 100644 --- a/resources/meta/character/优菈/calc.js +++ b/resources/meta/character/优菈/calc.js @@ -41,6 +41,7 @@ export const details = [{ } }] +export const defDmgIdx = 3 export const mainAttr = 'atk,cpct,cdmg' export const enemyName = '魔偶/女士/雷神' diff --git a/resources/meta/character/八重神子/calc.js b/resources/meta/character/八重神子/calc.js index c28efa68..64c2e9e7 100644 --- a/resources/meta/character/八重神子/calc.js +++ b/resources/meta/character/八重神子/calc.js @@ -1,9 +1,11 @@ export const details = [{ check: ({ cons }) => cons < 2, + dmgKey: 'e', title: '叄阶杀生樱伤害', dmg: ({ talent, attr }, dmg) => dmg(talent.e['杀生樱伤害·叁阶'], 'e') }, { check: ({ cons }) => cons >= 2, + dmgKey: 'e', title: '肆阶杀生樱伤害', dmg: ({ talent, attr }, dmg) => dmg(talent.e['杀生樱伤害·肆阶'], 'e') }, { @@ -15,6 +17,7 @@ export const details = [{ }] export const mainAttr = 'atk,cpct,cdmg,mastery' +export const defDmgKey = 'e' export const buffs = [{ title: '被动天赋:基于元素精通提高杀生樱伤害[eDmg]%', diff --git a/resources/meta/character/刻晴/calc.js b/resources/meta/character/刻晴/calc.js index e5931074..4a2a6a40 100644 --- a/resources/meta/character/刻晴/calc.js +++ b/resources/meta/character/刻晴/calc.js @@ -10,6 +10,7 @@ export const details = [{ dmg: ({ talent }, dmg) => dmg(talent.q['技能伤害'] + talent.q['连斩伤害'] + talent.q['最后一击伤害'], 'q') }] +export const defDmgIdx = 2 export const mainAttr = 'atk,cpct,cdmg' export const buffs = [{ diff --git a/resources/meta/character/可莉/calc.js b/resources/meta/character/可莉/calc.js index a9c72121..325ef3f5 100644 --- a/resources/meta/character/可莉/calc.js +++ b/resources/meta/character/可莉/calc.js @@ -11,6 +11,7 @@ export const details = [{ dmg: ({ talent }, dmg) => dmg(talent.q['轰轰火花伤害'], 'q') }] +export const defDmgIdx = 1 export const mainAttr = 'atk,cpct,cdmg,mastery' export const buffs = [{ diff --git a/resources/meta/character/夜兰/calc.js b/resources/meta/character/夜兰/calc.js index d6699f90..37ed9142 100644 --- a/resources/meta/character/夜兰/calc.js +++ b/resources/meta/character/夜兰/calc.js @@ -18,6 +18,7 @@ export const details = [{ } }] +export const defDmgIdx = 2 export const mainAttr = 'hp,cpct,cdmg' export const buffs = [{ diff --git a/resources/meta/character/宵宫/calc.js b/resources/meta/character/宵宫/calc.js index cf5a2155..0732858e 100644 --- a/resources/meta/character/宵宫/calc.js +++ b/resources/meta/character/宵宫/calc.js @@ -12,6 +12,7 @@ export const details = [{ dmg: ({ talent }, dmg) => dmg(talent.a['五段伤害'], 'a', 'vaporize') }] +export const defDmgIdx = 2 export const mainAttr = 'atk,cpct,cdmg,mastery' export const buffs = [{ diff --git a/resources/meta/character/温迪/calc.js b/resources/meta/character/温迪/calc.js index e84bf47e..8485ea3b 100644 --- a/resources/meta/character/温迪/calc.js +++ b/resources/meta/character/温迪/calc.js @@ -4,6 +4,7 @@ export const details = [{ }, { title: 'Q单段伤害', params: { q: true }, + dmgKey: 'q', dmg: ({ talent }, dmg) => dmg(talent.q['持续伤害'], 'q') }, { title: 'Q含转化单段', @@ -22,6 +23,7 @@ export const details = [{ dmg: ({}, { reaction }) => reaction('swirl') }] +export const defDmgKey = 'q' export const mainAttr = 'atk,cpct,cdmg,mastery' export const buffs = [{ diff --git a/resources/meta/character/烟绯/calc.js b/resources/meta/character/烟绯/calc.js index e9ae886d..92d635da 100644 --- a/resources/meta/character/烟绯/calc.js +++ b/resources/meta/character/烟绯/calc.js @@ -10,7 +10,8 @@ export const details = [{ title: 'E伤害', dmg: ({ talent }, dmg) => dmg(talent.e['技能伤害'], 'e') }] - +export const defDmgIdx = 1 +export const mainAttr = 'atk,cpct,cdmg,mastery' export const buffs = [{ title: '烟绯被动:重击消耗4枚丹火印增加20%火伤', cons: 6, diff --git a/resources/meta/character/珊瑚宫心海/calc.js b/resources/meta/character/珊瑚宫心海/calc.js index 4f39ce7b..b280ba70 100644 --- a/resources/meta/character/珊瑚宫心海/calc.js +++ b/resources/meta/character/珊瑚宫心海/calc.js @@ -3,15 +3,19 @@ import lodash from 'lodash' export const details = [{ check: ({ cons }) => cons < 2, title: '水母每跳治疗', + dmgKey: 'q', dmg: ({ attr, talent, calc }, { heal }) => { - let t = talent.e['治疗量2']; let hp = calc(attr.hp) + let t = talent.e['治疗量2']; + let hp = calc(attr.hp) return heal(hp * t[0] / 100 + t[1] * 1) } }, { cons: 2, title: '半血水母每跳治疗', + dmgKey: 'q', dmg: ({ attr, talent, calc }, { heal }) => { - let t = talent.e['治疗量2']; let hp = calc(attr.hp) + let t = talent.e['治疗量2']; + let hp = calc(attr.hp) return heal(hp * t[0] / 100 + t[1] * 1 + hp * 0.045) } }, { @@ -37,7 +41,7 @@ export const details = [{ return ret } }] - +export const defDmgKey = 'q' export const defDmgIdx = 2 export const mainAttr = 'hp,atk' diff --git a/resources/meta/character/琴/calc.js b/resources/meta/character/琴/calc.js index ff706609..cb9e2950 100644 --- a/resources/meta/character/琴/calc.js +++ b/resources/meta/character/琴/calc.js @@ -7,6 +7,7 @@ export const details = [{ dmg: ({ talent }, dmg) => dmg(talent.q['爆发伤害'], 'q') }, { title: 'Q爆发治疗', + dmgKey: 'qHeal', dmg: ({ talent, calc, attr }, { heal }) => heal(talent.q['领域发动治疗量2'][0] * calc(attr.atk) / 100 + talent.q['领域发动治疗量2'][1] * 1) }, { @@ -16,6 +17,7 @@ export const details = [{ }] export const mainAttr = 'atk,cpct,cdmg' +export const defDmgKey = 'qHeal' export const buffs = [{ cons: 1, diff --git a/resources/meta/character/神里绫华/calc.js b/resources/meta/character/神里绫华/calc.js index 221869f4..45f6d87c 100644 --- a/resources/meta/character/神里绫华/calc.js +++ b/resources/meta/character/神里绫华/calc.js @@ -6,10 +6,12 @@ export const details = [{ dmg: ({ talent }, dmg) => dmg(talent.e['技能伤害'], 'e') }, { title: '神里流·霜灭 单段伤害', + dmgKey: 'q', dmg: ({ talent }, dmg) => dmg(talent.q['切割伤害'], 'q') }] export const mainAttr = 'atk,cpct,cdmg' +export const defDmgKey = 'q' export const buffs = [{ passive: 1, diff --git a/resources/meta/character/纳西妲/calc.js b/resources/meta/character/纳西妲/calc.js index 8f606e39..a87d5740 100644 --- a/resources/meta/character/纳西妲/calc.js +++ b/resources/meta/character/纳西妲/calc.js @@ -40,6 +40,7 @@ export const details = [{ } }] +export const defDmgIdx = 4 export const mainAttr = 'atk,mastery,cpct,cdmg' export const buffs = [{ @@ -72,6 +73,6 @@ export const buffs = [{ title: '草神Q:开Q提升灭净三业伤害[eDmg]%', data: { eDmg: ({ cons, talent, params }) => (params.q === false ? 0 : 1) * - (cons >= 1 ? talent.q['火2伤害提升'] : talent.q['火1伤害提升']) + (cons >= 1 ? talent.q['火2伤害提升'] : talent.q['火1伤害提升']) } }] diff --git a/resources/meta/character/芭芭拉/calc.js b/resources/meta/character/芭芭拉/calc.js index f54acc55..38b43c90 100644 --- a/resources/meta/character/芭芭拉/calc.js +++ b/resources/meta/character/芭芭拉/calc.js @@ -10,11 +10,13 @@ export const details = [{ heal(talent.e['持续治疗量2'][0] * calc(attr.hp) / 100 + talent.e['持续治疗量2'][1] * 1) }, { title: 'Q治疗量', + dmgKey: 'qHeal', dmg: ({ talent, attr, calc }, { heal }) => heal(talent.q['治疗量2'][0] * calc(attr.hp) / 100 + talent.q['治疗量2'][1] * 1) }] export const defDmgIdx = 1 +export const defDmgKey = 'qHeal' export const mainAttr = 'atk,hp,cpct,cdmg,mastery' export const buffs = [{ diff --git a/resources/meta/character/赛诺/calc.js b/resources/meta/character/赛诺/calc.js index 4cd3a8c0..9a5b4f0b 100644 --- a/resources/meta/character/赛诺/calc.js +++ b/resources/meta/character/赛诺/calc.js @@ -23,6 +23,7 @@ export const details = [{ dmg: ({ talent }, dmg) => dmg(100, 'e') }] +export const defDmgIdx = 2 export const mainAttr = 'atk,cpct,cdmg,mastery' export const buffs = [{ @@ -38,7 +39,7 @@ export const buffs = [{ dmg: 50 } }, { - title: '赛诺被动:末途真眼状态提升E 35%伤害,发射渡荒之类造成100%攻击力伤害', + title: '赛诺被动:末途真眼状态提升E 35%伤害,发射渡荒之雷造成100%攻击力伤害', data: { ePlus: ({ params }) => [3, 4].includes(params.q) ? 35 : 0 } diff --git a/resources/meta/character/迪卢克/calc.js b/resources/meta/character/迪卢克/calc.js index 3be5789e..28b4f94a 100644 --- a/resources/meta/character/迪卢克/calc.js +++ b/resources/meta/character/迪卢克/calc.js @@ -3,6 +3,7 @@ export const details = [{ dmg: ({ talent }, dmg) => dmg(talent.e['三段伤害'], 'e') }, { title: 'E三段蒸发', + dmgKey: 'e', dmg: ({ talent }, dmg) => dmg(talent.e['三段伤害'], 'e', 'vaporize') }, { title: 'Q爆发伤害', @@ -15,6 +16,7 @@ export const details = [{ }] export const defParams = { monv: 3 } +export const defDmgKey = 'e' export const mainAttr = 'atk,cpct,cdmg,mastery' export const buffs = [{ diff --git a/resources/meta/character/香菱/calc.js b/resources/meta/character/香菱/calc.js index c9483cb8..cd8a73b2 100644 --- a/resources/meta/character/香菱/calc.js +++ b/resources/meta/character/香菱/calc.js @@ -9,9 +9,11 @@ export const details = [{ dmg: ({ talent }, dmg) => dmg(talent.q['旋火轮伤害'], 'q') }, { title: '旋火轮单次蒸发', + dmgKey: 'q', dmg: ({ talent }, dmg) => dmg(talent.q['旋火轮伤害'], 'q', 'vaporize') }] +export const defDmgKey = 'q' export const mainAttr = 'atk,cpct,cdmg' export const buffs = [{