排行榜:旧数据完成
This commit is contained in:
@@ -10,22 +10,19 @@ import { SystemConfigModel } from '../db/SystemConfig';
|
||||
import { GuildRankParam, GuildLeader, RankParam } from '../domain/rank';
|
||||
import { GuildModel } from '../db/Guild';
|
||||
import { comBtlRanges } from '../pubUtils/gamedata';
|
||||
import { getNextHourPoint } from '../pubUtils/timeUtil';
|
||||
import { gameData } from '../pubUtils/data';
|
||||
import { Rank } from './rankService';
|
||||
/**
|
||||
* 在服务重新启动时,将信息存入redis
|
||||
*/
|
||||
export async function initAllRank() {
|
||||
const client: Redis.RedisClient = redisClient();
|
||||
const serverList = await GameModel.getAllServerList();
|
||||
await client.delAsync(REDIS_KEY.ONLINE_USERS);
|
||||
await client.delAsync(REDIS_KEY.USER_INFO);
|
||||
|
||||
await client.delAsync(REDIS_KEY.GUILD_INFO);
|
||||
await client.delAsync(REDIS_KEY.PVP_RANK);
|
||||
await delKeys(REDIS_KEY.ONLINE_USERS);
|
||||
await delKeys(REDIS_KEY.USER_INFO);
|
||||
await delKeys(REDIS_KEY.GUILD_INFO);
|
||||
await delKeys(REDIS_KEY.PVP_RANK);
|
||||
await delKeys(REDIS_KEY.TOWER_RANK);
|
||||
await delKeys(REDIS_KEY.GUILD_ACTIVE_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);
|
||||
}
|
||||
}
|
||||
@@ -37,14 +34,8 @@ export async function initAllRank() {
|
||||
*/
|
||||
export async function initRank(serverId: number) {
|
||||
// console.log('*****', 'initRank')
|
||||
const client: Redis.RedisClient = redisClient();
|
||||
await setRankRedisFromDb(REDIS_KEY.TOWER_RANK, serverId);
|
||||
await setRankRedisFromDb(REDIS_KEY.GUILD_ACTIVE_RANK, serverId);
|
||||
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});
|
||||
|
||||
}
|
||||
|
||||
@@ -54,80 +45,48 @@ export async function initRank(serverId: number) {
|
||||
*/
|
||||
export async function initSingleRank(key: string) {
|
||||
|
||||
const serverList = await GameModel.getAllServerList();
|
||||
for(let {id} of serverList) {
|
||||
await initSingleRankWithServer(key, id);
|
||||
}
|
||||
}
|
||||
await delKeys(key);
|
||||
|
||||
/**
|
||||
* 初始化某一服内的某一种排行榜
|
||||
* @param key redis key
|
||||
*/
|
||||
export async function initSingleRankWithServer(key: string, serverId: number) {
|
||||
|
||||
await redisClient().delAsync(getKeyName(key, serverId));
|
||||
await setRankRedisFromDb(key, serverId);
|
||||
await redisClient().expireAsync(key, 30 * 24 * 60 * 60);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从数据库内获取排行榜存入redis
|
||||
* @param type 排行榜类型
|
||||
* @param serverId 分服
|
||||
*/
|
||||
async function setRankRedisFromDb(type: string, serverId: number) {
|
||||
if(type == REDIS_KEY.TOWER_RANK) {
|
||||
let ranks = await RoleModel.getRank('tower', serverId, ['roleId', 'roleName', 'towerLv', 'lv', 'vLv', 'head', 'frame', 'spine','title', 'updatedAt']);
|
||||
for(let {towerLv, roleId, roleName, lv, vLv, towerUpTime, head, frame, spine, title} of ranks) {
|
||||
// console.log(roleId);
|
||||
await redisClient().zaddAsync(getKeyName(REDIS_KEY.TOWER_RANK, serverId), encodeScoreWithTime(towerLv, towerUpTime?towerUpTime.getTime():0), roleId);
|
||||
let rankPram = new RankParam(roleName, lv, vLv, head, frame, spine, 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, memberCnt } of ranks) {
|
||||
let _leader = <RoleType>leader;
|
||||
let { roleName, title, head, frame, spine, lv: leaderLv } = _leader;
|
||||
await redisClient().zaddAsync(getKeyName(REDIS_KEY.GUILD_ACTIVE_RANK, serverId), encodeScoreWithTime(activeWeekly, activeUpdateTime * 1000 ), code);
|
||||
let rankParam = new GuildRankParam(icon, name, lv, { roleName, title, head, frame, spine, lv: leaderLv }, memberCnt);
|
||||
await redisUserInfoAdd(REDIS_KEY.GUILD_INFO, code, rankParam);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 排行榜是否存在
|
||||
export async function existsRank(key: string, serverId: number) {
|
||||
const result = await redisClient().existsAsync(getKeyName(key, serverId));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获得redis key的名字
|
||||
* @param key REDIS_KEY中配置的key
|
||||
* @param serverId 服务器id
|
||||
* @param plus 后面再加
|
||||
*/
|
||||
function getKeyName(key: string, serverId?: number, plus: string = '') {
|
||||
let newKey = '';
|
||||
if(serverId) {
|
||||
newKey = `${key}:${serverId}`;
|
||||
if(key == REDIS_KEY.PVP_RANK) {
|
||||
await setRankRedisFromDb(key, {});
|
||||
} else {
|
||||
newKey = key;
|
||||
const serverList = await GameModel.getAllServerList();
|
||||
for(let { id } of serverList) {
|
||||
await setRankRedisFromDb(key, { serverId: id });
|
||||
}
|
||||
}
|
||||
|
||||
if(plus) {
|
||||
newKey += `:${plus}`;
|
||||
}
|
||||
return newKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* debug接口使用,直接删除排行榜数据
|
||||
* @param params serverId => guildCodes
|
||||
*/
|
||||
export async function delGuildActivityRank(aid: number) {
|
||||
if(aid == GUILD_ACTIVITY_TYPE.GATE_ACTIVITY) {
|
||||
await delKeys(REDIS_KEY.USER_GATE_ACTIVITY);
|
||||
await delKeys(REDIS_KEY.GATE_ACTIVITY);
|
||||
} else if (aid == GUILD_ACTIVITY_TYPE.CITY_ACTIVITY) {
|
||||
await delKeys(REDIS_KEY.USER_CITY_ACTIVITY);
|
||||
await delKeys(REDIS_KEY.CITY_ACTIVITY);
|
||||
} else if (aid == GUILD_ACTIVITY_TYPE.RACE_ACTIVITY) {
|
||||
await delKeys(REDIS_KEY.RACE_ACTIVITY);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新玩家信息
|
||||
export async function redisUserInfoUpdate(key: string, roleId: string, arr: Array<{field: string, value:(string|number|GuildLeader)}>) {
|
||||
async function delKeys(key: string) {
|
||||
let keys = await redisClient().keysAsync(`${key}*`);
|
||||
for(let key of keys) {
|
||||
await redisClient().delAsync(key);
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
export async function setUserInfo(key: string, roleId: string, params: RankParam|GuildRankParam) {
|
||||
let value = JSON.stringify(params);
|
||||
return await redisClient().hsetAsync(key, roleId, value);
|
||||
}
|
||||
|
||||
export async function updateUserInfo(key: string, roleId: string, arr: Array<{field: string, value:(string|number|GuildLeader)}>) {
|
||||
let params = await redisClient().hgetAsync(key, roleId);
|
||||
if(params) {
|
||||
let obj = JSON.parse(params);
|
||||
@@ -138,142 +97,43 @@ export async function redisUserInfoUpdate(key: string, roleId: string, arr: Arra
|
||||
}
|
||||
}
|
||||
|
||||
// 添加玩家信息缓存
|
||||
export async function redisUserInfoAdd(key: string, roleId: string, params: RankParam|GuildRankParam) {
|
||||
let value = JSON.stringify(params);
|
||||
return await redisClient().hsetAsync(key, roleId, value);
|
||||
}
|
||||
/********排行榜结束 */
|
||||
|
||||
/**
|
||||
* 更新排行榜
|
||||
* @param key 配置在REDIS_KEY中的key
|
||||
* @param serverId 区服id 如pvp这样跨服的,serverId传0
|
||||
* @param myId 玩家roleId或军团code
|
||||
* @param score 得分
|
||||
* @param timestamp 时间 13位时间戳
|
||||
* @param params 玩家数据
|
||||
* @param isAtom 是否是原子性的更新
|
||||
* @param limit
|
||||
* 从数据库内获取排行榜存入redis
|
||||
* @param type 排行榜类型
|
||||
* @param serverId 分服
|
||||
*/
|
||||
export async function setRank(key: string, serverId: number, myId: string, score: number, timestamp: number, params: RankParam|GuildRankParam, isAtom = false, timelen = 10, limit = 100) {
|
||||
|
||||
// 更新分数
|
||||
let newScore = score;
|
||||
if(isAtom) {
|
||||
newScore = await updateRankAtom(key, serverId, myId, score, timestamp, true, timelen);
|
||||
} else {
|
||||
const _score = encodeScoreWithTime(score, timestamp);
|
||||
await redisClient().zaddAsync(getKeyName(key, serverId), _score, myId);
|
||||
// 移除100名以外
|
||||
await redisClient().zremrangebyrankAsync(getKeyName(key, serverId), limit, 10000);
|
||||
}
|
||||
async function setRankRedisFromDb(type: string, args?: {serverId?: number}) {
|
||||
|
||||
let infoKey = REDIS_RANK_TO_INFO.get(key)||REDIS_KEY.USER_INFO;
|
||||
// 如果没有信息,更新玩家信息
|
||||
const hasCurUser = await redisClient().hexistsAsync(infoKey, myId);
|
||||
if(!hasCurUser) {
|
||||
await redisUserInfoAdd(infoKey, myId, params);
|
||||
}
|
||||
return parseInt(newScore.toString());
|
||||
}
|
||||
|
||||
export async function setRankWithoutUserInfo(key: string, serverId: number, myId: string, score: number, timestamp: number, isAtom = false, isInc = true, timelen=10, limit = 100) {
|
||||
|
||||
let infoKey = REDIS_RANK_TO_INFO.get(key)||REDIS_KEY.USER_INFO;
|
||||
// 如果没有信息,更新玩家信息
|
||||
const hasCurUser = await redisClient().hexistsAsync(infoKey, myId);
|
||||
if(!hasCurUser) {
|
||||
let guild = await GuildModel.findByCode(myId, serverId);
|
||||
|
||||
let leader = <RoleType>guild.leader;
|
||||
let guildRankParam = new GuildRankParam(guild.icon, guild.name, guild.lv, leader, guild.memberCnt);
|
||||
await redisUserInfoAdd(infoKey, myId, guildRankParam);
|
||||
}
|
||||
|
||||
// 更新分数
|
||||
let newScore = score;
|
||||
if(isAtom) {
|
||||
newScore = await updateRankAtom(key, serverId, myId, score, timestamp, isInc, timelen);
|
||||
} else {
|
||||
const _score = encodeScoreWithTime(score, timestamp);
|
||||
await redisClient().zaddAsync(getKeyName(key, serverId), _score, myId);
|
||||
// 移除100名以外
|
||||
await redisClient().zremrangebyrankAsync(getKeyName(key, serverId), limit, 10000);
|
||||
}
|
||||
|
||||
return parseInt(newScore.toString());
|
||||
}
|
||||
|
||||
// 获取排行榜
|
||||
export async function getRank(key: string, serverId: number, roleId: string, limit = 100) {
|
||||
|
||||
let ranks = [], myRank = null;
|
||||
const rankFromDb = await redisClient().zrevrangebyscoreAsync(getKeyName(key, serverId), '+inf', '-inf', "WITHSCORES", "LIMIT", 0, limit);
|
||||
|
||||
let _key = key.split(':')[0];
|
||||
let infoKey = REDIS_RANK_TO_INFO.get(_key)||REDIS_KEY.USER_INFO;
|
||||
|
||||
for(let ii = 0; ii < rankFromDb.length; ii+=2) {
|
||||
const _roleId = rankFromDb[ii];
|
||||
const _score = decodeScoreWithTime(rankFromDb[ii + 1]);
|
||||
const info = await redisClient().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;
|
||||
if(type == REDIS_KEY.TOWER_RANK) {
|
||||
let serverId = args.serverId;
|
||||
let ranks = await RoleModel.getRank('tower', serverId, ['roleId', 'roleName', 'towerLv', 'lv', 'vLv', 'head', 'frame', 'spine','title', 'updatedAt']);
|
||||
let r = new Rank(REDIS_KEY.TOWER_RANK, { serverId });
|
||||
for(let role of ranks) {
|
||||
// console.log(roleId);
|
||||
await r.setRankWithRoleInfo(role.roleId, role.towerLv, role.towerUpTime?role.towerUpTime.getTime():0, role);
|
||||
}
|
||||
} else if (type == REDIS_KEY.GUILD_ACTIVE_RANK) {
|
||||
let serverId = args.serverId;
|
||||
let ranks = await GuildModel.getRank(serverId);
|
||||
let r = new Rank(REDIS_KEY.GUILD_ACTIVE_RANK, { serverId });
|
||||
for(let guild of ranks) {
|
||||
await r.setRankWithGuildInfo(guild.code, guild.activeWeekly, guild.activeUpdateTime * 1000, guild);
|
||||
}
|
||||
} else if ( type == REDIS_KEY.PVP_RANK) {
|
||||
let { seasonNum } = await SystemConfigModel.findSystemConfig();
|
||||
console.log('execute season resetPvpRanks seasonNum = ' + seasonNum);
|
||||
let ranks = await PvpDefenseModel.getRank(seasonNum);//获得全服前1000名的排名,加入到redis中
|
||||
let r = new Rank(REDIS_KEY.PVP_RANK, {});
|
||||
for(let {roleId, role: _role, score, updatedAt } of ranks) {
|
||||
let role = <RoleType>_role;
|
||||
if (!role) {
|
||||
continue;
|
||||
}
|
||||
await r.setRankWithRoleInfo(roleId, score, updatedAt.getTime(), role);
|
||||
}
|
||||
ranks.push(tmp);
|
||||
if(roleId == _roleId) myRank = tmp;
|
||||
}
|
||||
return {ranks, myRank}
|
||||
}
|
||||
|
||||
// 获取我的排名
|
||||
export async function getMyRank(key: string, serverId: number, roleId: string) {
|
||||
let myRank = await redisClient().zrevrankAsync(getKeyName(key, serverId), roleId);
|
||||
|
||||
if(!myRank && myRank != 0) {
|
||||
return 0
|
||||
} else {
|
||||
return myRank + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取排名第几名的信息
|
||||
export async function getFieldByRank(key: string, serverId: number, rank: number) {
|
||||
let myRank = await redisClient().zrevrangeAsync(getKeyName(key, serverId), rank - 1, rank - 1);
|
||||
return myRank;
|
||||
}
|
||||
|
||||
// 有序排行综合时间和得分排序
|
||||
function encodeScoreWithTime(score: number, timestamp: number): number {
|
||||
// value = score * Math.power(10, 14) + max_time - timestamp
|
||||
let timelen = 10;
|
||||
let pow = Math.pow(10, timelen + 1);
|
||||
return score * pow + pow - 1 - Math.floor(timestamp/1000)
|
||||
}
|
||||
|
||||
function decodeScoreWithTime(num: string, timelen: number = 10): number {
|
||||
let pow = Math.pow(10, timelen + 1);
|
||||
let _num = parseInt(num);
|
||||
return Math.floor(_num/pow);
|
||||
}
|
||||
|
||||
function decodeTime(num: string, timelen: number = 10): number {
|
||||
let pow = Math.pow(10, timelen + 1);
|
||||
let _num = parseInt(num);
|
||||
let time = _num % pow;
|
||||
console.log(pow, time, _num);
|
||||
return pow - time;
|
||||
}
|
||||
|
||||
// 从排行榜中移除
|
||||
export async function removeFromRank(key: string, serverId: number, myId: string) {
|
||||
await redisClient().zremAsync(getKeyName(key, serverId), myId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**************** 寻宝相关 start */
|
||||
@@ -504,26 +364,6 @@ export async function getAllOnlineRoles() {
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function resetPvpRanks() {
|
||||
await redisClient().delAsync(REDIS_KEY.PVP_RANK);
|
||||
let { seasonNum } = await SystemConfigModel.findSystemConfig();
|
||||
console.log('execute season resetPvpRanks seasonNum = ' + seasonNum);
|
||||
let pvpRank = await PvpDefenseModel.getRank(seasonNum);//获得全服前1000名的排名,加入到redis中
|
||||
for(let {roleId, role: _role, score, updatedAt } of pvpRank) {
|
||||
let role = <RoleType>_role;
|
||||
if (!role) {
|
||||
continue;
|
||||
}
|
||||
let { roleName, head, frame, spine, title, lv, vLv } = role;
|
||||
await redisClient().zaddAsync(getKeyName(REDIS_KEY.PVP_RANK), encodeScoreWithTime(score, updatedAt?updatedAt.getTime():0), roleId);
|
||||
|
||||
const hasCurUser = await redisClient().hexistsAsync(REDIS_KEY.USER_INFO, roleId);
|
||||
if(!hasCurUser) {
|
||||
let rankPram = new RankParam(roleName, lv, vLv, head, frame, spine, title);
|
||||
await redisUserInfoAdd(REDIS_KEY.USER_INFO, roleId, rankPram);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 排行榜是否存在
|
||||
export async function smembersAsync(key: string) {
|
||||
@@ -585,205 +425,9 @@ export async function getServerName(serverType: string, serverId: number) {
|
||||
return name
|
||||
}
|
||||
|
||||
function redisClient() {
|
||||
export function redisClient() {
|
||||
const client: Redis.RedisClient = pinus.app.get('redis');
|
||||
return client;
|
||||
}
|
||||
|
||||
/**************** 数据库表end */
|
||||
|
||||
/**************** 军团活动排行 */
|
||||
|
||||
/**
|
||||
* 更新排行榜(将得分和时间拆分开)
|
||||
* @param key 配置在REDIS_KEY中的key
|
||||
* @param serverId 区服id
|
||||
* @param field 玩家id/军团id
|
||||
* @param score 得分
|
||||
* @param time 事件
|
||||
*/
|
||||
async function updateRankAtom(key: string, serverId: number, field: string, score: number, timestamp: number, isInc = true, timelen = 10) {
|
||||
let originKey = getKeyName(key, serverId);
|
||||
let timeKey = getKeyName(key, serverId, 'time');
|
||||
|
||||
let pow = Math.pow(10, timelen + 1);
|
||||
let newScore = 0;
|
||||
console.log('********', isInc, field, score, pow - 1 - Math.floor(timestamp/1000));
|
||||
if(isInc) {
|
||||
newScore = await redisClient().zincrbyAsync(originKey, score, field);
|
||||
} else {
|
||||
newScore = await redisClient().zaddAsync(originKey, score, field);
|
||||
}
|
||||
await redisClient().zaddAsync(timeKey, pow - 1 - Math.floor(timestamp/1000), field);
|
||||
|
||||
await redisClient().expireatAsync(originKey, getNextHourPoint(5));
|
||||
await redisClient().expireatAsync(timeKey, getNextHourPoint(5));
|
||||
|
||||
return newScore;
|
||||
}
|
||||
|
||||
async function generateUnionRank(key: string, serverId: number, timelen = 10) {
|
||||
let unionKey = getKeyName(key, serverId, 'union'); // 联合的key
|
||||
let existsKey = await redisClient().existsAsync(unionKey);
|
||||
if(!existsKey) {
|
||||
let originKey = getKeyName(key, serverId);
|
||||
let timeKey = getKeyName(key, serverId, 'time');
|
||||
|
||||
let pow = Math.pow(10, timelen + 1);
|
||||
await redisClient().zunionstoreAsync(unionKey, 2, originKey, timeKey, 'WEIGHTS', pow, 1);
|
||||
if(originKey.indexOf(REDIS_KEY.RACE_ACTIVITY) == -1) {
|
||||
await redisClient().expireAsync(unionKey, 10); // 10秒更新一次
|
||||
} else {
|
||||
await redisClient().expireAsync(unionKey, 1); // 1秒更新一次
|
||||
}
|
||||
}
|
||||
return unionKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用updateRankAtom更新的排行榜,使用这个方法获取列表
|
||||
* @param key 配置在REDIS_KEY中的key
|
||||
* @param serverId 区服id
|
||||
* @param roleId 自己的id
|
||||
*/
|
||||
export async function getUnionRank(key: string, serverId: number, roleId: string, timelen = 10, limit = 100) {
|
||||
|
||||
let ranks = [], myRank = null;
|
||||
let unionKey = await generateUnionRank(key, serverId, timelen);
|
||||
const rankFromDb = await redisClient().zrevrangebyscoreAsync(unionKey, '+inf', '-inf', "WITHSCORES", "LIMIT", 0, limit);
|
||||
|
||||
let _key = key.split(':')[0];
|
||||
console.log(_key)
|
||||
let infoKey = REDIS_RANK_TO_INFO.get(_key)||REDIS_KEY.USER_INFO;
|
||||
|
||||
for(let ii = 0; ii < rankFromDb.length; ii+=2) {
|
||||
const _roleId = rankFromDb[ii];
|
||||
const _score = decodeScoreWithTime(rankFromDb[ii + 1], timelen);
|
||||
const _time = decodeTime(rankFromDb[ii + 1], timelen);
|
||||
const info = await redisClient().hgetAsync(infoKey, _roleId);
|
||||
const _userInfo = JSON.parse(info);
|
||||
const tmp = {..._userInfo, num: _score, time: _time, 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;
|
||||
}
|
||||
return {ranks, myRank}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取(分两个zset的)排行的一段排名内的数据
|
||||
* @param key 配置在REDIS_KEY中的key
|
||||
* @param serverId 区服id
|
||||
* @param startRank 开始排名
|
||||
* @param endRank 结束排名
|
||||
*/
|
||||
export async function getUnionRankRange(key: string, serverId: number, startRank: number, endRank: number) {
|
||||
let ranks = [];
|
||||
|
||||
let unionKey = await generateUnionRank(key, serverId);
|
||||
const rankFromDb = await redisClient().zrevrangeAsync(unionKey, startRank - 1, endRank - 1, "WITHSCORES");
|
||||
|
||||
let _key = key.split(':')[0];
|
||||
let infoKey = REDIS_RANK_TO_INFO.get(_key)||REDIS_KEY.USER_INFO;
|
||||
|
||||
for(let ii = 0; ii < rankFromDb.length; ii+=2) {
|
||||
const _roleId = rankFromDb[ii];
|
||||
const _score = decodeScoreWithTime(rankFromDb[ii + 1]);
|
||||
const info = await redisClient().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);
|
||||
}
|
||||
return ranks
|
||||
}
|
||||
|
||||
// 获取我的排名
|
||||
export async function getMyUnionRank(key: string, serverId: number, roleId: string) {
|
||||
let unionKey = await generateUnionRank(key, serverId);
|
||||
let myRank = await redisClient().zrevrankAsync(unionKey, roleId);
|
||||
return myRank + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取拼接得分的排行榜的某一个人的得分
|
||||
* @param key REDIS_KEY中配置的
|
||||
* @param serverId 分服
|
||||
* @param field 查询的人
|
||||
*/
|
||||
export async function getRankScore(key: string, serverId: number, field: string, needDecode = false) {
|
||||
let score = await redisClient().zscoreAsync(getKeyName(key, serverId), field);
|
||||
if(!score) score = 0;
|
||||
if(needDecode) {
|
||||
score = decodeScoreWithTime(score.toString());
|
||||
}
|
||||
return parseInt(score.toString());
|
||||
}
|
||||
|
||||
export async function setUserGuildActivityRank(key: string, guildCode: string, serverId: number, roleId: string, score: number, time: number, userParam: RankParam) {
|
||||
let nkey = getGuildKeyName(key, guildCode);
|
||||
let oldScore = await getRankScore(nkey, serverId, roleId, true);
|
||||
let nScore = await setRank(nkey, serverId, roleId, oldScore + score, time, userParam);
|
||||
await redisClient().expireatAsync(getKeyName(nkey, serverId), getNextHourPoint(5))
|
||||
return nScore
|
||||
}
|
||||
|
||||
/**
|
||||
* 按军团名拼接key
|
||||
* @param key
|
||||
* @param guildCode 军团编号
|
||||
*/
|
||||
export function getGuildKeyName(key: string, guildCode: string) {
|
||||
return `${key}:${guildCode}`;
|
||||
}
|
||||
|
||||
export function getCityKeyName(key: string, cityId: number) {
|
||||
return `${key}:${cityId}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* debug接口使用,直接删除排行榜数据
|
||||
* @param params serverId => guildCodes
|
||||
*/
|
||||
export async function delGuildActivityRank(aid: number, params: Map<number, string[]>) {
|
||||
if(aid == GUILD_ACTIVITY_TYPE.GATE_ACTIVITY) {
|
||||
for(let [serverId, guildCodes] of params) {
|
||||
await redisClient().delAsync(getKeyName(REDIS_KEY.GATE_ACTIVITY, serverId));
|
||||
await redisClient().delAsync(getKeyName(REDIS_KEY.GATE_ACTIVITY, serverId, 'time'));
|
||||
await redisClient().delAsync(getKeyName(REDIS_KEY.GATE_ACTIVITY, serverId, 'union'));
|
||||
|
||||
for(let guildCode of guildCodes) {
|
||||
await redisClient().delAsync(getKeyName(getGuildKeyName(REDIS_KEY.USER_GATE_ACTIVITY, guildCode), serverId));
|
||||
}
|
||||
}
|
||||
} else if (aid == GUILD_ACTIVITY_TYPE.CITY_ACTIVITY) {
|
||||
let dicCity = gameData.cityActivity;
|
||||
for(let [cityId] of dicCity) {
|
||||
for(let [serverId, guildCodes] of params) {
|
||||
await redisClient().delAsync(getKeyName(getCityKeyName(REDIS_KEY.CITY_ACTIVITY, cityId) , serverId));
|
||||
await redisClient().delAsync(getKeyName(getCityKeyName(REDIS_KEY.CITY_ACTIVITY, cityId), serverId, 'time'));
|
||||
await redisClient().delAsync(getKeyName(getCityKeyName(REDIS_KEY.CITY_ACTIVITY, cityId), serverId, 'union'));
|
||||
|
||||
for(let guildCode of guildCodes) {
|
||||
await redisClient().delAsync(getKeyName(getGuildKeyName(REDIS_KEY.USER_CITY_ACTIVITY, guildCode), serverId));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (aid == GUILD_ACTIVITY_TYPE.RACE_ACTIVITY) {
|
||||
for(let [serverId] of params) {
|
||||
await redisClient().delAsync(getKeyName(REDIS_KEY.RACE_ACTIVITY, serverId));
|
||||
await redisClient().delAsync(getKeyName(REDIS_KEY.RACE_ACTIVITY, serverId, 'time'));
|
||||
await redisClient().delAsync(getKeyName(REDIS_KEY.RACE_ACTIVITY, serverId, 'union'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**************** 军团活动排行end */
|
||||
Reference in New Issue
Block a user