巅峰演武:赛季优化修改

This commit is contained in:
luying
2022-10-17 14:42:40 +08:00
parent ddff18eb20
commit 08ca06d7ac
30 changed files with 590 additions and 272 deletions

View File

@@ -193,6 +193,10 @@ async function treatStartLogic(app: _pinus.Application) {
initGuildActivityIndexInPinus()
.then(resetJoinWoodenHorse);
}
if(app.getServerType() == 'battle'|| app.getServerType() == 'role'|| app.getServerType() == 'connector') {
timeTaskService.setPvpSeasonNum();
timeTaskService.setPvpSettleSeasonNum();
}
if(app.isMaster()) {
redisService.initAllRank();

View File

@@ -2,7 +2,7 @@
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, calLineupScore } from '../../../services/pvpService';
import { refreshEnemies, getEnemies, refChallengeCnt, generPVPOppRecInfo, generMyRecInfo, sendLastSeasonRewardIfNotSent, refreshRefOppCnt, generPvpLineupCe, calLineupScore, checkPvpSeasonIsStart, checkPvpSeasonIsSummit } from '../../../services/pvpService';
import { RoleModel, RoleType } from '../../../db/Role';
import { STATUS } from '../../../consts/statusCode';
import { resResult, genCode, checkRoleIsRobot, robotIdComBack } from '../../../pubUtils/util';
@@ -10,7 +10,7 @@ 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 { Attack, Defense, DefenseHero, PvpDataReturn, pvpSaveDataReturn } 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';
@@ -22,6 +22,8 @@ import { PvpRecordModel } from '../../../db/PvpRecord';
import { pvpEndParamInter } from '../../../pubUtils/interface';
import { getSeconds, nowSeconds } from '../../../pubUtils/timeUtil';
import { PlayerDetail, PlayerDetailHero } from '../../../domain/battleField/guild';
import { PvpSaveDataModel } from '../../../db/PvpSaveData';
import { PVPConfigModel } from '../../../db/PvpConfig';
export default function (app: Application) {
new HandlerService(app, {});
@@ -44,7 +46,9 @@ export class PvpHandler {
// 如果没有发过,将上赛季的奖励发下
pvpDefense = await sendLastSeasonRewardIfNotSent(pvpDefense);
let seasonNum: number = this.app.get('pvpSeasonNum');
let seasonStartTime: number = this.app.get('pvpSeasonStartTime');
let seasonEndTime: number = this.app.get('pvpSeasonEndTime');
let seasonRewardTime: number = this.app.get('pvpSeasonRewardTime');
let update: pvpUpdateInter = { };
let result = new PvpDataReturn(); // 返回对象
@@ -68,17 +72,16 @@ export class PvpHandler {
pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, update);
}
result.setPvpConfig(seasonNum, seasonEndTime);
result.setPvpConfig(seasonNum, seasonStartTime, seasonEndTime, seasonRewardTime);
result.setPvpDefense(pvpDefense);
result.calHasSaveDefense();
let oppPlayersReturn = await getEnemies(pvpDefense.oppPlayers||[], pvpDefense.winStreakNum);
result.setOppPlayers(oppPlayersReturn);
// 赛季结算
let pvpSeasonResult = await PvpSeasonResultModel.getPvpSeasonResult(roleId);
if (!!pvpSeasonResult && !!pvpSeasonResult.show && pvpDefense.seasonNum == seasonNum) {
if (!!pvpSeasonResult && !!pvpSeasonResult.show) {
result.setPvpSeasonResult(pvpSeasonResult);
result.setIsFirstEntry(true);
update.isFirstEntry = false;
await PvpSeasonResultModel.setShow(roleId);
}
// 拍卖
@@ -153,6 +156,9 @@ export class PvpHandler {
if (!warInfo) {
return resResult(STATUS.BATTLE_MISS_INFO);
}
if(!checkPvpSeasonIsStart()) {
return resResult(STATUS.PVP_SEASON_NOT_OPEN);
}
let pvpDefense = await PvpDefenseModel.findByRoleId(roleId);
if (!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN);
@@ -375,6 +381,30 @@ export class PvpHandler {
return resResult(STATUS.SUCCESS, pick(result, ['attack', 'oppPlayers', 'buyAttackCnt', 'setAttackCnt', 'challengeCnt', 'challengeRefTime']));
}
// 获取存档列表
async getSaveData(msg: {}, session: BackendSession) {
let roleId = session.get('roleId');
let pvpDefense = await PvpDefenseModel.findByRoleId(roleId);
if(!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN);
let pvpConfig = await PVPConfigModel.findCurPVPConfig();
if(!pvpConfig) return resResult(STATUS.PVP_SEASON_NOT_OPEN);
let saveDatas = await PvpSaveDataModel.findByRoleId(roleId);
let list: pvpSaveDataReturn[] = [];
for(let warId of (pvpConfig.warIds||[])) {
let data = new pvpSaveDataReturn(warId);
let curSaveData = saveDatas.find(cur => cur.warId == warId);
data.setUserSaveData(curSaveData);
if(pvpDefense.defense?.warId == warId) {
data.setAsUsing();
}
list.push(data);
}
return resResult(STATUS.SUCCESS, { list });
}
//3. 保存防守阵容
async saveDefense(msg: { heroes: { actorId: number, dataId: number, order: number, ai: number }[], warId: number, buff: number }, session: BackendSession) {
let { heroes, warId, buff } = msg;
@@ -382,10 +412,14 @@ export class PvpHandler {
if (heroes.length > LINEUP_NUM || heroes.length <= 0) {
return resResult(STATUS.WRONG_PARMS);
}
if(checkPvpSeasonIsSummit()) {
return resResult(STATUS.PVP_CAN_NOT_SAVE_DEFENSE);
}
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 refChallengeObj = await refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime, roleId, session.get('vipStartTime'));
// 更新防守阵容
@@ -417,8 +451,8 @@ export class PvpHandler {
});
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 });
await PvpSaveDataModel.createSaveData(roleId, warId, buff, defenseHeroes);
pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, { ...refChallengeObj, defense, lineupCe, hasDefense: true, seasonNum });
// 返回
let result = new PvpDataReturn();
result.setPvpDefense(pvpDefense);
@@ -584,10 +618,8 @@ export class PvpHandler {
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 debugPvpSeasonResetTime(msg: {}, session: BackendSession) {
return resResult(STATUS.DEBUG_FUNCTION_ERR);
}
async debugAddChallengeCnt(msg: { challengeCnt: number }, session: BackendSession) {

View File

@@ -1,10 +1,11 @@
import { Application, ChannelService, FrontendSession, RemoterClass, HandlerService, } from 'pinus';
import { PVPConfigModel, PVPConfigType } from '../../../db/SystemConfig';
import { Application, ChannelService, HandlerService, } from 'pinus';
import { PVPConfigModel, PVPConfigType } from '../../../db/PvpConfig';
import { reloadResources } from '../../../pubUtils/data';
import { setApiIsClose } from '../../../services/chatService';
import { getServerMainten, setServerMainten, stopServerMainten } from '../../../services/gmService';
import { savePvpSeasonMemory } from '../../../services/log/memoryLogService';
import { taflush } from '../../../services/sdkService';
import { setPvpSeasonNum, setPvpSettleSeasonNum } from '../../../services/timeTaskService';
import { errlogger } from '../../../util/logger';
export default function (app: Application) {
@@ -17,7 +18,6 @@ export class BattleRemote {
constructor(private app: Application) {
this.app = app;
this.channelService = app.get('channelService');
this.initPvpSeasonNum();
}
private channelService: ChannelService;
@@ -91,26 +91,23 @@ export class BattleRemote {
}
public setPvpSeasonNum(pvpConfig: PVPConfigType) {
public async setPvpSettleSeasonNum(pvpConfig: PVPConfigType) {
try {
if(pvpConfig) {
this.app.set('pvpSeasonNum', pvpConfig.seasonNum);
this.app.set('pvpSeasonEndTime', pvpConfig.seasonEndTime);
}
await setPvpSettleSeasonNum(pvpConfig);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async initPvpSeasonNum() {
public async setPvpSeasonNum(pvpConfig: PVPConfigType) {
try {
let pvpConfig = await PVPConfigModel.findCurPVPConfig();
this.setPvpSeasonNum(pvpConfig);
await setPvpSeasonNum(pvpConfig);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public setServerMainten(serverIds: number[], startTime: number, endTime: number) {
try {
setServerMainten(serverIds, startTime, endTime);

View File

@@ -1,10 +1,8 @@
import { Application, ChannelService, FrontendSession, pinus, RemoterClass, HandlerService, } from 'pinus';
import { STATUS } from '../../../consts/statusCode';
import { resResult } from '../../../pubUtils/util';
import { Application, HandlerService, } from 'pinus';
import { reloadResources } from '../../../pubUtils/data';
import { UserGuildType } from '../../../db/UserGuild';
import { incServerNum, kickUser } from '../../../services/connectorService';
import { PVPConfigModel, PVPConfigType } from '../../../db/SystemConfig';
import { PVPConfigModel, PVPConfigType } from '../../../db/PvpConfig';
import { setDicAuctionTime, setDicGuildActivity } from '../../../services/guildActivity/guildActivityService';
import { getServerMainten, setServerMainten, stopServerMainten } from '../../../services/gmService';
import { taflush } from '../../../services/sdkService';
@@ -12,6 +10,7 @@ import { errlogger } from '../../../util/logger';
import { setWeek } from '../../../pubUtils/timeUtil';
import { savePvpSeasonMemory } from '../../../services/log/memoryLogService';
import { setApiIsClose } from '../../../services/chatService';
import { setPvpSeasonNum, setPvpSettleSeasonNum } from '../../../services/timeTaskService';
export default function (app: Application) {
new HandlerService(app, {});
return new ConnectorRemote(app);
@@ -21,7 +20,6 @@ export class ConnectorRemote {
constructor(private app: Application) {
this.app = app;
this.initPvpSeasonNum();
}
public async remoteLogin(uid: string, message?: any) {
@@ -105,21 +103,17 @@ export class ConnectorRemote {
}
}
public setPvpSeasonNum(pvpConfig: PVPConfigType) {
public async setPvpSeasonNum(pvpConfig: PVPConfigType) {
try {
if(pvpConfig) {
this.app.set('pvpSeasonNum', pvpConfig.seasonNum);
this.app.set('pvpSeasonEndTime', pvpConfig.seasonEndTime);
}
await setPvpSeasonNum(pvpConfig);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async initPvpSeasonNum() {
public async setPvpSettleSeasonNum(pvpConfig: PVPConfigType) {
try {
let pvpConfig = await PVPConfigModel.findCurPVPConfig();
this.setPvpSeasonNum(pvpConfig);
await setPvpSettleSeasonNum(pvpConfig);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}

View File

@@ -2,7 +2,7 @@ import { Application, BackendSession, pinus } from 'pinus';
import { genCode, getRandSingleEelm, resResult } from '../../../pubUtils/util';
import { STATUS } from '../../../consts/statusCode';
import moment = require('moment');
import { CreateServerParam, UpdateRegionParams } from '../../../domain/backEndField/params';
import { CreatePvpConfigParam, CreateServerParam, UpdateRegionParams } from '../../../domain/backEndField/params';
import { RegionModel, RegionType } from '../../../db/Region';
import { gameData } from '../../../pubUtils/data';
import { Maintenance, ServerlistModel, ServerlistUpdate } from '../../../db/Serverlist';
@@ -11,6 +11,7 @@ import { createNewServer, sendOpenServerMail } from '../../../services/gmService
import { isNumber } from 'util';
import { MarqueeModel } from '../../../db/Marquee';
import { setApiIsCloseToRemote } from '../../../services/chatService';
import { PVPConfigModel } from '../../../db/PvpConfig';
export default function (app: Application) {
return new GmHandler(app);
@@ -180,4 +181,21 @@ export class GmHandler {
setApiIsCloseToRemote(region.isCloseApi);
return resResult(STATUS.SUCCESS);
}
async savePvpConfig(msg: CreatePvpConfigParam, session: BackendSession) {
let params = new CreatePvpConfigParam(msg);
if(!params.checkParams()) return resResult(STATUS.WRONG_PARMS);
if(params.seasonStartTime >= params.seasonEndTime) return resResult(STATUS.WRONG_PARMS, null, '开始时间不可晚于结束时间');
if(params.seasonEndTime >= params.seasonRewardTime) return resResult(STATUS.WRONG_PARMS, null, '结束时间不可晚于奖励时间');
if(await PVPConfigModel.checkTime(params.seasonNum, params.seasonStartTime, params.seasonRewardTime)) {
return resResult(STATUS.WRONG_PARMS, null, '不可与其他赛季时间重叠');
}
let uid = session.get('uid');
await PVPConfigModel.createPVPConfig(params.seasonNum, params.getUpdateParam(), uid);
pinus.app.rpc.systimer.systimerRemote.setPvpSeasonSchedule.broadcast(true);
return resResult(STATUS.SUCCESS);
}
}

View File

@@ -1,4 +1,4 @@
import { Application, BackendSession } from "pinus";
import { Application, BackendSession, pinus } from "pinus";
import { gameData, hasShopType } from "../../../pubUtils/data";
import { parseGoodStr, resResult } from "../../../pubUtils/util";
import { STATUS, GUILD_STRUCTURE, ITID, CONSUME_TYPE, HERO_QUALITY_TYPE, HERO_GROW_MAX, ITEM_CHANGE_REASON } from "../../../consts";
@@ -51,6 +51,7 @@ export class ShopHandler {
let roleName = session.get('roleName');
let sid = session.get('sid');
let serverId = session.get('serverId');
let seasonNum = pinus.app.get('pvpSeasonNum');
let { activityId = 0, shopItemId, count } = msg;
@@ -58,7 +59,7 @@ export class ShopHandler {
if(!dicShopItem) return resResult(STATUS.DIC_DATA_NOT_FOUND);
if(dicShopItem['productID'] && dicShopItem['productID'] != '&') return resResult(STATUS.CAN_NOT_PURCHASE);
let userShop = await UserShopModel.findByRoleAndItem(roleId, activityId, dicShopItem);
let userShop = await UserShopModel.findByRoleAndItem(roleId, activityId, dicShopItem, seasonNum);
let checkResult = await checkShopInPurchase(session, activityId, count, userShop?.count||0, dicShopItem);
if(checkResult.code != STATUS.SUCCESS.code) {
@@ -71,7 +72,7 @@ export class ShopHandler {
if(!costResult) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
// 次数
userShop = await UserShopModel.purchase(roleId, roleName, activityId, dicShopItem, count);
userShop = await UserShopModel.purchase(roleId, roleName, activityId, dicShopItem, count, seasonNum);
if(!userShop) return resResult(STATUS.BUY_COUNT_OVER);
// 获得

View File

@@ -1,16 +1,13 @@
import { Application, ChannelService, HandlerService, } from 'pinus';
// import { sendRolesMails } from '../../../services/mailService';
import { reloadResources } from '../../../pubUtils/data';
import { HeroUpdate } from '../../../db/Hero';
import { RoleUpdate } from '../../../db/Role';
import { SkinUpdate } from '../../../db/Skin';
import { RankFirstModel, RankFirstType } from '../../../db/RankFirst';
import { Figure } from '../../../domain/dbGeneral';
import { PVPConfigModel, PVPConfigType } from '../../../db/SystemConfig';
import { PVPConfigModel, PVPConfigType } from '../../../db/PvpConfig';
import { treatRoleName, taflush, sendSurveyMail } from '../../../services/sdkService';
import { getServerMainten, setServerMainten, stopServerMainten } from '../../../services/gmService';
import { errlogger } from '../../../util/logger';
import { setApiIsClose } from '../../../services/chatService';
import { setPvpSeasonNum, setPvpSettleSeasonNum } from '../../../services/timeTaskService';
export default function (app: Application) {
new HandlerService(app, {});
@@ -23,7 +20,6 @@ export class RoleRemote {
this.app = app;
// this.channelService = app.get('channelService');
this.loadRankFirst();
this.initPvpSeasonNum();
}
// private channelService: ChannelService;
@@ -74,21 +70,17 @@ export class RoleRemote {
}
public setPvpSeasonNum(pvpConfig: PVPConfigType) {
public async setPvpSeasonNum(pvpConfig: PVPConfigType) {
try {
if(pvpConfig) {
this.app.set('pvpSeasonNum', pvpConfig.seasonNum);
this.app.set('pvpSeasonEndTime', pvpConfig.seasonEndTime);
}
await setPvpSeasonNum(pvpConfig);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async initPvpSeasonNum() {
public async setPvpSettleSeasonNum(pvpConfig: PVPConfigType) {
try {
let pvpConfig = await PVPConfigModel.findCurPVPConfig();
this.setPvpSeasonNum(pvpConfig);
await setPvpSettleSeasonNum(pvpConfig);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}

View File

@@ -1,5 +1,5 @@
import { Application, ChannelService } from 'pinus';
import { resetPvpSeasonTime, guildActivityStart, gateActivityEnd, cityActivityEnd, raceActivityEnd, guildActivitySchedule, auctionSchedule, initMaintenance, stopMaintenance, initAutoCreateServer, addMailsToSchedule, updateTimeLimitRank, setLadderCountDown, cancelLadderCountDown, initSumSchedule } from '../../../services/timeTaskService';
import { guildActivityStart, gateActivityEnd, cityActivityEnd, raceActivityEnd, guildActivitySchedule, auctionSchedule, initMaintenance, stopMaintenance, initAutoCreateServer, addMailsToSchedule, updateTimeLimitRank, setLadderCountDown, cancelLadderCountDown, initSumSchedule, setPvpSeasonSchedule } from '../../../services/timeTaskService';
import PvpDefenseType from '../../../db/PvpDefense';
import { DicGuildActivity } from '../../../pubUtils/dictionary/DicGuildActivity';
import { reloadResources } from '../../../pubUtils/data';
@@ -30,14 +30,6 @@ export class SystimerRemote {
}
private channelService: ChannelService;
public async resetPvpSeasonTime(day: number) {
try {
return await resetPvpSeasonTime(day);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async guildActivityStart(dicGuildActivity: DicGuildActivity) {
try {
return await guildActivityStart(dicGuildActivity);
@@ -232,4 +224,12 @@ export class SystimerRemote {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
public async setPvpSeasonSchedule(fromBackend: boolean) {
try {
setPvpSeasonSchedule(fromBackend);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
}

View File

@@ -48,6 +48,7 @@ import { ComBattleTeamModel } from '../db/ComBattleTeam';
import { INFO_WINDOW } from '../pubUtils/dicParam';
import { getLadderData } from './ladderService';
import { dispatch } from '../pubUtils/dispatcher';
import { PvpDataReturn } from '../domain/battleField/pvp';
/**
* init: 初始的时候是否推送 true-推 false-不推
@@ -260,11 +261,17 @@ async function getPvpEntryData(roleId: string) {
pvpDefense = await sendLastSeasonRewardIfNotSent(pvpDefense);
let seasonNum: number = pinus.app.get('pvpSeasonNum');
let seasonEndTime: number = pinus.app.get('pvpSeasonEndTime');
let seasonStartTime: number = pinus.app.get('pvpSeasonStartTime');
let seasonRewardTime: number = pinus.app.get('pvpSeasonRewardTime');
let result = new PvpDataReturn(); // 返回对象
result.setPvpConfig(seasonNum, seasonStartTime, seasonEndTime, seasonRewardTime);
result.setPvpDefense(pvpDefense);
result.calHasSaveDefense();
let refChallengeObj = await refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime, roleId);
let { challengeCnt } = refChallengeObj;
let { receivedBox, score, seasonWinNum } = pvpDefense;
return { challengeCnt, score, seasonWinNum, receivedBox, seasonNum, seasonEndTime }
result.setChallengeCnt(challengeCnt);
return pick(result, ['challengeCnt', 'score', 'seasonWinNum', 'receivedBox', 'hasSaveDefense', 'seasonNum', 'seasonEndTime', 'seasonStartTime', 'seasonRewardTime'])
} else {
return null
}

View File

@@ -5,7 +5,6 @@ import { STATUS, MAIL_TYPE, GUILD_AUTH, GUILD_JOB, REDIS_KEY, CHAT_SERVER, TASK_
import { RoleModel, RoleType } from "../db/Role";
import { UserGuildModel, UserGuildType, WishGood } from "../db/UserGuild";
import { UserGuildApplyModel } from "../db/UserGuildApply";
import { PVPConfigModel } from "../db/SystemConfig";
import { getZeroPointD, getZeroPointOfTime, getZeroPointOfTimeD, nowSeconds } from "../pubUtils/timeUtil";
import { pinus, BackendSession, FrontendOrBackendSession } from "pinus";
import { ARMY } from "../pubUtils/dicParam";

View File

@@ -2,23 +2,21 @@
import { PvpDefenseModel, PvpDefenseType, pvpUpdateInter } from '../db/PvpDefense';
import { Defense, Attack, LineupCe, OppPlayer, HeroScore, HeroReward, OppPlayerReturn, AttackHero, DefenseHero } from '../domain/battleField/pvp';
import { RoleType } from '../db/Role';
import { REDIS_KEY, TASK_TYPE, MAIL_TYPE, TA_EVENT, ITID, getHeadItid, getFrameItid, getSpineItid } from '../consts';
import { REDIS_KEY, TASK_TYPE, MAIL_TYPE, TA_EVENT, ITID, getHeadItid, getFrameItid, getSpineItid, PVP_SEASON_STATUS } from '../consts';
import { dicPvpOpponent, DicPvpOpponent } from "../pubUtils/dictionary/DicPvpOpponent";
import { getRandSingleIndex, genCode, shouldRefresh, getChineseName, makeRobotId, robotIdComBack, getRandSingleEelm } from '../pubUtils/util';
import { pvpEndParamInter, RewardInter } from '../pubUtils/interface';
import { gameData, getPLvByScore, getPvpHeroRewardsByScore, getPvpRankRewardsByRank, getPvpDifficultByScore, getPlvAndScore, getPvpBoxsBySeasonNum, getPvpRankMaxRewardsBySeasonNum, randomGoodsByItid } from "../pubUtils/data";
import { EXTERIOR, PVP } from '../pubUtils/dicParam';
import { PVPConfigModel, PVPConfigType } from '../db/SystemConfig'
import { PVPConfigModel } from '../db/PvpConfig'
import { nowSeconds, getTimeFun } from '../pubUtils/timeUtil';
import { HeroesRecord, PvpRecordPlayerInfo } from '../db/PvpRecord';
import { HeroModel, HeroType } from '../db/Hero';
import { AttributeCal } from '../domain/roleField/attribute';
import { PvpEnemies, PvpHeroInfo, PvpOtherHeroes } from '../domain/dbGeneral';
import { DicWarJson } from '../pubUtils/dictionary/DicWarJson';
import { pinus } from 'pinus';
import { PvpHistoryOppModel, PvpHistoryOppType, PvpOppCreateParam } from '../db/PvpHistoryOpp';
import { Rank } from './rankService';
import { CounterModel } from '../db/Counter';
import { DicRankRewads } from '../pubUtils/dictionary/DicPvpRankReward';
import { PvpSeasonResultModel, PvpSeasonResultType } from '../db/PvpSeasonResult';
import { checkTask } from './task/taskService';
@@ -27,6 +25,7 @@ import { RoleRankInfo } from '../domain/rank';
import { reportTAEvent } from './sdkService';
import { getVipPvpChallengeMaxCnt } from './activity/monthlyTicketService';
import { getHeroesAttributes } from './playerCeService';
import { setPvpSeasonNumToRemote, setPvpSettleSeasonNumToRemote } from './timeTaskService';
/**
* 返回对手三人信息
@@ -166,7 +165,7 @@ export async function matchPlayerByRank(seasonNum: number, chosenOpps: string[],
oppRoleId = result[0];
let pvpdefense = await PvpDefenseModel.findByRoleIdIncludeAll(oppRoleId);
if (!pvpdefense || pvpdefense.seasonNum != seasonNum) return null;
if (!pvpdefense || pvpdefense.seasonNum != seasonNum || !pvpdefense.hasDefense) return null;
let pvpHistoryOpp = await generPlayerOppHis(pvpdefense, roleId, pos);
if (!pvpHistoryOpp) return null;
@@ -367,15 +366,21 @@ export async function comsumeChallengeCnt(challengeCnt: number, challengeRefTime
}
export async function sendLastSeasonRewardIfNotSent(pvpDefense: PvpDefenseType) {
let seasonNum: number = pinus.app.get('pvpSeasonNum');
if(pvpDefense.seasonNum < seasonNum) {
let oldPvpCongig = await PVPConfigModel.findPVPConfig(pvpDefense.seasonNum);
let result = await sendPVPRewardToUser(pvpDefense, pvpDefense.seasonNum, oldPvpCongig.seasonEndTime);
let seasonSettleNum: number = pinus.app.get('pvpSettleSeasonNum');
console.log('##### sendLastSeasonRewardIfNotSent seasonSettleNum', seasonSettleNum)
if(seasonSettleNum && !await checkHasSettled(seasonSettleNum, pvpDefense.roleId)) {
let oldPvpCongig = await PVPConfigModel.findPVPConfig(seasonSettleNum);
let result = await sendPVPRewardToUser(pvpDefense, seasonSettleNum, oldPvpCongig.seasonEndTime);
pvpDefense = result.pvpDefense;
}
return pvpDefense;
}
async function checkHasSettled(seasonSettleNum: number, roleId: string) {
let hasData = await PvpSeasonResultModel.checkResultBySeasonNum(roleId, seasonSettleNum);
return hasData;
}
// 获取刷新对手次数及消耗
export function refreshRefOppCnt(pvpDefense: PvpDefenseType) {
let { refOppCnt = 0, setAttackCnt = 0, buyAttackCnt = 0, refDaily } = pvpDefense;
@@ -563,7 +568,8 @@ export async function generPVPOppRecInfo(isSuccess: boolean, curOpp: OppPlayer,
let { pvpSeasonResult } = await sendPVPRewardToUser(pvpDefense, pvpConfig.seasonNum, pvpConfig.seasonEndTime);
reportTAEvent(roleId, TA_EVENT.PVP_SEASON_END, { top_rank: rank, hero_score: pvpSeasonResult.heroScores })
}
await PVPConfigModel.setReward(pvpConfig.seasonNum);
let settledPvpConfig = await PVPConfigModel.setReward(pvpConfig.seasonNum);
await setPvpSettleSeasonNumToRemote(settledPvpConfig);
}
/**
@@ -593,7 +599,7 @@ export async function sendPVPRewardToUser(pvpDefense: PvpDefenseType, seasonNum:
return {
pvpSeasonResult,
pvpDefense: await resetPvpScores(pvpDefense, seasonNum + 1, pvpSeasonResult)
pvpDefense: await resetPvpScores(pvpDefense, pvpSeasonResult)
}
}
@@ -612,17 +618,16 @@ async function sendUnreceivedPvpBox(roleId: string, seasonNum: number, seasonWin
}
}
async function resetPvpScores(pvpDefense: PvpDefenseType, seasonNum: number, pvpSeasonResult: PvpSeasonResultType) {
let { roleId, attack, defense } = pvpDefense;
async function resetPvpScores(pvpDefense: PvpDefenseType, pvpSeasonResult: PvpSeasonResultType) {
let { roleId, attack } = pvpDefense;
let { newHeroScores, newScore } = pvpSeasonResult;
let initCount = await getVipPvpChallengeMaxCnt(roleId)
let newAttack = <Attack>calLineupScore(attack, newHeroScores);
let newDefense = <Defense>calLineupScore(defense, newHeroScores);
pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, {
heroScores: newHeroScores, score: newScore, attack: newAttack, defense: newDefense,
seasonNum, challengeCnt: initCount, challengeRefTime: 0, winStreakNum: 0, isFirstEntry: true,
heroScores: newHeroScores, score: newScore, attack: newAttack, defense: null, hasDefense: false,
challengeCnt: initCount, challengeRefTime: 0, winStreakNum: 0,
seasonWinNum: 0, receivedBox: []
});
return pvpDefense;
@@ -664,8 +669,9 @@ export async function savePvpSeasonResult(pvpDefense: PvpDefenseType, seasonNum:
}
//pvp锁定的信息存入赛季结算表中
let {receivedBox, score, seasonWinNum, heroScores } = pvpDefense;
let pvpSeasonResult = await PvpSeasonResultModel.updatePvpSeasonResult(pvpDefense.roleId, seasonNum, {
...pvpDefense, rankLv, heroGoods, rankGoods, show: true, newScore, newHeroScores, seasonEndTime
receivedBox, score, seasonWinNum, heroScores, rankLv, heroGoods, rankGoods, show: true, newScore, newHeroScores, seasonEndTime
});//结算修改玩家pvp信息
if(newScore > 0) {
let r = new Rank(REDIS_KEY.PVP_RANK, { seasonNum: seasonNum + 1 });
@@ -702,4 +708,29 @@ export async function generPvpLineupCe(roleId: string, lineupCe: LineupCe[], att
newLineupCe.push({ hid, ce });
}
return newLineupCe;
}
export function getPvpSeasonStatus() {
let seasonEndTime: number = pinus.app.get('pvpSeasonEndTime');
let seasonStartTime: number = pinus.app.get('pvpSeasonStartTime');
let seasonRewardTime: number = pinus.app.get('pvpSeasonRewardTime');
let now = nowSeconds();
if(now >= seasonStartTime && now < seasonEndTime) {
return PVP_SEASON_STATUS.START;
} else if (now >= seasonEndTime && now < seasonRewardTime) {
return PVP_SEASON_STATUS.SUMMIT;
} else {
return PVP_SEASON_STATUS.WAITING;
}
}
export function checkPvpSeasonIsStart() {
let status = getPvpSeasonStatus();
return status == PVP_SEASON_STATUS.START;
}
export function checkPvpSeasonIsSummit() {
let status = getPvpSeasonStatus();
return status == PVP_SEASON_STATUS.SUMMIT;
}

View File

@@ -9,13 +9,14 @@ import { UserShopTypeModel, UserShopTypeType } from "../db/UserShopType";
import { GuildModel } from "../db/Guild";
import { RoleModel } from "../db/Role";
import { DicShop } from "../pubUtils/dictionary/DicShop";
import { BackendSession } from "pinus";
import { BackendSession, pinus } from "pinus";
import { ActivityModelType } from "../db/Activity";
import { addItems } from "./role/rewardService";
import { LadderMatchModel } from "../db/LadderMatch";
export async function getAllShopList(roleId: string, serverId: number) {
let userShopRecs = await UserShopModel.findByRoleId(roleId);
let seasonNum = pinus.app.get('pvpSeasonNum');
let userShopRecs = await UserShopModel.findByRoleId(roleId, seasonNum);
let userShopTypeRecs = await UserShopTypeModel.findByRoleId(roleId);
let activities = await getShopActivityDatas(roleId, serverId);
@@ -30,7 +31,8 @@ export async function getAllShopList(roleId: string, serverId: number) {
}
export async function getShopListByType(shop: number, type: number, roleId: string, serverId: number) {
let userShopRecs = await UserShopModel.findByShopType(roleId, shop, type);
let seasonNum = pinus.app.get('pvpSeasonNum');
let userShopRecs = await UserShopModel.findByShopType(roleId, shop, type, seasonNum);
let activities = await getShopActivityDatas(roleId, serverId);
let activity = activities.find(cur => cur.shop == shop && cur.type == type);
let readRecord = await UserShopTypeModel.findByType(roleId, shop, type);
@@ -128,6 +130,7 @@ export async function checkShopInPurchase(session: BackendSession, activityId: n
}
export async function checkShopCanBuyInOrder(roleId: string, serverId: number, activity: ActivityModelType, productID: string) {
let seasonNum = pinus.app.get('pvpSeasonNum');
let role = await RoleModel.findByRoleId(roleId, 'guildCode createTime vipStartTime');
let { createTime, guildCode, vipStartTime } = role;
let serverTime = await getServerCreateTime(serverId);
@@ -136,7 +139,7 @@ export async function checkShopCanBuyInOrder(roleId: string, serverId: number, a
let dicItem = shopData.findByProductID(productID);
if(!dicItem) return false;
let userShop = await UserShopModel.findByRoleAndItem(roleId, activity.activityId, dicItem);
let userShop = await UserShopModel.findByRoleAndItem(roleId, activity.activityId, dicItem, seasonNum);
let result = await checkShopItemCanBuy(activity.activityId, dicItem.id, roleId, serverId, guildCode, vipStartTime, 1, userShop?.count||0, dicItem);
return result.code == STATUS.SUCCESS.code;
}
@@ -188,6 +191,7 @@ export async function checkShopItemCanBuy(activityId: number, shopItemId: number
*
*/
export async function makeShopOrder(roleId: string, roleName: string, sid: string, serverId: number, activityId: number, productID: string) {
let seasonNum = pinus.app.get('pvpSeasonNum');
let activityData: ActivityModelType = await getActivityById(activityId);
if (!activityData) {
return STATUS.ACTIVITY_MISSING;
@@ -206,7 +210,7 @@ export async function checkShopItemCanBuy(activityId: number, shopItemId: number
}];
await addItems(roleId, roleName, sid, reward, ITEM_CHANGE_REASON.SHOP_PURCHASE);
await UserShopModel.purchase(roleId, roleName, activityId, dicItem, 1);
await UserShopModel.purchase(roleId, roleName, activityId, dicItem, 1, seasonNum);
return {
code: 0,
data: Object.assign({}, { item: { shop: dicItem.shop, type: dicItem.type, shopItemId: dicItem.id }, activityId: activityId })

View File

@@ -1,6 +1,6 @@
import { scheduleJob, Job, scheduledJobs, } from 'node-schedule';
import { PVPConfigModel, PVPConfigType } from '../db/SystemConfig';
import { PVPConfigModel, PVPConfigType } from '../db/PvpConfig';
import { nowSeconds, getTimeFun, getSeconds } from '../pubUtils/timeUtil';
import { getTodayGuildActivity, gameData } from '../pubUtils/data';
import { pvpSeasonEnd } from './pvpService';
@@ -46,6 +46,7 @@ const PER_SECOND = 1 * 1000;
const PER_DAY = 24 * 60 * 60;
const PER_HOUR = 1 * 60 * 60;
const PER_MINUTE = 1 * 60;
var seasonEndJob: Job;
var seasonMakeRewardTimJobId: Job;
var seasonRefreshTimeJobId: Job;
let guildWeeklyJobId: Job;
@@ -61,7 +62,7 @@ export async function init() {
console.log('******* init systimer *******')
// pvp赛季
await setPvpSeason(true);
await setPvpSeasonSchedule();
// 周功勋结算任务
guildWeeklyJobId = scheduleJob('settleGuildWeekly', '0 0 0 * * 1', settleGuildWeekly);
@@ -115,111 +116,115 @@ export async function everydayRefresh() {
// —————————————— PVP 及赛季相关 —————————————— //
function getSeasonContinueDay(seasonNum: number) {
const pvpSeasonDuring = PVP.PVP_SEASON_DAYS.split('|').map(cur => {
let arr = cur.split('&');
let seasonNum = parseInt(arr[0]);
let day = parseInt(arr[1]);
if(isNaN(seasonNum) || isNaN(day)) return null;
return { seasonNum, day }
}).filter(cur => !!cur);
let maxDay = 0;
for(let {seasonNum: dicSeasonNum, day } of pvpSeasonDuring) {
if(seasonNum == dicSeasonNum) return day;
if(maxDay < day) maxDay = day;
export async function setPvpSeasonSchedule(fromBackend = false) {
let pvpConfig = await PVPConfigModel.setCurrentPvp();
await setSeasonEndJob(pvpConfig);
await setPvpSeasonMakeRewardJob(pvpConfig); // 发送奖励定时器
await setNextSeasonJob(pvpConfig); // 赛季开始定时器
if(fromBackend) {
setPvpSeasonNumToRemote(pvpConfig);
setPvpSettleSeasonNumToRemote();
} else {
setPvpSeasonNum(pvpConfig);
setPvpSettleSeasonNum();
}
return maxDay;
}
async function setPvpSeasonJob() {
await setPvpSeason(false);
}
async function setPvpSeason(isFirst: boolean, isForce?: boolean, minute?: number) {
console.log(`******** setPvpSeason1 isForce-${isForce}, minute-${minute}`)
let during = minute? minute * PER_MINUTE: null; // 下一次重置赛季天数
let oldPvpConfig = await PVPConfigModel.findCurPVPConfig();
let pvpConfig = oldPvpConfig;
console.log(`******** setPvpSeason2 during-${during}, seasonEndTime-${pvpConfig?.seasonEndTime}, now-${nowSeconds()}`)
if(!pvpConfig || pvpConfig.seasonEndTime - PER_MINUTE <= nowSeconds() || isForce) {
if(pvpConfig && !pvpConfig.hasSettleReward) {
await pvpSeasonEnd(pvpConfig.seasonNum);
}
let lastSeasonNum = pvpConfig? pvpConfig.seasonNum: 0;
let lastSeasonEndTime = pvpConfig? pvpConfig.seasonEndTime: 0;
console.log(`******** setPvpSeason3 lastSeasonNum-${lastSeasonNum}, lastSeasonEndTime-${lastSeasonEndTime}`)
let newSeasonStartTime = lastSeasonEndTime;
if(!during) during = getSeasonContinueDay(lastSeasonNum + 1) * PER_DAY;
let rewardTime = PVP.PVP_SEASON_REWARD_TIME_BEFORE * PER_MINUTE;
if(nowSeconds() - newSeasonStartTime > during) {
newSeasonStartTime = <number>getTimeFun().getDayZeroPoint(0);
}
console.log(`******** setPvpSeason4 newSeasonStartTime-${newSeasonStartTime}, during-${during}`)
if(isForce) { // debug使用如果seasonEndTime是未来的强行结束掉新赛季从现在开始
newSeasonStartTime = nowSeconds();
} else { // 不是用debug的情况如果因为debugnewSeasonStartTime不是每天0点结算那么改成lastSeasonEndTime之后的0点开始
let d = new Date(newSeasonStartTime * 1000);
if(d.getHours() != 0) {
d.setHours(0, 0, 0, 0);
newSeasonStartTime = getSeconds(d);
}
}
console.log(`******** setPvpSeason5 isForce-${isForce}, newSeasonStartTime-${newSeasonStartTime}`)
let newSeasonNum = await CounterModel.getNewCounter(COUNTER.PVP_SEASON_NUM);
pvpConfig = await PVPConfigModel.createPVPConfig(newSeasonNum, newSeasonStartTime, newSeasonStartTime + during - rewardTime, newSeasonStartTime + during);
async function setSeasonEndJob(pvpConfig: PVPConfigType) {
if (!!seasonEndJob) {
seasonEndJob.cancel();
}
await setPvpSeasonMakeRewardJob(pvpConfig);
await setNextSeasonJob(pvpConfig);
setPvpSeasonNum(pvpConfig, isFirst);
return pvpConfig;
}
function setPvpSeasonNum(pvpConfig: PVPConfigType, isFirst = false) {
if(pvpConfig) {
pinus.app.set('pvpSeasonNum', pvpConfig.seasonNum);
pinus.app.set('pvpSeasonEndTime', pvpConfig.seasonEndTime);
if(!isFirst) {
pinus.app.rpc.battle.battleRemote.setPvpSeasonNum.broadcast(pvpConfig);
pinus.app.rpc.role.roleRemote.setPvpSeasonNum.broadcast(pvpConfig);
pinus.app.rpc.connector.connectorRemote.setPvpSeasonNum.broadcast(pvpConfig);
}
if(!pvpConfig || pvpConfig.seasonEndTime < nowSeconds()) {
pvpConfig = await PVPConfigModel.findPVPConfig(pvpConfig? pvpConfig.seasonNum + 1: 1);
if(!pvpConfig) return;
}
console.log('####### setSeasonEndJob', JSON.stringify(pvpConfig))
seasonEndJob = scheduleJob('seasonEndJob', pvpConfig.seasonEndTime * 1000, async () => {
console.log('************ setSeasonEndJob *********');
setPvpSeasonNumToRemote(pvpConfig);
let nextPvpConfig = await PVPConfigModel.findPVPConfig(pvpConfig.seasonNum + 1);
await setSeasonEndJob(nextPvpConfig);
});
}
async function setPvpSeasonMakeRewardJob(pvpConfig: PVPConfigType) {
if (!!seasonMakeRewardTimJobId) {
seasonMakeRewardTimJobId.cancel();
}
if(!pvpConfig) return;
if(pvpConfig.seasonRewardTime < nowSeconds() && !pvpConfig.hasSettleReward) { // 未发奖励
await pvpSeasonEnd(pvpConfig.seasonNum);
} else {
seasonMakeRewardTimJobId = scheduleJob('seasonMakeRewardTimJobId', pvpConfig.seasonRewardTime * 1000, async () => {
console.log('************ seasonMakeRewardTimJobId *********');
await pvpSeasonEnd(pvpConfig.seasonNum);
});
if(!pvpConfig || pvpConfig.seasonRewardTime - 60 < nowSeconds()) {
pvpConfig = await PVPConfigModel.findPVPConfig(pvpConfig? pvpConfig.seasonNum + 1: 1);
if(!pvpConfig) return;
}
console.log('####### setPvpSeasonMakeRewardJob', JSON.stringify(pvpConfig))
seasonMakeRewardTimJobId = scheduleJob('seasonMakeRewardTimJobId', pvpConfig.seasonRewardTime * 1000 - 60 * 1000, async () => {
console.log('************ seasonMakeRewardTimJobId *********');
await pvpSeasonEnd(pvpConfig.seasonNum);
let nextPvpConfig = await PVPConfigModel.findPVPConfig(pvpConfig.seasonNum + 1);
await setPvpSeasonMakeRewardJob(nextPvpConfig);
});
}
async function setNextSeasonJob(pvpConfig: PVPConfigType) {
if (!!seasonRefreshTimeJobId) {
seasonRefreshTimeJobId.cancel();
}
//定时开启新赛季比seasonEndTime多定一分钟保证定时器时间没错
seasonRefreshTimeJobId = scheduleJob('seasonRefreshTimeJobId', (pvpConfig.seasonEndTime) * 1000, setPvpSeasonJob);
if(!pvpConfig || pvpConfig.seasonStartTime < nowSeconds()) {
pvpConfig = await PVPConfigModel.findPVPConfig(pvpConfig? pvpConfig.seasonNum + 1: 1);
if(!pvpConfig) return;
}
console.log('####### setNextSeasonJob', JSON.stringify(pvpConfig))
seasonRefreshTimeJobId = scheduleJob('seasonRefreshTimeJobId', pvpConfig.seasonStartTime * 1000, async () => {
console.log('************ setNextSeasonJob *********');
setPvpSeasonNumToRemote(pvpConfig);
await PVPConfigModel.setNextPvp(pvpConfig.seasonNum);
let nextPvpConfig = await PVPConfigModel.findPVPConfig(pvpConfig.seasonNum + 1);
await setNextSeasonJob(nextPvpConfig);
});
}
/**
* debug接口
* @param hour
*/
export async function resetPvpSeasonTime(minute: number) {
return await setPvpSeason(false, true, minute);
export async function setPvpSeasonNumToRemote(pvpConfig: PVPConfigType) {
await setPvpSeasonNum(pvpConfig);
await pinus.app.rpc.battle.battleRemote.setPvpSeasonNum.broadcast(pvpConfig);
await pinus.app.rpc.role.roleRemote.setPvpSeasonNum.broadcast(pvpConfig);
await pinus.app.rpc.connector.connectorRemote.setPvpSeasonNum.broadcast(pvpConfig);
}
export async function setPvpSeasonNum(pvpConfig?: PVPConfigType) {
if(!pvpConfig) {
pvpConfig = await PVPConfigModel.findCurPVPConfig();
if(!pvpConfig) return;
}
let now = nowSeconds();
pinus.app.set('pvpSeasonNum', pvpConfig.seasonNum);
pinus.app.set('pvpSeasonStartTime', pvpConfig.seasonStartTime);
pinus.app.set('pvpSeasonEndTime', pvpConfig.seasonEndTime);
pinus.app.set('pvpSeasonRewardTime', pvpConfig.seasonRewardTime);
if(pvpConfig.seasonEndTime <= now) { // 赛季结束,需要显示下一赛季的倒计时
let nextPvpConfig = await PVPConfigModel.findPVPConfig(pvpConfig.seasonNum + 1);
if(nextPvpConfig) {
pinus.app.set('pvpSeasonStartTime', nextPvpConfig.seasonStartTime);
}
}
}
export async function setPvpSettleSeasonNumToRemote(settledPvpConfig?: PVPConfigType) {
setPvpSettleSeasonNum(settledPvpConfig);
await pinus.app.rpc.battle.battleRemote.setPvpSettleSeasonNum.broadcast(settledPvpConfig);
await pinus.app.rpc.role.roleRemote.setPvpSettleSeasonNum.broadcast(settledPvpConfig);
await pinus.app.rpc.connector.connectorRemote.setPvpSettleSeasonNum.broadcast(settledPvpConfig);
}
export async function setPvpSettleSeasonNum(settledPvpConfig?: PVPConfigType) {
if(!settledPvpConfig) {
settledPvpConfig = await PVPConfigModel.getSettledConfig();
if(!settledPvpConfig) return;
}
pinus.app.set('pvpSettleSeasonNum', settledPvpConfig.seasonNum);
}
export async function reportOnlineSchedule() {

View File

@@ -399,7 +399,6 @@ function getData(pinusClient, seasonEnd: boolean, cb) {
expect(heroScore.hid).to.be.a('number');
expect(heroScore.score).to.be.a('number');
});
expect(res.data.isFirstEntry).to.be.a('boolean');
if (seasonEnd) {
checkSeasonResult(res.data.seasonResult);
}

View File

@@ -194,4 +194,11 @@ export default class GameController extends Controller {
ctx.body = await ctx.service.game.getServerName();
return
}
public async getPvpConfig() {
const { ctx } = this;
const { page, pageSize, sortField, sortOrder } = ctx.request.body;
ctx.body = await ctx.service.game.getPvpConfig(page, pageSize, sortField, sortOrder);
return
}
}

View File

@@ -70,6 +70,7 @@ export default (app: Application) => {
router.post('/api/game/getmarqueelist', tokenParser, controller.game.getMarqueeList);
router.post('/api/game/updatemarquee', tokenParser, controller.game.updateMarquee);
router.post('/api/game/getaccuse', tokenParser, controller.game.getAccuse);
router.post('/api/game/getpvpconfig', controller.game.getPvpConfig);
router.post('/api/activity/getactivitylist', tokenParser, controller.activity.getActivityList);
router.post('/api/activity/getallactivities', tokenParser, controller.activity.getAllActivities);

View File

@@ -21,6 +21,7 @@ import { UserOrderModel } from '@db/UserOrder';
import { SurveyModel } from '@db/Survery';
import { RedisClient } from 'redis';
import { ChannelInfoModel } from '@db/ChannelInfo';
import { PVPConfigModel } from '@db/PvpConfig';
/**
* Test Service
@@ -314,4 +315,13 @@ export default class Game extends Service {
}), total
});
}
public async getPvpConfig(page: number, pageSize: number, sortField: string, sortOrder: string) {
const { ctx } = this;
const list = await PVPConfigModel.findByCondition(page, pageSize, sortField, sortOrder);
const total = await PVPConfigModel.countByCondition()
return ctx.service.utils.resResult(STATUS.SUCCESS, {
list, total
});
}
}

View File

@@ -639,7 +639,8 @@ export enum SHOP_REFRESH_TYPE {
DAILY = 1, // 每天刷新
WEEKLY = 2, // 每周
MONTHLY = 3, // 每月
FOREVER = 4 // 不重置
FOREVER = 4, // 不重置
PVP = 5, // pvp赛季
}
// 任务的大类
@@ -1154,4 +1155,10 @@ export enum SYSTEM_OPEN_ID {
EXPEDITION = 36, // 远征
}
export const DEBUG_PRICE = 0.01;
export const DEBUG_PRICE = 0.01;
export enum PVP_SEASON_STATUS {
START = 1, // 已开始
SUMMIT = 2, // 结算中
WAITING = 3, // 待新赛季
}

View File

@@ -21,6 +21,7 @@ export const STATUS = {
ADDRESS_ERR: { code: 17, simStr: '您的版本已停止支持,请前往应用商店下载最新安装包' },
GLOBAL_ERR: { code: 1003, simStr: '服务器内部错误' },
UPDATE_INFO_ERR: {code: 1004, simStr: '热更新配置错误'},
DEBUG_FUNCTION_ERR: {code: 1005, simStr: '功能逻辑已改debug接口不再提供'},
// http请求
REQUEST_TIME_OUT: { code: 2000, simStr: '请求超时' },
@@ -177,6 +178,8 @@ export const STATUS = {
PVP_SET_ATTACK_CNT_NOT_ENOUGH: { code: 20806, simStr: '设置挑战阵容次数不足' },
PVP_NOT_SET_ATTACK: { code: 20807, simStr: '未设置挑战阵容' },
PVP_BUY_ATTACK_CNT_NOT_ENOUGH: { code: 20808, simStr: '购买挑战阵容次数不足' },
PVP_SEASON_NOT_OPEN: { code: 20809, simStr: 'pvp赛季未开启' },
PVP_CAN_NOT_SAVE_DEFENSE: { code: 20810, simStr: '结算期不可保存防守阵容' },
// 军团 20900-20999
GUILD_AUTH_NOT_ENOUGH: { code: 20900, simStr: '权限不足' },

115
shared/db/PvpConfig.ts Normal file
View File

@@ -0,0 +1,115 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
import { nowSeconds } from '../pubUtils/timeUtil';
import { CounterModel } from './Counter';
import { COUNTER } from '../consts';
@index({ isCurrent: 1 })
@index({ seasonNum: 1 })
export default class PVPConfig extends BaseModel {
@prop({ required: true, default: 1 })
seasonNum: number; // 赛季
@prop({ required: true })
seasonStartTime: number; // 赛季开始时间
@prop({ required: true })
seasonRewardTime: number; // 结算奖励时间
@prop({ required: true })
seasonEndTime: number; // 赛季结束的时间
@prop({ required: true })
hasSettleReward: boolean; // 是否发放奖励
@prop({ required: true, type: Number })
warIds: number[]; // 关卡id
@prop({ required: true })
isCurrent: boolean; // 是否是当前赛季
public static async findCurPVPConfig() {
let result: PVPConfigType = await PVPConfigModel.findOne({ isCurrent: true }).lean();
if(!result) {
result = await PVPConfigModel.findOneAndUpdate({ seasonStartTime: { $lte: nowSeconds() } }, { $set: { isCurrent: true }}, { new: true }).sort({ seasonStartTime: -1 }).lean();
}
return result;
}
public static async findPVPConfig(seasonNum: number) {
const result: PVPConfigType = await PVPConfigModel.findOne({ seasonNum }).lean(true);
return result;
}
public static async createPVPConfig(seasonNum: number|'new', params: PVPConfigUpdate, uid: number) {
if(seasonNum == 'new') {
seasonNum = await CounterModel.getNewCounter(COUNTER.PVP_SEASON_NUM);
}
const result: PVPConfigType = await PVPConfigModel.findOneAndUpdate({ seasonNum }, { $set: { ...params, updatedBy: uid }, $setOnInsert: { hasSettleReward: false, isCurrent: false, createdBy: uid } }, { upsert: true, new: true }).lean(true);
return result;
}
public static async getSettledConfig() {
const result: PVPConfigType = await PVPConfigModel.findOne({ hasSettleReward: true }).sort({ seasonNum: -1}).lean();
return result;
}
public static async checkTime(seasonNum: number|'new', seasonStartTime: number, seasonRewardTime: number) {
if(seasonNum == 'new') {
return await PVPConfigModel.exists({ seasonRewardTime: { $gt: seasonStartTime } })
} else {
return await PVPConfigModel.exists({
seasonNum: { $ne: seasonNum },
$or: [
{ seasonNum: { $lt: seasonNum }, seasonRewardTime: { $gt: seasonStartTime } },
{ seasonNum: { $gt: seasonNum }, seasonStartTime: { $lt: seasonRewardTime } }
]
})
}
}
public static async setReward(seasonNum: number) {
const result: PVPConfigType = await PVPConfigModel.findOneAndUpdate({ seasonNum }, { hasSettleReward: true }, { new: true }).lean(true);
return result;
}
public static async setCurrentPvp() {
await PVPConfigModel.updateMany({ isCurrent: true }, { $set: { isCurrent: false } });
const result: PVPConfigType = await PVPConfigModel.findOneAndUpdate({ seasonStartTime: { $lte: nowSeconds() } }, { $set: { isCurrent: true }}, {new: true}).sort({ seasonStartTime: -1 }).lean(true);
return result;
}
public static async setNextPvp(seasonNum: number) {
await PVPConfigModel.updateMany({ isCurrent: true }, { $set: { isCurrent: false } });
const result: PVPConfigType = await PVPConfigModel.findOneAndUpdate({ seasonNum }, { $set: { isCurrent: true }}, {new: true}).sort({ seasonStartTime: -1 }).lean(true);
return result;
}
public static async findByCondition(page: number, pageSize: number, sortField: string = 'seasonNum', sortOrder: string = 'descend') {
let sort = {};
if (sortField && sortOrder) {
if (sortOrder == 'ascend') {
sort[sortField] = 1;
} else if (sortOrder == 'descend') {
sort[sortField] = -1;
}
}
const result: PVPConfigType[] = await PVPConfigModel.find().limit(pageSize).skip((page - 1) * pageSize).sort(sort).lean({ getters: true, virtuals: true });
return result;
}
public static async countByCondition() {
const result = await PVPConfigModel.count({});
return result;
}
}
export const PVPConfigModel = getModelForClass(PVPConfig);
export interface PVPConfigType extends Pick<DocumentType<PVPConfig>, keyof PVPConfig> {
id: number;
};
export type PVPConfigUpdate = Partial<PVPConfigType>; // 将所有字段变成可选项

View File

@@ -7,6 +7,7 @@ import { COUNTER } from '../consts';
import { PVP } from '../pubUtils/dicParam';
@index({ roleId: 1 })
@index({ score: 1 })
export default class PvpDefense extends BaseModel {
@prop({ required: true })
serverId: number; // 区 id
@@ -17,6 +18,8 @@ export default class PvpDefense extends BaseModel {
@prop({ ref: 'Role', type: mongoose.Schema.Types.ObjectId })
role: Ref<Role>;
@prop({ required: true, default: null, _id: false })
hasDefense: boolean;
@prop({ required: true, default: null, _id: false })
defense: Defense;
@prop({ required: true, default: null, _id: false })
attack: Attack;
@@ -58,8 +61,6 @@ export default class PvpDefense extends BaseModel {
seasonNum: number;
@prop({ required: true, default: 0 })
seasonWinNum: number; // 本赛季胜利次数
@prop({ required: true, default: true })
isFirstEntry: boolean;
@prop({ required: true, default: 0 })
defenseScoreCnt: number;
@@ -129,7 +130,7 @@ export default class PvpDefense extends BaseModel {
}
public static async findByTeamLv(seasonNum: number, min: number, max: number) {
const result: PvpDefenseType[] = await PvpDefenseModel.find({ seasonNum, 'defense.pLv': { $gte: min, $lte: max } })
const result: PvpDefenseType[] = await PvpDefenseModel.find({ seasonNum, hasDefense: true, 'defense.pLv': { $gte: min, $lte: max } })
.populate('role', '_id head frame spine heads frames spines topLineupCe roleId roleName lv globalCeAttr title')
.populate('heroes.hero')
.populate('oppPlayers.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes warId buff')
@@ -137,6 +138,25 @@ export default class PvpDefense extends BaseModel {
return result;
}
public static async findNeighborByScore(seasonNum: number, score: number) {
const beforeData: PvpDefenseType[] = await PvpDefenseModel.find({
seasonNum, hasDefense: true, score: { $lt: score }
}).sort({ score: -1 }).limit(10)
.populate('role', '_id head frame spine heads frames spines topLineupCe roleId roleName lv globalCeAttr title')
.populate('heroes.hero')
.populate('oppPlayers.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes warId buff')
.lean({ getters: true, virtuals: true });
const afterData: PvpDefenseType[] = await PvpDefenseModel.find({
seasonNum, hasDefense: true, score: { $gt: score }
}).sort({ score: 1 }).limit(10)
.populate('role', '_id head frame spine heads frames spines topLineupCe roleId roleName lv globalCeAttr title')
.populate('heroes.hero')
.populate('oppPlayers.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes warId buff')
.lean({ getters: true, virtuals: true });
return [...beforeData, ...afterData];
}
public static async updateInfoAndInclude(roleId: string, update: pvpUpdateInter) {
delete update._id;
let result: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({roleId}, {$set:update}, {new: true})
@@ -162,14 +182,6 @@ export default class PvpDefense extends BaseModel {
return ranks;
}
public static async resetScores(roleId: string, newSeasonNum: number, newScore: number, newHeroScores: HeroScore[]) {
let result: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({roleId}, {$set: { seasonNum: newSeasonNum, score: newScore, heroScores: newHeroScores, challengeCnt: PVP.PVP_CHALLENGE_COUNTS, challengeRefTime: 0, winStreakNum: 0 }}, {new: true})
.populate('role', 'roleId roleName head frame spine heads frames spines title lv vLv')
.populate('oppPlayers.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes warId buff').lean({ getters: true, virtuals: true })
.lean();
return result;
}
public static async deleteHero(roleId: string, hid: number) {
let result:PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({roleId}, {$pull:{lineupCe: {hid}, heroScores: {hid}}, $set: {defense: null, attack: null}}, {new: true}).lean();
return result;

36
shared/db/PvpSaveData.ts Normal file
View File

@@ -0,0 +1,36 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
import { DefenseHeroInSaveData, } from '../domain/battleField/pvp';
@index({ roleId: 1 })
@index({ roleId: 1, warId: 1 })
export default class PvpSaveData extends BaseModel {
@prop({ required: true })
roleId: string; // 角色 id
@prop({ required: true })
warId: number; // 关卡id
@prop({ required: true })
buff: number; // 地图buff
@prop({ required: true, default: [], _id: false, type: DefenseHeroInSaveData })
heroes: DefenseHeroInSaveData[];
public static async createSaveData(roleId: string, warId: number, buff: number, heroes: DefenseHeroInSaveData[]) {
const result: PvpSaveDataType = await PvpSaveDataModel.findOneAndUpdate({ roleId, warId }, { $set: { buff, heroes } }, { new: true, upsert: true }).lean();
return result;
}
public static async findByRoleId(roleId: string) {
const result: PvpSaveDataType[] = await PvpSaveDataModel.find({ roleId }).lean();
return result;
}
}
export const PvpSaveDataModel = getModelForClass(PvpSaveData);
export interface PvpSaveDataType extends Pick<DocumentType<PvpSaveData>, keyof PvpSaveData> { };
export type pvpSaveDataUpdate = Partial<PvpSaveDataType>;

View File

@@ -59,6 +59,10 @@ export default class PvpSeasonResult extends BaseModel {
let result: PvpSeasonResultType = await PvpSeasonResultModel.findOne({ roleId, show: true }).lean();
return result;
}
public static async checkResultBySeasonNum(roleId: string, seasonNum: number) {
return await PvpSeasonResultModel.exists({ roleId, seasonNum });
}
}
export const PvpSeasonResultModel = getModelForClass(PvpSeasonResult);

View File

@@ -1,59 +0,0 @@
import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
import { CounterModel } from './Counter';
import { COUNTER } from '../consts';
@index({ id: 1 })
@index({ seasonNum: 1 })
export default class PVPConfig extends BaseModel {
@prop({ required: true, default: 1 })
seasonNum: number; // 赛季
@prop({ required: true })
seasonStartTime: number; // 赛季开始时间
@prop({ required: true })
seasonRewardTime: number; // 结算奖励时间
@prop({ required: true })
seasonEndTime: number; // 赛季结束的时间
@prop({ required: true })
hasSettleReward: boolean; // 赛季结束的时间
public static async findCurPVPConfig() {
let seasonNum = await CounterModel.getCounter(COUNTER.PVP_SEASON_NUM);
const result: PVPConfigType = await PVPConfigModel.findOne({ seasonNum }).lean(true);
return result;
}
public static async findPVPConfig(seasonNum: number) {
const result: PVPConfigType = await PVPConfigModel.findOne({ seasonNum }).lean(true);
return result;
}
public static async createPVPConfig(seasonNum: number, seasonStartTime: number, seasonRewardTime: number, seasonEndTime: number) {
const result: PVPConfigType = await PVPConfigModel.findOneAndUpdate({ seasonNum }, { seasonStartTime, seasonRewardTime, seasonEndTime, hasSettleReward: false }, { upsert: true, new: true }).lean(true);
return result;
}
public static async setReward(seasonNum: number) {
const result: PVPConfigType = await PVPConfigModel.findOneAndUpdate({ seasonNum }, { hasSettleReward: true }, { new: true }).lean(true);
return result;
}
public static async setCurPvpConfig(update: PVPConfigUpdate) {
let seasonNum = await CounterModel.getCounter(COUNTER.PVP_SEASON_NUM);
const result: PVPConfigType = await PVPConfigModel.findOneAndUpdate({ seasonNum }, update).lean(true);
return result;
}
}
export const PVPConfigModel = getModelForClass(PVPConfig);
export interface PVPConfigType extends Pick<DocumentType<PVPConfig>, keyof PVPConfig> {
id: number;
};
export type PVPConfigUpdate = Partial<PVPConfigType>; // 将所有字段变成可选项

View File

@@ -44,7 +44,10 @@ export default class UserShop extends BaseModel {
@prop({ required: true })
count: number; // 数量
private static getRefreshCondition() {
@prop({ required: true })
seasonNum: number; // 赛季id
private static getRefreshCondition(seasonNum: number) {
let today = getZeroPointD();
let cutWeek = getZeroPointD(SHOP_REFRESH_TYPE.WEEKLY);
let curMonth = getZeroPointD(SHOP_REFRESH_TYPE.MONTHLY);
@@ -54,38 +57,39 @@ export default class UserShop extends BaseModel {
{ createdAt: { $gte: cutWeek }, refreshType: SHOP_REFRESH_TYPE.WEEKLY },
{ createdAt: { $gte: curMonth }, refreshType: SHOP_REFRESH_TYPE.MONTHLY },
{ refreshType: SHOP_REFRESH_TYPE.FOREVER },
{ refreshType: SHOP_REFRESH_TYPE.PVP, seasonNum },
]
}
public static async findByShopType(roleId: string, shop: number, type: number) {
let timeCondition = this.getRefreshCondition();
public static async findByShopType(roleId: string, shop: number, type: number, seasonNum: number) {
let timeCondition = this.getRefreshCondition(seasonNum);
let rec: UserShopType[] = await UserShopModel.find({ shop, type, roleId, $or: timeCondition }).lean();
return rec;
}
public static async findByRoleId(roleId: string) {
let timeCondition = this.getRefreshCondition();
public static async findByRoleId(roleId: string, seasonNum: number) {
let timeCondition = this.getRefreshCondition(seasonNum);
let rec: UserShopType[] = await UserShopModel.find({ roleId, $or: timeCondition }).lean();
return rec;
}
public static async findByRoleAndItem(roleId: string, activityId: number, dicShopItem: { id: number, shop: number, type: number, createTime?: number }) {
let timeCondition = this.getRefreshCondition();
public static async findByRoleAndItem(roleId: string, activityId: number, dicShopItem: { id: number, shop: number, type: number, createTime?: number }, seasonNum: number) {
let timeCondition = this.getRefreshCondition(seasonNum);
let { id, shop, type, createTime = 0 } = dicShopItem;
let rec: UserShopType = await UserShopModel.findOne({ roleId, itemId: id, shop, type, activityId, createTime, $or: timeCondition }).lean();
return rec;
}
public static async purchase(roleId: string, roleName: string, activityId: number, dicShopItem: { id: number, goodId: number, refreshType: number, shop: number, type: number, createTime?: number }, inc: number) {
public static async purchase(roleId: string, roleName: string, activityId: number, dicShopItem: { id: number, goodId: number, refreshType: number, shop: number, type: number, createTime?: number }, inc: number, seasonNum: number) {
let code = genCode(8);
let timeCondition = this.getRefreshCondition();
let timeCondition = this.getRefreshCondition(seasonNum);
let { id, goodId, refreshType, shop, type, createTime = 0 } = dicShopItem;
let rec: UserShopType = await UserShopModel.findOneAndUpdate(
{ roleId, itemId: id, $or: timeCondition, activityId, shop, type, createTime },
{ $setOnInsert: { roleName, code, goodId, refreshType }, $inc: { count: inc } },
{ $setOnInsert: { roleName, code, goodId, refreshType, seasonNum }, $inc: { count: inc } },
{ new: true, upsert: true }
).lean();
return rec;

View File

@@ -6,7 +6,7 @@ import { RewardInter } from "../../pubUtils/interface";
import { parseNumberList } from "../../pubUtils/util";
import { stringWithTypeToRewardInter } from "../../pubUtils/roleUtil";
import { ActivityBase } from './activityField';
import { PVPConfigModel } from "../../db/SystemConfig";
import { PVPConfigModel } from "../../db/PvpConfig";
import { getZeroPointOfTimeD, nowSeconds } from "../../pubUtils/timeUtil";
// 数据库格式

View File

@@ -3,7 +3,7 @@ import { isArray, isNumber, isString } from 'underscore';
import ServerStategy, { GMMail } from "../../db/ServerStategy";
import { RegionType } from "../../db/Region";
import { RewardInter } from "../../pubUtils/interface";
import { isTimestamp } from '../../pubUtils/util';
import { isTimestamp, parseNumberList } from '../../pubUtils/util';
import { isBoolean, isDate } from "util";
export class UpdateMailParams {
@@ -438,4 +438,36 @@ export class UpdateChannelParam {
if(this.privacyPolicyLink && !isString(this.privacyPolicyLink)) return false;
return true;
}
}
export class CreatePvpConfigParam {
env: string = '';
seasonNum: number|'new' = 0;
seasonStartTime: number = 0;
seasonEndTime: number = 0;
seasonRewardTime: number = 0;
warIds: string = '';
constructor(obj?: any) {
if(obj) {
for(let key in obj) {
this[key] = obj[key];
}
}
}
checkParams() {
// console.log('##### createNew', this.env, this.openTime, this.stopRegisterTime, this.hasOpenMail, this.hasCircleMail)
if(this.seasonNum != 'new' && !isNumber(this.seasonNum)) return false;
if(!this.env || !isNumber(this.seasonStartTime) || !isNumber(this.seasonEndTime) || !isNumber(this.seasonRewardTime) || !isString(this.warIds)) {
return false
}
return true;
}
getUpdateParam() {
let { seasonStartTime, seasonEndTime, seasonRewardTime, warIds } = this;
return { seasonStartTime, seasonEndTime, seasonRewardTime, warIds: parseNumberList(warIds)}
}
}

View File

@@ -3,13 +3,13 @@ import { prop, Ref, mongoose } from '@typegoose/typegoose';
import Hero from '../../db/Hero';
import { PvpDefenseType } from '../../db/PvpDefense';
import PvpHistoryOpp from '../../db/PvpHistoryOpp';
import { PvpSaveDataType } from '../../db/PvpSaveData';
import { PvpSeasonResultType } from '../../db/PvpSeasonResult';
import { getPlvAndScore } from '../../pubUtils/data';
import { RewardInter } from '../../pubUtils/interface';
import { nowSeconds } from '../../pubUtils/timeUtil';
// 防守阵容武将
export class DefenseHero {
export class DefenseHeroInSaveData {
@prop({ required: true })
actorId: number; // 武将id
@prop({ required: true })
@@ -18,16 +18,26 @@ export class DefenseHero {
dataId: number;
@prop({ required: true })
order: number;
@prop({ ref: 'Hero', type: mongoose.Schema.Types.ObjectId })
hero: Ref<Hero>;
constructor(param: { actorId: number, ai: number, dataId: number, order: number }, heroId: string) {
constructor(param: { actorId: number, ai: number, dataId: number, order: number }) {
this.actorId = param.actorId;
this.ai = param.ai;
this.dataId = param.dataId;
this.order = param.order;
}
}
// 防守阵容武将
export class DefenseHero extends DefenseHeroInSaveData {
@prop({ ref: 'Hero', type: mongoose.Schema.Types.ObjectId })
hero: Ref<Hero>;
constructor(param: { actorId: number, ai: number, dataId: number, order: number }, heroId: string) {
super(param);
this.hero = heroId;
}
}
// 防守阵容
@@ -228,7 +238,9 @@ export class PvpSeasonResultRecord {
export class PvpDataReturn {
seasonNum: number;
seasonStartTime: number;
seasonEndTime: number;
seasonRewardTime: number;
myRank: number = 0;
oppPlayers: OppPlayerReturn[] = [];
defense: DefenseLineupReturn = null;
@@ -244,7 +256,7 @@ export class PvpDataReturn {
receivedBox: number[] = [];
hisScore: number = 0;
heroScores: HeroScoreReturn[] = [];
isFirstEntry: boolean = false;
hasSaveDefense: boolean = false;
resultRecord: PvpSeasonResultRecord;
setPvpDefense(pvpDefense: PvpDefenseType) {
@@ -284,10 +296,6 @@ export class PvpDataReturn {
return { attackCe, defenseCe };
}
setIsFirstEntry(isFirstEntry: boolean) {
this.isFirstEntry = isFirstEntry;
}
setOppPlayers(oppPlayers: OppPlayerReturn[]) {
this.oppPlayers = oppPlayers;
}
@@ -296,12 +304,53 @@ export class PvpDataReturn {
this.myRank = rankLv;
}
setPvpConfig(seasonNum: number, seasonEndTime: number) {
setPvpConfig(seasonNum: number, seasonStartTime: number, seasonEndTime: number, seasonRewardTime: number) {
this.seasonNum = seasonNum;
this.seasonStartTime = seasonStartTime;
this.seasonEndTime = seasonEndTime;
this.seasonRewardTime = seasonRewardTime;
}
setPvpSeasonResult(pvpSeasonResult: PvpSeasonResultType) {
this.resultRecord = new PvpSeasonResultRecord(pvpSeasonResult);
}
getHasSaveDefense() {
if(this.seasonRewardTime < nowSeconds() && this.seasonStartTime > nowSeconds()) {
return true;
}
return !!this.defense;
}
calHasSaveDefense() {
this.hasSaveDefense = this.getHasSaveDefense();
return this.hasSaveDefense;
}
setChallengeCnt(challengeCnt: number) {
return this.challengeCnt = challengeCnt;
}
}
export class pvpSaveDataReturn {
warId: number; // 地图id
isUsing: boolean = false; // 设置的是否是这张地图
hasSet: boolean = false; // 玩家是否设置过
buff: number; // 选择的地图buff没有设置过不返回
heroes: DefenseHeroInSaveData[]; // 玩家武将,没有设置不返回
constructor(warId: number) {
this.warId = warId;
}
setUserSaveData(pvpSaveData: PvpSaveDataType) {
if(!pvpSaveData) return;
this.hasSet = true;
this.buff = pvpSaveData.buff;
this.heroes = pvpSaveData.heroes;
}
setAsUsing() {
this.isUsing = true;
}
}

View File

@@ -894,5 +894,19 @@
"name": "开关接口",
"module": "sys",
"type": "update"
},
{
"id": 129,
"api": "/api/game/getpvpconfig",
"name": "获取pvp赛季",
"module": "sys",
"type": "find"
},
{
"id": 130,
"api": "gm.gmServerHandler.savePvpConfig",
"name": "保存pvp赛季",
"module": "sys",
"type": "update"
}
]

View File

@@ -10,7 +10,7 @@
"lvLimit": 0,
"ranklimit": 0,
"purchaseLimit": 5,
"refreshType": 1,
"refreshType": 5,
"money": 31002,
"price": "1&0|2&50|3&100|4&150|5&200",
"chosen": 2,