红点:推送排行榜总榜

This commit is contained in:
luying
2021-06-01 19:32:20 +08:00
parent 07aa4a75fb
commit 0a5f3960eb
4 changed files with 114 additions and 4 deletions

View File

@@ -7,6 +7,7 @@ import { addUserToChannel, getSimpleRoleInfo } from '../../../services/roleServi
import { ChannelUser } from '../../../domain/ChannelUser';
import { getWorldChannelSid, groupRoomId } from '../../../services/chatService';
import { reloadResources } from '../../../pubUtils/data';
import { GeneralRankParamRole, GeneralRankParamBattle } from '../../../domain/rank';
export default function (app: Application) {
return new ChatRemote(app);
@@ -33,6 +34,7 @@ export class ChatRemote {
private channelService: ChannelService;
private GUILD_ACTIVITY_END = 'onGuildActivityEnd';
private RACE_ACTIVITY_START = 'onRaceStart';
private RANK_TOP_UPDATE = 'onRankTopUpdated';
/**
* 加入世界频道(分服).
@@ -190,6 +192,18 @@ export class ChatRemote {
channel.pushMessage(this.RACE_ACTIVITY_START, resResult(STATUS.SUCCESS, { }));
}
/**
* @description 全服推送排行榜更新信息
* @param serverId
*/
public async sendRankTopUpdated(serverId: number, rank: (GeneralRankParamRole|GeneralRankParamBattle)&{general: number}) {
let roomId = groupRoomId(CHANNEL_PREFIX.WORLD, serverId);
let channel = this.channelService.getChannel(roomId, false);
if (!channel) return;
channel.pushMessage(this.RANK_TOP_UPDATE, resResult(STATUS.SUCCESS, { rank }));
}
/**
* 重载json资源
*/

View File

@@ -8,6 +8,8 @@ import { SystemConfigModel } from "../db/SystemConfig";
import { PvpDefenseModel } from "../db/PvpDefense";
import { gameData } from "../pubUtils/data";
import { nowSeconds } from "../pubUtils/timeUtil";
import { getWorldChannelSid } from "./chatChannelService";
import { pinus } from "pinus";
/**
@@ -16,6 +18,7 @@ import { nowSeconds } from "../pubUtils/timeUtil";
* @class Rank
*/
export class Rank {
isInit: boolean = false; // 初始排行榜
key: string; // 排行榜原始key
keyName: KeyName; // 拼接之后的key
infoKey: string; // 玩家数据key
@@ -46,6 +49,10 @@ export class Rank {
this.limit = limit;
}
public setIsInit(init: boolean) {
this.isInit = init;
}
/**
* 返回字段修改
* @param obj
@@ -284,7 +291,8 @@ export class Rank {
* @param isInc
*/
public async setRank(myId: myIdInter, score: number, timestamp: number, isInc = false) {
let oldTop = await this.getRankByRank(0, 0);
let oldScore = oldTop.length > 0? oldTop[0].num: 0;
// 更新分数
let newScore = score;
if (this.isUnion) {
@@ -292,6 +300,7 @@ export class Rank {
} else {
newScore = await this.updateRankScoreEncode(myId, score, timestamp, isInc)
}
this.checkMyRankAndPush(myId, oldScore, newScore);
return newScore;
}
@@ -599,6 +608,47 @@ export class Rank {
return ranks
}
public async getRankByRank(start: number, end: number) {
let ranks = new Array<RoleRankInfo | GuildRankInfo>();
let key = this.keyName.getName();
if (this.isUnion) {
key = await this.generateUnionRank();
}
const rankFromDb = await redisClient().zrevrangeAsync(key, start, end, "WITHSCORES");
let num = 0;
for (let ii = 0; ii < rankFromDb.length; ii += 2) {
if(num >= this.limit) break;
const field = rankFromDb[ii];
let myId = this.decodeFields(this.key, field);
const { score, time } = this.decodeScore(rankFromDb[ii + 1]);
const info = await redisClient().hgetAsync(this.infoKey, this.composeFields(this.infoKey, myId));
const userInfo = JSON.parse(info);
let param: RoleRankInfo | GuildRankInfo;
if (this.infoKey == REDIS_KEY.USER_INFO) {
if(nowSeconds() - userInfo.updatedAt > 2 * 30 * 24 * 60 * 60) {
continue;
}
param = new RoleRankInfo(userInfo, false);
param.setInfo(Math.floor(ii / 2) + 1, myId, score, time);
} else if (this.infoKey == REDIS_KEY.GUILD_INFO) {
param = new GuildRankInfo(userInfo);
param.setInfo(Math.floor(ii / 2) + 1, myId, score, time);
}
for (let extraKey of this.extraKeys) {
await this.setExInfoToParam(extraKey, param, myId, {});
}
ranks.push(param);
num ++;
}
return ranks
}
// 获取我的排名
public async getMyRank(myId: myIdInter) {
@@ -681,6 +731,39 @@ export class Rank {
}
return timestamp
}
private async checkMyRankAndPush(myId: myIdInter, oldScore: number, newScore: number) {
if(this.isInit) return;
let myRank = await this.getMyRank(myId);
if(myRank == 1 && newScore > oldScore) {
let serverId = this.keyName.serverId;
let sid = await getWorldChannelSid(serverId);
for(let { id, general } of gameData.rank) {
let redisKey = RANK_TYPE_TO_KEY.get(id);
if(redisKey == this.key) {
if(general == 1) {
let r = new Rank(redisKey, { serverId }, false, 1);
let ranks = <RoleRankInfo[]> await r.getRankByRange();
if(ranks.length > 0) {
let param = new GeneralRankParamRole(id, ranks[0]||new RoleRankInfo({}, false));
pinus.app.rpc.chat.chatRemote.sendRankTopUpdated.toServer(sid, serverId, {...param, general});
}
} else if (general = 2) {
let r = new Rank(redisKey, { serverId }, false, 1);
let ranks = <RoleRankInfo[]> await r.getRankByRange();
let hero: HeroUpdate;
if(ranks.length > 0) {
hero = await HeroModel.getMyTopHero(ranks[0].roleId, 'hid skins');
let param = new GeneralRankParamBattle(id, ranks[0]||new RoleRankInfo({}, false), hero);
pinus.app.rpc.chat.chatRemote.sendRankTopUpdated.toServer(sid, serverId, {...param, general});
}
}
break;
}
}
}
}
}
@@ -695,6 +778,7 @@ export async function setRankRedisFromDb(type: string, args?: {serverId?: number
let serverId = args.serverId;
let ranks = await RoleModel.getRank('tower', serverId, ROLE_SELECT.RANK);
let r = new Rank(type, { serverId });
r.setIsInit(true);
for(let role of ranks) {
// console.log(roleId);
await r.setRankWithRoleInfo(role.roleId, role.towerLv, role.towerUpTime?role.towerUpTime.getTime():0, role);
@@ -703,6 +787,7 @@ export async function setRankRedisFromDb(type: string, args?: {serverId?: number
let serverId = args.serverId;
let ranks = await GuildModel.getRank(type, serverId);
let r = new Rank(type, { serverId });
r.setIsInit(true);
for(let guild of ranks) {
await r.setRankWithGuildInfo(guild.code, guild.activeWeekly, guild.activeUpdateTime, guild);
}
@@ -710,6 +795,7 @@ export async function setRankRedisFromDb(type: string, args?: {serverId?: number
let serverId = args.serverId;
let ranks = await GuildModel.getRank(type, serverId);
let r = new Rank(type, { serverId });
r.setIsInit(true);
for(let guild of ranks) {
await r.setRankWithGuildInfo(guild.code, guild.lv, guild.lvUpdateTime, guild);
}
@@ -718,6 +804,7 @@ export async function setRankRedisFromDb(type: string, args?: {serverId?: number
console.log('execute season resetPvpRanks seasonNum = ' + seasonNum);
let ranks = await PvpDefenseModel.getRank(seasonNum);//获得全服前1000名的排名加入到redis中
let r = new Rank(type, {});
r.setIsInit(true);
for(let {roleId, role: _role, score, updatedAt } of ranks) {
let role = <RoleType>_role;
if (!role) {
@@ -729,6 +816,7 @@ export async function setRankRedisFromDb(type: string, args?: {serverId?: number
let serverId = args.serverId;
let ranks = await RoleModel.getRank('topLineup', serverId, ROLE_SELECT.RANK);
let r = new Rank(type, { serverId });
r.setIsInit(true);
for(let role of ranks) {
// console.log(roleId);
await r.setRankWithRoleInfo(role.roleId, role.topLineupCe, role.updatedAt.getTime(), role);
@@ -737,6 +825,7 @@ export async function setRankRedisFromDb(type: string, args?: {serverId?: number
let serverId = args.serverId;
let ranks = await HeroModel.getAllRank(serverId, HERO_SELECT.RANK_LINEUP);
let r = new Rank(type, { serverId });
r.setIsInit(true);
for(let hero of ranks) {
await r.setRankWithHeroInfo(hero.roleId, hero.hid, hero.ce, hero.updatedAt.getTime(), hero);
}
@@ -744,6 +833,7 @@ export async function setRankRedisFromDb(type: string, args?: {serverId?: number
let serverId = args.serverId;
let ranks = await RoleModel.getRank('heroNum', serverId, ROLE_SELECT.RANK);
let r = new Rank(type, { serverId });
r.setIsInit(true);
for(let role of ranks) {
await r.setRankWithRoleInfo(role.roleId, role.heroNum, role.heroNumUpdatedAt, role );
}
@@ -751,6 +841,7 @@ export async function setRankRedisFromDb(type: string, args?: {serverId?: number
let serverId = args.serverId;
let ranks = await RoleModel.getRank('lv', serverId, ROLE_SELECT.RANK);
let r = new Rank(type, { serverId });
r.setIsInit(true);
for(let role of ranks) {
await r.setRankWithRoleInfo(role.roleId, role.lv, role.updatedAt.getTime(), role);
}
@@ -758,6 +849,7 @@ export async function setRankRedisFromDb(type: string, args?: {serverId?: number
let serverId = args.serverId;
let ranks = await RoleModel.getRank('ce', serverId, ROLE_SELECT.RANK);
let r = new Rank(type, { serverId });
r.setIsInit(true);
for(let role of ranks) {
await r.setRankWithRoleInfo(role.roleId, role.ce, role.updatedAt.getTime(), role);
}
@@ -765,6 +857,7 @@ export async function setRankRedisFromDb(type: string, args?: {serverId?: number
let serverId = args.serverId;
let ranks = await RoleModel.getRank('dungeon', serverId, ROLE_SELECT.RANK);
let r = new Rank(type, { serverId });
r.setIsInit(true);
for(let role of ranks) {
await r.setRankWithRoleInfo(role.roleId, role.dungeonWarId, role.dungeonUpdatedAt, role);
}
@@ -772,6 +865,7 @@ export async function setRankRedisFromDb(type: string, args?: {serverId?: number
let serverId = args.serverId;
let ranks = await RoleModel.getRank('main', serverId, ROLE_SELECT.RANK);
let r = new Rank(type, { serverId });
r.setIsInit(true);
for(let role of ranks) {
await r.setRankWithRoleInfo(role.roleId, role.mainWarId, role.mainUpdatedAt, role);
}
@@ -779,6 +873,7 @@ export async function setRankRedisFromDb(type: string, args?: {serverId?: number
let serverId = args.serverId;
let ranks = await RoleModel.getRank('mainElite', serverId, ROLE_SELECT.RANK);
let r = new Rank(type, { serverId });
r.setIsInit(true);
for(let role of ranks) {
await r.setRankWithRoleInfo(role.roleId, role.mainEliteWarId, role.mainEliteUpdatedAt, role);
}
@@ -788,6 +883,7 @@ export async function setRankRedisFromDb(type: string, args?: {serverId?: number
for(let hid of gameData.dicMyHeroes) {
let ranks = await HeroModel.getRank(hid, serverId, HERO_SELECT.RANK_LINEUP);
let r = new Rank(type, { serverId, hid });
r.setIsInit(true);
for(let hero of ranks) {
await r.setRankWithHeroInfo(hero.roleId, hid, hero.ce, hero.updatedAt.getTime(), hero);
}

View File

@@ -506,7 +506,7 @@ export default class Role extends BaseModel {
let dungeonHeroes = role && role.dungeonHeroes;
let hasHero = dungeonHeroes && dungeonHeroes.find(cur => cur.battleId == battleId);
if (!dungeonHeroes || !hasHero) {
role = await RoleModel.findOneAndUpdate({ roleId }, { $push: { dungeonHeroes: { battleId, heroes } }, $set: { dungeonWarId: battleId, dungeonUpdatedAt: nowSeconds() } });
role = await RoleModel.findOneAndUpdate({ roleId }, { $push: { dungeonHeroes: { battleId, heroes } }, $set: { dungeonWarId: battleId, dungeonUpdatedAt: nowSeconds() } }, { new: true });
}
return role;
}

View File

@@ -266,7 +266,7 @@ export class GeneralRankParamRole {
num: number;
received: number[];
constructor(type: number, rankInfo: RoleRankInfo, received: number[]) {
constructor(type: number, rankInfo: RoleRankInfo, received?: number[]) {
this.type = type;
this.roleId = rankInfo.roleId;
this.roleName = rankInfo.roleName;
@@ -296,7 +296,7 @@ export class GeneralRankParamBattle {
frame: number;
spine: number;
constructor(type: number, rankInfo: RoleRankInfo, hero: HeroUpdate, received: number[]) {
constructor(type: number, rankInfo: RoleRankInfo, hero: HeroUpdate, received?: number[]) {
this.type = type;
this.roleId = rankInfo.roleId;
this.roleName = rankInfo.roleName;