/* Sog 游戏基础库 2016 by zouwei */ using System; using Sog; using Sog.Log; namespace World { // 服务器入口 public class WorldServer : IScript { private Guid m_guid; private ServerApp m_app; private WorldMsgHandler m_messageHandler; public WorldServer() { m_guid = Guid.NewGuid(); } public IScriptHotfixCheck GetScriptHotfixCheck() { return new ServerScriptHotfixCheck(); } private void CommInitOnCreateReload(ServerApp app) { m_app = app; RegisterAllService(); DBServerIDUtils.Init(m_app); WorldServerUtils.GetEventHandlerMgr().RegisterAllEventHandler(); RobotUtils.InitRobotPool(); } public virtual void OnCreate(ServerApp app) { //打印消息统计日志 app.GetCluster().NeedLogMsgStat = true; m_app = app; RegisterAllDataObj(); CommInitOnCreateReload(app); WorldServerDataUtils.LoadDataFromFile(); TraceLog.Debug("WorldServer.OnCreate start at {0}, guid {1}", DateTime.Now, m_guid); } public virtual void OnHotfix(ServerApp app) { m_app = app; ReadServerConfig(); CommInitOnCreateReload(app); TraceLog.Debug("WorldServer.OnHotfix at {0}, guid {1}", DateTime.Now, m_guid); } public virtual void OnReloadConfig(string excelConfigFile) { TraceLog.Debug("WorldServer.OnReloadConfig at {0}", DateTime.Now); ReadServerConfig(); //重新读ip白名单,黑名单 LimitIPList.Clear(); } // TickNewDay每天只触发一次,如果内部调用的逻辑出错,要等到明天才有更新的机会 private void TickNewDay(long nowSec) { var svrData = WorldServerUtils.GetWorldServerData(); // world启动时会从文件WorldSvrData读入LastDayStartTime if (AppTime.IsSameDay(nowSec, svrData.lastDayStartTime)) { return; } svrData.lastDayStartTime = nowSec; //代码好像被废弃了 WorldServerUtils.GetEventHandlerMgr().TriggerNewDayStart?.Invoke(nowSec); } private void TickOneSecond(long nowMs, long nowSec) { if (nowMs < WorldServerUtils.GetWorldServerData().m_oneSecondMs + 1000) { return; } WorldServerUtils.GetWorldServerData().m_oneSecondMs = nowMs; RankSvc.OnTick(nowSec); //MailSvc.TickSendMailWithRule(nowSec);已废弃,移动到MailServer GameReportSvc.OnTick(nowSec); PlayerTickSvc.OnTick(nowSec); WorldGlobalDataSvc.OnTick(nowSec); TickServerStop(); if (!m_app.IsStopping) { WaitInLinePlayerTickSvc.OnTickOneSecond(nowSec); GmCmdSvc.OnTick(nowSec); } } private void Tick5Second(long nowMs, long nowSec) { if (nowMs < WorldServerUtils.GetWorldServerData().m_5SecondMs + 5000) { return; } WorldServerUtils.GetWorldServerData().m_5SecondMs = nowMs; TickNewDay(nowSec); WaitAckDiamondHolderReqSender.Instance.Tick(nowSec); AlertSvc.OnTick(nowSec); QueryRoleInfoSvc.OnTick5Second(nowSec); } private void TickOneMinute(long nowMs, long nowSec) { //以前是判断间隔大于60s触发一次,但在服务器tick卡顿时可能会出现在自然一分钟内不触发 //会出现自然一分钟不上报在线人数,从而出现数数在线人数统计抖动,现在改成不同一分钟内判断 if(AppTime.IsSameMinute(nowSec, WorldServerUtils.GetWorldServerData().m_oneMinute)) { return; } //if (nowSec < WorldServerUtils.GetWorldServerData().m_oneMinute + 60) //{ // return; //} WorldServerUtils.GetWorldServerData().m_oneMinute = nowSec; PlayerLinkServerTick.OnTick(nowSec); GameReportSvc.TickRealmOnline(); WaitInLinePlayerTickSvc.OnTickOneMinute(nowSec); WorldBDCLogUtils.OnlineScene(); } private void Tick5Minute(long nowMs, long nowSec) { if (nowSec < WorldServerUtils.GetWorldServerData().m_5Minute + 300) { return; } WorldServerUtils.GetWorldServerData().m_5Minute = nowSec; } private void TickServerStop() { if (m_app.CurrStopStage == ServerStopStage.stopping) { bool canStop = WaitAckStructRequestSender.Instance.IsEmpty(); canStop = canStop && RankUtils.IsAllDataSave() && WorldGlobalDataUtils.IsAllDataSave(); TraceLog.Debug("WorldServer.TickServerStop canStop {0}", canStop); if (canStop) { WorldServerDataUtils.SaveDataToFile(); WaitAckDiamondHolderReqSender.Instance.SaveToFile(); m_app.SetStopSuccess(); } } } public virtual void OnTick(long nowMs) { WaitAckStructRequestSender.Instance.Tick(nowMs); WorldServerStat.Tick(nowMs); long nowSec = m_app.GetTimeSecond(); TickOneSecond(nowMs, nowSec); Tick5Second(nowMs, nowSec); TickOneMinute(nowMs, nowSec); Tick5Minute(nowMs, nowSec); ServerStat.Instance.Tick(nowMs); } public virtual void OnMessage(uint remoteAppID, MessageData message) { m_messageHandler.HandlerMessage(remoteAppID, message); } public virtual void OnStop() { //SaveAbyssRecording(); } //所有引用对象置空 public void Dispose() { TraceLog.Debug("WorldServer.Disposed"); m_app = null; m_messageHandler = null; } private void ReadServerConfig() { // 读取配置文件 string strLogicServerConfig = m_app.GetCluster().GetAppConfigPath() + "/" + m_app.AppParam.ServerConfig.configfile; WorldServerConfig serverConfig = ServerConfigMgr.Instance.ReloadServerConfig(m_app,strLogicServerConfig); TraceLog.Debug("WorldServer.ReadServerConfig instId {0} onlinePlayerMax {1} waitLoginPlayerMax {2} homeCacheCount {3}", serverConfig.accountInstid, serverConfig.onlinePlayerMax, serverConfig.waitLoginPlayerMax, serverConfig.homeCacheCount); //排队列表白名单重置 LimitGameIdList.Clear(); // load config时刷新cluster层服务器的instId var app = WorldServerUtils.GetApp(); WorldServerUtils.GetWorldServerData().m_packetSender .Init(app.ServerID, app.GetCluster(), serverConfig.accountInstid); } private void RegisterAllDataObj() { WorldServerData serverData = new WorldServerData(m_app); ServerDataObjMgr.Instance.RegisterDataObj(serverData); WaitAckStructRequestSender.Instance.Init(WorldServerUtils.GetPacketSender(), m_app.ServerID, m_app); WaitAckDiamondHolderReqSender.Instance.Init(); ReadServerConfig(); //运营日志 BillLogWriter.Instance.Init(m_app.ServerID, WorldServerUtils.GetPacketSender()); //读取游戏数据文件 GameConfigMgr.Instance.ReadAllConfig(); AppTime.UpdateGameResetHour(CommParamDescMgr.Instance.CrossDaysTime.int_val); PlayerTable playerTable = new PlayerTable(); ServerDataObjMgr.Instance.RegisterDataObj(playerTable); WorldRankData rankData = new WorldRankData(); ServerDataObjMgr.Instance.RegisterDataObj(rankData); //排队等待玩家数据 WaitInLinePlayerTableData waitPlayerTableData = new WaitInLinePlayerTableData(); ServerDataObjMgr.Instance.RegisterDataObj(waitPlayerTableData); //全局数据 WorldGlobalData globalData = new WorldGlobalData(); ServerDataObjMgr.Instance.RegisterDataObj(globalData); //缓存的玩家数据 RoleCacheInfoSvc roleCacheInfoSvc = new RoleCacheInfoSvc(); ServerDataObjMgr.Instance.RegisterDataObj(roleCacheInfoSvc); WorldBattleRecordDataCache recordData = new WorldBattleRecordDataCache(); ServerDataObjMgr.Instance.RegisterDataObj(recordData); //int replayCacheCount = WorldServerUtils.GetServerConfig().battleReplayCacheCount; //WorldBattleReplayAllInfoCache replayCacheData = new WorldBattleReplayAllInfoCache(replayCacheCount); //ServerDataObjMgr.Instance.RegisterDataObj(replayCacheData); //TraceLog.Debug("WorldServer.RegisterAllDataObj replayCacheCount {0}", replayCacheData.m_maxReplayDataCount); //全局领地数据 int homeCacheCount = WorldServerUtils.GetServerConfig().homeCacheCount == 0 ? 20000 : WorldServerUtils.GetServerConfig().homeCacheCount; WorldHomeData worldHomeData = new WorldHomeData(homeCacheCount); ServerDataObjMgr.Instance.RegisterDataObj(worldHomeData); TraceLog.Debug("WorldServer.RegisterAllDataObj homeCacheCount {0} LastHomeCacheCount {1}", WorldServerUtils.GetServerConfig().homeCacheCount, homeCacheCount); //登录加载的数据 WorldLoginLoadingData loginLoadingData = new WorldLoginLoadingData(); ServerDataObjMgr.Instance.RegisterDataObj(loginLoadingData); //离线公会变动数据 WorldUnionChangeCacheData unionChangeCacheData = new WorldUnionChangeCacheData(); ServerDataObjMgr.Instance.RegisterDataObj(unionChangeCacheData); } private void RegisterAllService() { TraceLog.Debug("WorldServer.RegisterAllService"); m_messageHandler = new WorldMsgHandler(m_app); ServiceMgr.Instance.RegisterService(m_messageHandler); PlayerTableOp playerTableOp = new PlayerTableOp(WorldServerUtils.GetPlayerTable()); ServiceMgr.Instance.RegisterService(playerTableOp); EventHandlerMgr eventHandlerMgr = new EventHandlerMgr(); ServiceMgr.Instance.RegisterService(eventHandlerMgr); GmCmdSvc gmCmdSvc = new GmCmdSvc(); ServiceMgr.Instance.RegisterService(gmCmdSvc); //排队等待玩家数据操作 WaitInLinePlayerTableDataOp waitOp = new WaitInLinePlayerTableDataOp(WorldServerUtils.GetWaitInLinePlayerTableData()); ServiceMgr.Instance.RegisterService(waitOp); } } }