Files
ZYZ/game-server/app/services/mailService.ts
2022-02-23 20:02:10 +08:00

318 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { RewardInter, pushMail, mailData } from "../pubUtils/interface";
import { MailModel, MailType } from "../db/Mail";
import { GroupMailModel, GroupMailType } from "../db/GroupMail";
import { ServerMailModel, ServerMailType } from '../db/ServerMail';
import { getRoleOnlineInfo } from "./redisService";
import { pinus } from "pinus";
import { gameData } from "../pubUtils/data";
import { nowSeconds } from '../pubUtils/timeUtil';
import { STATUS } from '../consts/statusCode';
import { genCode, resResult } from '../pubUtils/util';
import { GM_MAIL_TYPE, ITID, MAIL_STATUS, MAIL_TIME_TYPE, MAIL_TYPE, SEND_NAME, SEND_TITLE } from "../consts";
import { MailParam } from '../domain/roleField/mail';
import { GMMailType, GMMailModel, GMMailTypeParam } from "../db/GMMail";
import { getGuildChannelSid, getWorldChannelSid } from "./chatChannelService";
import { GMMailRecordModel } from "../db/GMMailRecord";
import { BAG } from "../pubUtils/dicParam";
import { GuildModel, GuildType } from "../db/Guild";
import moment = require("moment");
/**
* 获取邮件信息
* @param {String} roleId 玩家id
* @param {Number} serverId 服务器id
*/
export async function getMails(roleId: string, serverId: number) {
let mails = await MailModel.findByRoleId(roleId)||[];
let groupMails = await GroupMailModel.findByRoleId(roleId)||[];
let serverMails = await ServerMailModel.findByRoleId(roleId, serverId)||[];
let list = getMailInfos(roleId, mails, groupMails, serverMails);
list.sort((a, b) => a.sendTime - b.sendTime);
return list;
}
/**
* 根据数据库数据,生成返回数据
* @param {String} roleId 玩家id
* @param {MailType[]} mails 单人邮件
* @param {GroupMailType[]} groupMails 多人邮件
* @param {ServerMailType[]} serverMails 全服邮件
*/
function getMailInfos(roleId: string, mails: MailType[], groupMails: GroupMailType[], serverMails: ServerMailType[]) {
let list: MailParam[] = []; // 结果
for(let mail of mails) {
list.push(new MailParam( GM_MAIL_TYPE.SINGLE, mail, roleId));
}
for(let mail of groupMails) {
list.push(new MailParam(GM_MAIL_TYPE.GROUP, mail, roleId));
}
for(let mail of serverMails) {
list.push(new MailParam(GM_MAIL_TYPE.SERVER, mail, roleId));
}
return list;
}
export async function sendMailByContent(contentId: MAIL_TYPE, hisRoleId: string, params: { sendName?: string, endTime?: number, params?: string[], goods?: RewardInter[] }) {
let f = new SendMailFun();
let code = f.setWithContentId(contentId, params);
await f.createSingleMails(code, [hisRoleId]);
await f.pushToUsers();
}
export async function sendMailToGuildByContent(contentId: MAIL_TYPE, guildCode: string, params: { sendName?: string, endTime?: number, params?: string[], goods?: RewardInter[] }, guild?: GuildType) {
if(!guild) guild = await GuildModel.findByCode(guildCode, null, '+members');
if(!guild) return false;
let f = new SendMailFun();
let code = f.setWithContentId(contentId, params);
await f.createGroupMails(code, guild.members, guildCode);
await f.pushToUsers();
return true;
}
class MailTemp {
public code: string;
public gmmail: GMMailTypeParam;
private contentId: MAIL_TYPE = MAIL_TYPE.SEND_MAIL; // 0-读GmMail1以上读dicMail
private sendName: string = SEND_NAME;
private title: string = SEND_TITLE;
private content: string = '';
private hasGoods: boolean = false; // 是否内含奖励
private goods: RewardInter[] = []; // 发送的奖励
public sendTime: number;
private endTime: number;
// 从dicMail读取数据
public setWithContentId(contentId: MAIL_TYPE, params: { sendName?: string, params?: string[], goods?: RewardInter[] }) {
this.code = genCode(8);
let dicMail = gameData.mail.get(contentId);
this.contentId = contentId;
this.sendTime = nowSeconds();
this.endTime = this.sendTime + dicMail?.time||0;
this.content = this.getContent(dicMail.content, params.params);
if(dicMail.title) this.title = dicMail.title;
if(dicMail.sendName) this.sendName = dicMail.sendName;
this.hasGoods = params.goods?.length > 0;
this.goods = params.goods||[];
}
public async setWithGmMail(gmmail: GMMailType) {
this.code = genCode(8);
this.gmmail = gmmail;
this.contentId = 0;
if(gmmail.timeType == MAIL_TIME_TYPE.IMMEDIATE) {
this.sendTime = nowSeconds();
} else if (gmmail.timeType == MAIL_TIME_TYPE.DELAY) {
this.sendTime = gmmail.startTime;
} else if (gmmail.timeType == MAIL_TIME_TYPE.CIRCLE) {
this.sendTime = moment(moment().format('YYYY-MM-DD ' + gmmail.circleHour)).unix();
}
this.endTime = this.sendTime + gmmail.expire * 60 * 60;
this.sendName = gmmail.sendName;
this.title = gmmail.title;
this.content = gmmail.content;
this.hasGoods = gmmail.hasGoods;
this.goods = gmmail.goods;
return gmmail;
}
private getContent(content: string, params: string[] = []) {
if(!content) content = '%d';
for(let p of params) {
content = content.replace(/%d/, p);
}
return content
}
public getCreateMailParams() {
return {
contentId: this.contentId,
mail: this.gmmail?._id,
sendTime: this.sendTime,
endTime: this.endTime,
goods: this.goods,
title: this.title,
sendName: this.sendName,
content: this.content,
hasGoods: this.hasGoods
}
}
}
/**
* 发送邮件方法类
*/
export class SendMailFun {
private mailTemps = new Map<string, MailTemp>();
private mails: MailType[] = [];
private groupMails: GroupMailType[] = [];
private serverMails: ServerMailType[] = [];
public getMailTemp(code: string) {
return this.mailTemps.get(code);
}
// 从dicMail读取数据
public setWithContentId(contentId: MAIL_TYPE, params: { sendName?: string, params?: string[], goods?: RewardInter[] }) {
let mailTemp = new MailTemp();
mailTemp.setWithContentId(contentId, params);
this.mailTemps.set(mailTemp.code, mailTemp);
return mailTemp.code;
}
// 从GMMail表读取数据
public async setWithGmMail(gmmail: GMMailType) {
let mailTemp = new MailTemp();
mailTemp.setWithGmMail(gmmail);
this.mailTemps.set(mailTemp.code, mailTemp);
return mailTemp.code;
}
// 生成单人邮件
public async createSingleMails(code: string, roleIds: string[]) {
let mapTemp = this.mailTemps.get(code);
if(mapTemp.sendTime < nowSeconds()) return;
for(let roleId of roleIds) {
let originMail = await MailModel.addMail({ roleId, ...mapTemp.getCreateMailParams() });
this.mails.push(originMail);
}
await GMMailModel.sendMail(mapTemp.gmmail._id, mapTemp.sendTime);
}
// 生成多人邮件
public async createGroupMails(code: string, roleIds: string[], guildCode?: string) {
let mapTemp = this.mailTemps.get(code);
if(mapTemp.sendTime < nowSeconds()) return;
let roleStatus = roleIds.map(roleId => {
return { roleId, status: MAIL_STATUS.CREATE }
})
let originMail = await GroupMailModel.addMail({ roleStatus, guildCode, ...mapTemp.getCreateMailParams() });
await GMMailModel.sendMail(mapTemp.gmmail._id, mapTemp.sendTime);
this.groupMails.push(originMail);
}
// 生成全服邮件
public async createServerMails(code: string, serverIds: number[]) {
let mapTemp = this.mailTemps.get(code);
if(mapTemp.sendTime < nowSeconds()) return;
for(let serverId of serverIds) {
let originMail = await ServerMailModel.addMail({ serverId, ...mapTemp.getCreateMailParams() });
this.serverMails.push(originMail);
}
await GMMailModel.sendMail(mapTemp.gmmail._id, mapTemp.sendTime);
}
public async setMails(mails: MailType[], groupMails: GroupMailType[], serverMails: ServerMailType[]) {
this.mails.push(...mails);
this.groupMails.push(...groupMails);
this.serverMails.push(...serverMails);
}
// 将存储的邮件发出
public async pushToUsers(myRoleId?: string, mySid?: string) {
// 将可以发的邮件发出
let pushByRoleId = new Map<string, MailParam[]>();
let pushByGuildCode = new Map<string, MailParam[]>();
let pushByServerId = new Map<number, MailParam[]>();
for(let mail of this.mails) {
if(mail.sendTime <= nowSeconds() && mail.endTime > nowSeconds()) {
let mailParam = new MailParam(GM_MAIL_TYPE.SINGLE, mail);
if(!pushByRoleId.has(mail.roleId)) pushByRoleId.set(mail.roleId, []);
pushByRoleId.get(mail.roleId).push(mailParam);
}
}
for(let mail of this.groupMails) {
if(mail.sendTime <= nowSeconds() && mail.endTime > nowSeconds()) {
let mailParam = new MailParam(GM_MAIL_TYPE.GROUP, mail);
if(!!mail.guildCode) {
if(!pushByGuildCode.has(mail.guildCode)) pushByGuildCode.set(mail.guildCode, []);
pushByGuildCode.get(mail.guildCode).push(mailParam);
} else {
for(let { roleId } of mail.roleStatus) {
if(!pushByRoleId.has(roleId)) pushByRoleId.set(roleId, []);
pushByRoleId.get(roleId).push(mailParam);
}
}
}
}
for(let mail of this.serverMails) {
if(mail.sendTime <= nowSeconds() && mail.endTime > nowSeconds()) {
let mailParam = new MailParam(GM_MAIL_TYPE.SERVER, mail);
if(!pushByServerId.has(mail.serverId)) pushByServerId.set(mail.serverId, []);
pushByServerId.get(mail.serverId).push(mailParam);
}
}
for(let [roleId, mails ] of pushByRoleId) {
let uids = await this.getUids(roleId, myRoleId, mySid);
if(uids.length > 0 && mails.length > 0) {
pinus.app.channelService.pushMessageByUids('onMailsAdd', resResult(STATUS.SUCCESS, { mails }), uids);
}
}
for(let [guildCode, mails] of pushByGuildCode) {
let chatSid = await getGuildChannelSid(guildCode);
if(!!chatSid && mails.length > 0) {
pinus.app.rpc.chat.guildRemote.sendMailToGuild.toServer(chatSid, guildCode, 'onMailsAdd', { mails });
}
}
for(let [serverId, mails] of pushByServerId) {
let chatSid = await getWorldChannelSid(serverId);
if(!!chatSid && mails.length > 0) {
pinus.app.rpc.chat.chatRemote.sendMail.toServer(chatSid, serverId, 'onMailsAdd', { mails });
}
}
// 延时邮件,设置定时器
pinus.app.rpc.systimer.systimerRemote.addMailsToSchedule.broadcast(this.mails, this.groupMails, this.serverMails);
}
private async getUids(roleId: string, myRoleId?: string, mySid?: string) {
let uids: { uid: string, sid: string }[] = [];
let sid = '';
if(roleId == myRoleId) {
sid = mySid;
} else {
let hisOnlineInfo = await getRoleOnlineInfo(roleId);
if(hisOnlineInfo.isOnline) {
sid = hisOnlineInfo.sid;
}
}
if(!!sid) {
uids.push({ uid: roleId, sid });
}
return uids;
}
public async saveRecord(createUid: number) {
for(let mail of this.mails) {
await GMMailRecordModel.createRecord(GM_MAIL_TYPE.SINGLE, mail, createUid);
}
for(let mail of this.groupMails) {
await GMMailRecordModel.createRecord(GM_MAIL_TYPE.GROUP, mail, createUid);
}
for(let mail of this.serverMails) {
await GMMailRecordModel.createRecord(GM_MAIL_TYPE.SERVER, mail, createUid);
}
}
}
export function checkMailGoods(mail: MailType | GroupMailType | ServerMailType, jewelCount: 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 == 'jewel') { // 装备
if (++jewelCount > BAG.BAG_EQUIP_UPLIMITED) {
isEquipOver = true;
break;
}
}
}
return {
isEquipOver, jewelCount
}
}