From 8386de213fb0584a2cab32271e0588e837376bf4 Mon Sep 17 00:00:00 2001 From: yoimiya-kokomi <592981798@qq.com> Date: Sat, 16 Apr 2022 06:05:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0#=E8=A7=92=E8=89=B2=E8=AF=A6?= =?UTF-8?q?=E6=83=85=20=E7=9A=84=E6=A0=B7=E5=BC=8F=E4=B8=8E=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/character.js | 44 ++- components/Profile.js | 58 +++- index.js | 2 +- resources/character/card.html | 1 - resources/character/detail.css | 512 ++++++++++++++++++++++++++++ resources/character/detail.html | 87 +++++ resources/character/icon.png | Bin 0 -> 9110 bytes resources/common/cont/card-bg.png | Bin 0 -> 2594 bytes resources/common/{ => item}/bg3.png | Bin resources/common/{ => item}/bg4.png | Bin resources/common/{ => item}/bg5.png | Bin resources/common/item/star.png | Bin 0 -> 4487 bytes 12 files changed, 670 insertions(+), 34 deletions(-) create mode 100644 resources/character/detail.css create mode 100644 resources/character/detail.html create mode 100644 resources/character/icon.png create mode 100644 resources/common/cont/card-bg.png rename resources/common/{ => item}/bg3.png (100%) rename resources/common/{ => item}/bg4.png (100%) rename resources/common/{ => item}/bg5.png (100%) create mode 100644 resources/common/item/star.png diff --git a/apps/character.js b/apps/character.js index 7b55cb7d..7fbeb951 100644 --- a/apps/character.js +++ b/apps/character.js @@ -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"); diff --git a/components/Profile.js b/components/Profile.js index bc357490..824088e9 100644 --- a/components/Profile.js +++ b/components/Profile.js @@ -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; diff --git a/index.js b/index.js index a2060e08..47508e02 100644 --- a/index.js +++ b/index.js @@ -35,7 +35,7 @@ let rule = { describe: "【#帮助】 #喵喵帮助", }, getProfile: { - reg: "^#获取游戏角色详情$", + reg: "^#\s*获取游戏角色详情\s*$", describe: "【#角色】 获取游戏橱窗详情数据", }, ...adminRule diff --git a/resources/character/card.html b/resources/character/card.html index 14b799c0..fff9bde8 100644 --- a/resources/character/card.html +++ b/resources/character/card.html @@ -44,7 +44,6 @@
请绑定Cookie以查询天赋信息
{{/if}} -
{{text1|| "-"}}
{{text2 || "-"}}
diff --git a/resources/character/detail.css b/resources/character/detail.css new file mode 100644 index 00000000..7c0037fe --- /dev/null +++ b/resources/character/detail.css @@ -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; +} \ No newline at end of file diff --git a/resources/character/detail.html b/resources/character/detail.html new file mode 100644 index 00000000..1b60d365 --- /dev/null +++ b/resources/character/detail.html @@ -0,0 +1,87 @@ + + + + + + + + + +
+
+
+
+
{{name}}
+
UID {{uid}} - Lv.{{data.lv}}
+
+ {{each talentMap tName key}} +
+
+ + {{talent[key].level_current}} +
+
+ {{/each}} +
+
    +
  • 生命值{{attr.hp}}(+{{attr.hpPlus}})
  • +
  • 攻击力{{attr.atk}}(+{{attr.atkPlus}})
  • +
  • 防御力{{attr.def}}(+{{attr.defPlus}})
  • +
  • 元素精通{{attr.mastery}}
  • +
  • 暴击率{{attr.cRate}}
  • +
  • 暴击伤害{{attr.cDmg}}
  • +
  • 元素充能{{attr.recharge}}
  • +
  • 元素伤害{{attr.dmgBonus}}
  • +
+
+
+ {{each cons con idx}} +
+
+ +
+
+ {{/each}} +
+
+
+
+ +
+ {{weapon.name}} +
+ Lv.{{weapon.level}} 精{{weapon.affix_level}} +
+
+ {{each reliquaries ds}} +
+ {{if ds.name}} +
+ + +{{ds.level}} +
+
+ {{ds.name}} + {{ds.pos_name}} - {{ds.mark}}分 +
+
    +
  • {{ds.main[0]}}+{{ds.main[1]}}
  • + {{each ds.attrs attr}} + {{if attr[0]}} +
  • {{attr[0]}}+{{attr[1]}}
  • + {{/if}} + {{/each}} +
+ {{/if}} +
+ {{/each}} +
+ +
+ + + diff --git a/resources/character/icon.png b/resources/character/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..06df16edfa1a2032e2f0c9e1aa0af9fe98ec66ff GIT binary patch literal 9110 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 literal 0 HcmV?d00001