diff --git a/CHANGELOG.md b/CHANGELOG.md index a80ee058..8eb6943e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/apps/character.js b/apps/character.js index 7109cdb1..26fd5bde 100644 --- a/apps/character.js +++ b/apps/character.js @@ -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 }) diff --git a/apps/character/profile-common.js b/apps/character/profile-common.js index 8cfcf5fe..67362581 100644 --- a/apps/character/profile-common.js +++ b/apps/character/profile-common.js @@ -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 diff --git a/apps/character/profile-list.js b/apps/character/profile-list.js new file mode 100644 index 00000000..8a9053cb --- /dev/null +++ b/apps/character/profile-list.js @@ -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 }) +} diff --git a/apps/index.js b/apps/index.js index 99f03e05..3110d622 100644 --- a/apps/index.js +++ b/apps/index.js @@ -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: '【#角色】查看当前已获取面板数据的角色列表' }, diff --git a/components/models/Character.js b/components/models/Character.js index 81d4f4b5..94f062ac 100644 --- a/components/models/Character.js +++ b/components/models/Character.js @@ -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] } diff --git a/resources/character/profile-list.css b/resources/character/profile-list.css new file mode 100644 index 00000000..31670c96 --- /dev/null +++ b/resources/character/profile-list.css @@ -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 */ \ No newline at end of file diff --git a/resources/character/profile-list.html b/resources/character/profile-list.html new file mode 100644 index 00000000..2d864fb1 --- /dev/null +++ b/resources/character/profile-list.html @@ -0,0 +1,29 @@ +{{extend elemLayout}} + +{{block 'css'}} + + +{{/block}} + + +{{block 'main'}} +{{set demo = chars[0]?.abbr || "雷神" }} +
+
角色面板列表
+
{{msg}}
+
你可以使用#{{demo}}面板#{{demo}}伤害#{{demo}}圣遗物命令来查看面板信息
+
+
+ {{each chars char}} +
+
+ +
+ {{char.abbr}} +
+ {{/each}} +
+ + +{{/block}} \ No newline at end of file diff --git a/resources/character/profile-list.less b/resources/character/profile-list.less new file mode 100644 index 00000000..44110c5e --- /dev/null +++ b/resources/character/profile-list.less @@ -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%; + } +} \ No newline at end of file diff --git a/resources/common/common.css b/resources/common/common.css index 94c77e8f..19b95196 100644 --- a/resources/common/common.css +++ b/resources/common/common.css @@ -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 */ \ No newline at end of file diff --git a/resources/common/common.less b/resources/common/common.less index 25c96af9..461292f7 100644 --- a/resources/common/common.less +++ b/resources/common/common.less @@ -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"); + } + }) +} \ No newline at end of file diff --git a/resources/common/item/bg1.png b/resources/common/item/bg1.png new file mode 100644 index 00000000..58115989 Binary files /dev/null and b/resources/common/item/bg1.png differ diff --git a/resources/common/item/bg2.png b/resources/common/item/bg2.png new file mode 100644 index 00000000..c1d5363c Binary files /dev/null and b/resources/common/item/bg2.png differ diff --git a/resources/common/layout/default.html b/resources/common/layout/default.html index 14f85ace..fbe1c9c2 100644 --- a/resources/common/layout/default.html +++ b/resources/common/layout/default.html @@ -1,13 +1,15 @@ - + - + + - - - - - + + + + + + miao-plugin {{block 'css'}} {{/block}} diff --git a/resources/common/layout/elem.html b/resources/common/layout/elem.html index aa0df654..ecdb4b44 100644 --- a/resources/common/layout/elem.html +++ b/resources/common/layout/elem.html @@ -1,13 +1,15 @@ - + - + + - - - - - + + + + + + miao-plugin {{block 'css'}} {{/block}} diff --git a/resources/common/tpl.css b/resources/common/tpl.css index 47d0f0ec..5f6310a9 100644 --- a/resources/common/tpl.css +++ b/resources/common/tpl.css @@ -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); diff --git a/resources/common/tpl/avatar-card.less b/resources/common/tpl/avatar-card.less index 6833168c..4ed44dec 100644 --- a/resources/common/tpl/avatar-card.less +++ b/resources/common/tpl/avatar-card.less @@ -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); diff --git a/resources/meta/character/温迪/calc.js b/resources/meta/character/温迪/calc.js index 38bde9be..d1dd02e0 100644 --- a/resources/meta/character/温迪/calc.js +++ b/resources/meta/character/温迪/calc.js @@ -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" -}]; \ No newline at end of file + title: '元素精通:扩散伤害提高[ks]%', + mastery: 'ks' +}] diff --git a/resources/stat/abyss-summary.html b/resources/stat/abyss-summary.html index 6d0e4a11..9fc81972 100644 --- a/resources/stat/abyss-summary.html +++ b/resources/stat/abyss-summary.html @@ -63,13 +63,13 @@
- {{each floor.display.up.avatars id}} + {{each floor?.display?.up?.avatars||[] id}} <% include(_layout_path+'../tpl/avatar-card.html', [avatars[id],{_res_path}]) %> {{/each}}
- {{each floor.display.down.avatars id}} + {{each floor?.display?.down?.avatars||[] id}} <% include(_tpl_path+'/avatar-card.html', [avatars[id],{_res_path}]) %> {{/each}}
@@ -82,12 +82,12 @@ 第{{idx}}间
-
{{level.up.time}}
+
{{level?.up?.time}}
{{each upDown v k}}
- {{each level[k].avatars id}} + {{each level[k]?.avatars||[] id}} {{set avatar = avatars[id] || {} }}