Files
ZYZ/game-server/app/services/redisService.ts
2021-03-30 18:07:04 +08:00

764 lines
26 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { GOOD_QUALITY, REDIS_RANK_TO_INFO, COM_BTL_QUALITY, GUILD_ACTIVITY_TYPE, GUILD_ACTIVITY_STATUS } from './../consts';
import { RoleModel, RoleType } from "../db/Role";
import * as Redis from 'redis';
import {REDIS_KEY} from '../consts'
import { GameModel } from "../db/Game";
import { promisifyAll } from 'bluebird';
import { pinus } from 'pinus';
import { PvpDefenseModel } from '../db/PvpDefense';
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';
/**
* 在服务重新启动时将信息存入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);
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 = 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);
}
/**
* 初始化某一个排行榜,如定时器内
* @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) {
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 } 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 });
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}`;
} else {
newKey = key;
}
if(plus) {
newKey += `:${plus}`;
}
return newKey;
}
// 更新玩家信息
export async function redisUserInfoUpdate(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);
for(let {field, value} of arr) {
obj[field] = value;
}
return await redisClient().hsetAsync(key, roleId, JSON.stringify(obj));
}
}
// 添加玩家信息缓存
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
*/
export async function setRank(key: string, serverId: number, myId: string, score: number, timestamp: number, params: RankParam|GuildRankParam, isAtom = false, limit = 100) {
// 更新分数
let newScore = score;
if(isAtom) {
newScore = await updateRankAtom(key, serverId, myId, score, timestamp);
} else {
const _score = encodeScoreWithTime(score, timestamp);
await redisClient().zaddAsync(getKeyName(key, serverId), _score, myId);
// 移除100名以外
await redisClient().zremrangebyrankAsync(getKeyName(key, serverId), limit, 10000);
}
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, limit = 100) {
// 更新分数
let newScore = score;
if(isAtom) {
newScore = await updateRankAtom(key, serverId, myId, score, timestamp, isInc);
} 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;
}
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);
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): number {
let timelen = 10;
let pow = Math.pow(10, timelen + 1);
let _num = parseInt(num);
return Math.floor(_num/pow);
}
// 从排行榜中移除
export async function removeFromRank(key: string, serverId: number, myId: string) {
await redisClient().zremAsync(getKeyName(key, serverId), myId);
return true;
}
/**************** 寻宝相关 start */
/**
* @description 拼接匹配分组的 key
* @param {number} quality 品质
* @param {number} lvRange 等级范围
*/
function getComTeamKey(quality: number, lvRange: number) {
return `${REDIS_KEY.COM_TEAM_SEARCH_PRE}:${quality}_${lvRange}`;
}
/**
* @description 拼接匹配分组中 member 的值
* @param {string} roleId
* @param {string} sid connector serverId
* @returns
*/
function getComTeamValue(roleId: string, sid: string) {
return `${roleId}:${sid}`;
}
/**
* @description 把寻宝的玩家信息存入 redis
* @export
* @param {string} roleId
* @param {string} sid
* @param {Array<number>} qualityArr
* @param {number} lvRange
* @returns
*/
export async function setTeamSearchReq(roleId: string, sid: string, qualityArr: Array<number>, lvRange: number) {
let cmds = [];
qualityArr.forEach(quality => {
if (quality) {
cmds.push(['sadd', getComTeamKey(quality, lvRange), getComTeamValue(roleId, sid)]);
}
});
const multiClient = redisClient().multi(cmds) as Redis.Multi;
const newMulti = promisifyAll(multiClient) as Redis.Multi;
const res = await newMulti.execAsync();
console.log('setTeamSearchReq: ', res);
return res;
}
/**
* @description 从匹配队列中删除某个用户
* @export
* @param {string} roleId
* @param {string} sid
* @param {Array<number>} qualityArr
* @param {number} lvRange
*/
export async function rmRoleFromQueue(roleId: string, sid: string, qualityArr: Array<number>, lvRange: number) {
let cmds = [];
for (let q of qualityArr) {
if (lvRange) {
cmds.push(['srem', getComTeamKey(q, lvRange), getComTeamValue(roleId, sid)]);
} else {
for (let range of comBtlRanges()) {
cmds.push(['srem', getComTeamKey(q, range), getComTeamValue(roleId, sid)]);
}
}
};
const multiClient = redisClient().multi(cmds) as Redis.Multi;
const newMulti = promisifyAll(multiClient) as Redis.Multi;
await newMulti.execAsync();
}
/**
* @description 在寻宝匹配队列中随机两个玩家
* @export
* @param {number} quality 队伍品质
* @param {number} lvRange 等级范围
* @returns
*/
export async function getTeamSearchByQuality(quality: number, lvRange: number) {
// TODO: 操作不具有原子性
const userInfos = await redisClient().srandmemberAsync(getComTeamKey(quality, lvRange), 2);
console.log('getTeamSearchByQuality: ' + userInfos);
if (!userInfos || !userInfos.length) return null;
let res = [];
for (let userInfo of userInfos) {
const decodeData = `${userInfo}`.split(':');
if (decodeData.length !== 2) return null;
res.push({roleId: decodeData[0], sid: decodeData[1]});
}
console.log('getTeamSearchByQuality res: ', res);
return res;
}
/**
* @description 检查玩家是否在某个队列中等待寻宝匹配
* @export
* @param {string} roleId
* @param {string} sid
* @param {Array<number>} qualityArr
* @param {number} lvRange
* @returns
*/
export async function checkRoleInQueue(roleId: string, sid: string, qualityArr: Array<number>, lvRange: number) {
for (let quality of qualityArr) {
let res = await redisClient().sismemberAsync(getComTeamKey(quality, lvRange), `${roleId}:${sid}`);
if (res) {
return true;
}
};
return false;
}
/**
* @description 清除所有的寻宝匹配队列
* @export
*/
export async function clearComBtlQueue() {
for (let q of COM_BTL_QUALITY) {
for (let lvRange of comBtlRanges()) {
await redisClient().delAsync(getComTeamKey(q, lvRange));
}
}
}
export function setRedis(key: string, data: string) {
redisClient().setAsync(key, data);
}
export async function getRedis(key: string) {
const str = await redisClient().getAsync(key);
return str;
}
export async function delRedis(key: string) {
await redisClient().delAsync(key);
}
export function redisSidKey(roleId: string) {
return `login_roleId_${roleId}`;
}
export async function redisChannelServer(roomId: string) {
const sid = await redisClient().hgetAsync(REDIS_KEY.CHANNEL_SERVERS, roomId);
return sid;
}
export async function addRedisChannel(roomId: string, sid: string) {
const result = await redisClient().hsetAsync(REDIS_KEY.CHANNEL_SERVERS, roomId, sid);
return result;
}
export async function clearChannelServers() {
const result = await redisClient().delAsync(REDIS_KEY.CHANNEL_SERVERS);
return result;
}
/**
* 玩家上线
* @param roleId role表id
* @param userCode user表唯一字符串标识
* @param sid connector服的那个sid
*/
export async function roleLogin(roleId: string, userCode: string, sid: string, pkgName: string) {
let param = { userCode, sid, pkgName };
return await redisClient().hsetAsync(REDIS_KEY.ONLINE_USERS, roleId, JSON.stringify(param));
}
/**
* 玩家下线
* @param roleId role表id
*/
export async function roleLeave(roleId: string) {
let role = await getRoleOnlineInfo(roleId);
await redisClient().hdelAsync(REDIS_KEY.ONLINE_USERS, roleId);
return role;
}
/**
* 判断玩家是否在线
* @param roleId role表id
*/
export async function isRoleOnline(roleId: string) {
let result = await redisClient().hexistsAsync(REDIS_KEY.ONLINE_USERS, roleId);
return !!result;
}
/**
* 获得在线玩家userCode和sid
* @param roleId
*/
export async function getRoleOnlineInfo(roleId: string) {
let str = await redisClient().hgetAsync(REDIS_KEY.ONLINE_USERS, roleId);
if(str) {
try {
let result = JSON.parse(str);
return {
isOnline: true,
userCode: result.userCode,
sid: result.sid,
pkgName: result.pkgName
}
} catch(e) {
return { isOnline: false }
}
} else {
return { isOnline: false }
}
}
/**
* 获得所有在线的玩家
*/
export async function getAllOnlineRoles() {
const client: Redis.RedisClient = pinus.app.get('redis');
let allRoles = await redisClient().hgetallAsync(REDIS_KEY.ONLINE_USERS);
let result = new Array<{roleId: string, userCode: string, sid: string, pkgName: string}>();
for(let roleId in allRoles) {
try{
let param = JSON.parse(allRoles[roleId]);
if(param) {
result.push({ roleId, userCode: param.userCode, sid: param.sid, pkgName: param.pkgName });
}
} catch(e) {
continue;
}
}
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) {
const result = await redisClient().smembersAsync(key);
return result;
}
export async function saddAsync(key: string, values: Array<string>) {
const result = await redisClient().saddAsync(key, values);
return result;
}
export async function sismemberAsync(key: string, value: string) {
const result = await redisClient().sismemberAsync(key, value);
return result;
}
export async function delAsync(key:string) {
await redisClient().delAsync(key);
}
export async function sremAsync(key:string, member:string) {
await redisClient().sremAsync(key, member);
}
/**************** 寻宝相关 end */
/**************** 数据库表存入缓存 */
export async function readDataBase() {
await setServerList();
}
async function setServerList() {
const serverList = await GameModel.getAllServerList();
await redisClient().delAsync(REDIS_KEY.DB_GAME);
for(let { id, serverType, name } of serverList) {
// console.log(roleId);
await redisClient().hsetAsync(REDIS_KEY.DB_GAME, `${serverType}_${id}`, name);
}
}
export async function getAllServers() {
let servers = await redisClient().hgetallAsync(REDIS_KEY.DB_GAME);
let serverlist = new Array<number>();
for(let serverStr in servers) {
let arr = serverStr.split('_');
let serverId = parseInt(arr[1]);
if(!isNaN(serverId) && !serverlist.includes(serverId)) {
serverlist.push(serverId);
}
}
return serverlist;
}
export async function getServerName(serverType: string, serverId: number) {
let name = await redisClient().hgetAsync(REDIS_KEY.DB_GAME, `${serverType}_${serverId}`);
return name
}
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) {
let originKey = getKeyName(key, serverId);
let timeKey = getKeyName(key, serverId, 'time');
let timelen = 10;
let pow = Math.pow(10, timelen + 1);
let newScore = 0;
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]);
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);
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 */