diff --git a/game-server/app/servers/connector/handler/entryHandler.ts b/game-server/app/servers/connector/handler/entryHandler.ts index be5262a15..465485c1a 100644 --- a/game-server/app/servers/connector/handler/entryHandler.ts +++ b/game-server/app/servers/connector/handler/entryHandler.ts @@ -23,7 +23,7 @@ import { addRoleToGuildChannel, addRoleToSysChannel, addRoleToWorldChannel, leav import { reportOneOnline } from '../../../services/timeTaskService'; import { Rank } from '../../../services/rankService'; import { checkTaskWithRole, getCurTask } from '../../../services/taskService'; -import { pushData } from '../../../services/connectorService'; +import { pushData, everydayRefresh } from '../../../services/connectorService'; export default function (app: Application) { return new EntryHandler(app); @@ -174,6 +174,34 @@ export class EntryHandler { 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.findByRoleId(roleId, null, true, true); + if (!role) { + return resResult(STATUS.ROLE_NOT_FOUND); + } + + let { serverId } = role; + // 任务 + checkTaskWithRole(serverId, role.roleId, self.app.get('serverId'), role.funcs, TASK_TYPE.LOGIN_SUM, role); + checkTaskWithRole(serverId, role.roleId, self.app.get('serverId'), role.funcs, TASK_TYPE.LOGIN_SERIES, role); + // 推送数据 + pushData(role, session, 'refresh'); + + let todayZeroPoint = getZeroPoint(); + return resResult(STATUS.SUCCESS, { todayZeroPoint }); + } + + /** * User log out handler * @@ -295,4 +323,15 @@ export class EntryHandler { console.log('debugQueryTokenById got user:', user); return resResult(STATUS.SUCCESS, { user }); } + + async debugPushRefToOnlineUsers(msg: { magicWord: string }, session: FrontendSession) { + const { magicWord } = msg; + console.log('debugQueryTokenById msg:', msg); + if (magicWord !== DEBUG_MAGIC_WORD) { + return resResult(STATUS.TOKEN_ERR); + } + await everydayRefresh(); + + return resResult(STATUS.SUCCESS); + } } \ No newline at end of file diff --git a/game-server/app/services/connectorService.ts b/game-server/app/services/connectorService.ts index 29a254778..b5812e602 100644 --- a/game-server/app/services/connectorService.ts +++ b/game-server/app/services/connectorService.ts @@ -8,7 +8,7 @@ import { getCurTask } from './taskService'; import { RoleType } from '../db/Role'; import { FrontendOrBackendSession, pinus } from 'pinus'; import { resResult } from '../pubUtils/util'; -import { STATUS, USER_GUILD_SELECT, GUILD_SELECT } from '../consts'; +import { STATUS, PUSH_BATCH, PUSH_INTERVAL } from '../consts'; import { getAllShopList } from './shopService'; import { getGeneralRank } from './rankService'; import { getFriendList, getApplyList } from './friendService'; @@ -18,7 +18,7 @@ import { getTowerStatus, getHungupRewards, getTasks } from './battleService'; import { getAllAssistCnt } from './comBattleService'; import { getDungeonData } from './dungeonService'; import { PvpSeasonResultModel } from '../db/PvpSeasonResult'; -import { nowSeconds } from '../pubUtils/timeUtil'; +import { nowSeconds, getZeroPoint } from '../pubUtils/timeUtil'; import { getGachaList } from './gachaService'; import { getSchoolList } from './roleService'; import { addRoleToGuildChannel } from './chatChannelService'; @@ -29,93 +29,106 @@ import { BossInstanceModel } from '../db/BossInstance'; import { getBossInstanceInfo } from './guildBossService'; import { getEvent } from './eventSercive'; import { getBattleListOfMain } from './normalBattleService'; +import { GuildType } from '../db/Guild'; +import UserGuild, { UserGuildType } from '../db/UserGuild'; +import { setMedianCe } from './guildActivityService'; +import { getAllOnlineRoles } from './redisService'; -export async function pushData(role: RoleType, session: FrontendOrBackendSession) { +export async function pushData(role: RoleType, session: FrontendOrBackendSession, pushType: 'entry'|'refresh' = 'entry') { try{ - const { roleId, serverId, roleName, guildCode } = role; + const { roleId } = role; const sid = session.get('sid'); pushEntryStart(roleId, sid); - - // 商店 - const shop = await getAllShopList(roleId); - pushEntryData('shop', roleId, sid, shop); - // 排行榜 - const rank = await getGeneralRank(role, serverId); - pushEntryData('rank', roleId, sid, rank); - // 邮件 - const mails = await getMails(roleId, serverId); - pushEntryData('mail', roleId, sid, mails); - // 好友 - const friendList = await getFriendList(role); - const applyList = await getApplyList(roleId); - pushEntryData('friend', roleId, sid, { friendList, applyList }); - // 每日关卡 - const daily = await getDailyBattleList(role); - pushEntryData('daily', roleId, sid, daily); - // 远征 - const expedition = await getExpeditionStatus(roleId, roleName); - pushEntryData('expedition', roleId, sid, expedition); - // 镇念塔 - const tower = await getTowerEntryData(role); - pushEntryData('tower', roleId, sid, tower); - // 寻宝 - const assistCnt = await getAllAssistCnt(roleId); - pushEntryData('comBattle', roleId, sid, { assistCnt }) - // 秘境 - const dungeon = await getDungeonData(role); - pushEntryData('dungeon', roleId, sid, dungeon); - // PVP - const hasSeasonReward = await getPvpEntryData(roleId); - pushEntryData('pvp', roleId, sid, { hasSeasonReward }); - // 招募 - const gacha = await getGachaList(roleId); - pushEntryData('gacha', roleId, sid, gacha); - // 百家学宫 - const school = await getSchoolList(roleId); - pushEntryData('school', roleId, sid, school); // 军团 - const { hasGuild, guild, userGuild, guildResult } = await getGuildEntryData(role, sid, session); - if(hasGuild) { - pushEntryData('guild', roleId, sid, guildResult); - // 拍卖 - const auction = await getAuction(guildCode, session); - pushEntryData('auction', roleId, sid, auction); - // 练兵场 - const train = await getGuildTrainInstance(roleId, guild, userGuild); - pushEntryData('train', roleId, sid, train); - // 演武台boss - const bossInstance = await BossInstanceModel.findBossInstance(guild.code); - if(bossInstance) { - const boss = await getBossInstanceInfo(bossInstance, roleId); - pushEntryData('boss', roleId, sid, boss); - } - // 许愿池 - const wishPool = await getWishPool(userGuild); - pushEntryData('wishPool', roleId, sid, wishPool); + const guildData = await getGuildEntryData(role, sid, session); + let modules = ['shop', 'rank', 'mail', 'friend', 'daily', 'expedition', 'tower', 'comBattle', 'dungeon', 'pvp', 'gacha', 'school', 'task', 'chat', 'event', 'battle']; + if(guildData.hasGuild) { + modules.push('guild', 'auction', 'train', 'boss', 'wishPool'); + } + let notIncludeModule: string[] = []; + if(pushType == 'refresh') { + notIncludeModule = ['rank', 'mail', 'school', 'auction', 'train', 'chat', 'battle']; } - // 任务 - const { mainTask, dailyTask, achievement } = await getCurTask(role.roleId, session); - pushEntryData('task', roleId, sid, { mainTask, dailyTask, achievement }); - // 聊天 - const worldMsgs = await recentWorldMsgs(serverId); - const sysMsgs = await recentSysMsgs(serverId); - const guildMsgs = await recentGuildMsgs(guildCode); - const recentPrivateChats = await recentPrivateChatInfos(roleId, roleName); - pushEntryData('chat', roleId, sid, { worldMsgs, sysMsgs, guildMsgs, recentPrivateChats }); - // 奇遇 - const event = await getEvent(role.eventStatus, roleId, roleName); - pushEntryData('event', roleId, sid, event); - // 主线关卡列表 - const battle = await getBattleListOfMain(role); - pushEntryData('battle', roleId, sid, battle); + for(let type of modules) { + if(notIncludeModule.indexOf(type) == -1) { + let data = await getModuleData(type, { role, session }, guildData); + pushEntryData(type, roleId, sid, data); + } + } pushEntryEnd(roleId, sid); }catch(e) { console.error(e.stack); } } + async function getModuleData(type: string, data: {role: RoleType, session: FrontendOrBackendSession}, guildData: { hasGuild: boolean, guild?: GuildType, userGuild?: UserGuildType, guildResult?: any} = { hasGuild: false }) { + let { role, session } = data; + const { roleId, serverId, roleName, guildCode } = role; + let { hasGuild, guild, userGuild, guildResult } = guildData; + switch(type) { + case 'shop': // 商店 + return await getAllShopList(roleId); + case 'rank': // 排名 + return await getGeneralRank(role, serverId); + case 'mail': // 邮件 + return await getMails(roleId, serverId); + case 'friend': // 好友 + const friendList = await getFriendList(role); + const applyList = await getApplyList(roleId); + return { friendList, applyList } + case 'daily': // 每日 + return await getDailyBattleList(role); + case 'expedition': // 远征 + return await getExpeditionStatus(roleId, roleName); + case 'tower': // 镇念塔 + return await getTowerEntryData(role); + case 'comBattle': // 寻宝 + const assistCnt = await getAllAssistCnt(roleId); + return { assistCnt } + case 'dungeon': // 秘境 + return await getDungeonData(role); + case 'pvp': // pvp + const hasSeasonReward = await getPvpEntryData(roleId); + return { hasSeasonReward } + case 'gacha': + return await getGachaList(roleId); + case 'school': + return await getSchoolList(roleId); + case 'guild': + return hasGuild? await guildResult: null; + case 'auction': + return hasGuild? await getAuction(guildCode, session): null; + case 'train': + return hasGuild? await getGuildTrainInstance(roleId, guild, userGuild): null; + case 'boss': + if(hasGuild) { + const bossInstance = await BossInstanceModel.findBossInstance(guild.code); + if(bossInstance) { + return await getBossInstanceInfo(bossInstance, roleId); + } + } + return null; + case 'wishPool': + return hasGuild? await getWishPool(userGuild): null; + case 'task': + return await getCurTask(role.roleId, session); + case 'chat': + const worldMsgs = await recentWorldMsgs(serverId); + const sysMsgs = await recentSysMsgs(serverId); + const guildMsgs = await recentGuildMsgs(guildCode); + const recentPrivateChats = await recentPrivateChatInfos(roleId, roleName); + return { worldMsgs, sysMsgs, guildMsgs, recentPrivateChats }; + case 'event': + return await getEvent(role.eventStatus, roleId, roleName); + case 'battle': + return await getBattleListOfMain(role); + default: + return null; + } + } + function pushEntryData(type: string, roleId: string, sid: string, param: T) { let uids = [{ uid: roleId, sid }]; let data = { type }; @@ -185,3 +198,24 @@ async function getGuildEntryData(role: RoleType, sid: string, session: FrontendO } return { hasGuild: false } } + +export async function everydayRefresh() { + let allOnlineUsers = await getAllOnlineRoles(); + let todayZeroPoint = getZeroPoint(); + let n = Math.ceil(allOnlineUsers.length / PUSH_BATCH); // 一共多少批 + console.log(n) + let i = -1; + let interval = setInterval(() => { + if(++i < n) { + let users = allOnlineUsers.slice(i * PUSH_BATCH, (i + 1) * PUSH_BATCH - 1); + for(let { roleId, sid } of users) { + pinus.app.channelService.pushMessageByUids('onRefreshTime', resResult(STATUS.SUCCESS, { + todayZeroPoint + } ), [{uid: roleId, sid: sid}]); + } + } else { + clearInterval(interval); + } + }, PUSH_INTERVAL) + setMedianCe(); +} \ No newline at end of file diff --git a/game-server/app/services/timeTaskService.ts b/game-server/app/services/timeTaskService.ts index 290c26f36..c677c2c09 100644 --- a/game-server/app/services/timeTaskService.ts +++ b/game-server/app/services/timeTaskService.ts @@ -26,6 +26,7 @@ import { GuildModel } from '../db/Guild'; import { dispatch } from '../util/dispatcher'; import { Rank } from './rankService'; import { checkTask } from './taskService'; +import { everydayRefresh } from './connectorService'; const PER_SECOND = 1 * 1000; const PER_DAY = 24 * 60 * 60; @@ -75,12 +76,13 @@ export async function init() { // 军团活动排行榜 guildActivitySchedule(); - // 每天0点计算前一天活跃玩家中位数战力 - scheduleJob('setMedian', '0 0 5 * * ?', setMedianCe); // 拍卖行刷新:拍卖阶段刷新,分红发放 auctionSchedule(); + // 每天5点推送刷新时间消息 + // 顺便每天0点计算前一天活跃玩家中位数战力 + scheduleJob('everyDayRefresh', `0 0 ${REFRESH_TIME} * * ?`, everydayRefresh); } function setPvpSeasonSchdule() { diff --git a/shared/consts/constModules/sysConst.ts b/shared/consts/constModules/sysConst.ts index a5255fcab..246f7cafa 100644 --- a/shared/consts/constModules/sysConst.ts +++ b/shared/consts/constModules/sysConst.ts @@ -17,6 +17,8 @@ export const GUEST_MAX_TIME = 60 * 60; // 游客体验时间 export const GUEST_DAY = 15; // 同一设备15天内不得重复体验游客模式 export const REFRESH_TIME = 5; // 统一一天刷新时间 +export const PUSH_BATCH = 100; // 推送分批人数 +export const PUSH_INTERVAL = 5 * 1000; // 分批时间,5秒一批 export enum TIME_OUTPUT_TYPE { DATE = 1, STAMP_10 = 2, diff --git a/shared/domain/activityField/signInField.ts b/shared/domain/activityField/signInField.ts index f11cd688a..51999ed40 100644 --- a/shared/domain/activityField/signInField.ts +++ b/shared/domain/activityField/signInField.ts @@ -1,5 +1,5 @@ import moment = require('moment'); -import { ACTIVITY_RESOURCES_TYPE, ACTIVITY_TYPE, SERVER_OPEN_TIME, SIGNIN_CLOSE, SIGNIN_OPEN } from '../../consts'; +import { ACTIVITY_TYPE, SERVER_OPEN_TIME, SIGNIN_CLOSE, SIGNIN_OPEN } from '../../consts'; import { ActivityModelType } from '../../db/Activity'; import { ActivitySignInModelType } from '../../db/ActivitySignIn'; import { deltaDays } from '../../pubUtils/util'; diff --git a/shared/domain/activityField/vipRechargeMoneyField.ts b/shared/domain/activityField/vipRechargeMoneyField.ts index 53707a2f1..4d4df4772 100644 --- a/shared/domain/activityField/vipRechargeMoneyField.ts +++ b/shared/domain/activityField/vipRechargeMoneyField.ts @@ -1,5 +1,3 @@ -import moment = require('moment'); -import { random } from 'underscore'; import { ActivityModelType } from '../../db/Activity'; import { ActivityVipRechargeMoneyModelType } from '../../db/ActivityVipRechargeMoney'; import { ActivityBase } from './activityField';