feat(gvg): 激战期内存以及玩家移动、挑战操作

This commit is contained in:
luying
2023-02-10 21:23:52 +08:00
parent 5d5137f203
commit 19b70baf8c
16 changed files with 536 additions and 125 deletions

View File

@@ -1,5 +1,4 @@
import { GVGCityType } from './../../../db/GVGCity';
import { LeagueCityPoint, GVGTeamMem } from './../../../domain/battleField/gvgBattle';
import { GVGRecModel } from '../../../db/GVGRec';
import { LeagueGood } from '../../../domain/gvgField/returnData';
import { GVGTeamModel } from '../../../db/GVGTeam';
@@ -10,7 +9,11 @@ import { DEBUG_MAGIC_WORD, GVG_PERIOD, STATUS } from "../../../consts";
import { LineupHero } from "../../../domain/roleField/hero";
import { resResult, genCode } from "../../../pubUtils/util";
import { GVGLeagueModel } from '../../../db/GVGLeague';
import { checkGVGPeriod, getGVGPeriodData } from '../../../services/gvg/gvgService';
import { checkGVGPeriod, getGroupIdOfServer, getGVGPeriodData, getGVGServerType } from '../../../services/gvg/gvgService';
import { checkMoveStatus, getBirthAreaOfCity, initRobots } from '../../../services/gvg/gvgBattleService';
import { getGVGBattleData } from '../../../services/gvg/gvgBattleMemory';
import { nowSeconds } from '../../../pubUtils/timeUtil';
import { GVGBattleRecModel } from '../../../db/GVGBattleRec';
export default function (app: Application) {
new HandlerService(app, {});
@@ -20,15 +23,15 @@ export default function (app: Application) {
export class GVGBattleHandler {
channelService: ChannelService;
// 积分点占领情况cityId -> LeagueCode -> LeagueCityPoint
private pointOccupy: Map<number, Map<string, LeagueCityPoint>> = new Map();
// 城池队伍状态cityId -> areaId -> GVGTeamMem
private cityTeamStatus: Map<number, Map<number, GVGTeamMem>> = new Map();
constructor(private app: Application) {
this.channelService = app.get('channelService');
}
// 获取我的编队信息
async getTeams(msg: {}, session: BackendSession) {
}
// 保存队伍
// index: 队伍索引位置
// head: 头像
@@ -53,60 +56,63 @@ export class GVGBattleHandler {
// 获取城池信息
async getCity(msg: { cityId: number }, session: BackendSession) {
if(checkGVGPeriod(GVG_PERIOD.BATTLE)) return resResult(STATUS.GVG_NOT_BATTLE_PERIOD);
const { cityId } = msg;
let { configId } = getGVGPeriodData();
const city = await GVGCityModel.findOne({ configId, cityId }).lean();
return resResult(STATUS.SUCCESS, { city });
return resResult(STATUS.SUCCESS, {
cityId,
guardLeague: city.guardLeague
});
}
// 进入城池之前的检查
async checkMyTeam(msg: { cityId: number }, session: BackendSession) {
}
// 进入城池
async enterCity(msg: { cityId: number }, session: BackendSession) {
if(checkGVGPeriod(GVG_PERIOD.BATTLE)) return resResult(STATUS.GVG_NOT_BATTLE_PERIOD);
if(!checkGVGPeriod(GVG_PERIOD.BATTLE)) return resResult(STATUS.GVG_NOT_BATTLE_PERIOD);
const roleId = session.get('roleId')
const guildCode = session.get('guildCode')
const roleId = session.get('roleId');
const serverId = session.get('serverId');
const guildCode = session.get('guildCode');
const { cityId } = msg;
let { configId } = getGVGPeriodData();
let city: GVGCityType = await GVGCityModel.findOne({ cityId, configId }).lean();
if (!city) {
return resResult(STATUS.GVG_CITY_NOT_FOUND);
}
let groupId = await getGroupIdOfServer(serverId);
let serverType = await getGVGServerType(serverId);
// 检测是否已经在城池中,如果在城池中,直接返回城池信息
let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
if(!myLeague) return resResult(STATUS.GVG_LEAGUE_NOT_EXIST);
await initRobots(groupId, serverType, cityId);
let city: GVGCityType = await GVGCityModel.findByCityId(configId, groupId, serverType, cityId);
let gvgUserData = await GVGUserDataModel.findByRole(configId, myLeague.leagueCode, roleId);
if (!gvgUserData) {
return resResult(STATUS.GVG_USER_NOT_FOUND);
}
if (gvgUserData.cityId === cityId) {
return resResult(STATUS.SUCCESS, { city });
}
// 不在城池则检测是否满员
const { userCnt } = city;
// 检测是否满员
if (userCnt >= 200) {
return resResult(STATUS.GVG_BATTLE_CITY_FULL);
}
// 检测是否已经在城池中,玩家不在这个城池中时进行处理
if (gvgUserData.cityId !== cityId) {
if(gvgUserData.cityId > 0) { // 如果leaveCity没有退出成功玩家还遗留在上一座城中做一下处理
await GVGCityModel.decreasePlayer(configId, groupId, serverType, gvgUserData.cityId, roleId);
}
city = await GVGCityModel.increasePlayer(configId, groupId, serverType, cityId, roleId, myLeague.leagueCode);
if(!city) return resResult(STATUS.GVG_BATTLE_CITY_FULL);
// 检测玩家是否已经在其他城池中,由 checkMyTeam 接口检测
// if (gvgUserData.cityId) {
// }
const roleTeamCnt = await GVGTeamModel.getTeamCnt(roleId);
city = await GVGCityModel.updateCityUser(configId, cityId, 1, roleTeamCnt);
gvgUserData = await GVGUserDataModel.changeCity(configId, myLeague.leagueCode, roleId, cityId);
// ! 队伍默认进入的据点暂时设为 0更新内存队伍信息
const res = await GVGTeamModel.resetTeamsLoc(roleId, cityId, 0);
if (!res) {
return resResult(STATUS.GVG_RESET_TEAM_LOC_FAILED);
gvgUserData = await GVGUserDataModel.changeCity(configId, myLeague.leagueCode, roleId, cityId);
// 更新内存队伍信息
let areaId = getBirthAreaOfCity(city, myLeague.leagueCode);
await GVGTeamModel.enterCity(roleId, cityId, areaId, groupId, serverType);
let teams = await GVGTeamModel.findByRole(roleId);
let teamObj = getGVGBattleData(groupId, serverType);
teamObj.enterCity(teams);
}
return resResult(STATUS.SUCCESS, { city });
@@ -114,11 +120,16 @@ export class GVGBattleHandler {
// 离开城池
async leaveCity(msg: { cityId: number }, session: BackendSession) {
if(checkGVGPeriod(GVG_PERIOD.BATTLE)) return resResult(STATUS.GVG_NOT_BATTLE_PERIOD);
const roleId = session.get('roleId')
const guildCode = session.get('guildCode')
if(!checkGVGPeriod(GVG_PERIOD.BATTLE)) return resResult(STATUS.GVG_NOT_BATTLE_PERIOD);
const roleId = session.get('roleId');
const guildCode = session.get('guildCode');
const serverId = session.get('serverId');
const { cityId } = msg;
let { configId } = getGVGPeriodData();
let groupId = await getGroupIdOfServer(serverId);
let serverType = await getGVGServerType(serverId);
// 检测是否已经在城池中
let myLeague = await GVGLeagueModel.findLeagueByGuild(guildCode);
@@ -131,20 +142,17 @@ export class GVGBattleHandler {
return resResult(STATUS.GVG_USER_NOT_IN_CITY);
}
const roleTeamCnt = await GVGTeamModel.getTeamCnt(roleId);
const city = await GVGCityModel.updateCityUser(configId, cityId, -1, -roleTeamCnt);
const city = await GVGCityModel.decreasePlayer(configId, groupId, serverType, cityId, roleId);
if (!city) {
return resResult(STATUS.GVG_CITY_NOT_FOUND);
}
// 更新玩家城池和队伍城池
gvgUserData = await GVGUserDataModel.changeCity(configId, myLeague.leagueCode, roleId, 0);
const res = await GVGTeamModel.resetTeamsLoc(roleId, 0, 0);
if (!res) {
return resResult(STATUS.GVG_RESET_TEAM_LOC_FAILED);
}
// ! 还需处理内存数据
await GVGTeamModel.enterCity(roleId, 0, 0, groupId, serverType);
// 处理内存数据
let teamObj = getGVGBattleData(groupId, serverType);
teamObj.leaveCity(roleId);
return resResult(STATUS.SUCCESS);
}
@@ -152,19 +160,46 @@ export class GVGBattleHandler {
// 开始移动
// areaId: 要移动的目标据点 id
async startMove(msg: { cityId: number, areaId: number, teamCode: string }, session: BackendSession) {
const { areaId, cityId } = msg;
const moveTime = Date.now();
const roleId = session.get('roleId');
const serverId = session.get('serverId');
const { areaId, cityId, teamCode } = msg;
return resResult(STATUS.SUCCESS, { areaId, cityId, moveTime });
let groupId = await getGroupIdOfServer(serverId);
let serverType = await getGVGServerType(serverId);
let team = await GVGTeamModel.findByTeamCode(roleId, teamCode);
let checkResult = checkMoveStatus(team, cityId, areaId);
if(checkResult.code != 0) return resResult(checkResult);
team = await GVGTeamModel.startMove(teamCode, areaId);
// 更新内存数据
let teamObj = getGVGBattleData(groupId, serverType);
teamObj.move(teamCode, areaId, team.startMoveTime, team.stopMoveTime);
return resResult(STATUS.SUCCESS, { areaId, cityId, stopMoveTime: team.stopMoveTime });
}
// 停止移动
// areaId: 移动到的目标据点 id
async stopMove(msg: { cityId: number, areaId: number, teamCode: string }, session: BackendSession) {
const roleId = session.get('roleId');
const serverId = session.get('serverId');
const { areaId, cityId, teamCode } = msg;
const players = await GVGUserDataModel.find({ cityId, areaId }).limit(20).lean();
const curTeam = await GVGTeamModel.findOneAndUpdate({ teamCode }, { areaId }).lean();
return resResult(STATUS.SUCCESS, { areaId, cityId, players, curTeam });
let groupId = await getGroupIdOfServer(serverId);
let serverType = await getGVGServerType(serverId);
let team = await GVGTeamModel.findByTeamCode(roleId, teamCode);
if(!team) return resResult(STATUS.GVG_BATTLE_TEAM_NOT_FOUND);
if(team.cityId != cityId && team.areaId != areaId) return resResult(STATUS.GVG_BATTLE_IS_NOT_IN_CITY);
team = await GVGTeamModel.stopMove(teamCode, areaId);
// 更新内存数据
let teamObj = getGVGBattleData(groupId, serverType);
teamObj.move(teamCode, areaId, team.startMoveTime, team.stopMoveTime);
return resResult(STATUS.SUCCESS, { areaId, cityId, curTeam: team });
}
// 队伍入驻积分点
@@ -182,29 +217,36 @@ export class GVGBattleHandler {
// 队伍开始攻击
// teamCode: 攻击方队伍
// oppoTeamCode: 防守方队伍
async battleStart(msg: { teamCode: string, oppoTeamCode: string }, session: BackendSession) {
async battleStart(msg: { cityId: number, teamCode: string, oppoTeamCode: string, pointId: number }, session: BackendSession) {
const roleId = session.get('roleId');
const serverId = session.get('serverId');
const { teamCode, oppoTeamCode } = msg;
const teams = await GVGTeamModel.find({ teamCode: { $in: [ teamCode, oppoTeamCode ] } }).lean();
let teamInvalid = false;
let invalidTeamCode = '';
teams.forEach(team => {
if (team.attackTime > Date.now() - 1000 * 5) {
teamInvalid = true;
invalidTeamCode = team.teamCode;
}
});
if (teamInvalid) {
return resResult(STATUS.GVG_BATTLE_TEAM_INVALID, { teamCode: invalidTeamCode });
}
// 生成 battleCode
const battleCode = genCode(8);
return resResult(STATUS.SUCCESS, { battleCode });
let groupId = await getGroupIdOfServer(serverId);
let serverType = await getGVGServerType(serverId);
let { attackTeam, defenseTeam } = await GVGTeamModel.findBattleTeams(teamCode, oppoTeamCode);
if(!attackTeam || !defenseTeam) return resResult(STATUS.GVG_BATTLE_TEAM_INVALID);
if(attackTeam.attackTime > nowSeconds()) return resResult(STATUS.GVG_TEAM_ATTACKING);
if(defenseTeam.defenseTime > nowSeconds()) return resResult(STATUS.GVG_TEAM_DEFENSEING);
const battleRecord = await GVGBattleRecModel.createRec(attackTeam, defenseTeam);
attackTeam = await GVGTeamModel.lockAttack(teamCode, groupId, serverType);
defenseTeam = await GVGTeamModel.lockDefense(oppoTeamCode, groupId, serverType);
// 内存处理
let teamObj = getGVGBattleData(groupId, serverType);
teamObj.setTime(teamCode, attackTeam);
teamObj.setTime(teamCode, defenseTeam);
return resResult(STATUS.SUCCESS, { battleCode: battleRecord.battleCode, curTeam: attackTeam });
}
// 队伍停止攻击
async battleEnd(msg: { battleCode: string, isSuccess: boolean }, session: BackendSession) {
async battleEnd(msg: { cityId: number, battleCode: string, isSuccess: boolean }, session: BackendSession) {
const { battleCode, isSuccess } = msg;
// ! 根据 battleCode 获取 teamCode
const record = await GVGBattleRecModel.findByBattleCode(battleCode);
if(!record) return resResult(STATUS.GVG_BATTLEREC_NOT_FOUND);
const teamCode = '';
const leagueGoods: LeagueGood[] = null;
// ! 计算并更新两支队伍耐久
@@ -223,7 +265,7 @@ export class GVGBattleHandler {
// 使用道具
// teamCode: 要使用道具的队伍
async useItem(msg: { itemId: number, teamCode: string }, session: BackendSession) {
async useItem(msg: { cityId: number, itemId: number, teamCode: string }, session: BackendSession) {
const { itemId, teamCode } = msg;
// ! 检查道具是否存在
// ! 检查道具是否可以使用在该队伍
@@ -233,7 +275,7 @@ export class GVGBattleHandler {
}
// 复活队伍
async reviveTeam(msg: { teamCode: string }, session: BackendSession) {
async reviveTeam(msg: { cityId: number, teamCode: string }, session: BackendSession) {
const { teamCode } = msg;
// ! 检查该队伍是否可以复活,可以的话更新队伍状态
const team = await GVGTeamModel.findOneAndUpdate({ teamCode }, {}).lean();
@@ -269,22 +311,4 @@ export class GVGBattleHandler {
]);
return resResult(STATUS.SUCCESS, { teams });
}
// debug 接口,创建城市
async createCity(msg: { cityId: number, magicWord: string }, session: BackendSession) {
const { cityId, magicWord } = msg;
if (magicWord !== DEBUG_MAGIC_WORD) {
return resResult(STATUS.INTERNAL_ERR);
}
let { configId } = getGVGPeriodData();
// 检查城市是否存在
let city = await GVGCityModel.getCityByCityId(configId, cityId);
if (city) {
return resResult(STATUS.SUCCESS, { city });
}
city = await GVGCityModel.createCity(configId, cityId);
return resResult(STATUS.SUCCESS, { city });
}
}