diff --git a/game-server/app/servers/role/handler/mailHandler.ts b/game-server/app/servers/role/handler/mailHandler.ts index d19561a3d..e811fbb19 100644 --- a/game-server/app/servers/role/handler/mailHandler.ts +++ b/game-server/app/servers/role/handler/mailHandler.ts @@ -5,10 +5,14 @@ import { resResult } from '../../../pubUtils/util'; import { STATUS } from '../../../consts/statusCode'; import { MAIL_STATUS, MAIL_TEM_TYPE, GM_MAIL_TYPE } from '../../../consts/constModules/mailConst'; import { addItems } from '../../../services/rewardService'; -import { getMails } from '../../../services/mailService'; +import { checkMailGoods, getMails } from '../../../services/mailService'; import { ServerMailModel, ServerMailType } from '../../../db/ServerMail'; import { MailParam } from '../../../domain/roleField/mail'; -import { RewardInter } from '../../../pubUtils/interface'; +import { ItemInter, RewardInter } from '../../../pubUtils/interface'; +import { RoleModel } from '../../../db/Role'; +import { gameData } from '../../../pubUtils/data'; +import { ITID, RECEIVE_MAIL_TYPE } from '../../../consts'; +import { BAG } from '../../../pubUtils/dicParam'; export default function(app: Application) { return new MailHandler(app); @@ -80,46 +84,68 @@ export class MailHandler { } } - public async getMailRewards(msg: { id: string, mailType: number, type: number }, session: BackendSession) { + public async getMailRewards(msg: { id: string, mailType: number, type: RECEIVE_MAIL_TYPE }, session: BackendSession) { let roleId: string = session.get('roleId'); let roleName: string = session.get('roleName'); let sid: string = session.get('sid'); let serverId: number = session.get('serverId'); let { id, type, mailType } = msg; - let mails: MailParam[] = []; - if (type == 1) {//单个领取 + let { equipCount } = await RoleModel.findByRoleId(roleId, 'equipCount'); + + let originMails: {mailType: GM_MAIL_TYPE, mail: MailType|GroupMailType|ServerMailType}[] = [] + + if (type == RECEIVE_MAIL_TYPE.SINGLE) {//单个领取 let mail: MailType|GroupMailType|ServerMailType; if (mailType == GM_MAIL_TYPE.SINGLE) { - mail = await MailModel.updateStatusWithCondition(id, MAIL_STATUS.RECEIVED, [MAIL_STATUS.READ, MAIL_STATUS.CREATE]); + mail = await MailModel.getMailById(id); } else if (mailType == GM_MAIL_TYPE.GROUP) { - mail = await GroupMailModel.updateStatusWithCondition(id, roleId, MAIL_STATUS.RECEIVED, [MAIL_STATUS.READ, MAIL_STATUS.CREATE]); + mail = await GroupMailModel.getMailById(id); } else if (mailType == GM_MAIL_TYPE.SERVER) { - mail = await ServerMailModel.updateStatusWithCondition(id, roleId, MAIL_STATUS.RECEIVED, [MAIL_STATUS.READ, MAIL_STATUS.CREATE]); + mail = await ServerMailModel.getMailById(id); } if (!mail) return resResult(STATUS.WRONG_PARMS); - mails.push(new MailParam(mailType, mail, roleId)); + originMails.push({ mailType, mail }); } else {//一键领取 let singlemails = await MailModel.findRewardsMails(roleId); let groupMails = await GroupMailModel.findRewardsMails(roleId); let servermails = await ServerMailModel.findRewardsMails(serverId, roleId); + [ + { mails: singlemails, mailType: GM_MAIL_TYPE.SINGLE }, + { mails: groupMails, mailType: GM_MAIL_TYPE.GROUP }, + { mails: servermails, mailType: GM_MAIL_TYPE.SERVER }, + ].forEach(({ mails, mailType }) => { + mails.forEach((mail: MailType|GroupMailType|ServerMailType) => { + originMails.push({ mailType, mail }) + }); + }); + } - for(let mail of singlemails) { + let mailGoods: ItemInter[] = [], mails: MailParam[] = []; + for(let { mail, mailType } of originMails) { + let { isEquipOver, equipCount: newEquipCount } = checkMailGoods(mail, equipCount); + if(isEquipOver) { + if(type == RECEIVE_MAIL_TYPE.SINGLE) { + return resResult(STATUS.EQUIP_IS_OVER); + } else { + continue; // 如果有装备数量超过,那么一键领取这条邮件就不领了 + } + } + equipCount = newEquipCount; + + if(mailType == GM_MAIL_TYPE.SINGLE) { mail = await MailModel.updateStatusWithCondition(mail._id, MAIL_STATUS.RECEIVED, [MAIL_STATUS.READ, MAIL_STATUS.CREATE]); - if(mail) mails.push(new MailParam(GM_MAIL_TYPE.SINGLE, mail, roleId)); - } - for(let mail of groupMails) { - mail = await GroupMailModel.updateStatusWithCondition(mail._id, roleId, MAIL_STATUS.RECEIVED, [MAIL_STATUS.READ, MAIL_STATUS.CREATE]); - if(mail) mails.push(new MailParam(GM_MAIL_TYPE.GROUP, mail, roleId)); - } - for(let mail of servermails) { + } else if (mailType == GM_MAIL_TYPE.GROUP) { + mail = await GroupMailModel.updateStatusWithCondition(mail._id, roleId, MAIL_STATUS.RECEIVED, [MAIL_STATUS.READ, MAIL_STATUS.CREATE]); + } else if (mailType == GM_MAIL_TYPE.SERVER) { mail = await ServerMailModel.updateStatusWithCondition(mail._id, roleId, MAIL_STATUS.RECEIVED, [MAIL_STATUS.READ, MAIL_STATUS.CREATE]); - if(mail) mails.push(new MailParam(GM_MAIL_TYPE.SERVER, mail, roleId)); - } - } - let mailGoods: RewardInter[] = []; - for(let mail of mails) { - mailGoods.push(...mail.goods) + } + if(!mail) return resResult(STATUS.MAIL_HAS_RECEIVE); + + let mailObj = new MailParam(mailType, mail, roleId); + mailGoods.push(...mailObj.goods); + mails.push(mailObj); } + let resGoods = await addItems(roleId, roleName, sid, mailGoods); return resResult(STATUS.SUCCESS, { mails, goods: resGoods }); diff --git a/game-server/app/services/mailService.ts b/game-server/app/services/mailService.ts index 47741e700..efa43583c 100644 --- a/game-server/app/services/mailService.ts +++ b/game-server/app/services/mailService.ts @@ -8,11 +8,12 @@ import { gameData } from "../pubUtils/data"; import { nowSeconds } from '../pubUtils/timeUtil'; import { STATUS } from '../consts/statusCode'; import { resResult } from '../pubUtils/util'; -import { GM_MAIL_TYPE, MAIL_STATUS, MAIL_TYPE, SEND_NAME } from "../consts"; +import { GM_MAIL_TYPE, ITID, MAIL_STATUS, MAIL_TYPE, SEND_NAME } from "../consts"; import { MailParam } from '../domain/roleField/mail'; import { GMMailType, GMMailModel } from "../db/GMMail"; import { getGuildChannelSid, getWorldChannelSid } from "./chatChannelService"; import { GMMailRecordModel } from "../db/GMMailRecord"; +import { BAG } from "../pubUtils/dicParam"; /** * 获取邮件信息 @@ -225,4 +226,22 @@ export class SendMailFun { await GMMailRecordModel.createRecord(GM_MAIL_TYPE.SERVER, mail, createUid); } } +} + +export function checkMailGoods(mail: MailType | GroupMailType | ServerMailType, equipCount: number) { + let isEquipOver = false; + for (let good of mail.goods) { + let dicGoods = gameData.goods.get(good.id); + let dicItid = ITID.get(dicGoods.itid); + if (dicItid.table == 'equip') { // 装备 + if (++equipCount > BAG.BAG_EQUIP_UPLIMITED) { + isEquipOver = true; + break; + } + } + } + + return { + isEquipOver, equipCount + } } \ No newline at end of file diff --git a/game-server/app/services/rewardService.ts b/game-server/app/services/rewardService.ts index ab2802624..69a44b664 100644 --- a/game-server/app/services/rewardService.ts +++ b/game-server/app/services/rewardService.ts @@ -1,16 +1,16 @@ -import { ITID, CONSUME_TYPE, getCurNameById, ITEM_TABLE, HERO_SYSTEM_TYPE, CURRENCY_BY_TYPE, FIGURE_UNLOCK_CONDITION, REDIS_KEY, TASK_TYPE, CURRENCY, CURRENCY_TYPE, MAIL_TYPE } from './../consts'; +import { ITID, CONSUME_TYPE, ITEM_TABLE, REDIS_KEY, TASK_TYPE, CURRENCY, CURRENCY_TYPE, MAIL_TYPE, HANDLE_REWARD_TYPE } from './../consts'; import { EquipModel } from './../db/Equip'; import { resResult } from '../pubUtils/util'; import { RoleModel, RoleType } from '../db/Role'; import { setAp } from './actionPointService'; -import { calAllHeroCe, pushCalPlayerCe, pushCalAllHeroCe } from './playerCeService'; +import { pushCalPlayerCe, pushCalAllHeroCe } from './playerCeService'; import { ItemModel } from '../db/Item'; import { STATUS } from '../consts/statusCode'; import { pinus } from 'pinus'; import { addEquips, addBags, addSkin, addFigure, unlockFigure as pubUnlockFigure, createHeroes as pubCreateHeroes, transPiece } from '../pubUtils/itemUtils'; import { ItemInter, RewardInter, } from '../pubUtils/interface'; import { gameData } from '../pubUtils/data'; -import { uniq, indexOf, findIndex } from 'underscore'; +import { uniq } from 'underscore'; import { HeroModel, HeroType } from '../db/Hero'; import { Figure } from '../domain/dbGeneral'; import { Rank } from './rankService'; @@ -24,7 +24,7 @@ import { sendMailByContent } from './mailService'; export async function handleCost(roleId: string, sid: string, goods: Array) { let uids = [{ uid: roleId, sid }]; - let { items, equips, gold, coin } = sortItems(goods, 2); + let { items, equips, gold, coin } = sortItems(goods, HANDLE_REWARD_TYPE.COST); let equipSeqIds = equips.map(cur => cur.seqId); // 检查货币是否充足 @@ -67,24 +67,27 @@ export async function handleCost(roleId: string, sid: string, goods: Array) { let uids = [{ uid: roleId, sid }]; - let { items, equips, gold, coin, ap, skins, figures } = sortItems(goods, 1); - let showItems: { id: number, seqId?: number, count: number }[] = []; + let { items, equips, gold, coin, ap, skins, figures } = sortItems(goods, HANDLE_REWARD_TYPE.RECEIVE); + let showItems: { id: number, seqId?: number, count: number, isBag?: boolean }[] = []; let role = await RoleModel.findByRoleId(roleId); // 1. 装备处理 if(equips.length > 0) { let { equipCount = 0 } = role; let incEquips = equips, mailEquips: { id?: number, hid?: number, seqId?: number }[] = []; if(equips.length + equipCount > BAG.BAG_EQUIP_UPLIMITED) { // 装备上限 - equips.reverse(); - mailEquips = equips.slice(0, equipCount + equips.length - BAG.BAG_EQUIP_UPLIMITED); - incEquips = equips.slice(equipCount + equips.length - BAG.BAG_EQUIP_UPLIMITED); - mailEquips.reverse(); incEquips.reverse(); + let inc = BAG.BAG_EQUIP_UPLIMITED - equipCount; + if(inc < 0) inc = 0; + incEquips = equips.slice(0, inc); + mailEquips = equips.slice(inc); } // 直接加的 let { equips: equipInfos, pushMessages } = await addEquips(roleId, roleName, <{id: number, hid?: number}[]>incEquips); for (let equip of equipInfos) { - showItems.push({ seqId: equip.seqId, id: equip.id, count: 1 }); + showItems.push({ seqId: equip.seqId, id: equip.id, count: 1, isBag: true }); + } + for(let equip of combineEquips(mailEquips)) { + showItems.push({ id: equip.id, count: equip.count, isBag: false }); } //装备推送 if (!!equipInfos.length) @@ -182,7 +185,7 @@ function combineEquips(equips: { id?: number }[]) { return result; } -function sortItems(goods: ItemInter[], handleType: 1|2) { +function sortItems(goods: ItemInter[], handleType: HANDLE_REWARD_TYPE) { let items: { id: number, count: number }[] = []; // 可叠加道具 let equips: { seqId?: number, id?: number, hid?: number }[] = []; // 不可叠加装备 let gold: { count: number, isPay: boolean }[] = []; // 金币 @@ -204,7 +207,7 @@ function sortItems(goods: ItemInter[], handleType: 1|2) { } let { type, table, isCurrency } = dicItid; if(table == ITEM_TABLE.EQUIP) { // 装备 - if(handleType == 1) { + if(handleType == HANDLE_REWARD_TYPE.RECEIVE) { for(let i = 0; i < good.count; i++) { equips.push({ id: good.id, hid: good.hid }) } @@ -221,7 +224,7 @@ function sortItems(goods: ItemInter[], handleType: 1|2) { items.push({ id: good.id, count: good.count }); } } else if (table == ITEM_TABLE.SKIN) { // 皮肤,不可重复获得,不可删 - if(handleType == 1) { + if(handleType == HANDLE_REWARD_TYPE.RECEIVE) { let index = skins.indexOf(good.id); if (index == -1) { skins.push(good.id); diff --git a/shared/consts/constModules/sysConst.ts b/shared/consts/constModules/sysConst.ts index 44284f366..98918fac7 100644 --- a/shared/consts/constModules/sysConst.ts +++ b/shared/consts/constModules/sysConst.ts @@ -692,4 +692,16 @@ export enum SERVER_STATUS { export enum WHITE_LIST_TYPE { IP = 1, // ip地址 TEL = 2, // 玩家手机号 +} + +// 获取道具类型 +export enum HANDLE_REWARD_TYPE { + RECEIVE = 1, // 获取 + COST = 2 // 消耗 +} + +// 领取邮件类型 +export enum RECEIVE_MAIL_TYPE { + SINGLE = 1, // 领取单个 + ALL = 2, // 一件领取 } \ No newline at end of file diff --git a/shared/consts/statusCode.ts b/shared/consts/statusCode.ts index 9867d0673..b2a788326 100644 --- a/shared/consts/statusCode.ts +++ b/shared/consts/statusCode.ts @@ -340,12 +340,14 @@ export const STATUS = { GACHA_TURNTABLE_POINT_NOT_ENOUGH: { code: 31105, simStr: '转盘积分不足' }, GACHA_HAS_VISITED: { code: 31106, simStr: '该武将已拜访过' }, GACHA_VISITED_COUNT_OVER: { code: 31107, simStr: '今天武将拜访已超过次数' }, - // 礼包码 31201-31300 GIFT_CODE_USED_NUM_MAX: { code: 31201, simStr: '礼包码使用次数超过' }, YOU_HAVE_USED_THIS_CODE: { code: 31202, simStr: '您已使用过该码' }, GIFT_CODE_NOT_START: { code: 31203, simStr: '礼包码未生效' }, GIFT_CODE_HAS_EXPIRED: { code: 31204, simStr: '礼包码已失效' }, + // 邮件相关 31301-31400 + MAIL_HAS_RECEIVE: { code: 31301, simStr: '邮件已领取'}, + EQUIP_IS_OVER: { code: 31302, simStr: '装备已超过上限,无法领取' }, // 社交相关状态 40000 - 49999 SYS_CHANNEL_AUTH_NOT_ENOUGH: { code: 40000, simStr: '无法在系统频道发送消息' }, diff --git a/shared/db/Item.ts b/shared/db/Item.ts index a122a103d..34824a250 100644 --- a/shared/db/Item.ts +++ b/shared/db/Item.ts @@ -1,6 +1,7 @@ import BaseModel from './BaseModel'; import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose'; import { findIndex } from 'underscore'; +import { BAG } from '../pubUtils/dicParam'; // const Transaction = require("mongoose-transactions"); @index({ roleId: 1, id: 1 }) @index({ seqId: 1 }) @@ -43,10 +44,13 @@ export default class Item extends BaseModel { return items; } - public static async increaseItem(roleId: string, id: number, count: number, itemInfo: { roleId: string, roleName: string, id: number, itemName: string, type: number, hid?: number }, lean = true) { + public static async increaseItem(roleId: string, id: number, count: number, itemInfo: { roleId: string, roleName: string, id: number, itemName: string, type: number, hid?: number }) { const doc = new ItemModel(); const setOnInsert = Object.assign(doc.toJSON(), itemInfo); - const items: ItemType = await ItemModel.findOneAndUpdate({ roleId, id }, { $setOnInsert: setOnInsert, $inc: { count } }, { new: true, upsert: true }).lean(lean); + let items: ItemType = await ItemModel.findOneAndUpdate({ roleId, id }, { $setOnInsert: setOnInsert, $inc: { count } }, { new: true, upsert: true }).lean(); + if(items.count > BAG.BAG_GOODS_UPLIMITED) { + items = await ItemModel.findOneAndUpdate({ roleId, id, count: { $gte: BAG.BAG_GOODS_UPLIMITED } }, { $set: { count: BAG.BAG_GOODS_UPLIMITED } }, { new: true }).lean(); + } return items; } diff --git a/shared/db/ServerMail.ts b/shared/db/ServerMail.ts index 4f8223e95..027d0eae4 100644 --- a/shared/db/ServerMail.ts +++ b/shared/db/ServerMail.ts @@ -38,6 +38,11 @@ export default class ServerMail extends MailTemp { return result; } + public static async getMailById(_id: string, lean = true) { + const result: ServerMailType = await ServerMailModel.findOne({ _id }).lean(lean); + return result; + } + /** * @description 创建邮件 * @param params