627 lines
27 KiB
TypeScript
627 lines
27 KiB
TypeScript
|
||
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 { checkActivityTask, checkTask, checkTaskInPvpEnd } from '../../../services/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 { getGoldObject } from '../../../pubUtils/itemUtils';
|
||
import { addItems, handleCost, unlockFigure } from '../../../services/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({ 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 = refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime);
|
||
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 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 seasonEndTime: number = this.app.get('pvpSeasonEndTime');
|
||
let { challengeCnt, challengeRefTime } = refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime);
|
||
if (challengeCnt == 0) {
|
||
return resResult(STATUS.PVP_CHALLENGE_TIMES_NOT_ENOUGH);
|
||
}
|
||
await PvpDefenseModel.updateInfo(roleId, { challengeCnt, challengeRefTime });
|
||
let { oppPlayers } = pvpDefense;
|
||
let curOpp = 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(roleId, sid, TASK_TYPE.PVP, 1, true, {});
|
||
|
||
return resResult(STATUS.SUCCESS, {
|
||
battleCode
|
||
});
|
||
}
|
||
|
||
// 结算
|
||
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.oppPlayers.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() });
|
||
|
||
// 对手记录更新
|
||
await PvpHistoryOppModel.setStatus(roleId, oppRoleId, 1);
|
||
|
||
// 刷新对手
|
||
let seasonNum: number = this.app.get('pvpSeasonNum');
|
||
let seasonEndTime: number = this.app.get('pvpSeasonEndTime');
|
||
let oppPlayers = await refreshEnemies(role, seasonNum, pvpDefense.score ,pvpDefense.attack.score, pvpDefense.attack.pLv||1);
|
||
update.oppPlayers = oppPlayers;
|
||
|
||
// 更新battleRecord
|
||
await BattleRecordModel.updateBattleRecordByCode(battleCode, {
|
||
$set: { status: isSuccess ? 1 : 2 }
|
||
}, true);
|
||
|
||
// 减少挑战次数
|
||
let refChallengeObj = refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime);
|
||
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);
|
||
|
||
// 加入排行榜
|
||
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(roleId, sid, isSuccess, pvpDefense.heroScores);
|
||
await checkActivityTask(serverId, sid, roleId, TASK_TYPE.PVP, 1)
|
||
if (isSuccess) {
|
||
await checkActivityTask(serverId, sid, roleId, TASK_TYPE.PVP_WIN, 1)
|
||
await checkActivityTask(serverId, sid, roleId, TASK_TYPE.PVP_WIN_SERIES, 1)
|
||
}
|
||
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 = refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime);
|
||
// 更新挑战阵容
|
||
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 = refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime);
|
||
// 更新防守阵容
|
||
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 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 } = refChallengeCnt(lastChallengeCnt, lastChallengeRefTime, seasonEndTime);
|
||
await PvpDefenseModel.updateInfo(roleId, { receivedBox, challengeCnt, challengeRefTime });
|
||
let result = await addItems(roleId, roleName, sid, pvpBox.reward, ITEM_CHANGE_REASON.PVP_BOX_REWARD);
|
||
// 任务
|
||
await checkTask(roleId, sid, TASK_TYPE.PVP_RECEIVE_BOX, 1, true, {});
|
||
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 { 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(roleId, sid, TASK_TYPE.PVP_HERO_SCORE, 0, false, { 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);
|
||
}
|
||
}
|