import { scheduleJob, Job, } from 'node-schedule'; import { PVPConfigModel, PVPConfigType } from '../db/SystemConfig'; import { nowSeconds, getTimeFun } from '../pubUtils/timeUtil'; import { getTodayGuildActivity, gameData } from '../pubUtils/data'; import { pvpSeasonEnd } from './pvpService'; import { getAllOnlineRoles, getAllServers, delGuildActivityRank } from './redisService'; import { GUILD_ACTIVITY_TYPE, REFRESH_TIME, SEND_NAME, SERVER_OPEN_TIME, COUNTER, AUCTION_TIME } from '../consts'; import { RoleModel } from '../db/Role'; import { pinus } from 'pinus'; import { indexOf } from 'underscore'; import { PvpSeasonResultModel } from '../db/PvpSeasonResult'; import { settleGuildWeekly } from './guildService'; import { sendMailByContent } from './mailService'; import { getGuildActivityByDic, sendEndMsgToAll, autoDeclare, sendGuildActivityStatus } from './guildActivityService'; import { sendUngotDividendJob, startGuildAuction, startWorldAuction, stopAuction } from './auctionService'; import { DicGuildActivity } from '../pubUtils/dictionary/DicGuildActivity'; import { dispatch } from '../pubUtils/dispatcher'; import { Rank } from './rankService'; import { checkTask } from './taskService'; import { everydayRefresh } from './connectorService'; import { initMarquee, initMaintenance } from './gmService'; import moment = require('moment'); import { CounterModel } from '../db/Counter'; import { reportOneOnline } from './authenticateService'; const PER_SECOND = 1 * 1000; const PER_DAY = 24 * 60 * 60; const SETTLE_DIFF_SECONDS = 29 * 60; const PER_MINUTE = 1 * 60; var seasonMakeRewardTimJobId: Job; var warJobId: Job; var seasonRefreshTimeJobId: Job; let guildWeeklyJobId: Job; let guildActStartJobId: Job; // 军团活动开启后每10(or 1)秒循环的定时任务,到结束活动清除 let guildActSecondsJobId: Job; // 军团活动开启后每10(or 1)秒循环的定时任务,到结束活动清除 let guildActEndJobId: Job; // 军团活动开启后每10(or 1)秒循环的定时任务,到结束活动清除 let pvpMakeRewardInterval = null; let pvpRefreshInterval = null; /** * 服务器启动即开启定时任务,结算时常是23-24点,实际结算的时间点是23:31分钟 */ export async function init() { // pvp赛季 await setPvpSeason(); // 周功勋结算任务 guildWeeklyJobId = scheduleJob('settleGuildWeekly', '0 0 0 * * 1', settleGuildWeekly); // 每5分钟汇报在线玩家在线情况 scheduleJob('reportOnline', '0 0/5 * * * *', reportOnlineSchedule); // 军团活动排行榜 guildActivitySchedule(); // 拍卖行刷新:拍卖阶段刷新,分红发放 auctionSchedule(); // 每天5点推送刷新时间消息 // 顺便每天0点计算前一天活跃玩家中位数战力 scheduleJob('everyDayRefresh', `0 0 ${REFRESH_TIME} * * ?`, everydayRefresh); // 跑马灯 await initMarquee(); // 维护信息 await initMaintenance(); } function getSeasonContinueDay(seasonNum: number) { const pvpSeasonDuring = [{seasonNum: 1, day: 7},{seasonNum: 2, day: 15},{seasonNum: 3, day: 30},]; let maxDay = 0; for(let {seasonNum: dicSeasonNum, day } of pvpSeasonDuring) { if(seasonNum == dicSeasonNum) return day; if(maxDay < day) maxDay = day; } return maxDay; } async function setPvpSeason() { let pvpConfig = await PVPConfigModel.findCurPVPConfig(); if(!pvpConfig || pvpConfig.seasonEndTime <= nowSeconds() ) { if(pvpConfig && !pvpConfig.hasSettleReward) { await pvpSeasonEnd(pvpConfig); } let lastSeasonNum = pvpConfig? pvpConfig.seasonNum: 0; let lastSeasonEndTime = pvpConfig? pvpConfig.seasonEndTime: 0; let newSeasonStartTime = lastSeasonEndTime; let during = getSeasonContinueDay(lastSeasonNum + 1) * PER_DAY; let rewardTime = SETTLE_DIFF_SECONDS; if(nowSeconds() - lastSeasonEndTime > during) { newSeasonStartTime = getTimeFun().getDayZeroPoint(0); } let newSeasonNum = await CounterModel.getNewCounter(COUNTER.PVP_SEASON_NUM); pvpConfig = await PVPConfigModel.createPVPConfig(newSeasonNum, newSeasonStartTime, newSeasonStartTime + during - rewardTime, newSeasonStartTime + during - PER_MINUTE); } await setPvpSeasonMakeRewardJob(pvpConfig); await setNextSeasonJob(pvpConfig); } async function setPvpSeasonMakeRewardJob(pvpConfig: PVPConfigType) { if (!!seasonMakeRewardTimJobId) { seasonMakeRewardTimJobId.cancel(); } if(pvpConfig.seasonRewardTime < nowSeconds() && !pvpConfig.hasSettleReward) { // 未发奖励 await pvpSeasonEnd(pvpConfig); } else { seasonMakeRewardTimJobId = scheduleJob('seasonMakeRewardTimJobId', pvpConfig.seasonRewardTime, async () => { await pvpSeasonEnd(pvpConfig); }); } } async function setNextSeasonJob(pvpConfig: PVPConfigType) { if (!!seasonRefreshTimeJobId) { seasonRefreshTimeJobId.cancel(); } //定时开启新赛季,比seasonEndTime多定一分钟,保证定时器时间没错 seasonRefreshTimeJobId = scheduleJob('seasonRefreshTimeJobId', pvpConfig.seasonEndTime + PER_MINUTE, setPvpSeason); } /** * debug接口 * @param hour */ export async function resetPvpSeasonTime(hour: number) { await PVPConfigModel.setCurPvpConfig({ seasonEndTime: getTimeFun().getDayZeroPoint(0) }); return await setPvpSeason(); } export async function reportOnlineSchedule() { let allRoles = await getAllOnlineRoles(); console.log('reportOnlineSchedule all roles count: ', allRoles.length) for (let { roleId, userCode, sid } of allRoles) { let result = reportOneOnline(roleId, userCode, sid, false); if (!result) continue; } } /** * 军团活动,每晚8点开启 */ export async function guildActivitySchedule() { /***********guildActivitySchedule***********/ if (guildActStartJobId) { guildActStartJobId.cancel(); } if (guildActSecondsJobId) { guildActSecondsJobId.cancel(); guildActSecondsJobId = undefined; } if (guildActEndJobId) { guildActEndJobId.cancel(); guildActEndJobId = undefined; } let dicGuildActivity = getTodayGuildActivity(); await delGuildActivityRank(dicGuildActivity.id); console.log(dicGuildActivity) guildActStartJobId = scheduleJob('guildActivityStart', `${dicGuildActivity.startSeconds} ${dicGuildActivity.startMinute} ${dicGuildActivity.startTime} * * ?`, guildActivityStartSchedule); } // 军团晚间活动,每天8点开始 async function guildActivityStartSchedule() { await guildActivityStart(); } export async function guildActivityStart(dicGuildActivity?: DicGuildActivity) { console.log('*******开始军团晚间活动****') if (!dicGuildActivity) dicGuildActivity = getTodayGuildActivity(); if (!dicGuildActivity) return; console.log('********', dicGuildActivity.id, Date.now() + dicGuildActivity.duringTime * 1000) let servers = await getAllServers(); // 玩家serverId列表 if (dicGuildActivity.id == GUILD_ACTIVITY_TYPE.GATE_ACTIVITY) { guildActSecondsJobId = scheduleJob('guildActivitySeconds', '*/10 * * * * *', gateActivitySeconds); // 结束时间 guildActEndJobId = scheduleJob('guildActivityEnd', Date.now() + dicGuildActivity.duringTime * 1000, gateActivityEnd); } else if (dicGuildActivity.id == GUILD_ACTIVITY_TYPE.CITY_ACTIVITY) { guildActSecondsJobId = scheduleJob('guildActivitySeconds', '*/10 * * * * *', cityActivitySeconds); // 结束时间 guildActEndJobId = scheduleJob('guildActivityEnd', Date.now() + dicGuildActivity.duringTime * 1000, cityActivityEnd); } else if (dicGuildActivity.id == GUILD_ACTIVITY_TYPE.RACE_ACTIVITY) { // 开始活动 let guildServers = pinus.app.getServersByType('guild'); for (let serverId of servers) { let sid = dispatch(serverId.toString(), guildServers, 'guild'); await pinus.app.rpc.guild.guildActivityRemote.raceActivityStart.toServer(sid.id, serverId); } guildActSecondsJobId = scheduleJob('guildActivitySeconds', '*/1 * * * * *', raceActivitySeconds); // 结束时间 guildActEndJobId = scheduleJob('guildActivityEnd', Date.now() + dicGuildActivity.duringTime * 1000, raceActivityEnd); } for (let serverId of servers) { await sendGuildActivityStatus(serverId); } return true; } // 蛮夷入侵 // 结束军团活动 export async function gateActivityEnd() { console.log('*****gateActivityEnd'); await sendEndMsgToAll(); await pinus.app.rpc.guild.guildActivityRemote.guildActivityEnd.broadcast(GUILD_ACTIVITY_TYPE.GATE_ACTIVITY); if (guildActSecondsJobId) { guildActSecondsJobId.cancel(); guildActSecondsJobId = undefined; } if (guildActEndJobId) { guildActEndJobId.cancel(); guildActEndJobId = undefined; } } // 每10秒下发一次的任务 export async function gateActivitySeconds() { console.log('*****gateActivitySeconds') await pinus.app.rpc.guild.guildActivityRemote.sendRankToGuilds.broadcast(GUILD_ACTIVITY_TYPE.GATE_ACTIVITY); } // 诸侯混战 // 结束军团活动 export async function cityActivityEnd() { console.log('*****cityActivityEnd'); await sendEndMsgToAll(); await pinus.app.rpc.guild.guildActivityRemote.guildActivityEnd.broadcast(GUILD_ACTIVITY_TYPE.CITY_ACTIVITY); // 发完之后再做下周自动宣战 let serverlists = await getAllServers(); for (let serverId of serverlists) { await autoDeclare(serverId); } if (guildActSecondsJobId) { guildActSecondsJobId.cancel(); guildActSecondsJobId = undefined; } if (guildActEndJobId) { guildActEndJobId.cancel(); guildActEndJobId = undefined; } } // 每10秒下发一次的任务 export async function cityActivitySeconds() { console.log('*****cityActivitySeconds') await pinus.app.rpc.guild.guildActivityRemote.sendRankToGuilds.broadcast(GUILD_ACTIVITY_TYPE.CITY_ACTIVITY); } // 粮草先行 // 结束军团活动 export async function raceActivityEnd() { console.log('*****raceActivityEnd'); await sendEndMsgToAll(); await pinus.app.rpc.guild.guildActivityRemote.guildActivityEnd.broadcast(GUILD_ACTIVITY_TYPE.RACE_ACTIVITY); if (guildActSecondsJobId) { guildActSecondsJobId.cancel(); guildActSecondsJobId = undefined; } if (guildActEndJobId) { guildActEndJobId.cancel(); guildActEndJobId = undefined; } } // 每10秒下发一次的任务 export async function raceActivitySeconds() { console.log('*****raveActivitySeconds') let servers = await getAllServers(); // 玩家serverId列表 let guildServers = pinus.app.getServersByType('guild'); for (let serverId of servers) { let sid = dispatch(serverId.toString(), guildServers, 'guild'); await pinus.app.rpc.guild.guildActivityRemote.calWoodenHorseAndSend.toServer(sid.id, serverId); } } let startGuildAuctionJobId: Job; let startWorldAuctionJobId: Job; let stopAuctionJobId: Job; let sendUngotDividendJobId: Job; export function auctionSchedule() { clearAuctionSchedule(); let guildOpen = gameData.auctionTime.get(AUCTION_TIME.GUILD_OPEN); let worldOpen = gameData.auctionTime.get(AUCTION_TIME.WORLD_OPEN); let worldClose = gameData.auctionTime.get(AUCTION_TIME.WORLD_CLOSE); console.log('***** auctionSchedule', guildOpen.hour, guildOpen.minute, guildOpen.seconds); console.log('***** auctionSchedule', worldOpen.hour, worldOpen.minute, worldOpen.seconds); console.log('***** auctionSchedule', worldClose.hour, worldClose.minute, worldClose.seconds); startGuildAuctionJobId = scheduleJob('startGuildAuction', `${guildOpen.seconds} ${guildOpen.minute} ${guildOpen.hour} * * ?`, startGuildAuction); startWorldAuctionJobId = scheduleJob('startWorldAuction', `${worldOpen.seconds} ${worldOpen.minute} ${worldOpen.hour} * * ?`, startWorldAuction); stopAuctionJobId = scheduleJob('stopAuction', `${worldClose.seconds} ${worldClose.minute} ${worldClose.hour} * * ?`, stopAuction); sendUngotDividendJobId = scheduleJob('sendUngotDividendJob', '0 0 5 00 * ?', sendUngotDividendJob); } function clearAuctionSchedule() { if (startGuildAuctionJobId) { startGuildAuctionJobId.cancel(); startGuildAuctionJobId = undefined; } if (startWorldAuctionJobId) { startWorldAuctionJobId.cancel(); startWorldAuctionJobId = undefined; } if (stopAuctionJobId) { stopAuctionJobId.cancel(); stopAuctionJobId = undefined; } if (sendUngotDividendJobId) { sendUngotDividendJobId.cancel(); sendUngotDividendJobId = undefined; } }