/* Sog 游戏基础库 2016 by zouwei */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using Sog; using Sog.Log; using ProtoCSStruct; namespace Friend { // 服务器入口 public class FriendServer : IScript { private Guid m_guid; private ServerApp m_app; private FriendMsgHandler m_messageHandler; private long m_oneSecondMs; private long m_5SecondMs; //测试用 /* private long oneTickTime; private long maxTickTime; private long allCountTick; private long allTimeTick; private Stopwatch m_stopwatch; */ public FriendServer() { m_guid = Guid.NewGuid(); } public IScriptHotfixCheck GetScriptHotfixCheck() { return new ServerScriptHotfixCheck(); } private void CommInitOnCreateReload(ServerApp app) { m_app = app; RegisterAllService(); FriendSvrIDUtils.Init(m_app); FriendServerUtils.GetEventHandlerMgr().RegisterAllEventHandler(); } public virtual void OnCreate(ServerApp app) { //打印消息统计日志 app.GetCluster().NeedLogMsgStat = true; m_app = app; RegisterAllDataObj(); CommInitOnCreateReload(app); TraceLog.Debug("FriendServer start at {0}, guid {1}", DateTime.Now, m_guid); } public virtual void OnHotfix(ServerApp app) { m_app = app; CommInitOnCreateReload(app); TraceLog.Debug("FriendServer hotfix at {0}, guid {1}", DateTime.Now, m_guid); } public virtual void OnReloadConfig(string excelConfigFile) { TraceLog.Debug("Server OnReloadConfig at {0}", DateTime.Now); ReadServerConfig(); } // TickNewDay每天只触发一次,如果内部调用的逻辑出错,要等到明天才有更新的机会 private void TickNewDay(long nowSec) { var svrData = FriendServerUtils.GetFriendServerData(); // world启动时会从文件WorldSvrData读入LastDayStartTime if (AppTime.IsSameDay(nowSec, svrData.m_lastDayStartTime)) { return; } svrData.m_lastDayStartTime = nowSec; } private void TickOneSecond(long nowMs, long nowSec) { if (nowMs < m_oneSecondMs + 1000) { return; } m_oneSecondMs = nowMs; TickServerStop(); PlayerTickSvc.OnTick(nowSec); } private void Tick5Second(long nowMs, long nowSec) { if (nowMs < m_5SecondMs + 5000) { return; } m_5SecondMs = nowMs; TickNewDay(nowSec); FriendRecommenTableSvc.Tick(nowSec); } private void TickServerStop() { if (m_app.IsStopping) { bool canStop = true; canStop = canStop && WaitAckStructRequestSender.Instance.IsEmpty(); canStop = canStop && FriendCacheSvc.IsAllDataSave(); TraceLog.Debug("FriendServer.TickServerStop canStop {0}", canStop); if (canStop) { m_app.SetStopSuccess(); } } } public virtual void OnTick(long nowMs) { //m_stopwatch = Stopwatch.StartNew(); long nowSec = m_app.GetTimeSecond(); TickOneSecond(nowMs, nowSec); Tick5Second(nowMs, nowSec); TickGetRealmList(nowSec); WaitAckStructRequestSender.Instance.Tick(nowMs); ServerStat.Instance.Tick(nowMs); FriendServerStat.Tick(nowMs); FriendTickSvc.Tick(nowMs); /* m_stopwatch.Stop(); oneTickTime = m_stopwatch.ElapsedMilliseconds; m_stopwatch.Reset(); allTimeTick += oneTickTime; allCountTick++; if (oneTickTime > maxTickTime) { maxTickTime = oneTickTime; } if (allCountTick >= 1000) { TraceLog.Trace("maxTickTime:{0},average tick time:{1},{2}..{3}..{4}",maxTickTime,allTimeTick/1000, GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2)); allCountTick = 0; allTimeTick = 0; maxTickTime = 0; } */ } public virtual void OnMessage(uint remoteAppID, MessageData message) { m_messageHandler.HandlerMessage(remoteAppID, message); } public virtual void OnStop() { FriendCacheSvc.OnStop(); } //所有引用对象置空 public void Dispose() { TraceLog.Debug("FriendServer be disposed"); m_app = null; m_messageHandler = null; } private void ReadServerConfig() { //读取配置文件 string strLogicServerConfig = m_app.GetCluster().GetAppConfigPath() + "/" + m_app.AppParam.ServerConfig.configfile; FriendServerConfig serverConfig = ServerConfigMgr.Instance.ReloadServerConfig(m_app, strLogicServerConfig); FriendServerUtils.GetFriendServerData().m_friendConfig = serverConfig; } private void RegisterAllDataObj() { TraceLog.Debug("FriendServer RegisterAllDataObj"); FriendServerData serverData = new FriendServerData(m_app); ServerDataObjMgr.Instance.RegisterDataObj(serverData); WaitAckStructRequestSender.Instance.Init(FriendServerUtils.GetPacketSender(), m_app.ServerID, m_app); ReadServerConfig(); TraceLog.Debug("RegisterAllDataObj, read WorldServerConfig"); //运营日志 BillLogWriter.Instance.Init(m_app.ServerID, FriendServerUtils.GetPacketSender()); //读取游戏数据文件 GameConfigMgr.Instance.ReadAllConfig(); AppTime.UpdateGameResetHour(CommParamDescMgr.Instance.CrossDaysTime.int_val); PlayerTable playerTable = new PlayerTable(); ServerDataObjMgr.Instance.RegisterDataObj(playerTable); FriendInfoCache friendCache = new FriendInfoCache( FriendConfig.GetFriendSelfCountMax(), FriendConfig.GetFriendListCountMax(), FriendConfig.GetFriendOpListCountMax(), FriendConfig.GetChatListCountMax(), 0); ServerDataObjMgr.Instance.RegisterDataObj(friendCache); FriendRecommendTable friendTable = new FriendRecommendTable(); ServerDataObjMgr.Instance.RegisterDataObj(friendTable); } private void RegisterAllService() { TraceLog.Debug("FriendServer RegisterAllService"); m_messageHandler = new FriendMsgHandler(m_app); ServiceMgr.Instance.RegisterService(m_messageHandler); PlayerTableOp playerTableOp = new PlayerTableOp(FriendServerUtils.GetPlayerTable()); ServiceMgr.Instance.RegisterService(playerTableOp); EventHandlerMgr eventHandlerMgr = new EventHandlerMgr(); ServiceMgr.Instance.RegisterService(eventHandlerMgr); GmCmdSvc gmCmdSvc = new GmCmdSvc(); ServiceMgr.Instance.RegisterService(gmCmdSvc); } private void TickGetRealmList(long nowSec) { var svrData = FriendServerUtils.GetFriendServerData(); int tickGap = 60; // 服务器刚启动时, tick间隔为5秒 if (svrData.m_realmInfosMap.Count == 0) { tickGap = 5; } if (nowSec - svrData.m_lastGetRealmTime < tickGap) { return; } svrData.m_lastGetRealmTime = nowSec; SSRankRealmlistReq req = new SSRankRealmlistReq(); FriendServerUtils.GetPacketSender().SendToWorldServer((int)SSGameMsgID.RankRealmlistReq, ref req, 0); } } }