diff --git a/game-server/app/servers/battle/handler/normalBattleHandler.ts b/game-server/app/servers/battle/handler/normalBattleHandler.ts index 29c6528e0..2772ad412 100644 --- a/game-server/app/servers/battle/handler/normalBattleHandler.ts +++ b/game-server/app/servers/battle/handler/normalBattleHandler.ts @@ -591,4 +591,63 @@ export class NormalBattleHandler { return; } + + // 是否可以跳过 + async checkSkip(msg: { battleCode: string }, session: BackendSession) { + const { battleCode } = msg; + let roleId = session.get('roleId'); + + let role = await RoleModel.findByRoleId(roleId, 'warStar vipStartTime'); + if(!role) return resResult(STATUS.ROLE_NOT_FOUND); + let { warStar, vipStartTime } = role; + + if(!vipStartTime || vipStartTime == 0) { + return resResult(STATUS.SUCCESS, { + battleCode, + canSkip: false + }); + } + + let battleRecord = await BattleRecordModel.getBattleRecordByCode(battleCode); + if(!battleRecord || battleRecord.roleId != roleId) return resResult(STATUS.BATTLE_NOT_FOUND); + let battleId = battleRecord.battleId; + let dicWar = gameData.war.get(battleId); + if(!dicWar) return resResult(STATUS.DIC_DATA_NOT_FOUND); + + let hasPass = warStar.findIndex(cur => cur.id == battleId) != -1; // 是否首通过 + let canSkip = false; + switch (dicWar.warType) { + case WAR_TYPE.VESTIGE: + case WAR_TYPE.BRANCH_ELITE: + case WAR_TYPE.ACT_DAILY_GK: + case WAR_TYPE.ACT_NEW_HERO_GK: + canSkip = false; + break; + case WAR_TYPE.NORMAL: + canSkip = dicWar.chapter != 0 && hasPass; + break; + case WAR_TYPE.MAIN_ELITE: + case WAR_TYPE.MYSTERY: + canSkip = hasPass; + break; + case WAR_TYPE.ACT_TREASURE_HUNT: + case WAR_TYPE.ACT_SELF_SHOP: + case WAR_TYPE.TOWER: + case WAR_TYPE.LADDER: + case WAR_TYPE.GUILD_TRAIN: + case WAR_TYPE.PVP: + case WAR_TYPE.DAILY: + case WAR_TYPE.EVENT: + case WAR_TYPE.EXPEDITION: + case WAR_TYPE.GVG_VESTIGE: + case WAR_TYPE.GVG_BATTLE: + canSkip = true; + break; + } + + + return resResult(STATUS.SUCCESS, { + battleCode, canSkip + }); + } } diff --git a/game-server/app/servers/comBattle/handler/comBattleHandler.ts b/game-server/app/servers/comBattle/handler/comBattleHandler.ts index 85f92de22..471c9be8d 100644 --- a/game-server/app/servers/comBattle/handler/comBattleHandler.ts +++ b/game-server/app/servers/comBattle/handler/comBattleHandler.ts @@ -449,10 +449,10 @@ export class ComBattleHandler { * @returns * @memberof ComBattleHandler */ - async action(msg: {teamCode: string, bossHurts: Array<{hid: number, dataId: number, hurtHp: number}>, killed: number[], curRnd: number}, session: BackendSession) { + async action(msg: {teamCode: string, bossHurts: Array<{hid: number, dataId: number, hurtHp: number}>, killed: number[], curRnd: number, timegap: number }, session: BackendSession) { let roleId = session.get('roleId'); let sid = session.get('sid'); - let { teamCode, killed, bossHurts, curRnd } = msg; + let { teamCode, killed, bossHurts, curRnd, timegap = 0 } = msg; let teamStatus = getComTeamByCode(teamCode); if (!teamStatus || !teamStatus.roleIds || teamStatus.roleIds.indexOf(roleId) === -1) { checkTeamStatusAndSend(teamCode, roleId, sid); @@ -469,6 +469,17 @@ export class ComBattleHandler { } // 重置总血量,计算真实伤害 const roleSt = teamStatus.findMemberByRoleId(roleId); + if(!roleSt) return resResult(STATUS.SUCCESS); + if(!roleSt.startActionTime || roleSt.startActionTime == 0) { // 第一次调用设置初始 + roleSt.startActionTime = nowSeconds(); + } + if(Math.abs(nowSeconds() - roleSt.startActionTime - timegap) > 5) { // 前后端误差超过5秒拦截 + return resResult(STATUS.SUCCESS, { + isError: true, + timegap: nowSeconds() - roleSt.startActionTime + }); + } + let actBossHurts: {dataId: number, hurtHp: number}[] = []; let totalHurtHp = 0; teamStatus.bossHpArr.forEach(boss => { @@ -504,7 +515,10 @@ export class ComBattleHandler { sendMessageToTeam(teamCode, PUSH_ROUTE.TEAMMATE_ACT, { teamCode, bossCurHp: teamStatus.bossCurHp, bossHpArr: teamStatus.bossHpArr, roleStatus, actRoleId: roleId, actBossHurts }); const result = await handleComBtlProgress(teamStatus); if (result && result.code !== 0) return result; - return resResult(STATUS.SUCCESS); + return resResult(STATUS.SUCCESS, { + isError: false, + timegap: nowSeconds() - roleSt.startActionTime + }); } // /** diff --git a/game-server/app/servers/guild/handler/cityActivityHandler.ts b/game-server/app/servers/guild/handler/cityActivityHandler.ts index f04ad9583..a82ba5ee3 100644 --- a/game-server/app/servers/guild/handler/cityActivityHandler.ts +++ b/game-server/app/servers/guild/handler/cityActivityHandler.ts @@ -245,18 +245,31 @@ export class CityActivityHandler { // 上报城门受到伤害 - async hitGate(msg: { cityId: number, code: string, damage: number, hid: number, round: number }, session: BackendSession) { + async hitGate(msg: { cityId: number, code: string, damage: number, hid: number, round: number, timegap: number }, session: BackendSession) { const roleId = session.get('roleId'); const roleName = session.get('roleName'); const serverId = session.get('serverId'); const guildCode = session.get('guildCode'); const sid = session.get('sid'); - let { cityId, code, damage, hid, round } = msg; + let { cityId, code, damage, hid, round, timegap = 0 } = msg; let obj = getCityActivityObj(); let { gateHp, maxHp } = await obj.getGateHpAndInc(serverId, cityId); if (gateHp <= 0) return resResult(STATUS.GATE_HP_IS_ZERO); + let member = obj.getMember(guildCode, roleId); + if(!member) return resResult(STATUS.NOT_CHECK_BATTLE); + if(!member.startActionTime || member.startActionTime == 0) { + member.startActionTime = nowSeconds(); + } + if(Math.abs(nowSeconds() - member.startActionTime - timegap) > 5) { // 前后端误差超过5秒拦截 + return resResult(STATUS.SUCCESS, { + isError: true, + timegap: nowSeconds() - member.startActionTime + }); + } + + let hero = await HeroModel.findBySeqIdAndRole(hid, roleId); if(!hero && (damage/maxHp > 0.01)) damage = 0; @@ -266,7 +279,9 @@ export class CityActivityHandler { if(statusResult.status != GUILD_ACTIVITY_STATUS.START) { return resResult(STATUS.SUCCESS, { code, - ...statusResult + ...statusResult, + isError: false, + timegap: nowSeconds() - member.startActionTime, }) } @@ -306,7 +321,9 @@ export class CityActivityHandler { ...statusResult, guildScore, myScore, - gateHp + gateHp, + isError: false, + timegap: nowSeconds() - member.startActionTime, }) } diff --git a/game-server/app/services/auctionService.ts b/game-server/app/services/auctionService.ts index be507931a..fb8eef8e4 100644 --- a/game-server/app/services/auctionService.ts +++ b/game-server/app/services/auctionService.ts @@ -9,7 +9,6 @@ import { DividendParam, DividendType } from '../db/Dividend'; import { sendMailByContent } from './mailService'; import { FrontendOrBackendSession, pinus } from 'pinus'; import { participants } from './guildActivity/guildActivityService'; -import { Member } from '../domain/battleField/guildActivity'; import * as dicParam from '../pubUtils/dicParam'; import { RewardInter } from '../pubUtils/interface'; import { reportTAEvent } from './sdkService'; @@ -251,11 +250,11 @@ function weekendDividend(posNum: number, date: Date) { return (day === 0 || day === 6) ? Math.floor(posNum * dicParam.GUILD_AUCTION.DIVIDEND_WEEKEND_RATE) : 0; } -function dividendRate(data: Member) { +function dividendRate(data: { roleId: string, job: number }) { return gameData.guildPosition.get(data.job).sellRatio; } -function totalDividendRatio(participantsData: Member[]) { +function totalDividendRatio(participantsData: { roleId: string, job: number }[]) { const result = participantsData.reduce((sum, data) => { return sum + dividendRate(data); }, 0); diff --git a/game-server/app/services/checkParam.ts b/game-server/app/services/checkParam.ts index 46918d745..fa1fad589 100644 --- a/game-server/app/services/checkParam.ts +++ b/game-server/app/services/checkParam.ts @@ -557,10 +557,10 @@ export function checkRouteParam(route: string, msg: any) { } case "comBattle.comBattleHandler.action": { - let { teamCode, bossHurts, killed, curRnd } = msg; + let { teamCode, bossHurts, killed, curRnd, timegap = 0 } = msg; if (!checkNaturalStrings(teamCode)) return false; if (!checkNumberArray(killed)) return false; - if (!checkNaturalNumbers(curRnd)) return false; + if (!checkNaturalNumbers(curRnd, timegap)) return false; if (!checkArrayCanEmpty(bossHurts)) return false; for (let { hid, dataId, hurtHp } of bossHurts) { if (hid && !checkNaturalNumbers(hid)) return false; @@ -709,6 +709,11 @@ export function checkRouteParam(route: string, msg: any) { if (!checkNaturalNumbers(msg.chapter, msg.warType)) return false; break; } + case "battle.normalBattleHandler.checkSkip": + { + if (!checkNaturalStrings(msg.battleCode)) return false; + break; + } case "battle.pvpHandler.getOppPlayer": case "battle.pvpHandler.getPlayerDetail": { @@ -1076,8 +1081,10 @@ export function checkRouteParam(route: string, msg: any) { } case "guild.cityActivityHandler.hitGate": { - let { cityId, code, damage, hid, round } = msg; - if (!checkNaturalNumbers(cityId, damage, hid, round)) return false; + let { cityId, code, damage, hid, round, timegap = 0 } = msg; + console.log('###### timegap 1', timegap) + if (!checkNaturalNumbers(cityId, damage, hid, round, timegap)) return false; + console.log('###### timegap 2', timegap) if (!checkNaturalStrings(code)) return false; break; } diff --git a/game-server/app/services/guildActivity/cityActivityObj.ts b/game-server/app/services/guildActivity/cityActivityObj.ts index 7ed710f25..6244d79d6 100644 --- a/game-server/app/services/guildActivity/cityActivityObj.ts +++ b/game-server/app/services/guildActivity/cityActivityObj.ts @@ -114,15 +114,21 @@ export class CityActivityObject { if(this.data.members.has(guildCode)) { let members = this.data.members.get(guildCode); if(members.findIndex(cur => cur.roleId == roleId) == -1) { - members.push({ roleId, job, code }); + members.push({ roleId, job, code, startActionTime: 0 }); } } else { let arr = new Array(); arr.push(roleId); - this.data.members.set(guildCode, [{ roleId, job, code }]); + this.data.members.set(guildCode, [{ roleId, job, code, startActionTime: 0 }]); } } + public getMember(guildCode: string, roleId: string) { + let members = this.data.members.get(guildCode)||[]; + let member = members.find(cur => cur.roleId == roleId); + return member; + } + public pushGuild(guildCode: string, serverId: number, cityId: number) { let key = this.getKey(serverId, cityId); if(!this.data.cities.has(key)) { diff --git a/shared/consts/statusCode.ts b/shared/consts/statusCode.ts index faec85044..90635228e 100644 --- a/shared/consts/statusCode.ts +++ b/shared/consts/statusCode.ts @@ -286,6 +286,7 @@ export const STATUS = { CAN_NOT_DECLARE: { code: 21109, simStr: '该城池不可宣战' }, CHALLENGE_TIME_NOT_NEED_RESET: { code: 21110, simStr: '不需要重置' }, CITY_NOT_FOUND: { code: 21111, simStr: '未找到该城池' }, + NOT_CHECK_BATTLE: { code: 21112, simStr: '挑战未开始' }, // 名将擂台 LADDER_NOT_OPEN: { code: 21200, simStr: '请先布置防守阵容' }, diff --git a/shared/db/ComBattleTeam.ts b/shared/db/ComBattleTeam.ts index 1df14626a..4cb61dcad 100644 --- a/shared/db/ComBattleTeam.ts +++ b/shared/db/ComBattleTeam.ts @@ -99,6 +99,9 @@ export class RoleStatus { @prop({ required: true, default: 0 }) frdRatio: number = 0; + @prop({ required: true, default: 0 }) + startActionTime: number = 0; + constructor(role: RoleUpdate, sid: string, isCap: boolean, isFrd: boolean, heroes: ComRoleStatusHero[] = [], isRobot = false) { if(role) { this.roleId = role.roleId||''; diff --git a/shared/domain/battleField/guildActivity.ts b/shared/domain/battleField/guildActivity.ts index 2e694084d..b0afe6c81 100644 --- a/shared/domain/battleField/guildActivity.ts +++ b/shared/domain/battleField/guildActivity.ts @@ -182,6 +182,8 @@ export class Member { job: number; // 在军团的职位 @prop({required: false}) code?: string; // 玩家的当前记录的code + @prop({required: false}) + startActionTime?: number; // 玩家的当前记录的code } export class JoinMember extends Member{