后台:自动开服

This commit is contained in:
luying
2021-12-08 16:23:00 +08:00
parent 02c2096704
commit fc38485f94
8 changed files with 102 additions and 97 deletions

View File

@@ -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);
}

View File

@@ -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(<MarqueeType>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((<NoticeType>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((<NoticeType>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((<MarqueeType>marquee).code);
// }
// console.log('*****', JSON.stringify(mail));
// if(mail) {
// let f = new SendMailFun();
// await f.setWithGmMail((<GMMailType>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);
}

View File

@@ -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<string, { servers: ServerlistType[], maintenance: Mai
export async function initMaintenance(servers?: ServerlistType[]) {
if(!servers) servers = await ServerlistModel.findByEnv(pinus.app.get('env'));
console.log('#### initMaintenance', servers)
for(let server of servers) {
let { maintenance } = server;
if(maintenance && maintenance.isOpen) {
@@ -532,7 +534,42 @@ export async function stopMaintenance(batchCode: string, serverIds: number[]) {
// —————————————— 维护 end —————————————— //
// —————————————— 自动开服 —————————————— //
async function initAutoCreateServer(region?: RegionType) {
export async function initAutoCreateServer(region?: RegionType) {
if(!region) region = await RegionModel.findRegionByEnv(pinus.app.get('env'));
if(region && region.stategy) {
for(let timer of region.stategy.timers) {
setStategyTimer(timer, region)
}
}
}
function setStategyTimer(timerId: number, region: RegionType) {
if(scheduledJobs[`autoServer${timerId}`]) scheduledJobs[`autoServer${timerId}`].cancel();
let cron = '';
switch(timerId) {
case SERVER_TIMER.FIVE_HALF:
cron = '0 30 5 * * *'; break;
case SERVER_TIMER.TEN_HALF:
cron = '0 30 10 * * *'; break;
case SERVER_TIMER.FIFTEEN_HALF:
cron = '0 19 16 * * *'; break;
case SERVER_TIMER.NINETEEN_HALF:
cron = '0 30 19 * * *'; break;
}
if(cron) {
scheduleJob(`autoServer${timerId}`, cron, () => {
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 —————————————— //

View File

@@ -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
}

View File

@@ -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: '缺少关卡信息' },

View File

@@ -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<typeof Serverlist, {}>;

View File

@@ -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

View File

@@ -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, {});