miao-plugin/models/ProfileRank.js

293 lines
7.4 KiB
JavaScript
Raw Normal View History

2022-11-07 20:08:24 +00:00
import lodash from 'lodash'
import moment from 'moment'
import { Common } from '../components/index.js'
2022-11-07 20:08:24 +00:00
export default class ProfileRank {
constructor (data) {
this.groupId = data.groupId || data.groupId || ''
if (!this.groupId || this.groupId === 'undefined') {
return false
}
2022-11-07 20:08:24 +00:00
this.qq = data.qq
this.uid = data.uid + ''
this.allowRank = false
2022-11-07 20:08:24 +00:00
}
static async create (data) {
let rank = new ProfileRank(data)
rank.allowRank = await ProfileRank.checkRankLimit(rank.uid)
return rank
2022-11-07 20:08:24 +00:00
}
key (profile, type) {
return `miao:rank:${this.groupId}:${type}:${profile.id}`
2022-11-07 20:08:24 +00:00
}
/**
* 获取排行信息
* @param profile
* @param force
* @returns {Promise<{}|boolean>}
*/
2022-11-07 20:08:24 +00:00
async getRank (profile, force = false) {
if (!this.groupId || !this.allowRank || !profile.hasData) {
2022-11-07 20:16:30 +00:00
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
2022-11-07 20:08:24 +00:00
}
}
return ret
}
async getTypeRank (profile, type, force) {
if (!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
2022-11-07 20:08:24 +00:00
}
}
return {
rank: rank + 1
}
}
async getTypeValue (profile, type) {
if (type === 'mark') {
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
* @param groupId
* @param charId
* @param type
* @returns {Promise<string|boolean>}
*/
static async getGroupMaxUid (groupId, charId, type = 'mark') {
let uids = await redis.zRange(`miao:rank:${groupId}:${type}:${charId}`, -1, -1)
return uids ? uids[0] : false
}
static async getGroupMaxUidList (groupId, type = 'mark') {
let keys = await redis.keys(`miao:rank:${groupId}:${type}:*`)
let ret = []
for (let key of keys) {
let keyRet = /^miao:rank:\d+:(?:mark|dmg):(\d{8})$/.exec(key)
if (keyRet && keyRet[1]) {
let charId = keyRet[1]
let uid = await ProfileRank.getGroupMaxUid(groupId, charId, type)
if (uid) {
ret.push({
uid,
charId
})
}
}
}
return ret
}
2022-11-10 20:56:15 +00:00
/**
* 获取排行榜
* @param groupId
* @param charId
* @param type
* @returns {Promise<ConvertArgumentType<ZMember, string>[]|boolean>}
*/
static async getGroupUidList (groupId, charId, type = 'mark') {
let uids = await redis.zRangeWithScores(`miao:rank:${groupId}:${type}:${charId}`, -15, -1)
2022-11-10 20:56:15 +00:00
return uids ? uids.reverse() : false
}
/**
* 重置群排行
* @param groupId
* @param charId
* @returns {Promise<void>}
*/
static async resetRank (groupId, groupMemList, charId = '') {
let keys = await redis.keys(`miao:rank:${groupId}:*`)
for (let key of keys) {
let charRet = /^miao:rank:\d+:(?:mark|dmg):(\d{8})$/.exec(key)
if (charRet) {
if (charId === '' || charId * 1 === charRet[1] * 1) {
await redis.del(key)
}
}
}
if (charId === '') {
await redis.del(`miao:rank:${groupId}:cfg`)
}
}
static async getGroupCfg (groupId) {
const rankLimitTxt = {
1: '无限制',
2022-11-13 20:43:59 +00:00
2: '绑定有CK的用户',
3: '绑定CK或列表有16个角色数据',
4: '绑定CK或列表有安柏&凯亚&丽莎的数据',
5: '绑定CK或列表有16个角色数据且包含安柏&凯亚&丽莎'
}
let rankLimit = Common.cfg('groupRankLimit') * 1 || 1
let ret = {
timestamp: (new Date()) * 1,
status: 0
}
try {
let cfg = await redis.get(`miao:rank:${groupId}:cfg`)
if (!cfg) {
await redis.set(`miao:rank:${groupId}:cfg`, JSON.stringify(ret), { EX: 3600 * 24 * 365 })
} else {
ret = JSON.parse(cfg)
}
} catch (e) {
}
2022-11-13 20:43:59 +00:00
ret.limitTxt = rankLimitTxt[rankLimit]
ret.time = moment(new Date(ret.timestamp)).format('MM-DD HH:mm')
return ret
2022-11-07 20:08:24 +00:00
}
static async setUidInfo ({ uid, qq, profiles, uidType = 'bind' }) {
if (!uid) {
return false
}
let basicCount = 0
let totalCount = 0
for (let charId in profiles) {
let profile = profiles[charId]
if (!profile || !profile.hasData) {
continue
}
if (['安柏', '凯亚', '丽莎'].includes(profile.name)) {
basicCount++
}
totalCount++
}
2022-11-13 20:43:59 +00:00
let data = {}
try {
2022-11-13 23:10:29 +00:00
let uData = await redis.get(`miao:rank:uid-info:${uid}`)
if (uData) {
data = JSON.parse(uData)
2022-11-13 20:43:59 +00:00
}
} catch (e) {
data = {}
}
data.totalCount = totalCount
data.basicCount = basicCount
if (data.isSelfUid) {
delete data.isSelfUid
data.uidType = 'ck'
}
if (uidType === 'ck') {
data.uidType = 'ck'
data.qq = qq || data.qq || ''
} else {
data.uidType = data.uidType || 'bind'
if (data.uidType === 'bind') {
data.qq = data.qq || qq || ''
} else {
data.qq = qq || data.qq || ''
}
}
await redis.set(`miao:rank:uid-info:${uid}`, JSON.stringify(data), { EX: 3600 * 24 * 365 })
}
static async getUidInfo (uid) {
try {
let data = await redis.get(`miao:rank:uid-info:${uid}`)
return JSON.parse(data)
} catch (e) {
}
return false
}
2022-11-13 20:43:59 +00:00
/**
* 1: '无限制',
* 2: '绑定有CK的用户',
* 3: '面板列表有16个角色数据或绑定CK',
* 4: '面板列表有安柏&凯亚&丽莎的数据或绑定CK',
* 5: '面板列表有16个角色数据且包含安柏&凯亚&丽莎或绑定CK'
* @param uid
* @returns {Promise<boolean>}
*/
static async checkRankLimit (uid) {
if (!uid) {
return false
}
try {
let rankLimit = Common.cfg('groupRankLimit') * 1 || 1
if (rankLimit === 1) {
return true
}
let data = await redis.get(`miao:rank:uid-info:${uid}`)
data = JSON.parse(data)
if (data.isSelfUid || data.uidType === 'ck') {
2022-11-13 20:43:59 +00:00
return true
}
if (rankLimit === 2) {
return false
}
if ((data.totalCount || 0) < 16 && [3, 5].includes(rankLimit)) {
return false
}
2022-11-13 20:43:59 +00:00
if ((data.basicCount || 0) < 3 && [4, 5].includes(rankLimit)) {
return false
}
return true
} catch (e) {
return false
}
}
2022-11-07 20:08:24 +00:00
}