军团:添加活跃排行榜

This commit is contained in:
luying
2021-01-26 13:26:33 +08:00
parent 3c3e734019
commit 08ef299fec
14 changed files with 293 additions and 59 deletions
+32 -11
View File
@@ -1,7 +1,7 @@
import { gameData, getGuildActiveWeekReward } from "../pubUtils/data";
import { gameData, getGuildActiveWeekReward, getGuildActiveByIdAndType } from "../pubUtils/data";
import { GuildModel, GuildType } from "../db/Guild";
import { resResult, shouldRefreshWeek, shouldRefresh } from "../pubUtils/util";
import { STATUS, GUILD_OPERATE, MAIL_TYPE, GUILD_AUTH, GUILD_JOB } from "../consts";
import { STATUS, GUILD_OPERATE, MAIL_TYPE, GUILD_AUTH, GUILD_JOB, REDIS_KEY, } from "../consts";
import { RoleModel, RoleType } from "../db/Role";
import { UserGuildModel, UserGuildType } from "../db/UserGuild";
import { UserGuildApplyModel } from "../db/UserGuildApply";
@@ -11,6 +11,8 @@ import { pinus } from "pinus";
import { GuildRecType } from "../db/GuildRec";
import { ARMY } from "../pubUtils/dicParam";
import { sendMail } from "./mailService";
import { setRank } from "./redisService";
import { GuildRankParam, GuildLeader } from "../pubUtils/interface";
/**
* @description 检查该玩家是否有权限做操作
@@ -90,16 +92,26 @@ export async function getGuildWithRefActive(guildCode: string, serverId: number)
* 增加活跃
* @param guildCode 军团唯一code
* @param serverId 区
* @param active 增加活跃
* @param id 增加活跃的操作
* @param type 类型 activePoint内配的type
* @param active debug直接增加的活跃
*/
export async function addActive(roleId: string, serverId: number, id: number, active: number) {
export async function addActive(roleId: string, serverId: number, id: number, type: number, active?: number) {
let dicActiveWay = gameData.guildActiveWays.get(id);
if(id && !dicActiveWay) {
return { status: 0, resResult: resResult(STATUS.DIC_DATA_NOT_FOUND) };
}
if(!active) {
active = getGuildActiveByIdAndType(id, type);
}
let userGuild = await getUserGuildWithRefActive(roleId, 'activeRecord receivedActive activeDaily activeWeekly guildCode');
if(!userGuild) return false;
if(!userGuild) return { status: 0, resResult: resResult(STATUS.GUILD_NOT_FOUND) };
let guildCode = userGuild.guildCode;
let guild = await getGuildWithRefActive(guildCode, serverId);
if(!guild) return false;
if(!guild) return { status: 0, resResult: resResult(STATUS.GUILD_NOT_FOUND) };
let {activeRecord} = userGuild;
if(id != 0) { // 用于debug,传0时直接增加活跃
@@ -107,13 +119,22 @@ export async function addActive(roleId: string, serverId: number, id: number, ac
if( curActiveRecord ) {
curActiveRecord.count ++;
} else {
activeRecord.push({id, count: 1});
curActiveRecord = {id, count: 1};
activeRecord.push(curActiveRecord);
}
if(curActiveRecord.count > dicActiveWay.count) { // 次数超过时,不增加活跃
active = 0;
}
}
userGuild = await UserGuildModel.updateInfo(roleId, { activeRecord }, { activeDaily: active, activeWeekly: active });
userGuild = await UserGuildModel.updateInfo(roleId, { activeRecord, activeUpdateTime: nowSeconds() }, { activeDaily: active, activeWeekly: active });
guild = await GuildModel.updateInfo(guildCode, { }, { activeDaily: active, activeWeekly: active });
return { guild, userGuild };
guild = await GuildModel.updateInfo(guildCode, { activeUpdateTime: nowSeconds() }, { activeDaily: active, activeWeekly: active });
// 排行榜更新
let leader = await RoleModel.findById(guild.leader);
let guildRankParam = new GuildRankParam(guild.icon, guild.name, guild.lv, new GuildLeader(leader));
await setRank(REDIS_KEY.GUILD_ACTIVE_RANK, serverId, guild.code, guild.activeWeekly, guild.activeUpdateTime * 1000, guildRankParam);
return { status: 1, guild, userGuild };
}
/**
@@ -176,7 +197,7 @@ export async function settleGuildWeekly() {
if(otherMemberCnt < rankCnt) break;
}
}
await UserGuildModel.updateInfo(roleId, { job, activeWeekly: 0 });
await UserGuildModel.updateInfo(roleId, { job, activeWeekly: 0 }, {});
jobNum += gameData.guildPosition.get(job).activeRatio;
members.set(roleId, {job, active});
@@ -21,8 +21,9 @@ export async function getUserGuild(roleId: string, serverId: number) {
if (trainTime < getHourPoint(REFRESH_HOUR)) {
trainCount = ARMY.ARMY_TRAIN_BUYTIMES;
buyTrainCount = 0;
userGuild = await UserGuildModel.updateInfo(roleId, {trainCount, trainTime: nowSeconds(), buyTrainCount});
userGuild = await UserGuildModel.updateInfo(roleId, {trainCount, trainTime: nowSeconds(), buyTrainCount}, {});
}
return userGuild;
}
@@ -34,7 +35,7 @@ export async function recordUserGuild(roleId: string, code: string) {
if (trainTime < getHourPoint(REFRESH_HOUR)) {
trainCount = 0;
}
userGuild = await UserGuildModel.updateInfo(roleId, {trainCount, trainTime: nowSeconds()});
userGuild = await UserGuildModel.updateInfo(roleId, {trainCount, trainTime: nowSeconds()}, {});
return userGuild;
}
@@ -6,6 +6,7 @@ import { redisUserInfoUpdate } from './redisService';
import { switchOnFunc } from './funcSwitchService';
import { FUNC_OPT_TYPE } from '../consts';
import { BackendSession } from 'pinus';
import { REDIS_KEY } from '../consts/consts';
export async function roleLevelup(roleId: string, kingExp: number, session: BackendSession) {
let role = await RoleModel.findByRoleId(roleId);
@@ -23,7 +24,7 @@ export async function roleLevelup(roleId: string, kingExp: number, session: Back
role = await RoleModel.levelup(roleId, newLv, newExp);
if(newLv > lv) { // 升级
await switchOnFunc(roleId, FUNC_OPT_TYPE.LEVEL_UP, newLv, session);
await redisUserInfoUpdate(roleId, [{field: 'lv', value: newLv}])
await redisUserInfoUpdate(REDIS_KEY.USER_INFO, roleId, [{field: 'lv', value: newLv}])
}
let actordata = [];
for(let i = lv; i <= newLv; i++) {
+100 -23
View File
@@ -1,4 +1,4 @@
import { GOOD_QUALITY } from './../consts';
import { GOOD_QUALITY, REDIS_RANK_TO_INFO } from './../consts';
import { RoleModel, RoleType } from "../db/Role";
import * as Redis from 'redis';
import {REDIS_KEY} from '../consts'
@@ -7,9 +7,9 @@ import { promisifyAll } from 'bluebird';
import { pinus } from 'pinus';
import { PvpDefenseModel } from '../db/PvpDefense';
import { SystemConfigModel } from '../db/SystemConfig';
import { RankParam } from '../pubUtils/interface';
import { accessSync } from 'fs';
import { values } from 'underscore';
import { RankParam, GuildRankParam, GuildLeader } from '../pubUtils/interface';
import { GuildModel } from '../db/Guild';
/**
* 在服务重新启动时,将信息存入redis
*/
@@ -17,28 +17,87 @@ export async function initAllRank() {
const client: Redis.RedisClient = pinus.app.get('redis');
const serverList = await GameModel.getAllServerList();
await client.delAsync(REDIS_KEY.USER_INFO);
await client.delAsync(REDIS_KEY.GUILD_INFO);
await client.delAsync(REDIS_KEY.PVP_RANK);
for(let {id} of serverList) {
await client.delAsync(getKeyName(REDIS_KEY.TOWER_RANK, id));
await client.delAsync(getKeyName(REDIS_KEY.GUILD_ACTIVE_RANK, id));
await initRank(id);
}
}
/**
* 分服内初始redis排行榜
*
* @param serverId 服务器
*/
export async function initRank(serverId: number) {
// console.log('*****', 'initRank')
const client: Redis.RedisClient = pinus.app.get('redis');
await client.expireAsync(getKeyName(REDIS_KEY.TOWER_RANK, serverId), 30 * 24 * 60 * 60);
await client.expireAsync(REDIS_KEY.PVP_RANK, 30 * 24 * 60 * 60);
await client.expireAsync(REDIS_KEY.USER_INFO, 30 * 24 * 60 * 60);
await client.expireAsync(REDIS_KEY.GUILD_INFO, 30 * 24 * 60 * 60);
await client.expireAsync(getKeyName(REDIS_KEY.GUILD_ACTIVE_RANK, serverId), 30 * 24 * 60 * 60);
await setRankRedisFromDb(REDIS_KEY.TOWER_RANK, serverId);
await setRankRedisFromDb(REDIS_KEY.GUILD_ACTIVE_RANK, serverId);
let ranks = await RoleModel.getRank('tower', serverId, ['roleId', 'roleName', 'towerLv', 'lv', 'vLv', 'headHid', 'sHid', 'title', 'updatedAt']);
for(let {towerLv, roleId, roleName, lv, vLv, towerUpTime, headHid, sHid, title} of ranks) {
// console.log(roleId);
await client.zaddAsync(getKeyName(REDIS_KEY.TOWER_RANK, serverId), encodeScoreWithTime(towerLv, towerUpTime?towerUpTime.getTime():0), roleId);
let rankPram = new RankParam(roleName, lv, vLv, headHid, sHid, title);
await redisUserInfoAdd(roleId, rankPram);
}
/**
* 初始化某一个排行榜,如定时器内
* @param key redis内的key
*/
export async function initSingleRank(key: string) {
const serverList = await GameModel.getAllServerList();
for(let {id} of serverList) {
await initSingleRankWithServer(key, id);
}
}
/**
* 初始化某一服内的某一种排行榜
* @param key redis key
*/
export async function initSingleRankWithServer(key: string, serverId: number) {
const client: Redis.RedisClient = pinus.app.get('redis');
await client.delAsync(getKeyName(key, serverId));
await client.expireAsync(key, 30 * 24 * 60 * 60);
await setRankRedisFromDb(key, serverId);
}
/**
* 从数据库内获取排行榜存入redis
* @param type 排行榜类型
* @param serverId 分服
*/
async function setRankRedisFromDb(type: string, serverId: number) {
const client: Redis.RedisClient = pinus.app.get('redis');
if(type == REDIS_KEY.TOWER_RANK) {
let ranks = await RoleModel.getRank('tower', serverId, ['roleId', 'roleName', 'towerLv', 'lv', 'vLv', 'headHid', 'sHid', 'title', 'updatedAt']);
for(let {towerLv, roleId, roleName, lv, vLv, towerUpTime, headHid, sHid, title} of ranks) {
// console.log(roleId);
await client.zaddAsync(getKeyName(REDIS_KEY.TOWER_RANK, serverId), encodeScoreWithTime(towerLv, towerUpTime?towerUpTime.getTime():0), roleId);
let rankPram = new RankParam(roleName, lv, vLv, headHid, sHid, title);
await redisUserInfoAdd(REDIS_KEY.USER_INFO, roleId, rankPram);
}
} else if (type == REDIS_KEY.GUILD_ACTIVE_RANK) {
let ranks = await GuildModel.getRank(serverId);
for(let { code, icon, name, lv, leader, activeWeekly = 0, activeUpdateTime = 0 } of ranks) {
let _leader = <RoleType>leader;
let { roleName, title, sHid, headHid, lv: leaderLv } = _leader;
console.log(activeWeekly, activeUpdateTime * 1000)
await client.zaddAsync(getKeyName(REDIS_KEY.GUILD_ACTIVE_RANK, serverId), encodeScoreWithTime(activeWeekly, activeUpdateTime * 1000 ), code);
let rankParam = new GuildRankParam(icon, name, lv, { roleName, title, sHid, headHid, lv: leaderLv });
await redisUserInfoAdd(REDIS_KEY.GUILD_INFO, code, rankParam);
}
}
}
// 排行榜是否存在
export async function existsRank(key: string, serverId: number) {
const client: Redis.RedisClient = pinus.app.get('redis');
@@ -55,38 +114,40 @@ export function getKeyName(key: string, serverId?: number) {
}
// 更新玩家信息
export async function redisUserInfoUpdate(roleId: string, arr: Array<{field: string, value:(string|number)}>) {
export async function redisUserInfoUpdate(key: string, roleId: string, arr: Array<{field: string, value:(string|number|GuildLeader)}>) {
const client: Redis.RedisClient = pinus.app.get('redis');
let params = await client.hgetAsync(REDIS_KEY.USER_INFO, roleId);
let params = await client.hgetAsync(key, roleId);
if(params) {
let obj = JSON.parse(params);
for(let {field, value} of arr) {
obj[field] = value;
}
return await client.hsetAsync(REDIS_KEY.USER_INFO, roleId, JSON.stringify(obj));
return await client.hsetAsync(key, roleId, JSON.stringify(obj));
}
}
// 添加玩家信息缓存
export async function redisUserInfoAdd(roleId: string, params: RankParam) {
export async function redisUserInfoAdd(key: string, roleId: string, params: RankParam|GuildRankParam) {
const client: Redis.RedisClient = pinus.app.get('redis');
let value = JSON.stringify(params);
return await client.hsetAsync(REDIS_KEY.USER_INFO, roleId, value);
return await client.hsetAsync(key, roleId, value);
}
// 更新排行榜, 如pvp这样跨服的,serverId传0
export async function setRank(key: string, serverId: number, roleId: string, score: number, timestamp: number, params: RankParam, limit = 100) {
export async function setRank(key: string, serverId: number, myId: string, score: number, timestamp: number, params: RankParam|GuildRankParam, limit = 100) {
const client: Redis.RedisClient = pinus.app.get('redis');
// 更新分数
const _score = encodeScoreWithTime(score, timestamp);
await client.zaddAsync(getKeyName(key, serverId), _score, roleId);
await client.zaddAsync(getKeyName(key, serverId), _score, myId);
// 移除100名以外
await client.zremrangebyrankAsync(getKeyName(key, serverId), limit, 10000);
let infoKey = REDIS_RANK_TO_INFO.get(key);
// 如果没有信息,更新玩家信息
const hasCurUser = await client.hexistsAsync(REDIS_KEY.USER_INFO, roleId);
const hasCurUser = await client.hexistsAsync(infoKey, myId);
if(!hasCurUser) {
await redisUserInfoAdd(roleId, params);
await redisUserInfoAdd(infoKey, myId, params);
}
return true;
}
@@ -97,12 +158,20 @@ export async function getRank(key: string, serverId: number, roleId: string) {
const client: Redis.RedisClient = pinus.app.get('redis');
let ranks = [], myRank = null;
const rankFromDb = await client.zrevrangebyscoreAsync(getKeyName(key, serverId), '+inf', '-inf', "WITHSCORES", "LIMIT", 0, 100);
let infoKey = REDIS_RANK_TO_INFO.get(key);
for(let ii = 0; ii < rankFromDb.length; ii+=2) {
const _roleId = rankFromDb[ii];
const _score = decodeScoreWithTime(rankFromDb[ii + 1]);
const userInfo = await client.hgetAsync(REDIS_KEY.USER_INFO, _roleId);
const _userInfo = JSON.parse(userInfo);
const tmp = {..._userInfo, roleId: _roleId, num: _score, rank: Math.floor(ii/2)+1}
const info = await client.hgetAsync(infoKey, _roleId);
const _userInfo = JSON.parse(info);
const tmp = {..._userInfo, num: _score, rank: Math.floor(ii/2)+1};
if(infoKey == REDIS_KEY.USER_INFO) {
tmp["roleId"] = _roleId;
} else if(infoKey == REDIS_KEY.GUILD_INFO) {
tmp["code"] = _roleId;
}
ranks.push(tmp);
if(roleId == _roleId) myRank = tmp;
}
@@ -138,6 +207,14 @@ function decodeScoreWithTime(num: string): number {
return Math.floor(_num/pow);
}
// 从排行榜中移除
export async function removeFromRank(key: string, serverId: number, myId: string) {
const client: Redis.RedisClient = pinus.app.get('redis');
await client.zremAsync(getKeyName(key, serverId), myId);
return true;
}
/**************** 寻宝相关 start */
// 把寻宝的玩家信息存入 redis
@@ -245,7 +322,7 @@ export async function resetPvpRanks() {
const hasCurUser = await client.hexistsAsync(REDIS_KEY.USER_INFO, roleId);
if(!hasCurUser) {
let rankPram = new RankParam(roleName, lv, vLv, headHid, sHid, title);
await redisUserInfoAdd(roleId, rankPram);
await redisUserInfoAdd(REDIS_KEY.USER_INFO, roleId, rankPram);
}
}
}