排行榜:修改格式

This commit is contained in:
luying
2021-09-08 17:48:58 +08:00
parent 343f77a40b
commit 5a02164803
12 changed files with 443 additions and 309 deletions
@@ -7,7 +7,7 @@ import { addUserToChannel, getSimpleRoleInfo } from '../../../services/roleServi
import { ChannelUser } from '../../../domain/ChannelUser'; import { ChannelUser } from '../../../domain/ChannelUser';
import { getWorldChannelSid, groupRoomId } from '../../../services/chatService'; import { getWorldChannelSid, groupRoomId } from '../../../services/chatService';
import { reloadResources } from '../../../pubUtils/data'; import { reloadResources } from '../../../pubUtils/data';
import { GeneralRankParamRole, GeneralRankParamBattle } from '../../../domain/rank'; import { GeneralRankParam } from '../../../domain/rank';
import { getAllGuildActivityStatus } from '../../../services/guildActivityService'; import { getAllGuildActivityStatus } from '../../../services/guildActivityService';
import { MailParam } from '../../../domain/roleField/mail'; import { MailParam } from '../../../domain/roleField/mail';
@@ -188,7 +188,7 @@ export class ChatRemote {
* @description 全服推送排行榜更新信息 * @description 全服推送排行榜更新信息
* @param serverId * @param serverId
*/ */
public async sendRankTopUpdated(serverId: number, rank: (GeneralRankParamRole | GeneralRankParamBattle) & { general: number }) { public async sendRankTopUpdated(serverId: number, rank: GeneralRankParam & { general: number }) {
let roomId = groupRoomId(CHANNEL_PREFIX.WORLD, serverId); let roomId = groupRoomId(CHANNEL_PREFIX.WORLD, serverId);
let channel = this.channelService.getChannel(roomId, false); let channel = this.channelService.getChannel(roomId, false);
@@ -236,9 +236,9 @@ export class GateActivityHandler {
if (isSuccess) { if (isSuccess) {
let score = gameData.gateActivityPoint.get(GET_POINT_WAYS.DEFENSE_SUCCESS); let score = gameData.gateActivityPoint.get(GET_POINT_WAYS.DEFENSE_SUCCESS);
// 更新redis数据 // 更新redis数据
await myR.setRank({ roleId }, score, Date.now(), true); await myR.setRank({ roleId }, [score, Date.now()], true);
await r.setRank({ guildCode }, score, Date.now(), true); await r.setRank({ guildCode }, [score, Date.now()], true);
} }
// 发放活跃 // 发放活跃
@@ -74,7 +74,7 @@ export class GuildHandler {
let r = new Rank(REDIS_KEY.GUILD_ACTIVE_RANK, { serverId }); let r = new Rank(REDIS_KEY.GUILD_ACTIVE_RANK, { serverId });
await r.setRankWithGuildInfo(guild.code, 0, Date.now(), guild); await r.setRankWithGuildInfo(guild.code, 0, Date.now(), guild);
let r2 = new Rank(REDIS_KEY.GUILD_LV_RANK, { serverId }); let r2 = new Rank(REDIS_KEY.GUILD_LV_RANK, { serverId });
await r2.setRankWithGuildInfo(guild.code, 0, Date.now(), guild); await r2.setRankWithGuildInfo2(guild.code, guild.lv, guild.activeWeekly, Date.now(), guild);
let rank = await r.getMyRank({ guildCode: guild.code }); let rank = await r.getMyRank({ guildCode: guild.code });
@@ -716,7 +716,7 @@ export class GuildHandler {
} }
if (id == GUILD_STRUCTURE.ARMY_CENTER) { if (id == GUILD_STRUCTURE.ARMY_CENTER) {
let r = new Rank(REDIS_KEY.GUILD_LV_RANK, { serverId }); let r = new Rank(REDIS_KEY.GUILD_LV_RANK, { serverId });
await r.setRankWithGuildInfo(code, guild.lv, guild.lvUpdateTime, guild); await r.setRankWithGuildInfo2(code, guild.lv, guild.activeWeekly, guild.lvUpdateTime, guild);
} }
const resultStructure = result.structure.find(cur => cur.id == id); const resultStructure = result.structure.find(cur => cur.id == id);
@@ -10,6 +10,7 @@ import { gameData } from "../../../pubUtils/data";
import { addItems } from "../../../services/rewardService"; import { addItems } from "../../../services/rewardService";
import { HeroModel, HeroUpdate } from "../../../db/Hero"; import { HeroModel, HeroUpdate } from "../../../db/Hero";
import { RewardInter } from "../../../pubUtils/interface"; import { RewardInter } from "../../../pubUtils/interface";
import { GuildRankInfo, RoleAndGuildRankInfo, RoleRankInfo } from "../../../domain/rank";
export default function (app: Application) { export default function (app: Application) {
new HandlerService(app, {}); new HandlerService(app, {});
@@ -28,21 +29,32 @@ export class RoleHandler {
let role = await RoleModel.findByRoleId(roleId, 'rankReceived'); let role = await RoleModel.findByRoleId(roleId, 'rankReceived');
if (!role) return resResult(STATUS.WRONG_PARMS); if (!role) return resResult(STATUS.WRONG_PARMS);
let res = await getGeneralRank(role, serverId); let ranks = await getGeneralRank(role, serverId);
return resResult(STATUS.SUCCESS, res); return resResult(STATUS.SUCCESS, { ranks });
} }
async getRank(msg: { type: number }, session: BackendSession) { async getRank(msg: { type: number }, session: BackendSession) {
let roleId = session.get('roleId'); let roleId = session.get('roleId');
let serverId = session.get('serverId'); let serverId = session.get('serverId');
let guildCode = session.get('guildCode');
let { type } = msg; let { type } = msg;
let redisKey = RANK_TYPE_TO_KEY.get(type); let redisKey = RANK_TYPE_TO_KEY.get(type);
if (!redisKey) return resResult(STATUS.WRONG_PARMS); if (!redisKey) return resResult(STATUS.WRONG_PARMS);
let r = new Rank(redisKey, { serverId }); let r = new Rank(redisKey, { serverId });
r.setGenerFieldsFun((obj => {
let result = new RoleAndGuildRankInfo(obj.rank, obj.num);
if(obj instanceof GuildRankInfo) {
result.setGuildInfo(obj);
}
if(obj instanceof RoleRankInfo) {
result.setUserInfo(obj);
}
return result
}));
let { ranks, myRank } = await r.getRankListWithMyRank({ roleId }); let { ranks, myRank } = await r.getRankListWithMyRank({ roleId, guildCode });
if (!myRank) { if (!myRank) {
let role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.RANK, true); let role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.RANK, true);
if (type == RANK_TYPE.TOP_LINTUP) { if (type == RANK_TYPE.TOP_LINTUP) {
@@ -64,6 +76,11 @@ export class RoleHandler {
myRank = await r.generMyRankWithRole(roleId, role.mainWarId, role.mainUpdatedAt, role); myRank = await r.generMyRankWithRole(roleId, role.mainWarId, role.mainUpdatedAt, role);
} else if (type == RANK_TYPE.MAIN_ELITE) { } else if (type == RANK_TYPE.MAIN_ELITE) {
myRank = await r.generMyRankWithRole(roleId, role.mainEliteWarId, role.mainEliteUpdatedAt, role); myRank = await r.generMyRankWithRole(roleId, role.mainEliteWarId, role.mainEliteUpdatedAt, role);
} else if (type == RANK_TYPE.GUILD_LV) {
if(role.hasGuild) {
let guild = await GuildModel.findByCode(guildCode, serverId);
myRank = await r.generMyRankWithGuild2(roleId, guild.lv, guild.activeWeekly, guild.lvUpdateTime, guild);
}
} }
} }
@@ -267,7 +267,7 @@ export class RaceActivityObject {
let needSendEnd = woodenHorse.calCurWoodenHorse(events); let needSendEnd = woodenHorse.calCurWoodenHorse(events);
if(woodenHorse.status == 1 || woodenHorse.status == 2) { // 更新距离 // TODO 写进const表 if(woodenHorse.status == 1 || woodenHorse.status == 2) { // 更新距离 // TODO 写进const表
let r = new Rank(REDIS_KEY.RACE_ACTIVITY, { serverId }, true, 5); let r = new Rank(REDIS_KEY.RACE_ACTIVITY, { serverId }, true, 5);
await r.setRank({guildCode}, Math.floor(woodenHorse.distance * 1000), woodenHorse.time - woodenHorse.startTime, false); await r.setRank({guildCode}, [Math.floor(woodenHorse.distance * 1000), woodenHorse.time - woodenHorse.startTime], false);
let tomorrow = <number>getTimeFun().getAfterDayWithHour(); let tomorrow = <number>getTimeFun().getAfterDayWithHour();
await r.setExpire(tomorrow); await r.setExpire(tomorrow);
if (needSendEnd) { // 抵达后发送奖励,发送消息,结算 if (needSendEnd) { // 抵达后发送奖励,发送消息,结算
+4 -1
View File
@@ -32,7 +32,7 @@ export async function getMyGuildInfo(roleId: string, sid: string, userGuild: Use
} }
// 获取排行榜 // 获取排行榜
let r = new Rank(REDIS_KEY.GUILD_ACTIVE_RANK, { serverId }); let r = new Rank(REDIS_KEY.GUILD_LV_RANK, { serverId });
const rank = await r.getMyRank({ guildCode: guild.code }); const rank = await r.getMyRank({ guildCode: guild.code });
let { lv: guildLv, memberCnt } = guild; let { lv: guildLv, memberCnt } = guild;
@@ -204,6 +204,8 @@ export async function addActive(roleId: string, serverId: number, id: number, ty
// 排行榜更新 // 排行榜更新
let r = new Rank(REDIS_KEY.GUILD_ACTIVE_RANK, { serverId }); let r = new Rank(REDIS_KEY.GUILD_ACTIVE_RANK, { serverId });
await r.setRankWithGuildInfo(guildCode, guild.activeWeekly, guild.activeUpdateTime, guild); await r.setRankWithGuildInfo(guildCode, guild.activeWeekly, guild.activeUpdateTime, guild);
let r2 = new Rank(REDIS_KEY.GUILD_LV_RANK, { serverId });
await r2.setRankWithGuildInfo2(guildCode, guild.lv, guild.activeWeekly, guild.lvUpdateTime, guild);
pinus.app.rpc.chat.guildRemote.updateInfo.toServer(CHAT_SERVER, guildCode, { activeDaily: guild.activeDaily, activeWeekly: guild.activeWeekly }); pinus.app.rpc.chat.guildRemote.updateInfo.toServer(CHAT_SERVER, guildCode, { activeDaily: guild.activeDaily, activeWeekly: guild.activeWeekly });
return { status: 1, guild, userGuild }; return { status: 1, guild, userGuild };
} }
@@ -312,6 +314,7 @@ export async function settleGuildWeekly() {
res.releaseCallback();//解锁 res.releaseCallback();//解锁
} }
await initSingleRank(REDIS_KEY.GUILD_ACTIVE_RANK); await initSingleRank(REDIS_KEY.GUILD_ACTIVE_RANK);
await initSingleRank(REDIS_KEY.GUILD_LV_RANK);
let curSeasonNum = await CounterModel.getCounter(COUNTER.PVP_SEASON_NUM); let curSeasonNum = await CounterModel.getCounter(COUNTER.PVP_SEASON_NUM);
await PVPConfigModel.updatePVPConfig(curSeasonNum, { settleGuildWeeklyTime: nowSeconds() }); // 记录一下,不知道原作者有什么用处... await PVPConfigModel.updatePVPConfig(curSeasonNum, { settleGuildWeeklyTime: nowSeconds() }); // 记录一下,不知道原作者有什么用处...
console.log('————— settleGuildWeekly结束 —————'); console.log('————— settleGuildWeekly结束 —————');
+189 -101
View File
@@ -1,4 +1,4 @@
import { KeyName, KeyNameParam, RankParam, GuildRankParam, RoleRankInfo, GuildRankInfo, GuildLeader, LineupParam, myIdInter, GeneralRankParamRole, GeneralRankParamBattle } from "../domain/rank"; import { KeyName, KeyNameParam, RankParam, GuildRankParam, RoleRankInfo, GuildLeader, LineupParam, myIdInter, GeneralRankParam, ValueConfig, GuildRankInfo } 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, RANK_TYPE_TO_KEY } from "../consts"; import { REDIS_RANK_TO_INFO, ROLE_SELECT, GUILD_SELECT, REDIS_KEY, REDIS_RANK_TO_EXTRA, HERO_SELECT, COMPOSE_FIELD_TYPE, KEY_TO_COMPOSE_FIELD, RANK_TYPE_TO_KEY } from "../consts";
import { redisClient, setUserInfo } from "./redisService"; import { redisClient, setUserInfo } from "./redisService";
import { RoleType, RoleModel } from "../db/Role"; import { RoleType, RoleModel } from "../db/Role";
@@ -19,38 +19,67 @@ import { pinus } from "pinus";
*/ */
export class Rank { export class Rank {
isInit: boolean = false; // 初始排行榜 isInit: boolean = false; // 初始排行榜
key: string; // 排行榜原始key key: REDIS_KEY; // 排行榜原始key
keyName: KeyName; // 拼接之后的key keyName: KeyName; // 拼接之后的key
infoKey: string; // 玩家数据key infoKey: REDIS_KEY; // 玩家数据key
extraKeys: string[]; extraKeys: string[];
isUnion: boolean; // 是否使用多个zset联合计算 isUnion: boolean; // 是否使用多个zset联合计算
limit: number = 200; // 排行榜长度 limit: number = 200; // 排行榜长度
timelen: number = 10; // 给时间位留的长度
unionRankLife: number = 10; unionRankLife: number = 10;
valueConfig: ValueConfig[] = []; // 值的组合方案
constructor(key: string, keyParam: KeyNameParam, isUnion = false, limit = 200) { constructor(key: REDIS_KEY, keyParam: KeyNameParam, isUnion = false, limit = 200) {
this.key = key; this.key = key;
this.keyName = new KeyName(key, keyParam); this.keyName = new KeyName(key, keyParam);
this.infoKey = REDIS_RANK_TO_INFO.get(key); this.infoKey = REDIS_RANK_TO_INFO.get(key);
this.extraKeys = REDIS_RANK_TO_EXTRA.get(key) || []; this.extraKeys = REDIS_RANK_TO_EXTRA.get(key) || [];
this.isUnion = isUnion; this.isUnion = isUnion;
this.limit = limit;
this.setValueConfig(key);
}
public setIsInit(init: boolean) {
this.isInit = init;
}
private setValueConfig(key: REDIS_KEY) {
switch (key) { switch (key) {
case REDIS_KEY.TOP_LINEUP_RANK: case REDIS_KEY.TOP_LINEUP_RANK:
case REDIS_KEY.TOP_HERO_RANK: case REDIS_KEY.TOP_HERO_RANK:
case REDIS_KEY.SUM_CE_RANK: case REDIS_KEY.SUM_CE_RANK:
case REDIS_KEY.HERO_RANK: case REDIS_KEY.HERO_RANK:
this.timelen = 0; break; this.valueConfig = [
new ValueConfig(true, 'score', 0, false, false)
];
break;
case REDIS_KEY.RACE_ACTIVITY: case REDIS_KEY.RACE_ACTIVITY:
this.timelen = 6; break; this.valueConfig = [
new ValueConfig(true, 'score', 0, false, false),
new ValueConfig(false, 'time', 6, true, true)
];
break;
case REDIS_KEY.GUILD_LV_RANK:
this.valueConfig = [
new ValueConfig(true, 'lv', 0, false, false),
new ValueConfig(false, 'active', 5, false, false),
new ValueConfig(false, 'time', 10, true, true)
];
break;
default: default:
this.timelen = 10; break; this.valueConfig = [
new ValueConfig(true, 'score', 0, false, false),
new ValueConfig(false, 'time', 10, true, true)
];
break;
} }
this.limit = limit; for(let i = 0; i < this.valueConfig.length; i++) {
} let weight = 0;
for(let j = i + 1; j < this.valueConfig.length; j++) {
public setIsInit(init: boolean) { weight = this.valueConfig[j].len;
this.isInit = init; }
this.valueConfig[i].setWeight(weight);
}
} }
/** /**
@@ -102,7 +131,7 @@ export class Rank {
await this.generParamAndSet(infoKey, { roleId }, { role }); await this.generParamAndSet(infoKey, { roleId }, { role });
} }
} }
let newScore = await this.setRank({ roleId }, score, timestamp, isInc); let newScore = await this.setRank({ roleId }, [score, timestamp], isInc);
return newScore; return newScore;
} }
@@ -116,13 +145,21 @@ export class Rank {
* @param isInc 得分是累加上的还是直接设置的 * @param isInc 得分是累加上的还是直接设置的
*/ */
public async setRankWithGuildInfo(guildCode: string, score: number, timestamp: number, guild?: GuildType, isInc = false) { public async setRankWithGuildInfo(guildCode: string, score: number, timestamp: number, guild?: GuildType, isInc = false) {
return await this.setRankWithGuildInfoArrParam(guildCode, [score, timestamp], guild, isInc);
}
public async setRankWithGuildInfo2(guildCode: string, lv: number, active: number, timestamp: number, guild?: GuildType, isInc = false) {
return await this.setRankWithGuildInfoArrParam(guildCode, [lv, active, timestamp], guild, isInc);
}
public async setRankWithGuildInfoArrParam(guildCode: string, scores: number[], guild?: GuildType, isInc = false) {
for (let infoKey of [this.infoKey, ...this.extraKeys]) { for (let infoKey of [this.infoKey, ...this.extraKeys]) {
const hasCurUser = await redisClient().hexistsAsync(infoKey, guildCode); const hasCurUser = await redisClient().hexistsAsync(infoKey, guildCode);
if (!hasCurUser) { if (!hasCurUser) {
await this.generParamAndSet(infoKey, { guildCode }, { guild }); await this.generParamAndSet(infoKey, { guildCode }, { guild });
} }
} }
let newScore = await this.setRank({ guildCode }, score, timestamp, isInc); let newScore = await this.setRank({ guildCode }, scores, isInc);
return newScore; return newScore;
} }
@@ -141,7 +178,7 @@ export class Rank {
for (let infoKey of [this.infoKey, ...this.extraKeys]) { for (let infoKey of [this.infoKey, ...this.extraKeys]) {
await this.generParamAndSet(infoKey, { roleId, hid }, { hero }); await this.generParamAndSet(infoKey, { roleId, hid }, { hero });
} }
let newScore = await this.setRank({ roleId, hid }, score, timestamp, isInc); let newScore = await this.setRank({ roleId, hid }, [score, timestamp], isInc);
return newScore; return newScore;
} }
@@ -151,7 +188,7 @@ export class Rank {
* @param {{ string }} key redis key * @param {{ string }} key redis key
* @param {{ roleId?: string; guildCode?: string; hid?: number }} param 玩家信息 * @param {{ roleId?: string; guildCode?: string; hid?: number }} param 玩家信息
*/ */
private composeFields(key: string, param: myIdInter) { private composeFields(key: REDIS_KEY, param: myIdInter) {
let type = KEY_TO_COMPOSE_FIELD.get(key); let type = KEY_TO_COMPOSE_FIELD.get(key);
if (type == COMPOSE_FIELD_TYPE.ROLE) { if (type == COMPOSE_FIELD_TYPE.ROLE) {
@@ -171,7 +208,7 @@ export class Rank {
* @param field * @param field
* @returns {{ roleId?: string; guildCode?: string; hid?: number }} * @returns {{ roleId?: string; guildCode?: string; hid?: number }}
*/ */
private decodeFields(key: string, field: string) { private decodeFields(key: REDIS_KEY, field: string) {
let type = KEY_TO_COMPOSE_FIELD.get(key); let type = KEY_TO_COMPOSE_FIELD.get(key);
let arr = field.split(':'); let arr = field.split(':');
@@ -277,7 +314,7 @@ export class Rank {
* @param myId * @param myId
* @param param * @param param
*/ */
private async setUserInfo(infoKey: string, myId: myIdInter, param: RankParam | GuildRankParam | LineupParam[]) { private async setUserInfo(infoKey: REDIS_KEY, myId: myIdInter, param: RankParam | GuildRankParam | LineupParam[]) {
let field = this.composeFields(infoKey, myId); let field = this.composeFields(infoKey, myId);
let value = JSON.stringify(param); let value = JSON.stringify(param);
return await redisClient().hsetAsync(infoKey, field, value); return await redisClient().hsetAsync(infoKey, field, value);
@@ -290,15 +327,15 @@ export class Rank {
* @param timestamp * @param timestamp
* @param isInc * @param isInc
*/ */
public async setRank(myId: myIdInter, score: number, timestamp: number, isInc = false) { public async setRank(myId: myIdInter, scores: number[], isInc = false) {
let oldTop = await this.getRankByRank(0, 0); let oldTop = await this.getRankByRank(0, 0);
let oldScore = oldTop.length > 0 ? oldTop[0].num : 0; let oldScore = oldTop.length > 0 && oldTop[0] ? oldTop[0].num : 0;
// 更新分数 // 更新分数
let newScore = score; let newScore = 0;
if (this.isUnion) { if (this.isUnion) {
newScore = await this.updateRankScoreAtom(myId, score, timestamp, isInc); newScore = await this.updateRankScoreAtom(myId, scores, isInc);
} else { } else {
newScore = await this.updateRankScoreEncode(myId, score, timestamp, isInc) newScore = await this.updateRankScoreEncode(myId, scores, isInc)
} }
this.checkMyRankAndPush(myId, oldScore, newScore); this.checkMyRankAndPush(myId, oldScore, newScore);
return newScore; return newScore;
@@ -310,15 +347,27 @@ export class Rank {
* @param score * @param score
* @param timestamp * @param timestamp
*/ */
private async updateRankScoreEncode(myId: myIdInter, score: number = 0, timestamp: number = 0, isInc = false) { private async updateRankScoreEncode(myId: myIdInter, scores: number[] = [], isInc = false) {
let newScore = score; let newScore = 0;
let key = this.keyName.getName(); let key = this.keyName.getName();
if (isInc) { let newScores: number[] = [];
let oldScore = await this.getMyScore(myId); for(let index = 0; index < this.valueConfig.length; index ++) {
newScore = oldScore + score; let config = this.valueConfig[index];
let score = scores[index];
if(config.isMain) {
if (isInc) {
let oldScore = await this.getMyScore(myId);
newScore = oldScore + score;
} else {
newScore = score;
}
newScores.push(newScore);
} else {
newScores.push(score);
}
} }
let scoreStr = this.encodeScore(newScore, timestamp); let scoreStr = this.encodeScore(newScores);
await redisClient().zaddAsync(key, scoreStr, this.composeFields(this.key, myId)); await redisClient().zaddAsync(key, scoreStr, this.composeFields(this.key, myId));
return newScore return newScore
} }
@@ -331,21 +380,30 @@ export class Rank {
* @param isInc * @param isInc
* @class Rank * @class Rank
*/ */
private async updateRankScoreAtom(myId: myIdInter, score: number = 0, timestamp: number = 0, isInc = false) { private async updateRankScoreAtom(myId: myIdInter, scores: number[], isInc = false) {
let key = this.keyName.getName();
let timeKey = this.keyName.getTimeName();
let pow = Math.pow(10, this.timelen + 1);
let newScore = 0; let newScore = 0;
// 分数zset for(let index = 0; index < this.valueConfig.length; index ++) {
if (isInc) { let config = this.valueConfig[index];
newScore = await redisClient().zincrbyAsync(key, score, this.composeFields(this.key, myId)); let score = scores[index];
} else { if(config.isMain) {
newScore = await redisClient().zaddAsync(key, score, this.composeFields(this.key, myId)); let key = this.keyName.getName();
// 分数zset
if (isInc) {
newScore = await redisClient().zincrbyAsync(key, score, this.composeFields(this.key, myId));
} else {
newScore = await redisClient().zaddAsync(key, score, this.composeFields(this.key, myId));
}
} else {
let key = this.keyName.getNameWithPlus(config.name);
if(config.isTimestamp) score = this.handleTimestamp(score, config.len);
if(config.reverse) {
let pow = Math.pow(10, config.len + 1);
score = pow - 1 - score;
}
await redisClient().zaddAsync(key, score, this.composeFields(this.key, myId));
}
} }
// 时间zset
await redisClient().zaddAsync(timeKey, pow - 1 - this.handleTimestamp(timestamp), this.composeFields(this.key, myId));
return parseInt(newScore.toString()); return parseInt(newScore.toString());
} }
@@ -414,6 +472,31 @@ export class Rank {
return await this.generFields(param); return await this.generFields(param);
} }
public async generMyRankWithGuild2(guildCode: string, score: number, time: number, active: number, guild?: GuildType) {
// 如果没有信息,更新玩家信息
let param: GuildRankInfo;
let hasCurUser = await redisClient().hexistsAsync(this.infoKey, guildCode);
if (!hasCurUser) {
if (!guild) {
guild = await GuildModel.findByCode(guildCode, this.keyName.serverId, GUILD_SELECT.RANK);
}
param = new GuildRankInfo(guild);
param.setInfo2(0, { guildCode }, score, time, active);
} else {
const info = await redisClient().hgetAsync(this.infoKey, guildCode);
const guildInfo = JSON.parse(info);
param = new GuildRankInfo(guildInfo);
param.setInfo2(0, { guildCode }, score, time, active);
}
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) { public async generMyRankWithHero(roleId: string, hid: number, score: number, time: number, hero?: HeroType, role?: RoleType) {
// 如果没有信息,更新玩家信息 // 如果没有信息,更新玩家信息
let param: RoleRankInfo; let param: RoleRankInfo;
@@ -583,7 +666,7 @@ export class Rank {
const field = rankFromDb[ii]; const field = rankFromDb[ii];
let myId = this.decodeFields(this.key, field); let myId = this.decodeFields(this.key, field);
const { score, time } = this.decodeScore(rankFromDb[ii + 1]); const scores = this.decodeScore(rankFromDb[ii + 1]);
const info = await redisClient().hgetAsync(this.infoKey, this.composeFields(this.infoKey, myId)); const info = await redisClient().hgetAsync(this.infoKey, this.composeFields(this.infoKey, myId));
const userInfo = JSON.parse(info); const userInfo = JSON.parse(info);
@@ -593,10 +676,15 @@ export class Rank {
continue; continue;
} }
param = new RoleRankInfo(userInfo, false); param = new RoleRankInfo(userInfo, false);
param.setInfo(Math.floor(ii / 2) + 1, myId, score, time); param.setInfo(Math.floor(ii / 2) + 1, myId, scores[0], scores[1]);
} else if (this.infoKey == REDIS_KEY.GUILD_INFO) { } else if (this.infoKey == REDIS_KEY.GUILD_INFO) {
param = new GuildRankInfo(userInfo); if(this.key == REDIS_KEY.GUILD_LV_RANK) {
param.setInfo(Math.floor(ii / 2) + 1, myId, score, time); param = new GuildRankInfo(userInfo);
param.setInfo2(Math.floor(ii / 2) + 1, myId, scores[0], scores[1], scores[2]);
} else {
param = new GuildRankInfo(userInfo);
param.setInfo(Math.floor(ii / 2) + 1, myId, scores[0], scores[1]);
}
} }
for (let extraKey of this.extraKeys) { for (let extraKey of this.extraKeys) {
@@ -624,7 +712,7 @@ export class Rank {
const field = rankFromDb[ii]; const field = rankFromDb[ii];
let myId = this.decodeFields(this.key, field); let myId = this.decodeFields(this.key, field);
const { score, time } = this.decodeScore(rankFromDb[ii + 1]); const scores = this.decodeScore(rankFromDb[ii + 1]);
const info = await redisClient().hgetAsync(this.infoKey, this.composeFields(this.infoKey, myId)); const info = await redisClient().hgetAsync(this.infoKey, this.composeFields(this.infoKey, myId));
const userInfo = JSON.parse(info); const userInfo = JSON.parse(info);
@@ -634,10 +722,15 @@ export class Rank {
continue; continue;
} }
param = new RoleRankInfo(userInfo, false); param = new RoleRankInfo(userInfo, false);
param.setInfo(Math.floor(ii / 2) + 1, myId, score, time); param.setInfo(Math.floor(ii / 2) + 1, myId, scores[0], scores[1]);
} else if (this.infoKey == REDIS_KEY.GUILD_INFO) { } else if (this.infoKey == REDIS_KEY.GUILD_INFO) {
param = new GuildRankInfo(userInfo); if(this.key == REDIS_KEY.GUILD_LV_RANK) {
param.setInfo(Math.floor(ii / 2) + 1, myId, score, time); param = new GuildRankInfo(userInfo);
param.setInfo2(Math.floor(ii / 2) + 1, myId, scores[0], scores[1], scores[2]);
} else {
param = new GuildRankInfo(userInfo);
param.setInfo(Math.floor(ii / 2) + 1, myId, scores[0], scores[1]);
}
} }
for (let extraKey of this.extraKeys) { for (let extraKey of this.extraKeys) {
@@ -680,7 +773,7 @@ export class Rank {
if (!score) score = 0; if (!score) score = 0;
if (!this.isUnion) { if (!this.isUnion) {
let result = this.decodeScore(score.toString()); let result = this.decodeScore(score.toString());
score = result.score; score = result[0];
} }
return parseInt(score.toString()); return parseInt(score.toString());
} }
@@ -697,37 +790,55 @@ export class Rank {
let unionKey = this.keyName.getUnionName(); // 联合的key let unionKey = this.keyName.getUnionName(); // 联合的key
let existsKey = await redisClient().existsAsync(unionKey); let existsKey = await redisClient().existsAsync(unionKey);
if (!existsKey) { if (!existsKey) {
let originKey = this.keyName.getName(); let keys = [], weights = [];
let timeKey = this.keyName.getTimeName(); this.valueConfig.forEach(({ isMain, name, weight }) => {
if(isMain) {
keys.push(this.keyName.getName());
} else {
keys.push(this.keyName.getNameWithPlus(name));
}
weights.push(Math.pow(10, weight))
let pow = Math.pow(10, this.timelen + 1); })
await redisClient().zunionstoreAsync(unionKey, 2, originKey, timeKey, 'WEIGHTS', pow, 1);
await redisClient().zunionstoreAsync(unionKey, 2, ...keys, 'WEIGHTS', ...weights);
await redisClient().expireAsync(unionKey, this.unionRankLife); // 10秒更新一次 await redisClient().expireAsync(unionKey, this.unionRankLife); // 10秒更新一次
} }
return unionKey; return unionKey;
} }
// 有序排行综合时间和得分排序 // 有序排行综合时间和得分排序
private encodeScore(score: number, timestamp: number) { private encodeScore(scores: number[]) {
let timelen = this.timelen; let encodeResult = 0;
let pow = Math.pow(10, timelen + 1); this.valueConfig.forEach(({ reverse, isTimestamp, len, weight }, index) => {
return score * pow + pow - 1 - this.handleTimestamp(timestamp) let score = scores[index];
if(isTimestamp) score = this.handleTimestamp(score, len);
if(!reverse) {
encodeResult += score * Math.pow(10, weight);
} else {
let pow = Math.pow(10, len + 1);
encodeResult += pow - 1 - score;
}
})
return encodeResult
} }
private decodeScore(num: string) { private decodeScore(num: string) {
let timelen = this.timelen;
let pow = Math.pow(10, timelen + 1);
let _num = parseInt(num); let _num = parseInt(num);
return { let scores: number[] = [];
time: pow - _num % pow, this.valueConfig.forEach(({ weight }) => {
score: Math.floor(_num / pow) let pow = Math.pow(10, weight);
}; let score = Math.floor(_num / pow);
_num -= pow * score;
scores.push(score);
})
return scores;
} }
private handleTimestamp(timestamp: number = 0) { private handleTimestamp(timestamp: number = 0, len: number) {
let l = timestamp.toString().length; let l = timestamp.toString().length;
if (l > this.timelen) { if (l > len) {
timestamp = Math.floor(timestamp / Math.pow(10, l - this.timelen)); timestamp = Math.floor(timestamp / Math.pow(10, l - len));
} }
return timestamp return timestamp
} }
@@ -741,22 +852,11 @@ export class Rank {
for (let { id, general } of gameData.rank) { for (let { id, general } of gameData.rank) {
let redisKey = RANK_TYPE_TO_KEY.get(id); let redisKey = RANK_TYPE_TO_KEY.get(id);
if (redisKey == this.key) { if (redisKey == this.key) {
if (general == 1) { let r = new Rank(redisKey, { serverId }, false, 1);
let r = new Rank(redisKey, { serverId }, false, 1); let ranks = <RoleRankInfo[]>await r.getRankByRange();
let ranks = <RoleRankInfo[]>await r.getRankByRange(); if (ranks.length > 0) {
if (ranks.length > 0) { let param = new GeneralRankParam(id, ranks[0] || new RoleRankInfo({}, false));
let param = new GeneralRankParamRole(id, ranks[0] || new RoleRankInfo({}, false)); pinus.app.rpc.chat.chatRemote.sendRankTopUpdated.toServer(sid, serverId, { ...param, general });
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; break;
@@ -798,7 +898,7 @@ export async function setRankRedisFromDb(type: string, args?: { serverId?: numbe
let r = new Rank(type, { serverId }); let r = new Rank(type, { serverId });
r.setIsInit(true); r.setIsInit(true);
for (let guild of ranks) { for (let guild of ranks) {
await r.setRankWithGuildInfo(guild.code, guild.lv, guild.lvUpdateTime, guild); await r.setRankWithGuildInfoArrParam(guild.code, [guild.lv, guild.activeWeekly, guild.activeUpdateTime], guild);
} }
} else if (type == REDIS_KEY.PVP_RANK) { } else if (type == REDIS_KEY.PVP_RANK) {
let { seasonNum } = await PVPConfigModel.findCurPVPConfig(); let { seasonNum } = await PVPConfigModel.findCurPVPConfig();
@@ -900,10 +1000,7 @@ export async function setRankRedisFromDb(type: string, args?: { serverId?: numbe
export async function getGeneralRank(role: RoleType & { rankReceived: number[] }, serverId: number) { export async function getGeneralRank(role: RoleType & { rankReceived: number[] }, serverId: number) {
let { rankReceived = [] } = role; let { rankReceived = [] } = role;
let res = { let result: GeneralRankParam[] = [];
role: new Array<GeneralRankParamRole>(),
battle: new Array<GeneralRankParamBattle>()
};
for (let { id, general } of gameData.rank) { for (let { id, general } of gameData.rank) {
let redisKey = RANK_TYPE_TO_KEY.get(id); let redisKey = RANK_TYPE_TO_KEY.get(id);
@@ -916,20 +1013,11 @@ export async function getGeneralRank(role: RoleType & { rankReceived: number[] }
let r = new Rank(redisKey, { serverId }, false, 1); let r = new Rank(redisKey, { serverId }, false, 1);
let ranks = <RoleRankInfo[]>await r.getRankByRange(); let ranks = <RoleRankInfo[]>await r.getRankByRange();
if (ranks.length > 0) { if (ranks.length > 0) {
let param = new GeneralRankParamRole(id, ranks[0] || new RoleRankInfo({}, false), received); let param = new GeneralRankParam(id, ranks[0] || new RoleRankInfo({}, false), received);
res.role.push(param); result.push(param);
}
} 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, received);
res.battle.push(param);
} }
} }
} }
} }
return res; return result;
} }
+109 -109
View File
@@ -30,128 +30,128 @@ describe('排行榜测试', function() {
}, 500); }, 500);
}); });
it('获取排行榜总览页面', function(done) { // it('获取排行榜总览页面', function(done) {
pinusClient.request('role.rankHandler.getGeneralRank', { } , (res) => { // pinusClient.request('role.rankHandler.getGeneralRank', { } , (res) => {
checkSuccessResponse(res); // checkSuccessResponse(res);
expect(res.data.role).to.be.an('array'); // expect(res.data.role).to.be.an('array');
res.data.role.forEach(data=> { // res.data.role.forEach(data=> {
expect(data.type).to.be.a('number'); // expect(data.type).to.be.a('number');
expect(data.roleId).to.be.a('string'); // expect(data.roleId).to.be.a('string');
expect(data.roleName).to.be.a('string'); // expect(data.roleName).to.be.a('string');
expect(data.head).to.be.a('number'); // expect(data.head).to.be.a('number');
expect(data.frame).to.be.a('number'); // expect(data.frame).to.be.a('number');
expect(data.spine).to.be.a('number'); // expect(data.spine).to.be.a('number');
expect(data.lv).to.be.a('number'); // expect(data.lv).to.be.a('number');
expect(data.guildName).to.be.a('string'); // expect(data.guildName).to.be.a('string');
expect(data.ce).to.be.a('number'); // expect(data.ce).to.be.a('number');
expect(data.num).to.be.a('number'); // expect(data.num).to.be.a('number');
expect(data.received).to.be.a('array'); // expect(data.received).to.be.a('array');
data.received.forEach(id=> { // data.received.forEach(id=> {
expect(id).to.be.a('number'); // expect(id).to.be.a('number');
}) // })
}) // })
expect(res.data.battle).to.be.an('array'); // expect(res.data.battle).to.be.an('array');
res.data.battle.forEach(data=> { // res.data.battle.forEach(data=> {
expect(data.type).to.be.a('number'); // expect(data.type).to.be.a('number');
expect(data.roleId).to.be.a('string'); // expect(data.roleId).to.be.a('string');
expect(data.roleName).to.be.a('string'); // expect(data.roleName).to.be.a('string');
expect(data.guildName).to.be.a('string'); // expect(data.guildName).to.be.a('string');
expect(data.hid).to.be.a('number'); // expect(data.hid).to.be.a('number');
expect(data.skinId).to.be.a('number'); // expect(data.skinId).to.be.a('number');
expect(data.num).to.be.a('number'); // expect(data.num).to.be.a('number');
expect(data.received).to.be.a('array'); // expect(data.received).to.be.a('array');
data.received.forEach(id=> { // data.received.forEach(id=> {
expect(id).to.be.a('number'); // expect(id).to.be.a('number');
}) // })
}) // })
}); // });
done(); // done();
}); // });
it('获取玩家最强阵容排行榜', function(done) { // it('获取玩家最强阵容排行榜', function(done) {
pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.TOP_LINTUP } , (res) => { // pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.TOP_LINTUP } , (res) => {
checkParamWithLineup(res); // checkParamWithLineup(res);
done(); // done();
}); // });
}); // });
it('获取玩家最强武将排行榜', function(done) { // it('获取玩家最强武将排行榜', function(done) {
pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.TOP_HERO } , (res) => { // pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.TOP_HERO } , (res) => {
checkParamWithLineup(res); // checkParamWithLineup(res);
done(); // done();
}); // });
}); // });
it('获取玩家武将数量排行榜', function(done) { // it('获取玩家武将数量排行榜', function(done) {
pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.HERO_NUM } , (res) => { // pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.HERO_NUM } , (res) => {
checkParam(res); // checkParam(res);
done(); // done();
}); // });
}); // });
it('获取玩家主公等级排行榜', function(done) { // it('获取玩家主公等级排行榜', function(done) {
pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.USER_LV } , (res) => { // pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.USER_LV } , (res) => {
checkParam(res); // checkParam(res);
done(); // done();
}); // });
}); // });
it('获取玩家总战力排行榜', function(done) { // it('获取玩家总战力排行榜', function(done) {
pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.SUM_CE } , (res) => { // pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.SUM_CE } , (res) => {
checkParam(res); // checkParam(res);
done(); // done();
}); // });
}); // });
it('获取镇念塔排行榜', function(done) { // it('获取镇念塔排行榜', function(done) {
pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.TOWER } , (res) => { // pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.TOWER } , (res) => {
checkParam(res); // checkParam(res);
done(); // done();
}); // });
}); // });
it('获取秘境排行榜', function(done) { // it('获取秘境排行榜', function(done) {
pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.DUNGEON } , (res) => { // pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.DUNGEON } , (res) => {
checkParamWithLineup(res); // checkParamWithLineup(res);
done(); // done();
}); // });
}); // });
it('获取主线排行榜', function(done) { // it('获取主线排行榜', function(done) {
pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.MAIN } , (res) => { // pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.MAIN } , (res) => {
checkParam(res); // checkParam(res);
done(); // done();
}); // });
}); // });
it('获取精英排行榜', function(done) { // it('获取精英排行榜', function(done) {
pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.MAIN_ELITE } , (res) => { // pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.MAIN_ELITE } , (res) => {
checkParam(res); // checkParam(res);
done(); // done();
}); // });
}); // });
it('获取军团排行榜', function(done) { // it('获取军团排行榜', function(done) {
pinusClient.request('role.rankHandler.getGuildRank', { type: RANK_TYPE.GUILD_LV } , (res) => { // pinusClient.request('role.rankHandler.getGuildRank', { type: RANK_TYPE.GUILD_LV } , (res) => {
checkGuildParam(res); // checkGuildParam(res);
done(); // done();
}); // });
}); // });
it('获取军团活跃排行榜', function(done) { // it('获取军团活跃排行榜', function(done) {
pinusClient.request('role.rankHandler.getGuildRank', { type: RANK_TYPE.GUILD_ACTIVE } , (res) => { // pinusClient.request('role.rankHandler.getGuildRank', { type: RANK_TYPE.GUILD_ACTIVE } , (res) => {
checkGuildParam(res); // checkGuildParam(res);
done(); // done();
}); // });
}); // });
it('获取武将排行榜', function(done) { // it('获取武将排行榜', function(done) {
pinusClient.request('role.rankHandler.getHeroRank', { type: RANK_TYPE.HERO, hid: 19 } , (res) => { // pinusClient.request('role.rankHandler.getHeroRank', { type: RANK_TYPE.HERO, hid: 19 } , (res) => {
checkParamWithLineupAndHero(res); // checkParamWithLineupAndHero(res);
done(); // done();
}); // });
}); // });
}); });
+2 -2
View File
@@ -14,7 +14,7 @@ export enum ROLE_SELECT {
COM_BATTLE = 'lv head frame spine topLineupCe', COM_BATTLE = 'lv head frame spine topLineupCe',
GET_HEADS = 'heads head frames frame spines spine', GET_HEADS = 'heads head frames frame spines spine',
// 排行榜基础数据 // 排行榜基础数据
RANK = 'roleId roleName lv vLv head frame spine title guildName ce isReducedCe topLineup towerLv towerUpTime topLineupCe heroNum updatedAt heroNumUpdatedAt dungeonWarId dungeonUpdatedAt dungeonHeroes mainWarId mainUpdatedAt mainEliteWarId mainEliteUpdatedAt showLineup', RANK = 'roleId roleName lv vLv head frame spine title guildName ce isReducedCe topLineup towerLv towerUpTime topLineupCe heroNum updatedAt heroNumUpdatedAt dungeonWarId dungeonUpdatedAt dungeonHeroes mainWarId mainUpdatedAt mainEliteWarId mainEliteUpdatedAt showLineup hasGuild',
}; };
export enum HERO_SELECT { export enum HERO_SELECT {
@@ -42,7 +42,7 @@ export enum GUILD_SELECT {
// 获得邀请列表 // 获得邀请列表
INVITED_MEMBER = '_id code isMemberMax +invitedMembers +inviteTime', INVITED_MEMBER = '_id code isMemberMax +invitedMembers +inviteTime',
// 排行榜字段 // 排行榜字段
RANK = 'code name icon lv memberCnt leader lvUpdateTime activeWeekly activeUpdateTime' RANK = 'code name icon lv memberCnt leader lvUpdateTime activeWeekly activeUpdateTime guildCe'
} }
export enum FRIEND_SHIP_SELECT { export enum FRIEND_SHIP_SELECT {
+31 -31
View File
@@ -199,37 +199,37 @@ export const DEFAULT_HERO_LV = 1;
export const FIX_SMS_CODE_TELS = ['18855953630', '13911134885', '15167549151', '15618654010', '15167549151', '18342915387', '15000250967']; export const FIX_SMS_CODE_TELS = ['18855953630', '13911134885', '15167549151', '15618654010', '15167549151', '18342915387', '15000250967'];
export const REDIS_KEY = { export enum REDIS_KEY {
USER_INFO: "userInfo", // 玩家缓存信息 USER_INFO ="userInfo", // 玩家缓存信息
TOWER_RANK: "towerRank", // 天梯排行榜 TOWER_RANK ="towerRank", // 天梯排行榜
COM_TEAM_SEARCH_PRE: 'comTeamSerQ', // 匹配中的玩家,按品质分 COM_TEAM_SEARCH_PRE ='comTeamSerQ', // 匹配中的玩家,按品质分
PVP_RANK: "pvpRank", // pvp排行榜 PVP_RANK ="pvpRank", // pvp排行榜
GUILD_INFO: "guildInfo", // 公会信息 GUILD_INFO ="guildInfo", // 公会信息
GUILD_ACTIVE_RANK: "guildActiveRank", // 公会周活跃排行榜 GUILD_ACTIVE_RANK ="guildActiveRank", // 公会周活跃排行榜
DB_GAME: 'dbGame', // 服务器列表 DB_GAME ='dbGame', // 服务器列表
ONLINE_USERS: 'onlineUsers', // 在线用户情况 ONLINE_USERS ='onlineUsers', // 在线用户情况
ONLINE_TIME: 'onlineTime', // 玩家在线时间 ONLINE_TIME ='onlineTime', // 玩家在线时间
CHANNEL_SERVERS: 'chat:channelServers', // 渠道对应的 chat 服务器 Id, CHANNEL_SERVERS ='chat:channelServers', // 渠道对应的 chat 服务器 Id,
USER_GATE_ACTIVITY: 'usrGateAct', // 蛮夷入侵玩家排行 USER_GATE_ACTIVITY ='usrGateAct', // 蛮夷入侵玩家排行
GATE_ACTIVITY: 'gateAct', // 蛮夷入侵军团排行 GATE_ACTIVITY ='gateAct', // 蛮夷入侵军团排行
USER_CITY_ACTIVITY: 'usrCityAct', // 诸侯混战玩家排行 USER_CITY_ACTIVITY ='usrCityAct', // 诸侯混战玩家排行
CITY_ACTIVITY: 'cityAct', // 诸侯混战军团排行 CITY_ACTIVITY ='cityAct', // 诸侯混战军团排行
RACE_ACTIVITY: 'raceAct', // 粮草先行军团排行 RACE_ACTIVITY ='raceAct', // 粮草先行军团排行
TOP_LINEUP_INFO: 'topLineInfo', // 最强阵容数据 TOP_LINEUP_INFO ='topLineInfo', // 最强阵容数据
TOP_LINEUP_RANK: 'topLineRank', // 最强阵容排行 TOP_LINEUP_RANK ='topLineRank', // 最强阵容排行
TOP_HERO_RANK: 'topHeroRank', // 最强武将排行 TOP_HERO_RANK ='topHeroRank', // 最强武将排行
HERO_INFO: 'heroInfo', // 最强武将信息 HERO_INFO ='heroInfo', // 最强武将信息
HERO_NUM_RANK: 'heroNum', // 武将数量排行 HERO_NUM_RANK ='heroNum', // 武将数量排行
USER_LV: 'usrLv', // 主公等级排行榜 USER_LV ='usrLv', // 主公等级排行榜
SUM_CE_RANK: 'sumCeRank', // 总战力排名 SUM_CE_RANK ='sumCeRank', // 总战力排名
DUNGEON_RANK: 'dungeonRank', // 秘境排名 DUNGEON_RANK ='dungeonRank', // 秘境排名
DUNGEON_LINEUP: 'dungeonLineup', // 秘境通关阵容 DUNGEON_LINEUP ='dungeonLineup', // 秘境通关阵容
MAIN_RANK: 'mainRank', // 主线通关排名 MAIN_RANK ='mainRank', // 主线通关排名
MAIN_ELITE_RANK: 'mainEliteRank', // 精英通关排名 MAIN_ELITE_RANK ='mainEliteRank', // 精英通关排名
GUILD_LV_RANK: "guildLvRank", // 公会等级排行榜 GUILD_LV_RANK ="guildLvRank", // 公会等级排行榜
HERO_RANK: "heroRank", // 武将排行榜 HERO_RANK ="heroRank", // 武将排行榜
SHOW_LINEUP: "showLineup", // 展示阵容 SHOW_LINEUP ="showLineup", // 展示阵容
SYS_SERVER: 'sysServer', // 全服connector服 SYS_SERVER ='sysServer', // 全服connector服
} }
// 各排行榜对应hash的key // 各排行榜对应hash的key
+74 -55
View File
@@ -6,6 +6,7 @@ import { GuildUpdateParam } from "../db/Guild";
import { HeroType, HeroUpdate } from "../db/Hero"; import { HeroType, HeroUpdate } from "../db/Hero";
import { getSeconds } from "../pubUtils/timeUtil"; import { getSeconds } from "../pubUtils/timeUtil";
import { prop } from "@typegoose/typegoose"; import { prop } from "@typegoose/typegoose";
import { pick } from "underscore";
// 排行榜返回玩家值 // 排行榜返回玩家值
export class RankParam { export class RankParam {
@@ -16,7 +17,7 @@ export class RankParam {
lv: number = 0; lv: number = 0;
@prop({ required: true }) @prop({ required: true })
vLv: number = 0; vLv?: number = 0;
@prop({ required: true }) @prop({ required: true })
guildName: string = ""; guildName: string = "";
@@ -37,7 +38,7 @@ export class RankParam {
ce: number = 0; ce: number = 0;
@prop({ required: true }) @prop({ required: true })
updatedAt: number = 0; updatedAt?: number = 0;
constructor(role: RoleUpdate|RankParam, fromDb: boolean) { constructor(role: RoleUpdate|RankParam, fromDb: boolean) {
if(role.roleName) this.roleName = role.roleName; if(role.roleName) this.roleName = role.roleName;
@@ -93,6 +94,8 @@ export class RoleRankInfo extends RankParam {
} }
} }
// 公会排行榜返回值 // 公会排行榜返回值
export class GuildRankParam { export class GuildRankParam {
icon: number; icon: number;
@@ -107,8 +110,8 @@ export class GuildRankParam {
head: number; head: number;
frame: number; frame: number;
spine: number; spine: number;
};
} guildCe: number;
constructor(guild: GuildUpdateParam) { constructor(guild: GuildUpdateParam) {
this.icon = guild.icon; this.icon = guild.icon;
@@ -117,6 +120,7 @@ export class GuildRankParam {
let leader = <RoleType>guild.leader; let leader = <RoleType>guild.leader;
let _leader = new GuildLeader(leader); let _leader = new GuildLeader(leader);
this.leader = _leader; this.leader = _leader;
this.guildCe = guild.guildCe;
this.memberCnt = guild.memberCnt; this.memberCnt = guild.memberCnt;
} }
} }
@@ -126,6 +130,7 @@ export class GuildRankInfo extends GuildRankParam {
code: string; code: string;
num: number; num: number;
time: number; time: number;
active?: number;
setInfo(rank: number, myId: myIdInter, num: number, time: number) { setInfo(rank: number, myId: myIdInter, num: number, time: number) {
this.rank = rank; this.rank = rank;
@@ -134,11 +139,53 @@ export class GuildRankInfo extends GuildRankParam {
this.time = time; this.time = time;
} }
setInfo2(rank: number, myId: myIdInter, num: number, active: number, time: number) {
this.rank = rank;
this.code = myId.guildCode;
this.num = num;
this.time = time;
this.active = active;
}
isMyInfo(myId: myIdInter) { isMyInfo(myId: myIdInter) {
return this.code == myId.guildCode; return this.code == myId.guildCode;
} }
} }
export class RoleAndGuildRankInfo {
rank: number;
num: number;
userInfo?: RankParam & { roleId: string };
lineup?: LineupParam[];
guildInfo?: GuildRankParam & { code: string };
constructor(rank: number, num: number) {
this.rank = rank;
this.num = num;
}
setUserInfo(role: RoleRankInfo) {
this.userInfo = pick(role, ['roleId', 'roleName', 'head', 'frame', 'spine', 'lv', 'title', 'guildName', 'ce']);
this.lineup = role.lineup;
}
setGuildInfo(guild: GuildRankInfo) {
this.guildInfo = pick(guild, ['code', 'icon', 'name', 'leader', 'guildCe', 'lv', 'memberCnt', 'active']);
}
isMyInfo(myId: myIdInter) {
if(this.userInfo && myId.roleId) {
if(this.userInfo.roleId == myId.roleId) return true;
}
if(this.guildInfo && myId.guildCode) {
if(this.guildInfo.code == myId.guildCode) return true;
}
return false;
}
}
export class GuildLeader { export class GuildLeader {
roleId: string; roleId: string;
roleName: string; roleName: string;
@@ -275,6 +322,26 @@ export class KeyName {
export type KeyNameParam = Partial<KeyName>; export type KeyNameParam = Partial<KeyName>;
export class ValueConfig {
isMain: boolean; // 最主要的排序,getRank的num字段,isInc的时候只有这个会用zinc
name: string
len: number; // 长度
weight?: number; // 按顺序排之后,其他参数的len加和
reverse: boolean = false; // 例如时间戳,需要倒转的那种
isTimestamp: boolean = false; // 是否是时间戳
constructor(isMain: boolean, name: string, len: number, reverse = false, isTimestamp = false) {
this.isMain = isMain;
this.name = name;
this.len = len;
this.reverse = reverse;
this.isTimestamp = isTimestamp;
}
setWeight(weight: number) {
this.weight = weight;
}
}
export interface myIdInter { export interface myIdInter {
roleId?: string; roleId?: string;
@@ -283,64 +350,16 @@ export interface myIdInter {
} }
// 排行榜总览左边的数据 // 排行榜总览左边的数据
export class GeneralRankParamRole { export class GeneralRankParam {
type: number; // 排行榜id type: number; // 排行榜id
roleId: string; userInfo: RankParam;
roleName: string;
head: number;
frame: number;
spine: number;
lv: number;
vLv: number;
guildName: string;
ce: number;
num: number; num: number;
received: number[]; received: number[];
constructor(type: number, rankInfo: RoleRankInfo, received?: number[]) { constructor(type: number, rankInfo: RoleRankInfo, received?: number[]) {
this.type = type; this.type = type;
this.roleId = rankInfo.roleId; this.userInfo = pick(rankInfo, ['roleId', 'roleName', 'head', 'frame', 'spine', 'guildName', 'ce', 'title', 'lv']);
this.roleName = rankInfo.roleName;
this.head = rankInfo.head;
this.frame = rankInfo.frame;
this.spine = rankInfo.spine;
this.lv = rankInfo.lv;
this.vLv = rankInfo.vLv;
this.guildName = rankInfo.guildName;
this.ce = rankInfo.ce;
this.num = rankInfo.num; this.num = rankInfo.num;
this.received = received; this.received = received;
} }
}
// 排行榜右边的数据
export class GeneralRankParamBattle {
type: number;
roleId: string;
roleName: string;
guildName: string;
hid: number = 0;
skinId: number = 0;
num: number;
received: number[];
head: number;
frame: number;
spine: number;
constructor(type: number, rankInfo: RoleRankInfo, hero: HeroUpdate, received?: number[]) {
this.type = type;
this.roleId = rankInfo.roleId;
this.roleName = rankInfo.roleName;
this.guildName = rankInfo.guildName;
this.num = rankInfo.num;
this.head = rankInfo.head;
this.frame = rankInfo.frame;
this.spine = rankInfo.spine;
if(hero) {
this.hid = hero.hid;
let curSkin = hero.skins.find(cur => cur.enable);
this.skinId = curSkin?curSkin.id: 0;
}
this.received = received;
}
} }
@@ -61,5 +61,12 @@
"group": 1, "group": 1,
"groupName": "玩家", "groupName": "玩家",
"general": 2 "general": 2
},
{
"id": 10,
"name": "军团",
"group": 1,
"groupName": "玩家",
"general": 2
} }
] ]