mirror of
https://github.com/yoimiya-kokomi/miao-plugin.git
synced 2024-11-21 22:48:13 +00:00
#喵喵设置
中可设置禁用获取角色或面板原图功能
增加`#删除面板`命令,目前绑定CK用户使用,Bot主人可删除任意UID数据
This commit is contained in:
parent
036d61d698
commit
6b11badb66
@ -15,6 +15,8 @@
|
|||||||
* 其他功能及界面优化,部分已知问题调整
|
* 其他功能及界面优化,部分已知问题调整
|
||||||
* `#上传深渊` 界面与样式调整
|
* `#上传深渊` 界面与样式调整
|
||||||
* `#刷新排名`、`#禁用排名`、`#启用排名`可由群管理员进行管理
|
* `#刷新排名`、`#禁用排名`、`#启用排名`可由群管理员进行管理
|
||||||
|
* `#喵喵设置` 中可设置禁用获取角色或面板原图功能
|
||||||
|
* 增加`#删除面板`命令,目前绑定CK用户使用,Bot主人可删除任意UID数据
|
||||||
|
|
||||||
# 2.2.1 ~ 2.2.2
|
# 2.2.1 ~ 2.2.2
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ let Avatar = {
|
|||||||
}, { e, scale, retMsgId: true })
|
}, { e, scale, retMsgId: true })
|
||||||
if (msgRes && msgRes.message_id) {
|
if (msgRes && msgRes.message_id) {
|
||||||
// 如果消息发送成功,就将message_id和图片路径存起来,3小时过期
|
// 如果消息发送成功,就将message_id和图片路径存起来,3小时过期
|
||||||
await redis.set(`miao:original-picture:${msgRes.message_id}`, bg.img, { EX: 3600 * 3 })
|
await redis.set(`miao:original-picture:${msgRes.message_id}`, JSON.stringify({ type: 'character', img: bg.img }), { EX: 3600 * 3 })
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
|
@ -39,7 +39,7 @@ async function getAvatarList (player, type) {
|
|||||||
let list = []
|
let list = []
|
||||||
player.forEachAvatar((avatar) => {
|
player.forEachAvatar((avatar) => {
|
||||||
if (type !== false) {
|
if (type !== false) {
|
||||||
if (!avatar.char.checkWifeType(avatar.id, type)) {
|
if (!avatar.char.checkWifeType(type)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,6 +115,12 @@ app.reg({
|
|||||||
rule: /^#?\s*(.+)(?:面板图列表)\s*$/,
|
rule: /^#?\s*(.+)(?:面板图列表)\s*$/,
|
||||||
fn: profileImgList,
|
fn: profileImgList,
|
||||||
describe: '【#刻晴面板图列表】 删除指定角色面板图(序号)'
|
describe: '【#刻晴面板图列表】 删除指定角色面板图(序号)'
|
||||||
|
},
|
||||||
|
|
||||||
|
profileDel: {
|
||||||
|
rule: /^#(删除全部面板|删除面板|删除面板数据)\s*(\d{9})?$/,
|
||||||
|
fn: ProfileList.del,
|
||||||
|
describe: '【#角色】 删除游戏橱窗详情数据'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
import { Data } from '../../components/index.js'
|
import { Data } from '../../components/index.js'
|
||||||
import { Character, ProfileData, Weapon,Player } from '../../models/index.js'
|
import { Character, ProfileData, Weapon, Player } from '../../models/index.js'
|
||||||
|
|
||||||
const keyMap = {
|
const keyMap = {
|
||||||
artis: '圣遗物',
|
artis: '圣遗物',
|
||||||
|
@ -87,7 +87,9 @@ export async function getProfileRefresh (e, avatar) {
|
|||||||
profile = player.getProfile(char.id)
|
profile = player.getProfile(char.id)
|
||||||
}
|
}
|
||||||
if (!profile || !profile.hasData) {
|
if (!profile || !profile.hasData) {
|
||||||
e.reply(`请确认${char.name}已展示在【游戏内】的角色展柜中,并打开了“显示角色详情”。然后请使用 #更新面板\n命令来获取${char.name}的面板详情`)
|
if (!e._isReplyed) {
|
||||||
|
e.reply(`请确认${char.name}已展示在【游戏内】的角色展柜中,并打开了“显示角色详情”。然后请使用 #更新面板\n命令来获取${char.name}的面板详情`)
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return profile
|
return profile
|
||||||
|
@ -205,7 +205,7 @@ export async function renderProfile (e, char, mode = 'profile', params = {}) {
|
|||||||
}, { e, scale: 1.6, retMsgId: true })
|
}, { e, scale: 1.6, retMsgId: true })
|
||||||
if (msgRes && msgRes.message_id) {
|
if (msgRes && msgRes.message_id) {
|
||||||
// 如果消息发送成功,就将message_id和图片路径存起来,3小时过期
|
// 如果消息发送成功,就将message_id和图片路径存起来,3小时过期
|
||||||
await redis.set(`miao:original-picture:${msgRes.message_id}`, costumeSplash, { EX: 3600 * 3 })
|
await redis.set(`miao:original-picture:${msgRes.message_id}`, JSON.stringify({ type: 'profile', img: costumeSplash }), { EX: 3600 * 3 })
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,11 @@ import { ProfileRank, Player, Character } from '../../models/index.js'
|
|||||||
import { Common, Data } from '../../components/index.js'
|
import { Common, Data } from '../../components/index.js'
|
||||||
|
|
||||||
const ProfileList = {
|
const ProfileList = {
|
||||||
|
/**
|
||||||
|
* 刷新面板
|
||||||
|
* @param e
|
||||||
|
* @returns {Promise<boolean|*>}
|
||||||
|
*/
|
||||||
async refresh (e) {
|
async refresh (e) {
|
||||||
let uid = await getTargetUid(e)
|
let uid = await getTargetUid(e)
|
||||||
if (!uid) {
|
if (!uid) {
|
||||||
@ -34,6 +39,13 @@ const ProfileList = {
|
|||||||
|
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染面板
|
||||||
|
* @param e
|
||||||
|
* @returns {Promise<boolean|*>}
|
||||||
|
*/
|
||||||
|
|
||||||
async render (e) {
|
async render (e) {
|
||||||
let uid = await getTargetUid(e)
|
let uid = await getTargetUid(e)
|
||||||
if (!uid) {
|
if (!uid) {
|
||||||
@ -113,9 +125,44 @@ const ProfileList = {
|
|||||||
hasNew,
|
hasNew,
|
||||||
msg,
|
msg,
|
||||||
groupRank,
|
groupRank,
|
||||||
|
updateTime: player.getUpdateTime(),
|
||||||
allowRank: rank && rank.allowRank,
|
allowRank: rank && rank.allowRank,
|
||||||
rankCfg
|
rankCfg
|
||||||
}, { e, scale: 1.6 })
|
}, { e, scale: 1.6 })
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 删除面板数据
|
||||||
|
* @param e
|
||||||
|
* @returns {Promise<boolean>}
|
||||||
|
*/
|
||||||
|
async del (e) {
|
||||||
|
let ret = /^#(删除全部面板|删除面板|删除面板数据)\s*(\d{9})?$/.exec(e.msg)
|
||||||
|
let uid = await getTargetUid(e)
|
||||||
|
if (!uid) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
let targetUid = ret[2]
|
||||||
|
|
||||||
|
let user = e?.runtime?.user || {}
|
||||||
|
if (!user.hasCk && !e.isMaster) {
|
||||||
|
e.reply('为确保数据安全,目前仅允许绑定CK用户删除自己UID的面板数据,请联系Bot主人删除...')
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!targetUid) {
|
||||||
|
e.reply(`你确认要删除面板数据吗? 请回复 #删除面板${uid} 以删除面板数据`)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
let ckUids = (user?.ckUids || []).join(',').split(',')
|
||||||
|
if (!ckUids.includes(targetUid) && !e.isMaster) {
|
||||||
|
e.reply(`仅允许删除自己的UID数据[${ckUids.join(',')}]`)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
Player.delByUid(targetUid)
|
||||||
|
e.reply(`UID${targetUid}的本地数据已删除,排名数据已清除...`)
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default ProfileList
|
export default ProfileList
|
||||||
|
@ -76,11 +76,10 @@ const ProfileStat = {
|
|||||||
info,
|
info,
|
||||||
updateTime: player.getUpdateTime(),
|
updateTime: player.getUpdateTime(),
|
||||||
isSelfCookie: e.isSelfCookie,
|
isSelfCookie: e.isSelfCookie,
|
||||||
talentLvMap: '0,1,1,1,2,2,3,3,3,4,5'.split(','),
|
|
||||||
face,
|
face,
|
||||||
avatars: avatarRet,
|
avatars: avatarRet,
|
||||||
talentNotice
|
talentNotice
|
||||||
}, { e, scale: 1.4 })
|
}, { e, scale: 1.4 })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export default ProfileStat
|
export default ProfileStat
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { segment } from 'oicq'
|
import { segment } from 'oicq'
|
||||||
import { MysApi } from '../../models/index.js'
|
import { MysApi } from '../../models/index.js'
|
||||||
|
import { Cfg } from '../../components/index.js'
|
||||||
|
|
||||||
/** 获取角色卡片的原图 */
|
/** 获取角色卡片的原图 */
|
||||||
export async function getOriginalPicture (e) {
|
export async function getOriginalPicture (e) {
|
||||||
@ -14,6 +15,7 @@ export async function getOriginalPicture (e) {
|
|||||||
if (!/^\[图片]$/.test(e.source.message)) {
|
if (!/^\[图片]$/.test(e.source.message)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
let originalPic = Cfg.get('originalPic') * 1
|
||||||
// 获取原消息
|
// 获取原消息
|
||||||
let source
|
let source
|
||||||
if (e.isGroup) {
|
if (e.isGroup) {
|
||||||
@ -24,7 +26,25 @@ export async function getOriginalPicture (e) {
|
|||||||
if (source) {
|
if (source) {
|
||||||
let imgPath = await redis.get(`miao:original-picture:${source.message_id}`)
|
let imgPath = await redis.get(`miao:original-picture:${source.message_id}`)
|
||||||
if (imgPath) {
|
if (imgPath) {
|
||||||
e.reply([segment.image(process.cwd() + '/plugins/miao-plugin/resources/' + decodeURIComponent(imgPath))], false, { recallMsg: 30 })
|
try {
|
||||||
|
if (imgPath[0] === '{') {
|
||||||
|
imgPath = JSON.parse(imgPath)
|
||||||
|
} else {
|
||||||
|
imgPath = { img: imgPath, type: '' }
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
if (imgPath.type === 'character' && [2, 0].includes(originalPic)) {
|
||||||
|
e.reply('已禁止获取角色原图...')
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (imgPath.type === 'profile' && [1, 0].includes(originalPic)) {
|
||||||
|
e.reply('已禁止获取面板原图...')
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (imgPath && imgPath.img) {
|
||||||
|
e.reply([segment.image(process.cwd() + '/plugins/miao-plugin/resources/' + decodeURIComponent(imgPath.img))], false, { recallMsg: 30 })
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if (source.time) {
|
if (source.time) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import fetch from 'node-fetch'
|
import fetch from 'node-fetch'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import { Character, Material } from '../../models/index.js'
|
import { Character, Material } from '../../models/index.js'
|
||||||
import { Common, Data } from '../../components/index.js'
|
import { Common, Data, Cfg } from '../../components/index.js'
|
||||||
import lodash from 'lodash'
|
import lodash from 'lodash'
|
||||||
|
|
||||||
const ignoreIds = [495, // 有奖问卷调查开启!
|
const ignoreIds = [495, // 有奖问卷调查开启!
|
||||||
@ -227,7 +227,7 @@ let Cal = {
|
|||||||
data.weekly = char.getMaterials('weekly')?.icon
|
data.weekly = char.getMaterials('weekly')?.icon
|
||||||
charTalent[t].chars.push(data)
|
charTalent[t].chars.push(data)
|
||||||
}
|
}
|
||||||
}, 'official')
|
}, Cfg.get('notReleasedData') ? 'official' : 'release')
|
||||||
let charNum = 0
|
let charNum = 0
|
||||||
lodash.forEach(charBirth, (charList) => {
|
lodash.forEach(charBirth, (charList) => {
|
||||||
charNum = Math.max(charNum, charList.length)
|
charNum = Math.max(charNum, charList.length)
|
||||||
|
@ -58,9 +58,12 @@ let Data = {
|
|||||||
delete data._res
|
delete data._res
|
||||||
return fs.writeFileSync(`${root}/${file}`, JSON.stringify(data, null, space))
|
return fs.writeFileSync(`${root}/${file}`, JSON.stringify(data, null, space))
|
||||||
},
|
},
|
||||||
delfile (file) {
|
delFile (file, root = '') {
|
||||||
|
root = getRoot(root)
|
||||||
try {
|
try {
|
||||||
fs.unlinkSync(`${_path}/${file}`)
|
if (fs.existsSync(`${root}/${file}`)) {
|
||||||
|
fs.unlinkSync(`${root}/${file}`)
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`文件删除失败:${error}`)
|
logger.error(`文件删除失败:${error}`)
|
||||||
|
@ -138,6 +138,14 @@ export const cfgSchema = {
|
|||||||
input: (n) => Math.min(200, Math.max(50, (n * 1 || 100))),
|
input: (n) => Math.min(200, Math.max(50, (n * 1 || 100))),
|
||||||
desc: '可选值50~200,建议100。设置高精度会提高图片的精细度,但因图片较大可能会影响渲染与发送速度'
|
desc: '可选值50~200,建议100。设置高精度会提高图片的精细度,但因图片较大可能会影响渲染与发送速度'
|
||||||
},
|
},
|
||||||
|
originalPic: {
|
||||||
|
title: '原图',
|
||||||
|
key: '原图',
|
||||||
|
type: 'num',
|
||||||
|
def: 3,
|
||||||
|
input: (n) => Math.min(3, Math.max(n * 1 || 0, 0)),
|
||||||
|
desc: '允许获取原图,0:不允许, 1:仅允许角色图, 2:仅允许面板图, 3:开启'
|
||||||
|
},
|
||||||
commaGroup: {
|
commaGroup: {
|
||||||
title: '数字逗号分组',
|
title: '数字逗号分组',
|
||||||
key: '逗号',
|
key: '逗号',
|
||||||
|
@ -73,17 +73,23 @@ export default class Base {
|
|||||||
// 设置超时时间
|
// 设置超时时间
|
||||||
_expire (time = 10 * 60) {
|
_expire (time = 10 * 60) {
|
||||||
let id = this._uuid
|
let id = this._uuid
|
||||||
|
let self = this
|
||||||
reFn[id] && clearTimeout(reFn[id])
|
reFn[id] && clearTimeout(reFn[id])
|
||||||
if (time > 0) {
|
if (time > 0) {
|
||||||
if (id) {
|
if (id) {
|
||||||
reFn[id] = setTimeout(() => {
|
reFn[id] = setTimeout(() => {
|
||||||
reFn[id] && clearTimeout(reFn[id])
|
self._delCache()
|
||||||
delete reFn[id]
|
|
||||||
delete cacheMap[id]
|
|
||||||
delete metaMap[id]
|
|
||||||
}, time * 1000)
|
}, time * 1000)
|
||||||
}
|
}
|
||||||
return cacheMap[id]
|
return cacheMap[id]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_delCache () {
|
||||||
|
let id = this._uuid
|
||||||
|
reFn[id] && clearTimeout(reFn[id])
|
||||||
|
delete reFn[id]
|
||||||
|
delete cacheMap[id]
|
||||||
|
delete metaMap[id]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,13 @@ export default class Player extends Base {
|
|||||||
return Serv.name
|
return Serv.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static delByUid (uid) {
|
||||||
|
let player = Player.create(uid)
|
||||||
|
if (player) {
|
||||||
|
player.del()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重新加载json文件
|
* 重新加载json文件
|
||||||
*/
|
*/
|
||||||
@ -89,6 +96,18 @@ export default class Player extends Base {
|
|||||||
Data.writeJSON(`/data/UserData/${this.uid}.json`, ret, '', 'root')
|
Data.writeJSON(`/data/UserData/${this.uid}.json`, ret, '', 'root')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
del () {
|
||||||
|
try {
|
||||||
|
Data.delFile(`/data/UserData/${this.uid}.json`, 'root')
|
||||||
|
ProfileRank.delUidInfo(this.uid)
|
||||||
|
this._delCache()
|
||||||
|
Bot.logger.mark(`【面板数据删除】${this.uid}本地文件数据已删除...`)
|
||||||
|
} catch (e) {
|
||||||
|
console.log('del error', e)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置玩家基础数据
|
* 设置玩家基础数据
|
||||||
* @param ds
|
* @param ds
|
||||||
|
@ -19,99 +19,6 @@ export default class ProfileRank {
|
|||||||
return rank
|
return rank
|
||||||
}
|
}
|
||||||
|
|
||||||
key (profile, type) {
|
|
||||||
return `miao:rank:${this.groupId}:${type}:${profile.id}`
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取排行信息
|
|
||||||
* @param profile
|
|
||||||
* @param force
|
|
||||||
* @returns {Promise<{}|boolean>}
|
|
||||||
*/
|
|
||||||
async getRank (profile, force = false) {
|
|
||||||
if (!profile || !this.groupId || !this.allowRank || !profile.hasData) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
let ret = {}
|
|
||||||
for (let typeKey of ['mark', 'dmg']) {
|
|
||||||
let typeRank = await this.getTypeRank(profile, typeKey, force)
|
|
||||||
ret[typeKey] = typeRank
|
|
||||||
if (!ret.rank || ret.rank >= typeRank.rank) {
|
|
||||||
ret.rank = typeRank.rank
|
|
||||||
ret.rankType = typeKey
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
async getTypeRank (profile, type, force) {
|
|
||||||
if (!profile || !profile.hasData || !type) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (type === 'dmg' && !profile.hasDmg) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
const typeKey = this.key(profile, type)
|
|
||||||
let value
|
|
||||||
let rank
|
|
||||||
if (force) {
|
|
||||||
value = await this.getTypeValue(profile, type)
|
|
||||||
} else {
|
|
||||||
rank = await redis.zRevRank(typeKey, this.uid)
|
|
||||||
if (!lodash.isNumber(rank)) {
|
|
||||||
value = await this.getTypeValue(profile, type)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (value && !lodash.isUndefined(value.score)) {
|
|
||||||
await redis.zAdd(typeKey, { score: value.score, value: this.uid })
|
|
||||||
}
|
|
||||||
if (!lodash.isNumber(rank)) {
|
|
||||||
rank = await redis.zRevRank(typeKey, this.uid)
|
|
||||||
}
|
|
||||||
if (rank === null) {
|
|
||||||
rank = 99
|
|
||||||
}
|
|
||||||
if (force) {
|
|
||||||
return {
|
|
||||||
rank: rank + 1,
|
|
||||||
value: value.score,
|
|
||||||
data: value.data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
rank: rank + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async getTypeValue (profile, type) {
|
|
||||||
if (!profile || !profile.hasData) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (type === 'mark') {
|
|
||||||
if (!profile?.artis?.hasArtis) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
let mark = profile.getArtisMark(false)
|
|
||||||
if (mark && mark._mark) {
|
|
||||||
return {
|
|
||||||
score: mark._mark * 1,
|
|
||||||
data: mark
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (type === 'dmg' && profile.hasDmg) {
|
|
||||||
let dmg = await profile.calcDmg({ mode: 'single' })
|
|
||||||
if (dmg && dmg.avg) {
|
|
||||||
return {
|
|
||||||
score: dmg.avg,
|
|
||||||
data: dmg
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取群排行UID
|
* 获取群排行UID
|
||||||
* @param groupId
|
* @param groupId
|
||||||
@ -258,6 +165,20 @@ export default class ProfileRank {
|
|||||||
await redis.set(`miao:rank:uid-info:${uid}`, JSON.stringify(data), { EX: 3600 * 24 * 365 })
|
await redis.set(`miao:rank:uid-info:${uid}`, JSON.stringify(data), { EX: 3600 * 24 * 365 })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async delUidInfo (uid) {
|
||||||
|
let keys = await redis.keys('miao:rank:*')
|
||||||
|
uid = uid + ''
|
||||||
|
if (!/\d{9}/.test(uid)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for (let key of keys) {
|
||||||
|
let charRet = /^miao:rank:\d+:(?:mark|dmg):(\d{8})$/.exec(key)
|
||||||
|
if (charRet) {
|
||||||
|
await redis.zRem(key, uid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static async getUidInfo (uid) {
|
static async getUidInfo (uid) {
|
||||||
try {
|
try {
|
||||||
let data = await redis.get(`miao:rank:uid-info:${uid}`)
|
let data = await redis.get(`miao:rank:uid-info:${uid}`)
|
||||||
@ -304,4 +225,97 @@ export default class ProfileRank {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key (profile, type) {
|
||||||
|
return `miao:rank:${this.groupId}:${type}:${profile.id}`
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取排行信息
|
||||||
|
* @param profile
|
||||||
|
* @param force
|
||||||
|
* @returns {Promise<{}|boolean>}
|
||||||
|
*/
|
||||||
|
async getRank (profile, force = false) {
|
||||||
|
if (!profile || !this.groupId || !this.allowRank || !profile.hasData) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
let ret = {}
|
||||||
|
for (let typeKey of ['mark', 'dmg']) {
|
||||||
|
let typeRank = await this.getTypeRank(profile, typeKey, force)
|
||||||
|
ret[typeKey] = typeRank
|
||||||
|
if (!ret.rank || ret.rank >= typeRank.rank) {
|
||||||
|
ret.rank = typeRank.rank
|
||||||
|
ret.rankType = typeKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
async getTypeRank (profile, type, force) {
|
||||||
|
if (!profile || !profile.hasData || !type) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (type === 'dmg' && !profile.hasDmg) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const typeKey = this.key(profile, type)
|
||||||
|
let value
|
||||||
|
let rank
|
||||||
|
if (force) {
|
||||||
|
value = await this.getTypeValue(profile, type)
|
||||||
|
} else {
|
||||||
|
rank = await redis.zRevRank(typeKey, this.uid)
|
||||||
|
if (!lodash.isNumber(rank)) {
|
||||||
|
value = await this.getTypeValue(profile, type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (value && !lodash.isUndefined(value.score)) {
|
||||||
|
await redis.zAdd(typeKey, { score: value.score, value: this.uid })
|
||||||
|
}
|
||||||
|
if (!lodash.isNumber(rank)) {
|
||||||
|
rank = await redis.zRevRank(typeKey, this.uid)
|
||||||
|
}
|
||||||
|
if (rank === null) {
|
||||||
|
rank = 99
|
||||||
|
}
|
||||||
|
if (force) {
|
||||||
|
return {
|
||||||
|
rank: rank + 1,
|
||||||
|
value: value.score,
|
||||||
|
data: value.data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
rank: rank + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getTypeValue (profile, type) {
|
||||||
|
if (!profile || !profile.hasData) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (type === 'mark') {
|
||||||
|
if (!profile?.artis?.hasArtis) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
let mark = profile.getArtisMark(false)
|
||||||
|
if (mark && mark._mark) {
|
||||||
|
return {
|
||||||
|
score: mark._mark * 1,
|
||||||
|
data: mark
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (type === 'dmg' && profile.hasDmg) {
|
||||||
|
let dmg = await profile.calcDmg({ mode: 'single' })
|
||||||
|
if (dmg && dmg.avg) {
|
||||||
|
return {
|
||||||
|
score: dmg.avg,
|
||||||
|
data: dmg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,9 +40,7 @@ export default class ProfileReq extends Base {
|
|||||||
empty: '请将角色放置在【游戏内】角色展柜,并打开【显示详情】,等待5分钟重新获取面板'
|
empty: '请将角色放置在【游戏内】角色展柜,并打开【显示详情】,等待5分钟重新获取面板'
|
||||||
}
|
}
|
||||||
msg = msgs[msg] || msg
|
msg = msgs[msg] || msg
|
||||||
if (msg) {
|
this.msg(msg)
|
||||||
this.e.reply(msg)
|
|
||||||
}
|
|
||||||
// 设置CD
|
// 设置CD
|
||||||
if (cd) {
|
if (cd) {
|
||||||
this.setCd(cd)
|
this.setCd(cd)
|
||||||
@ -51,7 +49,11 @@ export default class ProfileReq extends Base {
|
|||||||
}
|
}
|
||||||
|
|
||||||
msg (msg) {
|
msg (msg) {
|
||||||
this.e.reply(msg)
|
let e = this.e
|
||||||
|
if (msg && !e._isReplyed) {
|
||||||
|
e.reply(msg)
|
||||||
|
e._isReplyed = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async requestProfile (player, serv) {
|
async requestProfile (player, serv) {
|
||||||
|
@ -55,7 +55,9 @@ const Profile = {
|
|||||||
player.save()
|
player.save()
|
||||||
return player._update.length
|
return player._update.length
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
e.reply(`UID:${uid}更新面板失败,更新服务:${serv.name}`)
|
if (!e._isReplyed) {
|
||||||
|
e.reply(`UID:${uid}更新面板失败,更新服务:${serv.name}`)
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -57,9 +57,13 @@
|
|||||||
{{else}}
|
{{else}}
|
||||||
<span></span>
|
<span></span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<span class="serv">当前更新服务:{{servName}}</span>
|
<span class="serv">
|
||||||
|
当前更新服务:{{servName}}
|
||||||
|
{{if updateTime.profile }}
|
||||||
|
<span>,更新时间:{{updateTime.profile }}</span>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/block}}
|
{{/block}}
|
@ -358,14 +358,16 @@ body {
|
|||||||
margin-right: -60px;
|
margin-right: -60px;
|
||||||
}
|
}
|
||||||
.cont-notice {
|
.cont-notice {
|
||||||
color: #888;
|
background: rgba(0, 0, 0, 0.7);
|
||||||
background: rgba(255, 255, 255, 0.4);
|
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
text-align: center;
|
text-align: right;
|
||||||
padding: 8px;
|
padding: 8px 12px 8px 8px;
|
||||||
|
}
|
||||||
|
.cont-notice strong {
|
||||||
|
color: #d3bc8e;
|
||||||
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
.cont-notice span {
|
.cont-notice span {
|
||||||
padding: 0 3px;
|
margin-left: 5px;
|
||||||
color: #555;
|
|
||||||
}
|
}
|
||||||
/*# sourceMappingURL=profile-stat.css.map */
|
/*# sourceMappingURL=profile-stat.css.map */
|
@ -49,6 +49,7 @@
|
|||||||
<span class="fetter fetter{{['空','荧','旅行者'].includes(avatar.name)?10:avatar.fetter}}"></span>
|
<span class="fetter fetter{{['空','荧','旅行者'].includes(avatar.name)?10:avatar.fetter}}"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{set talentLvMap = [0,1,1,1,2,2,3,3,3,4,5] }}
|
||||||
{{each tk talentKey}}
|
{{each tk talentKey}}
|
||||||
{{set curr = (avatar.talent||{})[talentKey] || {original:1,level:'-'} }}
|
{{set curr = (avatar.talent||{})[talentKey] || {original:1,level:'-'} }}
|
||||||
<div class="td-talent lv{{talentLvMap[curr.original]}} {{curr.level>curr.original?'talent-plus':''}}">
|
<div class="td-talent lv{{talentLvMap[curr.original]}} {{curr.level>curr.original?'talent-plus':''}}">
|
||||||
@ -94,9 +95,22 @@
|
|||||||
</div>
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
{{if talentNotice}}
|
|
||||||
<p class="cont-notice">{{@talentNotice}}</p>
|
<div class="cont-notice">
|
||||||
{{/if}}
|
{{set ut = updateTime }}
|
||||||
|
{{if ut.profile || ut.mys}}
|
||||||
|
<strong>数据更新时间</strong>
|
||||||
|
{{if ut.profile}}
|
||||||
|
<span>#更新面板: {{ut.profile}}</span>
|
||||||
|
{{/if}}
|
||||||
|
{{if ut.mys}}
|
||||||
|
<span>米游社: {{ut.mys}}</span>
|
||||||
|
{{/if}}
|
||||||
|
{{else}}
|
||||||
|
未绑定CK或CK失效,信息可能不完全。发送<strong>#体力帮助</strong>查看CK绑定方法,发送<strong>#更新面板</strong>更新游戏内角色展柜信息
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -402,14 +402,17 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.cont-notice {
|
.cont-notice {
|
||||||
color: #888;
|
background: rgba(0, 0, 0, .7);
|
||||||
background: rgba(255, 255, 255, .4);
|
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
text-align: center;
|
text-align: right;
|
||||||
padding: 8px;
|
padding: 8px 12px 8px 8px;
|
||||||
|
|
||||||
|
strong {
|
||||||
|
color: #d3bc8e;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
span {
|
span {
|
||||||
padding: 0 3px;
|
margin-left: 5px;
|
||||||
color: #555;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Binary file not shown.
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 13 KiB |
Binary file not shown.
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 8.5 KiB |
Loading…
Reference in New Issue
Block a user