邮件,pvp赛季结算,boss关卡注释

This commit is contained in:
mamengke01
2021-02-23 20:28:58 +08:00
parent 6759a7dcb1
commit 33fb6689f7
16 changed files with 219 additions and 107 deletions

View File

@@ -15,6 +15,7 @@ Filter.prototype.before = function (routeRecord: RouteRecord, msg: any, session:
};
Filter.prototype.after = function (err: Error, routeRecord: RouteRecord, msg: any, session: FrontendOrBackendSession, resp: any, next: HandlerCallback) {
//刷新
refresh(session);
return checkEvent(session).then(()=>{
next(err);

View File

@@ -4,7 +4,7 @@ import { STATUS } from '../../../consts';
import { BossInstanceModel } from '../../../db/BossInstance';
import { BattleRecordModel } from '../../../db/BattleRecord';
import { nowSeconds, getTodayZeroPoint } from '../../../pubUtils/timeUtil';
import { getBossInstanceInfo, bossResult, checkMemberExists, pushBossHpMessage, getBossInstanceWhenEnd, addBossInstance } from '../../../services/guildBossService';
import { getBossInstanceInfo, bossResult, checkBossBattleMemberExists, pushBossHpMessage, getBossInstanceWhenEnd, addBossInstance } from '../../../services/guildBossService';
import { findWhere } from 'underscore'
import { GUILD_STRUCTURE, GUILD_BOSS_STATUS, GUILD_POINT_WAYS } from '../../../consts/constModules/guildConst';
import { DATA_NAME } from '../../../consts/dataName';
@@ -142,7 +142,7 @@ export class GuildHandler {
if (!userGuild)
return resResult(STATUS.WRONG_PARMS);
const { guildCode: code } = userGuild;
let flag = await checkMemberExists(code, serverId, roleId, battleCode);
let flag = await checkBossBattleMemberExists(code, serverId, roleId, battleCode);
if (!flag) {
return resResult(STATUS.REDLOCK_ERR);
}
@@ -177,7 +177,7 @@ export class GuildHandler {
}, true);
let bossInstance = await BossInstanceModel.findBossInstance(code);
let result = await getBossInstanceWhenEnd(bossInstance, roleId, battleRecord.record.recordNum);
await addActive(roleId, serverId, GUILD_POINT_WAYS.BOSS_WAR);
await addActive(roleId, serverId, GUILD_POINT_WAYS.BOSS_WAR);//获得活跃值
return resResult(STATUS.SUCCESS, result);
}

View File

@@ -105,14 +105,14 @@ export class PvpHandler {
let flag = false;
if (!!pvpSeasonResult) {
var { oldSeasonData, show, heroGoods, rankGoods} = pvpSeasonResult;
if ( oldSeasonData.seasonEndTime > nowSeconds()) {//结算中锁定玩家信息
if ( oldSeasonData.seasonEndTime > nowSeconds()) {//结算中锁定玩家信息,结算结束后统一展示修改完成的信息
seasonEndTime = oldSeasonData.seasonEndTime;
heroScores = oldSeasonData.heroScores;
score = oldSeasonData.score;
refOppCnt = oldSeasonData.refOppCnt;
challengeCnt = oldSeasonData.challengeCnt;
challengeRefTime = oldSeasonData.challengeRefTime;
} else if (show) {
} else if (show) {//是否需要弹出结算奖励界面
await PvpSeasonResultModel.updatePvpSeasonResult(roleId, {show: false});
flag = true;
}
@@ -124,7 +124,7 @@ export class PvpHandler {
let {actorId, dataId, order} = cur;
return { actorId, dataId, order }
}), score, pLv, winStreakNum, refOppCnt, challengeCnt, challengeRefTime, receivedBox, hisScore, heroScores, isFirstEntry, isDefaultHero }
if (flag) {//是否弹出结算奖励
if (flag) {//弹出结赛季结算奖励
data.resultRecord = { oldSeasonData, heroGoods, rankGoods }
}
return resResult(STATUS.SUCCESS, data);

View File

@@ -74,16 +74,16 @@ export class WishPoolHandler {
len++;
});
if (len >= ARMY.ARMY_WISH_TIMES) //今日已经许愿过
return resResult(STATUS.WRONG_PARMS);
return resResult(STATUS.HAS_REACH_WISH_COUNT_LIMIT);
if (type == 1) {
let wishGoodsEquip = findWhere(wishGoodsEquips, { quality: goodInfo.quality});
if (!wishGoodsEquip)
return resResult(STATUS.WRONG_PARMS);
return resResult(STATUS.NOT_WISH_THE_QUALITY_GOODS);
count = wishGoodsEquip.count;
} else {
let wishGoodsHero = findWhere(wishGoodsHeros, { quality: goodInfo.quality});
if (!wishGoodsHero)
return resResult(STATUS.WRONG_PARMS);
return resResult(STATUS.NOT_WISH_THE_QUALITY_GOODS);
count = wishGoodsHero.count;
}
const id = genCode(6);
@@ -111,7 +111,7 @@ export class WishPoolHandler {
if (dntRoleGuild.guildCode != code)
return resResult(STATUS.WRONG_PARMS);
if (dntRoleGuild.wishDntCnt >= ARMY.ARMY_WISH_HELP)
return resResult(STATUS.HAS_REACH_WISH_COUNT_LIMIT);
return resResult(STATUS.HAS_REACH_WISH_DONATE_COUNT_LIMIT);
let wishGood = findWhere(wishGoods, { id });
if (!wishGood)
return resResult(STATUS.WRONG_PARMS);//没有该许愿
@@ -121,7 +121,7 @@ export class WishPoolHandler {
let { wishGoods: resWishGoods } = await UserGuildModel.donateUpdate(wishRoleId, dntRoleName, id, 'wishGoods');
let key = 'login_roleId_' + wishRoleId;
let sid = await getRedis(key);
let goods = await addItems(wishRoleId, role.roleName , sid , [{ id : wishGood.goodId, count: 1 }]);
await addItems(wishRoleId, role.roleName , sid , [{ id : wishGood.goodId, count: 1 }]);
if (!!sid) {
this.app.channelService.pushMessageByUids('onWishGoodsRecive', resResult(STATUS.SUCCESS, { wishGoods: resWishGoods }), [{uid:wishRoleId, sid}]);
}

View File

@@ -77,11 +77,11 @@ export class GmHandler {
}]);
return resResult(STATUS.SUCCESS, { msg: content });
}
//对接gm后台下发邮件
async addMail(msg: { endTime: number, serverId: number, sendName: string, content: string, goods, sendRoles:[{roleId: string, status: number}], gmMailType: number, sendTime: number }) {
let {sendRoles, endTime, content, sendName, gmMailType, sendTime, goods, serverId} = msg;
let mail = await GMMailModel.addMail({serverId, sendRoles, sendName, endTime, content, gmMailType, sendTime, goods});
setGmMails([mail]);
this.app.rpc.role.roleRemote.sendGmMailsToRoles.toServer('role-server-1',[mail]);
setGmMails([mail]);//更新邮件缓存
this.app.rpc.role.roleRemote.sendGmMailsToRoles.toServer('role-server-1',[mail]);//检查是否是群体邮件并下发群体邮件非群体邮件通过Filter刷新下发
}
}

View File

@@ -104,19 +104,26 @@ export class GMRemote {
public refreshGmMails(mails:[any]) {
setGmMails(mails);
}
/**
* 获得邮件详情信息
* @param roleId
* @param serverId
* @param mails
* @param groupMails
*/
public getMailInfos(roleId: string, serverId: number, mails: [any], groupMails: [any]) {
let list: mailData[] = [];
let nowTime = nowSeconds();
//单个邮件
mails.map(function({ mailId, goods, sendTime, params, status, _id, mailTemType, sendName, endTime}) {
if (mailTemType == MAIL_TEM_TYPE.GAMEMAIL) { //模板邮件
if (mailTemType == MAIL_TEM_TYPE.GAMEMAIL) { //gm邮件检查是否超时并获得gm邮件的contentsendName endTime sendTime goods等信息
if (endTime < nowTime)
return;
let { content } = getContent(parseInt(mailId), params);
if (!content)
return;
list.push({ id: _id, goods, sendTime, endTime, content, status, mailType: MAIL_TYPE.SINGLEMAIL, sendName });
} else if (mailTemType == MAIL_TEM_TYPE.GMTYPE) { //系统邮件
} else if (mailTemType == MAIL_TEM_TYPE.GMTYPE) { //系统邮件
let gmMail = getGmMailById(mailId, serverId, nowTime);
if (!gmMail)
return;
@@ -124,16 +131,17 @@ export class GMRemote {
list.push({ id: _id, goods, sendTime, endTime, content, status, mailType: MAIL_TYPE.SINGLEMAIL, sendName });
}
});
//群体邮件
groupMails.map(function({ mailId, goods, sendTime, endTime, params, sendRoles, _id, mailTemType, sendName }) {
let { status } = findWhere(sendRoles, {roleId});
if (mailTemType == MAIL_TEM_TYPE.GAMEMAIL) { //模板邮件
if (mailTemType == MAIL_TEM_TYPE.GAMEMAIL) { //gm邮件检查是否超时并获得gm邮件的contentsendName endTime sendTime goods等信息
if (endTime < nowTime)
return;
let { content } = getContent( parseInt(mailId), params);
if (!content)
return;
list.push({ id: _id, goods, sendTime, content, endTime, status, mailType: MAIL_TYPE.GROUPMAIL, sendName });
} else if (mailTemType == MAIL_TEM_TYPE.GMTYPE) { //系统邮件
} else if (mailTemType == MAIL_TEM_TYPE.GMTYPE) { //系统邮件
let gmMail = getGmMailById(mailId, serverId, nowTime);
if (!gmMail)
return;
@@ -143,11 +151,21 @@ export class GMRemote {
});
return list;
}
public getMails(updatedMailAt: number, serverId: number) {
/**
* 获得据上次刷新后,可以加入的邮件
* @param updatedMailAt
* @param serverId
*/
public getMailsByTime(updatedMailAt: number, serverId: number) {
let gmMails = getGmMails(updatedMailAt, serverId);
return gmMails;
}
/**
* 获得可以领取的邮件奖
* @param serverId
* @param groupMailRewards
* @param mailRewards
*/
public getUseMails(serverId: number, groupMailRewards: GroupMailType[], mailRewards: MailType[]) {
let nowTime = nowSeconds();
let mailGoods = [];
@@ -155,14 +173,14 @@ export class GMRemote {
let mailIds = [];
let groupMailIds = [];
groupMailRewards.map(({_id, goods, mailId, mailTemType})=>{
if (mailTemType == MAIL_TEM_TYPE.GMTYPE) {
if (mailTemType == MAIL_TEM_TYPE.GMTYPE) {//gm邮件检查是否有奖励以及是否可以领取
let gmMail = getGmMailById(mailId, serverId, nowTime);
if (!gmMail || !gmMail.goods.length|| gmMail.endTime < nowSeconds()) {
return;
}
mailGoods.push(...gmMail.goods);
} else {
if (!goods.length)
if (!goods.length)//系统邮件,检查是否有奖励
return;
mailGoods.push(...goods);
}
@@ -170,14 +188,14 @@ export class GMRemote {
groupMailIds.push(_id);
});
mailRewards.map(({_id, goods, mailId, mailTemType})=>{
if (mailTemType == MAIL_TEM_TYPE.GMTYPE) {
if (mailTemType == MAIL_TEM_TYPE.GMTYPE) {//gm邮件检查是否有奖励以及是否可以领取
let gmMail = getGmMailById(mailId, serverId, nowTime);
if (!gmMail || !gmMail.goods.length|| gmMail.endTime < nowSeconds()) {
return;
}
mailGoods.push(...gmMail.goods);
} else {
if (!goods.length)
if (!goods.length)//系统邮件,检查是否有奖励
return;
mailGoods.push(...goods);
}
@@ -187,7 +205,7 @@ export class GMRemote {
return {mailIds, groupMailIds, mails, mailGoods};
}
/**
*
* 通过模板mailId获得gm邮件
* @param mailId
* @param serverId
* @param nowTime

View File

@@ -10,10 +10,10 @@ import { mongoose } from '@typegoose/typegoose';
const { ObjectId } = mongoose.Types;
import { nowSeconds } from '../../../pubUtils/timeUtil';
export default function(app: Application) {
return new RoleHandler(app);
return new MailHandler(app);
}
export class RoleHandler {
export class MailHandler {
constructor(private app: Application) {
}
@@ -67,7 +67,6 @@ export class RoleHandler {
return _id;
});
await MailModel.updateMailStatus(mailIds, MAIL_STATUS.DELETE);
return resResult(STATUS.SUCCESS, { mails });
}
}

View File

@@ -14,7 +14,7 @@ import { pushMail } from '../pubUtils/interface';
import { MAIL_TYPE } from '../consts';
import { GUILD_BOSS_STATUS } from '../consts/constModules/guildConst';
/**
*
* 获得boss界面
* @param bossInstance
* @param roleId
*/
@@ -63,11 +63,11 @@ export async function getBossInstanceWhenEnd(bossInstance: BossInstanceType, rol
let { warId, ranks, bossHp, winWarId, guildCode, recordRanks, winNum, bossLv, winBossLv } = bossInstance;
let pushRanks;
let result:any = {};
if (battleNum == winNum) {
if (battleNum == winNum) { //检查当前战斗回调是否是上一次战斗的回调,若是返回上次排名的结果
pushRanks = deepCopy(recordRanks);
result = {warId: winWarId, bossHp: 0, bossLv: winBossLv, status: GUILD_BOSS_STATUS.OPEN};
await BossInstanceModel.recordRoleIdWhenCheck(guildCode, roleId);
} else {
} else {
pushRanks = deepCopy(ranks);
result = {warId, bossHp, bossLv, status: GUILD_BOSS_STATUS.OPEN};
}
@@ -114,7 +114,7 @@ export async function bossResult(code: string, serverId: number, dataName: strin
return false;
}
ranks[index].score += bossHp;
if (bossHp > damage) {
if (bossHp > damage) {//检查造成的伤害是否会让boss死亡
res.releaseCallback();//解锁
return true;
}
@@ -124,6 +124,7 @@ export async function bossResult(code: string, serverId: number, dataName: strin
recordRanks.sort(function(a, b) {
return b.score - a.score + a.time - b.time;
});
//下发邮件奖励
let mails = new Array<MailType>();
let pushMessage = new Array<pushMail>();
recordRanks.forEach(async function({ roleId }, index){
@@ -135,11 +136,14 @@ export async function bossResult(code: string, serverId: number, dataName: strin
});
await MailModel.addMails(mails);
pushMessage.forEach(({route, data, uids })=>{
pinus.app.channelService.pushMessageByUids(route, resResult(STATUS.SUCCESS, { mails:data }), uids);
pinus.app.channelService.pushMessageByUids(route, resResult(STATUS.SUCCESS, { mails: data }), uids);
});
return true;
}
/**
* 获得排名区间奖励
* @param rankLv
*/
export function getArmyBossRankReward(rankLv: number) {
let armybossRankReward = getArmyBossRank();
for (let item of armybossRankReward) {
@@ -148,7 +152,12 @@ export function getArmyBossRankReward(rankLv: number) {
}
}
}
/**
* 将玩家加入到正在挑战boss队列中
* @param code
* @param serverId
* @param roleId
*/
export async function addBossInstance(code: string, serverId:number, roleId: string) {
let loginKey = 'login_roleId_' + roleId;
let sid = await getRedis(loginKey);
@@ -156,7 +165,13 @@ export async function addBossInstance(code: string, serverId:number, roleId: str
let value = roleId+ '|' + sid;
saddAsync(key, [value]);
}
/**
* 给当前正在挑战的玩家下发血量同步信息
* @param code
* @param serverId
* @param bossHp
* @param isDelKey
*/
export async function pushBossHpMessage(code: string, serverId:number, bossHp:number, isDelKey?: boolean ) {
let key = 'serverId_' + serverId + 'guildCode_' + code;
let members = await smembersAsync(key);
@@ -171,8 +186,14 @@ export async function pushBossHpMessage(code: string, serverId:number, bossHp:nu
delAsync(key);
}
}
export async function checkMemberExists(code: string, serverId:number, roleId: string, battleCode:string ) {
/**
* 检查该玩家当前是否正在挑战boss的队列中
* @param code
* @param serverId
* @param roleId
* @param battleCode
*/
export async function checkBossBattleMemberExists(code: string, serverId:number, roleId: string, battleCode:string ) {
let loginKey = 'login_roleId_' + roleId;
let sid = await getRedis(loginKey);
let key = 'serverId_' + serverId + 'guildCode_' + code ;

View File

@@ -1,14 +1,13 @@
import { gameData, getGuildActiveWeekReward, getGuildActiveByIdAndType, getGoodById } from "../pubUtils/data";
import { GuildModel, GuildType } from "../db/Guild";
import { GuildModel } from "../db/Guild";
import { resResult, shouldRefresh } from "../pubUtils/util";
import { STATUS, MAIL_TYPE, GUILD_AUTH, GUILD_JOB, REDIS_KEY, CHAT_SERVER } from "../consts";
import { RoleModel, RoleType } from "../db/Role";
import { RoleModel } from "../db/Role";
import { UserGuildModel, UserGuildType } from "../db/UserGuild";
import { UserGuildApplyModel } from "../db/UserGuildApply";
import { SystemConfigModel } from "../db/SystemConfig";
import { nowSeconds } from "../pubUtils/timeUtil";
import { pinus } from "pinus";
import { GuildRecType } from "../db/GuildRec";
import { ARMY } from "../pubUtils/dicParam";
import { sendMail } from "./mailService";
import { setRank, getMyRank, initSingleRank } from "./redisService";

View File

@@ -11,7 +11,16 @@ import { findWhere } from "underscore";
import { MAIL_TYPE, MAIL_TEM_TYPE, GM_MAIL_TYPE, MAIL_STATUS } from "../consts/constModules/mailConst";
import { DATA_NAME } from '../consts/dataName';
import { lockData } from './redLockService';
import GMMail from "../db/GMMail";
/**
* 下发邮件
* @param operate
* @param toRoleId
* @param sendName
* @param params
* @param goods
* @param sendTime
*/
export async function sendMail(operate: number, toRoleId: string, sendName: string = '系统', params: string[] = [], goods: RewardInter[] = [], sendTime: number = nowSeconds()) {
let { content, time } = getContent(operate, params);
if (!content)
@@ -19,13 +28,17 @@ export async function sendMail(operate: number, toRoleId: string, sendName: stri
let mail = await MailModel.addMail({roleId: toRoleId, sendTime, goods, sendName, mailId: JSON.stringify(operate), endTime: time + nowSeconds(), mailTemType: MAIL_TEM_TYPE.GAMEMAIL, params});
let key = 'login_roleId_' + toRoleId;
let sid = await getRedis(key);
if (!!sid) {
if (!!sid) {//下发邮件,对应前端红点提示
pinus.app.channelService.pushMessageByUids('onMailsAdd', resResult(STATUS.SUCCESS, { mails:[{
id: mail._id, goods, sendTime: mail.sendTime, endTime: mail.endTime, content, status: mail.status, mailType: MAIL_TYPE.SINGLEMAIL, sendName
}]}), [{uid: toRoleId, sid}]);
}
}
/**
* 封装玩家的邮件内容
* @param operate
* @param params
*/
export function getContent(operate: number, params: string[]) {
let mail = gameData.mail.get(operate);
if (!mail)
@@ -37,7 +50,17 @@ export function getContent(operate: number, params: string[]) {
}
return { content, time }
}
/**
* 封装获得邮件的下发信息,以及需要添加的邮件信息
* @param roleId
* @param operate
* @param params
* @param goods
* @param mails
* @param pushMessage
* @param sendTime
* @param sendName
*/
export async function getMailContent(roleId: string, operate: number, params: string[], goods: RewardInter[], mails: MailType[], pushMessage: pushMail[], sendTime?:number, sendName: string = '系统') {
const doc = new MailModel();
let { content, time } = getContent(operate, params);
@@ -53,16 +76,22 @@ export async function getMailContent(roleId: string, operate: number, params: st
}], uids: [{ uid: roleId, sid }]});
}
}
/**
* 检查上次刷新过后至今 gm后台是否有新邮件下发给玩家
* @param roleId
* @param sid
* @param serverId
* @param updatedMailAt
*/
export async function refreshMails(roleId: string, sid: string, serverId: number, updatedMailAt: number) {
let res:any = await lockData(serverId, DATA_NAME.GAMEMAIL, roleId);//加锁
let gmMails = await pinus.app.rpc.gm.gmRemote.getMails.toServer('gm-server-1', updatedMailAt, serverId);
let gmMails = await pinus.app.rpc.gm.gmRemote.getMailsByTime.toServer('gm-server-1', updatedMailAt, serverId);
let addGroupMails: GroupMailType[] = [];
let addMails: MailType[] = [];
let updateMails: mailData[] = [];
let pushMails: mailData[] = [];
for (let {gmMailType, id: mailId, sendRoles, endTime, content, goods, sendTime, sendName } of gmMails) {
if (gmMailType == GM_MAIL_TYPE.GROUPMAIL) { //群体邮件
for (let { gmMailType, id: mailId, sendRoles, endTime, content, goods, sendTime, sendName } of gmMails) {
if (gmMailType == GM_MAIL_TYPE.GROUPMAIL) { //检查gm群体邮件是否需要加入
let mail = await GroupMailModel.getMail(mailId, MAIL_TEM_TYPE.GMTYPE);
if (!mail) {
const doc = new GroupMailModel();
@@ -77,7 +106,7 @@ export async function refreshMails(roleId: string, sid: string, serverId: number
pushMails.push({ id: mail._id, goods, sendTime, endTime, content, status: MAIL_STATUS.CREATE, mailType: MAIL_TYPE.GROUPMAIL, sendName });
}
}
} else if (gmMailType == GM_MAIL_TYPE.SERVER) { //游戏分服邮件
} else if (gmMailType == GM_MAIL_TYPE.SERVER) { //检查gm服邮件是否需要加入
let mail = await MailModel.getMail(roleId, mailId, MAIL_TEM_TYPE.GMTYPE);
if (!mail) {
const doc = new MailModel();
@@ -85,11 +114,12 @@ export async function refreshMails(roleId: string, sid: string, serverId: number
addMails.push(mail);
pushMails.push({ id: mail._id, goods, sendTime, endTime, content, status: mail.status, mailType: MAIL_TYPE.SINGLEMAIL, sendName });
} else {
//若加入过,可能修改过奖励内容等信息,更新一下邮件的内容
updateMails.push({ id: mail._id, goods, sendTime, endTime, content, status: mail.status, mailType: MAIL_TYPE.SINGLEMAIL, sendName })
}
}
}
if (!!updateMails.length) {
if (!!updateMails.length) {//下发邮件修改推送
pinus.app.channelService.pushMessageByUids('onMailsUpdate', resResult(STATUS.SUCCESS, { mails: updateMails }), [{uid: roleId, sid}]);
}
if (!!addGroupMails.length) {
@@ -99,19 +129,26 @@ export async function refreshMails(roleId: string, sid: string, serverId: number
await MailModel.addMails(addMails);
}
if (!!pushMails.length) {
pinus.app.channelService.pushMessageByUids('onMailsAdd', resResult(STATUS.SUCCESS, { mails: pushMails}), [{uid: roleId, sid}]);
}
pinus.app.channelService.pushMessageByUids('onMailsAdd', resResult(STATUS.SUCCESS, { mails: pushMails}), [{uid: roleId, sid}]);//下发邮件,对应前端红点提示
}//下发邮件,对应前端红点提示
res.releaseCallback();
return nowSeconds();
}
/**
* 获取邮件信息gm邮件需要从gm-server-1缓存中读取
* @param roleId
* @param serverId
*/
export async function getMails(roleId: string, serverId: number) {
let mails = await MailModel.getMailsByRoleId(roleId)||[];
let groupMails = await GroupMailModel.getGroupMailsByRoleId(roleId)||[];
let list: mailData[] = await pinus.app.rpc.gm.gmRemote.getMailInfos.toServer('gm-server-1', roleId, serverId, mails, groupMails);
return list;
}
/**
* 下发gm邮件的群体邮件
* @param mails
*/
export async function sendRolesMails(mails) {
let addGroupMails: GroupMailType[] = [];
let pushMessage: pushMail[] = [];
@@ -119,7 +156,7 @@ export async function sendRolesMails(mails) {
let uids = [];
if (endTime < nowSeconds()|| sendTime > nowSeconds())
continue;
if (gmMailType != GM_MAIL_TYPE.GROUPMAIL)
if (gmMailType != GM_MAIL_TYPE.GROUPMAIL) //不是群体邮件说明是全服邮件,不进行下发
return;
let mail = await GroupMailModel.getMail(mailId, MAIL_TEM_TYPE.GMTYPE);
if (!mail) {
@@ -145,5 +182,5 @@ export async function sendRolesMails(mails) {
}
pushMessage.forEach( message=> {
pinus.app.channelService.pushMessageByUids('onMailsAdd', resResult(STATUS.SUCCESS, { mails: message.data }), message.uids);
});
});//下发邮件,对应前端红点提示
}

View File

@@ -443,11 +443,14 @@ export function getRefOppCnt(refOppCnt: number, refOppTime: Date) {
consume: gameData.pvpRefreshConsume.get(refOppCnt + 1)
}
}
/**
* 获得玩家pvp信息并检查是否在pvp赛季结算中结算过未结算的进行结算
* @param roleId
*/
export async function findPvpDefAllByRoleId(roleId: string) {
let pvpDefense = await PvpDefenseModel.findByRoleIdIncludeAll(roleId);
let { warId, seasonNum, seasonEndTime, oldSeasonEndTime } = await SystemConfigModel.findSystemConfig();
if (pvpDefense.seasonNum != seasonNum && oldSeasonEndTime < nowSeconds()) {
if (pvpDefense.seasonNum != seasonNum && oldSeasonEndTime < nowSeconds()) {//检查玩家是否在pvp赛季结算中结算过
let { score, pLv, winStreakNum, heroScores, challengeCnt, challengeRefTime } = await pinus.app.rpc.systimer.systimerRemote.setPvpDefResult.toServer('systimer-server-1', pvpDefense, seasonNum, oldSeasonEndTime);
pvpDefense.score = score;
pvpDefense.pLv = pLv;

View File

@@ -369,7 +369,7 @@ export async function resetPvpRanks() {
await client.delAsync(REDIS_KEY.PVP_RANK);
let { seasonNum } = await SystemConfigModel.findSystemConfig();
console.log('execute season resetPvpRanks seasonNum = ' + seasonNum);
let pvpRank = await PvpDefenseModel.getRank(seasonNum);
let pvpRank = await PvpDefenseModel.getRank(seasonNum);//获得全服前1000名的排名加入到redis中
for(let {roleId, role: _role, score, updatedAt } of pvpRank) {
let role = <RoleType>_role;
if (!role) {

View File

@@ -8,13 +8,13 @@ export async function refresh(session: FrontendOrBackendSession) {
const roleId = session.get('roleId');
const sid = session.get('sid');
const serverId: number = parseInt(session.get('serverId'));
let updatedMailAt: number = parseInt(session.get('updatedMailAt'));
let uids = [{uid: roleId, sid}];
let updatedMailAt: number = parseInt(session.get('updatedMailAt')); //记录上次更新gm邮件的时间
let uids = [{uid: roleId, sid}];
pinus.app.get('channelService').pushMessageByUids('onPushCurrentTime', resResult(STATUS.SUCCESS, {time: Date.now()}), uids);
let nowTime = nowSeconds();
if (!!roleId && updatedMailAt < nowTime - 5) { //保持最少5秒间隙
if (!!roleId && updatedMailAt < nowTime - 5) { //保持最少5秒间隙
session.set('updatedMailAt', nowTime);
RoleModel.updatedRoleMailAt(roleId, nowTime);
await refreshMails(roleId, sid, serverId, updatedMailAt);
await refreshMails(roleId, sid, serverId, updatedMailAt);
}
}

View File

@@ -26,44 +26,49 @@ const PER_MINUTE = 1 * 60;
var seasonJobId;
var warJobId;
var seasonEndTimeJobId;
let guildWeeklyJobId
let guildWeeklyJobId;
/**
* 服务器启动即开启定时任务结算时常是23-24点实际结算的时间点是2331分钟
*/
export async function init() {
let seasonEndTime = 0;
let systemConfig = await SystemConfigModel.findSystemConfig();
let systemConfig = await SystemConfigModel.findSystemConfig();//系统全局参数表
if (!systemConfig) {
console.log('create season seasonNum = '+ systemConfig.seasonNum);
let warIds = getPvpGkWarIds();
let warId = warIds[0];//TODO随机地图
let warId = warIds[0];
seasonEndTime = PVP.PVP_SEASON_DAYS * PER_DAY + getTodayZeroPoint();
systemConfig = await SystemConfigModel.createSystemConfig( seasonEndTime, warId );
} else {
} else {
seasonEndTime = systemConfig.seasonEndTime;
if (systemConfig.seasonEndTime - SETTLE_DIFF <= nowSeconds()) {
if (systemConfig.seasonEndTime - SETTLE_DIFF <= nowSeconds()) {//服务器启动时,检查当前时间是否大于实际结算的时间,若大于则重新开启定时任务,若小于则按照结束时间开启定时任务
seasonEndTime = PVP.PVP_SEASON_DAYS * PER_DAY + getTodayZeroPoint();
console.log('update season seasonNum = '+ systemConfig.seasonNum);
systemConfig.seasonNum++;
systemConfig.seasonNum++;//赛季值增加1
await SystemConfigModel.updateSystemConfig({ seasonEndTime, seasonNum: systemConfig.seasonNum, oldSeasonEndTime: systemConfig.seasonEndTime});
await setPvpSeasonResult({name: 'simpleJobExample' + systemConfig.seasonNum, notSetNext: true, notPush: true });
}
}
let settleTime = (seasonEndTime - SETTLE_DIFF)* PER_SECOND;
seasonJobId = scheduleJob(settleTime, setPvpSeasonResult, { name: 'setPvpSeasonResult' });
seasonJobId = scheduleJob(settleTime, setPvpSeasonResult, { name: 'setPvpSeasonResult' });//设置实际赛季结算时间
seasonEndTimeJobId = scheduleJob((seasonEndTime - PER_MINUTE)* PER_SECOND, resetPvpRanks, { name: 'resetRank' });
warJobId = scheduleJob("0 0 0 * * 3", resetPvpWarId);
console.log('execute season resetPvpRanks');
await resetPvpRanks();
seasonEndTimeJobId = scheduleJob(seasonEndTime* PER_SECOND, resetPvpRanks, { name: 'resetRank' });//由于24之后才展示结算之后的信息为保排行榜信息一致性设置实际重置排行榜的时间为12点
warJobId = scheduleJob("0 0 0 * * 1", resetPvpWarId);//每周1零点重置地图
await resetPvpRanks();//服务器重启,重置排行榜的信息
// 周功勋结算任务
guildWeeklyJobId = scheduleJob('0 0 0 * * 1', settleGuildWeekly, { name: 'settleGuildWeekly' });
}
/**
* pvp定时任务赛季结算
* @param obj
*/
export async function setPvpSeasonResult(obj:{ name:string, notSetNext?: boolean, notPush?: boolean }) {
console.log('exce setPvpSeasonResult'+ obj?.name);
let { seasonNum, seasonEndTime, oldSeasonEndTime } = await setNextPvpTime(obj?.notSetNext);
let resultMaxRank = getResultMaxRank();
let maxPage = (resultMaxRank.min + 1000) / pageNum;
let { seasonNum, seasonEndTime, oldSeasonEndTime } = await setNextPvpTime(obj?.notSetNext);//设置下个结算任务
let resultMaxRank = getResultMaxRank();//根据排行榜的奖励表获得最大排名挡位的最小值其余不在结算中结算的玩家按照最大排名挡位在登录或进入pvp时结算
let maxPage = (resultMaxRank.min + 1000) / pageNum; //保底结算玩家数量
let lastPageNum = resultMaxRank.min % pageNum;
for (let page = 0; page < maxPage + 1; page++) {
let pvpDefenses = await PvpDefenseModel.getPvpDef(pageNum, page == maxPage?lastPageNum:page);
@@ -84,42 +89,56 @@ export async function setPvpSeasonResult(obj:{ name:string, notSetNext?: boolean
}
return { seasonNum, seasonEndTime, oldSeasonEndTime};
}
/**
* pvp定时任务结算获得添加邮件信息
* @param pvpDefense
* @param seasonNum
* @param oldSeasonEndTime
* @param addMails
* @param pushMessage
*/
export async function setPvpDefResultOnTime(pvpDefense: PvpDefenseType, seasonNum: number, oldSeasonEndTime: number, addMails: Array<MailType>, pushMessage:Array<any>) {
//检查并返回排名结算以及武将功勋结算
let { score, pLv, heroScores, challengeCnt, challengeRefTime, rankGoods, heroGoods, rankLv } = await checkResult(pvpDefense, seasonNum, oldSeasonEndTime);
pvpDefense = await PvpDefenseModel.updateInfo(pvpDefense.roleId, {score, pLv, heroScores, seasonNum, challengeCnt, challengeRefTime});
//下发邮件
if (!!rankGoods.length)
await getMailContent(pvpDefense.roleId, MAIL_TYPE.PVP_RANK_REWARD, [JSON.stringify(seasonNum), JSON.stringify(rankLv)], rankGoods, addMails, pushMessage, oldSeasonEndTime);
if (!!heroGoods.length)
if (!!rankGoods.length) //排名奖励
await getMailContent(pvpDefense.roleId, MAIL_TYPE.PVP_RANK_REWARD, [JSON.stringify(seasonNum), (rankLv>1000?'999+':JSON.stringify(rankLv))], rankGoods, addMails, pushMessage, oldSeasonEndTime);
if (!!heroGoods.length) //武将功勋奖励
await getMailContent(pvpDefense.roleId, MAIL_TYPE.PVP_RESULT, [JSON.stringify(seasonNum)], heroGoods, addMails, pushMessage, oldSeasonEndTime);
return pvpDefense;
}
/**
* 检查并返回排名结算以及武将功勋结算
* @param pvpDefense
* @param seasonNum
* @param oldSeasonEndTime
* @param rankLv
*/
export async function checkResult(pvpDefense: PvpDefenseType, seasonNum: number, oldSeasonEndTime:number, rankLv?:number) {
let pvpRankRewards = getPvpRankRewards();
let pvpHeroRewards = getPvpHeroRewards();
if (!rankLv) {
rankLv = await getMyRank(REDIS_KEY.PVP_RANK, 0, pvpDefense.roleId);// 排行榜排名
rankLv = await getMyRank(REDIS_KEY.PVP_RANK, 0, pvpDefense.roleId);// 获得排行榜排名
}
let oldPLv = getLvByScore(pvpDefense.heroScores);
let oldPLv = getLvByScore(pvpDefense.heroScores);//结算前玩家的pvp等级
let { challengeCnt, challengeRefTime } = pvpDefense;
let pvpRankReward;
if (!!rankLv) {
pvpRankReward = getScore(pvpRankRewards, rankLv);
pvpRankReward = getScore(pvpRankRewards, rankLv);//获得排名挡位信息
} else {
pvpRankReward = getResultMaxRank();
pvpRankReward = getResultMaxRank();//最大排名等级挡位信息
}
let rankGoods = [];
if(pvpRankReward) {
rankGoods = pvpRankReward.reward;
rankGoods = pvpRankReward.reward;//排名奖励
}
let heroGoods = [];
let score = 0;
let oldHeroScores = deepCopy(pvpDefense.heroScores)
for (let i = 0; i < pvpDefense.heroScores.length; i++) {
let heroScore = pvpDefense.heroScores[i];
let pvpHeroReward = getScore(pvpHeroRewards, heroScore.score);
let pvpHeroReward = getScore(pvpHeroRewards, heroScore.score);//获得武将功勋奖励
if (pvpHeroReward) {
heroScore.score = pvpHeroReward.heroscore;
if (!!pvpHeroReward.reward[0]) {
@@ -136,19 +155,24 @@ export async function checkResult(pvpDefense: PvpDefenseType, seasonNum: number,
await PvpSeasonResultModel.updatePvpSeasonResult(pvpDefense.roleId, {
oldSeasonData:{refOppCnt: pvpDefense.refOppCnt, rankLv, score: pvpDefense.score, pLv: oldPLv, heroScores: oldHeroScores,
seasonNum: pvpDefense.seasonNum, challengeCnt, challengeRefTime, seasonEndTime: oldSeasonEndTime
}, heroGoods, rankGoods, show: true });
}, heroGoods, rankGoods, show: true });//结算修改玩家pvp信息
return { rankLv, score, pLv, heroScores: pvpDefense.heroScores, seasonNum, challengeCnt:PVP.PVP_CHALLENGE_COUNTS, challengeRefTime:0, oldSeasonEndTime, heroGoods:heroGoods.map(({id, count})=>{
return {id, count};
}), rankGoods};
}
/**
* 个人pvp结算结算中未结算的都按照最大排名挡位结算
* @param pvpDefense
* @param seasonNum
* @param oldSeasonEndTime
*/
export async function setPvpDefResult(pvpDefense: PvpDefenseType, seasonNum: number, oldSeasonEndTime:number) {
let role = await RoleModel.findByRoleId(pvpDefense.roleId);
if (!role) {
return;
}
let resultMaxRank = getResultMaxRank();
let rankLv = resultMaxRank.min;
let rankLv = resultMaxRank.min; //最大排名挡位结算
let {score, pLv, heroScores, challengeCnt, challengeRefTime, rankGoods, heroGoods } = await checkResult(pvpDefense, seasonNum, oldSeasonEndTime, rankLv);
pvpDefense = await PvpDefenseModel.updateInfoAndInclude(pvpDefense.roleId, {score, pLv, heroScores, seasonNum, challengeCnt, challengeRefTime});
let { roleName, lv, vLv, headHid, sHid, title , roleId } = role;
@@ -156,12 +180,14 @@ export async function setPvpDefResult(pvpDefense: PvpDefenseType, seasonNum: num
setRank(REDIS_KEY.PVP_RANK, 0, roleId, pvpDefense.score, pvpDefense.updatedAt.getTime(), params);
//下发邮件
if (!!rankGoods.length)
await sendMail(MAIL_TYPE.PVP_RANK_REWARD, roleId, '系统', [JSON.stringify(seasonNum), JSON.stringify(pLv)], rankGoods, oldSeasonEndTime);
await sendMail(MAIL_TYPE.PVP_RANK_REWARD, roleId, '系统', [JSON.stringify(seasonNum), '999+'], rankGoods, oldSeasonEndTime);
if (!!heroGoods.length)
await sendMail(MAIL_TYPE.PVP_RESULT, roleId, '系统', [JSON.stringify(seasonNum)], heroGoods, oldSeasonEndTime);
return pvpDefense;
}
/**
* 每周重置地图
*/
export async function resetPvpWarId() {
console.log('resetPvpWarId');
let systemConfig = await SystemConfigModel.findSystemConfig();
@@ -171,10 +197,13 @@ export async function resetPvpWarId() {
warIds.splice(index, 1);
}
let res = getRandomArr(warIds, 1);
let warId = res[0];//TODO随机地图
let warId = res[0];
return await SystemConfigModel.updateSystemConfig({ warId });
}
/**
* 重置下个定时结算
* @param notSetNext
*/
async function setNextPvpTime(notSetNext: boolean) {
let { seasonEndTime, seasonNum } = await SystemConfigModel.findSystemConfig();
if (!!notSetNext) {
@@ -185,7 +214,7 @@ async function setNextPvpTime(notSetNext: boolean) {
await SystemConfigModel.updateSeason(seasonEndTime, oldSeasonEndTime);
let settleTime = (seasonEndTime - SETTLE_DIFF)* PER_SECOND;
seasonJobId = scheduleJob(settleTime, setPvpSeasonResult, { name: 'setPvpSeasonResult' });
seasonEndTimeJobId = scheduleJob((seasonEndTime - PER_MINUTE)* PER_SECOND, resetPvpRanks, { name: 'resetRank' });
seasonEndTimeJobId = scheduleJob(seasonEndTime* PER_SECOND, resetPvpRanks, { name: 'resetRank' });
return { seasonEndTime, seasonNum: seasonNum + 1, oldSeasonEndTime };
}
@@ -196,7 +225,10 @@ function getScore(arr, score) {
}
}
}
/**
* debug接口
* @param hour
*/
export async function resetPvpSeasonTime(hour: number) {
if (!!seasonJobId) {
seasonJobId.cancel();
@@ -209,7 +241,7 @@ export async function resetPvpSeasonTime(hour: number) {
let systemConfig = await SystemConfigModel.findSystemConfig();
if (!systemConfig) {
let warIds = getPvpGkWarIds();
let warId = warIds[0];//TODO随机地图
let warId = warIds[0];
seasonEndTime = hour * 60 * 60 + getTodayZeroPoint();
systemConfig = await SystemConfigModel.createSystemConfig( seasonEndTime, warId );
} else {

View File

@@ -156,8 +156,10 @@ export const STATUS = {
GUILD_WISH_POOL_NOT_OWN_EQUIP: { code: 20926, simStr: '未拥有此装备或碎片,不能许愿' },
GUILD_WISH_POOL_NOT_OWN_HERO: { code: 20927, simStr: '未拥有此武将或碎片,不能许愿' },
HAS_REACH_WISH_COUNT_LIMIT: { code: 20928, simStr: '今日许愿次数已用完,不能许愿' },
HAS_RECEIVE_WISH_GOOD: { code: 20929, simStr: '玩家已经收到许愿物品' },
HAS_REACH_WISH_DONATE_COUNT_LIMIT: { code: 20929, simStr: '今日捐赠次数已用完,不能捐赠' },
HAS_RECEIVE_WISH_GOOD: { code: 20930, simStr: '玩家已经收到许愿物品' },
NOT_WISH_THE_QUALITY_GOODS: { code: 20931, simStr: '不能够许愿该品质的物品' },
GUILD_SCRIPT_IS_OPENED_TODAY: { code: 20950, simStr: '今日演武场已开启' },
GUILD_SCRIPT_NOT_OPENED: { code: 20951, simStr: '演武场未开启' },
GUILD_SCRIPT_IS_BATTLED: { code: 20952, simStr: '今日已挑战过演武场' },

View File

@@ -17,22 +17,22 @@ export default class SystemConfig extends BaseModel {
settleGuildWeeklyTime: number;
public static async findSystemConfig(lean = true) {
const result: SystemConfigType = await SystemConfigModel.findOne({ id: 1 }).lean(lean);
const result: SystemConfigType = await SystemConfigModel.findOne({}).lean(lean);
return result;
}
public static async createSystemConfig(seasonEndTime: number, warId: number, lean = true) {
const result: SystemConfigType = await SystemConfigModel.findOneAndUpdate({ id: 1}, { seasonEndTime, warId, seasonNum: 1 }, { upsert: true, new: true }).lean(lean);
const result: SystemConfigType = await SystemConfigModel.findOneAndUpdate({}, { seasonEndTime, warId, seasonNum: 1 }, { upsert: true, new: true }).lean(lean);
return result;
}
public static async updateSystemConfig(update: { seasonEndTime?: number, warId?: number, seasonNum?:number , oldSeasonEndTime?: number, settleGuildWeeklyTime?: number}, lean = true) {
const result: SystemConfigType = await SystemConfigModel.findOneAndUpdate({ id: 1}, update, { upsert: true, new: true }).lean(lean);
const result: SystemConfigType = await SystemConfigModel.findOneAndUpdate({}, update, { upsert: true, new: true }).lean(lean);
return result;
}
public static async updateSeason( seasonEndTime: number, oldSeasonEndTime: number, lean = true) {
const result: SystemConfigType = await SystemConfigModel.findOneAndUpdate({ id: 1}, { seasonEndTime, $inc: { seasonNum: 1 }, oldSeasonEndTime }, { upsert: true, new: true }).lean(lean);
const result: SystemConfigType = await SystemConfigModel.findOneAndUpdate({}, { seasonEndTime, $inc: { seasonNum: 1 }, oldSeasonEndTime }, { upsert: true, new: true }).lean(lean);
return result;
}
}