import { MarqueeType, MarqueeModel } from "../db/Marquee"; import { ACTIVITY_TYPE, MARQUEE_SHOW_TYPE, MARQUEE_TIME_TYPE, REDIS_KEY, SURVEY_SELECT } from "../consts"; import { scheduleJob, scheduledJobs, Job } from 'node-schedule'; import { createMarqueeMsg as sysCreateMarqueeMsg, pushMarqueeMsg as sysPushMarqueeMsg } from './sysChatService'; import { GroupMessageType } from "../db/GroupMessage"; import { pinus } from "pinus"; import { ServerlistModel, ServerlistType } from "../db/Serverlist"; import { sendMailsByGmMail } from "./mailService"; import GMMail, { GMMailModel } from '../db/GMMail'; import { getPastTime, nowSeconds } from "../pubUtils/timeUtil"; import { CreateServerParam } from "../domain/backEndField/params"; import { SignInData } from "../domain/activityField/signInField"; import { RegionModel, RegionType } from "../db/Region"; import { GMMail as StategyMail } from "../db/ServerStategy"; import { uniq } from "underscore"; import { ActivityModel, ActivityModelType } from "../db/Activity"; import { dicRMB } from "../pubUtils/dictionary/DicRMB"; import { LimitShopData } from "../domain/activityField/limitShopField"; import { YuanBaoShopData } from "../domain/activityField/yuanBaoShopField"; import { MonthlyTicketData } from "../domain/activityField/monthlyTicketField"; import { DailyRMBGiftsData } from "../domain/activityField/dailyRMBGiftsField"; import { PopShopItem, PopUpShopData, PopUpShopPackage } from "../domain/activityField/popUpShopField"; import { GrowthFundData } from "../domain/activityField/growthFundField"; import { TreasureHuntData } from "../domain/activityField/treasureHuntField"; import { RefreshShopData } from "../domain/activityField/refreshShopField"; import { RoleType } from "../db/Role"; import { MonopolyData } from "../domain/activityField/monopolyField"; import { ActivityPopUpShopModel, PopUpShopItem } from "../db/ActivityPopUpShop"; import { getActivitiesByType } from "./activity/activityService"; import { SurveyModel } from "../db/Survery"; import { SurveyRecModel } from "../db/SurveyRec"; import { getPopUpShopData } from "./activity/popUpShopService"; import { TaskPassData } from "../domain/activityField/taskPassField"; import { ActivityGroupModel } from "../db/ActivityGroup"; import { redisClient } from "./redisService"; import { gameData } from "../pubUtils/data"; import { GuildModel } from "../db/Guild"; import { GuildTrainModel } from "../db/GuildTrain"; import { unlockTrain } from "./guildTrainService"; import { HiddenDataModel, HiddenDataModelType } from "../db/HiddenData"; import { HiddenDataByIdModel } from "../db/HiddenDataById"; import moment = require("moment"); // —————————————— 跑马灯 —————————————— // // 初始 export async function initMarquee() { const marquees = await MarqueeModel.findEffectiveMarque(pinus.app.get('env')); for(let marquee of marquees) { await generateMarqueeSchedule(marquee); } } export async function setMarquee(marquee: MarqueeType) { console.log('******', marquee.timeType, marquee) if(marquee.timeType == MARQUEE_TIME_TYPE.INSTANT) { await startMarquee(marquee); return true; } else { return await generateMarqueeSchedule(marquee); } } async function generateMarqueeSchedule(marquee: MarqueeType) { // 定时发送 let setSecondsMarquee = scheduledJobs[`setSeconds${marquee.code}`]; if(setSecondsMarquee) return false; // 已经在运行中了 if(marquee.timeType != MARQUEE_TIME_TYPE.SCHEDULE) return false; if(marquee.endTime && marquee.endTime < nowSeconds()) return false; let startJob = scheduleJob(`start${marquee.code}`, marquee.startTime * 1000, async () => { await startMarquee(marquee, startJob) }); return true; } async function startMarquee(marquee: MarqueeType, startJob?: Job) { console.log('************', `跑马灯定时器 ${marquee.code}开始`, '************'); let msgDatas = await createMarqueeMsg(marquee); if(marquee.showType == MARQUEE_SHOW_TYPE.ONCE) { // 一次性发送 await pushMarqueeMsg(msgDatas); if(startJob) { startJob.cancel(); startJob = undefined; } } else { if(marquee.endTime > nowSeconds()) { await pushMarqueeMsg(msgDatas); let secondsJob = scheduleJob(`setSeconds${marquee.code}`, `*/${marquee.interval} * * * * *`, async () => { console.log(`*****setSeconds${marquee.code}****`) await pushMarqueeMsg(msgDatas); }); let endJob = scheduleJob(`end${marquee.code}`, marquee.endTime * 1000, async () => { if(startJob) { startJob.cancel(); startJob = undefined; } if(secondsJob) { secondsJob.cancel(); secondsJob = undefined; } if(endJob) { endJob.cancel(); endJob = undefined; } }); } else { if(startJob) { startJob.cancel(); startJob = undefined; } } } } async function createMarqueeMsg(marquee: MarqueeType) { let { receivers, content } = marquee; let msgDatas: GroupMessageType[] = []; let serverIds: number[] = []; for(let { env, serverId } of receivers) { if(serverId == 0) { let servers = await ServerlistModel.findByEnv(env); for(let { id } of servers) { serverIds.push(id); } } else { serverIds.push(serverId); } } for(let serverId of uniq(serverIds)) { let msgData = await sysCreateMarqueeMsg('', '系统', serverId, content); msgDatas.push(msgData); } return msgDatas; } async function pushMarqueeMsg(msgDatas: GroupMessageType[]) { for(let msgData of msgDatas) { await sysPushMarqueeMsg(msgData); } } export async function cancelMarquee(code: string) { let startMarquee = scheduledJobs[`start${code}`]; let setSecondsMarquee = scheduledJobs[`setSeconds${code}`]; let endMarquee = scheduledJobs[`end${code}`]; if(startMarquee) startMarquee.cancel(); if(setSecondsMarquee) setSecondsMarquee.cancel(); if(endMarquee) endMarquee.cancel(); return true } export async function sendOpenServerMail(type: 'openMail'|'circleMail', mail: StategyMail, newServer: ServerlistType, uid: number) { let addParam = new GMMail(); addParam.setByRegionStategy(type, mail, newServer, uid); let gmmail = await GMMailModel.addMail(addParam, uid); await sendMailsByGmMail([gmmail]); return true; } export function setServerMainten(serverIds: number[], startTime: number, endTime: number) { let maintenServers = pinus.app.get('maintenServers')||new Map(); for(let id of serverIds) { if(!maintenServers.has(id)) { maintenServers.set(id, { startTime, endTime }); } else { maintenServers.get(id).startTime = startTime; maintenServers.get(id).endTime = endTime; } } pinus.app.set('maintenServers', maintenServers); } export function stopServerMainten(serverIds: number[]) { let maintenServers = pinus.app.get('maintenServers')||new Map(); for(let id of serverIds) { if(maintenServers.has(id)) { maintenServers.delete(id); } } pinus.app.set('maintenServers', maintenServers); } export function getServerMainten(serverId: number) { let maintenServers = pinus.app.get('maintenServers')||new Map(); return maintenServers.get(serverId); } export async function createNewServer(region: RegionType ,serverId: number, params: CreateServerParam, uid?: number) { let newServer = await ServerlistModel.newServer(params, region, serverId, uid); if(params.openMail) await sendOpenServerMail('openMail', params.openMail, newServer, uid); if(params.circleMail) await sendOpenServerMail('circleMail', params.circleMail, newServer, uid); if(params.activityGroupId && params.activityGroupId.length > 0) { await ActivityGroupModel.addServerToGroupData(newServer.id, params.activityGroupId); let activityGroups = await ActivityGroupModel.findByServerId(newServer.id); await pinus.app.rpc.activity.activityRemote.addServerToGroup.broadcast(params.activityGroupId, [newServer.id]); let aids = activityGroups.reduce((pre, cur) => [...pre, ...cur.activities], []); let activities = await ActivityModel.findActivityByIds(aids); let timeLimitRanks = activities.filter(cur => cur.type == ACTIVITY_TYPE.TIME_LIMIT_RANK); if(timeLimitRanks.length > 0) { pinus.app.rpc.systimer.systimerRemote.updateTimeLimitRank.broadcast(timeLimitRanks); } } await RegionModel.newServer(region.id, newServer); await redisClient().hsetAsync(REDIS_KEY.SERVER, `${newServer.id}`, `${newServer.name}`); await redisClient().hsetAsync(REDIS_KEY.SERVER_OPEN_TIME, `${newServer.id}`, `${newServer.openTime}`); } function getDicRMB(productID: string) { let dic = dicRMB.get(productID); if(!dic) return null return { value: dic.productID, label: `${dic.message}(${dic.productID})`, } }; export function getActivityProducts(activity: ActivityModelType) { switch(activity.type) { case ACTIVITY_TYPE.SIGN_IN_VIP: // 高级签到 { let data = new SignInData(activity, 0, 0); return [getDicRMB(data.productID)]; } case ACTIVITY_TYPE.NEW_PLAYER_LIMIT_PACKAGE: // 新手限定RMB购买礼包 case ACTIVITY_TYPE.LIMIT_PACKAGE_SHOP_DAILY: // 日限购 case ACTIVITY_TYPE.LIMIT_PACKAGE_SHOP_WEEKLY: // 周限购 { let data = new LimitShopData(activity, 0, 0); return data.list.map(item => { return getDicRMB(item.productID); }); } case ACTIVITY_TYPE.YUAN_BAO_SHOP: // 元宝 { let data = new YuanBaoShopData(activity, 0, 0); return data.list.map(item => { return getDicRMB(item.productID); }); } case ACTIVITY_TYPE.MONTHLY_TICKET_1: case ACTIVITY_TYPE.MONTHLY_TICKET_2: { let data = new MonthlyTicketData(activity, 0, 0); return [getDicRMB(data.productID)]; } case ACTIVITY_TYPE.DAILY_RMB_GIFTS: { let data = new DailyRMBGiftsData(activity, 0, 0); return [getDicRMB(data.productID)]; } case ACTIVITY_TYPE.POP_UP_SHOP://弹出礼包 { let products: { label: string, value: string }[] = []; let data = new PopUpShopData(activity); for(let { items } of data.packages) { for(let item of items) { products.push(getDicRMB(item.productID)); } } return products; } case ACTIVITY_TYPE.GROWTH_FUND_MAIN_VIP: //主线成长基金(高阶) case ACTIVITY_TYPE.GROWTH_FUND_TOWER_VIP://镇念塔成长基金(高阶) case ACTIVITY_TYPE.GROWTH_FUND_MAIN_ELITE_VIP://精英成长基金(高阶) { let data = new GrowthFundData(activity, 0, 0); return data.list.map(item => { return getDicRMB(item.productID); }); } case ACTIVITY_TYPE.TREASURE_HUNT: { let data = new TreasureHuntData(activity, 0, 0); let shop = data.shop; return shop.list.map(item => { return getDicRMB(item.productID); }); } case ACTIVITY_TYPE.REFRESH_SHOP: { let data = new RefreshShopData(activity, 0, 0); let products: { label: string, value: string }[] = []; for(let shop of data.list) { for(let item of shop.items) { products.push(getDicRMB(item.productID)); } } return products; } case ACTIVITY_TYPE.TASK_PASS: { let data = new TaskPassData(activity, 0, 0); let products: { label: string, value: string }[] = []; for(let reward of data.rewards) { products.push(getDicRMB(reward.productID)); } return products; } } return false } export async function getParamStr(activity: ActivityModelType, productID: string, role: RoleType) { let param = {}; switch(activity.type) { case ACTIVITY_TYPE.POP_UP_SHOP: const roleId = role.roleId; let serverId = role.serverId; let playerData = await getPopUpShopData(activity.activityId, serverId, roleId, role); let item: PopShopItem, pkg: PopUpShopPackage; for(let _pkg of playerData.packages) { let _item = _pkg.findItemByProductID(productID); if(_item) { pkg = _pkg; item = _item; } } if(item.isPushing) { param['code'] = item.code; } else { let popUpShopRec = await ActivityPopUpShopModel.createRecord({ serverId, activityId: activity.activityId, roleId, id: pkg.id, ...await pkg.getEffectTime(), items: pkg.items.map(item => new PopUpShopItem(item)) }); param['code'] = popUpShopRec.code; } // let playerRecords = await ActivityPopUpShopModel.findAllOpenData(role.serverId, activity.activityId, role.roleId); // let playerRecord: ActivityPopUpShopModelType; // for(let record of playerRecords) { // let playerData = new PopUpShopData(task, activity.activityId); // playerData.setPlayerRecords(record); // if (record && playerData.buyCount < task.count) { // playerRecord = record; break; // } // } // console.log('####', playerRecord, task) // if(!playerRecord) { // let beginTime = new Date(); // let endTime = moment(new Date()).add(task.duration, 'h').toDate(); // playerRecord = await ActivityPopUpShopModel.addTaskPushMessage(role.serverId, activity.activityId, role.roleId, task.id, task.taskType, task.condition, beginTime, endTime); // } // param['beginTimeStamp'] = playerRecord.beginTime.getTime(); break; case ACTIVITY_TYPE.REFRESH_SHOP: let monopolyActivitys = await getActivitiesByType(role.serverId, ACTIVITY_TYPE.MONOPOLY); let parentActivity = monopolyActivitys.find(activity => { let data = new MonopolyData(activity, 0, 0); let curShop = data.list.find(land => { // 找到关联活动 return land.shopActivityId == activity.activityId; }); return !!curShop; }); if(parentActivity) { param['monopolyActivityId'] = parentActivity.activityId; } break; } return JSON.stringify(param); } export async function getSurvey(roleId: string, lv: number) { let surveys = await SurveyModel.findEnableSurvey(lv, SURVEY_SELECT.FIND); let recs = await SurveyRecModel.findByRole(roleId); return surveys.filter(survey => { let index = recs.findIndex(rec => rec.surveyId == survey.surveyId); return index == -1 }); } export async function setTrainLv(guildCode: string, trainLv: string) { let [_lv, _id] = trainLv.split('-'); let lv = parseInt(_lv), id = parseInt(_id); if(!isNaN(lv) && !isNaN(id)) { let structure = gameData.trainBase.get(lv); let trainIds = structure?.trainIds||[]; let trainId = trainIds[id - 1]; if(trainId) { await GuildModel.updateInfo(guildCode, { trainId, trainLv: lv }); await GuildTrainModel.resetGuildTrain(guildCode); await unlockTrain(guildCode, trainId); } } } export async function calHiddenData(uid: number) { let result = await HiddenDataByIdModel.findAllData(); // console.log('####', JSON.stringify(result)) let heroes: number[] = [], goods: number[] = []; await HiddenDataModel.clearData(); for(let { _id, ids } of result) { await HiddenDataModel.updateHiddenData(_id, heroes, goods, uid); for(let {type, id} of ids) { if(type == 1) heroes.push(id); if(type == 2) goods.push(id); } } await HiddenDataModel.updateHiddenData(getPastTime(), heroes, goods, uid); }