/* Sog 游戏基础库 2016 by zouwei */ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Sog; using Sog.Log; using Sog.Service; using ProtoCSStruct; using System.IO; using System.Security.Cryptography; namespace Game { // 游戏服务器入口 public class GameServer : IScript { private const string m_dirtyListFile = "../cfg/sog/dirty.txt"; private Guid m_guid; private ServerApp m_app; private RootMessageHandler m_rootMessageHandler; private long m_tickSecondMs; private long m_tick1MinMs; // 1分钟 private long m_tick5MinMs; // 5分钟 public static GameDungeonCfg m_gameDungeonCfg = new GameDungeonCfg(); //public static GameInfoCache m_gameInfoCache = new GameInfoCache(); public string[] needMd5Desc = { "PayDiamondDesc.bin", "MarketShopGoodsDesc.bin", }; public static string shopMallDescMd5 = ""; public void UpdateShopMallDescMd5() { try { TaskEXEvent.OnReloadConfig(string.Empty); string[] AllFile = needMd5Desc; string strMd5 = ""; MD5 md5 = MD5.Create(); for (int i = 0; i < AllFile.Length; i++) { string fullPath = "../cfg/data/" + AllFile[i]; //这里有io,后面请求量大了有可能有点性能问题,可以优化成每几秒只读一次 if (!File.Exists(fullPath)) { TraceLog.Error("GameSvc.CalcPatchFileMd5 file {0} not exist", fullPath); } byte[] filecontent = File.ReadAllBytes(fullPath); byte[] bOne = md5.ComputeHash(filecontent); for (int j = 0; j < bOne.Length; j++) { strMd5 += bOne[j].ToString("x2"); } } byte[] bMd5 = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(strMd5)); shopMallDescMd5 = string.Empty; for (int i = 0; i < bMd5.Length; i++) { shopMallDescMd5 += bMd5[i].ToString("x2"); } TraceLog.Trace("UpdateShopMallDescMd5 {0}", shopMallDescMd5); } catch { TraceLog.Error("UpdateShopMallDescMd5 read and set md5 error"); } } public GameServer() { m_guid = Guid.NewGuid(); } public IScriptHotfixCheck GetScriptHotfixCheck() { return new ServerScriptHotfixCheck(); } //每次reload执行一次 private void CommInitOnCreateReload(ServerApp app) { m_app = app; RegisterAllService(); m_rootMessageHandler.RegisterAllPacketHandler(); GameServerUtils.GetEventHandlerMgr().RegisterAllEventHandler(); TaskTypeHandle.Init(); ActRankTigger.RegisterAll(); ActivityUtils.RegisterAll(); PatchSvc.RegisterAll(); JobSvc.Register(); } public virtual void OnCreate(ServerApp app) { //打印消息统计日志 app.GetCluster().NeedLogMsgStat = true; m_app = app; //数据对象只注册一次,reload的时候不变 RegisterAllDataObj(); GameConfigMgr.Instance.ReadAllConfig(true); //必须设置为true,创建时初始化过滤配置 AppTime.UpdateGameResetHour(CommParamDescMgr.Instance.CrossDaysTime.int_val); UpdateGameCurrency(); CommInitOnCreateReload(app); //各种表格的二次处理 //全服数据 ServerDataFileDbSvc.LoadDataFromFile(); PresetSvc.LoadDataFromFile(); //刷新随机挑战任务(目前没有了) //TaskSvc.ResetRandomTask(); //缓存英雄羁绊信息 //CacheHeroFetterInfo(); GameServerUtils.ReadAllCsvConfig(); TraceLog.Trace("GameServer start at {0}, guid {1} App.ServerStartTime {2}", DateTime.Now, m_guid, m_app.ServerStartTime); GameRankInfo.InitRankConfig(); CheckSomeError(); UpdateShopMallDescMd5(); } public void UpdateGameCurrency() { var cfg = (GameServerConfig)ServerConfigMgr.Instance.m_serverConfig; int currency = cfg.currency; TraceLog.Trace("GameServer.UpdateGameCurrency currency {0}", (Currency)currency); if (currency == 0 && !OSUtils.IsWindows()) { throw new Exception("currency is 0"); } PayDiamondDescMgr.Instance.UpdateGameCurrency(currency); } public virtual void OnHotfix(ServerApp app) { m_app = app; ReadServerConfig(); CommInitOnCreateReload(app); //GameServerUtils.ReadAllCsvConfig(); TraceLog.Debug("GameServer hotfix at {0}, guid {1}", DateTime.Now, m_guid); UpdateShopMallDescMd5(); } public virtual void OnReloadConfig(string excelConfigFile) { TraceLog.Debug("GameServer.OnReloadConfig at {0}", DateTime.Now); ReadServerConfig(); LimitIPList.Clear(); UpdateGameCurrency(); UpdateShopMallDescMd5(); if (GameServerUtils.GetEventHandlerMgr().TriggerReloadConfig != null) { GameServerUtils.GetEventHandlerMgr().TriggerReloadConfig(excelConfigFile); } } private void TickSecond(long nowMs, long nowSec) { if (nowMs < m_tickSecondMs + 1000) { return; } m_tickSecondMs = nowMs; GameServerUtils.GetGameReportSvc().OnTick(nowSec); PlayerAutoReOnlineForBillSvc.OnTick(nowSec); Tick1Min(nowMs, nowSec); Tick5Min(nowMs, nowSec); } private void Tick1Min(long nowMs, long nowSec) { // 第一次启动等待10秒再拉取 if (nowMs < m_tick1MinMs + 60000 || (m_tick1MinMs == 0 && nowSec < m_app.ServerStartTime + 10)) { return; } // 1分钟更新1次所有realm的简要信息 GameReportSvc.GetAllRealmBrief(nowSec); // 上报在线数据 GameReportSvc.ReportRealmOnlineToWorld(); m_tick1MinMs = nowMs; } private void Tick5Min(long nowMs, long nowSec) { // 第一次启动等待10秒再拉取 if (nowMs < m_tick5MinMs + 300000 || (m_tick5MinMs == 0 && nowSec < m_app.ServerStartTime + 10)) { return; } //for (int i = 0; i < 20; i++) //{ // RankSvc.UpdateRankList(i+1); //} //ArenaSvc.TickUpdataRankList(); m_tick5MinMs = nowMs; } public virtual void OnTick(long nowMs) { GameServerUtils.GetPlayerDataSvc().OnTick(nowMs); GameServerStat.Tick(nowMs); GameServerTickSvc.Tick100MsAddTreasure(nowMs); //服务器数据tick管理, 逻辑tick入口 GameServerTickSvc.TickServerData(nowMs); //玩家tick管理,逻辑tick入口 PlayerTickSvc.TickAllPlayer(nowMs); WaitAckStructRequestSender.Instance.Tick(nowMs); ServerDataFileDbSvc.OnTick(nowMs); PresetSvc.OnTick(nowMs); long nowSec = m_app.GetTimeSecond(); TickSecond(nowMs, nowSec); StopServerSvc.Tick(nowMs); //ArenaSvc.OnTick(nowSec); } public virtual void OnMessage(uint remoteAppID, MessageData message) { m_rootMessageHandler.HandlerMessage(remoteAppID, message); } public virtual void OnStop() { //MainlandSvc.SaveAbyssRecording(); //HundredTowerEvent.OnHundredTowerRealmStop(); } //所有引用对象置空 public void Dispose() { TraceLog.Debug("GameServer be disposed"); m_app = null; m_rootMessageHandler = null; } private void ReadServerConfig() { TraceLog.Debug("GameServer.ReadServerConfig timezone {0}", AppTime.TimeZone); //读取配置文件 string strLogicServerConfig = m_app.GetCluster().GetAppConfigPath() + "/" + m_app.AppParam.ServerConfig.configfile; GameServerConfig serverConfig = ServerConfigMgr.Instance.ReloadServerConfig(m_app, strLogicServerConfig); //玩家日志初始化 TraceLog.InitUserLog(m_app.AppParam.ServerConfig.logpath , serverConfig.userLog.userlogname , LogLevel.ParseFromString(serverConfig.userLog.userloglevel) , serverConfig.userLog.userlogAll , serverConfig.userLog.userlogSome); TraceLog.Debug("GameServer.ReadServerConfig permitAddServerTime:{0} permitCliAddServerTime:{1}", serverConfig.permitAddServerTime, serverConfig.permitCliAddServerTime); } private void RegisterAllDataObj() { TraceLog.Debug("GameServer RegisterAllDataObj"); GameServerData gameServerData = new GameServerData(m_app); ServerDataObjMgr.Instance.RegisterDataObj(gameServerData); WaitAckStructRequestSender.Instance.Init(GameServerUtils.GetPacketSender(), m_app.ServerID, m_app); DiamondHolderData dhData = new DiamondHolderData(); ServerDataObjMgr.Instance.RegisterDataObj(dhData); ReadServerConfig(); PlayerTable playerTable = new PlayerTable(); ServerDataObjMgr.Instance.RegisterDataObj(playerTable); BattleServerVersionData battleVesionData = new BattleServerVersionData(); ServerDataObjMgr.Instance.RegisterDataObj(battleVesionData); //运营日志 BillLogWriter.Instance.Init(m_app.ServerID, gameServerData.m_packetSender); } private void RegisterAllService() { TraceLog.Debug("GameServer RegisterAllService"); //消息handler管理服务,需要在所有handler之前创建 m_rootMessageHandler = new RootMessageHandler(m_app, GameServerUtils.GetGameServerData()); ServiceMgr.Instance.RegisterService(m_rootMessageHandler); PlayerTableOp playerTableOp = new PlayerTableOp(GameServerUtils.GetPlayerTable()); ServiceMgr.Instance.RegisterService(playerTableOp); LoginHandler loginHandler = new LoginHandler(); ServiceMgr.Instance.RegisterService(loginHandler); GameReportSvc gameReportSvc = new GameReportSvc(); ServiceMgr.Instance.RegisterService(gameReportSvc); GmCmdSvc gmCmdSvc = new GmCmdSvc(); ServiceMgr.Instance.RegisterService(gmCmdSvc); PlayerDataSvc playerDataSvr = new PlayerDataSvc(); ServiceMgr.Instance.RegisterService(playerDataSvr); PayHandler payHandler = new PayHandler(); ServiceMgr.Instance.RegisterService(payHandler); SysHandler sysHandler = new SysHandler(); ServiceMgr.Instance.RegisterService(sysHandler); FriendHandler friendHandler = new FriendHandler(); ServiceMgr.Instance.RegisterService(friendHandler); FriendOpHandler friendOpHandler = new FriendOpHandler(); ServiceMgr.Instance.RegisterService(friendOpHandler); MailHandler mailHandler = new MailHandler(); ServiceMgr.Instance.RegisterService(mailHandler); EventHandlerMgr eventHandlerMgr = new EventHandlerMgr(); ServiceMgr.Instance.RegisterService(eventHandlerMgr); BagHandler bagHandler = new BagHandler(); ServiceMgr.Instance.RegisterService(bagHandler); DynamicMsgHandler dynamicHandler = new DynamicMsgHandler(); ServiceMgr.Instance.RegisterService(dynamicHandler); RankHandler rankHandler = new RankHandler(); ServiceMgr.Instance.RegisterService(rankHandler); TaskEXHandler taskEXHandler = new TaskEXHandler(); ServiceMgr.Instance.RegisterService(taskEXHandler); EquipmentHandler equipmentHandler = new EquipmentHandler(); ServiceMgr.Instance.RegisterService(equipmentHandler); LevelHandler levelHandler = new LevelHandler(); ServiceMgr.Instance.RegisterService(levelHandler); //EliteMainlandHandler eliteHandler = new EliteMainlandHandler(); //ServiceMgr.Instance.RegisterService(eliteHandler); MarketShopHandler marketShopHandler = new MarketShopHandler(); ServiceMgr.Instance.RegisterService(marketShopHandler); NameHandler nameHandler = new NameHandler(); ServiceMgr.Instance.RegisterService(nameHandler); ExchangeCodeHandler exchangeCodeHandler = new ExchangeCodeHandler(m_rootMessageHandler); ServiceMgr.Instance.RegisterService(exchangeCodeHandler); HomeAdHandler homeAdHandler = new HomeAdHandler(); ServiceMgr.Instance.RegisterService(homeAdHandler); BeginnerGuideHandler beginnerGuideHandler = new BeginnerGuideHandler(); ServiceMgr.Instance.RegisterService(beginnerGuideHandler); ChatHandler chatHandler = new ChatHandler(); ServiceMgr.Instance.RegisterService(chatHandler); MonitorHandler monitorHandler = new MonitorHandler(); ServiceMgr.Instance.RegisterService(monitorHandler); } //加一些保护逻辑 private void CheckSomeError() { //支付商品数量不能超过玩家身上的PayItemRecord最大数量 var tables = PayDiamondDescMgr.Instance.ItemTable; int totalCount = tables.Count; DBRolePayData payData = new DBRolePayData(); if (totalCount > payData.PayItemRecord.GetMaxCount()) { string errorString = string.Format("CheckSomeError PayDiamondDesc count {0} must < PaySuccessRecord.GetMaxCount {1}", totalCount, payData.PayItemRecord.GetMaxCount()); TraceLog.Error(errorString); System.Threading.Thread.Sleep(1000); throw new Exception(errorString); } } } }