排行榜: 获取排行榜

This commit is contained in:
luying
2021-04-12 09:47:15 +08:00
parent 34e02dea89
commit 5dca7b304d
32 changed files with 1077 additions and 290 deletions
+491 -89
View File
@@ -1,8 +1,13 @@
import { KeyName, KeyNameParam, RankParam, GuildRankParam, RoleRankInfo, GuildRankInfo, GuildLeader } from "../domain/rank";
import { REDIS_RANK_TO_INFO, ROLE_SELECT, GUILD_SELECT, REDIS_KEY } from "../consts";
import { KeyName, KeyNameParam, RankParam, GuildRankParam, RoleRankInfo, GuildRankInfo, GuildLeader, LineupParam, myIdInter } from "../domain/rank";
import { REDIS_RANK_TO_INFO, ROLE_SELECT, GUILD_SELECT, REDIS_KEY, REDIS_RANK_TO_EXTRA, HERO_SELECT, COMPOSE_FIELD_TYPE, KEY_TO_COMPOSE_FIELD } from "../consts";
import { redisClient, setUserInfo } from "./redisService";
import { RoleType, RoleModel } from "../db/Role";
import { GuildType, GuildModel } from "../db/Guild";
import Hero, { HeroModel, HeroType } from "../db/Hero";
import { SystemConfigModel } from "../db/SystemConfig";
import { PvpDefenseModel } from "../db/PvpDefense";
import { gameData } from "../pubUtils/data";
/**
* @description 排行榜相关操作
@@ -13,25 +18,27 @@ export class Rank {
key: string; // 排行榜原始key
keyName: KeyName; // 拼接之后的key
infoKey: string; // 玩家数据key
extraKeys: string[];
isUnion: boolean; // 是否使用多个zset联合计算
limit: number = 200; // 排行榜长度
timelen: number = 10; // 给时间位留的长度
unionRankLife: number = 10;
constructor(key: string, keyParam: KeyNameParam, isUnion = false, timelen = 10, limit = 200) {
this.key = key;
this.keyName = new KeyName(key, keyParam);
this.infoKey = REDIS_RANK_TO_INFO.get(key);
this.extraKeys = REDIS_RANK_TO_EXTRA.get(key) || [];
this.isUnion = isUnion;
this.timelen = timelen;
this.limit = limit;
}
private async generFields(obj: GuildRankInfo|RoleRankInfo) {
private async generFields(obj: GuildRankInfo | RoleRankInfo) {
return obj;
}
public setGenerFieldsFun(cb: (obj: GuildRankInfo|RoleRankInfo) => any) {
public setGenerFieldsFun(cb: (obj: GuildRankInfo | RoleRankInfo) => any) {
this.generFields = cb;
}
@@ -45,41 +52,162 @@ export class Rank {
return result;
}
public async setRankWithRoleInfo(roleId: string, score: number, timestamp: number, role?: RoleType, needReduceCe = false, isInc = true ) {
public async setRankWithRoleInfo(roleId: string, score: number, timestamp: number, role?: RoleType, isInc = true) {
// 如果没有信息,更新玩家信息
const hasCurUser = await redisClient().hexistsAsync(this.infoKey, roleId);
if(!hasCurUser) {
if(!role) {
role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.RANK, true);
needReduceCe = true;
for (let infoKey of [this.infoKey, ...this.extraKeys]) {
const hasCurUser = await redisClient().hexistsAsync(infoKey, roleId);
if (!hasCurUser) {
await this.generParamAndSet(infoKey, { roleId }, { role });
}
let param = new RankParam(role, needReduceCe);
await setUserInfo(this.infoKey, roleId, param);
}
let newScore = await this.setRank(roleId, score, timestamp, isInc);
let newScore = await this.setRank({ roleId }, score, timestamp, isInc);
return newScore;
}
public async setRankWithGuildInfo(guildCode: string, score: number, timestamp: number, guild?: GuildType, isInc = true) {
const hasCurUser = await redisClient().hexistsAsync(this.infoKey, guildCode);
if(!hasCurUser) {
if(!guild) {
guild = await GuildModel.findByCode(guildCode, this.keyName.serverId, GUILD_SELECT.RANK)
for (let infoKey of [this.infoKey, ...this.extraKeys]) {
const hasCurUser = await redisClient().hexistsAsync(infoKey, guildCode);
if (!hasCurUser) {
await this.generParamAndSet(infoKey, { guildCode }, { guild });
}
let param = new GuildRankParam(guild);
await setUserInfo(this.infoKey, guildCode, param);
}
let newScore = await this.setRank(guildCode, score, timestamp, isInc);
let newScore = await this.setRank({ guildCode }, score, timestamp, isInc);
return newScore;
}
public async setRank(myId: string, score: number, timestamp: number, isInc = false) {
public async setRankWithHeroInfo(roleId: string, hid: number, score: number, timestamp: number, hero?: HeroType, isInc = true) {
// 如果没有信息,更新玩家信息
for (let infoKey of [this.infoKey, ...this.extraKeys]) {
const hasCurUser = await redisClient().hexistsAsync(infoKey, roleId);
if (!hasCurUser) {
await this.generParamAndSet(infoKey, { roleId, hid }, { hero });
}
}
let newScore = await this.setRank({ roleId, hid }, score, timestamp, isInc);
return newScore;
}
private composeFields(key: string, param: myIdInter) {
let type = KEY_TO_COMPOSE_FIELD.get(key);
if (type == COMPOSE_FIELD_TYPE.ROLE) {
return param.roleId;
} else if (type == COMPOSE_FIELD_TYPE.GUILD) {
return param.guildCode;
} else if (type == COMPOSE_FIELD_TYPE.ROLE_HERO) {
return `${param.roleId}:${param.hid}`;
} else {
return '';
}
}
private decodeFields(key: string, field: string) {
let type = KEY_TO_COMPOSE_FIELD.get(key);
let arr = field.split(':');
if (type == COMPOSE_FIELD_TYPE.ROLE) {
return { roleId: arr[0] };
} else if (type == COMPOSE_FIELD_TYPE.GUILD) {
return { guildCode: arr[0] };
} else if (type == COMPOSE_FIELD_TYPE.ROLE_HERO) {
return { roleId: arr[0], hid: parseInt(arr[1]) };
} else {
return {};
}
}
private async generParamAndSet(infoKey: string, fields: myIdInter, db: { role?: RoleType, guild?: GuildType, hero?: HeroType }) {
let { roleId, guildCode, hid } = fields;
let { role, guild, hero } = db;
if (infoKey == REDIS_KEY.USER_INFO) {
if (!role) {
role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.RANK, true);
}
let param = new RankParam(role);
await this.setUserInfo(infoKey, { roleId }, param);
} else if (infoKey == REDIS_KEY.GUILD_INFO) {
if (!guild) {
guild = await GuildModel.findByCode(guildCode, this.keyName.serverId, GUILD_SELECT.RANK)
}
let param = new GuildRankParam(guild);
await this.setUserInfo(infoKey, { guildCode }, param);
} else if (infoKey == REDIS_KEY.TOP_LINEUP_INFO) {
if (!role) {
role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.RANK, true);
}
let { topLineup = [] } = role;
let heroes = await HeroModel.findByRole(roleId, [], HERO_SELECT.RANK_LINEUP);
let arr = new Array<LineupParam>();
for (let { hid } of topLineup) {
let curHero = heroes.find(cur => cur.hid == hid);
if (curHero) {
let param = new LineupParam(curHero);
arr.push(param);
}
}
await this.setUserInfo(infoKey, { roleId }, arr);
} else if (infoKey == REDIS_KEY.HERO_INFO) {
if (!hero) {
hero = await HeroModel.findByHidAndRole(hid, roleId, HERO_SELECT.RANK_LINEUP, true);
}
let arr = new Array<LineupParam>();
if (hero) {
let param = new LineupParam(hero);
arr.push(param);
await this.setUserInfo(infoKey, { roleId, hid }, arr);
}
} else if (infoKey == REDIS_KEY.DUNGEON_LINEUP) {
if (!role) {
role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.RANK, true);
}
let { dungeonWarId, dungeonHeroes } = role;
if(dungeonWarId > 0) {
let cur = dungeonHeroes.find(cur => cur.battleId == dungeonWarId);
let lineup = cur?cur.heroes: [];
let heroes = await HeroModel.findByRole(roleId, [], HERO_SELECT.RANK_LINEUP);
let arr = new Array<LineupParam>();
for (let seqId of lineup) {
let curHero = heroes.find(cur => cur.seqId == seqId);
if (curHero) {
let param = new LineupParam(curHero);
arr.push(param);
}
}
await this.setUserInfo(infoKey, { roleId }, arr);
}
} else if (infoKey == REDIS_KEY.SHOW_LINEUP) {
if (!role) {
role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.RANK, true);
}
let { showLineup, topLineup = [] } = role;
let heroes = await HeroModel.findByRole(roleId, [], HERO_SELECT.RANK_LINEUP);
let arr = new Array<LineupParam>();
if(!showLineup) showLineup = topLineup.map(cur => cur.hid);
for (let hid of showLineup) {
let curHero = heroes.find(cur => cur.hid == hid);
if (curHero) {
let param = new LineupParam(curHero);
arr.push(param);
}
}
await this.setUserInfo(infoKey, { roleId }, arr);
}
}
private async setUserInfo(infoKey: string, myId: myIdInter, param: RankParam | GuildRankParam | LineupParam[]) {
let field = this.composeFields(infoKey, myId);
await setUserInfo(infoKey, field, param);
}
public async setRank(myId: myIdInter, score: number, timestamp: number, isInc = false) {
// 更新分数
let newScore = score;
if(this.isUnion) {
if (this.isUnion) {
newScore = await this.updateRankScoreAtom(myId, score, timestamp, isInc);
} else {
newScore = await this.updateRankScoreEncode(myId, score, timestamp, isInc)
@@ -93,16 +221,16 @@ export class Rank {
* @param score
* @param timestamp
*/
private async updateRankScoreEncode(myId: string, score: number, timestamp: number, isInc = false) {
private async updateRankScoreEncode(myId: myIdInter, score: number = 0, timestamp: number = 0, isInc = false) {
let newScore = score;
let key = this.keyName.getName();
if(isInc) {
if (isInc) {
let oldScore = await this.getMyScore(myId);
newScore = oldScore + score;
}
let scoreStr = this.encodeScore(newScore, timestamp);
await redisClient().zaddAsync(key, scoreStr, myId);
await redisClient().zaddAsync(key, scoreStr, this.composeFields(this.key, myId));
return score
}
@@ -114,24 +242,25 @@ export class Rank {
* @param isInc
* @class Rank
*/
private async updateRankScoreAtom(myId: string, score: number, timestamp: number, isInc = false) {
private async updateRankScoreAtom(myId: myIdInter, score: number = 0, timestamp: number = 0, isInc = false) {
let key = this.keyName.getName();
let timeKey = this.keyName.getTimeName();
let pow = Math.pow(10, this.timelen + 1);
let newScore = 0;
// 分数zset
if(isInc) {
newScore = await redisClient().zincrbyAsync(key, score, myId);
if (isInc) {
newScore = await redisClient().zincrbyAsync(key, score, this.composeFields(this.key, myId));
} else {
newScore = await redisClient().zaddAsync(key, score, myId);
newScore = await redisClient().zaddAsync(key, score, this.composeFields(this.key, myId));
}
// 时间zset
await redisClient().zaddAsync(timeKey, pow - 1 - Math.floor(timestamp/1000), myId);
await redisClient().zaddAsync(timeKey, pow - 1 - this.handleTimestamp(timestamp), this.composeFields(this.key, myId));
return parseInt(newScore.toString());
}
/**
* @description 设置到期时间
* @param time 到期时间,10位时间戳
@@ -145,58 +274,202 @@ export class Rank {
await redisClient().expireatAsync(timeKey, time);
}
public async generMyRankWithRole(roleId: string, score: number, time: number, role?: RoleType, needReduceCe = false) {
public async generMyRankWithRole(roleId: string, score: number, time: number, role?: RoleType) {
// 如果没有信息,更新玩家信息
let param: RoleRankInfo;
let hasCurUser = await redisClient().hexistsAsync(this.infoKey, roleId);
if(!hasCurUser) {
if(!role) {
if (!hasCurUser) {
if (!role) {
role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.RANK, true);
needReduceCe = true;
}
let param = new RoleRankInfo(role, needReduceCe);
param.setInfo(0, roleId, score, time);
return await this.generFields(param);
param = new RoleRankInfo(role);
param.setInfo(0, { roleId }, score, time);
} else {
const info = await redisClient().hgetAsync(this.infoKey, roleId);
const userInfo = JSON.parse(info);
let param = new RoleRankInfo(userInfo);
param.setInfo(0, roleId, score, time);
return await this.generFields(param);
param = new RoleRankInfo(userInfo);
param.setInfo(0, { roleId }, score, time);
}
for (let extraKey of this.extraKeys) {
await this.setExInfoToParam(extraKey, param, { roleId }, {role});
}
return await this.generFields(param);
}
public async generMyRankWithGuild(guildCode: string, score: number, time: number, guild?: GuildType) {
// 如果没有信息,更新玩家信息
let param: GuildRankInfo;
let hasCurUser = await redisClient().hexistsAsync(this.infoKey, guildCode);
if(!hasCurUser) {
if(!guild) {
if (!hasCurUser) {
if (!guild) {
guild = await GuildModel.findByCode(guildCode, this.keyName.serverId, GUILD_SELECT.RANK);
}
let param = new GuildRankInfo(guild);
param.setInfo(0, guildCode, score, time);
return await this.generFields(param);
param = new GuildRankInfo(guild);
param.setInfo(0, { guildCode }, score, time);
} else {
const info = await redisClient().hgetAsync(this.infoKey, guildCode);
const guildInfo = JSON.parse(info);
let param = new GuildRankInfo(guildInfo);
param.setInfo(0, guildCode, score, time);
return await this.generFields(param);
param = new GuildRankInfo(guildInfo);
param.setInfo(0, { guildCode }, score, time);
}
for (let extraKey of this.extraKeys) {
await this.setExInfoToParam(extraKey, param, { guildCode }, { guild } );
}
return await this.generFields(param);
}
public async generMyRankWithHero(roleId: string, hid: number, score: number, time: number, hero?: HeroType, role?: RoleType) {
// 如果没有信息,更新玩家信息
let param: RoleRankInfo;
let hasCurUser = await redisClient().hexistsAsync(this.infoKey, roleId);
if (!hasCurUser) {
if(!role) {
role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.RANK, true);
}
param = new RoleRankInfo(role);
param.setInfo(0, { roleId, hid }, score, time);
} else {
const info = await redisClient().hgetAsync(this.infoKey, roleId);
const userInfo = JSON.parse(info);
param = new RoleRankInfo(userInfo);
param.setInfo(0, { roleId, hid }, score, time);
}
for (let extraKey of this.extraKeys) {
await this.setExInfoToParam(extraKey, param, { roleId, hid }, { hero, role });
}
return await this.generFields(param);
}
private async setExInfoToParam(extraKey: string, param: RoleRankInfo | GuildRankInfo, myId: myIdInter, db: { role?: RoleType, guild?: GuildType, hero?: HeroType }) {
let { role, guild, hero } = db;
if (extraKey == REDIS_KEY.TOP_LINEUP_INFO) {
param = <RoleRankInfo>param;
let hasCurUser = await redisClient().hexistsAsync(extraKey, this.composeFields(extraKey, myId));
if (!hasCurUser) {
if (!role) {
role = await RoleModel.findByRoleId(myId.roleId, ROLE_SELECT.RANK, true);
}
let { topLineup } = role;
let heroes = await HeroModel.findByRole(myId.roleId, [], HERO_SELECT.HERO_DETAIL);
let arr = new Array<LineupParam>();
for (let { hid } of topLineup) {
let curHero = heroes.find(cur => cur.hid == hid);
if (curHero) {
let param = new LineupParam(curHero);
arr.push(param);
}
}
param.setTopLine(arr);
} else {
const info = await redisClient().hgetAsync(extraKey, this.composeFields(extraKey, myId));
const infoObj = JSON.parse(info);
param.setTopLine(infoObj);
}
} else if (extraKey == REDIS_KEY.HERO_INFO) {
param = <RoleRankInfo>param;
let hasCurUser = await redisClient().hexistsAsync(extraKey, this.composeFields(extraKey, myId));
if (!hasCurUser) {
if(!hero) {
hero = await HeroModel.findByHidAndRole(myId.hid, myId.roleId, HERO_SELECT.RANK_LINEUP);
}
let arr = new Array<LineupParam>();
let lineParam = new LineupParam(hero);
arr.push(lineParam);
if(this.key == REDIS_KEY.HERO_RANK) {
param.setSingleHero(arr);
} else {
param.setTopLine(arr);
}
} else {
const info = await redisClient().hgetAsync(extraKey, this.composeFields(extraKey, myId));
const infoObj = JSON.parse(info);
if(this.key == REDIS_KEY.HERO_RANK) {
param.setSingleHero(infoObj);
} else {
param.setTopLine(infoObj);
}
}
} else if (extraKey == REDIS_KEY.DUNGEON_LINEUP) {
param = <RoleRankInfo>param;
let hasCurUser = await redisClient().hexistsAsync(extraKey, this.composeFields(extraKey, myId));
if (!hasCurUser) {
if (!role) {
role = await RoleModel.findByRoleId(myId.roleId, ROLE_SELECT.RANK, true);
}
let { dungeonWarId, dungeonHeroes } = role;
let cur = dungeonHeroes.find(cur => cur.battleId == dungeonWarId);
let lineup = cur?cur.heroes: [];
let heroes = await HeroModel.findByRole(myId.roleId, [], HERO_SELECT.RANK_LINEUP);
let arr = new Array<LineupParam>();
for (let seqId of lineup) {
let curHero = heroes.find(cur => cur.seqId == seqId);
if (curHero) {
let param = new LineupParam(curHero);
arr.push(param);
}
}
param.setTopLine(arr);
} else {
const info = await redisClient().hgetAsync(extraKey, this.composeFields(extraKey, myId));
const infoObj = JSON.parse(info);
param.setTopLine(infoObj);
}
} else if (extraKey == REDIS_KEY.SHOW_LINEUP) {
param = <RoleRankInfo>param;
let hasCurUser = await redisClient().hexistsAsync(extraKey, this.composeFields(extraKey, myId));
if (!hasCurUser) {
if (!role) {
role = await RoleModel.findByRoleId(myId.roleId, ROLE_SELECT.RANK, true);
}
let { showLineup, topLineup = [] } = role;
let heroes = await HeroModel.findByRole(myId.roleId, [], HERO_SELECT.HERO_DETAIL);
let arr = new Array<LineupParam>();
if(!showLineup) showLineup = topLineup.map(cur => cur.hid);
for (let hid of showLineup) {
let curHero = heroes.find(cur => cur.hid == hid);
if (curHero) {
let param = new LineupParam(curHero);
arr.push(param);
}
}
param.setTopLine(arr);
} else {
const info = await redisClient().hgetAsync(extraKey, this.composeFields(extraKey, myId));
const infoObj = JSON.parse(info);
param.setTopLine(infoObj);
}
}
}
public async getRankListWithMyRank(myId: string) {
public async getRankListWithMyRank(myId: myIdInter) {
let ranks = await this.getRankByRange();
let newRanks = [], newMyRank;
let newRanks = [], newMyRank: RoleRankInfo | GuildRankInfo;
let myRank = ranks.find(cur => {
return cur.isMyInfo(myId);
});
if(this.generFields) {
for(let rank of ranks) {
if (this.generFields) {
for (let rank of ranks) {
let n = await this.generFields(rank);
newRanks.push(n);
}
if(myRank) {
if (myRank) {
newMyRank = await this.generFields(myRank);
}
}
@@ -204,44 +477,53 @@ export class Rank {
return { myRank: newMyRank, ranks: newRanks }
}
public async getRankByRange(from: number|string = '+inf', to: number|string = '-inf') {
public async getRankByRange(from: number | string = '+inf', to: number | string = '-inf') {
let ranks = new Array<RoleRankInfo|GuildRankInfo>();
let ranks = new Array<RoleRankInfo | GuildRankInfo>();
let key = this.keyName.getName();
if(this.isUnion) {
if (this.isUnion) {
key = await this.generateUnionRank();
}
const rankFromDb = await redisClient().zrevrangebyscoreAsync(key, from, to, "WITHSCORES", "LIMIT", 0, this.limit);
for(let ii = 0; ii < rankFromDb.length; ii+=2) {
const myId = rankFromDb[ii];
for (let ii = 0; ii < rankFromDb.length; ii += 2) {
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, myId);
const info = await redisClient().hgetAsync(this.infoKey, this.composeFields(this.infoKey, myId));
const userInfo = JSON.parse(info);
if(this.infoKey == REDIS_KEY.USER_INFO) {
let param = new RoleRankInfo(userInfo);
param.setInfo(Math.floor(ii/2)+1, myId, score, time);
ranks.push(param);
} else if(this.infoKey == REDIS_KEY.GUILD_INFO) {
let param = new GuildRankInfo(userInfo);
param.setInfo(Math.floor(ii/2)+1, myId, score, time);
ranks.push(param);
let param: RoleRankInfo | GuildRankInfo;
if (this.infoKey == REDIS_KEY.USER_INFO) {
param = new RoleRankInfo(userInfo);
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);
}
return ranks
}
// 获取我的排名
public async getMyRank(myId: string) {
// 获取我的排名
public async getMyRank(myId: myIdInter) {
let key = this.keyName.getName();
if(this.isUnion) {
if (this.isUnion) {
key = await this.generateUnionRank();
}
let myRank = await redisClient().zrevrankAsync(key, myId);
return myRank + 1;
let myRank = await redisClient().zrevrankAsync(key, this.composeFields(this.key, myId));
if(!myRank && myRank != 0) {
return 0;
} else {
return myRank + 1;
}
}
// 获取排名第几名的信息
@@ -253,11 +535,11 @@ export class Rank {
// 获取排名第几名的信息
public async getMyScore(myId: string) {
public async getMyScore(myId: myIdInter) {
let key = this.keyName.getName();
let score = await redisClient().zscoreAsync(key, myId);
if(!score) score = 0;
if(!this.isUnion) {
let score = await redisClient().zscoreAsync(key, this.composeFields(this.key, myId));
if (!score) score = 0;
if (!this.isUnion) {
let result = this.decodeScore(score.toString());
score = result.score;
}
@@ -265,9 +547,9 @@ export class Rank {
}
// 从排行榜中移除
public async removeFromRank(myId: string) {
public async removeFromRank(myId: myIdInter) {
let key = this.keyName.getName();
await redisClient().zremAsync(key, myId);
await redisClient().zremAsync(key, this.composeFields(this.key, myId));
return true;
}
@@ -275,12 +557,12 @@ export class Rank {
private async generateUnionRank() {
let unionKey = this.keyName.getUnionName(); // 联合的key
let existsKey = await redisClient().existsAsync(unionKey);
if(!existsKey) {
if (!existsKey) {
let originKey = this.keyName.getName();
let timeKey = this.keyName.getTimeName();
let pow = Math.pow(10, this.timelen + 1);
await redisClient().zunionstoreAsync(unionKey, 2, originKey, timeKey, 'WEIGHTS', pow, 1);
await redisClient().zunionstoreAsync(unionKey, 2, originKey, timeKey, 'WEIGHTS', pow, 1);
await redisClient().expireAsync(unionKey, this.unionRankLife); // 10秒更新一次
}
return unionKey;
@@ -290,7 +572,7 @@ export class Rank {
private encodeScore(score: number, timestamp: number) {
let timelen = this.timelen;
let pow = Math.pow(10, timelen + 1);
return score * pow + pow - 1 - Math.floor(timestamp/1000)
return score * pow + pow - 1 - this.handleTimestamp(timestamp)
}
private decodeScore(num: string) {
@@ -299,7 +581,127 @@ export class Rank {
let _num = parseInt(num);
return {
time: pow - _num % pow,
score: Math.floor(_num/pow)
score: Math.floor(_num / pow)
};
}
private handleTimestamp(timestamp: number = 0) {
let l = timestamp.toString().length;
if(l > this.timelen) {
timestamp = Math.floor(timestamp / Math.pow(10, l - this.timelen));
}
return timestamp
}
}
/**
* 从数据库内获取排行榜存入redis
* @param type 排行榜类型
* @param serverId 分服
*/
export async function setRankRedisFromDb(type: string, args?: {serverId?: number}) {
if(type == REDIS_KEY.TOWER_RANK) {
let serverId = args.serverId;
let ranks = await RoleModel.getRank('tower', serverId, ROLE_SELECT.RANK);
let r = new Rank(type, { serverId });
for(let role of ranks) {
// console.log(roleId);
await r.setRankWithRoleInfo(role.roleId, role.towerLv, role.towerUpTime?role.towerUpTime.getTime():0, role);
}
} else if (type == REDIS_KEY.GUILD_ACTIVE_RANK) {
let serverId = args.serverId;
let ranks = await GuildModel.getRank(type, serverId);
let r = new Rank(type, { serverId });
for(let guild of ranks) {
await r.setRankWithGuildInfo(guild.code, guild.activeWeekly, guild.activeUpdateTime, guild);
}
} else if (type == REDIS_KEY.GUILD_LV_RANK) {
let serverId = args.serverId;
let ranks = await GuildModel.getRank(type, serverId);
let r = new Rank(type, { serverId });
for(let guild of ranks) {
await r.setRankWithGuildInfo(guild.code, guild.lv, guild.lvUpdateTime, guild);
}
} else if ( type == REDIS_KEY.PVP_RANK) {
let { seasonNum } = await SystemConfigModel.findSystemConfig();
console.log('execute season resetPvpRanks seasonNum = ' + seasonNum);
let ranks = await PvpDefenseModel.getRank(seasonNum);//获得全服前1000名的排名,加入到redis中
let r = new Rank(type, {});
for(let {roleId, role: _role, score, updatedAt } of ranks) {
let role = <RoleType>_role;
if (!role) {
continue;
}
await r.setRankWithRoleInfo(roleId, score, updatedAt.getTime(), role);
}
} else if (type == REDIS_KEY.TOP_LINEUP_RANK) {
let serverId = args.serverId;
let ranks = await RoleModel.getRank('topLineup', serverId, ROLE_SELECT.RANK);
let r = new Rank(type, { serverId }, false, 0);
for(let role of ranks) {
// console.log(roleId);
await r.setRankWithRoleInfo(role.roleId, role.topLineupCe, role.updatedAt.getTime(), role);
}
} else if (type == REDIS_KEY.TOP_HERO_RANK) {
let serverId = args.serverId;
let ranks = await HeroModel.getAllRank(serverId, HERO_SELECT.RANK_LINEUP);
let r = new Rank(type, { serverId }, false, 0);
for(let hero of ranks) {
await r.setRankWithHeroInfo(hero.roleId, hero.hid, hero.ce, hero.updatedAt.getTime(), hero);
}
} else if (type == REDIS_KEY.HERO_NUM_RANK) {
let serverId = args.serverId;
let ranks = await RoleModel.getRank('heroNum', serverId, ROLE_SELECT.RANK);
let r = new Rank(type, { serverId });
for(let role of ranks) {
await r.setRankWithRoleInfo(role.roleId, role.heroNum, role.heroNumUpdatedAt, role );
}
} else if (type == REDIS_KEY.USER_LV) {
let serverId = args.serverId;
let ranks = await RoleModel.getRank('lv', serverId, ROLE_SELECT.RANK);
let r = new Rank(type, { serverId });
for(let role of ranks) {
await r.setRankWithRoleInfo(role.roleId, role.lv, role.updatedAt.getTime(), role);
}
} else if (type == REDIS_KEY.SUM_CE_RANK) {
let serverId = args.serverId;
let ranks = await RoleModel.getRank('ce', serverId, ROLE_SELECT.RANK);
let r = new Rank(type, { serverId }, false, 0);
for(let role of ranks) {
await r.setRankWithRoleInfo(role.roleId, role.ce, role.updatedAt.getTime(), role);
}
} else if (type == REDIS_KEY.DUNGEON_RANK) {
let serverId = args.serverId;
let ranks = await RoleModel.getRank('dungeon', serverId, ROLE_SELECT.RANK);
let r = new Rank(type, { serverId });
for(let role of ranks) {
await r.setRankWithRoleInfo(role.roleId, role.dungeonWarId, role.dungeonUpdatedAt, role);
}
} else if (type == REDIS_KEY.MAIN_RANK) {
let serverId = args.serverId;
let ranks = await RoleModel.getRank('main', serverId, ROLE_SELECT.RANK);
let r = new Rank(type, { serverId });
for(let role of ranks) {
await r.setRankWithRoleInfo(role.roleId, role.mainWarId, role.mainUpdatedAt, role);
}
} else if (type == REDIS_KEY.MAIN_ELITE_RANK) {
let serverId = args.serverId;
let ranks = await RoleModel.getRank('mainElite', serverId, ROLE_SELECT.RANK);
let r = new Rank(type, { serverId });
for(let role of ranks) {
await r.setRankWithRoleInfo(role.roleId, role.mainEliteWarId, role.mainEliteUpdatedAt, role);
}
} else if (type == REDIS_KEY.HERO_RANK) {
let serverId = args.serverId;
for(let hid of gameData.dicMyHeroes) {
let ranks = await HeroModel.getRank(hid, serverId, HERO_SELECT.RANK_LINEUP);
let r = new Rank(type, { serverId, hid }, false, 0);
for(let hero of ranks) {
await r.setRankWithHeroInfo(hero.roleId, hid, hero.ce, hero.updatedAt.getTime(), hero);
}
}
}
}