miao-plugin/apps/profile/ProfileRank.js

255 lines
7.7 KiB
JavaScript
Raw Normal View History

import { Character, ProfileRank, ProfileDmg, Player } from '../../models/index.js'
2023-03-07 17:52:11 +00:00
import ProfileDetail from './ProfileDetail.js'
2023-03-27 20:02:49 +00:00
import { Data, Common, Format } from '#miao'
import lodash from 'lodash'
2022-11-10 20:56:15 +00:00
export async function groupRank (e) {
const groupRank = Common.cfg('groupRank')
let msg = e.original_msg || e.msg
2022-11-10 20:56:15 +00:00
let type = ''
if (/(排名|排行|列表)/.test(msg)) {
type = 'list'
} else if (/(最强|最高|最多|最高分|最牛|第一)/.test(msg)) {
2022-11-10 20:56:15 +00:00
type = 'detail'
} else if (/极限/.test(msg)) {
type = 'super'
2022-11-10 20:56:15 +00:00
}
let groupId = e.group_id
if (!type || (!groupId && type !== 'super')) {
return false
}
let mode = /(分|圣遗物|评分|ACE)/.test(msg) ? 'mark' : 'dmg'
2023-03-27 20:02:49 +00:00
mode = /(词条)/.test(msg) ? 'valid' : mode
mode = /(双爆)/.test(msg) ? 'crit' : mode
let name = msg.replace(/(#|最强|最高分|第一|词条|双爆|极限|最高|最多|最牛|圣遗物|评分|群内|群|排名|排行|面板|面版|详情|榜)/g, '')
let char = Character.get(name)
if (!char) {
// 名字不存在或不为列表模式则返回false
if (name || type !== 'list') {
return false
}
}
// 对鲸泽佬的极限角色文件增加支持
if (type === 'super') {
let player = Player.create(100000000)
if (player.getProfile(char.id)) {
e.uid = 100000000
2023-02-21 19:49:49 +00:00
return await ProfileDetail.render(e, char)
} else {
return true
}
}
// 正常群排名
let groupCfg = await ProfileRank.getGroupCfg(groupId)
2022-11-10 20:56:15 +00:00
if (!groupRank) {
2023-02-12 15:39:46 +00:00
e.reply('群面板排名功能已禁用Bot主人可通过【#喵喵设置】启用...')
return true
}
if (groupCfg.status === 1) {
2023-02-12 15:39:46 +00:00
e.reply('本群已关闭群排名群管理员或Bot主人可通过【#启用排名】启用...')
2022-11-10 20:56:15 +00:00
return true
}
if (type === 'detail') {
let uid = await ProfileRank.getGroupMaxUid(groupId, char.id, mode)
if (uid) {
e.uid = uid
2023-02-21 19:49:49 +00:00
return await ProfileDetail.render(e, char)
} else {
2022-11-10 20:56:15 +00:00
if (mode === 'dmg' && !ProfileDmg.dmgRulePath(char.name)) {
e.reply(`暂无排名:${char.name}暂不支持伤害计算,无法进行排名..`)
2022-11-10 20:56:15 +00:00
} else {
e.reply('暂无排名:请通过【#面板】查看角色面板以更新排名信息...')
2022-11-10 20:56:15 +00:00
}
}
2022-11-10 20:56:15 +00:00
} else if (type === 'list') {
if (mode === 'dmg' && char && !ProfileDmg.dmgRulePath(char.name)) {
e.reply(`暂无排名:${char.name}暂不支持伤害计算,无法进行排名..`)
} else {
let uids = []
if (char) {
uids = await ProfileRank.getGroupUidList(groupId, char ? char.id : '', mode)
} else {
uids = await ProfileRank.getGroupMaxUidList(groupId, mode)
}
if (uids.length > 0) {
return renderCharRankList({ e, uids, char, mode, groupId })
} else {
e.reply('暂无排名:请通过【#面板】查看角色面板以更新排名信息...')
}
}
return true
}
}
export async function resetRank (e) {
let groupId = e.group_id
if (!groupId) {
return true
}
if (!e.isMaster) {
e.reply('只有管理员可重置排名')
return true
}
let msg = e.original_msg || e.msg
let name = msg.replace(/(#|重置|重设|排名|排行|群|群内|面板|详情|面版)/g, '').trim()
let charId = ''
let charName = '全部角色'
if (name) {
let char = Character.get(name)
if (!char) {
e.reply(`重置排名失败,角色:${name}不存在`)
return true
}
charId = char.id
charName = char.name
}
await ProfileRank.resetRank(groupId, charId)
e.reply(`本群${charName}排名已重置...`)
}
2022-11-10 20:56:15 +00:00
/**
* 刷新群排名信息
* @param e
* @returns {Promise<boolean>}
*/
export async function refreshRank (e) {
let groupId = e.group_id
if (!groupId) {
return true
}
2023-02-12 15:39:46 +00:00
if (!e.isMaster && !this.e.member?.is_admin) {
e.reply('只有主人及群管理员可刷新排名...')
return true
}
e.reply('面板数据刷新中,等待时间可能较长,请耐心等待...')
await ProfileRank.resetRank(groupId)
let groupUids = await Common.getGroupUids(e)
let count = 0
for (let qq in groupUids) {
for (let { uid, type } of groupUids[qq]) {
2023-02-08 20:55:54 +00:00
let player = new Player(uid)
let profiles = player.getProfiles()
// 刷新rankLimit
await ProfileRank.setUidInfo({ uid, profiles, qq, uidType: type })
let rank = await ProfileRank.create({ groupId, uid, qq })
for (let id in profiles) {
let profile = profiles[id]
if (!profile.hasData) {
continue
}
await rank.getRank(profile, true)
}
if (rank.allowRank) {
count++
}
}
}
e.reply(`本群排名已刷新,共刷新${count}个UID数据...`)
}
export async function manageRank (e) {
let groupId = e.group_id
if (!groupId) {
return true
}
let isClose = /(关闭|禁用)/.test(e.msg)
2023-02-12 15:39:46 +00:00
if (!e.isMaster && !this.e.member?.is_admin) {
e.reply(`只有主人及群管理员可${isClose ? '禁用' : '启用'}排名...`)
return true
}
await ProfileRank.setGroupStatus(groupId, isClose ? 1 : 0)
if (isClose) {
e.reply('当前群排名功能已禁用...')
} else {
e.reply('当前群排名功能已启用...\n如数据有问题可通过【#刷新排名】命令来刷新当前群内排名')
}
}
async function renderCharRankList ({ e, uids, char, mode, groupId }) {
2022-11-10 20:56:15 +00:00
let list = []
for (let ds of uids) {
let uid = ds.uid || ds.value
2023-02-08 20:55:54 +00:00
let player = Player.create(uid)
let avatar = player.getAvatar(ds.charId || char.id)
if (!avatar) {
continue
}
2023-02-08 20:55:54 +00:00
let profile = avatar.getProfile()
2022-11-10 20:56:15 +00:00
if (profile) {
let profileRank = await ProfileRank.create({ groupId, uid })
let data = await profileRank.getRank(profile, true)
let mark = data?.mark?.data
let tmp = {
2022-11-10 20:56:15 +00:00
uid,
isMax: !char,
...avatar.getData('id,star,name,sName,level,fetter,cons,weapon,elem,talent,artisSet,imgs'),
artisMark: Data.getData(mark, 'mark,markClass,valid,crit')
}
let dmg = data?.dmg?.data
if (dmg && dmg.avg) {
let title = dmg.title
// 稍微缩短下title
if (title.length > 10) {
title = title.replace(/[ ·]*/g, '')
}
title = title.length > 10 ? title.replace(/伤害$/, '') : title
tmp.dmg = {
title: title,
avg: Format.comma(dmg.avg, 1)
}
}
if (uid) {
let userInfo = await ProfileRank.getUidInfo(uid)
if (userInfo && userInfo.qq) {
let member = e.group?.pickMember(userInfo.qq * 1)
let img = member?.getAvatarUrl(140)
if (img) {
tmp.qqFace = img
}
}
}
2023-03-27 20:02:49 +00:00
if (mode === 'crit') {
tmp._mark = mark?._crit * 6.6044 || 0
} else if (mode === 'valid') {
tmp._mark = mark?._valid || 0
2023-03-27 20:02:49 +00:00
} else {
tmp._mark = mark?._mark || 0
}
tmp._formatmark = Format.comma(tmp._mark, 1)
tmp._dmg = dmg?.avg || 0
tmp._star = 5 - tmp.star
list.push(tmp)
2022-11-10 20:56:15 +00:00
}
}
let title
if (char) {
2023-03-27 20:02:49 +00:00
if (mode === 'mark') {
title = `#${char.name}${'圣遗物评分'}排行`
}
2023-03-27 20:02:49 +00:00
if (mode === 'crit') {
title = `#${char.name}${'双爆副词条'}排行`
}
2023-03-27 20:02:49 +00:00
if (mode === 'valid') {
title = `#${char.name}${'加权有效词条'}排行`
}
list = lodash.sortBy(list, mode === 'dmg' ? '_dmg' : '_mark').reverse()
} else {
title = `#${mode === 'mark' ? '最高分' : '最强'}排行`
list = lodash.sortBy(list, ['uid', '_star', 'id'])
}
const rankCfg = await ProfileRank.getGroupCfg(groupId)
2022-11-10 20:56:15 +00:00
// 渲染图像
return await Common.render('character/rank-profile-list', {
save_id: char.id,
list,
title,
2022-11-10 20:56:15 +00:00
elem: char.elem,
bodyClass: `char-${char.name}`,
rankCfg,
2022-11-10 20:56:15 +00:00
mode
}, { e, scale: 1.4 })
2022-11-10 20:56:15 +00:00
}