import { Application, BackendSession, pinus, HandlerService, } from 'pinus'; import { findIndex } from 'underscore'; import { gameData, getPvpBoxBySeasonNumAndIndex } from '../../../pubUtils/data'; import { refreshEnemies, getEnemies, refChallengeCnt, generPVPOppRecInfo, generMyRecInfo, sendLastSeasonRewardIfNotSent, refreshRefOppCnt, generPvpLineupCe } from '../../../services/pvpService'; import { RoleModel, RoleType } from '../../../db/Role'; import { STATUS } from '../../../consts/statusCode'; import { resResult, genCode, checkRoleIsRobot, robotIdComBack } from '../../../pubUtils/util'; import { PvpDefenseModel, pvpUpdateInter } from '../../../db/PvpDefense'; import { PvpSeasonResultModel } from '../../../db/PvpSeasonResult'; import { Rank } from '../../../services/rankService'; import { checkTask, checkTaskInPvpEnd } from '../../../services/task/taskService'; import { Attack, Defense, DefenseHero, PvpDataReturn } from '../../../domain/battleField/pvp'; import { DEBUG_MAGIC_WORD, FIGURE_UNLOCK_CONDITION, ITEM_CHANGE_REASON, LINEUP_NUM, REDIS_KEY, TASK_TYPE } from '../../../consts'; import { PVP } from '../../../pubUtils/dicParam'; import { addItems, getGoldObject, handleCost, unlockFigure } from '../../../services/role/rewardService'; import { pick } from "underscore"; import { HeroModel } from '../../../db/Hero'; import PvpHistoryOpp, { PvpHistoryOppModel } from '../../../db/PvpHistoryOpp'; import { BattleRecordModel } from '../../../db/BattleRecord'; import { PvpRecordModel } from '../../../db/PvpRecord'; import { pvpEndParamInter } from '../../../pubUtils/interface'; import { getSeconds, nowSeconds } from '../../../pubUtils/timeUtil'; import { PlayerDetail, PlayerDetailHero } from '../../../domain/battleField/guild'; export default function (app: Application) { new HandlerService(app, {}); return new PvpHandler(app); } export class PvpHandler { constructor(private app: Application) { } //1获取主界面 async getData(msg: {}, session: BackendSession) { let roleId = session.get('roleId'); let pvpDefense = await PvpDefenseModel.findByRoleIdIncludeAll(roleId); if(!pvpDefense) { let role = await RoleModel.findByRoleId(roleId); pvpDefense = await PvpDefenseModel.createPvpDefense({ serverId: role.serverId, roleId: role.roleId, roleName: role.roleName, role: role._id }); } // 如果没有发过,将上赛季的奖励发下 pvpDefense = await sendLastSeasonRewardIfNotSent(pvpDefense); let seasonNum: number = this.app.get('pvpSeasonNum'); let seasonEndTime: number = this.app.get('pvpSeasonEndTime'); let update: pvpUpdateInter = { }; let result = new PvpDataReturn(); // 返回对象 // 刷新次数 let refChallengeObj = await refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime, roleId, session.get('vipStartTime')); if(refChallengeObj.hasChanged) { update = { ...update, ...refChallengeObj } } let refOppObj = refreshRefOppCnt(pvpDefense); // 每天首次打开要刷掉对手 if(refOppObj.shouldRefOpp) { if(pvpDefense.attack) { let role = pvpDefense.role; let oppPlayers = await refreshEnemies(role, seasonNum, pvpDefense.score, pvpDefense.attack.score, pvpDefense.attack.pLv||1); update.oppPlayers = oppPlayers; } update = { ...update, ...refOppObj } } if(Object.keys(update).length > 0) { pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, update); } result.setPvpConfig(seasonNum, seasonEndTime); result.setPvpDefense(pvpDefense); let oppPlayersReturn = await getEnemies(pvpDefense.oppPlayers||[], pvpDefense.winStreakNum); result.setOppPlayers(oppPlayersReturn); // 赛季结算 let pvpSeasonResult = await PvpSeasonResultModel.getPvpSeasonResult(roleId); if (!!pvpSeasonResult && !!pvpSeasonResult.show && pvpDefense.seasonNum == seasonNum) { result.setPvpSeasonResult(pvpSeasonResult); result.setIsFirstEntry(true); update.isFirstEntry = false; await PvpSeasonResultModel.setShow(roleId); } // 拍卖 let r = new Rank(REDIS_KEY.PVP_RANK, { seasonNum }); let myRank = await r.getMyRank({ roleId });//去redis中获取排名 result.setMyRank(myRank); return resResult(STATUS.SUCCESS, result); } // 刷新对手 async refreshOppPlayer(msg: {}, session: BackendSession) { let roleId = session.get('roleId'); let sid = session.get('sid'); let pvpDefense = await PvpDefenseModel.findByRoleIdIncludeAll(roleId); if(!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN); if(!pvpDefense.attack) return resResult(STATUS.PVP_NOT_SET_ATTACK); // 刷新次数及消耗 let refOppObj = refreshRefOppCnt(pvpDefense); if (refOppObj.refOppCnt >= gameData.maxPvpRefreshCnt.max) { return resResult(STATUS.PVP_REFRESH_CNT_REACH_MAX); } let costResult = await handleCost(roleId, sid, refOppObj.consume, ITEM_CHANGE_REASON.PVP_REFRESH_OPP); if (!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); refOppObj.refOppCnt ++; // 刷新对手 let role = pvpDefense.role; let seasonNum: number = this.app.get('pvpSeasonNum'); let oppPlayers = await refreshEnemies(role, seasonNum, pvpDefense.score, pvpDefense.attack.score, pvpDefense.attack.pLv||1); pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, { oppPlayers, ...refOppObj }); let result = new PvpDataReturn(); // 返回对象 result.setPvpDefense(pvpDefense); let oppPlayersReturn = await getEnemies(pvpDefense.oppPlayers, pvpDefense.winStreakNum); result.setOppPlayers(oppPlayersReturn); return resResult(STATUS.SUCCESS, pick(result, ['oppPlayers', 'refOppCnt', 'buyAttackCnt', 'setAttackCnt'])); } // 获取对手阵容具体信息 async getOppPlayer(msg: { roleId: string }, session: BackendSession) { let roleId = session.get('roleId'); let oppoRoleId = msg.roleId; let pvpDefense = await PvpDefenseModel.findByRoleIdIncludeAll(roleId); if(!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN); let { oppPlayers } = pvpDefense; let curOpp = oppPlayers.find(cur => cur.roleId == oppoRoleId); if (!curOpp) return resResult(STATUS.PVP_ROLE_NOT_FOUND); let pvpHistoryOpp = curOpp.oppDef; return resResult(STATUS.SUCCESS, { roleId: pvpHistoryOpp.oppRoleId, ...pick(pvpHistoryOpp, ['pos', 'warId', 'buff', 'heroes']) }); } // 开战 async pvpStart(msg: { warId: number, roleId: string }, session: BackendSession) { const { warId, roleId: oppRoleId } = msg; let roleId = session.get('roleId'); let roleName = session.get('roleName'); let serverId = session.get('serverId'); let sid = session.get('sid'); let warInfo = gameData.war.get(warId); if (!warInfo) { return resResult(STATUS.BATTLE_MISS_INFO); } let pvpDefense = await PvpDefenseModel.findByRoleId(roleId); if (!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN); // 检查挑战次数 let seasonNum: number = this.app.get('pvpSeasonNum'); let seasonEndTime: number = this.app.get('pvpSeasonEndTime'); let { challengeCnt, challengeRefTime } = await refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime, roleId, session.get('vipStartTime')); if (challengeCnt == 0) { return resResult(STATUS.PVP_CHALLENGE_TIMES_NOT_ENOUGH); } let curOpp = pvpDefense.oppPlayers.find(cur => cur.roleId == oppRoleId); if (!curOpp) return resResult(STATUS.PVP_ROLE_NOT_FOUND) const battleCode = genCode(8); // 关卡唯一值 let heroes = pvpDefense.attack.heroes.map(cur => cur.actorId); await BattleRecordModel.updateBattleRecordByCode(battleCode, { $set: { roleId, roleName, battleId: warId, status: 0, warName: warInfo.gk_name, warType: warInfo.warType, record: { heroes, pos: curOpp.pos, oppRoleId } } }, true); await checkTask(serverId, roleId, sid, TASK_TYPE.PVP); // 对手记录更新 await PvpHistoryOppModel.setStatus(roleId, oppRoleId, 1); let update: pvpUpdateInter = { oppBeforePlayers: pvpDefense.oppPlayers }; // 刷新对手 const role = await RoleModel.findByRoleId(roleId, null, true); let oppPlayers = await refreshEnemies(role, seasonNum, pvpDefense.score ,pvpDefense.attack.score, pvpDefense.attack.pLv||1); update.oppPlayers = oppPlayers; // 减少挑战次数 let refChallengeObj = await refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime, roleId, session.get('vipStartTime')); refChallengeObj.challengeCnt--; update = {...update, ...refChallengeObj}; pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, update); let result = new PvpDataReturn(); // 返回对象 result.setPvpDefense(pvpDefense); let oppPlayersReturn = await getEnemies(pvpDefense.oppPlayers, pvpDefense.winStreakNum); result.setOppPlayers(oppPlayersReturn); return resResult(STATUS.SUCCESS, { battleCode, ...pick(result, ['oppPlayers', 'challengeCnt', 'challengeRefTime']) }); } // 结算 async pvpEnd(msg: { battleCode: string, isSuccess: boolean, myHeroes: pvpEndParamInter[], oppHeroes: pvpEndParamInter[] }, session: BackendSession) { let roleId = session.get('roleId'); let roleName = session.get('roleName'); let sid = session.get('sid'); const serverId = session.get('serverId'); const { battleCode, isSuccess, myHeroes, oppHeroes } = msg; const BattleRecord = await BattleRecordModel.getBattleRecordByCode(battleCode, true); if (!BattleRecord || BattleRecord.status != 0) { return resResult(STATUS.BATTLE_STATUS_WRONG); } let { record: { heroes: dbHeroes, oppRoleId, pos }, createdAt } = BattleRecord; let flag = 1; // 对比hero信息 for (let { hid } of myHeroes) { if (dbHeroes.indexOf(hid) == -1) flag = 0; } if (!flag) return resResult(STATUS.BATTLE_INFO_VALIDATE_ERR); // 更新军功 let pvpDefense = await PvpDefenseModel.findByRoleIdIncludeAll(roleId); if (!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN); let { hisWinStreakNum = 0 } = pvpDefense; let update: pvpUpdateInter = {}; const role = await RoleModel.findByRoleId(roleId, null, true); const myRecInfo = await generMyRecInfo(pvpDefense, role, isSuccess, pos, myHeroes); let { attackInfo, showHeroScores, updateParam } = myRecInfo update = { ...update, ...updateParam }; let curOpp = pvpDefense.oppBeforePlayers.find(cur => cur.roleId == oppRoleId && cur.pos == pos); if (!curOpp) return resResult(STATUS.PVP_ROLE_NOT_FOUND); const defenseInfo = await generPVPOppRecInfo(isSuccess, curOpp, oppHeroes, role.lv); // 战报记录 await PvpRecordModel.createRec({ roleId1: roleId, roleId2: robotIdComBack(oppRoleId), warId: BattleRecord.battleId, attackInfo, defenseInfo, createTime: nowSeconds() }); let seasonNum: number = this.app.get('pvpSeasonNum'); // 更新battleRecord await BattleRecordModel.updateBattleRecordByCode(battleCode, { $set: { status: isSuccess ? 1 : 2 } }, true); pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, update); let result = new PvpDataReturn(); // 返回对象 result.setPvpDefense(pvpDefense); let oppPlayersReturn = await getEnemies(pvpDefense.oppPlayers, pvpDefense.winStreakNum); result.setOppPlayers(oppPlayersReturn); // 加入排行榜 let r = new Rank(REDIS_KEY.PVP_RANK, { seasonNum }); await r.setRankWithRoleInfo(roleId, pvpDefense.score, pvpDefense.updatedAt.getTime(), role); let myRank = await r.getMyRank({ roleId }); result.setMyRank(myRank); await checkTaskInPvpEnd(serverId, roleId, sid, isSuccess, pvpDefense.heroScores, pvpDefense.seasonWinNum); if(hisWinStreakNum < pvpDefense.hisWinStreakNum) { await unlockFigure(sid, roleId, [{ type: FIGURE_UNLOCK_CONDITION.PVP_WIN_SERIES, paramWinStreakNum: pvpDefense.hisWinStreakNum }]); } return resResult(STATUS.SUCCESS, { battleCode, isSuccess, heroScores: showHeroScores, createdAt: getSeconds(createdAt), ...pick(result, ['score', 'myRank', 'winStreakNum', 'attack', 'oppPlayers', 'challengeCnt', 'challengeRefTime', 'seasonWinNum']) }); } async buyAttackCnt(msg: { count: number }, session: BackendSession) { let { count } = msg; let roleId = session.get('roleId'); let sid = session.get('sid'); let pvpDefense = await PvpDefenseModel.findByRoleId(roleId); if(!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN); // 次数 let refOppObj = refreshRefOppCnt(pvpDefense); if(refOppObj.buyAttackCnt + count > PVP.PVP_BUY_SET_ATTACK_CNT) { return resResult(STATUS.PVP_BUY_ATTACK_CNT_NOT_ENOUGH); } refOppObj.buyAttackCnt += count; let gold = getGoldObject(PVP.PVP_SET_ATTACK_CNT_GOLD * count); let costResult = await handleCost(roleId, sid, [gold], ITEM_CHANGE_REASON.PVP_BUY_ATTACK_CNT); if(!costResult) return resResult(STATUS.TOWER_GOLD_NOT_ENOUGH); let update: pvpUpdateInter = { ...refOppObj }; // 更新挑战阵容 if(refOppObj.shouldRefOpp) { if(pvpDefense.attack) { let role = await RoleModel.findByRoleId(roleId); let seasonNum: number = this.app.get('pvpSeasonNum'); let oppPlayers = await refreshEnemies(role, seasonNum, pvpDefense.score, pvpDefense.attack.score, pvpDefense.attack.pLv||1); update.oppPlayers = oppPlayers; } } // 保存 pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, update); // 返回 let result = new PvpDataReturn(); result.setPvpDefense(pvpDefense); let pickParam = ['buyAttackCnt', 'setAttackCnt', 'refOppCnt']; if(refOppObj.shouldRefOpp) { let oppPlayersReturn = await getEnemies(pvpDefense.oppPlayers||[], pvpDefense.winStreakNum); result.setOppPlayers(oppPlayersReturn); pickParam.push('oppPlayers'); } return resResult(STATUS.SUCCESS, pick(result, pickParam)); } async saveAttack(msg: { heroes: { actorId: number, order: number }[] }, session: BackendSession) { let { heroes } = msg; let roleId = session.get('roleId'); let pvpDefense = await PvpDefenseModel.findByRoleIdIncludeAll(roleId); if(!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN); // 次数 let refOppObj = refreshRefOppCnt(pvpDefense); if(refOppObj.setAttackCnt >= PVP.PVP_SET_ATTACK_FREE_CNT + refOppObj.buyAttackCnt) { return resResult(STATUS.PVP_SET_ATTACK_CNT_NOT_ENOUGH); } if(!!pvpDefense.attack) { refOppObj.setAttackCnt ++; } let seasonNum: number = this.app.get('pvpSeasonNum'); let seasonEndTime: number = this.app.get('pvpSeasonEndTime'); let refChallengeObj = await refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime, roleId, session.get('vipStartTime')); // 更新挑战阵容 let scores: number[] = []; for(let { actorId } of heroes) { let heroScore = pvpDefense.heroScores.find(cur => cur.hid == actorId); if(heroScore) { scores.push(heroScore.score); } } let attack = new Attack(heroes, scores); let lineupCe = await generPvpLineupCe(roleId, pvpDefense.lineupCe, attack.heroes, pvpDefense.defense?.heroes??[], []); // 刷对手 let role = pvpDefense.role; let oppPlayers = await refreshEnemies(role, seasonNum, pvpDefense.score, attack?.score||0, attack?.pLv||1); // 保存 pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, { ...refOppObj, ...refChallengeObj, attack, oppPlayers, lineupCe }); // 返回 let result = new PvpDataReturn(); result.setPvpDefense(pvpDefense); let oppPlayersReturn = await getEnemies(pvpDefense.oppPlayers||[], pvpDefense.winStreakNum); result.setOppPlayers(oppPlayersReturn); return resResult(STATUS.SUCCESS, pick(result, ['attack', 'oppPlayers', 'buyAttackCnt', 'setAttackCnt', 'challengeCnt', 'challengeRefTime'])); } //3. 保存防守阵容 async saveDefense(msg: { heroes: { actorId: number, dataId: number, order: number, ai: number }[], warId: number, buff: number }, session: BackendSession) { let { heroes, warId, buff } = msg; let roleId = session.get('roleId'); if (heroes.length > LINEUP_NUM || heroes.length <= 0) { return resResult(STATUS.WRONG_PARMS); } let pvpDefense = await PvpDefenseModel.findByRoleId(roleId); if(!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN); // 刷新次数 let seasonEndTime: number = this.app.get('pvpSeasonEndTime'); let refChallengeObj = await refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime, roleId, session.get('vipStartTime')); // 更新防守阵容 let scores: number[] = [], heroIdMap = new Map(), hids: number[] = []; for(let { actorId } of heroes) { let heroScore = pvpDefense.heroScores.find(cur => cur.hid == actorId); if(heroScore) { scores.push(heroScore.score); } // 记录hero的objectId,用于存defense.heroes.hero if(pvpDefense.defense && pvpDefense.defense.heroes) { let heroInDefense = pvpDefense.defense.heroes.find(cur => cur.actorId == actorId); if(heroInDefense) { heroIdMap.set(actorId, heroInDefense.hero); } else { hids.push(actorId); } } else { hids.push(actorId); } } let dbHeroes = await HeroModel.findByHidRange(hids, roleId, '_id hid ce', true); for(let hero of dbHeroes) { heroIdMap.set(hero.hid, hero._id); } let defenseHeroes = heroes.map(cur => { return new DefenseHero(cur, heroIdMap.get(cur.actorId)); }); let defense = new Defense(defenseHeroes, scores, warId, buff); let lineupCe = await generPvpLineupCe(roleId, pvpDefense.lineupCe, pvpDefense.attack?.heroes??[], defense.heroes, dbHeroes); pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, { ...refChallengeObj, defense, lineupCe }); // 返回 let result = new PvpDataReturn(); result.setPvpDefense(pvpDefense); return resResult(STATUS.SUCCESS, pick(result, ['defense', 'challengeCnt', 'challengeRefTime'])); } //8. 排行榜 async getRank(msg: {}, session: BackendSession) { let roleId = session.get('roleId'); let seasonNum: number = this.app.get('pvpSeasonNum'); let r = new Rank(REDIS_KEY.PVP_RANK, { seasonNum }); let { ranks, myRank } = await r.getRankListWithMyRank({ roleId }); if (!myRank) { let pvpDefense = await PvpDefenseModel.findByRoleId(roleId); myRank = await r.generMyRankWithRole(roleId, pvpDefense.score, getSeconds(pvpDefense.refDaily)); } return resResult(STATUS.SUCCESS, { ranks, myRank }); } //2.5. 获取对手详细信息(排行榜,战报,阵容查看) async getPlayerDetail(msg: { roleId: string }, session: BackendSession) { let roleId = session.get('roleId'); let { roleId: oppoRoleId } = msg; let isRobot = checkRoleIsRobot(oppoRoleId); let result: PlayerDetail; if (isRobot) { // 如果是机器人,从自己的pvpDefense中寻找 let pvpHistoryOpp = await PvpHistoryOppModel.findByRoleIdAndOppId(roleId, oppoRoleId); if (!pvpHistoryOpp) { return resResult(STATUS.PVP_ROLE_NOT_FOUND); } let heroes = new Array(); for (let hero of pvpHistoryOpp.heroes) { let newHero = new PlayerDetailHero(); newHero.setPvpHeroInfo(hero); newHero.setIsDefense(true); heroes.push(newHero); } for (let hero of pvpHistoryOpp.otherHeroes) { let newHero = new PlayerDetailHero(); newHero.setPvpHeroInfo(hero); newHero.setIsDefense(false); heroes.push(newHero); } result = new PlayerDetail(pvpHistoryOpp.oppRoleId, heroes, pvpHistoryOpp.rankLv); result.setRobot(pvpHistoryOpp); } else { // 查询对方pvpDefense let pvpDefense = await PvpDefenseModel.findByRoleId(oppoRoleId); let dbHeroes = await HeroModel.findByRole(oppoRoleId); let role = await RoleModel.findByRoleId(oppoRoleId); let heroes = new Array(); for (let dbHero of dbHeroes) { let hero = new PlayerDetailHero(); hero.setByDbHero(dbHero); hero.setPvpDefense(pvpDefense); heroes.push(hero); } heroes.sort((a, b) => b.score - a.score); let seasonNum: number = this.app.get('pvpSeasonNum'); let r = new Rank(REDIS_KEY.PVP_RANK, { seasonNum }); let rank = await r.getMyRank({ roleId: oppoRoleId });//去redis中获取排名 result = new PlayerDetail(oppoRoleId, heroes, rank); result.setPlayer(role); result.setPvpDefense(pvpDefense); } return resResult(STATUS.SUCCESS, result); } //7. 领取巅峰之路奖励 async receiveBox(msg: { id: number }, session: BackendSession) { let { id } = msg; let roleId = session.get('roleId'); let sid: string = session.get('sid'); let serverId = session.get('serverId'); let roleName = session.get('roleName'); let seasonNum: number = this.app.get('pvpSeasonNum'); let seasonEndTime: number = this.app.get('pvpSeasonEndTime'); let { seasonWinNum, receivedBox, challengeCnt: lastChallengeCnt, challengeRefTime: lastChallengeRefTime } = await PvpDefenseModel.findByRoleIdIncludeAll(roleId); let dicPvpBox = getPvpBoxBySeasonNumAndIndex(seasonNum, id); if(!dicPvpBox) return resResult(STATUS.DIC_DATA_NOT_FOUND); if (seasonWinNum < dicPvpBox.winTimes) { return resResult(STATUS.PVP_NOT_REACH_BOX_SCORE); } if (receivedBox.indexOf(id) != -1) { return resResult(STATUS.PVP_BOX_IS_GOT); } receivedBox.push(id); let { challengeCnt, challengeRefTime } = await refChallengeCnt(lastChallengeCnt, lastChallengeRefTime, seasonEndTime, roleId, session.get('vipStartTime')); await PvpDefenseModel.updateInfo(roleId, { receivedBox, challengeCnt, challengeRefTime }); let result = await addItems(roleId, roleName, sid, dicPvpBox.reward, ITEM_CHANGE_REASON.PVP_BOX_REWARD); // 任务 await checkTask(serverId, roleId, sid, TASK_TYPE.PVP_RECEIVE_BOX); return resResult(STATUS.SUCCESS, { goods: result, receivedBox, challengeCnt, challengeRefTime, seasonWinNum }); } //9. 战报 async getRec(msg: {}, session: BackendSession) { let roleId = session.get('roleId'); let pvpRecords = await PvpRecordModel.getRecByRoleId(roleId); return resResult(STATUS.SUCCESS, { list: pvpRecords }); } // debug接口 async addRoleScore(msg: { heroScores: Array<{ hid: number, score: number }> }, session: BackendSession) { let { heroScores: addHeroScores } = msg; let roleId = session.get('roleId'); let sid = session.get('sid'); let serverId = session.get('serverId'); let { heroScores, hisScore } = await PvpDefenseModel.findByRoleId(roleId); let score = 0; for (let { hid, score: heroScore } of addHeroScores) { if (heroScore < 0) continue; let index = findIndex(heroScores, { hid }); if (index != -1) { heroScores[index].score = heroScore; } else { heroScores.push({ hid, score: heroScore }); } } for (let heroScore of heroScores) { score += heroScore.score; } if (score < 0) { score = 0; } if (hisScore < score) { hisScore = score; } let pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, { score, hisScore, heroScores }); const role = await RoleModel.findByRoleId(roleId); // 加入排行榜 let seasonNum: number = this.app.get('pvpSeasonNum'); let r = new Rank(REDIS_KEY.PVP_RANK, { seasonNum }); await r.setRankWithRoleInfo(roleId, pvpDefense.score, pvpDefense.updatedAt.getTime(), role); // 任务 await checkTask(serverId, roleId, sid, TASK_TYPE.PVP_HERO_SCORE, { heroScores }); return resResult(STATUS.SUCCESS, { score, hisScore, heroScores }); } async debugPvpSeasonResetTime(msg: { day: number }, session: BackendSession) { let { day: minute } = msg; let { seasonNum, seasonEndTime } = await pinus.app.rpc.systimer.systimerRemote.resetPvpSeasonTime.toServer('systimer-server-1', minute); return resResult(STATUS.SUCCESS, { seasonNum, seasonEndTime }); } async debugAddChallengeCnt(msg: { challengeCnt: number }, session: BackendSession) { let { challengeCnt } = msg; let roleId = session.get('roleId'); if (challengeCnt > PVP.PVP_CHALLENGE_COUNTS) { challengeCnt = PVP.PVP_CHALLENGE_COUNTS; } let { challengeRefTime } = await PvpDefenseModel.updateInfoAndInclude(roleId, { challengeCnt, challengeRefTime: nowSeconds(), refOppCnt: 0 }); return resResult(STATUS.SUCCESS, { challengeCnt, challengeRefTime }); } async debugResetRefOppCnt(msg: { magicWord: string }, session: BackendSession) { const { magicWord } = msg; if (magicWord !== DEBUG_MAGIC_WORD) { return resResult(STATUS.TOKEN_ERR); } let roleId = session.get('roleId'); await PvpDefenseModel.updateInfo(roleId, { refOppCnt: 0 }); return resResult(STATUS.SUCCESS); } async debugResetAttackCnt(msg: { magicWord: string }, session: BackendSession) { const { magicWord } = msg; if (magicWord !== DEBUG_MAGIC_WORD) { return resResult(STATUS.TOKEN_ERR); } let roleId = session.get('roleId'); await PvpDefenseModel.updateInfo(roleId, { setAttackCnt: 0, buyAttackCnt: 0 }); return resResult(STATUS.SUCCESS); } async debugResetBox(msg: { magicWord: string }, session: BackendSession) { const { magicWord } = msg; if (magicWord !== DEBUG_MAGIC_WORD) { return resResult(STATUS.TOKEN_ERR); } let roleId = session.get('roleId'); await PvpDefenseModel.updateInfo(roleId, { hisScore: 5000, receivedBox: [] }); return resResult(STATUS.SUCCESS); } }