This commit is contained in:
xy
2026-03-13 01:38:40 +00:00
parent e6e4f88257
commit 28855885cd
311 changed files with 89544 additions and 94350 deletions
+297 -179
View File
@@ -1,21 +1,21 @@
import {Application, RouteRecord, FrontendOrBackendSession, HandlerCallback, pinus, FrontendSession} from "pinus";
// import { checkEvent } from '../../../services/eventSercive';
import { refresh } from '../../../services/refreshService';
import { checkPrivateChat, checkGuildChat, checkOtherChat, checkRoleName, checkGuildName } from "../../../services/sdkService";
import { resResult, genCode } from "../../../pubUtils/util";
import { checkWhiteList, MsgEncrypt } from "../../../pubUtils/sysUtil";
import { BLOCK_TYPE, CHANNEL_PREFIX, MSG_TYPE, PUSH_ROUTE, STATUS } from "../../../consts";
import { nowSeconds } from "../../../pubUtils/timeUtil";
import { getServerMainten } from "../../../services/gmService";
import { errlogger, infologger } from "../../../util/logger";
import { gameData } from "../../../pubUtils/data";
import { sendMessageToUser } from "../../../services/pushService";
import { isCheckWord, isSkipEncode } from "../../../pubUtils/sdkUtil";
import { isDevelopEnv } from "../../../services/utilService";
import { refresh } from "@pubUtils/refreshService";
import { checkPrivateChat, checkGuildChat, checkOtherChat, checkRoleName, checkGuildName } from "@pubUtils/sdkService";
import { resResult, genCode } from "@pubUtils/util";
import { checkWhiteList, MsgEncrypt } from "@pubUtils/sysUtil";
import { BLOCK_TYPE, CHANNEL_PREFIX, MSG_TYPE, PUSH_ROUTE, STATUS } from "@consts";
import { nowSeconds } from "@pubUtils/timeUtil";
import { getServerMainten } from "@pubUtils/gmService";
import { errlogger, infologger } from "@pubUtils/logger";
import { gameData } from "@pubUtils/data";
import { sendMessageToUser } from "@pubUtils/pushService";
import { isCheckWord, isSkipEncode } from "@pubUtils/sdkUtil";
import { isDevelopEnv } from "@pubUtils/utilService";
import { isNumber } from "underscore";
import { getServerCreateTime, redisClient } from "../../../services/redisService";
import { checkRouteParam } from "../../../services/checkParam";
import { isApiClose } from "../../../services/chatService";
import { getServerCreateTime, redisClient } from "@pubUtils/redisService";
import { checkRouteParam } from "@pubUtils/checkParam";
import { isApiClose } from "@pubUtils/chatService";
export function globalFilter(app: Application) {
return new Filter(app);
@@ -29,13 +29,12 @@ class Filter {
this.app = app;
}
public async before (routeRecord: RouteRecord, msg: any, session: FrontendOrBackendSession, next: HandlerCallback) {
public async before (routeRecord: RouteRecord, msg: any, session: FrontendOrBackendSession, next: HandlerCallback) {
const serverId: number = session.get('serverId');
const sid: string = session.get('sid');
const roleId: string = session.get('roleId');
const uid: number = session.get('userid');
const ip: string = session.get('ip');
// console.log('*********** global before ip', ip)
const version: string = session.get('version');
const isNewUser: boolean = session.get('isNewUser');
let guildCode = session.get('guildCode');
@@ -46,172 +45,293 @@ class Filter {
if(!this.checkPassEncrypt(routeRecord.route)) {
msg = this.decryptMsg(msg, session);
if(!msg) return next(new Error('globalFilter'), resResult(STATUS.WRONG_PARMS, { route: routeRecord.route }));
if(!this.checkTimeStamp(msg)) return next(new Error('globalFilter'), resResult(STATUS.TIMESTAMP_ERR, { route: routeRecord.route }));
if(!this.checkDuplicateAccess(msg)) return next(new Error('globalFilter'), resResult(STATUS.DUPLICATE_ACCESS, { route: routeRecord.route }))
}
msg = this.setMsg(msg, { logCode });
// 访问频率控制
if(!this.checkFrequency(routeRecord.route, msg, roleId)) {
return next(new Error('globalFilter'), resResult(STATUS.ACCESS_BUSY, { route: routeRecord.route }));
}
if(!this.checkFunction(routeRecord.route, msg)) {
return next(new Error('globalFilter'), resResult(STATUS.FUNCTION_CLOSE, { route: routeRecord.route }));
// @ts-ignore
if(!this.checkTimeStamp(msg)) return next(new Error('globalFilter'), resResult(STATUS.TIMESTAMP_ERR, { route: routeRecord.route }));
}
if(!checkRouteParam(routeRecord.route, msg)) {
return next(new Error('globalFilter'), resResult(STATUS.WRONG_PARMS, { route: routeRecord.route }));
// @ts-ignore
if (isApiClose(routeRecord.route)) {
// @ts-ignore
return next(new Error('globalFilter'), resResult(STATUS.API_CLOSE, { route: routeRecord.route }));
}
// 玩家屏蔽
if(blockType == BLOCK_TYPE.BLOCK) return next(new Error('globalFilter'), resResult(STATUS.BLOCKED, { route: routeRecord.route }));
if(blockType == BLOCK_TYPE.BAN && this.checkBanRoute(routeRecord.route)) {
return next(new Error('globalFilter'), resResult(STATUS.BANNED, { route: routeRecord.route }));
}
session.push('teamCode', () => {});
if(isCheckWord(isDevelopEnv())) {
let hasBlockWords = await this.checkHasBlockWord(routeRecord.route, msg, roleId, serverId, guildCode);
if(hasBlockWords) return next(new Error('globalFilter'), resResult(STATUS.BLOCK_WORDS, { route: routeRecord.route }));
}
if(routeRecord.route == 'guild.guildHandler.createGuild') {
let guildCode = genCode(6);
msg.guildCode = guildCode;
}
if(routeRecord.route != 'connector.entryHandler.enter' && await this.checkMainten(serverId, sid, ip, uid, isNewUser)) {
sendMessageToUser(roleId, PUSH_ROUTE.SERVER_MAINTENANCE, resResult(STATUS.SERVER_MAINTENANCE), sid);
if(await this.checkMainten(serverId, sid, ip, uid, isNewUser)) {
const mainten = getServerMainten(serverId);
return next(new Error('globalFilter'), resResult(STATUS.SERVER_MAINTENANCE, { route: routeRecord.route, curVersion: version, minVersion: mainten.version }));
// @ts-ignore
return next(new Error('globalFilter'), resResult(STATUS.SERVER_MAINTAIN, {
route: routeRecord.route,
startTime: mainten.startTime,
endTime: mainten.endTime
}));
}
next(null);
};
public async after (err: Error, routeRecord: RouteRecord, msg: any, session: FrontendOrBackendSession, resp: any, next: HandlerCallback) {
//刷新
await refresh(session);
infologger.debug('global after', msg && msg.logCode, routeRecord.route, msg && JSON.stringify(msg), resp && JSON.stringify(resp), session && session.get('roleId'));
if(!this.checkPassEncrypt(routeRecord.route)) {
let data = this.encryptMsg(resp, session);
if(!data) return next(new Error('response data err'));
resp = this.setResp(resp, data);
}
next(null);
};
// 检查调用频率
private checkFrequency (route: string, msg: any, roleId: string) {
let protect = gameData.serverConst.PROTECT_API.find(cur => {
if(cur.route == route) {
let paramOK = true;
for(let key in cur.param) {
if(msg[key] != cur.param[key]) {
paramOK = false; break;
}
// @ts-ignore
if(!isDevelopEnv(this.app.get('env'))) {
if(!this.checkPassEncrypt(routeRecord.route)) {
if(!this.checkSign(routeRecord.route, msg, session)) {
infologger.error('checkSign false', routeRecord.route, msg, session.uid);
// @ts-ignore
return next(new Error('globalFilter'), resResult(STATUS.SIGN_ERROR, { route: routeRecord.route }));
}
if(paramOK) return true;
}
return false;
});
if(!protect) {
return true;
}
let keyOfRouteWithUser = `${protect.id}_${roleId}`;
if(this.accessTime && this.accessTime.has(keyOfRouteWithUser)) {
console.log(this.accessTime.get(keyOfRouteWithUser) - Date.now());
if(Date.now() - this.accessTime.get(keyOfRouteWithUser) < protect.interval) {
errlogger.info(`${keyOfRouteWithUser} 间隔时间小于${protect.interval}ms,为 ${Date.now() - this.accessTime.get(keyOfRouteWithUser)}`);
return false;
}
}
if(!this.accessTime) this.accessTime = new Map<string, number>();
this.accessTime.set(keyOfRouteWithUser, Date.now());
return true;
}
// 检查该接口是否关闭
private checkFunction (route: string, msg: any) {
if(isApiClose()) {
let isClose = gameData.serverConst.CLOSE_APIS.find(cur => {
if(cur.route == route) {
if(cur.param == null) return true;
for(let key in cur.param) {
if(cur.param[key] == true && msg[key] != undefined) return true;
if(cur.param[key] && msg[key] == cur.param[key]) return true;
}
}
return false;
});
return !isClose
if(roleId) {
// @ts-ignore
if(blockType && blockType === BLOCK_TYPE.ROLE) {
// @ts-ignore
return next(new Error('globalFilter'), resResult(STATUS.ROLE_BLOCKED, { route: routeRecord.route }));
}
}
return true;
}
// 这个接口是否需要加密解密
private checkPassEncrypt (route: string) {
return isSkipEncode(isDevelopEnv()) || route.startsWith('gm.') || route == 'connector.entryHandler.gmEnter' || route == 'gate.gateHandler.queryEntry';
}
// 解密接口
private decryptMsg (msg: any, session: FrontendOrBackendSession) {
let msgEncrypt = new MsgEncrypt({ encodeK: msg?.k, encodeV: msg?.v });
let { aesKey, aesIV } = msgEncrypt.getKv();
msg = this.setMsg(msg, msgEncrypt.decryptMsg(msg?.data));
if(!msg) return false;
session.set('k', aesKey);
session.set('v', aesIV);
session.push('k', () => {});
session.push('v', () => {});
return msg
}
// 解密接口
private encryptMsg (resp: any, session: FrontendOrBackendSession) {
let msgEncrypt = new MsgEncrypt({ k: session.get('k'), v: session.get('v')});
let data = msgEncrypt.encryptMsg(resp);
return data;
if(await this.checkDuplicateAccess(msg)) {
infologger.error('checkDuplicateAccess false', routeRecord.route, msg);
// @ts-ignore
return next(new Error('globalFilter'), resResult(STATUS.DUPLICATE_ACCESS, { route: routeRecord.route }));
}
if(routeRecord.route.indexOf('Handler.') != -1) {
if (!checkRouteParam(msg, routeRecord.route)) {
infologger.error('checkRouteParam false', routeRecord.route, msg);
return next(new Error('globalFilter'), resResult(STATUS.WRONG_PARMS, { route: routeRecord.route }));
}
}
if(msg.body) {
msg = msg.body;
}
if(!this.checkBlackList(roleId, serverId)) {
infologger.error('checkBlackList true', roleId, serverId);
// @ts-ignore
return next(new Error('globalFilter'), resResult(STATUS.IN_BLACK_LIST, { route: routeRecord.route }));
}
if(await this.checkHasBlockWord(routeRecord.route, msg, roleId, serverId, guildCode)) {
infologger.error('checkHasBlockWord true', roleId, serverId);
// @ts-ignore
return next(new Error('globalFilter'), resResult(STATUS.HAS_BLOCK_WORD, { route: routeRecord.route }));
}
if(routeRecord.route.indexOf('battle.') != -1) {
// @ts-ignore
if(!this.checkVersion(routeRecord.route, version)) {
// @ts-ignore
return next(new Error('globalFilter'), resResult(STATUS.VERSION_TOO_LOW, { route: routeRecord.route, version: version }));
}
}
const beginTime = Date.now();
this.accessTime.set(`${roleId}_${routeRecord.route}`, beginTime);
// @ts-ignore
next();
}
// 传入的msg的修改
private setMsg (msg:any, targetObj: any) {
if(!msg || !targetObj || typeof targetObj != 'object') {
return false;
}
delete msg.k;
delete msg.v;
if(typeof msg.data == 'string') delete msg.data;
for(let key in targetObj) {
if(targetObj.hasOwnProperty(key)) {
msg[key] = targetObj[key];
}
private checkVersion(route: string, version: string) {
if(!version) return true;
// @ts-ignore
const minVersion = gameData.serverConst.MIN_VERSION[route];
if(!minVersion) return true;
return version >= minVersion;
}
private decryptMsg(msg: any, session: FrontendOrBackendSession) {
if (!session) return msg;
const publicKey = session.get('publicKey');
const encode = session.get('encode');
// @ts-ignore
if(!encode || encode != MsgEncrypt.RSA) return msg;
if(!publicKey) return msg;
try {
// @ts-ignore
const decryptMsg = pinus.crypto.decrypt(Buffer.from(publicKey, 'base64'), Buffer.from(msg, 'base64'));
msg = JSON.parse(decryptMsg.toString());
} catch (e) {
errlogger.error('decryptMsg error', e);
return null;
}
return msg;
}
// 传出的resp的修改
private setResp(resp: any, data: string) {
for(let key in resp) {
if(resp.hasOwnProperty(key)) {
delete resp[key];
}
}
resp.data = data;
return resp;
private checkSign(route: string, msg: any, session: FrontendOrBackendSession) {
if (!session) return false;
const sign = msg['sign'];
const token = session.get('token');
if (!sign || !token) return false;
const md5 = require('crypto').createHash('md5');
const str = route + JSON.stringify(msg) + token;
const signVal = md5.update(str).digest('hex');
return sign === signVal;
}
// 禁言的接口
private checkBanRoute (route: string) {
return [
private checkPassEncrypt(route: string) {
// @ts-ignore
if(!gameData.serverConst.NOT_CHECK_SIGN_ROUTES) return false;
// @ts-ignore
return gameData.serverConst.NOT_CHECK_SIGN_ROUTES.indexOf(route) != -1;
}
private checkBlackList(roleId: string, serverId: number) {
if(!roleId) return true;
const blackRoleMap = this.app.get('blackRoleMap') || new Map();
const roleList = blackRoleMap.get(serverId);
if(!roleList) return true;
// @ts-ignore
if(roleList.indexOf(roleId) != -1) {
return false;
}
return true;
}
private checkRoleFrom(route: string, session: FrontendOrBackendSession) {
const needRoutes = [
'role.roleHandler.rename',
'role.roleHandler.setHead',
'role.roleHandler.setSign',
];
if(needRoutes.indexOf(route) == -1) return true;
return session.get('roleId') === session.get('createRoleId');
}
private checkNoRepeatRoute(route: string, session: FrontendOrBackendSession) {
if(!session) return true;
const noRepeatRoutes = [
'role.roleHandler.createRole',
'gate.gateHandler.login',
'connector.entryHandler.enter',
];
if(noRepeatRoutes.indexOf(route) == -1) return true;
if(session.get('hasEnter')) {
return false;
}
session.set('hasEnter', true);
return true;
}
private checkChat(route: string, session: FrontendOrBackendSession, msg: any) {
if(route.indexOf('chat.') == -1) return true;
// @ts-ignore
if(session.get('blockType') == BLOCK_TYPE.CHAT) {
return false;
}
const needCheckRoutes = [
'chat.chatHandler.sendPrivateMessage',
'chat.chatHandler.sendGroupMessage',
'battle.comBattleHandler.sendTeamMsg',
'battle.barrageHandler.sendBarrage',
];
if(needCheckRoutes.indexOf(route) == -1) return true;
// @ts-ignore
const sendLimit = gameData.serverConst.SEND_CHAT_LIMIT;
const roleId = session.get('roleId');
getServerCreateTime(session.get('serverId')).then((now: number) => {
const lastTime = this.accessTime.get(`${roleId}_${route}`) || 0;
if(now - lastTime < sendLimit) {
return false;
}
});
return true;
}
private isNoCheckRoute(route: string) {
return [
'gate.gateHandler.login',
'connector.entryHandler.enter',
'role.roleHandler.initRole',
'role.roleHandler.createRole',
'chat.chatHandler.getInitData',
'chat.chatHandler.getChatList',
'chat.chatHandler.getPrivateChatList',
'battle.barrageHandler.getBarrages',
'activity.activityHandler.getActivityList',
'activity.activityHandler.getServerTime',
'role.roleHandler.getRoleInitInfo',
'role.roleHandler.getRoleOtherInfo',
'gate.gateHandler.getServerList',
'gate.gateHandler.getServerList1',
'gate.gateHandler.getServerTime',
'gm.gmHandler.getServerList',
'gm.gmHandler.getServerList1',
'gm.gmHandler.getServerTime',
'role.roleHandler.getOtherRoleInfo',
'battle.normalBattleHandler.getChapterInfo',
'battle.normalBattleHandler.getChapterStarReward',
'battle.normalBattleHandler.getBoxReward',
'battle.pvpHandler.getPvpInfo',
'battle.pvpHandler.getRankList',
'battle.ladderHandler.getLadderInfo',
'battle.ladderHandler.getLadderRankList',
'battle.ladderHandler.getSeasonReward',
'role.roleHandler.getRechargeList',
'role.roleHandler.getVipInfo',
'role.roleHandler.getMonthCard',
'activity.signInHandler.getSignInInfo',
'activity.dailyGiftsHandler.getInfo',
'activity.dailyMealHandler.getInfo',
'activity.dailyRMBGiftsHandler.getInfo',
'activity.growthFundHandler.getInfo',
'activity.monthlyFundHandler.getInfo',
'activity.sevenDaysHandler.getInfo',
'activity.firstGiftHandler.getInfo',
'activity.rechargeMoneyHandler.getInfo',
'activity.rebateHandler.getInfo',
'activity.thirtyDaysHandler.getInfo',
'activity.timeLimitRankHandler.getRankList',
'activity.timeLimitRankHandler.getMyRankInfo',
'guild.guildHandler.getGuildList',
'guild.guildHandler.getGuildDetail',
'guild.guildHandler.getGuildMemberList',
'guild.guildHandler.getApplyList',
'guild.guildHandler.getGuildLog',
'guild.guildHandler.searchGuild',
'guild.guildTrainHandler.getTrainInfo',
'guild.guildTrainHandler.getDonateLog',
'guild.guildRefineHandler.getRefineLog',
'guild.guildBossHandler.getGuildBossDetail',
'guild.guildBossHandler.getRankList',
'guild.gvgHandler.getGVGInfo',
'guild.gvgBattleHandler.getSeasonReward',
'guild.gvgBattleHandler.getRankList',
'guild.gvgBattleHandler.getMyRankInfo',
'guild.wishPoolHandler.getWishPoolInfo',
'activity.popUpShopHandler.getPopUpShopInfo',
'activity.yuanbaoShopHandler.getYuanbaoShopInfo',
'activity.refreshShopHandler.getRefreshShopInfo',
'activity.selfServiceShopActivityHandler.getSelfServiceShopInfo',
'activity.forgeHandler.getForgeInfo',
'activity.limitPackageHandler.getLimitPackageInfo',
'battle.towerBattleHandler.getTowerInfo',
'battle.towerBattleHandler.getTowerRankList',
'battle.towerBattleHandler.getMyTowerRankInfo',
'battle.expeditionBattleHandler.getExpeditionInfo',
'battle.expeditionBattleHandler.getExpeditionRankList',
'battle.dungeonBattleHandler.getDungeonInfo',
'battle.friendBattleHandler.getFriendBattleInfo',
'battle.friendBattleHandler.getFriendBattleRecord',
'battle.rougeHandler.getRougeInfo',
'battle.rougeHandler.getRougeRecord',
'activity.weeklyFundHandler.getInfo',
'activity.monthlyTicketHandler.getInfo',
'activity.newHeroGachaHandler.getNewHeroGachaInfo',
'activity.newHeroGKHandler.getNewHeroGKInfo',
'activity.newHeroGiftsHandler.getNewHeroGiftsInfo',
'activity.groupShopHandler.getGroupShopInfo',
'activity.luckyHandler.getLuckyInfo',
'activity.luckyTurntableHandler.getLuckyTurntableInfo',
'activity.treasureHuntHandler.getTreasureHuntInfo',
'activity.bindPhoneHandler.getPhoneState',
'activity.midAutumnHandler.getMidAutumnInfo',
'activity.dragonBoatHandler.getDragonBoatInfo',
'activity.qixiHandler.getQixiInfo',
'activity.chongyangHandler.getChongyangInfo',
'activity.novemberHandler.getNovemberInfo',
'activity.entertainHandler.getEntertainInfo',
'activity.miniGameHandler.getMiniGameInfo',
'activity.activityMonopolyHandler.getActivityMonopolyInfo',
'activity.vipRechargeMoneyHandler.getVipRechargeMoneyInfo',
'activity.refreshTaskHandler.getRefreshTaskInfo',
'battle.barrageHandler.sendBarrage',
'guild.guildHandler.sendMail',
'guild.guildHandler.setGuildInfo',
'guild.gvgManageHandler.sendMail',
@@ -220,59 +340,58 @@ class Filter {
'guild.gvgBattleHandler.setNotice',
].indexOf(route) != -1
}
// 检查聊天屏蔽词
private async checkHasBlockWord (route: string, msg: any, roleId: string, serverId: number, guildCode: string) {
private async checkHasBlockWord (route: string, msg: any, roleId: string, serverId: number, guildCode: string) {
let hasBlockWords = false;
switch(route) {
case 'chat.chatHandler.sendPrivateMessage':
{
let result = await checkPrivateChat(roleId, msg.targetRoleId, msg.type == MSG_TYPE.IMG? "表情": msg.content);
if(!result) hasBlockWords = true;
if(!result) hasBlockWords = true;
break;
}
case 'chat.chatHandler.sendGroupMessage':
{
if(msg.channel == CHANNEL_PREFIX.GUILD) {
let result = await checkGuildChat(roleId, guildCode, msg.type == MSG_TYPE.IMG? "表情": msg.content);
if(!result) hasBlockWords = true;
if(!result) hasBlockWords = true;
break;
} else {
let result = await checkOtherChat(roleId, msg.channel, msg.type == MSG_TYPE.IMG? "表情": msg.content);
if(!result) hasBlockWords = true;
if(!result) hasBlockWords = true;
break;
}
}
case 'battle.comBattleHandler.sendTeamMsg':
{
let result = await checkOtherChat(roleId, CHANNEL_PREFIX.TEAM, msg.content);
if(!result) hasBlockWords = true;
if(!result) hasBlockWords = true;
break;
}
case 'battle.barrageHandler.sendBarrage':
{
let result = await checkOtherChat(roleId, CHANNEL_PREFIX.WORLD, msg.content);
if(!result) hasBlockWords = true;
if(!result) hasBlockWords = true;
break;
}
case 'guild.guildHandler.sendMail':
{
let result = await checkGuildChat(roleId, guildCode, msg.info);
if(!result) hasBlockWords = true;
if(!result) hasBlockWords = true;
break;
}
case 'role.roleHandler.rename':
case 'role.roleHandler.initRole':
{
let result = await checkRoleName(roleId, msg.roleName);
if(!result) hasBlockWords = true;
if(!result) hasBlockWords = true;
break;
}
case 'guild.guildHandler.createGuild':
case 'guild.guildHandler.setGuildInfo':
{
let result = await checkGuildName(guildCode, serverId, msg.name, msg.notice);
if(!result) hasBlockWords = true;
if(!result) hasBlockWords = true;
break;
}
case 'guild.gvgManageHandler.createLeague':
@@ -280,32 +399,31 @@ class Filter {
case 'guild.gvgBattleHandler.setNotice':
{
let result = await checkGuildName(guildCode, serverId, msg.name, msg.notice);
if(!result) hasBlockWords = true;
if(!result) hasBlockWords = true;
break;
}
case 'guild.gvgManageHandler.sendMail':
case 'guild.gvgManageHandler.recruit':
{
let result = await checkGuildChat(roleId, guildCode, msg.content);
if(!result) hasBlockWords = true;
if(!result) hasBlockWords = true;
break;
}
}
return hasBlockWords;
}
// 检查是否维护中
private async checkMainten(serverId: number, sid: string, ip: string, uid: number, isNewUser: boolean) {
if(!sid) return false;
const mainten = getServerMainten(serverId);
if(!mainten) return false // 该服务器维护
if(!mainten) return false
if(mainten.startTime > nowSeconds() || mainten.endTime < nowSeconds()) return false;
let isWhiteList = await checkWhiteList(this.app.get('env'), ip, uid);
if(isWhiteList) return false;
if(isNewUser) return false;
return true
}
@@ -328,4 +446,4 @@ class Filter {
await redis.expireAsync(`cs: ${cs}`, gameData.serverConst.ACCESS_CODE_EXPIRE_TIME/1000);
return true;
}
}
}
@@ -1,423 +1,424 @@
import { STATUS } from './../../../consts/statusCode';
import { RoleModel, RoleType } from './../../../db/Role';
import { UserModel, UserType } from '../../../db/User';
import { GMUserModel } from '../../../db/GMUser';
import { Application, HandlerService, pinus, } from 'pinus';
import { FrontendSession } from 'pinus';
import { HeroModel } from './../../../db/Hero';
import { compareVersion, genCode, generateStr, resResult } from '../../../pubUtils/util';
import { COM_BTL_QUALITY, HERO_SELECT, DEBUG_MAGIC_WORD, REDIS_KEY, TASK_TYPE, ENTERY_ROLE_PICK, COUNTER, DEFAULT_LV, TA_USERSET_TYPE, LOG_TYPE, JEWEL_SELECT, ITEM_SELECT, SKIN_SELECT, PUSH_ROUTE } from '../../../consts';
// import { loginRefresh } from '../../../services/playerEventService';
import { nowSeconds, getZeroPoint } from '../../../pubUtils/timeUtil';
import { rmRoleFromQueue, roleLeave, getRoleOnlineInfo, roleLogin, getOnlineRoleByUserCode } from '../../../services/redisService';
import { addRoleToGuildChannel, addRoleToSysChannel, addRoleToWorldChannel, leaveGroupShopChannel, leaveGuildAuctionChannel, leaveGuildChannel, leaveGVGAreaChannel, leaveGVGAreaTeamChannel, leaveGVGCityTeamChannel, leaveSysChannel, leaveWorldAuctionChannel, leaveWorldChannel } from '../../../services/chatService';
import { reportOneOnline, savePlayTime } from '../../../services/authenticateService';
import { checkTaskInEntry, } from '../../../services/task/taskService';
import { pushData, kickUser, getModuleData, assignServer, leaveServer } from '../../../services/connectorService';
// import { setComBtlOnUserLeave } from '../../../services/comBattleService';
import Counter from '../../../db/Counter';
import { getExpByLv } from '../../../pubUtils/data';
import { reportCreateRoleEventToTa, reportTAEvent, reportTAUserSet } from '../../../services/sdkService';
import { saveLoginAndOutLog } from '../../../pubUtils/logUtil';
import { sendMessageToAllWithSuc, sendMessageToUserWithSuc } from '../../../services/pushService';
import { checkIsNewUser, getIpLocation } from '../../../services/roleService';
import { leaveRaceActivityToRemote } from '../../../services/guildActivity/guildActivityService';
import { leaveCity } from '../../../services/gvg/gvgBattleService';
import { autoCreateServerWhenRoleInit } from '../../../services/serverService';
import { getHiddenData } from '../../../services/memoryCache/hiddenData';
import { ServerlistModel } from '../../../db/Serverlist';
import { checkWhiteList } from '../../../pubUtils/sysUtil';
import { getAp } from '../../../services/actionPointService';
import { RegionModel } from '../../../db/Region';
export default function (app: Application) {
new HandlerService(app, {});
return new EntryHandler(app);
}
export class EntryHandler {
constructor(private app: Application) {
}
/**
* New client entry chat server.
*
* @param {Object} msg request message
* @param {Object} session current session object
*/
async enter(msg: { token: string, serverId: number, version: string }, session: FrontendSession) {
// console.log('****** entry before', Date.now());
let self = this;
let serverId = msg.serverId;
let curRegion = await RegionModel.findRegionByEnv(pinus.app.get('env'));
const versionFlag = compareVersion(msg.version, curRegion?.minVersion);
if (!curRegion || versionFlag < 0) {
//版本号太低
return resResult(STATUS.VERSION_ERR, { version: curRegion.minVersion });
}
let user = await UserModel.findUserByToken(msg.token);
if (!user) {
console.log('user token not found');
return resResult(STATUS.TOKEN_ERR);
}
let ip = this.getIp(session);
let isWhiteList = await checkWhiteList(pinus.app.get('env'), ip, user.uid);
let ipLocation = await getIpLocation(ip);
let role = await RoleModel.findByUidAndSetTime(user.uid, serverId, ip, ipLocation, null, true);
if (!role) {
return resResult(STATUS.ROLE_NOT_FOUND);
}
let onlineRoleId = isWhiteList? role.roleId: await getOnlineRoleByUserCode(user.userCode);
if (!!onlineRoleId) { // 多地登陆踢下线
let connect = await getRoleOnlineInfo(onlineRoleId);
if (connect.sid = self.app.getServerId()) {
await kickUser(self.app, onlineRoleId);
} else {
await self.app.rpc.connector.connectorRemote.remoteLogin.toServer(connect.sid, onlineRoleId);
}
}
let server = await ServerlistModel.findByServerId(serverId);
if(!server) return resResult(STATUS.SERVER_NOT_FOUND);
if(!isWhiteList) { // 白名单
if(server.openTime > nowSeconds()) {
return resResult(STATUS.SERVER_IS_NOT_OPEN);
}
if(server.maintenance && server.maintenance.isOpen && server.maintenance.startTime <= nowSeconds() && server.maintenance.endTime >= nowSeconds()) {
let isNewUser = await checkIsNewUser(msg.version, server.maintenance.version, user.uid, server.latestServerUniqId);
console.log('#### isNewUser', isNewUser)
if(isNewUser && server.id == server.latestServerUniqId) {
user['isNewUser'] = true;
} else {
return resResult(STATUS.SERVER_MAINTENANCE, { curVersion: msg.version, minVersion: server.maintenance.version })
}
}
}
let serverName = this.app.getServerId();
await roleLogin(role.roleId, user.userCode, serverName, role.createTime, role.serverId, role.lv, role.topLineupCe); // 保存在线用户
await this.addSession(user, role, msg.version, session);
await reportCreateRoleEventToTa(role, ip);
saveLoginAndOutLog(LOG_TYPE.LOGIN, session);
addRoleToSysChannel(role.roleId, self.app.get('serverId'), role.serverId);
addRoleToWorldChannel(role.roleId, self.app.get('serverId'), role.serverId);
reportOneOnline(role.roleId, user.userCode, self.app.get('serverId'), true, user);
// 任务
checkTaskInEntry(serverId, role.roleId, self.app.get('serverId'), role);
if (role.hasGuild) {
addRoleToGuildChannel(role.roleId, self.app.get('serverId'), role.guildCode);
}
let todayZeroPoint = getZeroPoint();
if(role.needCount) autoCreateServerWhenRoleInit(serverId);
// console.log('****** entry after', Date.now());
return resResult(STATUS.SUCCESS, { roleId: role.roleId, todayZeroPoint });
}
async getData(msg: { }, session: FrontendSession) {
let ip = session.get('ip');
let roleId = session.get('roleId');
let role = await RoleModel.findByRoleId(roleId, '-_id', true, true);
// 推送数据
pushData(role.hasInit, role, session);
let todayZeroPoint = getZeroPoint();
return resResult(STATUS.SUCCESS, { todayZeroPoint });
}
private getIp(session: FrontendSession) {
return session.remoteAddress.ip.replace('::ffff:', '');
}
async addSession(user: UserType, role: RoleType, version: string, session: FrontendSession) {
const self = this;
let ip = this.getIp(session);
console.log('####### addSession', user['isNewUser']||false)
await session.abind(role.roleId);
session.set('userid', role.userInfo.uid);
session.set('roleId', role.roleId);
session.set('loginTime', nowSeconds());
session.set('roleName', role.roleName);
session.set('eventStatus', role.eventStatus);
session.set('blockType', role.blockType);
session.set('sid', self.app.get('serverId'));
session.set('serverId', role.serverId);
session.set('guildCode', role.guildCode);
session.set('ip', ip);
session.set('vipStartTime', role.vipStartTime||0);
session.set('channel', user.channelInfo?.platformAppid||'pc');
session.set('isNewUser', user['isNewUser']||false);
session.set('version', version);
session.set('quitTime', role.quitTime ? (role.quitTime * 1000) : Date.now())
session.push('userid', () => { });
session.push('sid', () => { });
session.push('roleId', () => { });
session.push('roleName', () => { });
session.push('eventStatus', () => { });
session.push('serverId', () => { });
session.push('loginTime', () => { });
session.push('guildCode', () => { });
session.push('blockType', () => { });
session.push('ip', () => { });
session.push('vipStartTime', () => { });
session.push('channel', () => { });
session.push('version', () => { });
session.push('isNewUser', () => { });
session.push('quitTime', () => { })
assignServer(role.roleId, session);
// console.log('#####', role.serverId, role.guildCode)
// console.log(role.guildCode)
// session.push('rid', function (err) {
// if (err) {
// console.error('set rid for session service failed! error is : %j', err.stack);
// }
// });
session.on('closed', this.onUserLeave.bind(this));
}
/**
* 每天5点时的刷新数据.
*
* @param {Object} msg request message
* @param {Object} session current session object
*/
async refresh(msg: {}, session: FrontendSession) {
let self = this;
let roleId = session.get('roleId');
let role = await RoleModel.findByRoleIdAndSetTime(roleId, '-_id', true);
if (!role) {
return resResult(STATUS.ROLE_NOT_FOUND);
}
let { serverId } = role;
// 任务
checkTaskInEntry(serverId, role.roleId, self.app.get('serverId'), role);
// 推送数据
pushData(role.hasInit, role, session, 'refresh');
let todayZeroPoint = getZeroPoint();
return resResult(STATUS.SUCCESS, { todayZeroPoint });
}
async getHiddenData(msg: { }, session: FrontendSession) {
let data = getHiddenData();
return resResult(STATUS.SUCCESS, data);
}
async comeBack(msg: { version: string }, session: FrontendSession) {
let roleId = session.get('roleId');
let ip = session.get('ip');
let role = await RoleModel.findByRoleId(roleId, 'lv');
if(!role) return resResult(STATUS.ROLE_NOT_FOUND);
let apJson = await getAp(roleId, ip, role.lv);
return resResult(STATUS.SUCCESS, { apJson });
}
/**
* User log out handler
*
* @param {Object} app current application
* @param {Object} session current session object
*
*/
async onUserLeave(session: FrontendSession, reason: string) {
if (!session || !session.uid) {
return;
}
let roleId = session.get('roleId');
let sid = session.get('sid');
let serverId = session.get('serverId');
let loginTime = session.get('loginTime');
const guildCode = session.get('guildCode');
const teamCode: string = session.get('teamCode');
roleLeave(roleId).then(function (roleInfo) {
if (roleInfo.isOnline) {
savePlayTime(roleInfo.userCode);
}
});
leaveRaceActivityToRemote(serverId, guildCode, roleId);
reportTAUserSet(TA_USERSET_TYPE.ADD, roleId, { total_play_time: nowSeconds() - loginTime });
rmRoleFromQueue(roleId, sid); // 删除redis中寻宝的匹配记录
let channelService = this.app.get('channelService');
let channel = channelService.getChannel(roleId, true);
channel.leave(roleId, sid);
try {
await leaveSysChannel(roleId, sid, serverId);
await leaveWorldChannel(roleId, sid, serverId);
await leaveGuildChannel(roleId, sid, guildCode);
await leaveGuildAuctionChannel(roleId, sid, guildCode);
await leaveWorldAuctionChannel(roleId, sid, serverId);
await leaveGroupShopChannel(roleId, sid);
await leaveGVGAreaChannel(roleId, sid);
await leaveGVGAreaTeamChannel(roleId, sid);
await leaveGVGCityTeamChannel(roleId, sid);
await leaveCity(true, roleId, serverId, guildCode);
} catch(e) {
console.error(e.stack);
}
RoleModel.updateRoleInfo(roleId, { quitTime: nowSeconds() });
// if(teamCode) { // 如果有寻宝中的队伍,那么等于战败
// setComBtlOnUserLeave(roleId, teamCode)
// }
saveLoginAndOutLog(LOG_TYPE.LOGINOUT, session);
leaveServer(session);
}
/**
* New client entry chat server.
*
* @param {Object} msg request message
* @param {Object} session current session object
*/
async gmEnter(msg: { token: string }, session: FrontendSession) {
let self = this;
let user = await GMUserModel.getGmAccountByToken(msg.token);
if (!user) {
console.log('user token not found');
return resResult(STATUS.TOKEN_ERR);
}
if(!user.isEnable) {
return resResult(STATUS.GM_NO_AUTHORITY_GET);
}
// console.log(self.app.get('serverId'));
await session.abind(user.username);
session.set('uid', user.uid);
session.set('roleId', user.username);
session.set('roleName', user.name);
session.set('groupId', user.groupId);
session.set('eventStatus', 0);
session.set('sid', self.app.get('serverId'));
session.push('uid', () => { });
session.push('sid', () => { });
session.push('roleId', () => { });
session.push('roleName', () => { });
session.push('groupId', () => { });
session.push('eventStatus', () => { });
// session.push('rid', function (err) {
// if (err) {
// console.error('set rid for session service failed! error is : %j', err.stack);
// }
// });
session.on('closed', this.onGmUserLeave.bind(this));
sendMessageToUserWithSuc(user.username, 'onGMENTER', {}, self.app.get('serverId'))
// put user into channel
return resResult(STATUS.SUCCESS, {
env: this.app.get('env')
});
}
/**
* User log out handler
*
* @param {Object} app current application
* @param {Object} session current session object
*
*/
async onGmUserLeave(session: FrontendSession, reason: string) {
if (!session || !session.uid) {
return;
}
}
/**
* ! 仅用于测试
* @description 测试接口,用于查询和返回 token
* @param {{ tel: string, magicWord: string }} msg 要查询的手机号;需要验证的密码
* @param {FrontendSession} session
* @returns
* @memberof EntryHandler
*/
async debugQueryToken(msg: { tel: string, magicWord: string }, session: FrontendSession) {
const { tel, magicWord } = msg;
if (magicWord !== DEBUG_MAGIC_WORD) {
return resResult(STATUS.TOKEN_ERR);
}
const token = await UserModel.findTokenByTel(tel);
return resResult(STATUS.SUCCESS, { token });
}
/**
* ! 仅用于测试
* @description 测试接口,用于查询和返回 token
* @param {{ seqId: string, magicWord: string }} msg 要查询的手机号;需要验证的密码
* @param {FrontendSession} session
* @returns
* @memberof EntryHandler
*/
async debugQueryTokenById(msg: { uid: number, magicWord: string }, session: FrontendSession) {
const { uid, magicWord } = msg;
console.log('debugQueryTokenById msg:', msg);
if (magicWord !== DEBUG_MAGIC_WORD) {
return resResult(STATUS.TOKEN_ERR);
}
const user = await UserModel.findTokenByUid(uid);
console.log('debugQueryTokenById got user:', user);
return resResult(STATUS.SUCCESS, { user });
}
async debugGetRole(msg: { magicWord: string, type: string }, session: FrontendSession) {
const { magicWord, type = 'role' } = msg;
if (magicWord !== DEBUG_MAGIC_WORD) {
return resResult(STATUS.TOKEN_ERR);
}
let roleId = session.get('roleId');
let role = await RoleModel.findByRoleId(roleId, '-_id', true, true);
let module = await getModuleData(type, { role, session });
return resResult(STATUS.SUCCESS, { role: module });
}
async debugQueryTokenByTel(msg: { tel: string, magicWord: string, serverId: number }, session: FrontendSession) {
const { tel, magicWord, serverId } = msg;
if (magicWord !== DEBUG_MAGIC_WORD) {
return resResult(STATUS.TOKEN_ERR);
}
let token = await UserModel.findTokenByTel(tel);
if(!token) {
// 用户注册登录
token = generateStr(256);
let {user} = await UserModel.createOrUpdate(false, tel, token, 'pc', ' ', pinus.app.get('env'), '', '');
const roleId = genCode(10);
const code = genCode(6);
const seqId = await Counter.getNewCounter(COUNTER.ROLE) || -1;
await RoleModel.createRole(user.uid, serverId, { roleId, code, roleName: roleId, seqId, lv: DEFAULT_LV, exp: (getExpByLv(DEFAULT_LV - 1) || { sum: 0 }).sum || 0 }, '');
}
console.log('debugQueryTokenByTel got user:', token);
return resResult(STATUS.SUCCESS, { user: token });
}
async debugPushRefToOnlineUsers(msg: { magicWord: string, todayZeroPoint: number }, session: FrontendSession) {
const { magicWord, todayZeroPoint } = msg;
console.log('debugQueryTokenById msg:', msg);
if (magicWord !== DEBUG_MAGIC_WORD) {
return resResult(STATUS.TOKEN_ERR);
}
await sendMessageToAllWithSuc(PUSH_ROUTE.REFRESH_TIME, { todayZeroPoint });
return resResult(STATUS.SUCCESS);
}
}
import { STATUS } from './../../../consts/statusCode';
import { RoleModel, RoleType } from './../../../db/Role';
import { UserModel, UserType } from '@db/User';
import { GMUserModel } from '@db/GMUser';
import { Application, HandlerService, pinus, } from 'pinus';
import { FrontendSession } from 'pinus';
import { HeroModel } from './../../../db/Hero';
import { compareVersion, genCode, generateStr, resResult } from '@pubUtils/util';
import { COM_BTL_QUALITY, HERO_SELECT, DEBUG_MAGIC_WORD, REDIS_KEY, TASK_TYPE, ENTERY_ROLE_PICK, COUNTER, DEFAULT_LV, TA_USERSET_TYPE, LOG_TYPE, JEWEL_SELECT, ITEM_SELECT, SKIN_SELECT, PUSH_ROUTE } from '../../../consts';
// import { loginRefresh } from '../../../services/playerEventService';
import { nowSeconds, getZeroPoint } from '@pubUtils/timeUtil';
import { rmRoleFromQueue, roleLeave, getRoleOnlineInfo, roleLogin, getOnlineRoleByUserCode } from '../../../services/redisService';
import { addRoleToGuildChannel, addRoleToSysChannel, addRoleToWorldChannel, leaveGroupShopChannel, leaveGuildAuctionChannel, leaveGuildChannel, leaveGVGAreaChannel, leaveGVGAreaTeamChannel, leaveGVGCityTeamChannel, leaveSysChannel, leaveWorldAuctionChannel, leaveWorldChannel } from '../../../services/chatService';
import { reportOneOnline, savePlayTime } from '../../../services/authenticateService';
import { checkTaskInEntry, } from '../../../services/task/taskService';
import { pushData, kickUser, getModuleData, assignServer, leaveServer } from '../../../services/connectorService';
// import { setComBtlOnUserLeave } from '../../../services/comBattleService';
import Counter from '@db/Counter';
import { getExpByLv } from '@pubUtils/data';
import { reportCreateRoleEventToTa, reportTAEvent, reportTAUserSet } from '../../../services/sdkService';
import { saveLoginAndOutLog } from '@pubUtils/logUtil';
import { sendMessageToAllWithSuc, sendMessageToUserWithSuc } from '../../../services/pushService';
import { checkIsNewUser, getIpLocation } from '../../../services/roleService';
import { leaveRaceActivityToRemote } from '../../../services/guildActivity/guildActivityService';
import { leaveCity } from '../../../services/gvg/gvgBattleService';
import { autoCreateServerWhenRoleInit } from '../../../services/serverService';
import { getHiddenData } from '../../../services/memoryCache/hiddenData';
import { ServerlistModel } from '@db/Serverlist';
import { checkWhiteList } from '@pubUtils/sysUtil';
import { getAp } from '../../../services/actionPointService';
import { RegionModel } from '@db/Region';
export default function (app: Application) {
new HandlerService(app, {});
return new EntryHandler(app);
}
export class EntryHandler {
constructor(private app: Application) {
}
/**
* New client entry chat server.
*
* @param {Object} msg request message
* @param {Object} session current session object
*/
async enter(msg: { token: string, serverId: number, version: string }, session: FrontendSession) {
// console.log('****** entry before', Date.now());
let self = this;
let serverId = msg.serverId;
let curRegion = await RegionModel.findRegionByEnv(pinus.app.get('env'));
const versionFlag = compareVersion(msg.version, curRegion?.minVersion);
if (!curRegion || versionFlag < 0) {
//版本号太低
return resResult(STATUS.VERSION_ERR, { version: curRegion.minVersion });
}
let user = await UserModel.findUserByToken(msg.token);
if (!user) {
console.log('user token not found');
return resResult(STATUS.TOKEN_ERR);
}
let ip = this.getIp(session);
let isWhiteList = await checkWhiteList(pinus.app.get('env'), ip, user.uid);
let ipLocation = await getIpLocation(ip);
let role = await RoleModel.findByUidAndSetTime(user.uid, serverId, ip, ipLocation, null, true);
if (!role) {
return resResult(STATUS.ROLE_NOT_FOUND);
}
let onlineRoleId = isWhiteList? role.roleId: await getOnlineRoleByUserCode(user.userCode);
if (!!onlineRoleId) { // 多地登陆踢下线
let connect = await getRoleOnlineInfo(onlineRoleId);
if (connect.sid = self.app.getServerId()) {
await kickUser(self.app, onlineRoleId);
} else {
await self.app.rpc.connector.connectorRemote.remoteLogin.toServer(connect.sid, onlineRoleId);
}
}
let server = await ServerlistModel.findByServerId(serverId);
if(!server) return resResult(STATUS.SERVER_NOT_FOUND);
if(!isWhiteList) { // 白名单
if(server.openTime > nowSeconds()) {
return resResult(STATUS.SERVER_IS_NOT_OPEN);
}
if(server.maintenance && server.maintenance.isOpen && server.maintenance.startTime <= nowSeconds() && server.maintenance.endTime >= nowSeconds()) {
let isNewUser = await checkIsNewUser(msg.version, server.maintenance.version, user.uid, server.latestServerUniqId);
console.log('#### isNewUser', isNewUser)
if(isNewUser && server.id == server.latestServerUniqId) {
user['isNewUser'] = true;
} else {
return resResult(STATUS.SERVER_MAINTENANCE, { curVersion: msg.version, minVersion: server.maintenance.version })
}
}
}
let serverName = this.app.getServerId();
await roleLogin(role.roleId, user.userCode, serverName, role.createTime, role.serverId, role.lv, role.topLineupCe); // 保存在线用户
await this.addSession(user, role, msg.version, session);
await reportCreateRoleEventToTa(role, ip);
saveLoginAndOutLog(LOG_TYPE.LOGIN, session);
addRoleToSysChannel(role.roleId, self.app.get('serverId'), role.serverId);
addRoleToWorldChannel(role.roleId, self.app.get('serverId'), role.serverId);
reportOneOnline(role.roleId, user.userCode, self.app.get('serverId'), true, user);
// 任务
checkTaskInEntry(serverId, role.roleId, self.app.get('serverId'), role);
if (role.hasGuild) {
addRoleToGuildChannel(role.roleId, self.app.get('serverId'), role.guildCode);
}
let todayZeroPoint = getZeroPoint();
if(role.needCount) autoCreateServerWhenRoleInit(serverId);
// console.log('****** entry after', Date.now());
return resResult(STATUS.SUCCESS, { roleId: role.roleId, todayZeroPoint });
}
async getData(msg: { }, session: FrontendSession) {
let ip = session.get('ip');
let roleId = session.get('roleId');
let role = await RoleModel.findByRoleId(roleId, '-_id', true, true);
// 推送数据
pushData(role.hasInit, role, session);
let todayZeroPoint = getZeroPoint();
return resResult(STATUS.SUCCESS, { todayZeroPoint });
}
private getIp(session: FrontendSession) {
return session.remoteAddress.ip.replace('::ffff:', '');
}
async addSession(user: UserType, role: RoleType, version: string, session: FrontendSession) {
const self = this;
let ip = this.getIp(session);
console.log('####### addSession', user['isNewUser']||false)
await session.abind(role.roleId);
session.set('userid', role.userInfo.uid);
session.set('roleId', role.roleId);
session.set('loginTime', nowSeconds());
session.set('roleName', role.roleName);
session.set('eventStatus', role.eventStatus);
session.set('blockType', role.blockType);
session.set('sid', self.app.get('serverId'));
session.set('serverId', role.serverId);
session.set('guildCode', role.guildCode);
session.set('ip', ip);
session.set('vipStartTime', role.vipStartTime||0);
session.set('channel', user.channelInfo?.platformAppid||'pc');
session.set('isNewUser', user['isNewUser']||false);
session.set('version', version);
session.set('quitTime', role.quitTime ? (role.quitTime * 1000) : Date.now())
session.push('userid', () => { });
session.push('sid', () => { });
session.push('roleId', () => { });
session.push('roleName', () => { });
session.push('eventStatus', () => { });
session.push('serverId', () => { });
session.push('loginTime', () => { });
session.push('guildCode', () => { });
session.push('blockType', () => { });
session.push('ip', () => { });
session.push('vipStartTime', () => { });
session.push('channel', () => { });
session.push('version', () => { });
session.push('isNewUser', () => { });
session.push('quitTime', () => { })
assignServer(role.roleId, session);
// console.log('#####', role.serverId, role.guildCode)
// console.log(role.guildCode)
// session.push('rid', function (err) {
// if (err) {
// console.error('set rid for session service failed! error is : %j', err.stack);
// }
// });
session.on('closed', this.onUserLeave.bind(this));
}
/**
* 每天5点时的刷新数据.
*
* @param {Object} msg request message
* @param {Object} session current session object
*/
async refresh(msg: {}, session: FrontendSession) {
let self = this;
let roleId = session.get('roleId');
let role = await RoleModel.findByRoleIdAndSetTime(roleId, '-_id', true);
if (!role) {
return resResult(STATUS.ROLE_NOT_FOUND);
}
let { serverId } = role;
// 任务
checkTaskInEntry(serverId, role.roleId, self.app.get('serverId'), role);
// 推送数据
pushData(role.hasInit, role, session, 'refresh');
let todayZeroPoint = getZeroPoint();
return resResult(STATUS.SUCCESS, { todayZeroPoint });
}
async getHiddenData(msg: { }, session: FrontendSession) {
let data = getHiddenData();
return resResult(STATUS.SUCCESS, data);
}
async comeBack(msg: { version: string }, session: FrontendSession) {
let roleId = session.get('roleId');
let ip = session.get('ip');
let role = await RoleModel.findByRoleId(roleId, 'lv');
if(!role) return resResult(STATUS.ROLE_NOT_FOUND);
let apJson = await getAp(roleId, ip, role.lv);
return resResult(STATUS.SUCCESS, { apJson });
}
/**
* User log out handler
*
* @param {Object} app current application
* @param {Object} session current session object
*
*/
async onUserLeave(session: FrontendSession, reason: string) {
if (!session || !session.uid) {
return;
}
let roleId = session.get('roleId');
let sid = session.get('sid');
let serverId = session.get('serverId');
let loginTime = session.get('loginTime');
const guildCode = session.get('guildCode');
const teamCode: string = session.get('teamCode');
roleLeave(roleId).then(function (roleInfo) {
if (roleInfo.isOnline) {
savePlayTime(roleInfo.userCode);
}
});
leaveRaceActivityToRemote(serverId, guildCode, roleId);
reportTAUserSet(TA_USERSET_TYPE.ADD, roleId, { total_play_time: nowSeconds() - loginTime });
rmRoleFromQueue(roleId, sid); // 删除redis中寻宝的匹配记录
let channelService = this.app.get('channelService');
let channel = channelService.getChannel(roleId, true);
channel.leave(roleId, sid);
try {
await leaveSysChannel(roleId, sid, serverId);
await leaveWorldChannel(roleId, sid, serverId);
await leaveGuildChannel(roleId, sid, guildCode);
await leaveGuildAuctionChannel(roleId, sid, guildCode);
await leaveWorldAuctionChannel(roleId, sid, serverId);
await leaveGroupShopChannel(roleId, sid);
await leaveGVGAreaChannel(roleId, sid);
await leaveGVGAreaTeamChannel(roleId, sid);
await leaveGVGCityTeamChannel(roleId, sid);
await leaveCity(true, roleId, serverId, guildCode);
} catch(e) {
console.error(e.stack);
}
RoleModel.updateRoleInfo(roleId, { quitTime: nowSeconds() });
// if(teamCode) { // 如果有寻宝中的队伍,那么等于战败
// setComBtlOnUserLeave(roleId, teamCode)
// }
saveLoginAndOutLog(LOG_TYPE.LOGINOUT, session);
leaveServer(session);
}
/**
* New client entry chat server.
*
* @param {Object} msg request message
* @param {Object} session current session object
*/
async gmEnter(msg: { token: string }, session: FrontendSession) {
let self = this;
let user = await GMUserModel.getGmAccountByToken(msg.token);
if (!user) {
console.log('user token not found');
return resResult(STATUS.TOKEN_ERR);
}
if(!user.isEnable) {
return resResult(STATUS.GM_NO_AUTHORITY_GET);
}
// console.log(self.app.get('serverId'));
await session.abind(user.username);
session.set('uid', user.uid);
session.set('roleId', user.username);
session.set('roleName', user.name);
session.set('groupId', user.groupId);
session.set('eventStatus', 0);
session.set('sid', self.app.get('serverId'));
session.push('uid', () => { });
session.push('sid', () => { });
session.push('roleId', () => { });
session.push('roleName', () => { });
session.push('groupId', () => { });
session.push('eventStatus', () => { });
// session.push('rid', function (err) {
// if (err) {
// console.error('set rid for session service failed! error is : %j', err.stack);
// }
// });
session.on('closed', this.onGmUserLeave.bind(this));
sendMessageToUserWithSuc(user.username, 'onGMENTER', {}, self.app.get('serverId'))
// put user into channel
return resResult(STATUS.SUCCESS, {
env: this.app.get('env')
});
}
/**
* User log out handler
*
* @param {Object} app current application
* @param {Object} session current session object
*
*/
async onGmUserLeave(session: FrontendSession, reason: string) {
if (!session || !session.uid) {
return;
}
}
/**
* ! 仅用于测试
* @description 测试接口,用于查询和返回 token
* @param {{ tel: string, magicWord: string }} msg 要查询的手机号;需要验证的密码
* @param {FrontendSession} session
* @returns
* @memberof EntryHandler
*/
async debugQueryToken(msg: { tel: string, magicWord: string }, session: FrontendSession) {
const { tel, magicWord } = msg;
if (magicWord !== DEBUG_MAGIC_WORD) {
return resResult(STATUS.TOKEN_ERR);
}
const token = await UserModel.findTokenByTel(tel);
return resResult(STATUS.SUCCESS, { token });
}
/**
* ! 仅用于测试
* @description 测试接口,用于查询和返回 token
* @param {{ seqId: string, magicWord: string }} msg 要查询的手机号;需要验证的密码
* @param {FrontendSession} session
* @returns
* @memberof EntryHandler
*/
async debugQueryTokenById(msg: { uid: number, magicWord: string }, session: FrontendSession) {
const { uid, magicWord } = msg;
console.log('debugQueryTokenById msg:', msg);
if (magicWord !== DEBUG_MAGIC_WORD) {
return resResult(STATUS.TOKEN_ERR);
}
const user = await UserModel.findTokenByUid(uid);
console.log('debugQueryTokenById got user:', user);
return resResult(STATUS.SUCCESS, { user });
}
async debugGetRole(msg: { magicWord: string, type: string }, session: FrontendSession) {
const { magicWord, type = 'role' } = msg;
if (magicWord !== DEBUG_MAGIC_WORD) {
return resResult(STATUS.TOKEN_ERR);
}
let roleId = session.get('roleId');
let role = await RoleModel.findByRoleId(roleId, '-_id', true, true);
let module = await getModuleData(type, { role, session });
return resResult(STATUS.SUCCESS, { role: module });
}
async debugQueryTokenByTel(msg: { tel: string, magicWord: string, serverId: number }, session: FrontendSession) {
const { tel, magicWord, serverId } = msg;
if (magicWord !== DEBUG_MAGIC_WORD) {
return resResult(STATUS.TOKEN_ERR);
}
let token = await UserModel.findTokenByTel(tel);
if(!token) {
// 用户注册登录
token = generateStr(256);
let {user} = await UserModel.createOrUpdate(false, tel, token, 'pc', ' ', pinus.app.get('env'), '', '');
const roleId = genCode(10);
const code = genCode(6);
const seqId = await Counter.getNewCounter(COUNTER.ROLE) || -1;
await RoleModel.createRole(user.uid, serverId, { roleId, code, roleName: roleId, seqId, lv: DEFAULT_LV, exp: (getExpByLv(DEFAULT_LV - 1) || { sum: 0 }).sum || 0 }, '');
}
console.log('debugQueryTokenByTel got user:', token);
return resResult(STATUS.SUCCESS, { user: token });
}
async debugPushRefToOnlineUsers(msg: { magicWord: string, todayZeroPoint: number }, session: FrontendSession) {
const { magicWord, todayZeroPoint } = msg;
console.log('debugQueryTokenById msg:', msg);
if (magicWord !== DEBUG_MAGIC_WORD) {
return resResult(STATUS.TOKEN_ERR);
}
await sendMessageToAllWithSuc(PUSH_ROUTE.REFRESH_TIME, { todayZeroPoint });
return resResult(STATUS.SUCCESS);
}
}
@@ -1,240 +1,241 @@
import { Application, HandlerService, } from 'pinus';
import { gameData, reloadResources } from '../../../pubUtils/data';
import { UserGuildType } from '../../../db/UserGuild';
import { incServerNum, kickUser } from '../../../services/connectorService';
import { PVPConfigModel, PVPConfigType } from '../../../db/PvpConfig';
import { setDicAuctionTime, setDicGuildActivity } from '../../../services/guildActivity/guildActivityService';
import { getServerMainten, setServerMainten, stopServerMainten } from '../../../services/gmService';
import { taflush } from '../../../services/sdkService';
import { errlogger } from '../../../util/logger';
import { setWeek } from '../../../pubUtils/timeUtil';
import { savePvpSeasonMemory } from '../../../services/log/memoryLogService';
import { setApiIsClose } from '../../../services/chatService';
import { setPvpSeasonNum, setPvpSettleSeasonNum } from '../../../services/timeTaskService';
import { setKvToMemory } from '../../../services/pushService';
import { setServerGroup } from '../../../services/serverService';
import { setHiddenData } from '../../../services/memoryCache/hiddenData';
import * as dicParam from '../../../pubUtils/dicParam';
export default function (app: Application) {
new HandlerService(app, {});
return new ConnectorRemote(app);
}
export class ConnectorRemote {
constructor(private app: Application) {
this.app = app;
}
public async remoteLogin(uid: string, message?: any) {
try {
await kickUser(this.app, uid, message);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async setOtherUserGuildSession(params: { roleId: string, userGuild: UserGuildType}[]) {
try {
let sessionService = this.app.get('sessionService');
for(let {roleId, userGuild} of params) {
let sessions = sessionService.getByUid(roleId);
if(!!sessions) {
sessions.forEach(session => {
if(userGuild && userGuild.status == 1) {
sessionService.aimportAll(session.id, { guildCode: userGuild?.guildCode, guildAuth: userGuild?.auth });
} else {
sessionService.aimportAll(session.id, { guildCode: '', guildAuth: 0 });
}
})
}
}
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async setOtherUserSession(params: { roleId: string, roleName?: string, blockType?: number, vipStartTime?: number}[]) {
try {
let sessionService = this.app.get('sessionService');
for(let {roleId, roleName, blockType, vipStartTime} of params) {
let sessions = sessionService.getByUid(roleId);
if(!!sessions) {
sessions.forEach(session => {
if(roleName) sessionService.aimportAll(session.id, { roleName });
if(blockType) sessionService.aimportAll(session.id, { blockType });
if(vipStartTime) sessionService.aimportAll(session.id, { vipStartTime });
});
}
}
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
/**
* 重载json资源
*/
public async reloadResources(type?: string) {
try {
reloadResources(type);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async setDicParam(field1: string, field2: string, value: string|number) {
try {
if(dicParam[field1] && dicParam[field1][field2]) dicParam[field1][field2] = value;
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async setGameDataToApp() {
try {
this.app.set('gameData', gameData);
this.app.set('dicParam', dicParam);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public setServerMainten(serverIds: number[], startTime: number, endTime: number, version: string) {
try {
setServerMainten(serverIds, startTime, endTime, version);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public stopServerMainten(serverIds: number[]) {
try {
stopServerMainten(serverIds);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public getServerMainten(serverId: number) {
try {
return getServerMainten(serverId);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async setPvpSeasonNum(pvpConfig: PVPConfigType) {
try {
await setPvpSeasonNum(pvpConfig);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async setPvpSettleSeasonNum(pvpConfig: PVPConfigType) {
try {
await setPvpSettleSeasonNum(pvpConfig);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
/**
* 改变字典表中的拍卖行时间
*/
async setDicAuctionTime(startTime: number, endActivity: number, startGuild: number, endGuild: number, startWorld: number, endWorld: number) {
try {
setDicAuctionTime(startTime, endActivity, startGuild, endGuild, startWorld, endWorld);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public taflush() {
try {
return taflush();
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
async setDay(week: number) {
try {
setWeek(week);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
/**
* 改变字典表中的军团活动开始时间&持续时间
* @param {number} aid 活动
* @param {number} startSeconds 从现在开始几秒后开启活动
* @param {number} endSeconds 从开始之后几秒后结束活动
*/
public async setDicGuildActivity(now: number, aid: number, startSeconds: number, endSeconds: number) {
try {
setDicGuildActivity(now, aid, startSeconds, endSeconds);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async incServerNum(sid: string, inc: number) {
try {
incServerNum(sid, inc);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public savePvpSeasonMemory() {
try {
return savePvpSeasonMemory();
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async setApiIsClose(isClose: boolean) {
try {
setApiIsClose(isClose);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async setHiddenData(heroes: number[], goods: number[], refTime: number) {
try {
setHiddenData(heroes, goods, refTime);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async setKvToMemory(originK: string, originV: string, aesKey: string, aesIV: string, now: number) {
try {
setKvToMemory(originK, originV, aesKey, aesIV, now);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async setServerGroup() {
try {
return setServerGroup();
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async fun() {
try {
console.log('预留一个函数,用于之后线上维护时需要使用');
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
}
import { Application, HandlerService, } from 'pinus';
import { gameData, reloadResources } from '@pubUtils/data';
import { UserGuildType } from '@db/UserGuild';
import { incServerNum, kickUser } from '../../../services/connectorService';
import { PVPConfigModel, PVPConfigType } from '@db/PvpConfig';
import { setDicAuctionTime, setDicGuildActivity } from '../../../services/guildActivity/guildActivityService';
import { getServerMainten, setServerMainten, stopServerMainten } from '../../../services/gmService';
import { taflush } from '../../../services/sdkService';
import { errlogger } from '../../../util/logger';
import { setWeek } from '@pubUtils/timeUtil';
import { savePvpSeasonMemory } from '../../../services/log/memoryLogService';
import { setApiIsClose } from '../../../services/chatService';
import { setPvpSeasonNum, setPvpSettleSeasonNum } from '../../../services/timeTaskService';
import { setKvToMemory } from '../../../services/pushService';
import { setServerGroup } from '../../../services/serverService';
import { setHiddenData } from '../../../services/memoryCache/hiddenData';
import * as dicParam from '@pubUtils/dicParam';
export default function (app: Application) {
new HandlerService(app, {});
return new ConnectorRemote(app);
}
export class ConnectorRemote {
constructor(private app: Application) {
this.app = app;
}
public async remoteLogin(uid: string, message?: any) {
try {
await kickUser(this.app, uid, message);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async setOtherUserGuildSession(params: { roleId: string, userGuild: UserGuildType}[]) {
try {
let sessionService = this.app.get('sessionService');
for(let {roleId, userGuild} of params) {
let sessions = sessionService.getByUid(roleId);
if(!!sessions) {
sessions.forEach(session => {
if(userGuild && userGuild.status == 1) {
sessionService.aimportAll(session.id, { guildCode: userGuild?.guildCode, guildAuth: userGuild?.auth });
} else {
sessionService.aimportAll(session.id, { guildCode: '', guildAuth: 0 });
}
})
}
}
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async setOtherUserSession(params: { roleId: string, roleName?: string, blockType?: number, vipStartTime?: number}[]) {
try {
let sessionService = this.app.get('sessionService');
for(let {roleId, roleName, blockType, vipStartTime} of params) {
let sessions = sessionService.getByUid(roleId);
if(!!sessions) {
sessions.forEach(session => {
if(roleName) sessionService.aimportAll(session.id, { roleName });
if(blockType) sessionService.aimportAll(session.id, { blockType });
if(vipStartTime) sessionService.aimportAll(session.id, { vipStartTime });
});
}
}
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
/**
* 重载json资源
*/
public async reloadResources(type?: string) {
try {
reloadResources(type);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async setDicParam(field1: string, field2: string, value: string|number) {
try {
if(dicParam[field1] && dicParam[field1][field2]) dicParam[field1][field2] = value;
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async setGameDataToApp() {
try {
this.app.set('gameData', gameData);
this.app.set('dicParam', dicParam);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public setServerMainten(serverIds: number[], startTime: number, endTime: number, version: string) {
try {
setServerMainten(serverIds, startTime, endTime, version);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public stopServerMainten(serverIds: number[]) {
try {
stopServerMainten(serverIds);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public getServerMainten(serverId: number) {
try {
return getServerMainten(serverId);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async setPvpSeasonNum(pvpConfig: PVPConfigType) {
try {
await setPvpSeasonNum(pvpConfig);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async setPvpSettleSeasonNum(pvpConfig: PVPConfigType) {
try {
await setPvpSettleSeasonNum(pvpConfig);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
/**
* 改变字典表中的拍卖行时间
*/
async setDicAuctionTime(startTime: number, endActivity: number, startGuild: number, endGuild: number, startWorld: number, endWorld: number) {
try {
setDicAuctionTime(startTime, endActivity, startGuild, endGuild, startWorld, endWorld);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public taflush() {
try {
return taflush();
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
async setDay(week: number) {
try {
setWeek(week);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
/**
* 改变字典表中的军团活动开始时间&持续时间
* @param {number} aid 活动
* @param {number} startSeconds 从现在开始几秒后开启活动
* @param {number} endSeconds 从开始之后几秒后结束活动
*/
public async setDicGuildActivity(now: number, aid: number, startSeconds: number, endSeconds: number) {
try {
setDicGuildActivity(now, aid, startSeconds, endSeconds);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async incServerNum(sid: string, inc: number) {
try {
incServerNum(sid, inc);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public savePvpSeasonMemory() {
try {
return savePvpSeasonMemory();
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async setApiIsClose(isClose: boolean) {
try {
setApiIsClose(isClose);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async setHiddenData(heroes: number[], goods: number[], refTime: number) {
try {
setHiddenData(heroes, goods, refTime);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async setKvToMemory(originK: string, originV: string, aesKey: string, aesIV: string, now: number) {
try {
setKvToMemory(originK, originV, aesKey, aesIV, now);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async setServerGroup() {
try {
return setServerGroup();
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async fun() {
try {
console.log('预留一个函数,用于之后线上维护时需要使用');
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
}