diff --git a/game-server/app/servers/activity/handler/novemberHandler.ts b/game-server/app/servers/activity/handler/novemberHandler.ts index 671d59004..238b813e1 100644 --- a/game-server/app/servers/activity/handler/novemberHandler.ts +++ b/game-server/app/servers/activity/handler/novemberHandler.ts @@ -1,6 +1,6 @@ import { Application, BackendSession, HandlerService, } from 'pinus'; import { getPlayerNovemberData, getPlayerNovemberDataShow } from '../../../services/activity/novemberServices'; -import { genCode, resResult } from '../../../pubUtils/util'; +import { genCode, getRandSingleEelm, resResult } from '../../../pubUtils/util'; import { ITEM_CHANGE_REASON, STATUS } from '../../../consts'; import { ActivityNovemberRecModel, NovemberRecord } from '../../../db/ActivityNovemberRec'; import { RewardInter } from '../../../pubUtils/interface'; @@ -8,7 +8,11 @@ import { addItems, handleCost } from '../../../services/role/rewardService'; import { stringToConsumeParam, stringToRewardParam } from '../../../services/activity/giftPackageService'; import { getZeroPoint } from '../../../pubUtils/timeUtil'; - +/** + * 辜月集会 + * @param app + * @returns + */ export default function (app: Application) { new HandlerService(app, {}); return new NovemberHandler(app); @@ -18,6 +22,12 @@ export class NovemberHandler { constructor(private app: Application) { } + /** + * 获取数据 + * @param msg + * @param session + * @returns + */ async getData(msg: { activityId: number }, session: BackendSession) { const { activityId } = msg; const roleId = session.get('roleId'); @@ -29,29 +39,38 @@ export class NovemberHandler { return resResult(STATUS.SUCCESS, playerData); } - async gameStart(msg: { activityId: number, menuId: number }, session: BackendSession) { - const { activityId, menuId } = msg; + /** + * 开始游戏 + * @param msg + * @param session + * @returns + */ + async gameStart(msg: { activityId: number }, session: BackendSession) { + const { activityId } = msg; const roleId = session.get('roleId'); const serverId = session.get('serverId'); let playerData = await getPlayerNovemberData(activityId, serverId, roleId); - if (!playerData || !playerData.menuMap) return resResult(STATUS.ACTIVITY_MISSING); - let menu = playerData.menuMap.get(menuId); - if (!menu) return resResult(STATUS.ACTIVITY_MISSING); - if (playerData.todayIndex < menu.dayIndex) return resResult(STATUS.ACTIVITY_NOVEMBER_MENU_LOCK); - + if (!playerData || playerData.menuIds.length == 0) return resResult(STATUS.ACTIVITY_MISSING); // 检测挑战次数 - if (menu.playCnt >= menu.maxPlayCnt) return resResult(STATUS.ACTIVITY_NOVEMBER_NO_NUM); + if (playerData.playCnt >= playerData.freeCnt + playerData.buyCnt) return resResult(STATUS.ACTIVITY_NOVEMBER_NO_NUM); const gameCode = genCode(10); + const menuId = getRandSingleEelm(playerData.menuIds); await ActivityNovemberRecModel.records(serverId, activityId, playerData.roundIndex, roleId, [{ - todayIndex: playerData.todayIndex, gameCode, time: new Date(), rewards: '', isSuccess: false, isSkip: false, menuId, isPass: false + todayIndex: playerData.todayIndex, gameCode, time: new Date(), rewards: '', isSuccess: false, isSkip: false, menuId, hasPass: false }]); - return resResult(STATUS.SUCCESS, { activityId, gameCode }); + return resResult(STATUS.SUCCESS, { activityId, gameCode, menuId }); } + /** + * 结束游戏 + * @param msg + * @param session + * @returns + */ async gameEnd(msg: { activityId: number, gameCode: string, isSuccess: boolean }, session: BackendSession) { const { activityId, gameCode, isSuccess } = msg; const roleId: string = session.get('roleId'); @@ -62,32 +81,35 @@ export class NovemberHandler { let playerData = await getPlayerNovemberData(activityId, serverId, roleId); if (!playerData) return resResult(STATUS.ACTIVITY_MISSING); - if (!playerData.records || playerData.records.length == 0) return resResult(STATUS.ACTIVITY_NOVEMBER_GAMECODE_NOT_FOUND); let record = playerData.records.find(cur => cur.gameCode == gameCode); if (!record) return resResult(STATUS.ACTIVITY_NOVEMBER_GAMECODE_NOT_FOUND); - if (record.isPass) return resResult(STATUS.ACTIVITY_NOVEMBER_GAMECODE_USE); + if (record.hasPass) return resResult(STATUS.ACTIVITY_NOVEMBER_GAMECODE_USE); let menuId = record.menuId; - let menu = playerData.menuMap.get(menuId); - if (!menu) return resResult(STATUS.ACTIVITY_MISSING); - if (menu.playCnt >= menu.maxPlayCnt) return resResult(STATUS.ACTIVITY_NOVEMBER_NO_NUM); + // 检测挑战次数 + if (playerData.playCnt >= playerData.freeCnt + playerData.buyCnt) return resResult(STATUS.ACTIVITY_NOVEMBER_NO_NUM); - let rewards: string = menu.successRewards; - if (!isSuccess) rewards = menu.failRewards; + let rewards: string = playerData.successRewards; + if (!isSuccess) rewards = playerData.failRewards; let playerRecord = await ActivityNovemberRecModel.gameEnd(serverId, activityId, playerData.roundIndex, roleId, gameCode, isSuccess, new Date(), rewards, true); if (!playerRecord) return resResult(STATUS.ACTIVITY_NOVEMBER_GAMECODE_NOT_FOUND); playerData = await getPlayerNovemberData(activityId, serverId, roleId); - menu = playerData.menuMap.get(menuId); let goods: RewardInter[] = await addItems(roleId, roleName, sid, stringToRewardParam(rewards), ITEM_CHANGE_REASON.NOVEMBER_REWARD); - return resResult(STATUS.SUCCESS, { activityId, menuId, playCnt: menu.playCnt, maxPlayCnt: menu.maxPlayCnt, goods }); + return resResult(STATUS.SUCCESS, { activityId, menuId, todayPlayCnt: playerData.todayPlayCnt, playCnt: playerData.playCnt, freeCnt: playerData.freeCnt, goods }); } - async buyCnt(msg: { activityId: number, count: number, menuId: number }, session: BackendSession) { - const { activityId, count, menuId } = msg; + /** + * 购买次数 + * @param msg + * @param session + * @returns + */ + async buyCnt(msg: { activityId: number, count: number }, session: BackendSession) { + const { activityId, count } = msg; const roleId: string = session.get('roleId'); const roleName: string = session.get('roleName'); const serverId: number = session.get('serverId'); @@ -95,27 +117,29 @@ export class NovemberHandler { let playerData = await getPlayerNovemberData(activityId, serverId, roleId); if (!playerData) return resResult(STATUS.ACTIVITY_MISSING); - let menu = playerData.menuMap.get(menuId); - if (!menu) return resResult(STATUS.ACTIVITY_MISSING); - if (playerData.todayIndex < menu.dayIndex) return resResult(STATUS.ACTIVITY_NOVEMBER_MENU_LOCK); - if (menu.buyCnt + count > menu.maxBuyCnt) return resResult(STATUS.ACTIVITY_NOVEMBER_BUY_COUNT_OVER); + if (playerData.buyCnt + count > playerData.maxBuyCnt) return resResult(STATUS.ACTIVITY_NOVEMBER_BUY_COUNT_OVER); // 扣材料 - let costResult = await handleCost(roleId, sid, stringToConsumeParam(menu.buyCost), ITEM_CHANGE_REASON.NOVEMBER_COST); + let costResult = await handleCost(roleId, sid, stringToConsumeParam(playerData.buyCost), ITEM_CHANGE_REASON.NOVEMBER_COST); if (!costResult) return resResult(STATUS.ROLE_MATERIAL_NOT_ENOUGH); - let buyResult = await ActivityNovemberRecModel.buyCnt(serverId, activityId, playerData.roundIndex, roleId, { menuId, buyCnt: count }, menu.isPushBuyRec); + let buyResult = await ActivityNovemberRecModel.buyCnt(serverId, activityId, playerData.roundIndex, roleId, count); if (!buyResult) return resResult(STATUS.ACTIVITY_NOVEMBER_GAMECODE_NOT_FOUND); playerData = await getPlayerNovemberData(activityId, serverId, roleId); - menu = playerData.menuMap.get(menuId); - return resResult(STATUS.SUCCESS, { activityId, menuId, buyCnt: menu.buyCnt, maxBuyCnt: menu.maxBuyCnt }); + return resResult(STATUS.SUCCESS, { activityId, buyCnt: playerData.buyCnt, maxBuyCnt: playerData.maxBuyCnt }); } - async gameSweep(msg: { activityId: number, count: number, menuId: number }, session: BackendSession) { - const { activityId, count, menuId } = msg; + /** + * 扫荡 + * @param msg + * @param session + * @returns + */ + async gameSweep(msg: { activityId: number, count: number }, session: BackendSession) { + const { activityId, count } = msg; const roleId: string = session.get('roleId'); const roleName: string = session.get('roleName'); const serverId: number = session.get('serverId'); @@ -123,28 +147,24 @@ export class NovemberHandler { let playerData = await getPlayerNovemberData(activityId, serverId, roleId); if (!playerData) return resResult(STATUS.ACTIVITY_MISSING); - let menu = playerData.menuMap.get(menuId); - if (!menu) return resResult(STATUS.ACTIVITY_MISSING); - if (playerData.todayIndex < menu.dayIndex) return resResult(STATUS.ACTIVITY_NOVEMBER_MENU_LOCK); + if (playerData.menuIds.length == 0) return (STATUS.ACTIVITY_NOVEMBER_MENU_NOT_FIND) + if (playerData.todayPlayCnt <= 0) return resResult(STATUS.ACTIVITY_NOVEMBER_GAMESWEEP_LOCK); - if (menu.playCnt + count > menu.maxPlayCnt) return resResult(STATUS.ACTIVITY_NOVEMBER_NO_NUM); - let isHasSuccess = playerData.records.find(cur => cur.isSuccess && !cur.isSkip && (getZeroPoint() * 1000 <= cur.time.getTime())); - if (!isHasSuccess) return resResult(STATUS.ACTIVITY_NOVEMBER_GAMESWEEP_LOCK); + if (playerData.playCnt + count > playerData.freeCnt + playerData.buyCnt) return resResult(STATUS.ACTIVITY_NOVEMBER_NO_NUM); let rewards: RewardInter[] = []; let records: NovemberRecord[] = []; for (let i = 0; i < count; i++) { - records.push({ todayIndex: playerData.todayIndex, gameCode: 'sweep', time: new Date(), rewards: menu.successRewards, isSuccess: true, isSkip: true, menuId, isPass: true }) - rewards.push(...stringToRewardParam(menu.successRewards)); + records.push({ todayIndex: playerData.todayIndex, gameCode: 'sweep', time: new Date(), rewards: playerData.successRewards, isSuccess: true, isSkip: true, menuId: 0, hasPass: true }) + rewards.push(...stringToRewardParam(playerData.successRewards)); } await ActivityNovemberRecModel.records(serverId, activityId, playerData.roundIndex, roleId, records); let goods = await addItems(roleId, roleName, sid, rewards, ITEM_CHANGE_REASON.NOVEMBER_REWARD) playerData = await getPlayerNovemberData(activityId, serverId, roleId); - menu = playerData.menuMap.get(menuId); - return resResult(STATUS.SUCCESS, { activityId, menuId, playCnt: menu.playCnt, maxPlayCnt: menu.maxPlayCnt, goods }); + return resResult(STATUS.SUCCESS, { activityId, todayPlayCnt: playerData.todayPlayCnt, playCnt: playerData.playCnt, goods }); } } \ No newline at end of file diff --git a/game-server/app/services/checkParam.ts b/game-server/app/services/checkParam.ts index f27e4f19e..5d1641917 100644 --- a/game-server/app/services/checkParam.ts +++ b/game-server/app/services/checkParam.ts @@ -2392,7 +2392,7 @@ export function checkRouteParam(route: string, msg: any) { } case 'activity.novemberHandler.gameStart': { - if (!checkNaturalNumbers(msg.activityId, msg.menuId)) return false; + if (!checkNaturalNumbers(msg.activityId)) return false; break; } case 'activity.novemberHandler.gameEnd': @@ -2404,12 +2404,12 @@ export function checkRouteParam(route: string, msg: any) { } case 'activity.novemberHandler.buyCnt': { - if (!checkNaturalNumbers(msg.activityId, msg.count, msg.menuId)) return false; + if (!checkNaturalNumbers(msg.activityId, msg.count)) return false; break; } case 'activity.novemberHandler.gameSweep': { - if (!checkNaturalNumbers(msg.activityId, msg.count, msg.menuId)) return false; + if (!checkNaturalNumbers(msg.activityId, msg.count)) return false; break; } case 'activity.activityHandler.debugActivityMemory': diff --git a/shared/consts/statusCode.ts b/shared/consts/statusCode.ts index f6b125eb1..edc66596e 100644 --- a/shared/consts/statusCode.ts +++ b/shared/consts/statusCode.ts @@ -728,7 +728,7 @@ export const STATUS = { ACTIVITY_NOVEMBER_GAMECODE_USE: { code: 50091, simStr: '游戏已经结算过' }, ACTIVITY_NOVEMBER_BUY_COUNT_OVER: { code: 50092, simStr: '购买次数不足' }, ACTIVITY_NOVEMBER_GAMESWEEP_LOCK: { code: 50093, simStr: '纯净召唤未开启' }, - ACTIVITY_NOVEMBER_MENU_LOCK: { code: 50094, simStr: '菜谱未解锁' }, + ACTIVITY_NOVEMBER_MENU_NOT_FIND: { code: 50094, simStr: '菜谱未找到' }, diff --git a/shared/db/ActivityNovemberRec.ts b/shared/db/ActivityNovemberRec.ts index 931a4eaf8..3c1660b5e 100644 --- a/shared/db/ActivityNovemberRec.ts +++ b/shared/db/ActivityNovemberRec.ts @@ -18,17 +18,16 @@ export class NovemberRecord { @prop({ required: true }) isSkip: boolean // 是否纯净召唤 @prop({ required: true }) - menuId: number //菜单id + hasPass: boolean; // 是否通过 @prop({ required: true }) - isPass: boolean // gameEnd后置为true + menuId: number //菜单id } export class NovemberBuyRec { @prop({ required: true }) menuId: number //菜单id - @prop({ required: true }) - buyCnt: number //购买次数 + } export default class Activity_November_Rec extends BaseModel { @prop({ required: true }) @@ -43,8 +42,8 @@ export default class Activity_November_Rec extends BaseModel { @prop({ required: true }) roleId: string; // 用户Id - @prop({ required: true, type: NovemberBuyRec, default: [], _id: false }) - buyRec: NovemberBuyRec[] // 购买 + @prop({ required: true }) + buyCnt: number //购买次数 @prop({ required: true, type: NovemberRecord, _id: false }) records: NovemberRecord[]; // 记录 @@ -55,20 +54,18 @@ export default class Activity_November_Rec extends BaseModel { } public static async records(serverId: number, activityId: number, roundIndex: number, roleId: string, records: NovemberRecord[]) { - let result: ActivityNovemberRecModelType = await ActivityNovemberRecModel.findOneAndUpdate({ serverId, roleId, activityId, roundIndex }, { $push: { records: { $each: records } }, $setOnInsert: { buyRec: [] } }, { new: true, upsert: true }).lean(); + let result: ActivityNovemberRecModelType = await ActivityNovemberRecModel.findOneAndUpdate({ serverId, roleId, activityId, roundIndex }, { $push: { records: { $each: records } }, $setOnInsert: { buyCnt: 0 } }, { new: true, upsert: true }).lean(); return result; } - public static async gameEnd(serverId: number, activityId: number, roundIndex: number, roleId: string, gameCode: string, isSuccess: boolean, time: Date, rewards: string, isPass: boolean) { + public static async gameEnd(serverId: number, activityId: number, roundIndex: number, roleId: string, gameCode: string, isSuccess: boolean, time: Date, rewards: string, hasPass: boolean) { let result: ActivityNovemberRecModelType = await ActivityNovemberRecModel.findOneAndUpdate({ serverId, roleId, activityId, roundIndex, 'records.gameCode': gameCode }, - { $set: { 'records.$.time': time, 'records.$.isSuccess': isSuccess, 'records.$.rewards': rewards, 'records.$.isPass': isPass } }, { new: true }).lean(); + { $set: { 'records.$.time': time, 'records.$.isSuccess': isSuccess, 'records.$.rewards': rewards, 'records.$.hasPass': hasPass } }, { new: true }).lean(); return result; } - public static async buyCnt(serverId: number, activityId: number, roundIndex: number, roleId: string, buyRec: NovemberBuyRec, isPushBuyRec: boolean) { - let result: ActivityNovemberRecModelType; - if (isPushBuyRec) result = await ActivityNovemberRecModel.findOneAndUpdate({ serverId, roleId, activityId, roundIndex }, { $push: { buyRec } }, { new: true, upsert: true }).lean(); - else result = await ActivityNovemberRecModel.findOneAndUpdate({ serverId, roleId, activityId, roundIndex, 'buyRec.menuId': buyRec.menuId }, { $inc: { 'buyRec.buyCnt': buyRec.buyCnt }, $setOnInsert: { records: [] } }, { new: true, upsert: true }).lean(); + public static async buyCnt(serverId: number, activityId: number, roundIndex: number, roleId: string, count: number) { + let result: ActivityNovemberRecModelType = await ActivityNovemberRecModel.findOneAndUpdate({ serverId, roleId, activityId, roundIndex }, { $inc: { buyCnt: count }, $setOnInsert: { record: [] } }, { new: true, upsert: true }).lean(); return result; } } diff --git a/shared/domain/activityField/novemberField.ts b/shared/domain/activityField/novemberField.ts index 52ba5364b..d7c2b4640 100644 --- a/shared/domain/activityField/novemberField.ts +++ b/shared/domain/activityField/novemberField.ts @@ -5,34 +5,42 @@ import { ActivityBase } from './activityField'; // 后台格式 interface NovemberDataInDb { - dayIndex: number; // 天数 - menuId: number; // 菜谱id - buyCost: string; // 对应菜谱购买一次次数的消耗,type&id&count - dailyBuyCnt: number; // 对应菜谱每天可以购买的次数 - dailyFreeCnt: number; // 对应菜谱每天可以免费的次数 - successRewards: string;// 对应菜谱每局的成功奖励 type&id&count - failRewards: string; // 对应菜谱每局的失败安慰奖励 type&id&count + menuIds: number[]; // 菜谱id + buyCost: string; // 购买一次次数的消耗,type&id&count + dailyBuyCnt: number; // 每天可以购买的次数 + dailyFreeCnt: number; // 每天可以免费的次数 + successRewards: string;// 每局的成功奖励 type&id&count + failRewards: string; // 每局的失败安慰奖励 type&id&count }; -interface NovemberDataReturn { - dayIndex: number; // 第几天 - menuId: number; // 菜谱id - buyCost: string; // 对应菜谱购买一次的消耗,type&id&count - buyCnt: number; // 对应菜谱累积到现在已经购买了的次数 - maxBuyCnt: number; // 对应菜谱累积到现在可购买的次数,buyCnt0时才可以扫荡 +// playCnt: number; // 总共的次数,playCnt < freeCnt + buyCnt的时候才能玩新的 - isPushBuyRec?: boolean; // -} +// menuIds: number[]; // 菜谱id +// successRewards: string;// 每局的成功奖励 type&id&count +// failRewards: string; // 每局的失败安慰奖励 type&id&count +// } export class NovemberData extends ActivityBase { + buyCost: string; // 购买一次次数的消耗,type&id&count + maxBuyCnt: number = 0; // 累积到现在可以购买的次数 + buyCnt: number = 0; // 累积到现在已经购买了的次数,buyCnt < maxBuyCnt 的时候才能购买 + freeCnt: number = 0; // 累计到现在可以免费玩的次数 + todayPlayCnt: number = 0; // 今天的次数,todayPlayCnt>0时才可以扫荡 + playCnt: number = 0; // 总共的次数,playCnt < freeCnt + buyCnt的时候才能玩新的 + + menuIds: number[] = []; // 菜谱id + successRewards: string;// 每局的成功奖励 type&id&count + failRewards: string; // 每局的失败安慰奖励 type&id&count + records: NovemberRecord[] = []; - menuMap = new Map(); constructor(activityData: ActivityModelType, createTime: number, serverTime: number) { super(activityData, createTime, serverTime) @@ -40,19 +48,18 @@ export class NovemberData extends ActivityBase { } public initData(data: string): void { - let novemberData: NovemberDataInDb[] = JSON.parse(data); - if (!novemberData || novemberData.length == 0) return; - for (const obj of novemberData) { - let buyCost = obj?.buyCost || '&'; - let buyCnt = 0; - let maxBuyCnt = this.todayIndex * (obj?.dailyBuyCnt || 0); - let playCnt = 0; - let maxPlayCnt = this.todayIndex * (obj?.dailyFreeCnt || 0); - let successRewards = obj?.successRewards || '&'; - let failRewards = obj?.failRewards || '&' - this.menuMap.set(obj.menuId, { dayIndex: obj.dayIndex, menuId: obj.menuId, buyCost, buyCnt, maxBuyCnt, playCnt, maxPlayCnt, successRewards, failRewards, isPushBuyRec: true }) - } + let novemberData: NovemberDataInDb = JSON.parse(data); + if (!novemberData) return; + this.buyCost = novemberData.buyCost || '&'; + this.maxBuyCnt = (novemberData.dailyBuyCnt || 0) * this.todayIndex; + this.buyCnt = 0; + this.freeCnt = (novemberData.dailyFreeCnt) * this.todayIndex; + this.todayPlayCnt = 0; + this.playCnt = 0; + this.menuIds = novemberData.menuIds || []; + this.successRewards = novemberData.successRewards || '&'; + this.failRewards = novemberData.failRewards || '&'; } public setPlayerRecords(playerData: ActivityNovemberRecModelType) { @@ -61,23 +68,13 @@ export class NovemberData extends ActivityBase { public updatePlayerRecord(playerData: ActivityNovemberRecModelType) { if (!playerData) return; + this.buyCnt = playerData?.buyCnt || 0 if (playerData.records) { - this.records = playerData.records; - for (const { menuId, isPass } of playerData.records) { - if (!isPass) continue; - let menu = this.menuMap.get(menuId); - menu.playCnt += 1; - this.menuMap.set(menuId, menu); - - } - } - if (playerData.buyRec) { - for (const { menuId, buyCnt } of playerData.buyRec) { - let menu = this.menuMap.get(menuId); - menu.buyCnt += buyCnt; - menu.maxPlayCnt += buyCnt; - menu.isPushBuyRec = false; - this.menuMap.set(menuId, menu); + this.records = playerData?.records || []; + for (const data of playerData.records) { + let { todayIndex, isSuccess, hasPass } = data; + if (todayIndex == this.todayIndex && isSuccess) this.todayPlayCnt++; + if (hasPass) this.playCnt++; } } } @@ -85,7 +82,15 @@ export class NovemberData extends ActivityBase { public getShowResult() { return { ...this.getBaseKeys(), - menus: [...this.menuMap.values()] + buyCost: this.buyCost, + maxBuyCnt: this.maxBuyCnt, + buyCnt: this.buyCnt, + freeCnt: this.freeCnt, + todayPlayCnt: this.todayPlayCnt, + playCnt: this.playCnt, + menuIds: this.menuIds, + successRewards: this.successRewards, + failRewards: this.failRewards, } } } \ No newline at end of file