diff --git a/game-server/app/servers/gm/handler/gmServerHandler.ts b/game-server/app/servers/gm/handler/gmServerHandler.ts index 3f6aae810..e595abe36 100644 --- a/game-server/app/servers/gm/handler/gmServerHandler.ts +++ b/game-server/app/servers/gm/handler/gmServerHandler.ts @@ -3,14 +3,14 @@ import { genCode, getRandSingleEelm, resResult } from '../../../pubUtils/util'; import { STATUS } from '../../../consts/statusCode'; import moment = require('moment'); import { CreateServerParam, UpdateRegionParams } from '../../../domain/backEndField/params'; -import { RegionModel } from '../../../db/Region'; +import { RegionModel, RegionType } from '../../../db/Region'; import { gameData } from '../../../pubUtils/data'; import { Maintenance, ServerlistModel, ServerlistUpdate } from '../../../db/Serverlist'; import { nowSeconds } from '../../../pubUtils/timeUtil'; import { GM_MAIL_TYPE, MAIL_TIME_TYPE, REF_CIRCLE_MAIL_TIME } from '../../../consts'; import { SendMailFun } from '../../../services/mailService'; -import { sendOpenServerMail } from '../../../services/gmService'; -import { initMaintenance, stopMaintenance } from '../../../services/timeTaskService'; +import { createNewServer, sendOpenServerMail } from '../../../services/gmService'; +import { initAutoCreateServer, initMaintenance, stopMaintenance } from '../../../services/timeTaskService'; import { isNumber } from 'util'; let timer: NodeJS.Timer; export default function (app: Application) { @@ -26,15 +26,18 @@ export class GmHandler { let params = new UpdateRegionParams(msg); let uid = session.get('uid'); if(!params.checkParams()) return resResult(STATUS.WRONG_PARMS); + let region: RegionType; if(params.id == 'new') { let update = params.getUpdateParam(); - await RegionModel.createNewRegion(update, uid); + region = await RegionModel.createNewRegion(update, uid); } else { let oldRegion = await RegionModel.findRegionById(params.id); if(!oldRegion) return resResult(STATUS.WRONG_PARMS); let update = params.getUpdateParam(oldRegion); - await RegionModel.updateRegion(params.id, update, uid); + region = await RegionModel.updateRegion(params.id, update, uid); } + await initAutoCreateServer(region); + return resResult(STATUS.SUCCESS); } @@ -52,10 +55,7 @@ export class GmHandler { let dicServerName = gameData.serverNames.get(latestServer + 1); if(!dicServerName) return resResult(STATUS.DIC_DATA_NOT_FOUND); - let newServer = await ServerlistModel.newServer(params, curRegion, dicServerName, uid); - if(params.openMail) await sendOpenServerMail('openMail', params.openMail, newServer, uid); - if(params.circleMail) await sendOpenServerMail('circleMail', params.circleMail, newServer, uid); - await RegionModel.newServer(curRegion.id, newServer) + await createNewServer(curRegion, latestServer + 1, params, uid); return resResult(STATUS.SUCCESS); } diff --git a/game-server/app/services/gmService.ts b/game-server/app/services/gmService.ts index 4faea1a24..63eebd310 100644 --- a/game-server/app/services/gmService.ts +++ b/game-server/app/services/gmService.ts @@ -11,6 +11,8 @@ import { SendMailFun } from "./mailService"; import GMMail, { GMMailModel, GMMailType } from '../db/GMMail'; import moment = require("moment"); import { getSeconds, nowSeconds } from "../pubUtils/timeUtil"; +import { CreateServerParam } from "../domain/backEndField/params"; +import { RegionModel, RegionType } from "../db/Region"; // —————————————— 跑马灯 —————————————— // // 初始 @@ -102,77 +104,6 @@ export async function cancelMarquee(code: string) { return true } -// —————————————— 停服维护 —————————————— // -// 维护信息 -// export async function initMaintenance() { -// let servers = await ServerlistModel.findByEnv(pinus.app.get('env')); -// for(let server of servers) -// // if(!maintenance) -// // maintenance = await MaintenanceModel.findOpenMaintenance(); -// // if(maintenance) { -// // let { startTime, marquee } = maintenance; -// // if(marquee) { -// // let result = await generateMarqueeSchedule(marquee); -// // // console.log(result); -// // } -// // if(Date.now() > startTime.getTime()) { -// // await startMaintenance(maintenance); -// // } else { -// // let startJob = scheduleJob(`startMainten${maintenance.code}`, startTime.getTime(), async () => { -// // await startMaintenance(maintenance, startJob); -// // }); -// // } -// } -// } - -// // 开启维护 -// async function startMaintenance(maintenance: MaintenanceType, startJob?: Job) { -// // 向全服发送 -// let { serverIds, notice } = maintenance; -// for(let serverId of serverIds) { -// let chatSid = await getWorldChannelSid(serverId); -// await pinus.app.rpc.chat.chatRemote.sendServerMaintenance.toServer(chatSid, serverId); -// } - -// // 更新serverlist上的status -// await ServerlistModel.updateByServerIds(serverIds, { serverStatus: SERVER_STATUS.MAINTENANCE }); -// // 更新notice的isEnable -// if(notice) { -// await NoticeModel.updateNotice((notice).id, { isEnable: true }); -// } - -// // 更新connectorRemote里面的维护服务器 -// await pinus.app.rpc.connector.connectorRemote.setServerMainten.broadcast(serverIds); -// } - -// // 停止维护 -// export async function stopMaintenance(maintenance: MaintenanceType, uid: number) { -// let { serverIds, notice, marquee, mail } = maintenance; -// // 更新serverlist上的status -// await ServerlistModel.updateByServerIds(serverIds, { serverStatus: SERVER_STATUS.HOT }); -// // 更新notice的isEnable -// if(notice) { -// await NoticeModel.updateNotice((notice).id, { isEnable: false }); -// } - -// // 更新connectorRemote里面的维护服务器 -// let connectorServers = pinus.app.getServersByType('connector'); -// for(let { id } of connectorServers) { -// await pinus.app.rpc.connector.connectorRemote.setServerMainten.toServer(id, []); -// } - -// if(marquee) { -// await cancelMarquee((marquee).code); -// } -// console.log('*****', JSON.stringify(mail)); -// if(mail) { -// let f = new SendMailFun(); -// await f.setWithGmMail((mail)._id); -// await f.sendToServer(serverIds); -// // await f.saveRecord(uid); -// } -// } - export async function sendOpenServerMail(type: 'openMail'|'circleMail', mail: GMMail, newServer: ServerlistType, uid: number) { let receivers = [{ env: newServer.env, @@ -186,7 +117,8 @@ export async function sendOpenServerMail(type: 'openMail'|'circleMail', mail: GM let gmmail = await GMMailModel.addMail(addParam, uid); let needSend = false; if(mail.timeType == MAIL_TIME_TYPE.CIRCLE) { - let refTime = moment(moment().format(`YYYY-MM-DD ${REF_CIRCLE_MAIL_TIME}:00:00`)).unix(); + let refTimeStr = REF_CIRCLE_MAIL_TIME >= 10? `${REF_CIRCLE_MAIL_TIME}`: `0${REF_CIRCLE_MAIL_TIME}`; + let refTime = moment(moment().format(`YYYY-MM-DD ${refTimeStr}:00:00`)).unix(); let sendTime = moment(moment().format('YYYY-MM-DD '+ mail.circleHour)).unix(); if(sendTime < refTime) sendTime += 86400; let now = nowSeconds(); @@ -204,8 +136,6 @@ export async function sendOpenServerMail(type: 'openMail'|'circleMail', mail: GM return true; } - - export function setServerMainten(serverIds: number[], startTime: number, endTime: number) { let maintenServers = pinus.app.get('maintenServers')||new Map(); for(let id of serverIds) { @@ -232,4 +162,11 @@ export function stopServerMainten(serverIds: number[]) { 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); + await RegionModel.newServer(region.id, newServer); } \ No newline at end of file diff --git a/game-server/app/services/timeTaskService.ts b/game-server/app/services/timeTaskService.ts index 974a677a2..a6a32eecd 100644 --- a/game-server/app/services/timeTaskService.ts +++ b/game-server/app/services/timeTaskService.ts @@ -5,7 +5,7 @@ import { nowSeconds, getTimeFun, getSeconds } from '../pubUtils/timeUtil'; import { getTodayGuildActivity, gameData } from '../pubUtils/data'; import { pvpSeasonEnd } from './pvpService'; import { getAllOnlineRoles, getAllServers, delGuildActivityRank } from './redisService'; -import { GUILD_ACTIVITY_TYPE, REFRESH_TIME, SEND_NAME, SERVER_OPEN_TIME, COUNTER, AUCTION_TIME, GM_MAIL_TYPE, SERVER_STATUS } from '../consts'; +import { GUILD_ACTIVITY_TYPE, REFRESH_TIME, SEND_NAME, SERVER_OPEN_TIME, COUNTER, AUCTION_TIME, GM_MAIL_TYPE, SERVER_STATUS, SERVER_TIMER } from '../consts'; import { RoleModel } from '../db/Role'; import { pinus } from 'pinus'; import { indexOf } from 'underscore'; @@ -19,7 +19,7 @@ import { dispatch } from '../pubUtils/dispatcher'; import { Rank } from './rankService'; import { checkTask } from './taskService'; import { everydayRefresh } from './connectorService'; -import { initMarquee } from './gmService'; +import { createNewServer, initMarquee } from './gmService'; import moment = require('moment'); import { CounterModel } from '../db/Counter'; import { reportOneOnline } from './authenticateService'; @@ -30,6 +30,7 @@ import { Maintenance, ServerlistModel, ServerlistType, ServerlistUpdate } from ' import { getWorldChannelSid } from './chatService'; import { createMarqueeMsg, pushMarqueeMsg } from './sysChatService'; import { RegionModel, RegionType } from '../db/Region'; +import { CreateServerParam } from '../domain/backEndField/params'; const PER_SECOND = 1 * 1000; const PER_DAY = 24 * 60 * 60; @@ -79,6 +80,9 @@ export async function init() { // 维护信息 await initMaintenance(); + + // 自动开服 + await initAutoCreateServer(); } // —————————————— PVP 及赛季相关 —————————————— // @@ -415,8 +419,6 @@ let maintenInfos = new Map { + autoCreateServerSchedule(region); + }) + } +} + +async function autoCreateServerSchedule(region: RegionType) { + console.log('******* createNewServer *******') + let latestServer = await ServerlistModel.findByServerId(region.latestServerUniqId); + if(!latestServer || latestServer.playerCnt >= region.stategy.maxPlayerCnt) { + let params = new CreateServerParam(); + params.setByRegionStategy(region, nowSeconds()) + await createNewServer(region, (latestServer?.serverId||0) + 1, params); + } } // —————————————— 自动开服 end —————————————— // \ No newline at end of file diff --git a/shared/consts/constModules/sysConst.ts b/shared/consts/constModules/sysConst.ts index d1745c53d..b5d9fcd94 100644 --- a/shared/consts/constModules/sysConst.ts +++ b/shared/consts/constModules/sysConst.ts @@ -762,5 +762,5 @@ export enum SERVER_TIMER { FIVE_HALF = 1, // 5:30 TEN_HALF = 2, // 10:30 FIFTEEN_HALF = 3, // 15:30 - SEVENTEEN_HALF = 4, // 19:30 + NINETEEN_HALF = 4, // 19:30 } \ No newline at end of file diff --git a/shared/consts/statusCode.ts b/shared/consts/statusCode.ts index b7d8cc406..c47e9a03c 100644 --- a/shared/consts/statusCode.ts +++ b/shared/consts/statusCode.ts @@ -37,6 +37,7 @@ export const STATUS = { ROLE_EXIST: { code: 10017, simStr: '账号已存在' }, CHANNEL_ERR: { code: 10018, simStr: '无此渠道' }, VALIDATE_ERR: { code: 10019, simStr: '渠道校验错误' }, + SERVER_STOP_REGISTER: { code: 10020, simStr: '服务器已停止注册' }, // 战斗相关状态 20000 - 29999 // 战斗通用 20000 - 20099 BATTLE_MISS_INFO: { code: 20001, simStr: '缺少关卡信息' }, diff --git a/shared/db/Serverlist.ts b/shared/db/Serverlist.ts index 1d1ac3bbf..145c18a07 100644 --- a/shared/db/Serverlist.ts +++ b/shared/db/Serverlist.ts @@ -4,8 +4,8 @@ import { CounterAllModal } from './CounterAll'; import { COUNTER, SERVER_STATUS } from '../consts'; import { CreateServerParam } from '../domain/backEndField/params'; import { RegionType } from './Region'; -import { DicServerName } from '../pubUtils/dictionary/DicServerName'; import { nowSeconds } from '../pubUtils/timeUtil'; +import { gameData } from '../pubUtils/data'; export class Maintenance { @@ -123,12 +123,13 @@ export default class Serverlist extends BaseModel { return result; } - public static async newServer(params: CreateServerParam, region: RegionType, dicServerName: DicServerName, uid = 1 ) { + public static async newServer(params: CreateServerParam, region: RegionType, serverId: number, uid = 1 ) { + let dicServerName = gameData.serverNames.get(serverId); let { prefix, id: regionId, env } = region; // 分大区 let id = await CounterAllModal.getNewCounter(COUNTER.SERVER); let { openTime, stopRegisterTime: hour, activityGroupId } = params; - let { id: serverId, sname: name, groupId, groupName } = dicServerName; + let { sname: name, groupId, groupName } = dicServerName; let stopRegisterTime = openTime + hour * 60 * 60; const doc = new ServerlistModel(); @@ -138,7 +139,8 @@ export default class Serverlist extends BaseModel { openTime, stopRegisterTime, createdBy: uid, updatedBy: uid }); - + // 旧服修改状态 + await ServerlistModel.updateMany({ env, serverStatus: SERVER_STATUS.NEW }, { $set: { serverStatus: SERVER_STATUS.HOT } }) let server: ServerlistType = await ServerlistModel.findOneAndUpdate({ id }, { $setOnInsert: update }, { new: true, upsert: true }).lean({ getters: true, virtuals: true }); return server; } @@ -168,6 +170,11 @@ export default class Serverlist extends BaseModel { return result; } + public static async incRoleCnt(serverId: number) { + let server: ServerlistType = await ServerlistModel.findOneAndUpdate({ serverId }, { $inc: { playerCnt: 1 } }); + return server; + } + } export let ServerlistModel: ReturnModelType; diff --git a/shared/domain/backEndField/params.ts b/shared/domain/backEndField/params.ts index 34b57cc6c..028491e44 100644 --- a/shared/domain/backEndField/params.ts +++ b/shared/domain/backEndField/params.ts @@ -3,6 +3,7 @@ import { isArray } from 'underscore'; import GMMail from "../../db/GMMail"; import ServerStategy from "../../db/ServerStategy"; import { RegionType } from "../../db/Region"; +import { nowSeconds } from "../../pubUtils/timeUtil"; export class UpdateMailParams { hasGoods: boolean = false; // 是否有道具 @@ -127,12 +128,28 @@ export class CreateServerParam { circleMail?: GMMail; stopRegisterTime: number = 0; - constructor(obj: CreateServerParam) { - for(let key in obj) { - this[key] = obj[key]; + constructor(obj?: any) { + if(obj) { + for(let key in obj) { + this[key] = obj[key]; + } } } + setByRegionStategy(region: RegionType, openTime: number) { + this.env = region.env; + this.openTime = openTime; + if(region.stategy) { + this.activityGroupId = region.stategy.activityGroupId; + this.hasOpenMail = !!region.stategy.openMail; + this.openMail = region.stategy.openMail; + this.hasCircleMail = !!region.stategy.circleMail; + this.circleMail = region.stategy.circleMail; + this.stopRegisterTime = region.stategy.stopRegisterTime; + } + + } + checkParams() { if(!this.env || !this.openTime || !this.stopRegisterTime || !isArray(this.activityGroupId) || this.activityGroupId.length <= 0 ) { return false diff --git a/web-server/app/service/Auth.ts b/web-server/app/service/Auth.ts index c79d9f5a0..1c7f3e857 100644 --- a/web-server/app/service/Auth.ts +++ b/web-server/app/service/Auth.ts @@ -8,13 +8,14 @@ import { Service } from 'egg'; import Counter from '@db/Counter'; import { getExpByLv } from '../pubUtils/data'; import { isString } from 'underscore'; -import { getAge } from '../pubUtils/timeUtil'; +import { getAge, nowSeconds } from '../pubUtils/timeUtil'; import { resResult } from '../pubUtils/util'; import { checkTeeanAgerTime } from '../pubUtils/authenticateUtil'; // import { authenticate } from '../pubUtils/httpUtil'; import { checkTask } from 'app/pubUtils/taskUtil'; import { getChannelId, loginValidata } from '../pubUtils/sdkUtil'; import { LoginValidateData37 } from 'app/domain/sdk'; +import { ServerlistModel } from '@db/Serverlist'; /** * Test Service @@ -308,12 +309,17 @@ export default class Auth extends Service { if (exist === true) { return ctx.service.utils.resResult(STATUS.ROLE_EXIST); } + const server = await ServerlistModel.findByServerId(serverId); + if(!server) return ctx.service.utils.resResult(STATUS.SERVER_NOT_FOUND); + if(nowSeconds() > server.stopRegisterTime) return ctx.service.utils.resResult(STATUS.SERVER_STOP_REGISTER); + const roleId = ctx.service.utils.genCode(10); const code = ctx.service.utils.genCode(6); const seqId = await Counter.getNewCounter(COUNTER.ROLE) || -1; const role = await RoleModel.createRole(uid, serverId, { roleId, code, roleName: "", seqId, lv: DEFAULT_LV, exp: (getExpByLv(DEFAULT_LV - 1) || { sum: 0 }).sum || 0 }); if (role) { + await ServerlistModel.incRoleCnt(serverId); // 任务 await checkTask(roleId, TASK_TYPE.ROLE_LV, role.lv, false, {});