You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

481 lines
15 KiB

/*
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<GameServerConfig>(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);
}
}
}
}