diff --git a/game-server/app/servers/guild/handler/gvgFightHandler.ts b/game-server/app/servers/guild/handler/gvgFightHandler.ts index f9908428d..58bc8eed0 100644 --- a/game-server/app/servers/guild/handler/gvgFightHandler.ts +++ b/game-server/app/servers/guild/handler/gvgFightHandler.ts @@ -500,7 +500,7 @@ export class GVGProduceHandler { if(canReceiveLeagueRanks.length <= 0 && canReceivePlayerRanks.length <= 0) return resResult(STATUS.GVG_RECEIVE_NO_RANK_REWARD); let { leagueReward, rewards } = calVestigeLeagueBoxRewards(canReceiveLeagueRanks, canReceivePlayerRanks); - let leagueGoods = await addGVGReward(roleId, roleName, myLeague.leagueCode, sid, leagueReward, rewards, ITEM_CHANGE_REASON.GVG_VESTIGE_RECEIVE_RANK) + let leagueGoods = await addGVGReward(roleId, roleName, myLeague.leagueCode, sid, leagueReward, rewards, ITEM_CHANGE_REASON.GVG_VESTIGE_RECEIVE_RANK); await GVGVestigeLeagueRankModel.receiveRanks(canReceiveLeagueRanks.map(cur => cur._id), roleId); await GVGVestigeSumRankModel.receiveRanks(canReceivePlayerRanks.map(cur => cur._id)); diff --git a/game-server/app/services/gvg/gvgBattleMemory.ts b/game-server/app/services/gvg/gvgBattleMemory.ts index 7b81b50ac..1495cae4d 100644 --- a/game-server/app/services/gvg/gvgBattleMemory.ts +++ b/game-server/app/services/gvg/gvgBattleMemory.ts @@ -14,7 +14,7 @@ class GVGBattleData { public groupKey: string; // 战区 private teams: Map = new Map(); // 队伍, teamCode => team - private rolePoints: Map> = new Map(); // roleId => pointId[],用于更新玩家的积分 + public rolePoints: Map> = new Map(); // roleId => pointId[],用于更新玩家的积分 private roleToTeam: Map = new Map(); // roleId => teamCode private leagueToTeam: Map> = new Map(); // leagueCode => teamCode public areaToTeams: Map> = new Map(); // areaId => teamCode set,用于定时下发地图玩家数据 diff --git a/game-server/app/services/gvg/gvgFightService.ts b/game-server/app/services/gvg/gvgFightService.ts index e44501f49..82a5413cf 100644 --- a/game-server/app/services/gvg/gvgFightService.ts +++ b/game-server/app/services/gvg/gvgFightService.ts @@ -1,7 +1,7 @@ // 征战中原相关 import moment = require("moment"); -import { GVG_PERIOD, GVG_RETURN_ITEM_TYPE, REDIS_KEY, VESTIGE_OPP_STATUS, VESTIGE_STATUS } from "../../consts"; +import { GVG_PERIOD, GVG_RETURN_ITEM_TYPE, ITEM_CHANGE_REASON, MAIL_TYPE, REDIS_KEY, VESTIGE_OPP_STATUS, VESTIGE_STATUS } from "../../consts"; import { ArtifactModel } from "../../db/Artifact"; import { GVGConfigModel } from "../../db/GVGConfig"; import { GVGLeagueModel, GVGLeagueType } from "../../db/GVGLeague"; @@ -23,11 +23,12 @@ import { RewardInter } from "../../pubUtils/interface"; import { getTimeFun, nowSeconds } from "../../pubUtils/timeUtil"; import { getRandEelm } from "../../pubUtils/util"; import { getNumberArr, uniqueArr } from "../ladderService"; +import { sendMailByContent } from "../mailService"; import { getHeroesAttributes } from "../playerCeService"; import { Rank } from "../rankService"; import { findKeys, getAllServerName, redisClient } from "../redisService"; import { isDevelopEnv } from "../utilService"; -import { combinePushItem } from "./gvgItemService"; +import { addGVGReward, combinePushItem } from "./gvgItemService"; import { addVestigeLeagueRankRec, addVestigeRankMessage } from "./gvgRecService"; import { getGroupIdOfServer, getGroupKey, getGVGServerType, getPeriodByTime } from "./gvgService"; @@ -409,7 +410,7 @@ export async function getVestigeRank(redisKey: REDIS_KEY, isSimple: boolean, key return { ranks, myRank } } -// systimer 服 +// systimer 服 每天晚上22点 export async function saveVestigeRankSchedule() { let config = await GVGConfigModel.findConfig(); let period = getPeriodByTime(config.teamTime, config.prepareTime, config.battleTime, config.scheduleTime); @@ -436,7 +437,60 @@ export async function saveVestigeRankSchedule() { await GVGUserDataModel.addVestigeScores(config.configId, playerSumRanks); } -export function calVestigeLeagueBoxRewards(canReceiveRanks: GVGVestigeLeagueRankType[], canReceivePlayerRanks: GVGVestigeSumRankType[]) { +// systimer 服,每周六5点 +export async function sendUngotVestigeReward() { + const config = await GVGConfigModel.findConfig(); + const playerDatas = await GVGVestigeSumRankModel.getAllCanReceiveRanks(config.configId); + const leagueCodeByConfig = new Map(); + const dataByConfig = new Map>>(); // configId => leagueCode => playerdata + const receiveLeagueParam: { _id: string, roleIds: string[] }[] = [], receivePlayerParam: string[] = []; + for(let player of playerDatas) { + if(!leagueCodeByConfig.has(player.configId)) leagueCodeByConfig.set(player.configId, []); + if(leagueCodeByConfig.get(player.configId).indexOf(player.leagueCode) == -1) { + leagueCodeByConfig.get(player.configId).push(player.leagueCode); + } + if(!dataByConfig.has(player.configId)) dataByConfig.set(player.configId, new Map()); + if(!dataByConfig.get(player.configId).has(player.leagueCode)) dataByConfig.get(player.configId).set(player.leagueCode, new Map()); + if(!dataByConfig.get(player.configId).get(player.leagueCode).has(player.roleId)) dataByConfig.get(player.configId).get(player.leagueCode).set(player.roleId, { playerRanks: [], leagueRanks: [] }); + dataByConfig.get(player.configId).get(player.leagueCode).get(player.roleId).playerRanks.push({ _id: player._id, rank: player.rank }); + + receivePlayerParam.push(player._id); + } + for(let [configId, leagueCodes] of leagueCodeByConfig) { + const leagueDatas = await GVGVestigeLeagueRankModel.getAllCanReceiveRanks(configId, leagueCodes); + for(let leagueData of leagueDatas) { + let players = dataByConfig.get(configId)?.get(leagueData.leagueCode); + if(players) { + for(let [roleId, data] of players) { + if(leagueData.receiveMembers.indexOf(roleId) == -1) { + data.leagueRanks.push({ _id: leagueData._id, rank: leagueData.rank }); + let index = receiveLeagueParam.findIndex(cur => cur._id == leagueData._id); + if(index == -1) { + receiveLeagueParam.push({ _id: leagueData._id, roleIds: [ roleId ] }); + } else { + receiveLeagueParam[index].roleIds.push(roleId); + } + } + } + } + } + } + + for(let [configId, leagueMap] of dataByConfig) { + for(let [ leagueCode, players ] of leagueMap) { + for(let [ roleId, { playerRanks, leagueRanks }] of players) { + let { leagueReward, rewards } = calVestigeLeagueBoxRewards(leagueRanks, playerRanks); + if(leagueReward.length > 0) await addGVGReward(roleId, '', leagueCode, null, leagueReward, [], ITEM_CHANGE_REASON.GVG_VESTIGE_RECEIVE_RANK); + if(rewards.length > 0) await sendMailByContent(MAIL_TYPE.VESTIGE_REWARD, roleId, { params: [`${configId}`], goods: rewards }); + } + } + } + + await GVGVestigeSumRankModel.receiveRanks(receivePlayerParam); + await GVGVestigeLeagueRankModel.receiveManyRanks(receiveLeagueParam); +} + +export function calVestigeLeagueBoxRewards(canReceiveRanks: { rank: number }[], canReceivePlayerRanks: { rank: number }[]) { let rewards: RewardInter[] = [], leagueReward: RewardInter[] = []; for(let { rank } of canReceiveRanks) { let dicRank = getGVGVestigeLeagueRank(rank); diff --git a/game-server/app/services/timeTaskService.ts b/game-server/app/services/timeTaskService.ts index cac9fe3b2..8a9a7f0a0 100644 --- a/game-server/app/services/timeTaskService.ts +++ b/game-server/app/services/timeTaskService.ts @@ -44,7 +44,7 @@ import { HiddenDataModel, HiddenDataModelType } from '../db/HiddenData'; import { setHiddenData, setHiddenDataToMemory } from './dataService'; import { GVGConfigModel } from '../db/GVGConfig'; import { createNewGVGConfig, initLeaguePrepare } from './gvg/gvgService'; -import { getFightTimeByPeriod, saveVestigeRankSchedule } from './gvg/gvgFightService'; +import { getFightTimeByPeriod, saveVestigeRankSchedule, sendUngotVestigeReward } from './gvg/gvgFightService'; import { gvgBattleEnd } from './gvg/gvgBattleService'; const PER_SECOND = 1 * 1000; @@ -925,6 +925,9 @@ export async function initGVGConfigSchedule() { if(scheduledJobs[`gvgFight`]) scheduledJobs[`gvgFight`].cancel(); scheduleJob(`gvgFight`, '0 0 22 * * ?', saveVestigeRankSchedule); + if(scheduledJobs[`gvgBattle`]) scheduledJobs[`gvgBattle`].cancel(); + scheduleJob(`gvgBattle`, config.battleTime * 1000, sendUngotVestigeReward); + let { startFightTime, endFightTime } = getFightTimeByPeriod(GVG_PERIOD.BATTLE, config.battleTime); if(nowSeconds() > startFightTime - GVG.GVG_GUARD_START_TIME && nowSeconds() < endFightTime) { diff --git a/shared/consts/constModules/mailConst.ts b/shared/consts/constModules/mailConst.ts index 6f49d2699..62dc2f712 100644 --- a/shared/consts/constModules/mailConst.ts +++ b/shared/consts/constModules/mailConst.ts @@ -70,6 +70,7 @@ export enum MAIL_TYPE { GVG_BATTLE_PLAYER_RANK_REWARD = 40, // 激战期个人排行榜奖励 GVG_GUARD_CITY_REWARD = 41, // 激战期城池占领奖励 LEAGUE_MAIL = 42, // 联军邮件 + VESTIGE_REWARD = 43, // 补发遗迹邮件 }; export const SEND_NAME = '系统'; diff --git a/shared/db/GVGVestigeLeagueRank.ts b/shared/db/GVGVestigeLeagueRank.ts index 1be906259..a4cfdad77 100644 --- a/shared/db/GVGVestigeLeagueRank.ts +++ b/shared/db/GVGVestigeLeagueRank.ts @@ -69,6 +69,17 @@ export default class GVGVestigeLeagueRank extends BaseModel { public static async receiveRanks(_ids: string[], roleId: string) { await GVGVestigeLeagueRankModel.updateMany({ _id: { $in: _ids } }, { $push: { receiveMembers: roleId } }); } + + public static async receiveManyRanks(arr: { _id: string, roleIds: string[]}[]) { + await GVGVestigeLeagueRankModel.bulkWrite(arr.map(({ _id, roleIds}) => { + return { updateOne: { filter: { _id }, update: { $push: { receiveMembers: roleIds } } } } + })); + } + + public static async getAllCanReceiveRanks(configId: number, leagueCodes: string[]) { + let result: GVGVestigeLeagueRankType[] = await GVGVestigeLeagueRankModel.find({ configId, rank: { $gt: 0 }, leagueCode: { $in: leagueCodes } }).lean(); + return result; + } } export const GVGVestigeLeagueRankModel = getModelForClass(GVGVestigeLeagueRank); diff --git a/shared/db/GVGVestigeSumRank.ts b/shared/db/GVGVestigeSumRank.ts index c2184870e..47d9bf0af 100644 --- a/shared/db/GVGVestigeSumRank.ts +++ b/shared/db/GVGVestigeSumRank.ts @@ -77,6 +77,11 @@ export default class GVGVestigeSumRank extends BaseModel { public static async receiveRanks(_ids: string[]) { await GVGVestigeSumRankModel.updateMany({ _id: { $in: _ids } }, { $set: { isReceived: true } }); } + + public static async getAllCanReceiveRanks(configId: number) { + let result: GVGVestigeSumRankType[] = await GVGVestigeSumRankModel.find({ configId: { $lte: configId }, rank: { $gt: 0 }, isReceived: false }).lean(); + return result; + } } export const GVGVestigeSumRankModel = getModelForClass(GVGVestigeSumRank); diff --git a/shared/resource/jsons/dic_email_content.json b/shared/resource/jsons/dic_email_content.json index 287c98be2..eabc272cb 100644 --- a/shared/resource/jsons/dic_email_content.json +++ b/shared/resource/jsons/dic_email_content.json @@ -299,5 +299,12 @@ "sendName": "&", "content": "%d", "time": 720 + }, + { + "id": 43, + "title": "&", + "sendName": "学宫驿使", + "content": "亲爱的百家传人,逐鹿中原本轮备战期已结束,您有奖励尚未领取,现已发送至邮箱,请查收", + "time": 720 } ] \ No newline at end of file