✨ feat(防破解): 防加速和防跳过

This commit is contained in:
luying
2023-08-03 16:54:31 +08:00
parent 8c2be216dd
commit 34c5f4b2ce
9 changed files with 124 additions and 16 deletions
@@ -591,4 +591,63 @@ export class NormalBattleHandler {
return; 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
});
}
} }
@@ -449,10 +449,10 @@ export class ComBattleHandler {
* @returns * @returns
* @memberof ComBattleHandler * @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 roleId = session.get('roleId');
let sid = session.get('sid'); let sid = session.get('sid');
let { teamCode, killed, bossHurts, curRnd } = msg; let { teamCode, killed, bossHurts, curRnd, timegap = 0 } = msg;
let teamStatus = getComTeamByCode(teamCode); let teamStatus = getComTeamByCode(teamCode);
if (!teamStatus || !teamStatus.roleIds || teamStatus.roleIds.indexOf(roleId) === -1) { if (!teamStatus || !teamStatus.roleIds || teamStatus.roleIds.indexOf(roleId) === -1) {
checkTeamStatusAndSend(teamCode, roleId, sid); checkTeamStatusAndSend(teamCode, roleId, sid);
@@ -469,6 +469,17 @@ export class ComBattleHandler {
} }
// 重置总血量,计算真实伤害 // 重置总血量,计算真实伤害
const roleSt = teamStatus.findMemberByRoleId(roleId); 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 actBossHurts: {dataId: number, hurtHp: number}[] = [];
let totalHurtHp = 0; let totalHurtHp = 0;
teamStatus.bossHpArr.forEach(boss => { 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 }); sendMessageToTeam(teamCode, PUSH_ROUTE.TEAMMATE_ACT, { teamCode, bossCurHp: teamStatus.bossCurHp, bossHpArr: teamStatus.bossHpArr, roleStatus, actRoleId: roleId, actBossHurts });
const result = await handleComBtlProgress(teamStatus); const result = await handleComBtlProgress(teamStatus);
if (result && result.code !== 0) return result; if (result && result.code !== 0) return result;
return resResult(STATUS.SUCCESS); return resResult(STATUS.SUCCESS, {
isError: false,
timegap: nowSeconds() - roleSt.startActionTime
});
} }
// /** // /**
@@ -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 roleId = session.get('roleId');
const roleName = session.get('roleName'); const roleName = session.get('roleName');
const serverId = session.get('serverId'); const serverId = session.get('serverId');
const guildCode = session.get('guildCode'); const guildCode = session.get('guildCode');
const sid = session.get('sid'); 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 obj = getCityActivityObj();
let { gateHp, maxHp } = await obj.getGateHpAndInc(serverId, cityId); let { gateHp, maxHp } = await obj.getGateHpAndInc(serverId, cityId);
if (gateHp <= 0) return resResult(STATUS.GATE_HP_IS_ZERO); 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); let hero = await HeroModel.findBySeqIdAndRole(hid, roleId);
if(!hero && (damage/maxHp > 0.01)) damage = 0; if(!hero && (damage/maxHp > 0.01)) damage = 0;
@@ -266,7 +279,9 @@ export class CityActivityHandler {
if(statusResult.status != GUILD_ACTIVITY_STATUS.START) { if(statusResult.status != GUILD_ACTIVITY_STATUS.START) {
return resResult(STATUS.SUCCESS, { return resResult(STATUS.SUCCESS, {
code, code,
...statusResult ...statusResult,
isError: false,
timegap: nowSeconds() - member.startActionTime,
}) })
} }
@@ -306,7 +321,9 @@ export class CityActivityHandler {
...statusResult, ...statusResult,
guildScore, guildScore,
myScore, myScore,
gateHp gateHp,
isError: false,
timegap: nowSeconds() - member.startActionTime,
}) })
} }
+2 -3
View File
@@ -9,7 +9,6 @@ import { DividendParam, DividendType } from '../db/Dividend';
import { sendMailByContent } from './mailService'; import { sendMailByContent } from './mailService';
import { FrontendOrBackendSession, pinus } from 'pinus'; import { FrontendOrBackendSession, pinus } from 'pinus';
import { participants } from './guildActivity/guildActivityService'; import { participants } from './guildActivity/guildActivityService';
import { Member } from '../domain/battleField/guildActivity';
import * as dicParam from '../pubUtils/dicParam'; import * as dicParam from '../pubUtils/dicParam';
import { RewardInter } from '../pubUtils/interface'; import { RewardInter } from '../pubUtils/interface';
import { reportTAEvent } from './sdkService'; 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; 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; return gameData.guildPosition.get(data.job).sellRatio;
} }
function totalDividendRatio(participantsData: Member[]) { function totalDividendRatio(participantsData: { roleId: string, job: number }[]) {
const result = participantsData.reduce((sum, data) => { const result = participantsData.reduce((sum, data) => {
return sum + dividendRate(data); return sum + dividendRate(data);
}, 0); }, 0);
+11 -4
View File
@@ -557,10 +557,10 @@ export function checkRouteParam(route: string, msg: any) {
} }
case "comBattle.comBattleHandler.action": case "comBattle.comBattleHandler.action":
{ {
let { teamCode, bossHurts, killed, curRnd } = msg; let { teamCode, bossHurts, killed, curRnd, timegap = 0 } = msg;
if (!checkNaturalStrings(teamCode)) return false; if (!checkNaturalStrings(teamCode)) return false;
if (!checkNumberArray(killed)) return false; if (!checkNumberArray(killed)) return false;
if (!checkNaturalNumbers(curRnd)) return false; if (!checkNaturalNumbers(curRnd, timegap)) return false;
if (!checkArrayCanEmpty(bossHurts)) return false; if (!checkArrayCanEmpty(bossHurts)) return false;
for (let { hid, dataId, hurtHp } of bossHurts) { for (let { hid, dataId, hurtHp } of bossHurts) {
if (hid && !checkNaturalNumbers(hid)) return false; 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; if (!checkNaturalNumbers(msg.chapter, msg.warType)) return false;
break; break;
} }
case "battle.normalBattleHandler.checkSkip":
{
if (!checkNaturalStrings(msg.battleCode)) return false;
break;
}
case "battle.pvpHandler.getOppPlayer": case "battle.pvpHandler.getOppPlayer":
case "battle.pvpHandler.getPlayerDetail": case "battle.pvpHandler.getPlayerDetail":
{ {
@@ -1076,8 +1081,10 @@ export function checkRouteParam(route: string, msg: any) {
} }
case "guild.cityActivityHandler.hitGate": case "guild.cityActivityHandler.hitGate":
{ {
let { cityId, code, damage, hid, round } = msg; let { cityId, code, damage, hid, round, timegap = 0 } = msg;
if (!checkNaturalNumbers(cityId, damage, hid, round)) return false; console.log('###### timegap 1', timegap)
if (!checkNaturalNumbers(cityId, damage, hid, round, timegap)) return false;
console.log('###### timegap 2', timegap)
if (!checkNaturalStrings(code)) return false; if (!checkNaturalStrings(code)) return false;
break; break;
} }
@@ -114,15 +114,21 @@ export class CityActivityObject {
if(this.data.members.has(guildCode)) { if(this.data.members.has(guildCode)) {
let members = this.data.members.get(guildCode); let members = this.data.members.get(guildCode);
if(members.findIndex(cur => cur.roleId == roleId) == -1) { if(members.findIndex(cur => cur.roleId == roleId) == -1) {
members.push({ roleId, job, code }); members.push({ roleId, job, code, startActionTime: 0 });
} }
} else { } else {
let arr = new Array<string>(); let arr = new Array<string>();
arr.push(roleId); 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) { public pushGuild(guildCode: string, serverId: number, cityId: number) {
let key = this.getKey(serverId, cityId); let key = this.getKey(serverId, cityId);
if(!this.data.cities.has(key)) { if(!this.data.cities.has(key)) {
+1
View File
@@ -286,6 +286,7 @@ export const STATUS = {
CAN_NOT_DECLARE: { code: 21109, simStr: '该城池不可宣战' }, CAN_NOT_DECLARE: { code: 21109, simStr: '该城池不可宣战' },
CHALLENGE_TIME_NOT_NEED_RESET: { code: 21110, simStr: '不需要重置' }, CHALLENGE_TIME_NOT_NEED_RESET: { code: 21110, simStr: '不需要重置' },
CITY_NOT_FOUND: { code: 21111, simStr: '未找到该城池' }, CITY_NOT_FOUND: { code: 21111, simStr: '未找到该城池' },
NOT_CHECK_BATTLE: { code: 21112, simStr: '挑战未开始' },
// 名将擂台 // 名将擂台
LADDER_NOT_OPEN: { code: 21200, simStr: '请先布置防守阵容' }, LADDER_NOT_OPEN: { code: 21200, simStr: '请先布置防守阵容' },
+3
View File
@@ -99,6 +99,9 @@ export class RoleStatus {
@prop({ required: true, default: 0 }) @prop({ required: true, default: 0 })
frdRatio: number = 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) { constructor(role: RoleUpdate, sid: string, isCap: boolean, isFrd: boolean, heroes: ComRoleStatusHero[] = [], isRobot = false) {
if(role) { if(role) {
this.roleId = role.roleId||''; this.roleId = role.roleId||'';
@@ -182,6 +182,8 @@ export class Member {
job: number; // 在军团的职位 job: number; // 在军团的职位
@prop({required: false}) @prop({required: false})
code?: string; // 玩家的当前记录的code code?: string; // 玩家的当前记录的code
@prop({required: false})
startActionTime?: number; // 玩家的当前记录的code
} }
export class JoinMember extends Member{ export class JoinMember extends Member{