From 985f117d39bcd7932d9adb3b97187b11763a530f Mon Sep 17 00:00:00 2001 From: luying Date: Mon, 12 Apr 2021 09:44:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=92=E8=A1=8C=E6=A6=9C=EF=BC=9A2=E4=B8=AA?= =?UTF-8?q?=E6=9C=88=E6=9C=AA=E7=99=BB=E5=BD=95=E6=8E=92=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- game-server/app/services/rankService.ts | 83 ++++++++++++++++++++++++- shared/domain/rank.ts | 3 + 2 files changed, 83 insertions(+), 3 deletions(-) diff --git a/game-server/app/services/rankService.ts b/game-server/app/services/rankService.ts index 808a87df4..e3f05102f 100644 --- a/game-server/app/services/rankService.ts +++ b/game-server/app/services/rankService.ts @@ -7,6 +7,7 @@ import { HeroModel, HeroType } from "../db/Hero"; import { SystemConfigModel } from "../db/SystemConfig"; import { PvpDefenseModel } from "../db/PvpDefense"; import { gameData } from "../pubUtils/data"; +import { nowSeconds } from "../pubUtils/timeUtil"; /** @@ -45,24 +46,47 @@ export class Rank { this.limit = limit; } + /** + * 返回字段修改 + * @param obj + */ private async generFields(obj: GuildRankInfo | RoleRankInfo) { return obj; } + /** + * 从外部设置返回字段 + * @param cb + */ public setGenerFieldsFun(cb: (obj: GuildRankInfo | RoleRankInfo) => any) { this.generFields = cb; } - // 合成的排行榜的生命时长 单位s + /** + * 设置合成的排行榜的生命时长 单位s + * @param unionRankLife + */ public setUnionRankLife(unionRankLife: number) { this.unionRankLife = unionRankLife; } + /** + * 该排行是否为空 + * @param void + */ public async existsRank() { const result = await redisClient().existsAsync(this.keyName.getName()); return result; } + /** + * 根据role表设置更新排行榜&玩家信息 + * @param roleId 玩家id + * @param score 得分 + * @param timestamp 时间点 + * @param role 玩家数据库数据 + * @param isInc 得分是累加上的还是直接设置的 + */ public async setRankWithRoleInfo(roleId: string, score: number, timestamp: number, role?: RoleType, isInc = true) { // 如果没有信息,更新玩家信息 for (let infoKey of [this.infoKey, ...this.extraKeys]) { @@ -76,6 +100,14 @@ export class Rank { return newScore; } + /** + * 根据军团表设置更新排行榜&军团信息 + * @param guildCode 军团code + * @param score 得分 + * @param timestamp 时间点 + * @param guild 军团数据库 + * @param isInc 得分是累加上的还是直接设置的 + */ public async setRankWithGuildInfo(guildCode: string, score: number, timestamp: number, guild?: GuildType, isInc = true) { for (let infoKey of [this.infoKey, ...this.extraKeys]) { const hasCurUser = await redisClient().hexistsAsync(infoKey, guildCode); @@ -88,6 +120,15 @@ export class Rank { return newScore; } + /** + * 根据武将表设置更新排行榜&玩家信息 + * @param roleId 玩家id + * @param hid 武将id + * @param score 得分 + * @param timestamp 时间点 + * @param hero 武将数据库 + * @param isInc 得分是累加上的还是直接设置的 + */ public async setRankWithHeroInfo(roleId: string, hid: number, score: number, timestamp: number, hero?: HeroType, isInc = true) { // 如果没有信息,更新玩家信息 for (let infoKey of [this.infoKey, ...this.extraKeys]) { @@ -98,6 +139,11 @@ export class Rank { return newScore; } + /** + * 将玩家信息按顺序组成 如:roleId:hid + * @param {{ string }} key redis key + * @param {{ roleId?: string; guildCode?: string; hid?: number }} param 玩家信息 + */ private composeFields(key: string, param: myIdInter) { let type = KEY_TO_COMPOSE_FIELD.get(key); @@ -112,6 +158,12 @@ export class Rank { } } + /** + * 将合成了的玩家顺序解开 + * @param key redis key + * @param field + * @returns {{ roleId?: string; guildCode?: string; hid?: number }} + */ private decodeFields(key: string, field: string) { let type = KEY_TO_COMPOSE_FIELD.get(key); @@ -127,7 +179,12 @@ export class Rank { } } - // 保存info相关数据 + /** + * 将玩家数据设置进redis + * @param infoKey 玩家信息的redis key + * @param fields 玩家id + * @param db 数据库内的数据 + */ public async generParamAndSet(infoKey: string, fields: myIdInter, db: { role?: RoleType, guild?: GuildType, hero?: HeroType }) { let { roleId, guildCode, hid } = fields; let { role, guild, hero } = db; @@ -207,12 +264,25 @@ export class Rank { } } + /** + * 设置信息 + * @param infoKey + * @param myId + * @param param + */ private async setUserInfo(infoKey: string, myId: myIdInter, param: RankParam | GuildRankParam | LineupParam[]) { let field = this.composeFields(infoKey, myId); let value = JSON.stringify(param); return await redisClient().hsetAsync(infoKey, field, value); } + /** + * 更新排行榜数据 + * @param myId + * @param score + * @param timestamp + * @param isInc + */ public async setRank(myId: myIdInter, score: number, timestamp: number, isInc = false) { // 更新分数 @@ -496,14 +566,20 @@ export class Rank { key = await this.generateUnionRank(); } - const rankFromDb = await redisClient().zrevrangebyscoreAsync(key, from, to, "WITHSCORES", "LIMIT", 0, this.limit); + const rankFromDb = await redisClient().zrevrangebyscoreAsync(key, from, to, "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); + if(nowSeconds() - userInfo.updatedAt > 2 * 30 * 24 * 60 * 60) { + continue; + } let param: RoleRankInfo | GuildRankInfo; if (this.infoKey == REDIS_KEY.USER_INFO) { @@ -518,6 +594,7 @@ export class Rank { await this.setExInfoToParam(extraKey, param, myId, {}); } ranks.push(param); + num ++; } return ranks } diff --git a/shared/domain/rank.ts b/shared/domain/rank.ts index cab5e086e..25264cee6 100644 --- a/shared/domain/rank.ts +++ b/shared/domain/rank.ts @@ -4,6 +4,7 @@ import { RoleUpdate, RoleType } from "../db/Role"; import { reduceCe } from "../pubUtils/util"; import { GuildUpdateParam } from "../db/Guild"; import { HeroType, HeroUpdate } from "../db/Hero"; +import { getSeconds } from "../pubUtils/timeUtil"; // 排行榜返回玩家值 export class RankParam { @@ -16,6 +17,7 @@ export class RankParam { spine: number = EXTERIOR.EXTERIOR_APPEARANCE; title: number = 1; ce: number = 0; + updatedAt: number = 0; constructor(role: RoleUpdate, fromDb: boolean) { if(role.roleName) this.roleName = role.roleName; @@ -33,6 +35,7 @@ export class RankParam { this.ce = role.ce; } } + if(role.updatedAt) this.updatedAt = getSeconds(role.updatedAt); } }