#面板#更新面板命令使用图片渲染结果

一些已知问题修复
This commit is contained in:
yoimiya-kokomi 2022-08-06 06:12:57 +08:00
parent 020c995a96
commit 041d46f788
19 changed files with 376 additions and 134 deletions

View File

@ -1,20 +1,24 @@
# 1.9.4
# 1.9.5
* `#面板`、`#更新面板`命令使用图片渲染结果
* Enka面板服务支持配置代理 **@永恒的小黑屋**
* 如需配置可在**miao-plugin/config/profile.js**文件中配置
* 一些已知问题修复
# 1.9.1 ~ 1.9.4
* `#上传深渊`使用图片渲染深渊结果,同时可被`#喵喵深渊`触发
* 可展示本期深渊的全部角色信息,包括组队、天赋及圣遗物
* 数据会上传至胡桃Api进行伤害排名并展示在页面内
* 可在`#喵喵设置`中启用`#喵喵深渊`作为默认`#深渊`,默认关闭
* 启用后不会覆盖`#上期深渊`以及`#深渊12层`具体楼层的命令
* 部分角色的圣遗物评分增加充能的词条评分权重
# 1.9.1 ~ 1.9.3
* `#更新面板`支持配置更新API适配Enka新校验逻辑
* B服角色使用Enka服务进行面板信息获取
* 感谢Enka官方 **@Algoinde**的官方授权及UA校验
* 感谢 **@MiniGrayGay**提供的Enka服务中转若面板更新失败可尝试在**miao-plugin/config/profile.js**文件中配置切换更新API
* 更新面板增加单用户更新间隔控制默认5分钟
* 修正部分V3Yunzai下的适配问题
* 部分角色的圣遗物评分增加充能的词条评分权重
# 1.9.0

View File

