import { pinus } from "pinus"; import { GVGConfigModel, GVGConfigType } from "../../db/GVGConfig"; import { getSeconds, getTimeFun, nowSeconds, WEEK_TO_SECOND } from "../../pubUtils/timeUtil"; import { getServerCreateTime } from "../redisService"; import { GVG_PERIOD, GVG_SERVER_TYPE, LEAGUE_JOB, PUSH_ROUTE } from "../../consts"; import { GVGLeagueModel, GVGLeagueType } from "../../db/GVGLeague"; import { GVGLeaguePrepareModel } from "../../db/GVGLeaguePrepare"; import { gameData } from "../../pubUtils/data"; import { getRandSingleEelm } from "../../pubUtils/util"; import { GVG } from "../../pubUtils/dicParam"; import { GuildModel, GuildType } from "../../db/Guild"; import { GVGLeagueApplyModel } from "../../db/GVGLeagueApply"; import { GVGMainData, LeagueContributeInfo } from "../../domain/gvgField/returnData"; import { Contribute, GVGUserDataModel, GVGUserDataType } from "../../db/GVGUserData"; import { GVGUserItemModel } from "../../db/GVGUserItem"; import { GVGUserTaskModel } from "../../db/GVGUserTask"; import { getMyAuth } from "./gvgTeamService"; import { pick } from "underscore"; import { calFighterContribute, calProducerContribute } from "./gvgPrepareService"; import { calVestigeLeagueBoxRewards, getFightTimeByPeriod } from "./gvgFightService"; import { GVGVestigeLeagueRankModel } from "../../db/GVGVestigeLeagueRank"; import { GVGVestigeSumRankModel } from "../../db/GVGVestigeSumRank"; import { GVGTeamModel } from "../../db/GVGTeam"; import { sendMessageToGuildWithSuc } from "../pushService"; import { GVGCityModel } from "../../db/GVGCity"; import { GVGRoleDataModel } from "../../db/GVGRoleData"; import { getGVGGroupIdOfServer } from "../serverService"; import { UserGuildModel } from "../../db/UserGuild"; // 定时器相关 export async function createNewGVGConfig() { let { teamTime, prepareTime, battleTime, scheduleTime } = getPeriodTime(); const config = await GVGConfigModel.createNewConfig(teamTime, prepareTime, battleTime, scheduleTime); try { await pinus.app.rpc.guild.guildRemote.setGVGConfig.broadcast(config); await pinus.app.rpc.guild.guildRemote.setServerGroup.broadcast(); await pinus.app.rpc.chat.chatRemote.setServerGroup.broadcast(); await pinus.app.rpc.connector.connectorRemote.setServerGroup.broadcast(); await pinus.app.rpc.gm.gmRemote.setServerGroup.broadcast(); await pinus.app.rpc.systimer.systimerRemote.setServerGroup.broadcast(); await pinus.app.rpc.guild?.guildRemote?.clearBattleMemory.broadcast(); } catch(e) { console.log('remote未初始完'); } // 每周自动解散一些联军 let autoLeagues = await GVGLeagueModel.findAutoCreateLeague(); let needDissmissLeagueId: string[] = [], needDissmissLeagueCodes: string[] = []; for(let league of autoLeagues) { let groupKey = await getGroupKey(league.serverId); if(!await GVGCityModel.checkLeagueHasGuard(groupKey, league.leagueCode)) { needDissmissLeagueId.push(league._id); needDissmissLeagueCodes.push(league.leagueCode); } } await GVGLeagueModel.dismissByIds(needDissmissLeagueId); await GuildModel.leagueAutoDismiss(needDissmissLeagueCodes); for(let league of autoLeagues) { if(needDissmissLeagueCodes.indexOf(league.leagueCode) == -1) continue; for(let guildCode of league.guildCodes) { await sendMessageToGuildWithSuc(guildCode, PUSH_ROUTE.LEAGUE_DISSMISS, { leagueCode: league.leagueCode }) } } await pinus.app.rpc.systimer.systimerRemote.initGVGConfigSchedule.broadcast(); return config; } // 获取各个周期的时间,大约每周日5点的时候刷的 export function getPeriodTime() { let now = new Date(); let curDay = now.getDay(); // 今天星期几 let teamConfig = gameData.gvgPeriod.get(GVG_PERIOD.TEAM); let prepareConfig = gameData.gvgPeriod.get(GVG_PERIOD.PREPARE); let battleConfig = gameData.gvgPeriod.get(GVG_PERIOD.BATTLE); // 如果现在是周日,那么就是本周期的组队开始时间,如果是其他日子(启动初始化),就是下周期的组队开始时间 let _teamTime = getTimeFun().getTimeWithWeek(teamConfig.startDay); let _prepareTime = getTimeFun().getTimeWithWeek(prepareConfig.startDay); let _battleTime = getTimeFun().getTimeWithWeek(battleConfig.startDay); console.log('_teamTime: ', _teamTime); let teamTime = curDay == 0? _teamTime: _teamTime - 7 * 86400; let prepareTime = curDay == 0? _prepareTime + 7 * 86400: _prepareTime; let battleTime = curDay == 0? _battleTime + 7 * 86400: _battleTime; let scheduleTime = teamTime + 7 * 86400; return { teamTime, prepareTime, battleTime, scheduleTime } } export async function getGVGConfigFromRemote() { let serverType = pinus.app.getServerType(); if(serverType == 'guild') { return getGVGConfig(); } else { let guildServers = pinus.app.getServersByType('guild'); let server = getRandSingleEelm(guildServers); return await pinus.app.rpc.guild.guildRemote.getGVGConfig.toServer(server.id); } } export async function setGVGConfig(config?: GVGConfigType) { if(!config) { config = await GVGConfigModel.findConfig(); } if(config.teamTime > nowSeconds()) { config = null; } pinus.app.set('gvgConfigId', config?.configId||0); pinus.app.set('gvgTeamTime', config?.teamTime||0); pinus.app.set('gvgPrepareTime', config?.prepareTime||0); pinus.app.set('gvgBattleTime', config?.battleTime||0); pinus.app.set('gvgScheduleTime', config?.scheduleTime||0); } /** * 获取当前的赛期id * @returns */ export function getGVGConfig() { let configId: number = pinus.app.get('gvgConfigId'); let teamTime: number = pinus.app.get('gvgTeamTime'); let prepareTime: number = pinus.app.get('gvgPrepareTime'); let battleTime: number = pinus.app.get('gvgBattleTime'); let scheduleTime: number = pinus.app.get('gvgScheduleTime'); return { configId, teamTime, prepareTime, battleTime, scheduleTime } } export function getServerTypeByTime(openTime: number) { let today = nowSeconds(); if(today - openTime < WEEK_TO_SECOND) return GVG_SERVER_TYPE.NO; let toWeek = getCurrentTeamTime(today); let openWeek = getCurrentTeamTime(openTime); let n = Math.floor((toWeek - openWeek) / WEEK_TO_SECOND); let day = new Date(openTime * 1000).getDay(); if(day == 6) n--; // 周六开服的服务器延后一周开启跨服 return n <= GVG.GVG_CROSS_SERVICE_STARTTIME? GVG_SERVER_TYPE.SINGLE: GVG_SERVER_TYPE.MULTI; } function getCurrentTeamTime(time: number) { let teamConfig = gameData.gvgPeriod.get(GVG_PERIOD.TEAM); // 本周日 let _teamTime = getTimeFun(time).getTimeWithWeek(teamConfig.startDay, teamConfig.startHour, teamConfig.startMinute, teamConfig.startSecond); return _teamTime > time? _teamTime - WEEK_TO_SECOND: _teamTime; } export async function getGVGServerType(serverId: number) { let openTime = await getServerCreateTime(serverId); return getServerTypeByTime(openTime) } export function getGVGPeriodData() { let { configId, teamTime, prepareTime, battleTime, scheduleTime } = getGVGConfig(); let period = getCurPeriod(); let countdownTime = teamTime; switch(period) { case GVG_PERIOD.TEAM: { countdownTime = prepareTime; break; } case GVG_PERIOD.PREPARE: { countdownTime = battleTime; break; } case GVG_PERIOD.BATTLE: { countdownTime = scheduleTime; break; } } // console.log('######## getGVGPeriodData', configId, teamTime, prepareTime, battleTime, scheduleTime) return { configId, period, countdownTime }; } export function getCurPeriod() { let { teamTime, prepareTime, battleTime, scheduleTime } = getGVGConfig(); return getPeriodByTime(teamTime, prepareTime, battleTime, scheduleTime) } export function getPeriodByTime(teamTime: number, prepareTime: number, battleTime: number, scheduleTime: number) { let now = nowSeconds(); if(now >= teamTime && now < prepareTime) { return GVG_PERIOD.TEAM; } else if (now >= prepareTime && now < battleTime) { return GVG_PERIOD.PREPARE; } else if (now >= battleTime && now < scheduleTime){ return GVG_PERIOD.BATTLE; } else { return GVG_PERIOD.NO; } } export async function initLeaguePrepare() { const config = await GVGConfigModel.findConfig(); if(!config) return; const leagues = await GVGLeagueModel.findAllLeague(); let groupKeyByServerId = new Map(); for(let { leagueCode, memberCnt, serverId } of leagues) { let groupKey = groupKeyByServerId.get(serverId); if(!groupKey) { groupKey = await getGroupKey(serverId); groupKeyByServerId.set(serverId, groupKey); } await GVGLeaguePrepareModel.initData(config.configId, groupKey, leagueCode, memberCnt); } } export async function getGVGInfoInGuild(roleId: string, guild: GuildType) { let hasLeague = !!guild.leagueCode; let serverId = guild.serverId; let { configId, period, countdownTime } = getGVGPeriodData(); let { startFightTime, endFightTime } = getFightTimeByPeriod(period); let type = await getGVGServerType(serverId); if(hasLeague && configId > 0) { return { hasLeague, configId, period, countdownTime, type, applyCnt: await getApplyCnt(guild.leagueCode), ...await getMainData(roleId, guild.leagueCode, configId, period, countdownTime, type), leagueDetailRank: await getLeagueRankBox(configId, guild.leagueCode, roleId), myTeamCnt: await GVGTeamModel.getTeamCntByRole(roleId), startFightTime, endFightTime } } else { return { hasLeague, configId, period, countdownTime, startFightTime, endFightTime, type, invitationCnt: await getInviteCnt(guild.code) } } } export async function calLeagueCe(league: GVGLeagueType) { const guildCodes = league?.guildCodes||[]; const guilds = await GuildModel.findByCodes(guildCodes); return guilds.reduce((pre, guild) => pre + guild.guildCe, 0); } // 检查当前赛季阶段 export async function checkGVGPeriod(p : GVG_PERIOD) { let { period } = getGVGPeriodData(); return period == p; } // —————— 红点相关 —————— // // 邀请 export async function getInviteCnt(guildCode: string) { let invitation = await GVGLeagueApplyModel.findInviteFromGuildWithoutPopulate(guildCode); return invitation.length } // 申请 export async function getApplyCnt(leagueCode: string) { let applies = await GVGLeagueApplyModel.findApplyFromLeagueWithoutPopulate(leagueCode); return applies.length } export async function getMainData(roleId: string, leagueCode: string, configId: number, period: number, countdownTime: number, serverType: number) { let data = new GVGMainData(configId, period, countdownTime, serverType); let league = await GVGLeagueModel.findByCode(leagueCode); if(league) { data.setLeague(league, {}); let leaguePrepare = await GVGLeaguePrepareModel.findByLeague(configId, league.leagueCode); data.setLeagueParpare(leaguePrepare); data.setTechQueue(leaguePrepare?.techQueue||[]); let userData = await GVGUserDataModel.findByRole(configId, league.leagueCode, roleId); let roleData = await GVGRoleDataModel.findByRole(configId, roleId); let items = await GVGUserItemModel.findByRole(configId, league.leagueCode, roleId); let tasks = await GVGUserTaskModel.findByRole(configId, league.leagueCode, roleId); data.setPlayerInfo(userData, roleData, getMyAuth(league, roleId), undefined, undefined, items, tasks); data.setLeagueCe(await calLeagueCe(league)); data.setConstribute(await getContribute(userData)); } let myInfo = pick(data.myInfo, ['auth', 'items', 'tasks', 'receivedLv']); return { ...pick(data, ['guildCnt', 'leagueLv', 'techQueue', 'constribute']), myInfo } } export async function getContribute(myUserData: GVGUserDataType) { const { contribute = new Contribute(), box = [] } = myUserData||{}; const result: LeagueContributeInfo[] = []; for(let curJob of [LEAGUE_JOB.PRODUCER, LEAGUE_JOB.FIGHTER]) { let sumContribute = curJob == LEAGUE_JOB.PRODUCER? calProducerContribute(contribute): calFighterContribute(contribute); let boxReceived = box.filter(boxId => { let dicBox = gameData.gvgContributeBox.get(boxId); return dicBox.job == curJob; }); let disObj = new LeagueContributeInfo(curJob, sumContribute, boxReceived); result.push(disObj) } return result; } export async function getLeagueRankBox(configId: number, leagueCode: string, roleId: string) { let joinTime = await getMemberJoinLeagueTime(leagueCode, roleId); let canReceiveLeagueRanks = await GVGVestigeLeagueRankModel.getCanReceiveRanks(configId, leagueCode, roleId, joinTime); let canReceivePlayerRanks = await GVGVestigeSumRankModel.getCanReceiveRanks(configId, roleId); let { canReceiveBox } = calVestigeLeagueBoxRewards(canReceiveLeagueRanks, canReceivePlayerRanks); return { canReceiveBox } } export async function getGroupKey(serverId: number) { let serverType = await getGVGServerType(serverId); if(serverType == GVG_SERVER_TYPE.SINGLE) { return `s${serverId}`; } else { let groupId = await getGVGGroupIdOfServer(serverId); return `g${groupId}`; } } /** * 之前gvgLeague表的members没有记录加入联军时间,所以如果查询没有time的话,根据userGuild的time来更新一下这个数据 * * 获取玩家加入联军时间 * @param leagueCode 联军id * @param roleId * @param league 联军表数据 * @returns */ export async function getMemberJoinLeagueTime(leagueCode: string, roleId: string, league?: GVGLeagueType) { if(!league) league = await GVGLeagueModel.findByCode(leagueCode, 'members'); let members = league?.members||[]; let member = members.find(cur => cur.roleId == roleId); if(!member) return 0; if(!member.time) { let userGuild = await UserGuildModel.getMyGuild(roleId, 'createdAt'); let time = getSeconds(userGuild.createdAt); await GVGLeagueModel.setMemberTime(leagueCode, roleId, time); return time; } return member.time; }