巅峰演武:赛季优化修改

This commit is contained in:
luying
2022-10-17 16:04:45 +08:00
parent ddff18eb20
commit 08ca06d7ac
30 changed files with 590 additions and 272 deletions
+4
View File
@@ -193,6 +193,10 @@ async function treatStartLogic(app: _pinus.Application) {
initGuildActivityIndexInPinus() initGuildActivityIndexInPinus()
.then(resetJoinWoodenHorse); .then(resetJoinWoodenHorse);
} }
if(app.getServerType() == 'battle'|| app.getServerType() == 'role'|| app.getServerType() == 'connector') {
timeTaskService.setPvpSeasonNum();
timeTaskService.setPvpSettleSeasonNum();
}
if(app.isMaster()) { if(app.isMaster()) {
redisService.initAllRank(); redisService.initAllRank();
@@ -2,7 +2,7 @@
import { Application, BackendSession, pinus, HandlerService, } from 'pinus'; import { Application, BackendSession, pinus, HandlerService, } from 'pinus';
import { findIndex } from 'underscore'; import { findIndex } from 'underscore';
import { gameData, getPvpBoxBySeasonNumAndIndex } from '../../../pubUtils/data'; 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 { RoleModel, RoleType } from '../../../db/Role';
import { STATUS } from '../../../consts/statusCode'; import { STATUS } from '../../../consts/statusCode';
import { resResult, genCode, checkRoleIsRobot, robotIdComBack } from '../../../pubUtils/util'; import { resResult, genCode, checkRoleIsRobot, robotIdComBack } from '../../../pubUtils/util';
@@ -10,7 +10,7 @@ import { PvpDefenseModel, pvpUpdateInter } from '../../../db/PvpDefense';
import { PvpSeasonResultModel } from '../../../db/PvpSeasonResult'; import { PvpSeasonResultModel } from '../../../db/PvpSeasonResult';
import { Rank } from '../../../services/rankService'; import { Rank } from '../../../services/rankService';
import { checkTask, checkTaskInPvpEnd } from '../../../services/task/taskService'; 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 { DEBUG_MAGIC_WORD, FIGURE_UNLOCK_CONDITION, ITEM_CHANGE_REASON, LINEUP_NUM, REDIS_KEY, TASK_TYPE } from '../../../consts';
import { PVP } from '../../../pubUtils/dicParam'; import { PVP } from '../../../pubUtils/dicParam';
import { addItems, getGoldObject, handleCost, unlockFigure } from '../../../services/role/rewardService'; import { addItems, getGoldObject, handleCost, unlockFigure } from '../../../services/role/rewardService';
@@ -22,6 +22,8 @@ import { PvpRecordModel } from '../../../db/PvpRecord';
import { pvpEndParamInter } from '../../../pubUtils/interface'; import { pvpEndParamInter } from '../../../pubUtils/interface';
import { getSeconds, nowSeconds } from '../../../pubUtils/timeUtil'; import { getSeconds, nowSeconds } from '../../../pubUtils/timeUtil';
import { PlayerDetail, PlayerDetailHero } from '../../../domain/battleField/guild'; import { PlayerDetail, PlayerDetailHero } from '../../../domain/battleField/guild';
import { PvpSaveDataModel } from '../../../db/PvpSaveData';
import { PVPConfigModel } from '../../../db/PvpConfig';
export default function (app: Application) { export default function (app: Application) {
new HandlerService(app, {}); new HandlerService(app, {});
@@ -44,7 +46,9 @@ export class PvpHandler {
// 如果没有发过,将上赛季的奖励发下 // 如果没有发过,将上赛季的奖励发下
pvpDefense = await sendLastSeasonRewardIfNotSent(pvpDefense); pvpDefense = await sendLastSeasonRewardIfNotSent(pvpDefense);
let seasonNum: number = this.app.get('pvpSeasonNum'); let seasonNum: number = this.app.get('pvpSeasonNum');
let seasonStartTime: number = this.app.get('pvpSeasonStartTime');
let seasonEndTime: number = this.app.get('pvpSeasonEndTime'); let seasonEndTime: number = this.app.get('pvpSeasonEndTime');
let seasonRewardTime: number = this.app.get('pvpSeasonRewardTime');
let update: pvpUpdateInter = { }; let update: pvpUpdateInter = { };
let result = new PvpDataReturn(); // 返回对象 let result = new PvpDataReturn(); // 返回对象
@@ -68,17 +72,16 @@ export class PvpHandler {
pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, update); pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, update);
} }
result.setPvpConfig(seasonNum, seasonEndTime); result.setPvpConfig(seasonNum, seasonStartTime, seasonEndTime, seasonRewardTime);
result.setPvpDefense(pvpDefense); result.setPvpDefense(pvpDefense);
result.calHasSaveDefense();
let oppPlayersReturn = await getEnemies(pvpDefense.oppPlayers||[], pvpDefense.winStreakNum); let oppPlayersReturn = await getEnemies(pvpDefense.oppPlayers||[], pvpDefense.winStreakNum);
result.setOppPlayers(oppPlayersReturn); result.setOppPlayers(oppPlayersReturn);
// 赛季结算 // 赛季结算
let pvpSeasonResult = await PvpSeasonResultModel.getPvpSeasonResult(roleId); let pvpSeasonResult = await PvpSeasonResultModel.getPvpSeasonResult(roleId);
if (!!pvpSeasonResult && !!pvpSeasonResult.show && pvpDefense.seasonNum == seasonNum) { if (!!pvpSeasonResult && !!pvpSeasonResult.show) {
result.setPvpSeasonResult(pvpSeasonResult); result.setPvpSeasonResult(pvpSeasonResult);
result.setIsFirstEntry(true);
update.isFirstEntry = false;
await PvpSeasonResultModel.setShow(roleId); await PvpSeasonResultModel.setShow(roleId);
} }
// 拍卖 // 拍卖
@@ -153,6 +156,9 @@ export class PvpHandler {
if (!warInfo) { if (!warInfo) {
return resResult(STATUS.BATTLE_MISS_INFO); return resResult(STATUS.BATTLE_MISS_INFO);
} }
if(!checkPvpSeasonIsStart()) {
return resResult(STATUS.PVP_SEASON_NOT_OPEN);
}
let pvpDefense = await PvpDefenseModel.findByRoleId(roleId); let pvpDefense = await PvpDefenseModel.findByRoleId(roleId);
if (!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN); 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'])); 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. 保存防守阵容 //3. 保存防守阵容
async saveDefense(msg: { heroes: { actorId: number, dataId: number, order: number, ai: number }[], warId: number, buff: number }, session: BackendSession) { async saveDefense(msg: { heroes: { actorId: number, dataId: number, order: number, ai: number }[], warId: number, buff: number }, session: BackendSession) {
let { heroes, warId, buff } = msg; let { heroes, warId, buff } = msg;
@@ -382,10 +412,14 @@ export class PvpHandler {
if (heroes.length > LINEUP_NUM || heroes.length <= 0) { if (heroes.length > LINEUP_NUM || heroes.length <= 0) {
return resResult(STATUS.WRONG_PARMS); return resResult(STATUS.WRONG_PARMS);
} }
if(checkPvpSeasonIsSummit()) {
return resResult(STATUS.PVP_CAN_NOT_SAVE_DEFENSE);
}
let pvpDefense = await PvpDefenseModel.findByRoleId(roleId); let pvpDefense = await PvpDefenseModel.findByRoleId(roleId);
if(!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN); if(!pvpDefense) return resResult(STATUS.PVP_NOT_OPEN);
// 刷新次数 // 刷新次数
let seasonNum: number = this.app.get('pvpSeasonNum');
let seasonEndTime: number = this.app.get('pvpSeasonEndTime'); let seasonEndTime: number = this.app.get('pvpSeasonEndTime');
let refChallengeObj = await refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime, roleId, session.get('vipStartTime')); 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 defense = new Defense(defenseHeroes, scores, warId, buff);
let lineupCe = await generPvpLineupCe(roleId, pvpDefense.lineupCe, pvpDefense.attack?.heroes??[], defense.heroes, dbHeroes); let lineupCe = await generPvpLineupCe(roleId, pvpDefense.lineupCe, pvpDefense.attack?.heroes??[], defense.heroes, dbHeroes);
await PvpSaveDataModel.createSaveData(roleId, warId, buff, defenseHeroes);
pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, { ...refChallengeObj, defense, lineupCe }); pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, { ...refChallengeObj, defense, lineupCe, hasDefense: true, seasonNum });
// 返回 // 返回
let result = new PvpDataReturn(); let result = new PvpDataReturn();
result.setPvpDefense(pvpDefense); result.setPvpDefense(pvpDefense);
@@ -584,10 +618,8 @@ export class PvpHandler {
return resResult(STATUS.SUCCESS, { score, hisScore, heroScores }); return resResult(STATUS.SUCCESS, { score, hisScore, heroScores });
} }
async debugPvpSeasonResetTime(msg: { day: number }, session: BackendSession) { async debugPvpSeasonResetTime(msg: {}, session: BackendSession) {
let { day: minute } = msg; return resResult(STATUS.DEBUG_FUNCTION_ERR);
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) { async debugAddChallengeCnt(msg: { challengeCnt: number }, session: BackendSession) {
@@ -1,10 +1,11 @@
import { Application, ChannelService, FrontendSession, RemoterClass, HandlerService, } from 'pinus'; import { Application, ChannelService, HandlerService, } from 'pinus';
import { PVPConfigModel, PVPConfigType } from '../../../db/SystemConfig'; import { PVPConfigModel, PVPConfigType } from '../../../db/PvpConfig';
import { reloadResources } from '../../../pubUtils/data'; import { reloadResources } from '../../../pubUtils/data';
import { setApiIsClose } from '../../../services/chatService'; import { setApiIsClose } from '../../../services/chatService';
import { getServerMainten, setServerMainten, stopServerMainten } from '../../../services/gmService'; import { getServerMainten, setServerMainten, stopServerMainten } from '../../../services/gmService';
import { savePvpSeasonMemory } from '../../../services/log/memoryLogService'; import { savePvpSeasonMemory } from '../../../services/log/memoryLogService';
import { taflush } from '../../../services/sdkService'; import { taflush } from '../../../services/sdkService';
import { setPvpSeasonNum, setPvpSettleSeasonNum } from '../../../services/timeTaskService';
import { errlogger } from '../../../util/logger'; import { errlogger } from '../../../util/logger';
export default function (app: Application) { export default function (app: Application) {
@@ -17,7 +18,6 @@ export class BattleRemote {
constructor(private app: Application) { constructor(private app: Application) {
this.app = app; this.app = app;
this.channelService = app.get('channelService'); this.channelService = app.get('channelService');
this.initPvpSeasonNum();
} }
private channelService: ChannelService; private channelService: ChannelService;
@@ -91,26 +91,23 @@ export class BattleRemote {
} }
public setPvpSeasonNum(pvpConfig: PVPConfigType) { public async setPvpSettleSeasonNum(pvpConfig: PVPConfigType) {
try { try {
if(pvpConfig) { await setPvpSettleSeasonNum(pvpConfig);
this.app.set('pvpSeasonNum', pvpConfig.seasonNum);
this.app.set('pvpSeasonEndTime', pvpConfig.seasonEndTime);
}
} catch(e) { } catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`); errlogger.error(`remote ${__filename} \n ${e.stack}`);
} }
} }
public async initPvpSeasonNum() { public async setPvpSeasonNum(pvpConfig: PVPConfigType) {
try { try {
let pvpConfig = await PVPConfigModel.findCurPVPConfig(); await setPvpSeasonNum(pvpConfig);
this.setPvpSeasonNum(pvpConfig);
} catch(e) { } catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`); errlogger.error(`remote ${__filename} \n ${e.stack}`);
} }
} }
public setServerMainten(serverIds: number[], startTime: number, endTime: number) { public setServerMainten(serverIds: number[], startTime: number, endTime: number) {
try { try {
setServerMainten(serverIds, startTime, endTime); setServerMainten(serverIds, startTime, endTime);
@@ -1,10 +1,8 @@
import { Application, ChannelService, FrontendSession, pinus, RemoterClass, HandlerService, } from 'pinus'; import { Application, HandlerService, } from 'pinus';
import { STATUS } from '../../../consts/statusCode';
import { resResult } from '../../../pubUtils/util';
import { reloadResources } from '../../../pubUtils/data'; import { reloadResources } from '../../../pubUtils/data';
import { UserGuildType } from '../../../db/UserGuild'; import { UserGuildType } from '../../../db/UserGuild';
import { incServerNum, kickUser } from '../../../services/connectorService'; 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 { setDicAuctionTime, setDicGuildActivity } from '../../../services/guildActivity/guildActivityService';
import { getServerMainten, setServerMainten, stopServerMainten } from '../../../services/gmService'; import { getServerMainten, setServerMainten, stopServerMainten } from '../../../services/gmService';
import { taflush } from '../../../services/sdkService'; import { taflush } from '../../../services/sdkService';
@@ -12,6 +10,7 @@ import { errlogger } from '../../../util/logger';
import { setWeek } from '../../../pubUtils/timeUtil'; import { setWeek } from '../../../pubUtils/timeUtil';
import { savePvpSeasonMemory } from '../../../services/log/memoryLogService'; import { savePvpSeasonMemory } from '../../../services/log/memoryLogService';
import { setApiIsClose } from '../../../services/chatService'; import { setApiIsClose } from '../../../services/chatService';
import { setPvpSeasonNum, setPvpSettleSeasonNum } from '../../../services/timeTaskService';
export default function (app: Application) { export default function (app: Application) {
new HandlerService(app, {}); new HandlerService(app, {});
return new ConnectorRemote(app); return new ConnectorRemote(app);
@@ -21,7 +20,6 @@ export class ConnectorRemote {
constructor(private app: Application) { constructor(private app: Application) {
this.app = app; this.app = app;
this.initPvpSeasonNum();
} }
public async remoteLogin(uid: string, message?: any) { public async remoteLogin(uid: string, message?: any) {
@@ -105,21 +103,17 @@ export class ConnectorRemote {
} }
} }
public setPvpSeasonNum(pvpConfig: PVPConfigType) { public async setPvpSeasonNum(pvpConfig: PVPConfigType) {
try { try {
if(pvpConfig) { await setPvpSeasonNum(pvpConfig);
this.app.set('pvpSeasonNum', pvpConfig.seasonNum);
this.app.set('pvpSeasonEndTime', pvpConfig.seasonEndTime);
}
} catch(e) { } catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`); errlogger.error(`remote ${__filename} \n ${e.stack}`);
} }
} }
public async initPvpSeasonNum() { public async setPvpSettleSeasonNum(pvpConfig: PVPConfigType) {
try { try {
let pvpConfig = await PVPConfigModel.findCurPVPConfig(); await setPvpSettleSeasonNum(pvpConfig);
this.setPvpSeasonNum(pvpConfig);
} catch(e) { } catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`); errlogger.error(`remote ${__filename} \n ${e.stack}`);
} }
@@ -2,7 +2,7 @@ import { Application, BackendSession, pinus } from 'pinus';
import { genCode, getRandSingleEelm, resResult } from '../../../pubUtils/util'; import { genCode, getRandSingleEelm, resResult } from '../../../pubUtils/util';
import { STATUS } from '../../../consts/statusCode'; import { STATUS } from '../../../consts/statusCode';
import moment = require('moment'); 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 { RegionModel, RegionType } from '../../../db/Region';
import { gameData } from '../../../pubUtils/data'; import { gameData } from '../../../pubUtils/data';
import { Maintenance, ServerlistModel, ServerlistUpdate } from '../../../db/Serverlist'; import { Maintenance, ServerlistModel, ServerlistUpdate } from '../../../db/Serverlist';
@@ -11,6 +11,7 @@ import { createNewServer, sendOpenServerMail } from '../../../services/gmService
import { isNumber } from 'util'; import { isNumber } from 'util';
import { MarqueeModel } from '../../../db/Marquee'; import { MarqueeModel } from '../../../db/Marquee';
import { setApiIsCloseToRemote } from '../../../services/chatService'; import { setApiIsCloseToRemote } from '../../../services/chatService';
import { PVPConfigModel } from '../../../db/PvpConfig';
export default function (app: Application) { export default function (app: Application) {
return new GmHandler(app); return new GmHandler(app);
@@ -180,4 +181,21 @@ export class GmHandler {
setApiIsCloseToRemote(region.isCloseApi); setApiIsCloseToRemote(region.isCloseApi);
return resResult(STATUS.SUCCESS); 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);
}
} }
@@ -1,4 +1,4 @@
import { Application, BackendSession } from "pinus"; import { Application, BackendSession, pinus } from "pinus";
import { gameData, hasShopType } from "../../../pubUtils/data"; import { gameData, hasShopType } from "../../../pubUtils/data";
import { parseGoodStr, resResult } from "../../../pubUtils/util"; import { parseGoodStr, resResult } from "../../../pubUtils/util";
import { STATUS, GUILD_STRUCTURE, ITID, CONSUME_TYPE, HERO_QUALITY_TYPE, HERO_GROW_MAX, ITEM_CHANGE_REASON } from "../../../consts"; 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 roleName = session.get('roleName');
let sid = session.get('sid'); let sid = session.get('sid');
let serverId = session.get('serverId'); let serverId = session.get('serverId');
let seasonNum = pinus.app.get('pvpSeasonNum');
let { activityId = 0, shopItemId, count } = msg; let { activityId = 0, shopItemId, count } = msg;
@@ -58,7 +59,7 @@ export class ShopHandler {
if(!dicShopItem) return resResult(STATUS.DIC_DATA_NOT_FOUND); if(!dicShopItem) return resResult(STATUS.DIC_DATA_NOT_FOUND);
if(dicShopItem['productID'] && dicShopItem['productID'] != '&') return resResult(STATUS.CAN_NOT_PURCHASE); 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); let checkResult = await checkShopInPurchase(session, activityId, count, userShop?.count||0, dicShopItem);
if(checkResult.code != STATUS.SUCCESS.code) { if(checkResult.code != STATUS.SUCCESS.code) {
@@ -71,7 +72,7 @@ export class ShopHandler {
if(!costResult) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH); 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); if(!userShop) return resResult(STATUS.BUY_COUNT_OVER);
// 获得 // 获得
@@ -1,16 +1,13 @@
import { Application, ChannelService, HandlerService, } from 'pinus'; import { Application, ChannelService, HandlerService, } from 'pinus';
// import { sendRolesMails } from '../../../services/mailService'; // import { sendRolesMails } from '../../../services/mailService';
import { reloadResources } from '../../../pubUtils/data'; 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 { RankFirstModel, RankFirstType } from '../../../db/RankFirst';
import { Figure } from '../../../domain/dbGeneral'; import { PVPConfigModel, PVPConfigType } from '../../../db/PvpConfig';
import { PVPConfigModel, PVPConfigType } from '../../../db/SystemConfig';
import { treatRoleName, taflush, sendSurveyMail } from '../../../services/sdkService'; import { treatRoleName, taflush, sendSurveyMail } from '../../../services/sdkService';
import { getServerMainten, setServerMainten, stopServerMainten } from '../../../services/gmService'; import { getServerMainten, setServerMainten, stopServerMainten } from '../../../services/gmService';
import { errlogger } from '../../../util/logger'; import { errlogger } from '../../../util/logger';
import { setApiIsClose } from '../../../services/chatService'; import { setApiIsClose } from '../../../services/chatService';
import { setPvpSeasonNum, setPvpSettleSeasonNum } from '../../../services/timeTaskService';
export default function (app: Application) { export default function (app: Application) {
new HandlerService(app, {}); new HandlerService(app, {});
@@ -23,7 +20,6 @@ export class RoleRemote {
this.app = app; this.app = app;
// this.channelService = app.get('channelService'); // this.channelService = app.get('channelService');
this.loadRankFirst(); this.loadRankFirst();
this.initPvpSeasonNum();
} }
// private channelService: ChannelService; // private channelService: ChannelService;
@@ -74,21 +70,17 @@ export class RoleRemote {
} }
public setPvpSeasonNum(pvpConfig: PVPConfigType) { public async setPvpSeasonNum(pvpConfig: PVPConfigType) {
try { try {
if(pvpConfig) { await setPvpSeasonNum(pvpConfig);
this.app.set('pvpSeasonNum', pvpConfig.seasonNum);
this.app.set('pvpSeasonEndTime', pvpConfig.seasonEndTime);
}
} catch(e) { } catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`); errlogger.error(`remote ${__filename} \n ${e.stack}`);
} }
} }
public async initPvpSeasonNum() { public async setPvpSettleSeasonNum(pvpConfig: PVPConfigType) {
try { try {
let pvpConfig = await PVPConfigModel.findCurPVPConfig(); await setPvpSettleSeasonNum(pvpConfig);
this.setPvpSeasonNum(pvpConfig);
} catch(e) { } catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`); errlogger.error(`remote ${__filename} \n ${e.stack}`);
} }
@@ -1,5 +1,5 @@
import { Application, ChannelService } from 'pinus'; 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 PvpDefenseType from '../../../db/PvpDefense';
import { DicGuildActivity } from '../../../pubUtils/dictionary/DicGuildActivity'; import { DicGuildActivity } from '../../../pubUtils/dictionary/DicGuildActivity';
import { reloadResources } from '../../../pubUtils/data'; import { reloadResources } from '../../../pubUtils/data';
@@ -30,14 +30,6 @@ export class SystimerRemote {
} }
private channelService: ChannelService; 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) { public async guildActivityStart(dicGuildActivity: DicGuildActivity) {
try { try {
return await guildActivityStart(dicGuildActivity); return await guildActivityStart(dicGuildActivity);
@@ -232,4 +224,12 @@ export class SystimerRemote {
errlogger.error(`remote ${__filename} \n ${e.stack}`); errlogger.error(`remote ${__filename} \n ${e.stack}`);
} }
} }
public async setPvpSeasonSchedule(fromBackend: boolean) {
try {
setPvpSeasonSchedule(fromBackend);
} catch(e) {
errlogger.error(`remote ${__filename} \n ${e.stack}`);
}
}
} }
+10 -3
View File
@@ -48,6 +48,7 @@ import { ComBattleTeamModel } from '../db/ComBattleTeam';
import { INFO_WINDOW } from '../pubUtils/dicParam'; import { INFO_WINDOW } from '../pubUtils/dicParam';
import { getLadderData } from './ladderService'; import { getLadderData } from './ladderService';
import { dispatch } from '../pubUtils/dispatcher'; import { dispatch } from '../pubUtils/dispatcher';
import { PvpDataReturn } from '../domain/battleField/pvp';
/** /**
* init: 初始的时候是否推送 true-推 false-不推 * init: 初始的时候是否推送 true-推 false-不推
@@ -260,11 +261,17 @@ async function getPvpEntryData(roleId: string) {
pvpDefense = await sendLastSeasonRewardIfNotSent(pvpDefense); pvpDefense = await sendLastSeasonRewardIfNotSent(pvpDefense);
let seasonNum: number = pinus.app.get('pvpSeasonNum'); let seasonNum: number = pinus.app.get('pvpSeasonNum');
let seasonEndTime: number = pinus.app.get('pvpSeasonEndTime'); 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 refChallengeObj = await refChallengeCnt(pvpDefense.challengeCnt, pvpDefense.challengeRefTime, seasonEndTime, roleId);
let { challengeCnt } = refChallengeObj; let { challengeCnt } = refChallengeObj;
let { receivedBox, score, seasonWinNum } = pvpDefense; result.setChallengeCnt(challengeCnt);
return pick(result, ['challengeCnt', 'score', 'seasonWinNum', 'receivedBox', 'hasSaveDefense', 'seasonNum', 'seasonEndTime', 'seasonStartTime', 'seasonRewardTime'])
return { challengeCnt, score, seasonWinNum, receivedBox, seasonNum, seasonEndTime }
} else { } else {
return null return null
} }
-1
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 { RoleModel, RoleType } from "../db/Role";
import { UserGuildModel, UserGuildType, WishGood } from "../db/UserGuild"; import { UserGuildModel, UserGuildType, WishGood } from "../db/UserGuild";
import { UserGuildApplyModel } from "../db/UserGuildApply"; import { UserGuildApplyModel } from "../db/UserGuildApply";
import { PVPConfigModel } from "../db/SystemConfig";
import { getZeroPointD, getZeroPointOfTime, getZeroPointOfTimeD, nowSeconds } from "../pubUtils/timeUtil"; import { getZeroPointD, getZeroPointOfTime, getZeroPointOfTimeD, nowSeconds } from "../pubUtils/timeUtil";
import { pinus, BackendSession, FrontendOrBackendSession } from "pinus"; import { pinus, BackendSession, FrontendOrBackendSession } from "pinus";
import { ARMY } from "../pubUtils/dicParam"; import { ARMY } from "../pubUtils/dicParam";
+48 -17
View File
@@ -2,23 +2,21 @@
import { PvpDefenseModel, PvpDefenseType, pvpUpdateInter } from '../db/PvpDefense'; import { PvpDefenseModel, PvpDefenseType, pvpUpdateInter } from '../db/PvpDefense';
import { Defense, Attack, LineupCe, OppPlayer, HeroScore, HeroReward, OppPlayerReturn, AttackHero, DefenseHero } from '../domain/battleField/pvp'; import { Defense, Attack, LineupCe, OppPlayer, HeroScore, HeroReward, OppPlayerReturn, AttackHero, DefenseHero } from '../domain/battleField/pvp';
import { RoleType } from '../db/Role'; 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 { dicPvpOpponent, DicPvpOpponent } from "../pubUtils/dictionary/DicPvpOpponent";
import { getRandSingleIndex, genCode, shouldRefresh, getChineseName, makeRobotId, robotIdComBack, getRandSingleEelm } from '../pubUtils/util'; import { getRandSingleIndex, genCode, shouldRefresh, getChineseName, makeRobotId, robotIdComBack, getRandSingleEelm } from '../pubUtils/util';
import { pvpEndParamInter, RewardInter } from '../pubUtils/interface'; import { pvpEndParamInter, RewardInter } from '../pubUtils/interface';
import { gameData, getPLvByScore, getPvpHeroRewardsByScore, getPvpRankRewardsByRank, getPvpDifficultByScore, getPlvAndScore, getPvpBoxsBySeasonNum, getPvpRankMaxRewardsBySeasonNum, randomGoodsByItid } from "../pubUtils/data"; import { gameData, getPLvByScore, getPvpHeroRewardsByScore, getPvpRankRewardsByRank, getPvpDifficultByScore, getPlvAndScore, getPvpBoxsBySeasonNum, getPvpRankMaxRewardsBySeasonNum, randomGoodsByItid } from "../pubUtils/data";
import { EXTERIOR, PVP } from '../pubUtils/dicParam'; import { EXTERIOR, PVP } from '../pubUtils/dicParam';
import { PVPConfigModel, PVPConfigType } from '../db/SystemConfig' import { PVPConfigModel } from '../db/PvpConfig'
import { nowSeconds, getTimeFun } from '../pubUtils/timeUtil'; import { nowSeconds, getTimeFun } from '../pubUtils/timeUtil';
import { HeroesRecord, PvpRecordPlayerInfo } from '../db/PvpRecord'; import { HeroesRecord, PvpRecordPlayerInfo } from '../db/PvpRecord';
import { HeroModel, HeroType } from '../db/Hero'; import { HeroModel, HeroType } from '../db/Hero';
import { AttributeCal } from '../domain/roleField/attribute'; import { AttributeCal } from '../domain/roleField/attribute';
import { PvpEnemies, PvpHeroInfo, PvpOtherHeroes } from '../domain/dbGeneral'; import { PvpEnemies, PvpHeroInfo, PvpOtherHeroes } from '../domain/dbGeneral';
import { DicWarJson } from '../pubUtils/dictionary/DicWarJson';
import { pinus } from 'pinus'; import { pinus } from 'pinus';
import { PvpHistoryOppModel, PvpHistoryOppType, PvpOppCreateParam } from '../db/PvpHistoryOpp'; import { PvpHistoryOppModel, PvpHistoryOppType, PvpOppCreateParam } from '../db/PvpHistoryOpp';
import { Rank } from './rankService'; import { Rank } from './rankService';
import { CounterModel } from '../db/Counter';
import { DicRankRewads } from '../pubUtils/dictionary/DicPvpRankReward'; import { DicRankRewads } from '../pubUtils/dictionary/DicPvpRankReward';
import { PvpSeasonResultModel, PvpSeasonResultType } from '../db/PvpSeasonResult'; import { PvpSeasonResultModel, PvpSeasonResultType } from '../db/PvpSeasonResult';
import { checkTask } from './task/taskService'; import { checkTask } from './task/taskService';
@@ -27,6 +25,7 @@ import { RoleRankInfo } from '../domain/rank';
import { reportTAEvent } from './sdkService'; import { reportTAEvent } from './sdkService';
import { getVipPvpChallengeMaxCnt } from './activity/monthlyTicketService'; import { getVipPvpChallengeMaxCnt } from './activity/monthlyTicketService';
import { getHeroesAttributes } from './playerCeService'; import { getHeroesAttributes } from './playerCeService';
import { setPvpSeasonNumToRemote, setPvpSettleSeasonNumToRemote } from './timeTaskService';
/** /**
* 返回对手三人信息 * 返回对手三人信息
@@ -166,7 +165,7 @@ export async function matchPlayerByRank(seasonNum: number, chosenOpps: string[],
oppRoleId = result[0]; oppRoleId = result[0];
let pvpdefense = await PvpDefenseModel.findByRoleIdIncludeAll(oppRoleId); 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); let pvpHistoryOpp = await generPlayerOppHis(pvpdefense, roleId, pos);
if (!pvpHistoryOpp) return null; if (!pvpHistoryOpp) return null;
@@ -367,15 +366,21 @@ export async function comsumeChallengeCnt(challengeCnt: number, challengeRefTime
} }
export async function sendLastSeasonRewardIfNotSent(pvpDefense: PvpDefenseType) { export async function sendLastSeasonRewardIfNotSent(pvpDefense: PvpDefenseType) {
let seasonNum: number = pinus.app.get('pvpSeasonNum'); let seasonSettleNum: number = pinus.app.get('pvpSettleSeasonNum');
if(pvpDefense.seasonNum < seasonNum) { console.log('##### sendLastSeasonRewardIfNotSent seasonSettleNum', seasonSettleNum)
let oldPvpCongig = await PVPConfigModel.findPVPConfig(pvpDefense.seasonNum); if(seasonSettleNum && !await checkHasSettled(seasonSettleNum, pvpDefense.roleId)) {
let result = await sendPVPRewardToUser(pvpDefense, pvpDefense.seasonNum, oldPvpCongig.seasonEndTime); let oldPvpCongig = await PVPConfigModel.findPVPConfig(seasonSettleNum);
let result = await sendPVPRewardToUser(pvpDefense, seasonSettleNum, oldPvpCongig.seasonEndTime);
pvpDefense = result.pvpDefense; pvpDefense = result.pvpDefense;
} }
return pvpDefense; return pvpDefense;
} }
async function checkHasSettled(seasonSettleNum: number, roleId: string) {
let hasData = await PvpSeasonResultModel.checkResultBySeasonNum(roleId, seasonSettleNum);
return hasData;
}
// 获取刷新对手次数及消耗 // 获取刷新对手次数及消耗
export function refreshRefOppCnt(pvpDefense: PvpDefenseType) { export function refreshRefOppCnt(pvpDefense: PvpDefenseType) {
let { refOppCnt = 0, setAttackCnt = 0, buyAttackCnt = 0, refDaily } = pvpDefense; 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); let { pvpSeasonResult } = await sendPVPRewardToUser(pvpDefense, pvpConfig.seasonNum, pvpConfig.seasonEndTime);
reportTAEvent(roleId, TA_EVENT.PVP_SEASON_END, { top_rank: rank, hero_score: pvpSeasonResult.heroScores }) 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 { return {
pvpSeasonResult, 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) { async function resetPvpScores(pvpDefense: PvpDefenseType, pvpSeasonResult: PvpSeasonResultType) {
let { roleId, attack, defense } = pvpDefense; let { roleId, attack } = pvpDefense;
let { newHeroScores, newScore } = pvpSeasonResult; let { newHeroScores, newScore } = pvpSeasonResult;
let initCount = await getVipPvpChallengeMaxCnt(roleId) let initCount = await getVipPvpChallengeMaxCnt(roleId)
let newAttack = <Attack>calLineupScore(attack, newHeroScores); let newAttack = <Attack>calLineupScore(attack, newHeroScores);
let newDefense = <Defense>calLineupScore(defense, newHeroScores);
pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, { pvpDefense = await PvpDefenseModel.updateInfoAndInclude(roleId, {
heroScores: newHeroScores, score: newScore, attack: newAttack, defense: newDefense, heroScores: newHeroScores, score: newScore, attack: newAttack, defense: null, hasDefense: false,
seasonNum, challengeCnt: initCount, challengeRefTime: 0, winStreakNum: 0, isFirstEntry: true, challengeCnt: initCount, challengeRefTime: 0, winStreakNum: 0,
seasonWinNum: 0, receivedBox: [] seasonWinNum: 0, receivedBox: []
}); });
return pvpDefense; return pvpDefense;
@@ -664,8 +669,9 @@ export async function savePvpSeasonResult(pvpDefense: PvpDefenseType, seasonNum:
} }
//pvp锁定的信息存入赛季结算表中 //pvp锁定的信息存入赛季结算表中
let {receivedBox, score, seasonWinNum, heroScores } = pvpDefense;
let pvpSeasonResult = await PvpSeasonResultModel.updatePvpSeasonResult(pvpDefense.roleId, seasonNum, { 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信息 });//结算修改玩家pvp信息
if(newScore > 0) { if(newScore > 0) {
let r = new Rank(REDIS_KEY.PVP_RANK, { seasonNum: seasonNum + 1 }); let r = new Rank(REDIS_KEY.PVP_RANK, { seasonNum: seasonNum + 1 });
@@ -703,3 +709,28 @@ export async function generPvpLineupCe(roleId: string, lineupCe: LineupCe[], att
} }
return newLineupCe; 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;
}
+9 -5
View File
@@ -9,13 +9,14 @@ import { UserShopTypeModel, UserShopTypeType } from "../db/UserShopType";
import { GuildModel } from "../db/Guild"; import { GuildModel } from "../db/Guild";
import { RoleModel } from "../db/Role"; import { RoleModel } from "../db/Role";
import { DicShop } from "../pubUtils/dictionary/DicShop"; import { DicShop } from "../pubUtils/dictionary/DicShop";
import { BackendSession } from "pinus"; import { BackendSession, pinus } from "pinus";
import { ActivityModelType } from "../db/Activity"; import { ActivityModelType } from "../db/Activity";
import { addItems } from "./role/rewardService"; import { addItems } from "./role/rewardService";
import { LadderMatchModel } from "../db/LadderMatch"; import { LadderMatchModel } from "../db/LadderMatch";
export async function getAllShopList(roleId: string, serverId: number) { 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 userShopTypeRecs = await UserShopTypeModel.findByRoleId(roleId);
let activities = await getShopActivityDatas(roleId, serverId); 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) { 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 activities = await getShopActivityDatas(roleId, serverId);
let activity = activities.find(cur => cur.shop == shop && cur.type == type); let activity = activities.find(cur => cur.shop == shop && cur.type == type);
let readRecord = await UserShopTypeModel.findByType(roleId, shop, 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) { 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 role = await RoleModel.findByRoleId(roleId, 'guildCode createTime vipStartTime');
let { createTime, guildCode, vipStartTime } = role; let { createTime, guildCode, vipStartTime } = role;
let serverTime = await getServerCreateTime(serverId); let serverTime = await getServerCreateTime(serverId);
@@ -136,7 +139,7 @@ export async function checkShopCanBuyInOrder(roleId: string, serverId: number, a
let dicItem = shopData.findByProductID(productID); let dicItem = shopData.findByProductID(productID);
if(!dicItem) return false; 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); let result = await checkShopItemCanBuy(activity.activityId, dicItem.id, roleId, serverId, guildCode, vipStartTime, 1, userShop?.count||0, dicItem);
return result.code == STATUS.SUCCESS.code; 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) { 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); let activityData: ActivityModelType = await getActivityById(activityId);
if (!activityData) { if (!activityData) {
return STATUS.ACTIVITY_MISSING; 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 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 { return {
code: 0, code: 0,
data: Object.assign({}, { item: { shop: dicItem.shop, type: dicItem.type, shopItemId: dicItem.id }, activityId: activityId }) data: Object.assign({}, { item: { shop: dicItem.shop, type: dicItem.type, shopItemId: dicItem.id }, activityId: activityId })
+90 -85
View File
@@ -1,6 +1,6 @@
import { scheduleJob, Job, scheduledJobs, } from 'node-schedule'; 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 { nowSeconds, getTimeFun, getSeconds } from '../pubUtils/timeUtil';
import { getTodayGuildActivity, gameData } from '../pubUtils/data'; import { getTodayGuildActivity, gameData } from '../pubUtils/data';
import { pvpSeasonEnd } from './pvpService'; import { pvpSeasonEnd } from './pvpService';
@@ -46,6 +46,7 @@ const PER_SECOND = 1 * 1000;
const PER_DAY = 24 * 60 * 60; const PER_DAY = 24 * 60 * 60;
const PER_HOUR = 1 * 60 * 60; const PER_HOUR = 1 * 60 * 60;
const PER_MINUTE = 1 * 60; const PER_MINUTE = 1 * 60;
var seasonEndJob: Job;
var seasonMakeRewardTimJobId: Job; var seasonMakeRewardTimJobId: Job;
var seasonRefreshTimeJobId: Job; var seasonRefreshTimeJobId: Job;
let guildWeeklyJobId: Job; let guildWeeklyJobId: Job;
@@ -61,7 +62,7 @@ export async function init() {
console.log('******* init systimer *******') console.log('******* init systimer *******')
// pvp赛季 // pvp赛季
await setPvpSeason(true); await setPvpSeasonSchedule();
// 周功勋结算任务 // 周功勋结算任务
guildWeeklyJobId = scheduleJob('settleGuildWeekly', '0 0 0 * * 1', settleGuildWeekly); guildWeeklyJobId = scheduleJob('settleGuildWeekly', '0 0 0 * * 1', settleGuildWeekly);
@@ -115,111 +116,115 @@ export async function everydayRefresh() {
// —————————————— PVP 及赛季相关 —————————————— // // —————————————— 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; export async function setPvpSeasonSchedule(fromBackend = false) {
for(let {seasonNum: dicSeasonNum, day } of pvpSeasonDuring) { let pvpConfig = await PVPConfigModel.setCurrentPvp();
if(seasonNum == dicSeasonNum) return day; await setSeasonEndJob(pvpConfig);
if(maxDay < day) maxDay = day; await setPvpSeasonMakeRewardJob(pvpConfig); // 发送奖励定时器
await setNextSeasonJob(pvpConfig); // 赛季开始定时器
if(fromBackend) {
setPvpSeasonNumToRemote(pvpConfig);
setPvpSettleSeasonNumToRemote();
} else {
setPvpSeasonNum(pvpConfig);
setPvpSettleSeasonNum();
} }
return maxDay;
} }
async function setPvpSeasonJob() { async function setSeasonEndJob(pvpConfig: PVPConfigType) {
await setPvpSeason(false); if (!!seasonEndJob) {
} seasonEndJob.cancel();
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的情况,如果(因为debug)newSeasonStartTime不是每天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);
} }
await setPvpSeasonMakeRewardJob(pvpConfig);
await setNextSeasonJob(pvpConfig);
setPvpSeasonNum(pvpConfig, isFirst);
return pvpConfig;
}
function setPvpSeasonNum(pvpConfig: PVPConfigType, isFirst = false) { if(!pvpConfig || pvpConfig.seasonEndTime < nowSeconds()) {
if(pvpConfig) { pvpConfig = await PVPConfigModel.findPVPConfig(pvpConfig? pvpConfig.seasonNum + 1: 1);
pinus.app.set('pvpSeasonNum', pvpConfig.seasonNum); if(!pvpConfig) return;
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);
}
} }
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) { async function setPvpSeasonMakeRewardJob(pvpConfig: PVPConfigType) {
if (!!seasonMakeRewardTimJobId) { if (!!seasonMakeRewardTimJobId) {
seasonMakeRewardTimJobId.cancel(); seasonMakeRewardTimJobId.cancel();
} }
if(!pvpConfig) return; if(!pvpConfig || pvpConfig.seasonRewardTime - 60 < nowSeconds()) {
if(pvpConfig.seasonRewardTime < nowSeconds() && !pvpConfig.hasSettleReward) { // 未发奖励 pvpConfig = await PVPConfigModel.findPVPConfig(pvpConfig? pvpConfig.seasonNum + 1: 1);
await pvpSeasonEnd(pvpConfig.seasonNum); if(!pvpConfig) return;
} else {
seasonMakeRewardTimJobId = scheduleJob('seasonMakeRewardTimJobId', pvpConfig.seasonRewardTime * 1000, async () => {
console.log('************ seasonMakeRewardTimJobId *********');
await pvpSeasonEnd(pvpConfig.seasonNum);
});
} }
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) { async function setNextSeasonJob(pvpConfig: PVPConfigType) {
if (!!seasonRefreshTimeJobId) { if (!!seasonRefreshTimeJobId) {
seasonRefreshTimeJobId.cancel(); seasonRefreshTimeJobId.cancel();
} }
//定时开启新赛季,比seasonEndTime多定一分钟,保证定时器时间没错 if(!pvpConfig || pvpConfig.seasonStartTime < nowSeconds()) {
seasonRefreshTimeJobId = scheduleJob('seasonRefreshTimeJobId', (pvpConfig.seasonEndTime) * 1000, setPvpSeasonJob); 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);
});
} }
/** export async function setPvpSeasonNumToRemote(pvpConfig: PVPConfigType) {
* debug接口 await setPvpSeasonNum(pvpConfig);
* @param hour await pinus.app.rpc.battle.battleRemote.setPvpSeasonNum.broadcast(pvpConfig);
*/ await pinus.app.rpc.role.roleRemote.setPvpSeasonNum.broadcast(pvpConfig);
export async function resetPvpSeasonTime(minute: number) { await pinus.app.rpc.connector.connectorRemote.setPvpSeasonNum.broadcast(pvpConfig);
return await setPvpSeason(false, true, minute); }
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() { export async function reportOnlineSchedule() {
-1
View File
@@ -399,7 +399,6 @@ function getData(pinusClient, seasonEnd: boolean, cb) {
expect(heroScore.hid).to.be.a('number'); expect(heroScore.hid).to.be.a('number');
expect(heroScore.score).to.be.a('number'); expect(heroScore.score).to.be.a('number');
}); });
expect(res.data.isFirstEntry).to.be.a('boolean');
if (seasonEnd) { if (seasonEnd) {
checkSeasonResult(res.data.seasonResult); checkSeasonResult(res.data.seasonResult);
} }
+7
View File
@@ -194,4 +194,11 @@ export default class GameController extends Controller {
ctx.body = await ctx.service.game.getServerName(); ctx.body = await ctx.service.game.getServerName();
return 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
}
} }
+1
View File
@@ -70,6 +70,7 @@ export default (app: Application) => {
router.post('/api/game/getmarqueelist', tokenParser, controller.game.getMarqueeList); router.post('/api/game/getmarqueelist', tokenParser, controller.game.getMarqueeList);
router.post('/api/game/updatemarquee', tokenParser, controller.game.updateMarquee); router.post('/api/game/updatemarquee', tokenParser, controller.game.updateMarquee);
router.post('/api/game/getaccuse', tokenParser, controller.game.getAccuse); 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/getactivitylist', tokenParser, controller.activity.getActivityList);
router.post('/api/activity/getallactivities', tokenParser, controller.activity.getAllActivities); router.post('/api/activity/getallactivities', tokenParser, controller.activity.getAllActivities);
+10
View File
@@ -21,6 +21,7 @@ import { UserOrderModel } from '@db/UserOrder';
import { SurveyModel } from '@db/Survery'; import { SurveyModel } from '@db/Survery';
import { RedisClient } from 'redis'; import { RedisClient } from 'redis';
import { ChannelInfoModel } from '@db/ChannelInfo'; import { ChannelInfoModel } from '@db/ChannelInfo';
import { PVPConfigModel } from '@db/PvpConfig';
/** /**
* Test Service * Test Service
@@ -314,4 +315,13 @@ export default class Game extends Service {
}), total }), 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
});
}
} }
+8 -1
View File
@@ -639,7 +639,8 @@ export enum SHOP_REFRESH_TYPE {
DAILY = 1, // 每天刷新 DAILY = 1, // 每天刷新
WEEKLY = 2, // 每周 WEEKLY = 2, // 每周
MONTHLY = 3, // 每月 MONTHLY = 3, // 每月
FOREVER = 4 // 不重置 FOREVER = 4, // 不重置
PVP = 5, // pvp赛季
} }
// 任务的大类 // 任务的大类
@@ -1155,3 +1156,9 @@ export enum SYSTEM_OPEN_ID {
} }
export const DEBUG_PRICE = 0.01; export const DEBUG_PRICE = 0.01;
export enum PVP_SEASON_STATUS {
START = 1, // 已开始
SUMMIT = 2, // 结算中
WAITING = 3, // 待新赛季
}
+3
View File
@@ -21,6 +21,7 @@ export const STATUS = {
ADDRESS_ERR: { code: 17, simStr: '您的版本已停止支持,请前往应用商店下载最新安装包' }, ADDRESS_ERR: { code: 17, simStr: '您的版本已停止支持,请前往应用商店下载最新安装包' },
GLOBAL_ERR: { code: 1003, simStr: '服务器内部错误' }, GLOBAL_ERR: { code: 1003, simStr: '服务器内部错误' },
UPDATE_INFO_ERR: {code: 1004, simStr: '热更新配置错误'}, UPDATE_INFO_ERR: {code: 1004, simStr: '热更新配置错误'},
DEBUG_FUNCTION_ERR: {code: 1005, simStr: '功能逻辑已改,debug接口不再提供'},
// http请求 // http请求
REQUEST_TIME_OUT: { code: 2000, simStr: '请求超时' }, REQUEST_TIME_OUT: { code: 2000, simStr: '请求超时' },
@@ -177,6 +178,8 @@ export const STATUS = {
PVP_SET_ATTACK_CNT_NOT_ENOUGH: { code: 20806, simStr: '设置挑战阵容次数不足' }, PVP_SET_ATTACK_CNT_NOT_ENOUGH: { code: 20806, simStr: '设置挑战阵容次数不足' },
PVP_NOT_SET_ATTACK: { code: 20807, simStr: '未设置挑战阵容' }, PVP_NOT_SET_ATTACK: { code: 20807, simStr: '未设置挑战阵容' },
PVP_BUY_ATTACK_CNT_NOT_ENOUGH: { code: 20808, 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 // 军团 20900-20999
GUILD_AUTH_NOT_ENOUGH: { code: 20900, simStr: '权限不足' }, GUILD_AUTH_NOT_ENOUGH: { code: 20900, simStr: '权限不足' },
+115
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>; // 将所有字段变成可选项
+23 -11
View File
@@ -7,6 +7,7 @@ import { COUNTER } from '../consts';
import { PVP } from '../pubUtils/dicParam'; import { PVP } from '../pubUtils/dicParam';
@index({ roleId: 1 }) @index({ roleId: 1 })
@index({ score: 1 })
export default class PvpDefense extends BaseModel { export default class PvpDefense extends BaseModel {
@prop({ required: true }) @prop({ required: true })
serverId: number; // 区 id serverId: number; // 区 id
@@ -17,6 +18,8 @@ export default class PvpDefense extends BaseModel {
@prop({ ref: 'Role', type: mongoose.Schema.Types.ObjectId }) @prop({ ref: 'Role', type: mongoose.Schema.Types.ObjectId })
role: Ref<Role>; role: Ref<Role>;
@prop({ required: true, default: null, _id: false }) @prop({ required: true, default: null, _id: false })
hasDefense: boolean;
@prop({ required: true, default: null, _id: false })
defense: Defense; defense: Defense;
@prop({ required: true, default: null, _id: false }) @prop({ required: true, default: null, _id: false })
attack: Attack; attack: Attack;
@@ -58,8 +61,6 @@ export default class PvpDefense extends BaseModel {
seasonNum: number; seasonNum: number;
@prop({ required: true, default: 0 }) @prop({ required: true, default: 0 })
seasonWinNum: number; // 本赛季胜利次数 seasonWinNum: number; // 本赛季胜利次数
@prop({ required: true, default: true })
isFirstEntry: boolean;
@prop({ required: true, default: 0 }) @prop({ required: true, default: 0 })
defenseScoreCnt: number; defenseScoreCnt: number;
@@ -129,7 +130,7 @@ export default class PvpDefense extends BaseModel {
} }
public static async findByTeamLv(seasonNum: number, min: number, max: number) { 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('role', '_id head frame spine heads frames spines topLineupCe roleId roleName lv globalCeAttr title')
.populate('heroes.hero') .populate('heroes.hero')
.populate('oppPlayers.oppDef', 'oppRoleId pos roleName head frame spine heads frames spines rankLv pLv title lv defCe heroes warId buff') .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; 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) { public static async updateInfoAndInclude(roleId: string, update: pvpUpdateInter) {
delete update._id; delete update._id;
let result: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({roleId}, {$set:update}, {new: true}) let result: PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({roleId}, {$set:update}, {new: true})
@@ -162,14 +182,6 @@ export default class PvpDefense extends BaseModel {
return ranks; 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) { 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(); let result:PvpDefenseType = await PvpDefenseModel.findOneAndUpdate({roleId}, {$pull:{lineupCe: {hid}, heroScores: {hid}}, $set: {defense: null, attack: null}}, {new: true}).lean();
return result; return result;
+36
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>;
+4
View File
@@ -59,6 +59,10 @@ export default class PvpSeasonResult extends BaseModel {
let result: PvpSeasonResultType = await PvpSeasonResultModel.findOne({ roleId, show: true }).lean(); let result: PvpSeasonResultType = await PvpSeasonResultModel.findOne({ roleId, show: true }).lean();
return result; return result;
} }
public static async checkResultBySeasonNum(roleId: string, seasonNum: number) {
return await PvpSeasonResultModel.exists({ roleId, seasonNum });
}
} }
export const PvpSeasonResultModel = getModelForClass(PvpSeasonResult); export const PvpSeasonResultModel = getModelForClass(PvpSeasonResult);
-59
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>; // 将所有字段变成可选项
+14 -10
View File
@@ -44,7 +44,10 @@ export default class UserShop extends BaseModel {
@prop({ required: true }) @prop({ required: true })
count: number; // 数量 count: number; // 数量
private static getRefreshCondition() { @prop({ required: true })
seasonNum: number; // 赛季id
private static getRefreshCondition(seasonNum: number) {
let today = getZeroPointD(); let today = getZeroPointD();
let cutWeek = getZeroPointD(SHOP_REFRESH_TYPE.WEEKLY); let cutWeek = getZeroPointD(SHOP_REFRESH_TYPE.WEEKLY);
let curMonth = getZeroPointD(SHOP_REFRESH_TYPE.MONTHLY); 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: cutWeek }, refreshType: SHOP_REFRESH_TYPE.WEEKLY },
{ createdAt: { $gte: curMonth }, refreshType: SHOP_REFRESH_TYPE.MONTHLY }, { createdAt: { $gte: curMonth }, refreshType: SHOP_REFRESH_TYPE.MONTHLY },
{ refreshType: SHOP_REFRESH_TYPE.FOREVER }, { refreshType: SHOP_REFRESH_TYPE.FOREVER },
{ refreshType: SHOP_REFRESH_TYPE.PVP, seasonNum },
] ]
} }
public static async findByShopType(roleId: string, shop: number, type: number) { public static async findByShopType(roleId: string, shop: number, type: number, seasonNum: number) {
let timeCondition = this.getRefreshCondition(); let timeCondition = this.getRefreshCondition(seasonNum);
let rec: UserShopType[] = await UserShopModel.find({ shop, type, roleId, $or: timeCondition }).lean(); let rec: UserShopType[] = await UserShopModel.find({ shop, type, roleId, $or: timeCondition }).lean();
return rec; return rec;
} }
public static async findByRoleId(roleId: string) { public static async findByRoleId(roleId: string, seasonNum: number) {
let timeCondition = this.getRefreshCondition(); let timeCondition = this.getRefreshCondition(seasonNum);
let rec: UserShopType[] = await UserShopModel.find({ roleId, $or: timeCondition }).lean(); let rec: UserShopType[] = await UserShopModel.find({ roleId, $or: timeCondition }).lean();
return rec; return rec;
} }
public static async findByRoleAndItem(roleId: string, activityId: number, dicShopItem: { id: number, shop: number, type: number, createTime?: number }) { public static async findByRoleAndItem(roleId: string, activityId: number, dicShopItem: { id: number, shop: number, type: number, createTime?: number }, seasonNum: number) {
let timeCondition = this.getRefreshCondition(); let timeCondition = this.getRefreshCondition(seasonNum);
let { id, shop, type, createTime = 0 } = dicShopItem; let { id, shop, type, createTime = 0 } = dicShopItem;
let rec: UserShopType = await UserShopModel.findOne({ roleId, itemId: id, shop, type, activityId, createTime, $or: timeCondition }).lean(); let rec: UserShopType = await UserShopModel.findOne({ roleId, itemId: id, shop, type, activityId, createTime, $or: timeCondition }).lean();
return rec; 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 code = genCode(8);
let timeCondition = this.getRefreshCondition(); let timeCondition = this.getRefreshCondition(seasonNum);
let { id, goodId, refreshType, shop, type, createTime = 0 } = dicShopItem; let { id, goodId, refreshType, shop, type, createTime = 0 } = dicShopItem;
let rec: UserShopType = await UserShopModel.findOneAndUpdate( let rec: UserShopType = await UserShopModel.findOneAndUpdate(
{ roleId, itemId: id, $or: timeCondition, activityId, shop, type, createTime }, { 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 } { new: true, upsert: true }
).lean(); ).lean();
return rec; return rec;
@@ -6,7 +6,7 @@ import { RewardInter } from "../../pubUtils/interface";
import { parseNumberList } from "../../pubUtils/util"; import { parseNumberList } from "../../pubUtils/util";
import { stringWithTypeToRewardInter } from "../../pubUtils/roleUtil"; import { stringWithTypeToRewardInter } from "../../pubUtils/roleUtil";
import { ActivityBase } from './activityField'; import { ActivityBase } from './activityField';
import { PVPConfigModel } from "../../db/SystemConfig"; import { PVPConfigModel } from "../../db/PvpConfig";
import { getZeroPointOfTimeD, nowSeconds } from "../../pubUtils/timeUtil"; import { getZeroPointOfTimeD, nowSeconds } from "../../pubUtils/timeUtil";
// 数据库格式 // 数据库格式
+33 -1
View File
@@ -3,7 +3,7 @@ import { isArray, isNumber, isString } from 'underscore';
import ServerStategy, { GMMail } from "../../db/ServerStategy"; import ServerStategy, { GMMail } from "../../db/ServerStategy";
import { RegionType } from "../../db/Region"; import { RegionType } from "../../db/Region";
import { RewardInter } from "../../pubUtils/interface"; import { RewardInter } from "../../pubUtils/interface";
import { isTimestamp } from '../../pubUtils/util'; import { isTimestamp, parseNumberList } from '../../pubUtils/util';
import { isBoolean, isDate } from "util"; import { isBoolean, isDate } from "util";
export class UpdateMailParams { export class UpdateMailParams {
@@ -439,3 +439,35 @@ export class UpdateChannelParam {
return true; 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)}
}
}
+61 -12
View File
@@ -3,13 +3,13 @@ import { prop, Ref, mongoose } from '@typegoose/typegoose';
import Hero from '../../db/Hero'; import Hero from '../../db/Hero';
import { PvpDefenseType } from '../../db/PvpDefense'; import { PvpDefenseType } from '../../db/PvpDefense';
import PvpHistoryOpp from '../../db/PvpHistoryOpp'; import PvpHistoryOpp from '../../db/PvpHistoryOpp';
import { PvpSaveDataType } from '../../db/PvpSaveData';
import { PvpSeasonResultType } from '../../db/PvpSeasonResult'; import { PvpSeasonResultType } from '../../db/PvpSeasonResult';
import { getPlvAndScore } from '../../pubUtils/data'; import { getPlvAndScore } from '../../pubUtils/data';
import { RewardInter } from '../../pubUtils/interface'; import { RewardInter } from '../../pubUtils/interface';
import { nowSeconds } from '../../pubUtils/timeUtil';
export class DefenseHeroInSaveData {
// 防守阵容武将
export class DefenseHero {
@prop({ required: true }) @prop({ required: true })
actorId: number; // 武将id actorId: number; // 武将id
@prop({ required: true }) @prop({ required: true })
@@ -18,16 +18,26 @@ export class DefenseHero {
dataId: number; dataId: number;
@prop({ required: true }) @prop({ required: true })
order: number; 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.actorId = param.actorId;
this.ai = param.ai; this.ai = param.ai;
this.dataId = param.dataId; this.dataId = param.dataId;
this.order = param.order; 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; this.hero = heroId;
} }
} }
// 防守阵容 // 防守阵容
@@ -228,7 +238,9 @@ export class PvpSeasonResultRecord {
export class PvpDataReturn { export class PvpDataReturn {
seasonNum: number; seasonNum: number;
seasonStartTime: number;
seasonEndTime: number; seasonEndTime: number;
seasonRewardTime: number;
myRank: number = 0; myRank: number = 0;
oppPlayers: OppPlayerReturn[] = []; oppPlayers: OppPlayerReturn[] = [];
defense: DefenseLineupReturn = null; defense: DefenseLineupReturn = null;
@@ -244,7 +256,7 @@ export class PvpDataReturn {
receivedBox: number[] = []; receivedBox: number[] = [];
hisScore: number = 0; hisScore: number = 0;
heroScores: HeroScoreReturn[] = []; heroScores: HeroScoreReturn[] = [];
isFirstEntry: boolean = false; hasSaveDefense: boolean = false;
resultRecord: PvpSeasonResultRecord; resultRecord: PvpSeasonResultRecord;
setPvpDefense(pvpDefense: PvpDefenseType) { setPvpDefense(pvpDefense: PvpDefenseType) {
@@ -284,10 +296,6 @@ export class PvpDataReturn {
return { attackCe, defenseCe }; return { attackCe, defenseCe };
} }
setIsFirstEntry(isFirstEntry: boolean) {
this.isFirstEntry = isFirstEntry;
}
setOppPlayers(oppPlayers: OppPlayerReturn[]) { setOppPlayers(oppPlayers: OppPlayerReturn[]) {
this.oppPlayers = oppPlayers; this.oppPlayers = oppPlayers;
} }
@@ -296,12 +304,53 @@ export class PvpDataReturn {
this.myRank = rankLv; this.myRank = rankLv;
} }
setPvpConfig(seasonNum: number, seasonEndTime: number) { setPvpConfig(seasonNum: number, seasonStartTime: number, seasonEndTime: number, seasonRewardTime: number) {
this.seasonNum = seasonNum; this.seasonNum = seasonNum;
this.seasonStartTime = seasonStartTime;
this.seasonEndTime = seasonEndTime; this.seasonEndTime = seasonEndTime;
this.seasonRewardTime = seasonRewardTime;
} }
setPvpSeasonResult(pvpSeasonResult: PvpSeasonResultType) { setPvpSeasonResult(pvpSeasonResult: PvpSeasonResultType) {
this.resultRecord = new PvpSeasonResultRecord(pvpSeasonResult); 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;
}
} }
+14
View File
@@ -894,5 +894,19 @@
"name": "开关接口", "name": "开关接口",
"module": "sys", "module": "sys",
"type": "update" "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"
} }
] ]
+1 -1
View File
@@ -10,7 +10,7 @@
"lvLimit": 0, "lvLimit": 0,
"ranklimit": 0, "ranklimit": 0,
"purchaseLimit": 5, "purchaseLimit": 5,
"refreshType": 1, "refreshType": 5,
"money": 31002, "money": 31002,
"price": "1&0|2&50|3&100|4&150|5&200", "price": "1&0|2&50|3&100|4&150|5&200",
"chosen": 2, "chosen": 2,