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 00000000..06df16ed Binary files /dev/null and b/resources/character/icon.png differ diff --git a/resources/common/cont/card-bg.png b/resources/common/cont/card-bg.png new file mode 100644 index 00000000..036d416e Binary files /dev/null and b/resources/common/cont/card-bg.png differ diff --git a/resources/common/bg3.png b/resources/common/item/bg3.png similarity index 100% rename from resources/common/bg3.png rename to resources/common/item/bg3.png diff --git a/resources/common/bg4.png b/resources/common/item/bg4.png similarity index 100% rename from resources/common/bg4.png rename to resources/common/item/bg4.png diff --git a/resources/common/bg5.png b/resources/common/item/bg5.png similarity index 100% rename from resources/common/bg5.png rename to resources/common/item/bg5.png diff --git a/resources/common/item/star.png b/resources/common/item/star.png new file mode 100644 index 00000000..80d18882 Binary files /dev/null and b/resources/common/item/star.png differ