🐞 fix(gvg): 投石车定时任务

This commit is contained in:
luying
2023-02-17 11:00:23 +08:00
parent 4359bfd9cc
commit 7543baa8cb
17 changed files with 304 additions and 52 deletions
@@ -1,6 +1,6 @@
import { GVGCityType } from './../../../db/GVGCity';
import { GVGRecModel } from '../../../db/GVGRec';
import { GVGAreaInMap, GVGTeamInList, GVGTeamInListOnPoint, GVGTeamSpineInMap, LeagueGood, MyTeamInfo } from '../../../domain/gvgField/returnData';
import { GVGAreaInMap, GVGTeamInList, GVGTeamInListOnPoint, GVGTeamSpineInMap, LeagueGood, MyTeamInfo, MyTeamSimpleInfo } from '../../../domain/gvgField/returnData';
import { GVGTeamModel, GVGTeamType, GVGTeamUpdate } from '../../../db/GVGTeam';
import { GVGUserDataModel } from '../../../db/GVGUserData';
import { GVGCityModel } from '../../../db/GVGCity';
@@ -23,6 +23,7 @@ import { sendMessageToUserWithSuc } from '../../../services/pushService';
import { GVGHeroInfo } from '../../../domain/dbGeneral';
import { ArtifactModel } from '../../../db/Artifact';
import { getHeroesAttributes } from '../../../services/playerCeService';
import { gvgBattleStartSchedule } from '../../../services/timeTaskService';
export default function (app: Application) {
new HandlerService(app, {});
@@ -40,8 +41,8 @@ export class GVGBattleHandler {
async getTeams(msg: {}, session: BackendSession) {
const roleId = session.get('roleId');
const teams = await GVGTeamModel.findByRole(roleId, '-_id teamCode index head frame spine lineup')
return resResult(STATUS.SUCCESS, { teams });
return resResult(STATUS.SUCCESS, { teams: teams.map(team => new MyTeamSimpleInfo(team)) });
}
// 保存队伍
@@ -101,7 +102,7 @@ export class GVGBattleHandler {
if (!team) {
return resResult(STATUS.GVG_SAVE_TEAM_FAILED);
}
return resResult(STATUS.SUCCESS, { curTeam: pick(team, ['teamCode', 'index', 'head', 'frame', 'spine', 'lineup']) });
return resResult(STATUS.SUCCESS, { curTeam: new MyTeamSimpleInfo(team) });
}
// 获取城池信息
@@ -509,4 +510,8 @@ export class GVGBattleHandler {
// ! 重新组织每个城市的数据,添加据点和积分点的信息
return resResult(STATUS.SUCCESS, { cities });
}
async debugStartSchedule() {
await gvgBattleStartSchedule();
}
}
@@ -145,7 +145,7 @@ export class GVGProduceHandler {
let dicWarJson = gameData.warJson.get(dicWar.dispatchJsonId);
result.setRobot(dicGVGVestige, dicWarJson, serverNames[serverId]);
} else {
let hisVestigeRank = await GVGVestigeRankModel.findByRole(vestigeId, roleId);
let hisVestigeRank = await GVGVestigeRankModel.findByRole(vestigeId, targetRoleId);
if(!hisVestigeRank) return resResult(STATUS.GVG_VESTIGE_TARGET_NOT_FOUND);
let role = await RoleModel.findByRoleId(hisVestigeRank.roleId, 'roleId roleName serverId guildName title lv heads head spines spine frames frame')
@@ -1,9 +1,9 @@
import { Application, BackendSession, ChannelService, HandlerService, pinus } from "pinus";
import { GVG_ITEM, DATA_NAME, GVG_ACTIVE_TYPE, GVG_PERIOD, GVG_SERVER_TYPE, ITEM_CHANGE_REASON, LEAGUE_JOB, LEAGUE_MANAGE_TYPE, STATUS, GVG_REC_TYPE, TASK_TYPE } from "../../../consts";
import { GVG_ITEM, DATA_NAME, GVG_ACTIVE_TYPE, GVG_PERIOD, GVG_SERVER_TYPE, ITEM_CHANGE_REASON, LEAGUE_JOB, LEAGUE_MANAGE_TYPE, STATUS, GVG_REC_TYPE, TASK_TYPE, GVG_TECH_TYPE } from "../../../consts";
import { GVGLeagueModel } from "../../../db/GVGLeague";
import { GVGLeaguePrepareModel } from "../../../db/GVGLeaguePrepare";
import { GVGMainData, LeagueContributeInfo, LeagueMemberContributeInfo, LeagueMemberListInfo } from "../../../domain/gvgField/returnData";
import { resResult } from "../../../pubUtils/util";
import { getRandEelm, resResult } from "../../../pubUtils/util";
import { calLeagueCe, getGroupIdOfServer, getGVGConfig, getGVGPeriodData, getGVGServerType, getServerTypeByTime } from "../../../services/gvg/gvgService";
import { autoCreateLeague, checkCanChooseJob, checkCanPrepare, checkLeagueAuth, getMyAuth } from "../../../services/gvg/gvgTeamService";
import { getAllServerName } from "../../../services/redisService";
@@ -421,6 +421,14 @@ export class GVGHandler {
let curQueue = leaguePrepare.techQueue.find(cur => cur.id == techId);
if(curQueue.progress >= curQueue.maxProgress) {
leaguePrepare = await GVGLeaguePrepareModel.activate(configId, myLeague.leagueCode, techId);
// 发放连弩
if(dicTech.type == GVG_TECH_TYPE.BATTLE_ITEM_KNIFE) {
let members = myLeague.members||[];
let randMembers = getRandEelm(members, dicTech.param[0]);
for(let { roleId } of randMembers) {
await addGVGReward(roleId, '', myLeague.leagueCode, null, [{ id: GVG_ITEM.KNIFE, count: dicTech.param[1] }], [], ITEM_CHANGE_REASON.GVG_TECH_SEND_KNIFE);
}
}
}
// 添加 活跃
@@ -8,6 +8,7 @@ import { setHiddenData } from '../../../services/dataService';
import { setKvToMemory } from '../../../services/pushService';
import { getGVGConfig, setGVGConfig, setGVGServerGroup } from '../../../services/gvg/gvgService';
import { GVGConfigType } from '../../../db/GVGConfig';
import { catapultHurt, gvgBattleStart, initCatapult } from '../../../services/gvg/gvgBattleService';
export default function (app: Application) {
new HandlerService(app, {});
@@ -118,4 +119,28 @@ export class GuildRemote {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async gvgBattleStart() {
try {
return await gvgBattleStart();
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async initCatapult(cityId: number, groupId: number, serverType: number, leagueCode: string, leagueName: string) {
try {
return await initCatapult(cityId, groupId, serverType, leagueCode, leagueName);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async catapultHurt() {
try {
return await catapultHurt();
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
}
@@ -1,7 +1,7 @@
// 存在激战期的内存数据
import { pinus } from "pinus";
import { GVG_PERIOD } from "../../consts";
import { GVG_CATAPULT, GVG_PERIOD } from "../../consts";
import { GVGTeamModel, GVGTeamType } from "../../db/GVGTeam";
import { GVGTeamMem } from "../../domain/battleField/gvgBattle";
import { dispatch } from "../../pubUtils/dispatcher";
@@ -34,6 +34,18 @@ class GVGBattleData {
return teams.slice(0, 20);
}
public findCatapultAttackTeam(areaIds: number[], leagueCode: string) {
let teams: string[] = [];
for(let areaId of areaIds) {
let teamCodes = this.areaToTeams.get(areaId)||new Set();
for(let teamCode of teamCodes) {
let team = this.teams.get(teamCode);
if(team && team.leagueCode != leagueCode && !team.isRobot) teams.push(teamCode);
}
}
return teams;
}
public leaveCity(roleId: string) {
let teamCodes = this.roleToTeam.get(roleId)||[];
for(let teamCode of teamCodes) {
@@ -117,11 +129,17 @@ class GVGBattleData {
this.enterCity(team); continue;
}
let { areaId: fromAreaId, pointId: fromPointId } = teamMem;
teamMem.battleEnd(team);
teamMem.updateTeam(team);
this.setRolePoints(team.roleId, fromPointId, team.pointId);
this.setAreaMap(team.teamCode, fromAreaId, team.areaId);
}
}
// 投石车
public findCatapult() {
let teamCodes = this.roleToTeam.get(GVG_CATAPULT)||[];
return teamCodes.map(teamCode => this.teams.get(teamCode));
}
}
export function getGVGBattleData(groupId: number, serverType: number) {
@@ -132,11 +150,15 @@ export function getGVGBattleData(groupId: number, serverType: number) {
return gvgBattleMap.get(key);
}
export function getGVGBattleMap() {
return gvgBattleMap;
}
export async function initTeamToMem() {
let sid = pinus.app.getServerId();
let servers = pinus.app.getServersByType('guild');
let { configId, period } = getGVGPeriodData();
if(period != GVG_PERIOD.BATTLE) return;
// if(period != GVG_PERIOD.BATTLE) return;
let teams = await GVGTeamModel.findByConfigId(configId);
for(let team of teams) {
if(dispatch(team.cityId.toString(), servers)?.id == sid) {
@@ -3,14 +3,18 @@ import { GVGLeagueType } from "../../db/GVGLeague";
import { GVGTeamModel, GVGTeamType, GVGTeamUpdate } from "../../db/GVGTeam";
import { GVGCityModel, GVGCityType } from "../../db/GVGCity";
import { gameData } from "../../pubUtils/data";
import { STATUS } from "../../consts";
import { GVG_AREA_TYPE, GVG_TECH_TYPE, STATUS } from "../../consts";
import { nowSeconds } from "../../pubUtils/timeUtil";
import { DicGVGAreaPoint } from "../../pubUtils/dictionary/DicGVGAreaPoint";
import { getGVGBattleData } from "./gvgBattleMemory";
import { getGVGBattleData, getGVGBattleMap } from "./gvgBattleMemory";
import { GVGCityMapInfo } from "../../domain/gvgField/returnData";
import { pick } from "underscore";
import { GVG } from "../../pubUtils/dicParam";
import { GVGHeroInfo, PvpEnemies, PvpHeroInfo } from "../../domain/dbGeneral";
import { getGVGConfig } from "./gvgService";
import { GVGLeaguePrepareModel } from "../../db/GVGLeaguePrepare";
import { pinus } from "pinus";
import { dispatch } from "../../pubUtils/dispatcher";
/**
@@ -63,6 +67,7 @@ export function getBirthAreaOfCity(city: GVGCityType, leagueCode: string) {
return isGuard? dicGVGCity.defenseBirth: dicGVGCity.attackBirth;
}
// guild.gvgBattleHandler.startMove 检测
export function checkMoveStatus(team: GVGTeamType, cityId: number, areaId: number) {
if(!team) return STATUS.GVG_BATTLE_TEAM_NOT_FOUND;
if(team.cityId != cityId) return STATUS.GVG_BATTLE_IS_NOT_IN_CITY;
@@ -122,6 +127,7 @@ export function getGVGWarId(defenseTeam: GVGTeamType) {
return GVG.GVG_ROBOT_WARJSON; // 据点守卫使用
}
// guild.gvgBattleHandler.battleStart 里的heroes返回
export function getOppHeroes(warId: number, isRobot: boolean, lineup: GVGHeroInfo[]) {
let heroes: PvpEnemies[] = [];
const dicWar = gameData.war.get(warId);
@@ -147,6 +153,7 @@ export function getOppHeroes(warId: number, isRobot: boolean, lineup: GVGHeroInf
return heroes
}
// guild.gvgBattleHandler.battleStart 检测
export function checkGVGBattleStart(roleId: string, attackTeam: GVGTeamType, defenseTeam: GVGTeamType) {
if(!attackTeam || !defenseTeam) return STATUS.GVG_BATTLE_TEAM_INVALID;
@@ -160,4 +167,58 @@ export function checkGVGBattleStart(roleId: string, attackTeam: GVGTeamType, def
if(defenseTeam.durability <= 0) return STATUS.GVG_DEFENSE_TEAM_BROKEN;
return STATUS.SUCCESS;
}
// gvg激战期开始定时器
export async function gvgBattleStart() {
let servers = pinus.app.getServersByType('guild');
let { configId } = getGVGConfig();
let guardCities = await GVGCityModel.findAllGuardCities(configId);
for(let { cityId, groupId, serverType, guardLeague, guardLeagueName } of guardCities) {
let sid = dispatch(cityId.toString(), servers)?.id;
await pinus.app.rpc.guild.guildRemote.initCatapult.toServer(sid, cityId, groupId, serverType, guardLeague, guardLeagueName);
}
}
// 每次活动开始初始化投石车
export async function initCatapult(cityId: number, groupId: number, serverType: number, leagueCode: string, leagueName: string) {
let { configId } = getGVGConfig();
let leaguePrepare = await GVGLeaguePrepareModel.findByLeague(configId, leagueCode);
let activeTech = leaguePrepare?.activeTech||[];
let hasCatapult = false, atk = 0, durability = 0;
for(let techId of activeTech) {
let dicTech = gameData.gvgTech.get(techId);
if(dicTech && dicTech.type == GVG_TECH_TYPE.BATTLE_ITEM_CATAPULT) {
hasCatapult = true, atk = dicTech.param[0]; durability = dicTech.param[1];
}
}
if(hasCatapult) {
let dicCity = gameData.gvgCity.get(cityId);
let areaIds = (dicCity?.areaIds||[]).filter(areaId => {
let dicArea = gameData.gvgArea.get(areaId);
return dicArea && dicArea.areaType == GVG_AREA_TYPE.CATAPULT;
});
let teams = await GVGTeamModel.initCatapult(configId, groupId, serverType, cityId, leagueCode, leagueName, areaIds, atk, durability);
// 处理内存
let teamObj = getGVGBattleData(groupId, serverType);
teamObj.enterCity(...teams);
}
}
// 投石车投伤害
export async function catapultHurt() {
for(let [_, teamObj] of getGVGBattleMap()) {
let teams = teamObj.findCatapult();
for(let catapult of teams) {
if(catapult.isBroken) continue;
let dicArea = gameData.gvgArea.get(catapult.areaId);
let relateArea = dicArea?.relateArea||[];
let teamCodes = teamObj.findCatapultAttackTeam(relateArea, catapult.leagueCode);
let dicGVGCity = gameData.gvgCity.get(catapult.cityId);
let teams = await GVGTeamModel.attackByCatapult(teamCodes, catapult.captapultAtk, dicGVGCity.attackBirth)
teamObj.battleEnd(teams);
}
}
}
@@ -31,13 +31,13 @@ import { addVestigeLeagueRankRec } from "./gvgRecService";
import { getGroupIdOfServer, getGVGServerType } from "./gvgService";
// 备战期的遗迹和激战期的开始结束战斗时间
export function getFightTimeByPeriod(period: GVG_PERIOD) {
export function getFightTimeByPeriod(period: GVG_PERIOD, time?: number) {
let dicPeriod = gameData.gvgPeriod.get(period);
if(!dicPeriod) return { startFightTime: 0, endFightTime: 0 };
return {
startFightTime: <number>getTimeFun().getTimeWithHour(dicPeriod.startHour, dicPeriod.startMinute, dicPeriod.startSecond),
endFightTime: <number>getTimeFun().getTimeWithHour(dicPeriod.endHour, dicPeriod.endMinute, dicPeriod.endSecond),
startFightTime: <number>getTimeFun(time).getTimeWithHour(dicPeriod.startHour, dicPeriod.startMinute, dicPeriod.startSecond),
endFightTime: <number>getTimeFun(time).getTimeWithHour(dicPeriod.endHour, dicPeriod.endMinute, dicPeriod.endSecond),
}
}
@@ -32,6 +32,7 @@ export async function createNewGVGConfig() {
if(!await checkHasCities(league)) needDissmissLeagueId.push(league._id);
}
await GVGLeagueModel.dismissByIds(needDissmissLeagueId);
await pinus.app.rpc.systimer.systimerRemote.initGVGConfigSchedule.broadcast();
return config;
}
+52 -3
View File
@@ -5,7 +5,7 @@ import { nowSeconds, getTimeFun, getSeconds } from '../pubUtils/timeUtil';
import { getTodayGuildActivity, gameData } from '../pubUtils/data';
import { pvpSeasonEnd } from './pvpService';
import { getAllOnlineRoles, getAllServers, delGuildActivityRank, getServerCreateTime } from './redisService';
import { GUILD_ACTIVITY_TYPE, REFRESH_TIME, COUNTER, AUCTION_TIME, GM_MAIL_TYPE, SERVER_TIMER, ACTIVITY_TYPE, PUSH_ROUTE, STATUS, LADDER_STATUS, LADDER_SERVER_GAP_TIME } from '../consts';
import { GUILD_ACTIVITY_TYPE, REFRESH_TIME, COUNTER, AUCTION_TIME, GM_MAIL_TYPE, SERVER_TIMER, ACTIVITY_TYPE, PUSH_ROUTE, STATUS, LADDER_STATUS, LADDER_SERVER_GAP_TIME, GVG_PERIOD } from '../consts';
import { pinus } from 'pinus';
import { settleGuildWeekly } from './guildService';
import { SendMailFun, sendMailsByGmMail, } from './mailService';
@@ -16,7 +16,7 @@ import { dispatch } from '../pubUtils/dispatcher';
import { createNewServer, initMarquee, setServerMainten } from './gmService';
import moment = require('moment');
import { reportOneOnline } from './authenticateService';
import { LADDER, PVP } from '../pubUtils/dicParam';
import { GVG, LADDER, PVP } from '../pubUtils/dicParam';
import { fetch37Words } from './sdkService';
import { GMMailModel, GMMailType } from '../db/GMMail';
import { Maintenance, ServerlistModel, ServerlistType } from '../db/Serverlist';
@@ -44,7 +44,7 @@ import { HiddenDataModel, HiddenDataModelType } from '../db/HiddenData';
import { setHiddenData, setHiddenDataToMemory } from './dataService';
import { GVGConfigModel } from '../db/GVGConfig';
import { createNewGVGConfig, initLeaguePrepare } from './gvg/gvgService';
import { saveVestigeRankSchedule } from './gvg/gvgFightService';
import { getFightTimeByPeriod, saveVestigeRankSchedule } from './gvg/gvgFightService';
const PER_SECOND = 1 * 1000;
const PER_DAY = 24 * 60 * 60;
@@ -913,5 +913,54 @@ export async function initGVGConfigSchedule() {
}
scheduleJob('gvgFightSchedule', '0 0 22 * * ?', saveVestigeRankSchedule);
let { startFightTime, endFightTime } = getFightTimeByPeriod(GVG_PERIOD.BATTLE, config.battleTime);
scheduleJob(`gvgBattleStartSchedule`, startFightTime * 1000, gvgBattleStartSchedule);
scheduleJob(`gvgBattleEndSchedule`, endFightTime * 1000, gvgBattleEndSchedule);
}
let gvgBattleSecondJob: Job; // gvg每5秒的定时器
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(guildServers[0].id);
}
// 发放道具
if(gvgBattleSecondJob) gvgBattleSecondJob.cancel();
gvgBattleSecondJob = scheduleJob('gvgBattleSecondJob', '*/5 * * * * *', gvgBattleSecondSchedule);
if(gvgBattleCatapultJob) gvgBattleCatapultJob.cancel();
gvgBattleCatapultJob = scheduleJob('gvgBattleCatapultJob', `*/${GVG.GVG_CATAPULT_TIME} * * * * *`, gvgBattleCatapult);
}
// 每隔5秒的积分计算定时器
async function gvgBattleSecondSchedule() {
// console.log('********** gvgBattleSecondJob *************');
}
// 每隔10秒的投石车投机定时器
async function gvgBattleCatapult() {
console.log('********** gvgBattleCatapultJob *************');
pinus.app.rpc.guild.guildRemote.catapultHurt.broadcast();
}
// gvg激战期结束定时器
async function gvgBattleEndSchedule() {
// 排行榜发放奖励
// 城池占领情况
// 定时器关闭
if(gvgBattleSecondJob) {
gvgBattleSecondJob.cancel();
gvgBattleSecondJob = undefined;
}
if(gvgBattleCatapultJob) {
gvgBattleCatapultJob.cancel();
gvgBattleCatapultJob = undefined;
}
}
// —————————————— gvg end —————————————— //