diff --git a/game-server/app/servers/guild/handler/gvgBattleHandler.ts b/game-server/app/servers/guild/handler/gvgBattleHandler.ts index 9826f2515..72dde409e 100644 --- a/game-server/app/servers/guild/handler/gvgBattleHandler.ts +++ b/game-server/app/servers/guild/handler/gvgBattleHandler.ts @@ -15,7 +15,7 @@ import { gameData, getReviveGold } from '../../../pubUtils/data'; import { getAllServerName } from '../../../services/redisService'; import { checkBattleHeroesByHid } from '../../../services/normalBattleService'; import { SaveTeamParam, SaveTeamUpdateParam } from '../../../domain/gvgField/gvgDb'; -import { GVG_AREA_TYPE, GVG_ITEM, GVG_PERIOD, GVG_REC_TYPE, ITEM_CHANGE_REASON, REDIS_KEY, STATUS } from '../../../consts'; +import { GVG_AREA_TYPE, GVG_ITEM, GVG_PERIOD, GVG_REC_TYPE, ITEM_CHANGE_REASON, PUSH_ROUTE, REDIS_KEY, STATUS } from '../../../consts'; import { GVGHeroInfo } from '../../../domain/dbGeneral'; import { ArtifactModel } from '../../../db/Artifact'; import { getHeroesAttributes } from '../../../services/playerCeService'; @@ -29,6 +29,8 @@ import { Rank } from '../../../services/rankService'; import { LeagueRankInfo, RoleRankInfo } from '../../../domain/rank'; import { addBattleEndRec, addTeamSettleRec } from '../../../services/gvg/gvgRecService'; import { RoleModel } from '../../../db/Role'; +import { GVG } from '../../../pubUtils/dicParam'; +import { sendMessageToGVGAreaByTeamWithSuc } from '../../../services/pushService'; export default function (app: Application) { new HandlerService(app, {}); @@ -142,7 +144,7 @@ export class GVGBattleHandler { return resResult(STATUS.SUCCESS, { cityId, guardLeague: { leagueCode, name, icon }, - guardStartTime: startFightTime - 3 * 60,// TODO 进系统参数表 + guardStartTime: startFightTime - GVG.GVG_GUARD_START_TIME, startTime: startFightTime, endTime: endFightTime, ourTeamCnt, @@ -532,7 +534,7 @@ export class GVGBattleHandler { let city = await GVGCityModel.findByCityId(configId, groupKey, cityId); if (!city) return resResult(STATUS.GVG_CITY_NOT_FOUND); - defenseTeam = await GVGTeamModel.battleEndDefense(teamCode, await getTechKnifeHurt(configId, attackTeam.leagueCode), getBirthAreaOfCity(city, defenseTeam.leagueCode), await getTechReviveMinus(configId, defenseTeam.leagueCode)); + defenseTeam = await GVGTeamModel.battleEndDefense(oppoTeamCode, await getTechKnifeHurt(configId, attackTeam.leagueCode), getBirthAreaOfCity(city, defenseTeam.leagueCode), await getTechReviveMinus(configId, defenseTeam.leagueCode)); if(defenseTeam.curTeamBreak && defenseTeam.originPointId > 0) { // 打败的对手原来占领着一个位置,现在这个位置是你的了 if(!attackTeam.curTeamBreak) { attackTeam = await GVGTeamModel.settlePoint(attackTeam.teamCode, defenseTeam.originPointId); @@ -552,7 +554,9 @@ export class GVGBattleHandler { teamObj.battleEnd([attackTeam, defenseTeam]); await battleEndSendMessage(groupKey, cityId, defenseTeam, attackTeam); - + await sendMessageToGVGAreaByTeamWithSuc(groupKey, defenseTeam.areaId, PUSH_ROUTE.GVG_TEAM_ATTACKED, { + cityId, areaId: defenseTeam.areaId, attackType: 2, teams: [new GVGTeamInList(defenseTeam), new GVGTeamInList(attackTeam)] + }); return resResult(STATUS.SUCCESS, { curTeam: new MyTeamInfo(attackTeam) }); } diff --git a/game-server/app/services/gvg/gvgBattleMemory.ts b/game-server/app/services/gvg/gvgBattleMemory.ts index bf3ba871d..eacd20f5b 100644 --- a/game-server/app/services/gvg/gvgBattleMemory.ts +++ b/game-server/app/services/gvg/gvgBattleMemory.ts @@ -129,9 +129,10 @@ class GVGBattleData { if(!teamMem) { // 基本不会有没有这个内存的情况,有的话就让他重新计算一次吧 this.enterCity(team); continue; } - let { areaId: fromAreaId, pointId: fromPointId } = teamMem; + let { curTeamBreak, pointId } = team; + let { areaId: fromAreaId, pointId: originPointId } = teamMem; teamMem.updateTeam(team); - this.setRolePoints(team.roleId, fromPointId, team.pointId, team.teamCode); + this.setRolePoints(team.roleId, originPointId, curTeamBreak? 0: pointId, team.teamCode); this.setAreaMap(team.teamCode, fromAreaId, team.areaId); } } @@ -191,6 +192,7 @@ export async function initTeamToMem() { if(period != GVG_PERIOD.BATTLE) return; let teams = await GVGTeamModel.findByConfigId(configId); for(let team of teams) { + if(team.isBroken) continue; if(dispatch(team.cityId.toString(), servers)?.id == sid) { let teamObj = getGVGBattleData(team.groupKey); teamObj.enterCity(team); diff --git a/game-server/app/services/gvg/gvgBattleService.ts b/game-server/app/services/gvg/gvgBattleService.ts index 02b178137..524307efb 100644 --- a/game-server/app/services/gvg/gvgBattleService.ts +++ b/game-server/app/services/gvg/gvgBattleService.ts @@ -22,17 +22,7 @@ import { sendMailByContent, sendMailToLeagueByContent } from "../mailService"; import { GVGCityAreaPointModel } from "../../db/GVGCityAreaPoint"; import { addCityGuardMessage } from "./gvgRecService"; import { GVGUserDataModel } from "../../db/GVGUserData"; - - -/** - * 检查上周是否有占领城池 - * @param league - * @returns boolean 是否占领 - */ -export async function checkHasCities(league: GVGLeagueType) { - let { configId } = getGVGConfig(); - return await GVGCityModel.checkLeagueHasGuard(configId, league.leagueCode); -} +import { RoleModel } from "../../db/Role"; /** * 获取本联军上周占领的城池 @@ -138,7 +128,8 @@ export async function refreshTeams(configId: number, groupKey: string, roleId: s for(let team of oldTeams) { if(team.configId != configId) { let { teamCode, maxDurability } = team; - let newTeam = await GVGTeamModel.refreshByConfig(team.teamCode, { teamCode, durability: maxDurability, cityId: 0, areaId: 0, pointId: 0, roleName, guildCode, leagueCode: myLeague.leagueCode, leagueName: myLeague.name, groupKey }); + let { lv } = await RoleModel.findByRoleId(roleId, 'lv'); + let newTeam = await GVGTeamModel.refreshByConfig(teamCode, { configId, lv, durability: maxDurability, cityId: 0, areaId: 0, pointId: 0, roleName, guildCode, leagueCode: myLeague.leagueCode, leagueName: myLeague.name, groupKey }); teams.push(newTeam); } else { teams.push(team); @@ -297,16 +288,18 @@ export async function catapultHurt() { let dicGVGCity = gameData.gvgCity.get(catapult.cityId); let teams = await GVGTeamModel.attackByCatapult(teamCodes, catapult.captapultAtk, dicGVGCity.attackBirth); teamObj.battleEnd(teams); - await sendMessageToGVGAreaWithSuc(teamObj.groupKey, catapult.areaId, PUSH_ROUTE.GVG_TEAM_ATTACKED, { - cityId: catapult.cityId, areaId: catapult.areaId, attackType: 1, teams: teams.map(team => new GVGTeamInList(team)) - }); - await sendMessageToGVGAreaByTeamWithSuc(teamObj.groupKey, catapult.areaId, PUSH_ROUTE.GVG_SPINE_ATTACKED, { - cityId: catapult.cityId, areaId: catapult.areaId, attackType: 1, teams: teams.map(team => new GVGAttackSpine(team, catapult.captapultAtk)) - }); - for(let team of teams) { - await pushTeamBeHurtMessage(team); - if(team.curTeamBreak && team.originPointId > 0) { - await GVGCityAreaPointModel.leavePoint(configId, teamObj.groupKey, team.originPointId); + if(teams.length > 0) { + await sendMessageToGVGAreaByTeamWithSuc(teamObj.groupKey, catapult.areaId, PUSH_ROUTE.GVG_TEAM_ATTACKED, { + cityId: catapult.cityId, areaId: catapult.areaId, attackType: 1, teams: teams.map(team => new GVGTeamInList(team)) + }); + await sendMessageToGVGAreaWithSuc(teamObj.groupKey, catapult.areaId, PUSH_ROUTE.GVG_SPINE_ATTACKED, { + cityId: catapult.cityId, areaId: catapult.areaId, attackType: 1, teams: teams.map(team => new GVGAttackSpine(team, catapult.captapultAtk)) + }); + for(let team of teams) { + await pushTeamBeHurtMessage(team); + if(team.curTeamBreak && team.originPointId > 0) { + await GVGCityAreaPointModel.leavePoint(configId, teamObj.groupKey, team.originPointId); + } } } } diff --git a/game-server/app/services/gvg/gvgService.ts b/game-server/app/services/gvg/gvgService.ts index 52ccb6e9a..a6005c827 100644 --- a/game-server/app/services/gvg/gvgService.ts +++ b/game-server/app/services/gvg/gvgService.ts @@ -2,7 +2,7 @@ import { pinus } from "pinus"; import { GVGConfigModel, GVGConfigType } from "../../db/GVGConfig"; import { getTimeFun, getZeroPoint, getZeroPointOfTime, nowSeconds, WEEK_TO_SECOND } from "../../pubUtils/timeUtil"; import { getAllServerCreateTime, getServerCreateTime } from "../redisService"; -import { GVG_PERIOD, GVG_SERVER_TYPE, LEAGUE_JOB, SHOP_REFRESH_TYPE } from "../../consts"; +import { GVG_PERIOD, GVG_SERVER_TYPE, LEAGUE_JOB, PUSH_ROUTE, SHOP_REFRESH_TYPE } from "../../consts"; import { GVGLeagueModel, GVGLeagueType } from "../../db/GVGLeague"; import { GVGLeaguePrepareModel } from "../../db/GVGLeaguePrepare"; import { GVGServerGroupModel } from "../../db/GVGServerGroup"; @@ -11,7 +11,6 @@ import { getRandSingleEelm } from "../../pubUtils/util"; import { GVG } from "../../pubUtils/dicParam"; import { ServerlistModel } from "../../db/Serverlist"; import { GuildModel, GuildType } from "../../db/Guild"; -import { checkHasCities } from "./gvgBattleService"; import { GVGLeagueApplyModel } from "../../db/GVGLeagueApply"; import { GVGMainData, LeagueContributeInfo } from "../../domain/gvgField/returnData"; import { Contribute, GVGUserDataModel, GVGUserDataType } from "../../db/GVGUserData"; @@ -24,6 +23,8 @@ import { calVestigeLeagueBoxRewards, getFightTimeByPeriod } from "./gvgFightServ import { GVGVestigeLeagueRankModel } from "../../db/GVGVestigeLeagueRank"; import { GVGVestigeSumRankModel } from "../../db/GVGVestigeSumRank"; import { GVGTeamModel } from "../../db/GVGTeam"; +import { sendMessageToGuildWithSuc } from "../pushService"; +import { GVGCityModel } from "../../db/GVGCity"; // 定时器相关 export async function createNewGVGConfig() { @@ -42,13 +43,20 @@ export async function createNewGVGConfig() { let autoLeagues = await GVGLeagueModel.findAutoCreateLeague(); let needDissmissLeagueId: string[] = [], needDissmissLeagueCodes: string[] = []; for(let league of autoLeagues) { - if(!await checkHasCities(league)) { + if(!await GVGCityModel.checkLeagueHasGuard(config.configId, 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; } diff --git a/game-server/app/services/gvg/gvgTeamService.ts b/game-server/app/services/gvg/gvgTeamService.ts index 1ec4769a4..a97d9b521 100644 --- a/game-server/app/services/gvg/gvgTeamService.ts +++ b/game-server/app/services/gvg/gvgTeamService.ts @@ -27,7 +27,7 @@ export async function autoCreateLeague(guildCode: string) { if(!guild || guild.lv < GVG.GVG_ARMY_LEAGUE_TIME) return; let { configId, period } = getGVGPeriodData(); - if(period == GVG_PERIOD.PREPARE || period == GVG_PERIOD.BATTLE) { + if(period == GVG_PERIOD.PREPARE) { let league = await createLeague(guild, {}); await GVGLeaguePrepareModel.initData(configId, league.leagueCode, guild.memberCnt); return league; diff --git a/game-server/app/services/timeTaskService.ts b/game-server/app/services/timeTaskService.ts index b25b50401..d7d39e1bb 100644 --- a/game-server/app/services/timeTaskService.ts +++ b/game-server/app/services/timeTaskService.ts @@ -921,9 +921,12 @@ export async function initGVGConfigSchedule() { let { startFightTime, endFightTime } = getFightTimeByPeriod(GVG_PERIOD.BATTLE, config.battleTime); if(nowSeconds() > startFightTime && nowSeconds() < endFightTime) { - startGvgBattleSeconds(); + if(gvgBattleSecondJob) gvgBattleSecondJob.cancel(); + gvgBattleSecondJob = scheduleJob('gvgBattleSecondJob', '*/5 * * * * *', gvgBattleSecondSchedule); + if(gvgBattleCatapultJob) gvgBattleCatapultJob.cancel(); + gvgBattleCatapultJob = scheduleJob('gvgBattleCatapultJob', `*/${GVG.GVG_CATAPULT_TIME} * * * * *`, gvgBattleCatapult); } else { - scheduleJob(`gvgBattleStartSchedule`, startFightTime * 1000, gvgBattleStartSchedule); + scheduleJob(`gvgBattleStartSchedule`, (startFightTime - GVG.GVG_GUARD_START_TIME) * 1000, gvgBattleStartSchedule); } scheduleJob(`gvgBattleEndSchedule`, endFightTime * 1000, gvgBattleEndSchedule); } @@ -933,20 +936,21 @@ let gvgBattleCatapultJob: Job; // gvg投石车定时器 // gvg激战期开始定时器 export async function gvgBattleStartSchedule() { - // 初始化投石车 - let guildServers = pinus.app.getServersByType('guild'); - if(guildServers.length > 0) { - pinus.app.rpc.guild.guildRemote.gvgBattleStart.toServer(getRandSingleEelm(guildServers).id); - } - startGvgBattleSeconds(); -} - -function startGvgBattleSeconds() { - // 发放道具 if(gvgBattleSecondJob) gvgBattleSecondJob.cancel(); gvgBattleSecondJob = scheduleJob('gvgBattleSecondJob', '*/5 * * * * *', gvgBattleSecondSchedule); - if(gvgBattleCatapultJob) gvgBattleCatapultJob.cancel(); - gvgBattleCatapultJob = scheduleJob('gvgBattleCatapultJob', `*/${GVG.GVG_CATAPULT_TIME} * * * * *`, gvgBattleCatapult); + + setTimeout(async () => { + console.log('############') + if(gvgBattleCatapultJob) gvgBattleCatapultJob.cancel(); + gvgBattleCatapultJob = scheduleJob('gvgBattleCatapultJob', `*/${GVG.GVG_CATAPULT_TIME} * * * * *`, gvgBattleCatapult); + // 初始化投石车 + let guildServers = pinus.app.getServersByType('guild'); + if(guildServers.length > 0) { + pinus.app.rpc.guild.guildRemote.gvgBattleStart.toServer(getRandSingleEelm(guildServers).id); + } + + }, 60); + } // 每隔5秒的积分计算定时器 diff --git a/shared/db/GVGCity.ts b/shared/db/GVGCity.ts index 0163e6ee1..4d5636956 100644 --- a/shared/db/GVGCity.ts +++ b/shared/db/GVGCity.ts @@ -49,7 +49,8 @@ export default class GVGCity extends BaseModel { // 添加人数 public static async increasePlayer(configId: number, groupKey: string, cityId: number, roleId: string, leagueCode: string, teamCnt: number) { - const city: GVGCityType = await GVGCityModel.findOneAndUpdate({ configId, groupKey, cityId, userCnt: { $lt: 200 } }, { $inc: { userCnt: 1 }, $push: { players: { roleId, leagueCode, teamCnt } }}, { new: true, upsert: true }).lean(); + await GVGCityModel.findOneAndUpdate({ configId, groupKey, cityId }, { $setOnInsert: { userCnt: 0, players: [] } }, { upsert: true }).lean() + const city: GVGCityType = await GVGCityModel.findOneAndUpdate({ configId, groupKey, cityId, userCnt: { $lt: 200 } }, { $inc: { userCnt: 1 }, $push: { players: { roleId, leagueCode, teamCnt } }}, { new: true }).lean(); return city; } @@ -98,7 +99,7 @@ export default class GVGCity extends BaseModel { public static async guardCity(configId: number, groupKey: string, cityId: number, league: LeagueRankInfo) { const city: GVGCityType = await GVGCityModel.findOneAndUpdate({ configId: configId + 1, cityId, groupKey }, { $set: { hasGuard: true, guardLeague: league.code, guardLeagueName: league.name, guardLeagueIcon: league.icon - } }, { upsert: true, new: true }).lean(); + }, $setOnInsert: { userCnt: 0, players: [] } }, { upsert: true, new: true }).lean(); return city; } diff --git a/shared/db/GVGTeam.ts b/shared/db/GVGTeam.ts index 2d30d8e5b..79991a54a 100644 --- a/shared/db/GVGTeam.ts +++ b/shared/db/GVGTeam.ts @@ -282,7 +282,7 @@ export default class GVGTeam extends BaseModel { // 结算防守方 public static async battleEndDefense(teamCode: string, hpInc: number, rebirthAreaId: number, reviveCd: number) { - let team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { defenseTime: nowSeconds() + GVG.GVG_DEFAULT_DEFENSE_CD, lockTime: 0, lockTeamCode: '' }, $inc: { durability: hpInc } }, { new: true }).lean(); + let team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { defenseTime: nowSeconds() + GVG.GVG_DEFAULT_DEFENSE_CD, lockTime: 0, lockTeamCode: '' }, $inc: { durability: -hpInc } }, { new: true }).lean(); if(team.durability <= 0) { let originPointId = team.pointId; team = await GVGTeamModel.teamBreak(teamCode, team.isRobot, team.maxDurability, rebirthAreaId, team.areaId, reviveCd); @@ -294,11 +294,11 @@ export default class GVGTeam extends BaseModel { // 队伍进入修整器 public static async teamBreak(teamCode: string, isRobot: boolean, maxDurability: number, areaId: number, fromAreaId: number, reviveCd: number) { if(!isRobot) { - const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { restartTime: nowSeconds() - reviveCd, stopMoveTime: nowSeconds(), areaId, fromAreaId, durability: maxDurability, pointId: 0 } }, { new: true }).lean(); + const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { restartTime: nowSeconds() + reviveCd, stopMoveTime: nowSeconds(), areaId, fromAreaId, durability: maxDurability, pointId: 0 } }, { new: true }).lean(); team.curTeamBreak = true; return team; } else { - const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { fromAreaId, pointId: 0, durability: 0, isBroken: true } }, { new: true }).lean(); + const team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { fromAreaId, durability: 0, isBroken: true } }, { new: true }).lean(); team.curTeamBreak = true; return team; } diff --git a/shared/pubUtils/dicParam.ts b/shared/pubUtils/dicParam.ts index b38d6dadf..997b64dbf 100644 --- a/shared/pubUtils/dicParam.ts +++ b/shared/pubUtils/dicParam.ts @@ -375,7 +375,7 @@ export const GUIDE = { }; export const GVG = { GVG_LEAGUE_COMPOSE: 3, // 一个联军有最多多少军团组成 - GVG_CROSS_SERVICE_STARTTIME: 4, // 开服几周后开始跨服玩法 + GVG_CROSS_SERVICE_STARTTIME: 2, // 开服几周后开始跨服玩法 GVG_ROLE_TOTAL_RATIO: 1.2, // 贤臣+猛将总人数上限系数 GVG_ROLE_RATIO: 1, // 贤臣/猛将各职能选择人数上限系数 GVG_PRODUCER_GET: '10&6|11&2', // 贤臣每天发多少令 @@ -386,7 +386,7 @@ export const GVG = { GVG_ARMY_LEAGUE_TIME: 3, // GVG开启军团等级开启限制 GVG_ROLE_TYPE: '1&贤臣|2&猛将', // GVG中职能选择 GVG_TEAM_NUMBER: '1&1&100|2&50&100|3&80&100', // GVG编队,index&lv&durability - GVG_CATAPULT: '&', // & + GVG_GUARD_START_TIME: 300, // 城池占领者提前入城时间 GVG_CITY_OCCUPIED_NUMBER: 2, // 一个联军最多可以占领的城池数量 GVG_SP_FIELD_ADD: 0.2, // 农田特殊格子上种植对应的植物的加成 GVG_FARM_LOCK_TIME: 300, // 农田锁定时间(秒) @@ -418,6 +418,7 @@ export const GVG = { GVG_ROBOT_WARJSON: 85002, // GVG城池守卫的出兵表 GVG_REDPOINT_BATTLEFEAT: 0, // 千机阁战功红点大于多少可能出现红点 GVG_REVIVE_GOLD: '1&100|2&150|3&200|4&250|5&300|6&500', // GVG激战期元宝购买复活的消耗,次数&元宝数 + GVG_VESTIGE_CHALLENGE_TIME: '5:00:00&22:00:00', // 征战中原遗迹可挑战时间 }; export const PLATFORM_CONFIG = { OPEN_ANIMATION: 1, // 0关,1开(开场动画视频) diff --git a/shared/resource/jsons/dic_email_content.json b/shared/resource/jsons/dic_email_content.json index ac300841b..8c5ed7e69 100644 --- a/shared/resource/jsons/dic_email_content.json +++ b/shared/resource/jsons/dic_email_content.json @@ -292,5 +292,12 @@ "sendName": "学宫驿使", "content": "亲爱的百家传人,逐鹿中原激战期已结束,您的联军锐不可当成功占领%d,占领奖励现已发送至邮箱,请查收", "time": 720 + }, + { + "id": 42, + "title": "联军邮件", + "sendName": "&", + "content": "%d", + "time": 0 } ] \ No newline at end of file diff --git a/shared/resource/jsons/dic_zyz_GVGPeriod.json b/shared/resource/jsons/dic_zyz_GVGPeriod.json index 2d74ca52d..b39dc9e8c 100644 --- a/shared/resource/jsons/dic_zyz_GVGPeriod.json +++ b/shared/resource/jsons/dic_zyz_GVGPeriod.json @@ -14,7 +14,7 @@ { "periodType": 3, "day": "6&", - "startTime": "17:00:00", - "endTime": "22:00:00" + "startTime": "22:06:00", + "endTime": "23:00:00" } ] \ No newline at end of file