feat: initial commit - HJHA game server full source
6 major server modules (PdkFriendServer/GlobalSever/ServerCore/GameModule/GameNetModule) + game logic (GameFix/GameDAL/ServerData) + network layer (NetWorkMessage) + data layer (ObjectModel) + utilities (MrWu/Core/Config/CloudAPI/dll) + adapters (zyxAdapter/base) .NET 8.0 C# solution, 16 projects, 958 source files
This commit is contained in:
846
GlobalSever/GlobalManager/GlobalManager.cs
Normal file
846
GlobalSever/GlobalManager/GlobalManager.cs
Normal file
@ -0,0 +1,846 @@
|
||||
/*
|
||||
* 由SharpDevelop创建。
|
||||
* 用户: Administrator
|
||||
* 日期: 2018-09-13
|
||||
* 时间: 17:14
|
||||
*
|
||||
* 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using GameData;
|
||||
using MrWu.Debug;
|
||||
using MrWu.RabbitMQ;
|
||||
using Server.Data.Module;
|
||||
using Server.DB.Redis;
|
||||
using Server.DB.Sql;
|
||||
using Server.MQ;
|
||||
using Server.Pack;
|
||||
using Server.Config;
|
||||
using Server.Core;
|
||||
using Server.Net;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
/// <summary>
|
||||
/// 全局管理
|
||||
/// </summary>
|
||||
public abstract partial class GlobalManager : ITimerProcessor, IServer
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否需要重新加载配置
|
||||
/// </summary>
|
||||
public bool IsReloadTable;
|
||||
|
||||
/// <summary>
|
||||
/// 服务器单元工厂
|
||||
/// </summary>
|
||||
public static ServerUtilFactory Factory;
|
||||
|
||||
private static GlobalManager mInstance;
|
||||
|
||||
/// <summary>
|
||||
/// 每个服务器只能管理一个服务,单例模式
|
||||
/// </summary>
|
||||
public static GlobalManager instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (mInstance == null)
|
||||
mInstance = Factory.GetGlobalManager();
|
||||
return mInstance;
|
||||
}
|
||||
}
|
||||
|
||||
#region 数据
|
||||
|
||||
/// <summary>
|
||||
/// 是否自杀
|
||||
/// </summary>
|
||||
public bool isKill { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否可以开战,关闭服务器前先禁止,然后再关闭服务器
|
||||
/// </summary>
|
||||
public bool IsCanWar = true;
|
||||
|
||||
/// <summary>
|
||||
/// 客户端要得到的配置
|
||||
/// </summary>
|
||||
public ConfigHead ClientConfig;
|
||||
|
||||
/// <summary>
|
||||
/// 服务器信息
|
||||
/// </summary>
|
||||
protected ServerInfo m_serverinfo;
|
||||
|
||||
/// <summary>
|
||||
/// 服务器信息
|
||||
/// </summary>
|
||||
public virtual ServerInfo serverinfo
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_serverinfo == null)
|
||||
m_serverinfo = new ServerInfo();
|
||||
return m_serverinfo;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 获取配置头
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected virtual ConfigHead GetConfigHead()
|
||||
{
|
||||
ConfigHead cfh = new ConfigHead();
|
||||
cfh.style = 1;
|
||||
cfh.id = ServerConfigManager.Instance.NodeId;
|
||||
cfh.num = ServerConfigManager.Instance.NodeNum;
|
||||
cfh.maxSVer = ServerConfigManager.Instance.MaxVer;
|
||||
cfh.minSVer = ServerConfigManager.Instance.MinVer;
|
||||
cfh.maxCver = ServerConfigManager.Instance.MaxCVer;
|
||||
cfh.minCver = ServerConfigManager.Instance.MinCVer;
|
||||
return cfh;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置系统时间间隔
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
[DllImport("winmm")]
|
||||
protected static extern void timeBeginPeriod(int t);
|
||||
|
||||
/// <summary>
|
||||
/// 恢复系统时间间隔
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
[DllImport("winmm")]
|
||||
protected static extern void timeEndPeriod(int t);
|
||||
|
||||
/// <summary>
|
||||
/// 定时器管理
|
||||
/// </summary>
|
||||
private TimerManager timermgr;
|
||||
|
||||
/// <summary>
|
||||
/// 更新服务器信息的时间
|
||||
/// </summary>
|
||||
public int updateServerInfo_time;
|
||||
|
||||
/// <summary>
|
||||
/// 更新服务器信息
|
||||
/// </summary>
|
||||
protected virtual void UpdateServerInfo(bool isStart = false)
|
||||
{
|
||||
timeBeginPeriod(1);
|
||||
|
||||
serverinfo.moduleId = myUtil.id;
|
||||
serverinfo.nodenum = myUtil.nodeNum;
|
||||
if (isStart)
|
||||
serverinfo.startTime = DateTime.Now;
|
||||
|
||||
serverinfo.serverName = ServerName;
|
||||
serverinfo.dopackCnt = 0;
|
||||
serverinfo.minfps = minfps;
|
||||
serverinfo.fps = Fps;
|
||||
serverinfo.maxRuntime = maxruntiming;
|
||||
serverinfo.ConnectCnt = UserSessionsInfo.GetAllSessionCount();
|
||||
serverinfo.BindConnectCnt = UserSessionsInfo.GetBindSessionCount();
|
||||
|
||||
updateServerInfo_time = ServerConfigManager.Instance.UpdateServerInfoTime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新
|
||||
/// </summary>
|
||||
protected virtual void Update()
|
||||
{
|
||||
TimeInfo.Instance.Update();
|
||||
// long key = Debug.StartTiming();
|
||||
GameNetDispatcher.Instance.Update();
|
||||
GlobalDispatcher.Instance.Update();
|
||||
GameDispatcher.Instance.Update();
|
||||
|
||||
// double runtime = Debug.GetRunTime(key);
|
||||
// if (runtime > 200)
|
||||
// {
|
||||
// Debug.Error($"Update: 处理慢:{runtime}");
|
||||
// }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected virtual bool Init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private void DayChange()
|
||||
{
|
||||
GameDispatcher.Instance.Dispatch(GameMsgId.DayChange);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// fps计数
|
||||
/// </summary>
|
||||
private int fpscount = -1;
|
||||
|
||||
/// <summary>
|
||||
/// 帧率
|
||||
/// </summary>
|
||||
public int Fps { get; protected set; }
|
||||
|
||||
private int m_minfps = -1;
|
||||
|
||||
/// <summary>
|
||||
/// 最小fps
|
||||
/// </summary>
|
||||
public int minfps
|
||||
{
|
||||
get { return m_minfps; }
|
||||
protected set { m_minfps = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 最大运行时间
|
||||
/// </summary>
|
||||
public double maxruntiming { get; protected set; }
|
||||
|
||||
private System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
|
||||
|
||||
/// <summary>
|
||||
/// 发送配置包裹
|
||||
/// </summary>
|
||||
protected virtual void SendConfigPack()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理模块死亡信号
|
||||
/// </summary>
|
||||
/// <param name="node"></param>
|
||||
/// <param name="nodenum"></param>
|
||||
protected void DoModuleDieSign(object param)
|
||||
{
|
||||
if (param is ServerNode serverNode)
|
||||
{
|
||||
Debug.Info("模块死亡包处理!");
|
||||
|
||||
PackHead head = PackHead.Create();
|
||||
head.packlx = ServerPackAgreement.ModuleDie;
|
||||
Message msg = GlobalMQ.CreateMessage(head, serverNode);
|
||||
GlobalMQ.instance.AddMessage(msg);
|
||||
head.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送开启节点包
|
||||
/// </summary>
|
||||
protected virtual void SendOpenNode()
|
||||
{
|
||||
//注册模块
|
||||
PackHead head = PackHead.Create();
|
||||
head.packlx = ServerPackAgreement.openNode;
|
||||
var data = this.myType != ModuleType.WatchDog ? MonitoringAppInfo : null;
|
||||
GlobalMQ.instance.DeliveryAll(GlobalMQ.CreateMessage(head, data), true);
|
||||
head.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送关闭节点包
|
||||
/// </summary>
|
||||
protected void SendCloseNode()
|
||||
{
|
||||
PackHead head = PackHead.Create();
|
||||
head.packlx = ServerPackAgreement.closeNode;
|
||||
var data = this.myType != ModuleType.WatchDog ? MonitoringAppInfo : null;
|
||||
|
||||
GlobalMQ.instance.DeliveryAll(GlobalMQ.CreateMessage(head, data), true);
|
||||
head.Dispose();
|
||||
}
|
||||
|
||||
//自身主机信息应该是不变的。 暂存这个信息
|
||||
MonitoringAppInfo MonitoringAppInfo =>
|
||||
MonitoringAppInfo.GetCurrentApplicateInfo(this.myUtil.onlyId, this.myUtil.id, this.myUtil.nodeNum);
|
||||
|
||||
/// <summary>
|
||||
/// 退出游戏
|
||||
/// </summary>
|
||||
public virtual void Quit()
|
||||
{
|
||||
state = ServerState.Stoping;
|
||||
}
|
||||
|
||||
#region ITimerProcessor
|
||||
|
||||
/// <summary>
|
||||
/// 100毫秒定时器
|
||||
/// </summary>
|
||||
public virtual void OnTime(int Interval)
|
||||
{
|
||||
//Debug.Log("秒级定时器:" + "," + System.DateTime.Now.Ticks);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 记录天
|
||||
/// </summary>
|
||||
int Day = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 秒级定时器
|
||||
/// </summary>
|
||||
public virtual void SecondTime()
|
||||
{
|
||||
updateServerInfo_time--;
|
||||
|
||||
if (updateServerInfo_time == 0)
|
||||
{
|
||||
UpdateServerInfo();
|
||||
}
|
||||
|
||||
DoFps();
|
||||
|
||||
if (Day != DateTime.Now.Day)
|
||||
{
|
||||
Day = DateTime.Now.Day;
|
||||
DayInit();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 每一天初始化一次
|
||||
/// </summary>
|
||||
public virtual void DayInit()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理Fps的赋值
|
||||
/// </summary>
|
||||
protected virtual void DoFps()
|
||||
{
|
||||
if (minfps < 0 || minfps > fpscount)
|
||||
{
|
||||
minfps = fpscount;
|
||||
//Debug.Warning("fps最低记录:" + minfps);
|
||||
}
|
||||
|
||||
Fps = fpscount;
|
||||
fpscount = 0;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 缓存变化
|
||||
/// </summary>
|
||||
/// <param name="msg"></param>
|
||||
protected virtual void CacheChange(WaitBeMsg msg)
|
||||
{
|
||||
var head = msg.head;
|
||||
if (head.otherString == null || head.otherString.Length == 0)
|
||||
return;
|
||||
Debug.Info("处理缓存更新!" + head.otherString[0]);
|
||||
CaCheManager.instance.UpdateKeyAsync(head.otherString[0]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理其他
|
||||
/// </summary>
|
||||
/// <param name="msg"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual bool HandleOtherServerPack(WaitBeMsg msg) => false;
|
||||
|
||||
/// <summary>
|
||||
/// 处理模块死亡信号——意外死亡
|
||||
/// </summary>
|
||||
/// <param name="msg"></param>
|
||||
protected virtual void ModuleDie(WaitBeMsg msg)
|
||||
{
|
||||
var data = JsonPack.GetData<ServerNode>(msg.jsondata);
|
||||
if (data == null)
|
||||
Debug.Error("数据错误!");
|
||||
else
|
||||
Debug.Warning("模块死亡信号:" + data.id + "," + data.nodeNum);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected virtual void Ping(PackHead head, string jsondata)
|
||||
{
|
||||
ModuleUtile util = JsonPack.GetData<ModuleUtile>(jsondata);
|
||||
if (util == null)
|
||||
Debug.Error("收到网络监测包数据为空!");
|
||||
head.packlx = ServerPackAgreement.Pong;
|
||||
GlobalMQ.instance.DeliveryOne(new ServerNode(util.id, util.nodeNum), GlobalMQ.CreateMessage(head, myUtil),
|
||||
true);
|
||||
|
||||
Debug.Info("发送探测包:" + myUtil.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="head"></param>
|
||||
/// <param name="jsondata"></param>
|
||||
protected virtual void Pong(PackHead head, string jsondata)
|
||||
{
|
||||
ModuleUtile util = JsonPack.GetData<ModuleUtile>(jsondata);
|
||||
if (util == null)
|
||||
Debug.Error("收到网络探测回包数据为空!");
|
||||
else
|
||||
Debug.Info("Pong : " + util.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 心跳处理包
|
||||
/// </summary>
|
||||
/// <param name="msg">消息</param>
|
||||
protected virtual void Heart(WaitBeMsg msg)
|
||||
{
|
||||
PackHead head = msg.head;
|
||||
ServerNode node = head.sendutil;
|
||||
if (node == null)
|
||||
{
|
||||
Debug.Error("心跳包错误,没有发送者的描述!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.Equals(myUtil)) //自己的包不处理
|
||||
return;
|
||||
|
||||
//ServerHeart.instanece.DoHeartAsync(node.id, node.nodeNum);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 节点开启信号
|
||||
/// </summary>
|
||||
/// <param name="msg">消息</param>
|
||||
[System.Diagnostics.DebuggerNonUserCode]
|
||||
protected virtual void RecvOpenNode(WaitBeMsg msg)
|
||||
{
|
||||
PackHead head = msg.head;
|
||||
ModuleUtile node = head.sendutil;
|
||||
if (node == null)
|
||||
{
|
||||
Debug.Error("节点开启信号包错误,没有发送者的描述!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.Equals(myUtil))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Debug.Info($"接收到模块开启:{node.ToString()}");
|
||||
|
||||
RountingManager.instance.AddModule(node.id, node.name);
|
||||
|
||||
if (node.id == (int)ModuleType.ConfigModule)
|
||||
{
|
||||
SendConfigPack();
|
||||
}
|
||||
|
||||
if (head.otherString == null || head.otherString.Length == 0 || head.otherString[0] != "ok")
|
||||
{
|
||||
head.packlx = ServerPackAgreement.openNode;
|
||||
head.otherString = new string[] { "ok" };
|
||||
var data = this.myType != ModuleType.WatchDog ? MonitoringAppInfo : null;
|
||||
var sendmsg = GlobalMQ.CreateMessage(head, data, null, -1, -1, null, null);
|
||||
GlobalMQ.instance.DeliveryOne(node, sendmsg, true);
|
||||
}
|
||||
|
||||
ServerHeart.instanece.AddModule(node.id, node.name, node.nodeNum);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 节点关闭信号_正常关闭
|
||||
/// </summary>
|
||||
/// <param name="msg">消息</param>
|
||||
protected virtual void RecvCloseNode(WaitBeMsg msg)
|
||||
{
|
||||
ModuleUtile node = msg.head.sendutil;
|
||||
|
||||
if (node == null)
|
||||
{
|
||||
Debug.Error("收到节点关闭信号,没有发送者的描述!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.Equals(myUtil))
|
||||
{
|
||||
//是本模块
|
||||
if (node.onlyId != myUtil.onlyId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (state == ServerState.Runing)
|
||||
{
|
||||
//检测到已经死了
|
||||
//直接退出
|
||||
Debug.Error("收到死完包!直接退出!");
|
||||
state = ServerState.Error;
|
||||
return;
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
//模块死亡信号
|
||||
ServerHeart.instanece.RemoveDie(node.id, node.nodeNum, true);
|
||||
Debug.Warning("收到模块关闭信号:" + node);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理命令
|
||||
/// </summary>
|
||||
protected virtual void DoCommand(WaitBeMsg msg)
|
||||
{
|
||||
string[] cmds = msg.head.otherString;
|
||||
if (cmds == null || cmds.Length <= 0)
|
||||
return;
|
||||
|
||||
Debug.Info("收到命令" + cmds[0]);
|
||||
|
||||
switch (cmds[0])
|
||||
{
|
||||
case "exit":
|
||||
Quit();
|
||||
break;
|
||||
case "test":
|
||||
break;
|
||||
case "onlineModules": //在线的所有模块
|
||||
Debug.Log("所有的在线模块");
|
||||
break;
|
||||
|
||||
case "redislocktest":
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// DistributedLock
|
||||
/// </summary>
|
||||
protected DistributedLock dtl { get; } = new DistributedLock(1000);
|
||||
|
||||
#region IServer
|
||||
|
||||
/// <summary>
|
||||
/// 服务器状态
|
||||
/// </summary>
|
||||
public ServerState state { get; set; } = ServerState.Close;
|
||||
|
||||
/// <summary>
|
||||
/// 服务器名称
|
||||
/// </summary>
|
||||
public string ServerName
|
||||
{
|
||||
get
|
||||
{
|
||||
return ServerConfigManager.Instance.ServerName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 我的模块单元
|
||||
/// </summary>
|
||||
public ModuleUtile myUtil { get; protected set; }
|
||||
|
||||
private ModuleType mMyType;
|
||||
|
||||
/// <summary>
|
||||
/// 模块类型
|
||||
/// </summary>
|
||||
public ModuleType myType
|
||||
{
|
||||
get { return mMyType; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 消息处理器
|
||||
/// </summary>
|
||||
public MessageProcessor msgProcessor;
|
||||
|
||||
/// <summary>
|
||||
/// 其他配置初始化
|
||||
/// </summary>
|
||||
public virtual void OtherConfigInit()
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (int i = 0; i < 50; i++)
|
||||
{
|
||||
stringBuilder.Append('0');
|
||||
}
|
||||
|
||||
if (ServerConfigManager.Instance.GameConfig != null)
|
||||
{
|
||||
ServerConfigManager.Instance.GameConfig.GameGz = stringBuilder.ToString();
|
||||
|
||||
if (ServerConfigManager.Instance.TingCnt > 0)
|
||||
{
|
||||
foreach (var ting in ServerConfigManager.Instance.Tings)
|
||||
{
|
||||
ting.TingGz = stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 检查配置表是否有问题
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public virtual bool CheckConfig()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
public bool Start()
|
||||
{
|
||||
//启动中
|
||||
state = ServerState.Starting;
|
||||
|
||||
mMyType = (ModuleType)ServerConfigManager.Instance.NodeId;
|
||||
|
||||
myUtil = new ModuleUtile(ServerConfigManager.Instance.NodeId,
|
||||
ServerConfigManager.Instance.NodeNum,
|
||||
Enum.GetName(myType.GetType(), myType),
|
||||
ServerConfigManager.Instance.MaxVer);
|
||||
|
||||
TimeInfo.Instance.DayChange += DayChange;
|
||||
|
||||
//序列化预热
|
||||
PreLoadMessagePack();
|
||||
|
||||
GlobalDispatcher.Instance.Dispatch(GlobalMsgId.GameNameReadSuccess, ServerConfigManager.Instance.ServerName);
|
||||
Debug.Info($"Start ServerName:{ServerConfigManager.Instance.ServerName}");
|
||||
|
||||
//数据库初始化
|
||||
GameDB.Instance.Init(SqlConfigCategory.Instance.GetDBSqlConfig());
|
||||
|
||||
//redis启动
|
||||
redisManager.Start();
|
||||
|
||||
ClientConfig = GetConfigHead();
|
||||
|
||||
//存储自己的模块信息
|
||||
if (!redisManager.db.HashExists(RedisDictionary.moduleNames, ServerConfigManager.Instance.NodeId.ToString()))
|
||||
redisManager.db.HashSet(RedisDictionary.moduleNames, ServerConfigManager.Instance.NodeId, myUtil.name);
|
||||
|
||||
//心跳开始,并检查模块是否在线
|
||||
if (!ServerHeart.instanece.Start(myType, ServerConfigManager.Instance.NodeNum))
|
||||
{
|
||||
Debug.ImportantLog("启动失败,模块在线!");
|
||||
return false;
|
||||
}
|
||||
|
||||
MessagePool.tag = "" + myUtil.id + "-" + myUtil.nodeNum + "-" + myUtil.ver + "-" + myUtil.name;
|
||||
|
||||
//模块死亡事件监听
|
||||
GlobalDispatcher.Instance.AddListener(GlobalMsgId.ModuleNodeDie, DoModuleDieSign);
|
||||
|
||||
//创建消息处理
|
||||
Factory.CreateGlobalMQFactory().CreateGlobalMQ();
|
||||
|
||||
//启动rabbit
|
||||
if (!GlobalMQ.instance.StartModule(RabbitConfigCategory.Instance.GetRabbitMQConfig(), myUtil))
|
||||
{
|
||||
Debug.Error("启动失败:A71134F4-EA97-44C0-A305-E35966622FEB");
|
||||
return false;
|
||||
}
|
||||
|
||||
msgProcessor = Factory.CreateMessageProcessor();
|
||||
|
||||
new UserSessionsManager().Register();
|
||||
//重要数据启动
|
||||
if (!Init())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Debug.ImportantLog("init over!!!");
|
||||
//发送开启信号
|
||||
SendOpenNode();
|
||||
|
||||
//定时器管理
|
||||
timermgr = new TimerManager(ServerConfigManager.Instance.OnTime);
|
||||
timermgr.Start();
|
||||
|
||||
//更改状态为运行中
|
||||
state = ServerState.Runing;
|
||||
|
||||
//更新服务器信息
|
||||
UpdateServerInfo(true);
|
||||
|
||||
//开始发送心跳包
|
||||
ServerHeart.instanece.BeginHeart(Factory.CreateHeartPack(myUtil));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private StringBuilder logs = new StringBuilder();
|
||||
|
||||
private int GcCount = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 预热 MessagePack
|
||||
/// </summary>
|
||||
protected virtual void PreLoadMessagePack()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void ReLoadTable()
|
||||
{
|
||||
TableManager.Instance.ReLoadTableData();
|
||||
|
||||
try
|
||||
{
|
||||
ReLoadTableInit();
|
||||
Debug.ImportantLog("配置重新加载成功!");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Error("重载配置出错!" + e.Message);
|
||||
TableManager.Instance.RollBack();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void ReLoadTableInit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 主线程
|
||||
/// </summary>
|
||||
public void Loop()
|
||||
{
|
||||
if (state == ServerState.Runing)
|
||||
{
|
||||
try
|
||||
{
|
||||
logs.Clear();
|
||||
watch.Restart();
|
||||
//watch.Restart();
|
||||
|
||||
if (IsReloadTable)
|
||||
{
|
||||
IsReloadTable = false;
|
||||
ReLoadTable();
|
||||
}
|
||||
|
||||
if (timermgr.GetMillScoend())
|
||||
{
|
||||
#if DEBUG
|
||||
var key = Debug.StartTiming();
|
||||
logs.AppendLine($"GlobalManager Loop DoTime begin");
|
||||
#endif
|
||||
OnTime(timermgr.Interval);
|
||||
#if DEBUG
|
||||
logs.AppendLine($"GlobalManager Loop DoTime end, time: {Debug.GetRunTime(key)}");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (timermgr.GetSecoend())
|
||||
{
|
||||
#if DEBUG
|
||||
var key = Debug.StartTiming();
|
||||
logs.AppendLine($"GlobalManager Loop DoTimeSecond begin");
|
||||
#endif
|
||||
SecondTime();
|
||||
#if DEBUG
|
||||
logs.AppendLine($"GlobalManager Loop DoTimeSecond end, time: {Debug.GetRunTime(key)}");
|
||||
#endif
|
||||
}
|
||||
|
||||
//消息处理
|
||||
msgProcessor.Run(logs);
|
||||
|
||||
#if DEBUG
|
||||
var updateKey = Debug.StartTiming();
|
||||
#endif
|
||||
fpscount++;
|
||||
Update();
|
||||
#if DEBUG
|
||||
logs.AppendLine($"Update Loop time:{Debug.GetRunTime(updateKey)}");
|
||||
#endif
|
||||
watch.Stop();
|
||||
double runtime = watch.ElapsedMilliseconds; //.ElapsedMilliseconds;
|
||||
|
||||
if (runtime >= 100)
|
||||
{
|
||||
logs.AppendLine(
|
||||
$"GlobalManager Loop end, now: {DateTime.Now}, runtime: {runtime} / {watch.Elapsed.TotalMilliseconds}");
|
||||
|
||||
Debug.Error($"Loop runtime warning: " + logs.ToString());
|
||||
}
|
||||
|
||||
if (runtime > maxruntiming)
|
||||
maxruntiming = runtime;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Error("主线程错误:" + e.ToString());
|
||||
}
|
||||
}
|
||||
else if (state == ServerState.Stoping)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 阻塞检查,直到正常退出
|
||||
/// </summary>
|
||||
public virtual void Close()
|
||||
{
|
||||
UUIDManager.Instance.Close();
|
||||
UserSessionsManager.Instance.Dispose();
|
||||
timermgr.Stop();
|
||||
|
||||
SendCloseNode();
|
||||
ServerHeart.instanece.Close();
|
||||
//ServerManager.instance.Close();
|
||||
if (GlobalMQ.instance != null)
|
||||
GlobalMQ.instance.Close();
|
||||
|
||||
//保存道具日志
|
||||
PropManager.Instance.Dispose();
|
||||
state = ServerState.Stop;
|
||||
|
||||
Debug.Log("模块正常退出!");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 收到获取在线人数的请求
|
||||
/// </summary>
|
||||
/// <param name="msg"></param>
|
||||
protected virtual void ReportPlayerOnLineData(WaitBeMsg msg)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user