Files
ZYZ/game-server/app/servers/battle/handler/pvpHandler.ts
2022-04-20 21:37:51 +08:00

635 lines
28 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Application, BackendSession, pinus, HandlerService, } from 'pinus';
import { uniq, findWhere, findIndex } from 'underscore';
import { gameData, getPvpBoxs, getPLvByScore } from '../../../pubUtils/data';
import { refreshEnemies, getEnemies, getLvByScore, comsumeChallengeCnt, 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 { PVPConfigModel } from '../../../db/SystemConfig';
import { Rank } from '../../../services/rankService';
import { checkTask, checkTaskInPvpEnd } from '../../../services/task/taskService';
import { Attack, AttackHero, 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 { checkBattleHeroesByHid } from '../../../services/normalBattleService';
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 = <RoleType>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 = <RoleType>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 = <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, myRank);
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', 'hisScore'])
});
}
async buyAttackCnt(msg: { count: number }, session: BackendSession) {
let { count } = msg;
let roleId = session.get('roleId');
let sid = session.get('sid');
if(count <= 0 || count == undefined) return resResult(STATUS.WRONG_PARMS);
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 sid = session.get('sid');
if (heroes.length > LINEUP_NUM || heroes.length <= 0) {
return resResult(STATUS.WRONG_PARMS);
}
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, []);
// 刷对手
let role = <RoleType>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<number, string>(), 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, <string>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, 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<PlayerDetailHero>();
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<PlayerDetailHero>();
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 seasonEndTime: number = this.app.get('pvpSeasonEndTime');
let { hisScore, receivedBox, challengeCnt: lastChallengeCnt, challengeRefTime: lastChallengeRefTime } = await PvpDefenseModel.findByRoleIdIncludeAll(roleId);
let pvpBoxs = getPvpBoxs();
let pvpBox = findWhere(pvpBoxs, { id });
if (hisScore < pvpBox.score) {
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, pvpBox.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 });
}
//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);
}
}