diff --git a/game-server/app/servers/battle/handler/towerBattleHandler.ts b/game-server/app/servers/battle/handler/towerBattleHandler.ts index 929cd4798..b9618e875 100644 --- a/game-server/app/servers/battle/handler/towerBattleHandler.ts +++ b/game-server/app/servers/battle/handler/towerBattleHandler.ts @@ -7,8 +7,8 @@ import { RoleModel } from './../../../db/Role'; import { TowerRecordModel } from './../../../db/TowerRecord'; import { Application, BackendSession } from 'pinus'; import { getTaskById, getTowerDataByLv } from '../../../pubUtils/gamedata'; -import { decodeArrayStr, resResult, shouldRefresh, calculateNum } from '../../../pubUtils/util'; -import { calcuHangUpReward, checkTaskConditions, checkHangUpSpdUpCnt, createCurTasks, treatTask, getRemainTime, getTasksReward } from '../../../services/battleService'; +import { decodeArrayStr, resResult, shouldRefresh, calculateNum, getRefTime, genCode } from '../../../pubUtils/util'; +import { calcuHangUpReward, checkTaskConditions, checkHangUpSpdUpCnt, createCurTasks, treatTask, getRemainTime, getTasksReward, getTaskStatus, getDoingOrWaitingTasks } from '../../../services/battleService'; import { handleFixedReward, handleReward } from '../../../services/rewardService'; export default function(app: Application) { @@ -137,17 +137,23 @@ export class TowerBattleHandler { let roleId = session.get('roleId'); let roleName = session.get('roleName'); let curTime = new Date(); - let { towerLv, towerTaskReCnt = 0, towerTaskRefTime = curTime } = await RoleModel.findByRoleId(roleId); - let needRefresh = shouldRefresh(towerTaskRefTime, curTime, TOWER_TASK_CONST.REFRESH_TIME); + + let { towerLv, towerTaskRefTime } = await RoleModel.findByRoleId(roleId); + let curTasks = await TowerTaskRecModel.getCurTasks(roleId); // 当前显示中的任务 + + const needRefresh = shouldRefresh(towerTaskRefTime, curTime, TOWER_TASK_CONST.REFRESH_TIME); if(needRefresh) { - towerTaskReCnt = 0; - } - let costGold = calculateNum(GOLD_COST_RATIO.TPWER_TASK_REF, {num: towerTaskReCnt}, 200); - let curTasks = await TowerTaskRecModel.getCurTasks(roleId); - if (!curTasks || curTasks.length == 0) { - curTasks = await createCurTasks(towerLv, roleId, roleName); + const batchCode = genCode(8); + await RoleModel.resetTowerCnt(roleId, curTime); // 重置派遣次数 + let {waitingTaskCode, doingTaskCode} = getDoingOrWaitingTasks(curTasks, curTime); + await TowerTaskRecModel.hideTask(roleId, waitingTaskCode); // 隐藏没有在做的任务 + await TowerTaskRecModel.updateBatchCode(roleId, doingTaskCode, batchCode); // 更新留下来的旧任务的batchCode + await createCurTasks(towerLv, batchCode, roleId, roleName, doingTaskCode.length); // 新建任务 + curTasks = await TowerTaskRecModel.getCurTasks(roleId); } + let refRemainTime = getRemainTime(curTime); + let costGold = TOWER_TASK_CONST.COST_GOLD; return resResult(STATUS.SUCCESS, { curTasks: treatTask(curTasks, curTime), refRemainTime, nextCostGold: costGold }); } @@ -156,36 +162,34 @@ export class TowerBattleHandler { let roleId = session.get('roleId'); let roleName = session.get('roleName'); let curTime = new Date(); - let { towerLv, towerTaskReCnt = 0, towerTaskRefTime = curTime } = await RoleModel.findByRoleId(roleId); - let needRefresh = shouldRefresh(towerTaskRefTime, curTime, TOWER_TASK_CONST.REFRESH_TIME); - if(needRefresh) { - towerTaskReCnt = 0; + let { towerLv, towerTaskCnt = 0 } = await RoleModel.findByRoleId(roleId); + if(TOWER_TASK_CONST.MAX_TASK_REF_CNT <= towerTaskCnt) { // 每派遣一个任务加一,最多8个完成任务 + return resResult(STATUS.TOWER_REF_CNT_NOT_ENOUGH); } - let costGold = calculateNum(GOLD_COST_RATIO.TPWER_TASK_REF, {num: towerTaskReCnt}, 200); + let costGold = TOWER_TASK_CONST.COST_GOLD; let {gold} = await RoleModel.findByRoleId(roleId); if(costGold > gold) { return resResult(STATUS.TOWER_GOLD_NOT_ENOUGH); } - await RoleModel.increaseTowerRefCnt(roleId, needRefresh, curTime); - // tmp: 将刷掉的旧任务的奖励发送到邮件中 - let oldReward = await getTasksReward(roleId, curTime); - console.log(JSON.stringify(oldReward)); - await TowerTaskRecModel.refreshTask(roleId); // 刷掉旧的任务 + // 只刷掉当前面板上没有做派遣的任务 + const batchCode = genCode(8); + let curTasks = await TowerTaskRecModel.getCurTasks(roleId); // 当前显示中的任务 + let {waitingTaskCode, doingTaskCode} = getDoingOrWaitingTasks(curTasks, curTime); + await TowerTaskRecModel.hideTask(roleId, waitingTaskCode); // 隐藏没有在做的任务 + await TowerTaskRecModel.updateBatchCode(roleId, doingTaskCode, batchCode); // 更新留下来的旧任务的batchCode + await createCurTasks(towerLv, batchCode, roleId, roleName, 0); + curTasks = await TowerTaskRecModel.getCurTasks(roleId); - - let curTasks = await createCurTasks(towerLv, roleId, roleName); // 刷出新的任务 - - let nextCostGold = calculateNum(GOLD_COST_RATIO.TPWER_TASK_REF, {num: towerTaskReCnt + 1}, 200); let refRemainTime = getRemainTime(curTime); - return resResult(STATUS.SUCCESS, { curTasks: treatTask(curTasks, curTime), costGold, nextCostGold, refRemainTime}); + return resResult(STATUS.SUCCESS, { curTasks: treatTask(curTasks, curTime), costGold, nextCostGold:costGold, refRemainTime}); } async sendTaskHero(msg: {batchCode: string, tasks: Array<{taskCode: string, heroes: Array}>}, session: BackendSession) { let roleId = session.get('roleId'); const curTime = new Date(); - const curTasks = await TowerTaskRecModel.getCurTasks(roleId); // 当前一批的任务 + let curTasks = await TowerTaskRecModel.getCurTasks(roleId); // 当前一批的任务 if (!curTasks || curTasks.length == 0) { return resResult(STATUS.TOWER_TASK_NOT_FOUND); } @@ -203,7 +207,7 @@ export class TowerBattleHandler { return resResult(STATUS.TOWER_TASK_MISSING) } let taskInfo = getTaskById(curTask.taskId); - if (task.heroes.length > taskInfo.actorNeeded) { // 武将数,从策划表中读取 + if (task.heroes.length == taskInfo.actorNeeded) { // 武将数,从策划表中读取 return resResult(STATUS.TOWER_TASK_MAX_HERO); } if (tasksCode.indexOf(task.taskCode) === -1) { @@ -222,9 +226,11 @@ export class TowerBattleHandler { if (!recs || recs.length === 0) { return resResult(STATUS.TOWER_TASK_SEND_ERR); } + await RoleModel.increaseTowerCnt(roleId, tasks.length) let refRemainTime = getRemainTime(curTime); - return resResult(STATUS.SUCCESS, { tasks: treatTask(recs, curTime), refRemainTime }); + curTasks = await TowerTaskRecModel.getCurTasks(roleId); // 当前显示中的任务 + return resResult(STATUS.SUCCESS, { tasks: treatTask(curTasks, curTime), refRemainTime }); } async settleTask(msg: {batchCode: string, taskCode: string}, session: BackendSession) { @@ -234,7 +240,7 @@ export class TowerBattleHandler { let allFlag = !msg.taskCode; const curTime = new Date(); - const curTasks = await TowerTaskRecModel.getCurTasks(roleId); + let curTasks = await TowerTaskRecModel.getCurTasks(roleId); if (!curTasks || curTasks.length == 0) { return resResult(STATUS.TOWER_TASK_NOT_FOUND); } @@ -258,10 +264,12 @@ export class TowerBattleHandler { } } } - const rec = await TowerTaskRecModel.finishTask(msg.batchCode, compTasks); + await TowerTaskRecModel.finishTask(msg.batchCode, compTasks); + await TowerTaskRecModel.showTask(roleId, msg.batchCode, compTasks.length); let refRemainTime = getRemainTime(curTime); - return resResult(STATUS.SUCCESS, { compTasks: treatTask(rec, curTime), goods, refRemainTime }); + curTasks = await TowerTaskRecModel.getCurTasks(roleId); // 当前显示中的任务 + return resResult(STATUS.SUCCESS, { compTasks: treatTask(curTasks, curTime), goods, refRemainTime }); } diff --git a/game-server/app/services/battleService.ts b/game-server/app/services/battleService.ts index a193d7d02..d6d9d1998 100644 --- a/game-server/app/services/battleService.ts +++ b/game-server/app/services/battleService.ts @@ -6,12 +6,13 @@ import { BattleRecordModel } from './../db/BattleRecord'; import { TowerRecordModel } from './../db/TowerRecord'; import { RoleModel } from './../db/Role'; import { getHeroInfoById, getJobInfoById, getTowerDataByLv, getTaskById, getGamedata } from "../pubUtils/gamedata" -import { decodeArrayStr, shouldRefresh, resResult, decodeStr, cal, getRandomWithWeight, getRefTime, decodeStrSingle } from '../pubUtils/util'; +import { decodeArrayStr, shouldRefresh, resResult, decodeStr, cal, getRandomWithWeight, getRefTime, decodeStrSingle, genCode } from '../pubUtils/util'; import { handleFixedReward } from './rewardService'; import { STATUS } from '../consts/statusCode'; import { HangUpSpdUpRecModel } from '../db/HangUpSpdUpRec'; import TowerTaskRec, { TowerTaskRecModel } from '../db/TowerTaskRec'; import { PvpDefenseModel } from '../db/PvpDefense'; +import { Document } from 'mongoose'; export async function checkTowerWar(roleId: string, battleId: number, heroes: Array) { const battleIdStr = `${battleId}`; @@ -250,10 +251,10 @@ export async function checkTaskConditions(roleId: string, heroes: Array, * @param towerLv 玩家层数 * @param roleId 玩家id * @param roleName 玩家名 + * @param hideNum 隐藏的任务数量 */ -export async function createCurTasks(towerLv: number, roleId: string, roleName: string) { +export async function createCurTasks(towerLv: number, batchCode: string, roleId: string, roleName: string, hideNum: number) { - let taskIds = []; let randomList = []; let dicTask = getGamedata('dic_zyz_search'); for(let task of dicTask) { @@ -264,16 +265,25 @@ export async function createCurTasks(towerLv: number, roleId: string, roleName: randomList.push(task); } } - for(let i = 0; i < TOWER_TASK_CONST.RAND_CNT; i++) { - let list = randomList.filter(cur => !taskIds.includes(cur.taskId)); - let {dic: tmp} = getRandomWithWeight(list); - if(tmp) { - taskIds.push(tmp.taskId); + let returnTasks = new Array(); + let showNum = TOWER_TASK_CONST.RAND_CNT - hideNum; + const arr = [{refreshStatus: 0, num: hideNum}, {refreshStatus: 1, num: showNum}]; + for(let {refreshStatus, num} of arr) { + let taskIds = []; + for(let i = 0; i < num; i++) { + let list = randomList.filter(cur => !taskIds.includes(cur.taskId)); + let {dic: tmp} = getRandomWithWeight(list); + if(tmp) { + taskIds.push(tmp.taskId); + } + } + const curTasks = await TowerTaskRecModel.createTasks(roleId, roleName, batchCode, taskIds, refreshStatus); + if(refreshStatus == 1) { + returnTasks = curTasks; } } - const curTasks = await TowerTaskRecModel.createTasks(roleId, roleName, taskIds); - return curTasks + return returnTasks; } export function getRemainTime(curTime: Date) { @@ -284,18 +294,39 @@ export function getRemainTime(curTime: Date) { export function treatTask(recs: Array, curTime: Date) { return recs.map(cur => { let { heroes, batchCode, taskId, taskCode, status, completeTime} = cur; - let remainTime = 0; - if(status == 1) { - // console.log(curTime.getTime(), completeTime.getTime()) - remainTime = Math.floor((completeTime.getTime() - curTime.getTime())/1000); - if(remainTime < 0) { - status = 2; remainTime = 0; - } - } - return { heroes, batchCode, taskId, taskCode, status, completeTime, remainTime } + + let getStatusResult = getTaskStatus(status, completeTime, curTime); + return { heroes, batchCode, taskId, taskCode, completeTime, ...getStatusResult } }); } +// 刷新任务,正在进行中的部分保留,没有进行中的刷掉 +export function getDoingOrWaitingTasks (taskList: Array, curTime: Date) { + let doingTaskCode = new Array(), waitingTaskCode = new Array(); + for(let task of taskList) { + let {status} = getTaskStatus(task.status, task.completeTime, curTime); + if(status == 1||status == 2) { + doingTaskCode.push(task.taskCode); + } else if(status == 0|| status == 3) { + waitingTaskCode.push(task.taskCode); + } + } + return {doingTaskCode, waitingTaskCode} +} + +export function getTaskStatus(status: number, completeTime: Date, curTime: Date) { + let remainTime = 0; + if(status == 1) { + // console.log(curTime.getTime(), completeTime.getTime()) + remainTime = Math.floor((completeTime.getTime() - curTime.getTime())/1000); + if(remainTime < 0) { + status = 2; remainTime = 0; + } + } + + return {status, remainTime} +} + export async function getTasksReward(roleId: string, curTime: Date) { let oldTasks = await TowerTaskRecModel.getCurTasks(roleId); let goods = []; diff --git a/shared/consts/consts.ts b/shared/consts/consts.ts index 3887fe233..7f2c630f9 100644 --- a/shared/consts/consts.ts +++ b/shared/consts/consts.ts @@ -145,8 +145,10 @@ export const HANG_UP_CONSTS = { export const TOWER_TASK_CONST = { REFRESH_TIME: 5, - RAND_CNT: 5, - MAX_HEROES_NUM: 3 + RAND_CNT: 8, + MAX_TASK_REF_CNT: 8, // 完成的派遣人数最多 + MAX_HEROES_NUM: 3, + COST_GOLD: 50 } export const DAILY_CONST = { diff --git a/shared/consts/statusCode.ts b/shared/consts/statusCode.ts index 4af1b5cbe..99f260a2f 100644 --- a/shared/consts/statusCode.ts +++ b/shared/consts/statusCode.ts @@ -68,6 +68,7 @@ export const STATUS = { TOWER_GOLD_NOT_ENOUGH: { code: 20516, simStr: '元宝不足' }, TOWER_TASK_MISSING: { code: 20517, simStr: '未找到该任务' }, TOWER_HANG_UP_NOT_START: { code: 20518, simStr: '挂机尚未开启' }, + TOWER_REF_CNT_NOT_ENOUGH: { code: 20518, simStr: '派遣次数不足' }, // 共斗 20600 - 20699 COM_BATTLE_DUP_ENTER: { code: 20601, simStr: '不能重复加入' }, // 养成相关状态 30000 - 39999 diff --git a/shared/db/Role.ts b/shared/db/Role.ts index c8f406593..5a21664b4 100644 --- a/shared/db/Role.ts +++ b/shared/db/Role.ts @@ -110,7 +110,7 @@ export default class Role extends BaseModel { lastSpdUpTime: Date; // 最后一次挂机加速时间 @prop({ required: true, default: 0}) - towerTaskReCnt: number; // 刷新派遣任务的次数,向上累加,消耗元宝和这个相关 + towerTaskCnt: number; // 刷新派遣任务的次数,向上累加,每天8个 @prop({ required: true, default: new Date()}) towerTaskRefTime: Date; // 刷新派遣任务的时间 @@ -251,15 +251,14 @@ export default class Role extends BaseModel { return result; } + // 重置派遣次数 + public static async resetTowerCnt(roleId: string, curTime: Date, lean = true) { + const role = await RoleModel.findOneAndUpdate({roleId}, {towerTaskCnt: 0, towerTaskRefTime: curTime}, {new: true}).lean(lean); + return role; + } // 刷新派遣任务次数增长 - public static async increaseTowerRefCnt(roleId: string, needRefresh: boolean, curTime: Date, lean = true) { - - let role = null; - if (needRefresh) { - role = await RoleModel.findOneAndUpdate({roleId}, {towerTaskReCnt: 1, towerTaskRefTime: curTime}, {new: true}).lean(lean); - } else { - role = await RoleModel.findOneAndUpdate({roleId}, {$inc: {towerTaskReCnt: 1}}, {new: true}).lean(lean); - } + public static async increaseTowerCnt(roleId: string, num: number, lean = true) { + const role = await RoleModel.findOneAndUpdate({roleId}, {$inc: {towerTaskCnt: num}}, {new: true}).lean(lean); return role; } diff --git a/shared/db/TowerTaskRec.ts b/shared/db/TowerTaskRec.ts index 623a1bf09..7979d711e 100644 --- a/shared/db/TowerTaskRec.ts +++ b/shared/db/TowerTaskRec.ts @@ -31,7 +31,7 @@ export default class TowerTaskRec extends BaseModel { @prop({ required: true, default: 0}) status: number; // 派遣任务当前状态,0-可派遣,1-已派遣,2-已完成,3-已领取 @prop({ required: true, default: 1}) - refreshStatus: number; // 派遣任务是否显示 0-不显示,被刷新掉了 1-显示 + refreshStatus: number; // 派遣任务是否显示 -1-刷掉 0-隐藏 1-显示 @prop({ required: true, type: Number, default: [] }) heroes: Array; // 此批派遣使用的全部武将 @@ -45,18 +45,15 @@ export default class TowerTaskRec extends BaseModel { completeTime: Date; // 派遣结束时间 public static async getCurTasks(roleId: string, lean = true) { - let curTime = new Date(); - const refTime = getRefTime(curTime, TOWER_TASK_CONST.REFRESH_TIME); - const recs = await TowerTaskRecModel.find({roleId, createdAt: {$gte: refTime}, refreshStatus: 1}).sort({createdAt: 1}).lean(lean); + const recs = await TowerTaskRecModel.find({roleId, refreshStatus: 1}).sort({createdAt: 1}).lean(lean); return recs; } - public static async createTasks(roleId: string, roleName: string, taskIds: Array/*, lean = true*/) { - const batchCode = genCodeTmp(8); + public static async createTasks(roleId: string, roleName: string, batchCode: string, taskIds: Array, refreshStatus: number) { const tasksData = taskIds.map(id => { const taskModel = new TowerTaskRecModel(); const taskCode = genCodeTmp(6); - const taskData = Object.assign(taskModel.toJSON(), {batchCode, taskId: id, taskCode, roleId, roleName}); + const taskData = Object.assign(taskModel.toJSON(), {batchCode, taskId: id, taskCode, roleId, roleName, refreshStatus}); return taskData; }); const recs = await TowerTaskRecModel.insertMany(tasksData, {ordered: false}); @@ -70,11 +67,9 @@ export default class TowerTaskRec extends BaseModel { public static async sendHeroes(_roleId: string, batchCode: string, tasks: Array<{taskCode:string, heroes: Array, completeTime: number}>, sendTime: Date, lean = true) { let recs = new Array(); - let curTime = new Date(); - const refTime = getRefTime(curTime, TOWER_TASK_CONST.REFRESH_TIME); for (let {taskCode, heroes, completeTime} of tasks) { const rec = await TowerTaskRecModel.findOneAndUpdate( - {batchCode, taskCode: taskCode, createdAt: {$gte: refTime}}, + {batchCode, taskCode: taskCode, refreshStatus: 1}, {heroes: heroes, status: 1, sendTime, completeTime: new Date(sendTime.getTime() + completeTime * 1000)}, {new: true}).lean(lean); @@ -84,25 +79,24 @@ export default class TowerTaskRec extends BaseModel { } public static async finishTask(batchCode: string, tasks: Array, lean = true) { - let recs = new Array(); - // const refTime = getRefTime(); - for (let task of tasks) { - const rec = await TowerTaskRecModel.findOneAndUpdate( - {batchCode, taskCode: task}, - {status: 3}, - {new: true}).lean(lean); - - recs.push(rec); - } + const recs = await TowerTaskRecModel.updateMany({batchCode, taskCode: {$in:tasks}}, {status: 3, refreshStatus: -1}).lean(lean); return recs; } - // 刷掉旧任务 - public static async refreshTask(roleId: string, lean = true) { - let curTime = new Date(); - const refTime = getRefTime(curTime, TOWER_TASK_CONST.REFRESH_TIME); + // 将隐藏的任务显示出来 0=>1 + public static async showTask(roleId: string, bactchCode: string, num: number, lean = true) { + const recs = await TowerTaskRecModel.updateMany({roleId, refreshStatus: 0}, {bactchCode, refreshStatus: 1}).sort({createdAt: 1}).limit(num).lean(lean); + return recs; + } + // 刷掉旧任务 1=>-1 + public static async hideTask(roleId: string, taskIds: Array, lean = true) { // console.log(refTime) - const recs = await TowerTaskRecModel.updateMany({roleId, createdAt: {$gte: refTime}, refreshStatus: 1}, {refreshStatus: 0}, {new: true}).lean(lean); + const recs = await TowerTaskRecModel.updateMany({roleId, taskCode: {$in: taskIds}, refreshStatus: 1}, {refreshStatus: -1}).lean(lean); + return recs; + } + + public static async updateBatchCode(roleId: string, taskIds: Array, batchCode: string, lean = true) { + const recs = await TowerTaskRecModel.updateMany({roleId, taskCode: {$in: taskIds}}, {batchCode}).lean(lean); return recs; } diff --git a/shared/pubUtils/util.ts b/shared/pubUtils/util.ts index 457f3697e..bbce76b1d 100644 --- a/shared/pubUtils/util.ts +++ b/shared/pubUtils/util.ts @@ -179,9 +179,11 @@ export function deltaDays(preTime: Date, proTime: Date): number { * @param deltaDay 间隔几天刷新,默认每天刷新(deltaDay = 1) */ export function shouldRefresh(preTime: Date, now: Date, hour: number, deltaDay = 1): boolean { + if(!preTime) return true; let curTime = new Date(now.getTime()); let refeshTime = setLocalHours(hour, curTime); - if (refeshTime - preTime.getTime() > deltaDay * 24 * 60 * 60 * 1000 && curTime.getTime() >= refeshTime) { + console.log(refeshTime - preTime.getTime()) + if (refeshTime - preTime.getTime() > (deltaDay>=1?deltaDay-1:0) * 24 * 60 * 60 * 1000 && curTime.getTime() >= refeshTime) { return true; } return false; @@ -306,7 +308,7 @@ export function calculateNum(ratio: {A: number, B: number}, params: {num: number export function setLocalHours(hour: number, curTime = new Date()) { // curTime: 格林威治时间 let offset = curTime.getTimezoneOffset(); // 格林威治时间和本地时间之间的时差(分) - let localTime = new Date(curTime.getTime() - offset * 60 * 1000 + 8 * 60 * 60 * 1000); // 中国时间 + let localTime = new Date(curTime.getTime() + offset * 60 * 1000 + 8 * 60 * 60 * 1000); // 中国时间 localTime.setUTCHours(hour, 0, 0, 0); // 中国的几点 - return localTime.getTime() + offset * 60 * 1000 - 8 * 60 * 60 * 1000; // 回到格林威治时间 + return localTime.getTime() - offset * 60 * 1000 - 8 * 60 * 60 * 1000; // 回到格林威治时间 } \ No newline at end of file