排行榜:一览&领取

This commit is contained in:
luying
2021-04-12 09:47:16 +08:00
parent 5dca7b304d
commit 22e6a82100
20 changed files with 496 additions and 139 deletions
@@ -118,7 +118,7 @@ export class PvpHandler {
}
let r = new Rank(REDIS_KEY.PVP_RANK, {});
let myRank = await r.getMyRank(roleId);//去redis中获取排名
let myRank = await r.getMyRank({roleId});//去redis中获取排名
let data:any = {warId, seasonNum, seasonEndTime, myRank, oppPlayers, heroes: heroes.map(cur => {
let {actorId, dataId, order} = cur;
@@ -286,7 +286,7 @@ export class PvpHandler {
// 加入排行榜
let r = new Rank(REDIS_KEY.PVP_RANK, {});
await r.setRankWithRoleInfo(roleId, pvpDefense.score, pvpDefense.updatedAt.getTime(), role);
let myRank = await r.getMyRank(roleId);
let myRank = await r.getMyRank({roleId});
return resResult(STATUS.SUCCESS, {
battleCode, isSuccess,
@@ -389,7 +389,7 @@ export class PvpHandler {
let roleId = session.get('roleId');
let r = new Rank(REDIS_KEY.PVP_RANK, {});
let {ranks, myRank} = await r.getRankListWithMyRank(roleId);
let {ranks, myRank} = await r.getRankListWithMyRank({roleId});
if(!myRank) {
let pvpDefense = await PvpDefenseModel.findByRoleId(roleId);
@@ -187,7 +187,7 @@ export class CityActivityHandler {
// 返回当前军团总军功
let r = new Rank(REDIS_KEY.CITY_ACTIVITY, { serverId, cityId }, true);
let guildScore = await r.getMyScore(guildCode);
let guildScore = await r.getMyScore({guildCode});
const dbCities = await GuildActivityCityModel.getAllCities(serverId);
let cityStatus = pubGetCityStatus(guildCode, cityId, dicCity, dbCities);
@@ -283,9 +283,9 @@ export class CityActivityHandler {
await addActive(roleId, serverId, GUILD_POINT_WAYS.ACTIVITY); //获得活跃值
// 返回当前军团总军功
let myR = new Rank(REDIS_KEY.USER_CITY_ACTIVITY, { serverId, guildCode });
let myScore = await myR.getMyScore(roleId);
let myScore = await myR.getMyScore({roleId});
let r = new Rank(REDIS_KEY.CITY_ACTIVITY, { serverId, cityId }, true);
let guildScore = await r.getMyScore(guildCode);
let guildScore = await r.getMyScore({guildCode});
let gateHp = obj.getGateHpAndInc(serverId, cityId, dicCity.hp);
return resResult(STATUS.SUCCESS, {
@@ -96,7 +96,7 @@ export class GateActivityHandler {
// 返回当前军团总军功
let r = new Rank(REDIS_KEY.GATE_ACTIVITY, { serverId }, true);
let guildScore = await r.getMyScore(guildCode);
let guildScore = await r.getMyScore({guildCode});
// 前一天中位数战力
let medianCe = await getMedianCe(serverId);
@@ -185,9 +185,9 @@ export class GateActivityHandler {
// 返回当前军团总军功
let myR = new Rank(REDIS_KEY.USER_GATE_ACTIVITY, { serverId, guildCode });
let myScore = await myR.getMyScore(roleId);
let myScore = await myR.getMyScore({roleId});
let r = new Rank(REDIS_KEY.GATE_ACTIVITY, { serverId }, true);
let guildScore = await r.getMyScore(guildCode);
let guildScore = await r.getMyScore({guildCode});
return resResult(STATUS.SUCCESS, {
code,
@@ -233,16 +233,16 @@ export class GateActivityHandler {
if(isSuccess) {
let score = gameData.gateActivityPoint.get(GET_POINT_WAYS.DEFENSE_SUCCESS);
// 更新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);
}
// 发放活跃
await addActive(roleId, serverId, GUILD_POINT_WAYS.ACTIVITY); //获得活跃值
// 返回当前军团总军功
let guildScore = await r.getMyScore(guildCode);
let myScore = await r.getMyScore(roleId);
let guildScore = await r.getMyScore({guildCode});
let myScore = await r.getMyScore({roleId});
let gateHp = obj.getGateHpAndInc(guildCode);
obj.delMemberRecord(code);
@@ -171,7 +171,7 @@ export class RaceActivityHandler {
await addActive(roleId, serverId, GUILD_POINT_WAYS.ACTIVITY); //获得活跃值
// 返回当前军团总军功
let r = new Rank(REDIS_KEY.RACE_ACTIVITY, { serverId });
let myGuildRank = await r.getMyRank(guildCode);
let myGuildRank = await r.getMyRank({guildCode});
return resResult(STATUS.SUCCESS, {
timestamp: Date.now(),
@@ -4,10 +4,13 @@ import { STATUS, REDIS_KEY, RANK_TYPE_TO_KEY, ROLE_SELECT, RANK_TYPE, HERO_SELEC
import { RoleModel } from "../../../db/Role";
import { UserGuildModel } from "../../../db/UserGuild";
import { GuildModel } from "../../../db/Guild";
import { HeroModel } from "../../../db/Hero";
import { UserModel } from "../../../db/User";
import { Rank } from "../../../services/rankService";
import { nowSeconds } from "../../../pubUtils/timeUtil";
import { GeneralRankParamRole, GeneralRankParamBattle, RoleRankInfo } from "../../../domain/rank";
import { gameData } from "../../../pubUtils/data";
import { addItems } from "../../../services/rewardService";
import { HeroModel, HeroUpdate } from "../../../db/Hero";
export default function (app: Application) {
return new RoleHandler(app);
@@ -22,22 +25,42 @@ export class RoleHandler {
let roleName = session.get('roleName');
let serverId = session.get('serverId');
return resResult(STATUS.SUCCESS, {
role: [
{ type: 1, roleId: "8l6HPZAbdS", roleName: "东方月初", head: 11219, frame: 11301, spine: 11419, lv: 40, vLv: 0, guildName: "军团A", ce: 464262, num: 464262, received: [], },
{ type: 2, roleId: "8l6HPZAbdS", roleName: "东方月初", head: 11219, frame: 11301, spine: 11419, lv: 40, vLv: 0, guildName: "军团A", ce: 464262, num: 64262, received: [], },
{ type: 3, roleId: "8l6HPZAbdS", roleName: "东方月初", head: 11219, frame: 11301, spine: 11419, lv: 40, vLv: 0, guildName: "军团A", ce: 464262, num: 100, received: [], },
{ type: 4, roleId: "8l6HPZAbdS", roleName: "东方月初", head: 11219, frame: 11301, spine: 11419, lv: 40, vLv: 0, guildName: "军团A", ce: 464262, num: 99, received: [], },
],
battle: [ // 右边列
{ type: 5, roleId: "8l6HPZAbdS", roleName: "东方月初", head: 11219, frame: 11301, spine: 11419, guildName: "军团A", hid: 19, skinId: 41020, num: 464262, received: [], },
{ type: 6, roleId: "8l6HPZAbdS", roleName: "东方月初", head: 11219, frame: 11301, spine: 11419, guildName: "军团A", hid: 19, skinId: 41020, num: 99, received: [], },
{ type: 7, roleId: "8l6HPZAbdS", roleName: "东方月初", head: 11219, frame: 11301, spine: 11419, guildName: "军团A", hid: 19, skinId: 41020, num: 5060, received: [], },
{ type: 8, roleId: "8l6HPZAbdS", roleName: "东方月初", head: 11219, frame: 11301, spine: 11419, guildName: "军团A", hid: 19, skinId: 41020, num: 323, received: [], },
{ type: 9, roleId: "8l6HPZAbdS", roleName: "东方月初", head: 11219, frame: 11301, spine: 11419, guildName: "军团A", hid: 19, skinId: 41020, num: 9224, received: [], },
]
});
let role = await RoleModel.findByRoleId(roleId, 'rankReceived');
if(!role) return resResult(STATUS.WRONG_PARMS);
let { rankReceived = []} = role;
let res = {
role: new Array<GeneralRankParamRole>(),
battle: new Array<GeneralRankParamBattle>()
};
for(let { id, general } of gameData.rank) {
let redisKey = RANK_TYPE_TO_KEY.get(id);
if(redisKey) {
let received = rankReceived.filter(rewardId => {
let dic = gameData.generalRankReward.get(rewardId);
return dic && dic.rankId == id;
});
if(general == 1) {
let r = new Rank(redisKey, { serverId }, false, 1);
let ranks = <RoleRankInfo[]> await r.getRankByRange();
let param = new GeneralRankParamRole(id, ranks[0]||new RoleRankInfo({}, false), received);
res.role.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 resResult(STATUS.SUCCESS, res);
}
async getRank(msg: { type: number }, session: BackendSession) {
@@ -47,17 +70,9 @@ export class RoleHandler {
let { type } = msg;
let redisKey = RANK_TYPE_TO_KEY.get(type);
if(!redisKey) return resResult(STATUS.WRONG_PARMS);
let r = new Rank(redisKey, { serverId });
let r: Rank;
switch(type) {
case RANK_TYPE.TOP_LINTUP:
case RANK_TYPE.TOP_HERO:
case RANK_TYPE.SUM_CE:
r = new Rank(redisKey, { serverId }, false, 0); break;
default:
r = new Rank(redisKey, { serverId }); break;
}
let { ranks, myRank } = await r.getRankListWithMyRank(roleId);
let { ranks, myRank } = await r.getRankListWithMyRank({roleId});
if(!myRank) {
let role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.RANK, true);
if(type == RANK_TYPE.TOP_LINTUP) {
@@ -120,7 +135,7 @@ export class RoleHandler {
let redisKey = RANK_TYPE_TO_KEY.get(type);
if(!redisKey) return resResult(STATUS.WRONG_PARMS);
let r = new Rank(redisKey, { serverId, hid }, false, 0);
let r = new Rank(redisKey, { serverId, hid });
let ranks = await r.getRankByRange();
return resResult(STATUS.SUCCESS, {
@@ -129,12 +144,37 @@ export class RoleHandler {
}
async receiveReward(msg: { type: number, id: number }, session: BackendSession) {
let { type } = msg;
let roleId = session.get('roleId');
let serverId = session.get('serverId');
let roleName = session.get('roleName');
let sid = session.get('sid');
let { type, id } = msg;
let dicReward = gameData.generalRankReward.get(id);
if(!dicReward || dicReward.rankId != type) return resResult(STATUS.WRONG_PARMS);
let redisKey = RANK_TYPE_TO_KEY.get(type);
let r = new Rank(redisKey, { serverId }, false, 1);
let ranks = await r.getRankByRange();
let num = ranks.length > 0? ranks[0].num: 0;
if(num < dicReward.condition) return resResult(STATUS.REWARD_CONDITION_NOT_REACH);
let role = await RoleModel.receiveRankReward(roleId, id);
if(!role) return resResult(STATUS.REWARD_HAS_RECEIVED);
let reward = dicReward.reward;
let goods = await addItems(roleId, roleName, sid, reward);
let received = role.rankReceived.filter(rewardId => {
let dic = gameData.generalRankReward.get(rewardId);
return dic && dic.rankId == id;
});
return resResult(STATUS.SUCCESS, {
type: type,
received: [],
goods: []
received,
goods
})
}
@@ -12,8 +12,10 @@ import { SclResultInter, SclPosInter } from '../../../pubUtils/interface';
import { SchoolModel } from '../../../db/School';
import { checkTeraphMaterialEnough } from '../../../services/roleService'
import { calPlayerCeAndSave, calAllHeroCe } from '../../../services/playerCeService';
import { HERO_SYSTEM_TYPE, LINEUP_NUM, ROLE_SELECT } from '../../../consts';
import { HERO_SYSTEM_TYPE, LINEUP_NUM, ROLE_SELECT, REDIS_KEY } from '../../../consts';
import { checkBattleHeroesByHid } from '../../../services/normalBattleService';
import { Rank } from '../../../services/rankService';
import { updateUserInfo } from '../../../services/redisService';
export default function(app: Application) {
return new RoleHandler(app);
@@ -410,6 +412,7 @@ export class RoleHandler {
async saveShowLineup(msg: { showLineup: number[] }, session: BackendSession) {
let { showLineup } = msg;
let roleId = session.get('roleId');
let serverId = session.get('serverId');
let checkHeroes = await checkBattleHeroesByHid(roleId, showLineup);
if(showLineup.length > 0 && !checkHeroes) return resResult(STATUS.BATTLE_HERO_NOT_FOUND);
@@ -419,6 +422,8 @@ export class RoleHandler {
}
let role = await RoleModel.updateRoleInfo(roleId, { showLineup });
let r = new Rank(REDIS_KEY.SHOW_LINEUP, {});
await r.generParamAndSet(REDIS_KEY.SHOW_LINEUP, { roleId }, { role });
return resResult(STATUS.SUCCESS, { showLineup: role.showLineup });
}
@@ -443,6 +448,7 @@ export class RoleHandler {
curHead.enable = true;
role = await RoleModel.updateRoleInfo(roleId, { heads });
await updateUserInfo(REDIS_KEY.USER_INFO, roleId, [{ field: 'head', value: id }]);
return resResult(STATUS.SUCCESS, { heads: role.heads, head: role.head });
}
@@ -467,6 +473,7 @@ export class RoleHandler {
curFrame.enable = true;
role = await RoleModel.updateRoleInfo(roleId, { frames });
await updateUserInfo(REDIS_KEY.USER_INFO, roleId, [{ field: 'frame', value: id }]);
return resResult(STATUS.SUCCESS, { frames: role.frames, frame: role.frame });
}
@@ -491,6 +498,7 @@ export class RoleHandler {
curSpine.enable = true;
role = await RoleModel.updateRoleInfo(roleId, { spines });
await updateUserInfo(REDIS_KEY.USER_INFO, roleId, [{ field: 'spine', value: id }]);
return resResult(STATUS.SUCCESS, { spines: role.spines, spine: role.spine });
}
@@ -507,6 +515,7 @@ export class RoleHandler {
let role = await RoleModel.updateRoleInfo(roleId, { roleName });
session.set('roleName', role.roleName);
session.push('roleName', () => {});
await updateUserInfo(REDIS_KEY.USER_INFO, roleId, [{ field: 'roleName', value: roleName }]);
return resResult(STATUS.SUCCESS, { roleName: role.roleName });
}
@@ -266,7 +266,7 @@ export class RaceActivityObject {
let events = this.events.get(guildCode)||[];
let needSendEnd = woodenHorse.calCurWoodenHorse(events);
if(woodenHorse.status == 1 || woodenHorse.status == 2) { // 更新距离 // TODO 写进const表
let r = new Rank(REDIS_KEY.RACE_ACTIVITY, { serverId }, true, 6, 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.setExpire(getNextHourPoint(5));
if (needSendEnd) { // 抵达后发送奖励,发送消息,结算
@@ -191,7 +191,7 @@ export async function getCityActivityRank(guildCode: string, serverId: number, c
}
export async function getRaceActivityRank(guildCode: string, serverId: number) {
let r = new Rank(REDIS_KEY.RACE_ACTIVITY, { serverId }, true, 6);
let r = new Rank(REDIS_KEY.RACE_ACTIVITY, { serverId }, true);
r.setGenerFieldsFun(generField);
let { myRank, ranks } = await r.getRankListWithMyRank({guildCode});
if(!myRank) {
@@ -215,7 +215,7 @@ function generField(params: GuildRankInfo) {
*/
export async function getWoodenHorseList(guildCode: string, serverId: number) {
let obj = getRaceActivityObj();
let r = new Rank(REDIS_KEY.RACE_ACTIVITY, {serverId}, true, 6, 5);
let r = new Rank(REDIS_KEY.RACE_ACTIVITY, {serverId}, true, 5);
let myRank = await r.getMyRank({guildCode});
let startRank = myRank - 2 > 0? myRank - 2: 1;
@@ -577,7 +577,7 @@ export async function calWoodenHorseAndSend(serverId: number) {
let _obj = await obj.getWoodenHorse(code, serverId);
return new SimpleGuildRankWithTimeParam(rank, code, name, _obj);
}
let r = new Rank(REDIS_KEY.RACE_ACTIVITY, { serverId }, true, 6);
let r = new Rank(REDIS_KEY.RACE_ACTIVITY, { serverId }, true);
r.setGenerFieldsFun(fun);
let ranks = <GuildRankInfo[]> await r.getRankByRange();
let map = new Map<number, WoodenHorse[]>();
+31 -39
View File
@@ -9,9 +9,9 @@ import { resResult, reduceCe } from '../pubUtils/util';
import { calPlayerCeAndSave as pubCalPlayerCeAndSave, reCalAllHeroCe } from '../pubUtils/playerCe';
import Hero, { HeroType, HeroUpdate } from '../db/Hero';
import { defaultHeroes } from './pvpService';
import { RoleUpdate } from '../db/Role';
import { Rank, updateUserInfo } from './rankService';
import { RoleUpdate, RoleType } from '../db/Role';
import { Rank, updateUserInfo } from './rankService';
import { REDIS_KEY } from '../consts';
//修改并下发战力
@@ -23,27 +23,10 @@ export async function calPlayerCeAndSave(type: number, sid: string, roleId: stri
let uids = [{ uid: roleId, sid }];
pinus.app.get('channelService').pushMessageByUids('onPlayerCeUpdate', resResult(STATUS.SUCCESS, { ce: reduceCe(role.ce) , heros: pushHeros, topLineupCe: reduceCe(topLineupCe) }), uids);
defaultHeroes(role);
if(guild) {
await updateUserInfo(REDIS_KEY.GUILD_INFO, guild.code, [{ field: 'guildCe', value: guild.guildCe }]);
}
// 最强阵容
let r = new Rank(REDIS_KEY.TOP_LINEUP_RANK, { serverId }, false, 0);
await r.setRankWithRoleInfo(roleId, reduceCe(topLineupCe), 0, role);
// 最强武将
for(let { hid, ce } of pushHeros) {
let r2 = new Rank(REDIS_KEY.TOP_HERO_RANK, { serverId }, false, 0);
await r2.setRankWithHeroInfo(roleId, hid, ce, 0, hero);
let r4 = new Rank(REDIS_KEY.HERO_RANK, { serverId, hid }, false, 0);
await r4.setRankWithHeroInfo(roleId, hid, ce, 0, hero);
}
// 总战力
let r3 = new Rank(REDIS_KEY.SUM_CE_RANK, { serverId }, false, 0);
await r3.setRankWithRoleInfo(roleId, reduceCe(role.ce), 0, role);
updateRank(roleId, serverId, topLineupCe, role, pushHeros);
return hero;
}
@@ -54,28 +37,37 @@ export async function calAllHeroCe(type:number, sid: string, roleId: string, upd
if(pushHeros.length > 0) {
let uids = [{ uid: roleId, sid }];
pinus.app.get('channelService').pushMessageByUids('onPlayerCeUpdate', resResult(STATUS.SUCCESS, { ce: reduceCe(ce), heros: pushHeros, topLineupCe: reduceCe(topLineupCe) }), uids);
if(guild) {
await updateUserInfo(REDIS_KEY.GUILD_INFO, guild.code, [{ field: 'guildCe', value: guild.guildCe }]);
}
// 最强阵容
let r = new Rank(REDIS_KEY.TOP_LINEUP_RANK, { serverId }, false, 0);
await r.setRankWithRoleInfo(roleId, reduceCe(topLineupCe), 0, role);
// 最强武将
for(let { hid, ce } of pushHeros) {
let r2 = new Rank(REDIS_KEY.TOP_HERO_RANK, { serverId }, false, 0);
await r2.setRankWithHeroInfo(roleId, hid, ce, 0);
let r4 = new Rank(REDIS_KEY.HERO_RANK, { serverId, hid }, false, 0);
await r4.setRankWithHeroInfo(roleId, hid, ce, 0);
}
// 总战力
let r3 = new Rank(REDIS_KEY.SUM_CE_RANK, { serverId }, false, 0);
await r3.setRankWithRoleInfo(roleId, reduceCe(role.ce), 0, role);
updateRank(roleId, serverId, topLineupCe, role, pushHeros);
}
return role;
}
// 更新排行榜数据
async function updateRank(roleId: string, serverId: number, topLineupCe: number, role: RoleType, pushHeros: {hid: number, ce: number}[]) {
// 最强阵容
let r = new Rank(REDIS_KEY.TOP_LINEUP_RANK, { serverId });
await r.setRankWithRoleInfo(roleId, reduceCe(topLineupCe), 0, role);
// 最强武将
for(let { hid, ce } of pushHeros) {
let r2 = new Rank(REDIS_KEY.TOP_HERO_RANK, { serverId });
await r2.setRankWithHeroInfo(roleId, hid, ce, 0);
let r4 = new Rank(REDIS_KEY.HERO_RANK, { serverId, hid });
await r4.setRankWithHeroInfo(roleId, hid, ce, 0);
}
// 总战力
let r3 = new Rank(REDIS_KEY.SUM_CE_RANK, { serverId });
await r3.setRankWithRoleInfo(roleId, reduceCe(role.ce), 0, role);
// 更新最强五人阵容信息
let r5 = new Rank(REDIS_KEY.TOP_LINEUP_INFO, { serverId });
await r5.generParamAndSet(REDIS_KEY.TOP_LINEUP_INFO, { roleId }, { role });
}
+33 -21
View File
@@ -1,9 +1,9 @@
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 { 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 } 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 { HeroModel, HeroType } from "../db/Hero";
import { SystemConfigModel } from "../db/SystemConfig";
import { PvpDefenseModel } from "../db/PvpDefense";
import { gameData } from "../pubUtils/data";
@@ -24,13 +24,24 @@ export class Rank {
timelen: number = 10; // 给时间位留的长度
unionRankLife: number = 10;
constructor(key: string, keyParam: KeyNameParam, isUnion = false, timelen = 10, limit = 200) {
constructor(key: string, keyParam: KeyNameParam, isUnion = false, 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;
switch (key) {
case REDIS_KEY.TOP_LINEUP_RANK:
case REDIS_KEY.TOP_HERO_RANK:
case REDIS_KEY.SUM_CE_RANK:
case REDIS_KEY.HERO_RANK:
this.timelen = 0; break;
case REDIS_KEY.RACE_ACTIVITY:
this.timelen = 6; break;
default:
this.timelen = 10; break;
}
this.limit = limit;
}
@@ -80,10 +91,7 @@ export class Rank {
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 });
}
await this.generParamAndSet(infoKey, { roleId, hid }, { hero });
}
let newScore = await this.setRank({ roleId, hid }, score, timestamp, isInc);
@@ -119,7 +127,8 @@ export class Rank {
}
}
private async generParamAndSet(infoKey: string, fields: myIdInter, db: { role?: RoleType, guild?: GuildType, hero?: HeroType }) {
// 保存info相关数据
public async generParamAndSet(infoKey: string, fields: myIdInter, db: { role?: RoleType, guild?: GuildType, hero?: HeroType }) {
let { roleId, guildCode, hid } = fields;
let { role, guild, hero } = db;
@@ -127,7 +136,7 @@ export class Rank {
if (!role) {
role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.RANK, true);
}
let param = new RankParam(role);
let param = new RankParam(role, true);
await this.setUserInfo(infoKey, { roleId }, param);
} else if (infoKey == REDIS_KEY.GUILD_INFO) {
if (!guild) {
@@ -200,7 +209,8 @@ export class Rank {
private async setUserInfo(infoKey: string, myId: myIdInter, param: RankParam | GuildRankParam | LineupParam[]) {
let field = this.composeFields(infoKey, myId);
await setUserInfo(infoKey, field, param);
let value = JSON.stringify(param);
return await redisClient().hsetAsync(infoKey, field, value);
}
public async setRank(myId: myIdInter, score: number, timestamp: number, isInc = false) {
@@ -274,7 +284,7 @@ export class Rank {
await redisClient().expireatAsync(timeKey, time);
}
public async generMyRankWithRole(roleId: string, score: number, time: number, role?: RoleType) {
public async generMyRankWithRole(roleId: string, score: number = 0, time: number = 0, role?: RoleType) {
// 如果没有信息,更新玩家信息
let param: RoleRankInfo;
@@ -283,13 +293,13 @@ export class Rank {
if (!role) {
role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.RANK, true);
}
param = new RoleRankInfo(role);
param = new RoleRankInfo(role, true);
param.setInfo(0, { roleId }, score, time);
} else {
const info = await redisClient().hgetAsync(this.infoKey, roleId);
const userInfo = JSON.parse(info);
param = new RoleRankInfo(userInfo);
param = new RoleRankInfo(userInfo, false);
param.setInfo(0, { roleId }, score, time);
}
@@ -334,13 +344,13 @@ export class Rank {
if(!role) {
role = await RoleModel.findByRoleId(roleId, ROLE_SELECT.RANK, true);
}
param = new RoleRankInfo(role);
param = new RoleRankInfo(role, true);
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 = new RoleRankInfo(userInfo, false);
param.setInfo(0, { roleId, hid }, score, time);
}
@@ -353,6 +363,7 @@ export class Rank {
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;
@@ -496,7 +507,7 @@ export class Rank {
let param: RoleRankInfo | GuildRankInfo;
if (this.infoKey == REDIS_KEY.USER_INFO) {
param = new RoleRankInfo(userInfo);
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);
@@ -518,6 +529,7 @@ export class Rank {
if (this.isUnion) {
key = await this.generateUnionRank();
}
console.log('**getMyRank',key, this.composeFields(this.key, myId), this.key, myId)
let myRank = await redisClient().zrevrankAsync(key, this.composeFields(this.key, myId));
if(!myRank && myRank != 0) {
return 0;
@@ -639,7 +651,7 @@ export async function setRankRedisFromDb(type: string, args?: {serverId?: number
} 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);
let r = new Rank(type, { serverId });
for(let role of ranks) {
// console.log(roleId);
await r.setRankWithRoleInfo(role.roleId, role.topLineupCe, role.updatedAt.getTime(), role);
@@ -647,7 +659,7 @@ export async function setRankRedisFromDb(type: string, args?: {serverId?: number
} 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);
let r = new Rank(type, { serverId });
for(let hero of ranks) {
await r.setRankWithHeroInfo(hero.roleId, hero.hid, hero.ce, hero.updatedAt.getTime(), hero);
}
@@ -668,7 +680,7 @@ export async function setRankRedisFromDb(type: string, args?: {serverId?: number
} 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);
let r = new Rank(type, { serverId });
for(let role of ranks) {
await r.setRankWithRoleInfo(role.roleId, role.ce, role.updatedAt.getTime(), role);
}
@@ -698,7 +710,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 }, false, 0);
let r = new Rank(type, { serverId, hid });
for(let hero of ranks) {
await r.setRankWithHeroInfo(hero.roleId, hid, hero.ce, hero.updatedAt.getTime(), hero);
}
+165
View File
@@ -30,6 +30,44 @@ describe('排行榜测试', function() {
}, 500);
});
it('获取排行榜总览页面', function(done) {
pinusClient.request('role.rankHandler.getGeneralRank', { } , (res) => {
checkSuccessResponse(res);
expect(res.data.role).to.be.an('array');
res.data.role.forEach(data=> {
expect(data.type).to.be.a('number');
expect(data.roleId).to.be.a('string');
expect(data.roleName).to.be.a('string');
expect(data.head).to.be.a('number');
expect(data.frame).to.be.a('number');
expect(data.spine).to.be.a('number');
expect(data.lv).to.be.a('number');
expect(data.guildName).to.be.a('string');
expect(data.ce).to.be.a('number');
expect(data.num).to.be.a('number');
expect(data.received).to.be.a('array');
data.received.forEach(id=> {
expect(id).to.be.a('number');
})
})
expect(res.data.battle).to.be.an('array');
res.data.battle.forEach(data=> {
expect(data.type).to.be.a('number');
expect(data.roleId).to.be.a('string');
expect(data.roleName).to.be.a('string');
expect(data.guildName).to.be.a('string');
expect(data.hid).to.be.a('number');
expect(data.skinId).to.be.a('number');
expect(data.num).to.be.a('number');
expect(data.received).to.be.a('array');
data.received.forEach(id=> {
expect(id).to.be.a('number');
})
})
});
done();
});
it('获取玩家最强阵容排行榜', function(done) {
pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.TOP_LINTUP } , (res) => {
checkParamWithLineup(res);
@@ -43,8 +81,110 @@ describe('排行榜测试', function() {
done();
});
});
it('获取玩家武将数量排行榜', function(done) {
pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.HERO_NUM } , (res) => {
checkParam(res);
done();
});
});
it('获取玩家主公等级排行榜', function(done) {
pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.USER_LV } , (res) => {
checkParam(res);
done();
});
});
it('获取玩家总战力排行榜', function(done) {
pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.SUM_CE } , (res) => {
checkParam(res);
done();
});
});
it('获取镇念塔排行榜', function(done) {
pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.TOWER } , (res) => {
checkParam(res);
done();
});
});
it('获取秘境排行榜', function(done) {
pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.DUNGEON } , (res) => {
checkParamWithLineup(res);
done();
});
});
it('获取主线排行榜', function(done) {
pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.MAIN } , (res) => {
checkParam(res);
done();
});
});
it('获取精英排行榜', function(done) {
pinusClient.request('role.rankHandler.getRank', { type: RANK_TYPE.MAIN_ELITE } , (res) => {
checkParam(res);
done();
});
});
it('获取军团排行榜', function(done) {
pinusClient.request('role.rankHandler.getGuildRank', { type: RANK_TYPE.GUILD_LV } , (res) => {
checkGuildParam(res);
done();
});
});
it('获取军团活跃排行榜', function(done) {
pinusClient.request('role.rankHandler.getGuildRank', { type: RANK_TYPE.GUILD_ACTIVE } , (res) => {
checkGuildParam(res);
done();
});
});
it('获取武将排行榜', function(done) {
pinusClient.request('role.rankHandler.getHeroRank', { type: RANK_TYPE.HERO, hid: 19 } , (res) => {
checkParamWithLineupAndHero(res);
done();
});
});
});
function checkParamWithLineupAndHero(res) {
checkSuccessResponse(res);
expect(res.data.type).to.be.a('number');
expect(res.data.ranks).to.be.a('array');
res.data.ranks.forEach(cur => {
checkRankParamWithLineupAndHero(cur);
})
}
function checkGuildParam(res) {
checkSuccessResponse(res);
expect(res.data.type).to.be.a('number');
expect(res.data.ranks).to.be.a('array');
expect(res.data.myRank).to.be.an('object');
checkGuildRankParam(res.data.myRank);
res.data.ranks.forEach(cur => {
checkGuildRankParam(cur);
})
}
function checkParam(res) {
checkSuccessResponse(res);
expect(res.data.type).to.be.a('number');
expect(res.data.ranks).to.be.a('array');
expect(res.data.myRank).to.be.an('object');
checkBasicParam(res.data.myRank);
res.data.ranks.forEach(cur => {
checkBasicParam(cur);
})
}
function checkParamWithLineup(res) {
checkSuccessResponse(res);
expect(res.data.type).to.be.a('number');
@@ -64,6 +204,17 @@ function checkRankParamWithLineup(data) {
})
}
function checkRankParamWithLineupAndHero(data) {
checkBasicParam(data);
expect(data.lineup).to.be.a('array');
data.lineup.forEach(cur => {
checkLineup(cur);
});
data.hero.forEach(cur => {
checkLineup(cur);
});
}
function checkBasicParam(data) {
expect(data.rank).to.be.a('number');
expect(data.num).to.be.a('number');
@@ -84,4 +235,18 @@ function checkLineup(hero) {
expect(hero.lv).to.be.a('number');
expect(hero.quality).to.be.a('number');
expect(hero.job).to.be.a('number');
}
function checkGuildRankParam(data) {
expect(data.rank).to.be.a('number');
expect(data.num).to.be.a('number');
expect(data.code).to.be.a('string');
expect(data.name).to.be.a('string');
expect(data.icon).to.be.a('number');
expect(data.lv).to.be.a('number');
expect(data.memberCnt).to.be.a('number');
expect(data.leader).to.be.a('object');
expect(data.leader.roleId).to.be.a('string');
expect(data.leader.roleName).to.be.a('string');
}
+1 -1
View File
@@ -42,7 +42,7 @@ export enum GUILD_SELECT {
// 获得邀请列表
INVITED_MEMBER = '_id code isMemberMax +invitedMembers +inviteTime',
// 排行榜字段
RANK = 'code name icon lv memberCnt leader leader activeWeekly activeUpdateTime'
RANK = 'code name icon lv memberCnt leader lvUpdateTime activeWeekly activeUpdateTime'
}
export enum FRIEND_SHIP_SELECT {
+6 -1
View File
@@ -349,6 +349,9 @@ export const KEY_TO_COMPOSE_FIELD = new Map([
[REDIS_KEY.MAIN_ELITE_RANK, COMPOSE_FIELD_TYPE.ROLE],
[REDIS_KEY.HERO_RANK, COMPOSE_FIELD_TYPE.ROLE_HERO],
[REDIS_KEY.SHOW_LINEUP, COMPOSE_FIELD_TYPE.ROLE],
[REDIS_KEY.SUM_CE_RANK, COMPOSE_FIELD_TYPE.ROLE],
[REDIS_KEY.PVP_RANK, COMPOSE_FIELD_TYPE.ROLE],
]);
@@ -456,7 +459,9 @@ export const FILENAME = {
DIC_CITY_ACTIVITY_REWARD: 'dic_zyz_cityActivityReward',
DIC_RACE_ACTIVITY: 'dic_zyz_raceActivity',
DIC_SHOP: 'dic_zyz_shop',
DIC_SHOP_LIST: 'dic_zyz_shopList'
DIC_SHOP_LIST: 'dic_zyz_shopList',
DIC_RANK: 'dic_zyz_rankingType',
DIC_RANK_REWARD: 'dic_zyz_rankingReward'
}
export const WAR_RELATE_TABLES = [
+3
View File
@@ -214,6 +214,9 @@ export const STATUS = {
// 通用 30000 - 30099
DIC_DATA_NOT_FOUND: { code: 30000, simStr: '数据表未找到' },
ROLE_MATERIAL_NOT_ENOUGH: { code: 30001, simStr: '材料数量不足' },
REWARD_CONDITION_NOT_REACH: { code: 30002, simStr: '未满足领取条件' },
REWARD_HAS_RECEIVED: { code: 30003, simStr: '奖励已领取' },
// 武将养成通用 30100 - 30199
// 武将合成,升级,升星,升品相关 30200 - 30299
+1 -1
View File
@@ -148,7 +148,7 @@ export default class Guild extends BaseModel {
.sort(sort)
.limit(100).skip((page - 1) * 100)
.select(GUILD_SELECT.RANK)
.populate('leader', {roleName: 1, title: 1, frame: 1, head: 1, spine: 1, lv: 1, _id: 0}, 'Role')
.populate('leader', {roleId: 1, roleName: 1, title: 1, frame: 1, head: 1, spine: 1, lv: 1, _id: 0}, 'Role')
.lean({ virtuals: true });
return guildList;
}
+9
View File
@@ -269,6 +269,8 @@ export default class Role extends BaseModel {
// 排行相关
@prop({ required: true, default: 0 })
lvUpdatedAt: number; // 升级时间
@prop({ required: true, default: 0 })
heroNum: number; // 武将数量
@prop({ required: true, default: 0 })
heroNumUpdatedAt: number; // 武将数量更新时间
@@ -284,6 +286,8 @@ export default class Role extends BaseModel {
mainEliteWarId: number; // 精英通关关卡
@prop({ required: true, default: 0 })
mainEliteUpdatedAt: number; // 精英通关时间
@prop({ required: true, default: [], type: Number })
rankReceived: number[]; // 已领取奖励
public static async findAllByUid(uid: number, getters = false, virtuals = true) {
@@ -626,6 +630,11 @@ export default class Role extends BaseModel {
.sort({ ce: -1 }).lean();
return roles[Math.floor(roles.length/2)]
}
public static async receiveRankReward(roleId: string, id: number) {
const role: RoleType = await RoleModel.findOneAndUpdate({ roleId, rankReceived: { $nin: [id] } }, { $push: { rankReceived: id } }, {new: true}).lean();
return role;
}
}
export const RoleModel = getModelForClass(Role);
+87 -25
View File
@@ -3,43 +3,44 @@ import { WoodenHorse } from "./battleField/guildActivity";
import { RoleUpdate, RoleType } from "../db/Role";
import { reduceCe } from "../pubUtils/util";
import { GuildUpdateParam } from "../db/Guild";
import { currentId } from "async_hooks";
import { HeroType } from "../db/Hero";
import { HeroType, HeroUpdate } from "../db/Hero";
// 排行榜返回玩家值
export class RankParam {
roleName: string;
lv: number;
vLv: number;
roleName: string = "";
lv: number = 0;
vLv: number = 0;
guildName: string = "";
head: number = EXTERIOR.EXTERIOR_FACE;
frame: number = EXTERIOR.EXTERIOR_FACECASE;
spine: number = EXTERIOR.EXTERIOR_APPEARANCE;
title: number;
ce: number;
title: number = 1;
ce: number = 0;
constructor(role: RoleUpdate) {
this.roleName = role.roleName;
this.lv = role.lv;
this.vLv = role.vLv;
this.head = role.head;
this.frame = role.frame;
this.spine = role.spine;
this.title = role.title;
this.guildName = role.guildName||"";
if(role.isReducedCe) {
this.ce = role.ce;
} else {
this.ce = reduceCe(role.ce);
constructor(role: RoleUpdate, fromDb: boolean) {
if(role.roleName) this.roleName = role.roleName;
if(role.lv) this.lv = role.lv;
if(role.vLv) this.vLv = role.vLv;
if(role.head) this.head = role.head;
if(role.frame) this.frame = role.frame;
if(role.spine) this.spine = role.spine;
if(role.title) this.title = role.title;
if(role.guildName) this.guildName = role.guildName||"";
if(role.ce) {
if(fromDb && !role.isReducedCe) {
this.ce = reduceCe(role.ce);
} else {
this.ce = role.ce;
}
}
}
}
export class RoleRankInfo extends RankParam {
rank: number;
roleId: string;
num: number;
time: number;
rank: number = 1;
roleId: string = "";
num: number = 0;
time: number = 0;
hero: LineupParam[];
lineup: LineupParam[];
@@ -70,6 +71,7 @@ export class GuildRankParam {
lv: number;
memberCnt: number;
leader: {
roleId: string;
roleName: string;
title: number;
lv: number;
@@ -84,6 +86,7 @@ export class GuildRankParam {
this.name = guild.name;
this.lv = guild.lv;
let leader = <RoleType>guild.leader;
console.log('**', JSON.stringify(leader))
let _leader = new GuildLeader(leader);
this.leader = _leader;
this.memberCnt = guild.memberCnt;
@@ -109,6 +112,7 @@ export class GuildRankInfo extends GuildRankParam {
}
export class GuildLeader {
roleId: string;
roleName: string;
title: number;
lv: number;
@@ -116,7 +120,8 @@ export class GuildLeader {
frame: number;
spine: number;
constructor(leader: {roleName: string, title: number, lv: number, head: number, frame: number, spine: number}) {
constructor(leader: { roleId: string, roleName: string, title: number, lv: number, head: number, frame: number, spine: number}) {
this.roleId = leader.roleId;
this.roleName = leader.roleName;
this.title = leader.title;
this.lv = leader.lv;
@@ -236,4 +241,61 @@ export interface myIdInter {
roleId?: string;
guildCode?: string;
hid?: number;
}
// 排行榜总览左边的数据
export class GeneralRankParamRole {
type: number; // 排行榜id
roleId: string;
roleName: string;
head: number;
frame: number;
spine: number;
lv: number;
vLv: number;
guildName: string;
ce: number;
num: number;
received: number[];
constructor(type: number, rankInfo: RoleRankInfo, received: number[]) {
this.type = type;
this.roleId = rankInfo.roleId;
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.received = received;
}
}
// 排行榜右边的数据
export class GeneralRankParamBattle {
type: number;
roleId: string;
roleName: string;
guildName: string;
hid: number = 0;
skinId: number = 0;
num: number;
received: 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;
if(hero) {
this.hid = hero.hid;
let curSkin = hero.skins.find(cur => cur.enable);
this.skinId = curSkin?curSkin.id: 0;
}
this.received = received;
}
}
+5 -1
View File
@@ -71,6 +71,8 @@ import { decodeIdCntArrayStr, parseGoodStr, decodeArrayListStr, getRandValueByMi
import { RACE_EVENT_TYPE } from "../consts";
import { dicShop, dicShopItem } from "./dictionary/DicShop";
import { dicShopList } from "./dictionary/DicShopList";
import { dicRank } from "./dictionary/DicRank";
import { dicRankReward } from "./dictionary/DicRankReward";
export const gameData = {
blurprtCompose: dicBlueprtCompose,
@@ -167,7 +169,9 @@ export const gameData = {
shop: dicShop,
shopItem: dicShopItem,
shopList: dicShopList,
dicMyHeroes: dicMyHeroes
dicMyHeroes: dicMyHeroes,
rank: dicRank,
generalRankReward: dicRankReward
};
// 在此提供一些原先在gamedata中提供的方法,以便更方便获取gameData数据
+26
View File
@@ -0,0 +1,26 @@
// 排行榜表
import { readJsonFile } from '../util'
import { FILENAME } from '../../consts'
export interface DicRank {
// 排行榜id
readonly id: number;
// 属于哪个页签
readonly group: number;
// 总览中的位置
readonly general: number;
}
const str = readJsonFile(FILENAME.DIC_RANK);
let arr = JSON.parse(str);
export const dicRank = new Array<DicRank>();
arr.forEach(o => {
dicRank.push(o);
});
arr = undefined;
@@ -0,0 +1,30 @@
// 排行榜奖励表
import { readJsonFile, parseGoodStr } from '../util'
import { FILENAME } from '../../consts'
import { RewardInter } from '../interface';
export interface DicRankReward {
// 奖励id
readonly id: number;
// 排行榜id
readonly rankId: number;
// 条件
readonly condition: number;
// 奖励
readonly reward: Array<RewardInter>;
}
const str = readJsonFile(FILENAME.DIC_RANK_REWARD);
let arr = JSON.parse(str);
export const dicRankReward = new Map<number, DicRankReward>();
arr.forEach(o => {
o.reward = parseGoodStr(o.reward);
dicRankReward.set(o.id, o);
});
arr = undefined;