@ -1,25 +1,26 @@
import { Common, Cfg } from '../components/index.js'
import { renderAvatar } from './character/avatar-card.js'
import { getTargetUid, getProfile, profileHelp, getProfileAll } from './character/profile-common.js'
import { getTargetUid, getProfile, profileHelp, getProfileAll, inputProfile } from './character/profile-common.js'
import { profileArtis } from './character/profile-artis.js'
import { renderProfile } from './character/profile-detail.js'
import { Character } from '../components/models.js'
import { isV3 } from '../components/Changelog.js'
//
export { getProfileAll, getProfile, profileHelp }
export { enemyLv, getOriginalPicture } from './character/utils.js'
// 角色图像上传
export { uploadCharacterImg } from './character/character-img-upload.js'
//
export { getProfileAll, getProfile, profileHelp }
// 圣遗物列表
export { profileArtisList } from './character/profile-artis.js'
// 老婆
export { wife, pokeWife, wifeReg } from './character/avatar-wife.js'
// 面板角色列表
export { profileList } from './character/profile-list.js'
// 查看当前角色
export async function character (e, { render }) {
let msg = e.original_msg || e.msg
@ -108,8 +109,11 @@ export async function character (e, { render }) {
if (mode === 'profile' || mode === 'dmg') {
return renderProfile(e, char, render, mode, { dmgIdx })
} else if (mode === 'refresh' || mode === 'input') {
await getProfile(e, mode)
} else if (mode === 'input') {
await inputProfile(e, mode)
return true
} else if (mode === 'refresh') {
await getProfile(e, { render })
return true
} else if (mode === 'artis') {
return profileArtis(e, { render })

View File

@ -3,6 +3,7 @@
* */
import lodash from 'lodash'
import { segment } from 'oicq'
import { profileList } from './profile-list.js';
import Profile from '../../components/Profile.js'
import { Character } from '../../components/models.js'
import { isV3 } from '../../components/Changelog.js'
@ -150,33 +151,38 @@ export async function autoGetProfile (e, uid, avatar, callback) {
return { profile, char, refresh }
}
/*
* 面板数据更新
* */
export async function getProfile (e, mode = 'refresh') {
export async function inputProfile (e) {
let uid = await getTargetUid(e)
if (!uid) {
return true
}
if (mode === 'input') {
if (e.inputData.trim().length < 5) {
e.reply('【输入示例】\n#录入夜兰面板 生命14450+25469, 攻击652+444, 防御548+144, 元素精通84, 暴击76.3, 爆伤194.2, 治疗0,充能112.3,元素伤害61.6,物伤0')
return true
// await profileHelp(e);
}
if (e.inputData.trim().length < 5) {
e.reply('【输入示例】\n#录入夜兰面板 生命14450+25469, 攻击652+444, 防御548+144, 元素精通84, 暴击76.3, 爆伤194.2, 治疗0,充能112.3,元素伤害61.6,物伤0')
return true
// await profileHelp(e);
}
let ret = Profile.inputProfile(uid, e)
let char = Character.get(e.avatar)
if (lodash.isString(ret)) {
e.reply(ret)
return true
} else if (ret) {
e.reply(`${char.name}信息手工录入完成,你可以使用 #角色名+面板 / #角色名+伤害 来查看详细角色面板属性了`)
} else {
e.reply(`${char.name}信息手工录入失败,请检查录入格式。回复 #角色面板帮助 可查看录入提示`)
e.reply('【输入示例】\n#录入夜兰面板 生命14450+25469, 攻击652+444, 防御548+144, 元素精通84, 暴击76.3, 爆伤194.2, 治疗0,充能112.3,元素伤害61.6,物伤0')
}
let ret = Profile.inputProfile(uid, e)
let char = Character.get(e.avatar)
if (lodash.isString(ret)) {
e.reply(ret)
return true
} else if (ret) {
e.reply(`${char.name}信息手工录入完成,你可以使用 #角色名+面板 / #角色名+伤害 来查看详细角色面板属性了`)
} else {
e.reply(`${char.name}信息手工录入失败,请检查录入格式。回复 #角色面板帮助 可查看录入提示`)
e.reply('【输入示例】\n#录入夜兰面板 生命14450+25469, 攻击652+444, 防御548+144, 元素精通84, 暴击76.3, 爆伤194.2, 治疗0,充能112.3,元素伤害61.6,物伤0')
}
return true
}
/*
* 面板数据更新
* */
export async function getProfile (e, { render }) {
let uid = await getTargetUid(e)
if (!uid) {
return true
}
@ -189,17 +195,18 @@ export async function getProfile (e, mode = 'refresh') {
if (!data.chars) {
e.reply('获取角色面板数据失败请确认角色已在游戏内橱窗展示并开放了查看详情。设置完毕后请5分钟后再进行请求~')
} else {
let ret = []
let ret = {}
lodash.forEach(data.chars, (ds) => {
let char = Character.get(ds.id)
if (char) {
ret.push(char.name)
ret[char.name] = true
}
})
if (ret.length === 0) {
e.reply('获取角色面板数据失败未能请求到角色数据。请确认角色已在游戏内橱窗展示并开放了查看详情。设置完毕后请5分钟后再进行请求~')
} else {
e.reply(`获取角色面板数据成功!\n${ret.length > 8 ? '所有已获取' : '本次获取成功'}角色: ${ret.join(', ')}\n你可以使用 #角色名+面板 来查看详细角色面板属性了。`)
e.newChar = ret
return await profileList(e, { render })
}
}
return true

View File

@ -0,0 +1,54 @@
import lodash from 'lodash'
import { autoRefresh, getTargetUid } from './profile-common.js'
import { Common, Profile } from '../../components/index.js'
import { Character } from '../../components/models.js';
export async function profileList (e, { render }) {
let uid = await getTargetUid(e)
if (!uid) {
return true
}
let profiles = Profile.getAll(uid) || {}
let chars = []
let msg = ''
let newChar = {}
if (e.newChar) {
msg = '获取角色面板数据成功'
newChar = e.newChar
}
lodash.forEach(profiles || [], (ds) => {
if (!['enka', 'input2', 'miao-pre', 'miao'].includes(ds.dataSource)) {
return
}
let { id } = ds
let char = Character.get(id)
let tmp = char.getData('id,name,abbr,element,star')
tmp.source = ds.dataSource
tmp.level = ds.lv || 1
tmp.isNew = newChar[char.name] ? 1 : 0
chars.push(tmp)
})
if (chars.length === 0) {
if (await autoRefresh(e)) {
await profileList(e, { render })
return true
} else {
e.reply('尚未获取任何角色数据')
}
return true
}
chars = lodash.sortBy(chars, ['isNew', 'star', 'level', 'id'])
chars = chars.reverse()
// 渲染图像
return await Common.render('character/profile-list', {
save_id: uid,
uid,
chars,
msg
}, { e, render, scale: 1.6 })
}

View File

@ -16,7 +16,8 @@ export {
getProfileAll,
profileHelp,
getOriginalPicture,
uploadCharacterImg
uploadCharacterImg,
profileList
} from './character.js'
export {
@ -48,7 +49,7 @@ let rule = {
reg: '^#圣遗物列表\\s*(\\d{9})?$',
describe: '【#角色】圣遗物列表'
},
getProfileAll: {
profileList: {
reg: '^#(面板角色|角色面板|面板)(列表)?\\s*(\\d{9})?$',
describe: '【#角色】查看当前已获取面板数据的角色列表'
},

View File

@ -200,6 +200,10 @@ class Character extends Base {
return !/10\d{6}/.test(this.id)
}
get abbr () {
return abbrMap[this.name] || this.name
}
checkWifeType (type) {
return !!wifeMap[type][this.id]
}

View File

@ -0,0 +1,53 @@
body,
.container {
width: 650px;
}
.container > .cont {
margin-left: 15px;
}
.head-box {
margin-top: 10px;
}
.head-box .label {
font-size: 14px;
}
.char-list {
display: flex;
flex-wrap: wrap;
padding: 10px;
}
.char-item {
margin: 5px;
}
.char-item .name {
margin-top: 5px;
display: block;
font-size: 14px;
color: #fff;
text-align: center;
text-shadow: 0 0 1px #000;
}
.char-item.new-char .name:before {
content: "";
display: inline-block;
width: 8px;
height: 8px;
background: #90e800;
border-radius: 50%;
margin-right: 3px;
}
.char-icon {
width: 64px;
height: 64px;
border-radius: 50%;
border: 2px solid #fff;
box-shadow: 1px 1px 3px 0 #000;
overflow: visible;
}
.char-icon .img {
background-size: auto 100%;
background-position: top center;
overflow: hidden;
border-radius: 50%;
}
/*# sourceMappingURL=profile-list.css.map */

View File

@ -0,0 +1,29 @@
{{extend elemLayout}}
{{block 'css'}}
<link rel="stylesheet" type="text/css" href="{{_res_path}}/character/detail.css"/>
<link rel="stylesheet" type="text/css" href="{{_res_path}}/character/profile-list.css"/>
{{/block}}
{{block 'main'}}
{{set demo = chars[0]?.abbr || "雷神" }}
<div class="head-box">
<div class="title">角色面板列表</div>
<div class="label">{{msg}}</div>
<div class="label">你可以使用<span>#{{demo}}面板</span><span>#{{demo}}伤害</span><span>#{{demo}}圣遗物</span>命令来查看面板信息</div>
</div>
<div class="cont char-list">
{{each chars char}}
<div class="char-item {{char.isNew?'new-char':''}}">
<div class="item-icon char-icon star{{char.star}}">
<span class="img"
style="background-image:url({{_res_path}}/meta/character/{{char.name}}/face.png)"></span>
</div>
<span class="name">{{char.abbr}}</span>
</div>
{{/each}}
</div>
{{/block}}

View File

@ -0,0 +1,62 @@
body, .container {
width: 650px;
}
.container > .cont {
margin-left: 15px;
}
.head-box {
margin-top: 10px;
.label {
font-size: 14px;
}
}
.char-list {
display: flex;
flex-wrap: wrap;
padding: 10px;
}
.char-item {
margin: 5px;
.name {
margin-top: 5px;
display: block;
font-size: 14px;
color: #fff;
text-align: center;
text-shadow: 0 0 1px #000;
}
&.new-char {
.name:before {
content: "";
display: inline-block;
width: 8px;
height: 8px;
background: #90e800;
border-radius: 50%;
margin-right: 3px;
}
}
}
.char-icon {
width: 64px;
height: 64px;
border-radius: 50%;
border: 2px solid #fff;
box-shadow: 1px 1px 3px 0 #000;
overflow: visible;
.img {
background-size: auto 100%;
background-position: top center;
overflow: hidden;
border-radius: 50%;
}
}

View File

@ -32,6 +32,7 @@
margin: 0;
padding: 0;
box-sizing: border-box;
-webkit-user-select: none;
user-select: none;
}
body {
@ -69,6 +70,10 @@ body {
font-size: 16px;
text-shadow: 0 0 1px #000, 1px 1px 3px rgba(0, 0, 0, 0.9);
}
.head-box .label span {
color: #d3bc8e;
padding: 0 2px;
}
.notice {
color: #888;
font-size: 12px;
@ -329,4 +334,35 @@ ul.cont-msg li strong,
color: #fff;
margin: 20px 0 10px 0;
}
/* item-icon */
.item-icon {
width: 100%;
height: 100%;
border-radius: 4px;
position: relative;
overflow: hidden;
}
.item-icon .img {
width: 100%;
height: 100%;
display: block;
background-size: contain;
background-position: center;
background-repeat: no-repeat;
}
.item-icon.star1 {
background-image: url("../common/item/bg1.png");
}
.item-icon.star2 {
background-image: url("../common/item/bg2.png");
}
.item-icon.star3 {
background-image: url("../common/item/bg3.png");
}
.item-icon.star4 {
background-image: url("../common/item/bg4.png");
}
.item-icon.star5 {
background-image: url("../common/item/bg5.png");
}
/*# sourceMappingURL=common.css.map */

View File

@ -37,6 +37,7 @@
margin: 0;
padding: 0;
box-sizing: border-box;
-webkit-user-select: none;
user-select: none;
}
@ -63,25 +64,28 @@ body {
color: #fff;
margin-top: 30px;
}
.title {
font-size: 36px;
font-family: NZBZ, sans-serif;
text-shadow: 0 0 1px #000, 1px 1px 3px rgba(0, 0, 0, .9);
}
.head-box .title {
font-size: 36px;
font-family: NZBZ, sans-serif;
text-shadow: 0 0 1px #000, 1px 1px 3px rgba(0, 0, 0, .9);
}
.genshin_logo {
position: absolute;
top: 1px;
right: 15px;
width: 97px;
}
.label {
font-size: 16px;
text-shadow: 0 0 1px #000, 1px 1px 3px rgba(0, 0, 0, .9);
.head-box .genshin_logo {
position: absolute;
top: 1px;
right: 15px;
width: 97px;
}
.head-box .label {
font-size: 16px;
text-shadow: 0 0 1px #000, 1px 1px 3px rgba(0, 0, 0, .9);
span {
color: #d3bc8e;
padding: 0 2px;
}
}
}
@ -305,3 +309,28 @@ ul.cont-msg, .cont-footer ul {
color: #fff;
margin: 20px 0 10px 0;
}
/* item-icon */
.item-icon {
width: 100%;
height: 100%;
border-radius: 4px;
position: relative;
overflow: hidden;
.img {
width: 100%;
height: 100%;
display: block;
background-size: contain;
background-position: center;
background-repeat: no-repeat;
}
@stars: 1, 2, 3, 4, 5;
each(@stars, {
&.star@{value} {
background-image: url("../common/item/bg@{value}.png");
}
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -1,13 +1,15 @@
<!DOCTYPE html>
<html>
<html lang="zh-cn">
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<link rel="shortcut icon" href="#"/>
<link rel="preload" href="{{_res_path}}/common/font/HYWH-65W.ttf" as="font" crossorigin>
<link rel="preload" href="{{_res_path}}/common/font/HYWH-85W.ttf" as="font" crossorigin>
<link rel="preload" href="{{_res_path}}/common/font/NZBZ.ttf" as="font" crossorigin>
<link rel="preload" href="{{_res_path}}/common/font/tttgbnumber.ttf" as="font" crossorigin>
<link rel="stylesheet" type="text/css" href="{{_res_path}}/common/common.css"/>
<link rel="preload" href="{{_res_path}}common/font/HYWH-65W.ttf" as="font" type="font/ttf" crossorigin>
<link rel="preload" href="{{_res_path}}common/font/HYWH-85W.ttf" as="font" type="font/ttf" crossorigin>
<link rel="preload" href="{{_res_path}}common/font/NZBZ.ttf" as="font" type="font/ttf" crossorigin>
<link rel="preload" href="{{_res_path}}common/font/tttgbnumber.ttf" as="font" type="font/ttf" crossorigin>
<link rel="stylesheet" type="text/css" href="{{_res_path}}common/common.css"/>
<title>miao-plugin</title>
{{block 'css'}}
{{/block}}
</head>

View File

@ -1,13 +1,15 @@
<!DOCTYPE html>
<html>
<html lang="zh-cn">
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<link rel="shortcut icon" href="#"/>
<link rel="preload" href="{{_res_path}}/common/font/HYWH-65W.ttf" as="font" crossorigin>
<link rel="preload" href="{{_res_path}}/common/font/HYWH-85W.ttf" as="font" crossorigin>
<link rel="preload" href="{{_res_path}}/common/font/NZBZ.ttf" as="font" crossorigin>
<link rel="preload" href="{{_res_path}}/common/font/tttgbnumber.ttf" as="font" crossorigin>
<link rel="stylesheet" type="text/css" href="{{_res_path}}/common/common.css"/>
<link rel="preload" href="{{_res_path}}common/font/HYWH-65W.ttf" as="font" type="font/ttf" crossorigin>
<link rel="preload" href="{{_res_path}}common/font/HYWH-85W.ttf" as="font" type="font/ttf" crossorigin>
<link rel="preload" href="{{_res_path}}common/font/NZBZ.ttf" as="font" type="font/ttf" crossorigin>
<link rel="preload" href="{{_res_path}}common/font/tttgbnumber.ttf" as="font" type="font/ttf" crossorigin>
<link rel="stylesheet" type="text/css" href="{{_res_path}}common/common.css"/>
<title>miao-plugin</title>
{{block 'css'}}
{{/block}}
</head>

View File

@ -138,27 +138,6 @@
.item-card .life5 {
background-color: #ff5722;
}
.item-icon {
width: 100%;
height: 100%;
border-radius: 4px;
position: relative;
overflow: hidden;
}
.item-icon .img {
width: 100%;
height: 100%;
display: block;
background-size: contain;
background-position: center;
background-repeat: no-repeat;
}
.item-icon.star5 {
background-image: url(../common/item/bg5.png);
}
.item-icon.star4 {
background-image: url(../common/item/bg4.png);
}
.avatar-card {
margin: 3px;
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.8);

View File

@ -1,28 +1,3 @@
.item-icon {
width: 100%;
height: 100%;
border-radius: 4px;
position: relative;
overflow: hidden;
.img {
width: 100%;
height: 100%;
display: block;
background-size: contain;
background-position: center;
background-repeat: no-repeat;
}
&.star5 {
background-image: url(../common/item/bg5.png);
}
&.star4 {
background-image: url(../common/item/bg4.png);
}
}
.avatar-card {
margin: 3px;
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.8);

View File

@ -1,47 +1,48 @@
export const details = [{
title: "E点按伤害",
title: 'E点按伤害',
dmg: ({ talent }, dmg) => dmg(talent.e['点按伤害'], 'e')
}, {
title: "E长按伤害",
dmg: ({ talent }, dmg) => dmg(talent.e['长按伤害'], 'e')
title: 'Q单段伤害',
params: { q: true },
dmg: ({ talent }, dmg) => dmg(talent.q['持续伤害'], 'q')
}, {
title: "Q单段伤害",
title: 'Q含转化单段',
params: { q: true },
dmg: ({ talent }, dmg) => {
let basic = dmg(talent.q['持续伤害'], 'q');
//暂时以物伤近似计算
let fj = dmg(talent.q['附加元素伤害'], 'q', 'phy');
let basic = dmg(talent.q['持续伤害'], 'q')
// 暂时以物伤近似计算
let fj = dmg(talent.q['附加元素伤害'], 'q', 'phy')
return {
dmg: basic.dmg + fj.dmg,
avg: basic.avg + fj.avg
}
}
}, {
title: "扩散反应伤害",
title: '扩散反应伤害',
dmg: ({}, { ks }) => ks()
}];
}]
export const mainAttr = "atk,cpct,cdmg";
export const mainAttr = 'atk,cpct,cdmg'
export const buffs = [{
title: "温迪2命E降低12%风抗与物抗",
title: '温迪2命E降低12%风抗与物抗',
cons: 2,
data: {
kx: 12
}
}, {
title: "温迪4命温迪获取元素晶球或元素微粒后获得25%风元素伤害加成",
title: '温迪4命温迪获取元素晶球或元素微粒后获得25%风元素伤害加成',
cons: 4,
data: {
dmg: 25
}
}, {
title: "温迪6命Q降低20%风抗",
title: '温迪6命Q降低20%风抗',
cons: 6,
data: {
kx: ({ params }) => params.q ? 20 : 0
}
}, {
title: "元素精通:扩散伤害提高[ks]%",
mastery: "ks"
}];
title: '元素精通:扩散伤害提高[ks]%',
mastery: 'ks'
}]

View File

@ -63,13 +63,13 @@
</div>
<div class="abyss-floor-team">
<div class="abyss-team">
{{each floor.display.up.avatars id}}
{{each floor?.display?.up?.avatars||[] id}}
<% include(_layout_path+'../tpl/avatar-card.html', [avatars[id],{_res_path}]) %>
{{/each}}
</div>
<div class="line"></div>
<div class="abyss-team">
{{each floor.display.down.avatars id}}
{{each floor?.display?.down?.avatars||[] id}}
<% include(_tpl_path+'/avatar-card.html', [avatars[id],{_res_path}]) %>
{{/each}}
</div>
@ -82,12 +82,12 @@
第{{idx}}间
</div>
<span class="star star{{level.star}}"></span>
<div class="time">{{level.up.time}}</div>
<div class="time">{{level?.up?.time}}</div>
</div>
<div class="avatars">
{{each upDown v k}}
<div class="avatar-list {{k}}">
{{each level[k].avatars id}}
{{each level[k]?.avatars||[] id}}
{{set avatar = avatars[id] || {} }}
<div class="avatar-icon item-icon star{{avatar.star==4?4:5}}">
<span class="img"