diff --git a/game-server/app.ts b/game-server/app.ts index 5e328d422..e24957fc4 100644 --- a/game-server/app.ts +++ b/game-server/app.ts @@ -207,9 +207,9 @@ async function treatStartLogic(app: _pinus.Application) { setGVGServerGroup(); } if(app.getServerType() == 'guild') { - setGVGConfig(); + app.event.on('start_all', () => { - initTeamToMem(); + setGVGConfig().then(initTeamToMem); }); } @@ -218,6 +218,7 @@ async function treatStartLogic(app: _pinus.Application) { redisService.readDataBase(); redisService.clearComBtlQueue(); redisService.clearChannelServers(); + redisService.clearGVGHistoryAreas(); updateTeamStatus(COM_TEAM_STATUS.DEFAULT, COM_TEAM_STATUS.LOOSE); updateTeamStatus(COM_TEAM_STATUS.FIGHTING, COM_TEAM_STATUS.LOOSE); } diff --git a/game-server/app/servers/connector/handler/entryHandler.ts b/game-server/app/servers/connector/handler/entryHandler.ts index 54569e624..d41b6f540 100644 --- a/game-server/app/servers/connector/handler/entryHandler.ts +++ b/game-server/app/servers/connector/handler/entryHandler.ts @@ -11,7 +11,7 @@ import { COM_BTL_QUALITY, HERO_SELECT, DEBUG_MAGIC_WORD, REDIS_KEY, TASK_TYPE, E import { nowSeconds, getZeroPoint } from '../../../pubUtils/timeUtil'; import { rmRoleFromQueue, roleLeave, getRoleOnlineInfo, roleLogin, getOnlineRoleByUserCode } from '../../../services/redisService'; -import { addRoleToGuildChannel, addRoleToSysChannel, addRoleToWorldChannel, leaveGroupShopChannel, leaveGuildAuctionChannel, leaveGuildChannel, leaveSysChannel, leaveWorldAuctionChannel, leaveWorldChannel } from '../../../services/chatService'; +import { addRoleToGuildChannel, addRoleToSysChannel, addRoleToWorldChannel, leaveGroupShopChannel, leaveGuildAuctionChannel, leaveGuildChannel, leaveGVGAreaChannel, leaveGVGAreaTeamChannel, leaveSysChannel, leaveWorldAuctionChannel, leaveWorldChannel } from '../../../services/chatService'; import { reportOneOnline, savePlayTime } from '../../../services/authenticateService'; import { checkTaskInEntry, } from '../../../services/task/taskService'; import { pushData, kickUser, getModuleData, assignServer, leaveServer } from '../../../services/connectorService'; @@ -213,12 +213,18 @@ export class EntryHandler { let channelService = this.app.get('channelService'); let channel = channelService.getChannel(roleId, true); channel.leave(roleId, sid); - await leaveSysChannel(roleId, sid, serverId); - await leaveWorldChannel(roleId, sid, serverId); - await leaveGuildChannel(roleId, sid, guildCode); - await leaveGuildAuctionChannel(roleId, sid, guildCode); - await leaveWorldAuctionChannel(roleId, sid, serverId); - await leaveGroupShopChannel(roleId, sid); + try { + await leaveSysChannel(roleId, sid, serverId); + await leaveWorldChannel(roleId, sid, serverId); + await leaveGuildChannel(roleId, sid, guildCode); + await leaveGuildAuctionChannel(roleId, sid, guildCode); + await leaveWorldAuctionChannel(roleId, sid, serverId); + await leaveGroupShopChannel(roleId, sid); + await leaveGVGAreaChannel(roleId, sid); + await leaveGVGAreaTeamChannel(roleId, sid); + } catch(e) { + console.error(e); + } RoleModel.updateRoleInfo(roleId, { quitTime: nowSeconds() }); // if(teamCode) { // 如果有寻宝中的队伍,那么等于战败 // setComBtlOnUserLeave(roleId, teamCode) diff --git a/game-server/app/servers/guild/handler/gvgBattleHandler.ts b/game-server/app/servers/guild/handler/gvgBattleHandler.ts index c9c7a1ba9..d901835fe 100644 --- a/game-server/app/servers/guild/handler/gvgBattleHandler.ts +++ b/game-server/app/servers/guild/handler/gvgBattleHandler.ts @@ -4,11 +4,11 @@ import { GVGAreaInMap, GVGTeamInList, GVGTeamInListOnPoint, GVGTeamSpineInMap, L import { GVGTeamModel, GVGTeamType, GVGTeamUpdate } from '../../../db/GVGTeam'; import { GVGUserDataModel } from '../../../db/GVGUserData'; import { GVGCityModel } from '../../../db/GVGCity'; -import { Application, BackendSession, ChannelService, HandlerService } from "pinus"; +import { Application, BackendSession, ChannelService, HandlerService, pinus } from "pinus"; import { resResult, genCode } from "../../../pubUtils/util"; import { GVGLeagueModel } from '../../../db/GVGLeague'; import { checkGVGPeriod, getGroupIdOfServer, getGVGConfig, getGVGPeriodData, getGVGServerType } from '../../../services/gvg/gvgService'; -import { addBattleRankScore, calBattleScoreByCe, checkAreaIsInCity, checkGVGBattleStart, checkMoveStatus, getBattleRanks, getBirthAreaOfCity, getGVGWarId, getOppHeroes, initRobots, teamBreak } from '../../../services/gvg/gvgBattleService'; +import { addBattleRankScore, calBattleScoreByCe, checkAreaIsInCity, checkGVGBattleStart, checkMoveStatus, getBattleRanks, getBirthAreaOfCity, getGVGWarId, getOppHeroes, initRobots, pushTeamMoveMessage, teamBreak } from '../../../services/gvg/gvgBattleService'; import { getGVGBattleData } from '../../../services/gvg/gvgBattleMemory'; import { nowSeconds } from '../../../pubUtils/timeUtil'; import { GVGBattleRecModel } from '../../../db/GVGBattleRec'; @@ -19,11 +19,12 @@ import { checkBattleHeroesByHid } from '../../../services/normalBattleService'; import { pick } from 'underscore'; import { SaveTeamParam, SaveTeamUpdateParam } from '../../../domain/gvgField/gvgDb'; import { GVG_PERIOD, PUSH_ROUTE, STATUS } from '../../../consts'; -import { sendMessageToUserWithSuc } from '../../../services/pushService'; +import { sendMessageToGVGAreaByTeamWithSuc, sendMessageToUserWithSuc } from '../../../services/pushService'; import { GVGHeroInfo } from '../../../domain/dbGeneral'; import { ArtifactModel } from '../../../db/Artifact'; import { getHeroesAttributes } from '../../../services/playerCeService'; import { gvgBattleEndSchedule, gvgBattleStartSchedule } from '../../../services/timeTaskService'; +import { addRoleToAreaChannel, addRoleToAreaTeamChannel, leaveGVGAreaChannel, leaveGVGAreaTeamChannel } from '../../../services/chatChannelService'; export default function (app: Application) { new HandlerService(app, {}); @@ -218,6 +219,7 @@ export class GVGBattleHandler { async leaveCity(msg: { cityId: number }, session: BackendSession) { const roleId = session.get('roleId'); + const sid = session.get('sid'); const guildCode = session.get('guildCode'); const serverId = session.get('serverId'); const { cityId } = msg; @@ -249,11 +251,16 @@ export class GVGBattleHandler { let teamObj = getGVGBattleData(groupId, serverType); teamObj.leaveCity(roleId); + await leaveGVGAreaChannel(roleId, sid); + await leaveGVGAreaTeamChannel(roleId, sid); + return resResult(STATUS.SUCCESS); } // 获取区域上的队伍 async getAreaTeams(msg: { cityId: number, areaIds: number[] }, session: BackendSession) { + const roleId = session.get('roleId'); + const sid = session.get('sid'); const serverId = session.get('serverId'); const { cityId, areaIds } = msg; @@ -271,6 +278,9 @@ export class GVGBattleHandler { let spines = teams.map(team => new GVGTeamSpineInMap(team, serverNames)); result.push({ areaId, spines }) } + // 加入频道 + await leaveGVGAreaChannel(roleId, sid); + await addRoleToAreaChannel(roleId, groupId, serverType, areaIds, sid); return resResult(STATUS.SUCCESS, { cityId, areas: result }); } @@ -278,6 +288,7 @@ export class GVGBattleHandler { // 点击自己的编队获取区域列表 async getAreaOfMyTeam(msg: { cityId: number, teamCode: string }, session: BackendSession) { const roleId = session.get('roleId'); + const sid = session.get('sid'); const serverId = session.get('serverId'); const { cityId, teamCode } = msg; @@ -302,6 +313,10 @@ export class GVGBattleHandler { players.push(obj); } } + + await leaveGVGAreaTeamChannel(roleId, sid); + await addRoleToAreaTeamChannel(roleId, groupId, serverType, myTeam.areaId, sid); + return resResult(STATUS.SUCCESS, { cityId, areaId: myTeam.areaId, points, players }); @@ -327,6 +342,7 @@ export class GVGBattleHandler { let teamObj = getGVGBattleData(groupId, serverType); teamObj.move(teamCode, areaId, team.fromAreaId, team.startMoveTime, team.stopMoveTime); + await pushTeamMoveMessage(team); return resResult(STATUS.SUCCESS, { areaId, cityId, stopMoveTime: team.stopMoveTime }); } @@ -466,10 +482,8 @@ export class GVGBattleHandler { teamObj.battleEnd([attackTeam, defenseTeam]); // 更新rec await GVGBattleRecModel.battleEnd(battleCode, isSuccess); - // TODO 完善推送 - if(!defenseTeam.isRobot) { - sendMessageToUserWithSuc(defenseTeam.roleId, PUSH_ROUTE.GVG_TEAM_ATTACKED, { cityId, areaId: defenseTeam.areaId, teams: [defenseTeam] }); - } + + return resResult(STATUS.SUCCESS, { curTeam: new MyTeamInfo(attackTeam) }); } @@ -510,12 +524,12 @@ export class GVGBattleHandler { } async debugStartSchedule() { - await gvgBattleStartSchedule(); + await pinus.app.rpc.systimer.systimerRemote.gvgBattleStartSchedule.broadcast(); return resResult(STATUS.SUCCESS); } async debugEndSchedule() { - await gvgBattleEndSchedule(); + await pinus.app.rpc.systimer.systimerRemote.gvgBattleEndSchedule.broadcast(); return resResult(STATUS.SUCCESS); } } diff --git a/game-server/app/servers/systimer/remote/systimerRemote.ts b/game-server/app/servers/systimer/remote/systimerRemote.ts index 5a91886b0..753177fff 100644 --- a/game-server/app/servers/systimer/remote/systimerRemote.ts +++ b/game-server/app/servers/systimer/remote/systimerRemote.ts @@ -1,5 +1,5 @@ import { Application, ChannelService } from 'pinus'; -import { guildActivityStart, gateActivityEnd, cityActivityEnd, raceActivityEnd, guildActivitySchedule, auctionSchedule, initMaintenance, stopMaintenance, initAutoCreateServer, addMailsToSchedule, updateTimeLimitRank, setLadderCountDown, cancelLadderCountDown, initSumSchedule, setPvpSeasonSchedule, initGVGConfigSchedule } from '../../../services/timeTaskService'; +import { guildActivityStart, gateActivityEnd, cityActivityEnd, raceActivityEnd, guildActivitySchedule, auctionSchedule, initMaintenance, stopMaintenance, initAutoCreateServer, addMailsToSchedule, updateTimeLimitRank, setLadderCountDown, cancelLadderCountDown, initSumSchedule, setPvpSeasonSchedule, initGVGConfigSchedule, gvgBattleStartSchedule, gvgBattleEndSchedule } from '../../../services/timeTaskService'; import PvpDefenseType from '../../../db/PvpDefense'; import { DicGuildActivity } from '../../../pubUtils/dictionary/DicGuildActivity'; import { reloadResources } from '../../../pubUtils/data'; @@ -258,4 +258,20 @@ export class SystimerRemote { errlogger.error(`remote ${__filename} \n ${e.stack}`); } } + + public async gvgBattleStartSchedule() { + try { + await gvgBattleStartSchedule(); + } catch(e) { + errlogger.error(`remote ${__filename} \n ${e.stack}`); + } + } + + public async gvgBattleEndSchedule() { + try { + await gvgBattleEndSchedule(); + } catch(e) { + errlogger.error(`remote ${__filename} \n ${e.stack}`); + } + } } diff --git a/game-server/app/services/chatChannelService.ts b/game-server/app/services/chatChannelService.ts index fcbde39b1..b115c5bf0 100644 --- a/game-server/app/services/chatChannelService.ts +++ b/game-server/app/services/chatChannelService.ts @@ -1,5 +1,5 @@ -import { addRedisChannel, redisChannelServer } from './redisService'; +import { addGVGHistoryAreas, addGVGHistoryAreaTeam, addRedisChannel, getGVGHistoryAreas, getGVGHistoryAreaTeam, redisChannelServer } from './redisService'; import { groupRoomId } from './chatService'; import { pinus } from 'pinus'; import { crc32 } from 'crc'; @@ -61,6 +61,20 @@ export async function addRoleToGroupShopChannel(roleId: string, sid: string) { await addRoleToChannel(roomId, roleId, sid); } +export async function addRoleToAreaChannel(roleId: string, groupId: number, serverType: number, areaIds: number[], sid: string) { + for(let areaId of areaIds) { + const roomId = groupRoomId(CHANNEL_PREFIX.GVG_AREAS, `${groupId}_${serverType}_${areaId}`); + await addRoleToChannel(roomId, roleId, sid); + } + await addGVGHistoryAreas(roleId, groupId, serverType, areaIds); +} + +export async function addRoleToAreaTeamChannel(roleId: string, groupId: number, serverType: number, areaId: number, sid: string) { + const roomId = groupRoomId(CHANNEL_PREFIX.GVG_AREA_BY_TEAM, `${groupId}_${serverType}_${areaId}`); + await addRoleToChannel(roomId, roleId, sid); + await addGVGHistoryAreaTeam(roleId, groupId, serverType, areaId); +} + async function leaveChannel(roomId: string, roleId: string, sid: string) { const channelSid = await channelServer(roomId); await pinus.app.rpc.chat.chatRemote.leaveChannel.toServer(channelSid, roomId, roleId, sid); @@ -102,6 +116,22 @@ export async function leaveGuildChannel(roleId: string, sid: string, guildCode: await leaveChannel(roomId, roleId, sid); } +export async function leaveGVGAreaChannel(roleId: string, sid: string) { + let keys = await getGVGHistoryAreas(roleId)||[]; + for(let key of keys) { + const roomId = groupRoomId(CHANNEL_PREFIX.GVG_AREAS, key); + await leaveChannel(roomId, roleId, sid); + } +} + +export async function leaveGVGAreaTeamChannel(roleId: string, sid: string) { + let channelName = await getGVGHistoryAreaTeam(roleId); + if(channelName) { + const roomId = groupRoomId(CHANNEL_PREFIX.GVG_AREA_BY_TEAM, channelName); + await leaveChannel(roomId, roleId, sid); + } +} + export async function getWorldChannelSid(serverId: number) { const roomId = groupRoomId(CHANNEL_PREFIX.WORLD, serverId); const channelSid = await channelServer(roomId); @@ -138,6 +168,18 @@ export async function getGroupShopSid() { return channelSid; } +export async function getGVGAreaChannelSid(groupId: number, serverType: number, areaId: number) { + const roomId = groupRoomId(CHANNEL_PREFIX.GVG_AREAS, `${groupId}_${serverType}_${areaId}`); + const channelSid = await channelServer(roomId); + return channelSid; +} + +export async function getGVGAreaTeamChannelSid(groupId: number, serverType: number, areaId: number) { + const roomId = groupRoomId(CHANNEL_PREFIX.GVG_AREA_BY_TEAM, `${groupId}_${serverType}_${areaId}`); + const channelSid = await channelServer(roomId); + return channelSid; +} + async function delChannel(roomId: string) { const channelSid = await channelServer(roomId); await pinus.app.rpc.chat.chatRemote.deleteChannel.toServer(channelSid, roomId); diff --git a/game-server/app/services/gvg/gvgBattleMemory.ts b/game-server/app/services/gvg/gvgBattleMemory.ts index 188125777..5cee6920a 100644 --- a/game-server/app/services/gvg/gvgBattleMemory.ts +++ b/game-server/app/services/gvg/gvgBattleMemory.ts @@ -17,7 +17,7 @@ class GVGBattleData { private teams: Map = new Map(); // 队伍, teamCode => team private rolePoints: Map> = new Map(); // roleId => pointId[],用于更新玩家的积分 private roleToTeam: Map = new Map(); // roleId => teamCode - private areaToTeams: Map> = new Map(); // areaId => teamCode set,用于定时下发地图玩家数据 + public areaToTeams: Map> = new Map(); // areaId => teamCode set,用于定时下发地图玩家数据 constructor(groupId: number, serverType: number) { this.groupId = groupId; @@ -152,6 +152,10 @@ class GVGBattleData { } return teams; } + + public findAreas() { + return this.areaToTeams.keys(); + } } export function getGVGBattleData(groupId: number, serverType: number) { @@ -168,7 +172,6 @@ export function getGVGBattleMap() { export async function initTeamToMem() { let sid = pinus.app.getServerId(); - console.log('##### initTeamToMem', sid) let servers = pinus.app.getServersByType('guild'); let { configId, period } = getGVGPeriodData(); // if(period != GVG_PERIOD.BATTLE) return; diff --git a/game-server/app/services/gvg/gvgBattleService.ts b/game-server/app/services/gvg/gvgBattleService.ts index 54118532c..342f4df7a 100644 --- a/game-server/app/services/gvg/gvgBattleService.ts +++ b/game-server/app/services/gvg/gvgBattleService.ts @@ -3,11 +3,11 @@ import { GVGLeagueType } from "../../db/GVGLeague"; import { GVGTeamModel, GVGTeamType, GVGTeamUpdate } from "../../db/GVGTeam"; import { GVGCityModel, GVGCityType } from "../../db/GVGCity"; import { gameData } from "../../pubUtils/data"; -import { GVG_AREA_TYPE, GVG_TECH_TYPE, REDIS_KEY, STATUS } from "../../consts"; +import { GVG_AREA_TYPE, GVG_TECH_TYPE, PUSH_ROUTE, REDIS_KEY, STATUS } from "../../consts"; import { nowSeconds } from "../../pubUtils/timeUtil"; import { DicGVGAreaPoint } from "../../pubUtils/dictionary/DicGVGAreaPoint"; import { getGVGBattleData, getGVGBattleMap } from "./gvgBattleMemory"; -import { GVGCityMapInfo } from "../../domain/gvgField/returnData"; +import { GVGAreaInMap, GVGCityMapInfo, GVGTeamInList, GVGTeamInListOnPoint, GVGTeamSpineInMap } from "../../domain/gvgField/returnData"; import { pick } from "underscore"; import { GVG } from "../../pubUtils/dicParam"; import { GVGHeroInfo, PvpEnemies, PvpHeroInfo } from "../../domain/dbGeneral"; @@ -17,7 +17,8 @@ import { pinus } from "pinus"; import { dispatch } from "../../pubUtils/dispatcher"; import { Rank } from "../rankService"; import { LeagueRankInfo } from "../../domain/rank"; -import { findKeys } from "../redisService"; +import { findKeys, getAllServerName } from "../redisService"; +import { sendMessageToChannel, sendMessageToGVGAreaByTeamWithSuc, sendMessageToGVGAreaWithSuc } from "../pushService"; /** @@ -223,6 +224,12 @@ 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 sendMessageToGVGAreaByTeamWithSuc(teamObj.groupId, teamObj.serverType, catapult.areaId, PUSH_ROUTE.GVG_TEAM_ATTACKED, { + cityId: catapult.cityId, areaId: catapult.areaId, attackType: 1, teams: teams.map(team => new GVGTeamInList(team)) + }); + for(let team of teams) { + await pushTeamBeHurtMessage(team); + } } } } @@ -258,8 +265,9 @@ export async function getBattleRanks(configId: number, groupId: number, serverTy // 每5秒一次结算 export async function gvgBattleSeconds() { - // 每5秒给据点上的人加积分 + const serverNames = await getAllServerName(); for(let [_key, teamObj] of getGVGBattleMap()) { + // 每5秒给据点上的人加积分 let teams = teamObj.findSettledPoint(); for(let teamMem of teams) { if(teamMem.isBroken || teamMem.durability <= 0) continue; @@ -267,8 +275,15 @@ export async function gvgBattleSeconds() { let team = await GVGTeamModel.addScore(teamMem.teamCode, addScore); await addBattleRankScore(team, addScore); } + // 向下推送区域数据 + for(let areaId of teamObj.findAreas()) { + let dicArea = gameData.gvgArea.get(areaId); + let teams = teamObj.findTeamsByArea(areaId); + let result = teams.map(team => new GVGTeamSpineInMap(team, serverNames)); + sendMessageToGVGAreaWithSuc(teamObj.groupId, teamObj.serverType, areaId, PUSH_ROUTE.GVG_AREA_SPINE_CHANGE, { cityId: dicArea.cityId, areaId, spines: result }); + } + } - // 向下推送区域数据 } @@ -300,4 +315,50 @@ export async function gvgBattleEnd() { // 排行榜发放奖励 -} \ No newline at end of file +} + +// —————————— 定时器相关 end —————————— // + +// —————————— 推送相关 —————————— // +// 推送 +export async function battleEndSendMessage(groupId: number, serverType: number, cityId: number, defenseTeam: GVGTeamType, attackTeam: GVGTeamType) { + // 推送伤害 + await sendMessageToGVGAreaByTeamWithSuc(groupId, serverType, defenseTeam.areaId, PUSH_ROUTE.GVG_TEAM_ATTACKED, { + cityId, areaId: defenseTeam.areaId, attackType: 3, teams: [new GVGTeamInList(defenseTeam), new GVGTeamInList(attackTeam)] + }); + await pushTeamBeHurtMessage(defenseTeam, attackTeam); + await pushTeamBeHurtMessage(attackTeam); +} + +// 队伍移动 +export async function pushTeamBeHurtMessage(team: GVGTeamType, replaceTeam?: GVGTeamType) { + + if(team.curTeamBreak && team.originPointId > 0) { + await sendMessageToGVGAreaByTeamWithSuc(team.groupId, team.serverType, team.originPointId, PUSH_ROUTE.GVG_AREA_POINT_CHANGE, { + cityId: team.cityId, areaId: team.originPointId, point: new GVGTeamInListOnPoint(team.originPointId, replaceTeam && !replaceTeam.curTeamBreak, replaceTeam) + }); + } + + await pushTeamMoveMessage(team); + if(team.isRobot && team.isBroken) { + await sendMessageToGVGAreaByTeamWithSuc(team.groupId, team.serverType, team.fromAreaId, PUSH_ROUTE.GVG_PLAYER_LEAVE_AREA, { + cityId: team.cityId, areaId: team.areaId, teamCode: team.teamCode + }); + } +} + +export async function pushTeamMoveMessage(team: GVGTeamType) { + if(team.fromAreaId != team.areaId) { + if(team.fromAreaId > 0) { + await sendMessageToGVGAreaByTeamWithSuc(team.groupId, team.serverType, team.fromAreaId, PUSH_ROUTE.GVG_PLAYER_LEAVE_AREA, { + cityId: team.cityId, areaId: team.fromAreaId, teamCode: team.teamCode + }); + } + if(team.areaId > 0) { + await sendMessageToGVGAreaByTeamWithSuc(team.groupId, team.serverType, team.fromAreaId, PUSH_ROUTE.GVG_PLAYER_AREA_ADD, { + cityId: team.cityId, areaId: team.fromAreaId, player: new GVGTeamInList(team) + }); + } + } +} +// —————————— 推送相关 end —————————— // \ No newline at end of file diff --git a/game-server/app/services/pushService.ts b/game-server/app/services/pushService.ts index 210ef45dc..2b1a4e226 100644 --- a/game-server/app/services/pushService.ts +++ b/game-server/app/services/pushService.ts @@ -1,7 +1,7 @@ import { Channel, pinus } from "pinus"; import { CHANNEL_PREFIX, PUSH_BATCH, PUSH_INTERVAL, PUSH_ROUTE, STATUS } from "../consts"; import { genCode, resResult } from "../pubUtils/util"; -import { getCityChannelSid, getGuildChannelSid, getWorldChannelSid, groupRoomId, getGroupShopSid } from "./chatService"; +import { getCityChannelSid, getGuildChannelSid, getWorldChannelSid, groupRoomId, getGroupShopSid, getGVGAreaChannelSid, getGVGAreaTeamChannelSid } from "./chatService"; import { getAllOnlineRoles, getAllServers, getRoleOnlineInfo } from "./redisService"; import { errlogger, infologger } from '../util/logger'; import { MsgEncrypt } from "../pubUtils/sysUtil"; @@ -61,6 +61,18 @@ export async function sendMessageToGuild(guildCode: string, route: string, data: await pinus.app.rpc.chat.chatRemote.pushMessage.toServer(channelSid, roomId, route, data); } +export async function sendMessageToGVGAreaWithSuc(groupId: number, serverType: number, areaId: number, route: string, data: any) { + let channelSid = await getGVGAreaChannelSid(groupId, serverType, areaId); + let roomId = groupRoomId(CHANNEL_PREFIX.GVG_AREAS, `${groupId}_${serverType}_${areaId}`); + await pinus.app.rpc.chat.chatRemote.pushMessage.toServer(channelSid, roomId, route, data); +} + +export async function sendMessageToGVGAreaByTeamWithSuc(groupId: number, serverType: number, areaId: number, route: string, data: any) { + let channelSid = await getGVGAreaTeamChannelSid(groupId, serverType, areaId); + let roomId = groupRoomId(CHANNEL_PREFIX.GVG_AREA_BY_TEAM, `${groupId}_${serverType}_${areaId}`); + await pinus.app.rpc.chat.chatRemote.pushMessage.toServer(channelSid, roomId, route, data); +} + export async function sendMessageToCityWithSuc(serverId: number, cityId: number, route: string, data: any) { await sendMessageToCity(serverId, cityId, route, resResult(STATUS.SUCCESS, data)); } diff --git a/game-server/app/services/redisService.ts b/game-server/app/services/redisService.ts index 0c92c403d..b5e25931a 100644 --- a/game-server/app/services/redisService.ts +++ b/game-server/app/services/redisService.ts @@ -8,7 +8,7 @@ import { Rank, setRankRedisFromDb } from './rankService'; import { ServerlistModel } from '../db/Serverlist'; import moment = require('moment'); import { getRedisSubChannel } from '../pubUtils/sdkUtil'; -import { getRandSingleEelm } from '../pubUtils/util'; +import { getRandSingleEelm, parseNumberList } from '../pubUtils/util'; import { ActivityModel } from '../db/Activity'; import { TimeLimitRankData } from '../domain/activityField/timeLimitRankField'; import { ActivityTimeLimitRankModel } from '../db/ActivityTimeLimitRank'; @@ -699,3 +699,46 @@ export async function setHistoryCity(roleId: string, cityId: number) { await redisClient().hsetAsync(REDIS_KEY.GA_HISTORY_CITY, `${roleId}`, cityId); } +// gvg激战期玩家之前所处的区域,用于退出的时候查询 +export async function getGVGHistoryAreas(roleId: string) { + let areaIds = await redisClient().hgetAsync(REDIS_KEY.GVG_HISTORY_AREA, roleId); + if(!areaIds) return [] + return areaIds.split('&'); +} + +export async function addGVGHistoryAreas(roleId: string, groupId: number, serverType: number, areaIds: number[]) { + let key = areaIds.map(areaId => `${groupId}_${serverType}_${areaId}`).join('&'); + const result = await redisClient().hsetAsync(REDIS_KEY.GVG_HISTORY_AREA, roleId, key); + return result; +} + +export async function delGVGHistoryAreas(roleId: string) { + const result = await redisClient().hdelAsync(REDIS_KEY.GVG_HISTORY_AREA, roleId); + return result; +} + +export async function clearGVGHistoryAreas() { + const result = await redisClient().delAsync(REDIS_KEY.GVG_HISTORY_AREA); + return result; +} + + +export async function getGVGHistoryAreaTeam(roleId: string) { + let channelName = await redisClient().hgetAsync(REDIS_KEY.GVG_HISTORY_AREA_TEAM, roleId); + return channelName +} + +export async function addGVGHistoryAreaTeam(roleId: string, groupId: number, serverType: number, areaId: number) { + const result = await redisClient().hsetAsync(REDIS_KEY.GVG_HISTORY_AREA_TEAM, roleId, `${groupId}_${serverType}_${areaId}`); + return result; +} + +export async function delGVGHistoryAreaTeam(roleId: string) { + const result = await redisClient().hdelAsync(REDIS_KEY.GVG_HISTORY_AREA_TEAM, roleId); + return result; +} + +export async function clearGVGHistoryAreaTeam() { + const result = await redisClient().delAsync(REDIS_KEY.GVG_HISTORY_AREA_TEAM); + return result; +} diff --git a/shared/consts/constModules/chatConst.ts b/shared/consts/constModules/chatConst.ts index 3277cabcc..90829cc1a 100644 --- a/shared/consts/constModules/chatConst.ts +++ b/shared/consts/constModules/chatConst.ts @@ -23,6 +23,8 @@ export const CHANNEL_PREFIX = { GUILD_AUCTION: 'g_auction', // 军团拍卖 WORLD_AUCTION: 'w_auction', // 军团拍卖 GROUP_SHOP: 'groupShop', // 团购页面 + GVG_AREAS: 'gvgAreas', // 大地图界面 + GVG_AREA_BY_TEAM: 'gvgTeam', // 选中玩家队伍后加入频道 } export const getChannelType = function(prefix: string) { @@ -181,4 +183,8 @@ export const PUSH_ROUTE = { LEAGUE_ITEM_UPDATE: 'onLeagueItemUpdate', GVG_TASK_UPDATE: 'onGVGTaskUpdate', // GVG任务更新 GVG_TEAM_ATTACKED: 'onTeamAttacked', // 当队伍受到攻击 + GVG_AREA_SPINE_CHANGE: 'onAreaSpinesChange', // 可见区域内spine的变动,每隔5秒会下发 + GVG_AREA_POINT_CHANGE: 'onMyAreaPointChange', // 积分点上的驻守人变更 + GVG_PLAYER_AREA_ADD: 'onPlayerAddToArea', // 积分点上的驻守人变更 + GVG_PLAYER_LEAVE_AREA: 'onPlayerLeaveArea', // 积分点上的驻守人变更 } \ No newline at end of file diff --git a/shared/consts/constModules/sysConst.ts b/shared/consts/constModules/sysConst.ts index 9ed6b956e..e304dc782 100644 --- a/shared/consts/constModules/sysConst.ts +++ b/shared/consts/constModules/sysConst.ts @@ -261,6 +261,8 @@ export enum REDIS_KEY { LEAGUE_INFO ="leagueInfo", // 联军信息 GVG_BATTLE_RANK ="gvgBattleUsr", // 激战期个人排行榜 GVG_BATTLE_LEAGUE_RANK = "gvgBattleLeague", // 激战期联军排行榜 + GVG_HISTORY_AREA ='gvgHisArea', // gvg激战期玩家加入的区域 + GVG_HISTORY_AREA_TEAM ='gvgHisAreaTeam', // gvg激战期玩家加入的区域 } // 各排行榜对应hash的key diff --git a/shared/db/GVGTeam.ts b/shared/db/GVGTeam.ts index 58dfff809..649aa2d15 100644 --- a/shared/db/GVGTeam.ts +++ b/shared/db/GVGTeam.ts @@ -119,6 +119,9 @@ export default class GVGTeam extends BaseModel { @prop({ required: false }) batchCode: string; // 批量编号 + originPointId: number; + curTeamBreak: boolean; + // 创建队伍 public static async saveTeam(roleId: string, index: number, updateParam: SaveTeamUpdateParam, initParam: InitTeamParam) { const doc = new GVGTeamModel(); @@ -256,12 +259,13 @@ export default class GVGTeam extends BaseModel { public static async battleEndAttack(teamCode: string, hpInc: number, playerScoreInc: number, rebirthAreaId: number) { let team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $inc: { durability: hpInc, score: playerScoreInc } }, { new: true }).lean(); if(team.durability <= 0) { + let originPointId = team.pointId; team = await GVGTeamModel.teamBreak(teamCode, team.isRobot, team.maxDurability, rebirthAreaId); + team.originPointId = originPointId; } return team; } - originPointId: number; // 结算防守方 public static async battleEndDefense(teamCode: string, hpInc: number, playerScoreInc: number, rebirthAreaId: number) { let team: GVGTeamType = await GVGTeamModel.findOneAndUpdate({ teamCode }, { $set: { defenseTime: nowSeconds() + GVG.GVG_DEFAULT_DEFENSE_CD, lockTime: 0, lockTeamCode: '' }, $inc: { durability: hpInc, score: playerScoreInc } }, { new: true }).lean(); @@ -273,7 +277,6 @@ export default class GVGTeam extends BaseModel { return team; } - curTeamBreak: boolean; // 队伍进入修整器 public static async teamBreak(teamCode: string, isRobot: boolean, maxDurability: number, areaId: number) { if(!isRobot) { @@ -313,7 +316,14 @@ export default class GVGTeam extends BaseModel { })); } let teams: GVGTeamType[] = await GVGTeamModel.find({ batchCode }).lean(); - return teams + return teams.map(team => { + let originTeam = brokenTeams.find(origin => origin.teamCode == team.teamCode); + if(originTeam) { + team.originPointId = originTeam.originPointId; + team.curTeamBreak = originTeam.curTeamBreak; + } + return team + }) } // 加积分 diff --git a/shared/db/GVGUserItem.ts b/shared/db/GVGUserItem.ts index 21ed2d7a0..af883d548 100644 --- a/shared/db/GVGUserItem.ts +++ b/shared/db/GVGUserItem.ts @@ -55,7 +55,7 @@ export default class GVGUserItem extends BaseModel { } public static async checkItemCnt(configId: number, leagueCode: string, roleId: string, id: number, count: number) { - return await GVGUserItemModel.exists({ configId, leagueCode, roleId, id, count: { $gte: count } }); + return await GVGUserItemModel.exists({ configId, leagueCode, roleId, id, count: { $gte: count }, expireTime: { $gte: nowSeconds() } }); } } diff --git a/shared/resource/jsons/dic_zyz_GVGItems.json b/shared/resource/jsons/dic_zyz_GVGItems.json index 95df3b35f..4a260315e 100644 --- a/shared/resource/jsons/dic_zyz_GVGItems.json +++ b/shared/resource/jsons/dic_zyz_GVGItems.json @@ -12,7 +12,7 @@ "value": 1000, "reward": "40005&1000", "leagueReward": "12&100", - "ripeTime": 600, + "ripeTime": 14400, "getWays": "&", "info_1": "&" }, @@ -29,7 +29,7 @@ "value": 1500, "reward": "40005&1400", "leagueReward": "12&150", - "ripeTime": 900, + "ripeTime": 18000, "getWays": "&", "info_1": "&" }, @@ -46,7 +46,7 @@ "value": 2000, "reward": "40005&1800", "leagueReward": "12&150", - "ripeTime": 1200, + "ripeTime": 21600, "getWays": "&", "info_1": "&" }, diff --git a/shared/resource/jsons/dic_zyz_GVGResourceBase.json b/shared/resource/jsons/dic_zyz_GVGResourceBase.json index 80c164d9f..25109857c 100644 --- a/shared/resource/jsons/dic_zyz_GVGResourceBase.json +++ b/shared/resource/jsons/dic_zyz_GVGResourceBase.json @@ -5,9 +5,9 @@ "lv": 1, "type": 1, "image_id": "&", - "limit": "6名武将3星", + "limit": "6名武将2星", "limitType": 1, - "limitParams": "6&3", + "limitParams": "6&2", "value": "1&0", "sum": 100, "size": "&" @@ -44,9 +44,9 @@ "lv": 4, "type": 1, "image_id": "&", - "limit": "6名武将4星", + "limit": "6名武将5星", "limitType": 1, - "limitParams": "6&4", + "limitParams": "6&5", "value": "1&15", "sum": 100, "size": "&" @@ -57,9 +57,9 @@ "lv": 5, "type": 1, "image_id": "&", - "limit": "6名武将5星", + "limit": "6名武将6星", "limitType": 1, - "limitParams": "6&5", + "limitParams": "6&6", "value": "1&20", "sum": 100, "size": "&" @@ -70,9 +70,9 @@ "lv": 6, "type": 1, "image_id": "&", - "limit": "6名武将5星", + "limit": "6名武将7星", "limitType": 1, - "limitParams": "6&5", + "limitParams": "6&7", "value": "1&25", "sum": 100, "size": "&" @@ -83,9 +83,9 @@ "lv": 7, "type": 1, "image_id": "&", - "limit": "6名武将6星", + "limit": "6名武将8星", "limitType": 1, - "limitParams": "6&6", + "limitParams": "6&8", "value": "1&30", "sum": 100, "size": "&" @@ -96,9 +96,9 @@ "lv": 8, "type": 1, "image_id": "&", - "limit": "6名武将6星", + "limit": "12名武将8星", "limitType": 1, - "limitParams": "6&6", + "limitParams": "12&8", "value": "1&35", "sum": 100, "size": "&" @@ -109,9 +109,9 @@ "lv": 9, "type": 1, "image_id": "&", - "limit": "6名武将7星", + "limit": "12名武将9星", "limitType": 1, - "limitParams": "6&7", + "limitParams": "12&9", "value": "1&40", "sum": 100, "size": "&" @@ -122,9 +122,9 @@ "lv": 10, "type": 1, "image_id": "&", - "limit": "6名武将8星", + "limit": "12名武将10星", "limitType": 1, - "limitParams": "6&8", + "limitParams": "12&10", "value": "1&50", "sum": 100, "size": "&" @@ -135,11 +135,11 @@ "lv": 1, "type": 2, "image_id": "&", - "limit": "6件装备1星", + "limit": "4件装备1星", "limitType": 2, - "limitParams": "6&1", + "limitParams": "4&1", "value": "1&100&5|2&120&3|3&150&2", - "sum": 400, + "sum": 300, "size": "5&8" }, { @@ -148,11 +148,11 @@ "lv": 2, "type": 2, "image_id": "&", - "limit": "6件装备1星", + "limit": "8件装备1星", "limitType": 2, - "limitParams": "6&1", + "limitParams": "8&1", "value": "1&100&3|2&120&5|3&150&2", - "sum": 400, + "sum": 300, "size": "5&8" }, { @@ -161,11 +161,11 @@ "lv": 3, "type": 2, "image_id": "&", - "limit": "6件装备2星", + "limit": "12件装备2星", "limitType": 2, - "limitParams": "6&2", + "limitParams": "12&2", "value": "1&100&2|2&120&3|3&150&5", - "sum": 400, + "sum": 300, "size": "5&8" }, { @@ -174,11 +174,11 @@ "lv": 4, "type": 2, "image_id": "&", - "limit": "6件装备2星", + "limit": "12件装备3星", "limitType": 2, - "limitParams": "6&2", + "limitParams": "12&3", "value": "1&100&5|2&120&3|3&150&5", - "sum": 400, + "sum": 300, "size": "5&9" }, { @@ -187,11 +187,11 @@ "lv": 5, "type": 2, "image_id": "&", - "limit": "6件装备3星", + "limit": "24件装备3星", "limitType": 2, - "limitParams": "6&3", + "limitParams": "24&3", "value": "1&100&3|2&120&5|3&150&5", - "sum": 400, + "sum": 300, "size": "5&9" }, { @@ -200,11 +200,11 @@ "lv": 6, "type": 2, "image_id": "&", - "limit": "6件装备4星", + "limit": "24件装备4星", "limitType": 2, - "limitParams": "6&4", + "limitParams": "24&4", "value": "2&120&5|3&150&5|4&180&3", - "sum": 400, + "sum": 300, "size": "5&9" }, { @@ -213,11 +213,11 @@ "lv": 7, "type": 2, "image_id": "&", - "limit": "6件装备5星", + "limit": "24件装备5星", "limitType": 2, - "limitParams": "6&5", + "limitParams": "24&5", "value": "2&120&3|3&150&5|4&180&5", - "sum": 400, + "sum": 300, "size": "5&9" }, { @@ -226,11 +226,11 @@ "lv": 8, "type": 2, "image_id": "&", - "limit": "6件装备6星", + "limit": "48件装备5星", "limitType": 2, - "limitParams": "6&6", + "limitParams": "48&5", "value": "2&120&5|3&150&5|4&180&5", - "sum": 400, + "sum": 300, "size": "6&9" }, { @@ -239,11 +239,11 @@ "lv": 9, "type": 2, "image_id": "&", - "limit": "6件装备7星", + "limit": "48件装备6星", "limitType": 2, - "limitParams": "6&7", + "limitParams": "48&6", "value": "2&120&3|3&150&7|4&180&5", - "sum": 400, + "sum": 300, "size": "6&9" }, { @@ -252,11 +252,11 @@ "lv": 10, "type": 2, "image_id": "&", - "limit": "6件装备8星", + "limit": "48件装备7星", "limitType": 2, - "limitParams": "6&8", + "limitParams": "48&7", "value": "2&120&3|3&150&5|4&180&7", - "sum": 400, + "sum": 300, "size": "6&9" }, { @@ -269,7 +269,7 @@ "limitType": 3, "limitParams": 1000000, "value": "3&100", - "sum": 500, + "sum": 200, "size": "&" }, { @@ -282,7 +282,7 @@ "limitType": 3, "limitParams": 1500000, "value": "3&150", - "sum": 500, + "sum": 200, "size": "&" }, { @@ -295,7 +295,7 @@ "limitType": 3, "limitParams": 2000000, "value": "3&200", - "sum": 500, + "sum": 200, "size": "&" }, { @@ -308,7 +308,7 @@ "limitType": 3, "limitParams": 2500000, "value": "3&250", - "sum": 500, + "sum": 200, "size": "&" }, { @@ -321,7 +321,7 @@ "limitType": 3, "limitParams": 3000000, "value": "3&300", - "sum": 500, + "sum": 200, "size": "&" }, { @@ -330,11 +330,11 @@ "lv": 6, "type": 3, "image_id": "&", - "limit": "最强6人战力达3500000", + "limit": "最强6人战力达4000000", "limitType": 3, - "limitParams": 3500000, + "limitParams": 4000000, "value": "3&350", - "sum": 500, + "sum": 200, "size": "&" }, { @@ -343,11 +343,11 @@ "lv": 7, "type": 3, "image_id": "&", - "limit": "最强6人战力达4000000", + "limit": "最强6人战力达5000000", "limitType": 3, - "limitParams": 4000000, + "limitParams": 5000000, "value": "3&400", - "sum": 500, + "sum": 200, "size": "&" }, { @@ -356,11 +356,11 @@ "lv": 8, "type": 3, "image_id": "&", - "limit": "最强6人战力达4500000", + "limit": "最强6人战力达6000000", "limitType": 3, - "limitParams": 4500000, + "limitParams": 6000000, "value": "3&450", - "sum": 500, + "sum": 200, "size": "&" }, { @@ -369,11 +369,11 @@ "lv": 9, "type": 3, "image_id": "&", - "limit": "最强6人战力达5000000", + "limit": "最强6人战力达7000000", "limitType": 3, - "limitParams": 5000000, + "limitParams": 7000000, "value": "3&500", - "sum": 500, + "sum": 200, "size": "&" }, { @@ -382,11 +382,11 @@ "lv": 10, "type": 3, "image_id": "&", - "limit": "最强6人战力达6000000", + "limit": "最强6人战力达9000000", "limitType": 3, - "limitParams": 6000000, + "limitParams": 9000000, "value": "3&600", - "sum": 500, + "sum": 200, "size": "&" } ] \ No newline at end of file