新增*练度统计,请确保Miao-Yunzai为最新版本再更新

This commit is contained in:
Aluxes 2024-04-05 11:28:51 +08:00
parent 9fa319fb98
commit 20f4628084
No known key found for this signature in database
GPG Key ID: 6696152F9C003087
13 changed files with 141 additions and 76 deletions

View File

@ -72,7 +72,7 @@ app.reg({
profileStat: {
name: '面板练度统计',
fn: ProfileStat.stat,
rule: /^#(面板|喵喵)练度统计$/,
rule: /^#(星铁|原神)?(面板|喵喵)?练度统计$/,
yzRule: /^#*(我的)*(武器|角色|练度|五|四|5|4|星)+(汇总|统计|列表)(force|五|四|5|4|星)*[ |0-9]*$/,
yzCheck: () => Cfg.get('profileStat', false)
},
@ -94,7 +94,7 @@ app.reg({
refreshTalent: {
name: '强制刷新天赋',
fn: ProfileStat.refreshTalent,
rule: /^#(强制)?(刷新|更新)(所有|角色)*(天赋|技能)$/
rule: /^#(星铁|原神)?(强制)?(刷新|更新)(所有|角色)*(天赋|技能)$/
},
profileHelp: {

View File

@ -13,23 +13,32 @@ const ProfileStat = {
},
async refreshTalent (e) {
let game = /星铁/.test(e.msg) ? 'sr' : 'gs'
e.isSr = game === 'sr'
let mys = await MysApi.init(e)
if (!mys || !mys.uid) return false
let player = Player.create(e)
let player = Player.create(e, game)
let refreshCount = await player.refreshTalent('', 2)
if (refreshCount) {
if (refreshCount && !e.isSr) {
e.reply(`角色天赋更新成功,共${refreshCount}个角色\n你现在可以通过【#练度统计】【#天赋统计】来查看角色信息了...`)
} else if (e.isSr) {
e.reply(`角色天赋更新成功,共${refreshCount}个角色\n你现在可以通过【*练度统计】来查看角色信息了...`)
} else {
e.reply('角色天赋未能更新...')
}
},
// 渲染
// isAvatarList true:角色列表 false练度统计
// mode stat:练度统计 avatar:角色列表 talent:天赋统计
async render (e, mode = 'stat') {
let game = /星铁/.test(e.msg) ? 'sr' : 'gs'
e.isSr = game === 'sr'
e.game = game
// 缓存时间,单位小时
let msg = e.msg.replace('#', '').trim()
let msg = e.msg.replace(/#星铁|#/, '').trim()
if (msg === '角色统计' || msg === '武器统计') {
// 暂时避让一下抽卡分析的关键词
return false
@ -39,13 +48,12 @@ const ProfileStat = {
mode = 'talent'
}
let mys = await MysApi.init(e)
if (!mys || !mys.uid) return false
const uid = mys.uid
let player = Player.create(e)
let player = Player.create(e, game)
let avatarRet = await player.refreshAndGetAvatarData({
index: 2,
@ -112,7 +120,6 @@ const ProfileStat = {
goldCount: '金卡总数'
}
let tpl = mode === 'avatar' ? 'character/avatar-list' : 'character/profile-stat'
return await Common.render(tpl, {
save_id: uid,
@ -123,7 +130,8 @@ const ProfileStat = {
face,
mode,
week,
avatars: avatarRet
avatars: avatarRet,
game
}, { e, scale: 1.4 })
}
}

View File

@ -206,7 +206,7 @@ export default class Avatar extends Base {
level: ds.level || ds.lv || 1,
promote: lodash.isUndefined(ds.promote) ? Attr.calcPromote(ds.level || ds.lv || 1) : (ds.promote || 0),
affix: ds.affix,
...w.getData('star,abbr,type,img')
...w.getData('star,abbr,type,img,imgs')
}
if (this.weapon.level < 20) {
this.weapon.promote = 0

View File

@ -3,7 +3,7 @@ import { Version } from '#miao'
import { Button } from '#miao.models'
export default class MysApi {
constructor (e, uid, mysInfo) {
constructor(e, uid, mysInfo) {
this.e = e
this.mysInfo = mysInfo
this.ckInfo = mysInfo.ckInfo
@ -82,7 +82,7 @@ export default class MysApi {
if (this.mys) {
return this.mys
}
this.mys = await e.runtime.getMysApi(targetType, option)
this.mys = await e.runtime.getMysApi(targetType, option, e.isSr)
return this.mys
}
@ -146,6 +146,7 @@ export default class MysApi {
}
async getDetail (id) {
if (this.e.isSr) { return await this.getData('detail', { avatar_id: id, tab_from: 'TabOwned' }) }
return await this.getData('detail', { avatar_id: id })
}

View File

@ -17,7 +17,7 @@ Data.createDir('/data/PlayerData/gs', 'root')
Data.createDir('/data/PlayerData/sr', 'root')
export default class Player extends Base {
constructor (uid, game = 'gs') {
constructor(uid, game = 'gs') {
super()
uid = uid?._mys?.uid || uid?.uid || uid
if (!uid) {
@ -381,6 +381,9 @@ export default class Player extends Base {
let { talent } = avatar
let ds = avatar.getDetail()
ds.aeq = talent?.a?.original + talent?.e?.original + talent?.q?.original || 3
if (avatar.game === 'sr') {
ds.aeq = talent?.a?.original + talent?.e?.original + talent?.q?.original + talent?.t?.original || 4
}
avatarRet[ds.id] = ds
let profile = avatar.getProfile()
@ -407,6 +410,4 @@ export default class Player extends Base {
}
return avatarRet
}
}

View File

@ -1,12 +1,11 @@
import Base from './Base.js'
import { Data, Format, Meta } from '#miao'
import lodash from 'lodash'
let weaponSet
import lodash from 'lodash'
class Weapon extends Base {
constructor (meta, game = 'gs') {
constructor(meta, game = 'gs') {
if (!meta || !meta.name) {
return false
}
@ -309,7 +308,6 @@ class Weapon extends Base {
if (!tables[ds.idx]) return true
ds.data[ds.key] = tables[ds.idx]
} else if (ds.refine) {
lodash.forEach(ds.refine, (r, key) => {
ds.data[key] = ({ refine }) => r[refine] * (ds.buffCount || 1)
})

View File

@ -17,13 +17,6 @@ const MysAvatar = {
return force
}
return force
// 暂时不处理ck变更
player._info = 0
player._mys = 0
player.forEachAvatar((avatar) => {
avatar._talent = 0
})
return 2
},
/**
* 更新米游社角色信息
@ -241,7 +234,8 @@ const MysAvatar = {
let id = char.id
let talent = {}
let talentRes = await mys.getDetail(id)
if (talentRes && talentRes.skill_list) {
let game = avatar.game
if (game === 'gs' && 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
@ -257,6 +251,27 @@ const MysAvatar = {
talent.q = lv
}
}
} else if (game === 'sr' && talentRes && talentRes.skills) {
let talentList = lodash.orderBy(talentRes.skills, ['point_id'], ['asc'])
for (let val of talentList) {
let { cur_level: lv, anchor } = val
if (anchor.includes('Point01')) {
talent.a = lv
continue
}
if (anchor.includes('Point02')) {
talent.e = lv
continue
}
if (anchor.includes('Point03')) {
talent.q = lv
continue
}
if (anchor.includes('Point04')) {
talent.t = lv
continue
}
}
}
let ret = char.getAvatarTalent(talent, avatar.cons, 'original')
avatar.setTalent(ret, 'original', true)

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 674 KiB

View File

@ -1,11 +1,3 @@
body {
background: url('./imgs/bg-01.jpg') left center;
background-size: 100% auto;
}
.container {
background: url('./imgs/main-01.png') center -25px no-repeat;
background-size: 100% auto;
}
.head-box {
margin-top: 0;
}
@ -266,6 +258,10 @@ body {
.cont .tr .lv5.talent-plus {
color: #b70000;
}
.cont .tr .lv5.crown-sr {
background: url("../common/item/crown-sr-o.png") center center no-repeat rgba(255, 36, 26, 0.55);
background-size: contain;
}
.cont .td-artis {
width: 115px;
text-align: left;
@ -392,4 +388,3 @@ body {
.cont-notice span {
margin-left: 5px;
}
/*# sourceMappingURL=profile-stat.css.map */

View File

@ -1,14 +1,41 @@
{{extend defaultLayout}}
{{set isSr = game === 'sr'}}
{{block 'css'}}
<link rel="stylesheet" type="text/css" href="{{_res_path}}/character/profile-stat.css"/>
{{if isSr}}
<style>
body {
background: url('{{_res_path}}/character/imgs/bg-02.jpg') left center;
background-size: 100% auto;
}
.container {
background: url('{{_res_path}}/character/imgs/main-02.png') center -25px no-repeat;
background-size: 100% auto;
}
</style>
{{else}}
<style>
body {
background: url('{{_res_path}}/character/imgs/bg-01.jpg') left center;
background-size: 100% auto;
}
.container {
background: url('{{_res_path}}/character/imgs/main-01.png') center -25px no-repeat;
background-size: 100% auto;
}
</style>
{{/if}}
<link rel="stylesheet" type="text/css" href="{{_res_path}}/character/profile-stat.css" />
{{/block}}
{{block 'main'}}
<div class="head-box">
<div class="title">#面板练度统计</div>
<div class="label">UID:{{uid}} 共{{avatars.length }}名角色</div>
<div class="title">{{isSr?'*':'#'}}面板练度统计</div>
<div class="label">UID:{{uid}} 共{{avatars.length}}名角色</div>
</div>
<div id="profile-stat">
<div class="cont">
@ -17,23 +44,28 @@
<div class="td-idx">#</div>
<div class="td-name">角色</div>
<div class="td-lv">Lv</div>
<div class="td-cons">命座</div>
<div class="td-cons">{{isSr?'星魂':'命座'}}</div>
{{if !isSr}}
<div class="td-fetter">好感</div>
{{/if}}
<div class="td-talent">A</div>
<div class="td-talent">E</div>
<div class="td-talent">Q</div>
{{if isSr}}
<div class="td-talent">T</div>
{{/if}}
{{if mode === 'talent'}}
<div class="td">周本</div>
<div class="td">天赋书</div>
{{else}}
<div class="td-weapon">武器</div>
<div class="td-artis">圣遗物</div>
<div class="td-weapon">{{isSr?'光锥':'武器'}}</div>
<div class="td-artis">{{isSr?'遗器':'圣遗物'}}</div>
{{/if}}
</div>
{{each avatars avatar idx}}
{{set talent = avatar.talent}}
{{set weapon = avatar.weapon}}
{{set tk = ['a','e','q'] }}
{{set tk = isSr?['a','e','q','t']:['a','e','q']}}
<div class="avatar tr">
<div class="td td-idx star{{avatar.star}}">{{idx+1}}</div>
<div class="td td-name star{{avatar.star}}">
@ -49,15 +81,26 @@
<div class="td td-cons">
<span class="cons avatar cons-{{avatar.cons}}">{{avatar.cons}}</span>
</div>
{{if !isSr}}
<div class="td td-fetter">
<span class="fetter fetter{{['空','荧','旅行者'].includes(avatar.name)?10:avatar.fetter}}"></span>
</div>
{{/if}}
{{set talentLvMap = [0,1,1,1,2,2,3,3,3,4,5] }}
{{set talentALvMap = [0,1,1,2,3,4,5]}}
{{each tk talentKey}}
{{set curr = (avatar.talent||{})[talentKey] || {original:1,level:'-'} }}
<div class="td-talent lv{{talentLvMap[curr.original]}} {{curr.level>curr.original?'talent-plus':''}}">
{{if isSr && talentKey === 'a'}}
<div
class="td-talent lv{{talentALvMap[curr.original]}} {{curr.level>curr.original?'talent-plus':''}} {{isSr?'crown-sr':''}}">
{{curr.level}}
</div>
{{else}}
<div
class="td-talent lv{{talentLvMap[curr.original]}} {{curr.level>curr.original?'talent-plus':''}} {{isSr?'crown-sr':''}}">
{{curr.level}}
</div>
{{/if}}
{{/each}}
{{if mode === 'talent'}}
{{set m = avatar.materials || {} }}
@ -81,7 +124,8 @@
<div class="item-banner star{{weapon.star}}">
<span class="level">{{weapon.level}}</span>
<div class="item-icon weapon-icon">
<span class="img" style="background-image:url({{_res_path}}{{weapon.img}})"></span>
<span class="img"
style="background-image:url({{_res_path}}{{isSr?weapon.imgs?.icon2:weapon.img}})"></span>
</div>
<span class="cons weapon cons-{{weapon.affix+1}} star{{weapon.star}}">{{weapon.affix}}</span>
<span class="item-name">{{weapon.abbr}}</span>
@ -118,19 +162,19 @@
{{if ut.profile || ut.mys}}
<strong>数据更新时间</strong>
{{if ut.profile}}
<span>#更新面板: {{ut.profile}}</span>
<span>{{isSr?'*':'#'}}更新面板: {{ut.profile}}</span>
{{/if}}
{{if ut.mys}}
<span>米游社: {{ut.mys}}</span>
<div>
天赋数据每2小时最多更新一次可通过<strong>#刷新天赋</strong>来强制刷新天赋数据需具备有效CK
天赋数据每2小时最多更新一次可通过<strong>{{isSr?'*':'#'}}刷新天赋</strong>来强制刷新天赋数据需具备有效CK
</div>
{{/if}}
{{else}}
未绑定CK或CK失效信息可能不完全。发送<strong>#体力帮助</strong>查看CK绑定方法发送<strong>#更新面板</strong>更新游戏内角色展柜信息
未绑定CK或CK失效信息可能不完全。发送<strong>#体力帮助</strong>查看CK绑定方法发送<strong>{{isSr?'*':'#'}}更新面板</strong>更新游戏内角色展柜信息
{{/if}}
</div>
</div>
</div>
{{/block}}
{{/block}}

View File

@ -1,13 +1,3 @@
body {
background: url('./imgs/bg-01.jpg') left center;
background-size: 100% auto;
}
.container {
background: url('./imgs/main-01.png') center -25px no-repeat;
background-size: 100% auto;
}
.head-box {
margin-top: 0;
}
@ -57,7 +47,8 @@ body {
font-size: 14px;
background: none;
.cons, .level {
.cons,
.level {
height: 22px;
line-height: 22px;
display: inline-block;
@ -89,7 +80,7 @@ body {
background: rgba(0, 0, 0, .4);
font-weight: bold;
& > div {
&>div {
box-shadow: 0 0 1px 0 rgba(255, 255, 255, .7);
text-align: center;
}
@ -107,7 +98,7 @@ body {
box-shadow: 0 0 1px 0 rgba(100, 100, 100, .3) inset;
}
.star(@s, @color, @color2:#333) {
.star(@s, @color, @color2: #333) {
.td.star@{s} {
background: @color;
@ -116,6 +107,7 @@ body {
}
}
}
.star(1, rgba(200, 200, 200, 0.35));
.star(2, rgba(168, 255, 133, 0.35));
.star(3, rgba(137, 168, 255, 0.35));
@ -125,7 +117,7 @@ body {
&.thead {
background: rgba(0, 0, 0, 0.5) !important;
& > div {
&>div {
color: #d3bc8e !important;
}
}
@ -138,7 +130,7 @@ body {
background: rgba(240, 240, 240, 1);
}
& > div {
&>div {
text-align: center;
height: 36px;
vertical-align: middle;
@ -248,9 +240,7 @@ body {
}
}
.td-talent {
}
.td-talent {}
.talent-plus {
font-weight: bold;
@ -259,7 +249,7 @@ body {
text-shadow: 0px 0px 1px #fff;
}
.lv(@lv, @c1, @c2:#333) {
.lv(@lv, @c1, @c2: #333) {
.lv@{lv} {
background: @c1;
@ -268,6 +258,7 @@ body {
}
}
}
.lv(1, rgba(60, 63, 65, .3));
.lv(2, rgba(23, 184, 58, .5), #005800);
.lv(3, rgba(27, 128, 212, .5));
@ -280,6 +271,11 @@ body {
&.talent-plus {
color: #b70000;
}
&.crown-sr {
background: url("../common/item/crown-sr-o.png") center center no-repeat rgba(255, 36, 26, .55);
background-size: contain;
}
}
@ -298,7 +294,9 @@ body {
text-align: left;
&.class- {
&ACE, &MAX {
&ACE,
&MAX {
background: rgba(255, 228, 180, .5);
.artis-mark-class {
@ -306,7 +304,8 @@ body {
}
}
&SSS, &SS {
&SSS,
&SS {
background: rgba(223, 190, 255, .5);
.artis-mark-class {
@ -314,7 +313,8 @@ body {
}
}
&S, &A {
&S,
&A {
background: rgba(190, 208, 255, .5);
.artis-mark-class {
@ -322,7 +322,9 @@ body {
}
}
&B, &C, &D {
&B,
&C,
&D {
background: rgba(171, 171, 171, .5);
.artis-mark-class {
@ -410,7 +412,8 @@ body {
text-align: left !important;
}
.td-weekly, .td-material {
.td-weekly,
.td-material {
&.today {
background: rgba(255, 212, 132, 0.35);
@ -442,4 +445,4 @@ body {
span {
margin-left: 5px;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB