import { Service } from 'egg'; import { resResult as pubResult } from '../pubUtils/util'; import { gameData } from 'app/pubUtils/data'; import { RedisClient } from 'redis'; import { REDIS_KEY, SERVER_STATUS } from '@consts'; import { getRedisSubChannel } from 'app/pubUtils/sdkUtil'; import { ServerlistType } from '@db/Serverlist'; import { nowSeconds } from 'app/pubUtils/timeUtil'; import { checkWhiteList } from 'app/pubUtils/sysUtil'; const csprng = require('csprng'); /** * Utils Service */ export default class Utils extends Service { /** * 生成 len 长度的随机字符串 * @param len 长度 * @param radix 基数 */ public generateStr(len: number, radix = 36) { return `${csprng(len, radix)}`; } public genCode(len) { const chars = '123456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijklmnopqrstuvwxyz'; const charArr = chars.split(''); let code = ''; for (let i = 0; i < len; i++) { code += charArr[Math.floor(Math.random() * charArr.length)]; } return code; } /** * 生成指定长度的随机数 * @param len 随机数长度 */ public generateNum(len: number) { let code = ''; for (let i = 0; i < len; i++) { code += parseInt(`${Math.random() * 10}`); } return code; } public resResult(status: {code: number, simStr: string}, data?, customMsg?: string) { return pubResult(status, data, customMsg); } public log(level: 'DEBUG'|'INFO'|'WARN'| 'ERROR', message: string) { const log = this.app.loggers.get('linkLogger'); if(level == 'DEBUG') { log.debug(`${message}`); } else if (level == 'INFO') { log.info(`${message}`); } else if (level == 'WARN') { log.warn(`${message}`); } else if (level == "ERROR") { log.error(`${message}`); } } public async checkOnlineUser(userCode: string) { let redisClient: RedisClient = this.ctx.app.context.redisClient; let onlineRoleId = await redisClient.hgetAsync(REDIS_KEY.USER_CODE, userCode); let isWhiteList = await checkWhiteList(this.ctx.app.config.realEnv, this.ctx.clientIp, this.ctx.uid); if (!isWhiteList && !!onlineRoleId) { // 多地登陆踢下线 let str = await redisClient.hgetAsync(REDIS_KEY.ONLINE_USERS, onlineRoleId); if(str) { try { let [,sid] = str?.split('|')??[]; let name = getRedisSubChannel(REDIS_KEY.USER_CHANNEL, this.ctx.app.config.env); await redisClient.publishAsync(name, `${sid}|${onlineRoleId}`); } catch(e) { console.error('checkOnlineUser', e); } } } } public async pushPubAccountGiftChannel(activityId: number, userCode: string, channelId: string) { let redisClient: RedisClient = this.ctx.app.context.redisClient; try { let name = getRedisSubChannel(REDIS_KEY.PUBLIC_ACCOUNT_GIFT, this.ctx.app.config.env); await redisClient.publishAsync(name, `${activityId}|${userCode}|${channelId}`); } catch(e) { console.error('pushPubAccountGiftChannel', e); } } public async pushGiftCodeChannel(roleId: string, giftCode: string) { let redisClient: RedisClient = this.ctx.app.context.redisClient; try { let name = getRedisSubChannel(REDIS_KEY.SEND_GIFT_CODE, this.ctx.app.config.env); await redisClient.publishAsync(name, `${roleId}|${giftCode}`); } catch(e) { console.error('pushPubAccountGiftChannel', e); } } // 检测是否可以登录 public async validateCanLogin() { try { if(gameData.serverConst.CLOSE_LOGIN == 1) return false; if(gameData.serverConst.CLOSE_LOGIN_WHEN_ONLINE_MAX) { let redisClient: RedisClient = this.ctx.app.context.redisClient; let count = await redisClient.hlenAsync(REDIS_KEY.ONLINE_USERS); const Max = await redisClient.getAsync(REDIS_KEY.MAX_ONLINE_USERS); console.log('validateCanLogin:', count, Max); if(Max && count >= parseInt(Max)) { console.log('validateCanLogin false:', count, Max); return false } } return true; } catch(e) { console.error('validateCanLogin', e); return true; } } // 比较以 . 分隔的版本号。返回 0 则版本号相等,返回正数则 versionA 大,返回负数则 versionB 大 public compareVersion (versionA: string, versionB: string) { var vA = versionA.split('.'); var vB = versionB.split('.'); for (var i = 0; i < vA.length; ++i) { var a = parseInt(vA[i]); var b = parseInt(vB[i] || '0'); if (a === b) { } else { return a - b; } } if (vB.length > vA.length) { return -1; } else { return 0; } }; public getServerStatus(server: ServerlistType, version: string, hasRole: boolean) { let now = nowSeconds(); if (now < server.openTime) { return SERVER_STATUS.WILL_OPEN; } else if (server.maintenance && server.maintenance.isOpen && server.maintenance.startTime < now && server.maintenance.endTime > now) { const versionFlag = this.ctx.service.utils.compareVersion(version, server.maintenance.version||'0.0.0'); if(versionFlag >= 0) { // 新版本号 if(!hasRole && server.id == server.latestServerUniqId) { // 新玩家 return server.serverStatus; } else { return SERVER_STATUS.MAINTENANCE; } } else { return SERVER_STATUS.MAINTENANCE; } } else { return server.serverStatus; // 未开服 } } }