更新#角色详情 的样式与功能

This commit is contained in:
yoimiya-kokomi 2022-04-16 06:05:31 +08:00
parent c921d57a81
commit 8386de213f
12 changed files with 670 additions and 34 deletions

View File

@ -412,19 +412,28 @@ export async function getProfile(e) {
}
let selfUser = e.selfUser;
if (!selfUser.isCookieUser) {
e.reply("仅绑定cookie用户可用")
e.reply("此功能仅绑定cookie用户可用")
return true;
}
e.reply("开始更新用户信息,可能会需要一定时间");
//try {
let data = await Profile.request(selfUser.uid);
//} catch (err) {
let data = await Profile.request(selfUser.uid, e);
//e.reply("更新错误");
//}
if (data) {
e.reply("更新成功")
if (!data || !data.chars) {
e.reply("请求游戏信息失败请确认角色已在游戏内橱窗展示并开放了查看详情。设置完毕后请5分钟后再进行请求~");
} else {
let ret = [];
lodash.forEach(data.chars, (ds) => {
let char = Character.get(ds.id);
if (char) {
ret.push(char.name);
}
})
if (ret.length === 0) {
e.reply("更新失败未能请求到角色数据。请确认角色已在游戏内橱窗展示并开放了查看详情。设置完毕后请5分钟后再进行请求~")
} else {
e.reply(`更新成功!本次更新角色: ${ret.join(",")}。你可以使用 #角色名+详情 来查看详细角色属性了`)
}
}
return true;
}
@ -540,6 +549,7 @@ export async function renderProfile(e, char, render) {
let profile = Profile.get(uid, char.id);
if (!profile) {
e.reply(`尚无${char.name}的属性信息。请在游戏内将角色展示在“角色展柜”中并打开“显示角色详情”。设置完成5分钟后请使用 #获取游戏角色详情 命令获取角色详情数据~`)
return renderAvatar(e, char.name, render)
}
@ -563,11 +573,15 @@ export async function renderProfile(e, char, render) {
let avatar = await getAvatar(e, char, MysApi);
let talent = await getTalent(e, avatar);
let reliquaries = [];
let reliquaries = [], totalMark = 0;
lodash.forEach(avatar.reliquaries, (ds, idx)=>{
let arti = profile.artis[`arti${idx+1}`];
if(arti){
lodash.forEach(avatar.reliquaries, (ds, idx) => {
let arti = profile.artis[`arti${idx + 1}`];
if (arti) {
let mark = Profile.getArtiMark(arti.attrs, ds.pos_name === "理之冠" ? arti.main : false);
totalMark += mark;
ds.mark = c(mark, 1);
ds.markType = mark > 45 ? (mark >= 50 ? "high" : "good") : "normal";
ds.main = Profile.formatArti(arti.main);
ds.attrs = Profile.formatArti(arti.attrs);
}
@ -578,14 +592,16 @@ export async function renderProfile(e, char, render) {
save_id: uid,
uid: uid,
data: profile,
// meta: char,
attr,
avatar,
talent,
key: char.key,
cons: char.cons,
name: char.name,
elem: char.elem,
reliquaries,
totalMark,
weapon: avatar.weapon,
talentMap: { a: "普攻", e: "战技", q: "爆发" },
cfgScale: Cfg.scale(1.25)
}, "png");

View File

@ -33,7 +33,7 @@ const artifactMap = {
pct: true
},
'暴击伤害': {
title: "爆伤",
title: "暴击伤害",
pct: true
},
'防御力': {
@ -51,14 +51,14 @@ const artifactMap = {
pct: true
},
'元素精通': {
title: "精通"
title: "元素精通"
},
'元素充能效率': {
title: "充能",
title: "充能效率",
pct: true
},
'治疗加成': {
title: "治疗",
title: "治疗加成",
pct: true
}
}
@ -202,10 +202,12 @@ let Data = {
}
let Profile = {
async request(uid) {
async request(uid, e) {
if (!cfg.api) {
return {};
e.reply("尚未配置更新Api无法更新数据~");
return false;
}
e.reply("开始获取角色展柜中展示的角色详情,请确认已经打开显示角色详情开关,数据获取可能会需要一定时间~");
const api = cfg.api + uid;
let req = await fetch(api);
let data = await req.text();
@ -225,18 +227,14 @@ let Profile = {
if (fs.existsSync(userFile)) {
userData = JSON.parse(fs.readFileSync(userFile, "utf8")) || {};
}
let data = Data.getData(uid, ds);
lodash.assignIn(userData, lodash.pick(data, "uid,name,lv,avatar".split(",")));
userData.chars = userData.chars || {};
lodash.forEach(data.chars, (char, charId) => {
userData.chars[charId] = char;
});
fs.writeFileSync(userFile, JSON.stringify(userData), "", " ");
return userData;
return data;
},
get(uid, charId) {
const userFile = `${userPath}/${uid}.json`;
@ -258,20 +256,44 @@ let Profile = {
return ret;
}
let title = ds[0], val = ds[1];
if (/伤害加成/.test(title) && val<1) {
val = Format.pct(val*100);
}else if (/伤害加成|大|暴|爆|充能|治疗/.test(title)) {
if (/伤害加成/.test(title) && val < 1) {
val = Format.pct(val * 100);
} else if (/伤害加成|大|暴|充能|治疗/.test(title)) {
val = Format.pct(val);
} else {
val = Format.comma(val,1);
}
if (title == "爆伤") {
title = "暴击伤害";
val = Format.comma(val, 1);
}
if (/元素伤害加成/.test(title)) {
title = title.replace("元素伤害", "伤");
}
return [title, val];
},
getArtiMark(data, ds) {
let mark = {
"暴击率": 2,
"暴击伤害": 1,
"元素精通": 0.25,
"大攻击": 1,
"大生命": 0.86,
"大防御": 0.7,
"小攻击": 0.12,
"小生命": 0.014,
"小防御": 0.18,
"充能效率": 0.65
};
let total = 0;
lodash.forEach(data, (ret) => {
if (ret[0] && ret[1]) {
total += mark[ret[0]] * ret[1];
}
})
if (ds && /暴/.test(ds[0])) {
total += 20;
}
return total;
}
};
export default Profile;

View File

@ -35,7 +35,7 @@ let rule = {
describe: "【#帮助】 #喵喵帮助",
},
getProfile: {
reg: "^#获取游戏角色详情$",
reg: "^#\s*获取游戏角色详情\s*$",
describe: "【#角色】 获取游戏橱窗详情数据",
},
...adminRule

View File

@ -44,7 +44,6 @@
<div class="talent_{{key}}">请绑定Cookie以查询天赋信息</div>
</div>
{{/if}}
<div class="equiv_info">
<div class="text">{{text1|| "-"}}</div>
<div class="text">{{text2 || "-"}}</div>

View File

@ -0,0 +1,512 @@
body {
width: 600px;
height: 1000px;
}
.container {
width: 600px;
height: 1030px;
padding: 0;
background-size: cover;
overflow: hidden;
}
.container:after {
content: "";
display: block;
position: absolute;
left: 8px;
top: 115px;
bottom: 470px;
right: 8px;
box-shadow: 0 0 2px 0 #fff;
border-radius: 5px;
z-index: 1;
}
.main-pic {
width: 800px;
height: 500px;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
margin-left: -260px;
position: relative;
z-index: 2;
}
.detail {
position: absolute;
right: 20px;
top: 20px;
color: #fff;
z-index: 3;
}
.char-name {
font-size: 50px;
font-family: NZBZ;
text-shadow: 0 0 3px #000, 2px 2px 4px rgba(0, 0, 0, .7);
text-align: right;
}
.char-lv {
font-family: Number;
margin-bottom: 20px;
text-shadow: 0 0 3px #000, 2px 2px 4px rgba(0, 0, 0, .7);
text-align: right;
}
.attr {
border-radius: 4px;
overflow: hidden;
}
.detail li {
width: 300px;
font-size: 18px;
list-style: none;
padding: 5px 100px 5px 35px;
position: relative;
font-family: YS;
font-weight: 400;
}
.attr li i {
display: inline-block;
height: 20px;
width: 20px;
background-image: url("./icon.png");
background-size: auto 20px;
position: absolute;
left: 10px;
top: 8px;
opacity: .9;
transform: scale(.9);
}
.i-hp {
background-position: -20px 0;
}
.i-atk {
background-position: -40px 0;
}
.i-def {
background-position: -60px 0;
}
.i-mastery {
background-position: -80px 0;
}
.i-cr {
background-position: -100px 0;
}
.i-cd {
background-position: -140px 0;
}
.i-re {
background-position: -120px 0;
}
.i-dmg {
background-position: -160px 0;
}
.detail li:nth-child(even) {
background: rgba(0, 0, 0, .4)
}
.detail li:nth-child(odd) {
background: rgba(50, 50, 50, .4)
}
.detail li strong {
display: inline-block;
position: absolute;
right: 85px;
text-align: right;
font-family: Number, sans-serif;
font-weight: normal;
}
.detail li span {
position: absolute;
right: 0;
text-align: left;
width: 75px;
display: inline-block;
font-family: Number, sans-serif;
color: #90e800;
font-size: 15px;
}
.talent-icon {
width: 100px;
height: 100px;
padding: 5px;
display: table;
border-radius: 50%;
position: relative;
background-size: contain;
background-repeat: no-repeat;
background-position: center center;
z-index: 90;
}
.talent-icon img {
width: 46%;
height: 46%;
position: absolute;
top: 50%;
left: 50%;
margin: -22% 0 0 -23%;
}
.talent-icon span {
background: #fff;
width: 34px;
height: 26px;
line-height: 26px;
font-size: 17px;
text-align: center;
border-radius: 5px;
position: absolute;
bottom: 2px;
left: 50%;
margin-left: -15px;
color: #000;
box-shadow: 0 0 5px 0 #000;
font-family: Number;
}
.talent-icon.talent-plus span {
background: #2e353e;
color: #ffdfa0;
font-weight: bold;
box-shadow: 0 0 1px 0 #d3bc8e, 1px 1px 2px 0 rgba(0, 0, 0, 0.5);
}
.talent-icon.talent-crown:after {
content: "";
display: block;
width: 28px;
height: 28px;
background: url("../character/imgs/crown.png") no-repeat;
background-size: contain;
position: absolute;
left: 50%;
top: 0px;
margin-left: -14px;
}
.char-talents {
display: flex;
width: 300px;
margin-bottom: 15px;
}
.char-cons {
display: flex;
width: 250px;
position: absolute;
top: 465px;
left: 20px;
}
.char-cons .talent-item,
.char-talents .talent-item {
flex: 1;
}
.char-cons .talent-icon {
width: 50px;
height: 50px;
margin: 0 -5px
}
.char-cons .talent-icon.off {
filter: grayscale(100%);
opacity: .4;
}
.elem_anemo .talent-icon {
background-image: url(../common/bg/talent-anemo.png)
}
.elem_anemo .container {
background-image: url(../common/bg/bg-anemo.jpg);
}
.elem_cryo .talent-icon {
background-image: url(../common/bg/talent-cryo.png)
}
.elem_cryo .container {
background-image: url(../common/bg/bg-cryo.jpg);
}
.elem_electro .talent-icon {
background-image: url(../common/bg/talent-electro.png)
}
.elem_electro .container {
background-image: url(../common/bg/bg-electro.jpg);
}
.elem_geo .talent-icon {
background-image: url(../common/bg/talent-geo.png)
}
.elem_geo .container {
background-image: url(../common/bg/bg-geo.jpg);
}
.elem_hydro .talent-icon {
background-image: url(../common/bg/talent-hydro.png)
}
.elem_hydro .container {
background-image: url(../common/bg/bg-hydro.jpg);
}
.elem_pyro .talent-icon {
background-image: url(../common/bg/talent-pyro.png)
}
.elem_pyro .container {
background-image: url(../common/bg/bg-pyro.jpg);
}
.artis {
display: flex;
width: 600px;
flex-wrap: wrap;
margin-top: 40px;
margin-bottom: 5px;
padding: 5px;
}
.artis .item {
width: 185px;
border-radius: 10px;
background: url("../common/cont/card-bg.png") top left repeat-x;
background-size: auto 100%;
margin: 5px;
height: 210px;
position: relative;
box-shadow: 0 0 1px 0 #ccc, 2px 2px 4px 0 rgba(50, 50, 50, .8);
}
.artis .item .arti-icon {
width: 60px;
height: 60px;
position: absolute;
left: 2px;
top: 3px;
}
.artis .item .arti-icon span {
position: absolute;
right: 2px;
bottom: 0;
margin-left: 5px;
background: rgba(0, 0, 0, .5);
border-radius: 5px;
height: 18px;
line-height: 18px;
padding: 0 3px;
color: #fff;
font-size: 12px;
display: block;
}
.artis .item img {
width: 60px;
height: 60px;
}
.artis .head {
color: #fff;
padding: 12px 0 8px 68px;
}
.artis .head strong {
font-size: 15px;
display: block;
white-space: nowrap;
overflow: hidden;
}
.artis .head span {
font-size: 14px;
}
.artis .head .mark {
font-family: YS;
}
.artis .head span.high-lvl {
color: #ffe699;
font-weight: bold;
}
.artis .head span.good-lvl {
color: #d699ff;
font-weight: bold;
}
.arti-main {
color: #fff;
padding: 6px 15px;
}
.artis ul.detail {
width: 100%;
padding: 0;
position: initial;
font-family: YS;
}
.artis ul.detail li {
padding: 3px;
font-size: 14px;
position: initial;
width: 100%;
display: table;
}
.artis ul.detail li.arti-main {
font-size: 16px;
padding: 8px 3px;
font-weight: bold;
}
.artis ul.detail li span {
position: initial;
display: table-cell;
color: #fff;
font-family: YS;
}
.artis ul.detail li span.title {
text-align: left;
padding-left: 10px;
}
.artis ul.detail li span.val {
text-align: right;
padding-right: 10px;
}
.artis .weapon .star {
height: 20px;
width: 100px;
background: url("../common/item/star.png") no-repeat;
background-size: 100px 100px;
transform: scale(0.8);
transform-origin: 100px 10px;
display: inline-block;
}
.artis .weapon .star.star-2 {
background-position: 0 -20px;
}
.artis .weapon .star.star-3 {
background-position: 0 -40px;
}
.artis .weapon .star.star-4 {
background-position: 0 -60px;
}
.artis .weapon .star.star-5 {
background-position: 0 -80px;
}
.artis .weapon {
overflow: hidden;
}
.artis .weapon img {
width: 185px;
height: 185px;
top: 0;
left: 0;
position: absolute;
}
.artis .weapon .head {
position: absolute;
bottom: 0;
right: 0;
left: 0;
text-align: right;
padding: 8px 12px 10px 0;
background-image: linear-gradient(to right, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.7));
}
.artis .weapon .head strong {
font-size: 18px;
margin-bottom: 3px;
}
.artis .weapon .head > span {
display: block;
}
.artis .weapon span {
font-size: 16px;
}
.artis .weapon .affix {
color: #000;
padding: 0 7px;
border-radius: 4px;
margin-left: 5px;
font-size: 16px;
}
.artis .weapon .affix-1 {
box-shadow: 0 0 4px 0 #a3a3a3 inset;
background: #ebebebaa;
}
.artis .weapon .affix-2 {
box-shadow: 0 0 4px 0 #51b72fbd inset;
background: #ddffdeaa;
}
.artis .weapon .affix-3 {
box-shadow: 0 0 4px 0 #396cdecf inset;
background: #ddebffaa;
}
.artis .weapon .affix-4 {
box-shadow: 0 0 4px 0 #c539debf inset;
background: #ffddf0aa;
}
.artis .weapon .affix-5 {
box-shadow: 0 0 4px 0 #deaf39 inset;
background: #fff6dd;
}

View File

@ -0,0 +1,87 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<link rel="shortcut icon" href="#"/>
<link rel="stylesheet" type="text/css" href="{{_res_path}}/common/common.css"/>
<link rel="stylesheet" type="text/css" href="{{_res_path}}/character/detail.css"/>
</head>
<body {{cfgScale}} class="elem_{{elem}} char-{{key}}">
<div class="container" id="container">
<div class="basic">
<div class="main-pic"
style="background-image:url({{_res_path}}/meta/character/{{name}}/gacha_splash.png)"></div>
<div class="detail">
<div class="char-name">{{name}}</div>
<div class="char-lv">UID {{uid}} - Lv.{{data.lv}}</div>
<div class="char-talents">
{{each talentMap tName key}}
<div class="talent-item">
<div class="talent-icon
{{talent[key].level_current > talent[key].level_original ? `talent-plus`:``}}
{{talent[key].level_original == 10 ? `talent-crown`:``}}">
<img src="{{_res_path}}/meta/character/{{name}}/talent_{{key}}.png"/>
<span>{{talent[key].level_current}}</span>
</div>
</div>
{{/each}}
</div>
<ul class="attr">
<li><i class="i-hp"></i>生命值<strong>{{attr.hp}}</strong><span>(+{{attr.hpPlus}})</span></li>
<li><i class="i-atk"></i>攻击力<strong>{{attr.atk}}</strong><span>(+{{attr.atkPlus}})</span></li>
<li><i class="i-def"></i>防御力<strong>{{attr.def}}</strong><span>(+{{attr.defPlus}})</span></li>
<li><i class="i-mastery"></i>元素精通<strong>{{attr.mastery}}</strong></li>
<li><i class="i-cr"></i>暴击率<strong>{{attr.cRate}}</strong></li>
<li><i class="i-cd"></i>暴击伤害<strong>{{attr.cDmg}}</strong></li>
<li><i class="i-re"></i>元素充能<strong>{{attr.recharge}}</strong></li>
<li><i class="i-dmg"></i>元素伤害<strong>{{attr.dmgBonus}}</strong></li>
</ul>
</div>
<div class="char-cons">
{{each cons con idx}}
<div class="cons-item">
<div class="talent-icon {{idx*1>data.cons*1 ? 'off':''}}">
<img src="{{_res_path}}/meta/character/{{name}}/cons_{{idx}}.png"/>
</div>
</div>
{{/each}}
</div>
</div>
<div class="artis">
<div class="item weapon">
<img src="{{_sys_res_path}}/genshin/logo/weapon/{{weapon.name}}.png"/>
<div class="head">
<strong>{{weapon.name}}</strong>
<div class="star star-{{weapon.rarity}}"></div>
<span>Lv.{{weapon.level}} <span
class="affix affix-{{weapon.affix_level}}">精{{weapon.affix_level}}</span></span>
</div>
</div>
{{each reliquaries ds}}
<div class="item arti">
{{if ds.name}}
<div class="arti-icon">
<img src="{{_sys_res_path}}/genshin/logo/reliquaries/{{ds.name}}.png"/>
<span>+{{ds.level}}</span>
</div>
<div class="head">
<strong>{{ds.name}}</strong>
<span>{{ds.pos_name}} - <span class="mark {{ds.markType}}-lvl">{{ds.mark}}分</span></span>
</div>
<ul class="detail">
<li class="arti-main"><span class="title">{{ds.main[0]}}</span><span class="val">+{{ds.main[1]}}</span></li>
{{each ds.attrs attr}}
{{if attr[0]}}
<li><span class="title">{{attr[0]}}</span><span class="val">+{{attr[1]}}</span></li>
{{/if}}
{{/each}}
</ul>
{{/if}}
</div>
{{/each}}
</div>
<div class="copyright">Create By Yunzai-Bot & Miao-Plugin</div>
</div>
</body>
<script type="text/javascript"></script>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB