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.
819 lines
27 KiB
819 lines
27 KiB
using System;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Diagnostics;
|
|
|
|
using Sog.Log;
|
|
using Sog.IO;
|
|
|
|
namespace Sog
|
|
{
|
|
/*
|
|
* 服务器统一入口,不同的服务器逻辑加载不同的逻辑dll
|
|
* dll支持reload(hotfix)
|
|
* 不支持卸载,只能重复加载,每reload一次内存会变大一些,不要太频繁reload问题不大
|
|
* 测试结果:reload一次内存增加个几百k的样子
|
|
*/
|
|
public class ServerEntry
|
|
{
|
|
private ServerApp m_app;
|
|
private ServerType m_serverType;
|
|
|
|
private AppParam m_appParam;
|
|
private IScript m_scriptObj;
|
|
private IScript m_scriptObjReloaded;
|
|
private IShareCommand m_shareCommand;
|
|
|
|
|
|
private long m_lastReadShmCommandTime = 0;
|
|
private long m_serverStartTime = 0;
|
|
|
|
private Mutex m_procMutex;
|
|
|
|
//工作线程
|
|
private Thread m_workThread;
|
|
private bool m_serverCanExit = false;
|
|
private string m_serverCommand;
|
|
|
|
// reload测试模式, 每分钟reload一次
|
|
private int m_reloadedCount = 0;
|
|
private long m_needReloadTime = 0;
|
|
private int m_testReloadCount;
|
|
|
|
public ServerApp GetApp()
|
|
{
|
|
return m_app;
|
|
}
|
|
|
|
public ServerEntry(AppParam appParam)
|
|
{
|
|
m_appParam = appParam;
|
|
|
|
m_app = new ServerApp(m_appParam);
|
|
|
|
m_serverType = (ServerType)ServerIDUtils.GetServerType(m_app.ServerID);
|
|
|
|
//初始化日志等级,文件路径,文件名
|
|
TraceLog.SetLogPathName(m_appParam.ServerConfig.logpath, m_appParam.ServerConfig.logname);
|
|
SetLogReloadableParam();
|
|
|
|
//只运行模式
|
|
if (m_appParam.RunMode == AppRunMode.Run)
|
|
{
|
|
m_app.OnTick += this.OnTick;
|
|
}
|
|
|
|
m_testReloadCount = 0;
|
|
|
|
//gate 在使用异步模式的时候由于涉及到异步模式回掉dll里的函数,reload会出问题,所以不支持
|
|
if (m_serverType == ServerType.AccountGate ||
|
|
m_serverType == ServerType.GameGate ||
|
|
m_serverType == ServerType.VersionGate ||
|
|
m_serverType == ServerType.ChatGate ||
|
|
m_serverType == ServerType.Operation ||
|
|
m_serverType == ServerType.HttpProxy ||
|
|
m_serverType == ServerType.HttpProxyWorld ||
|
|
m_serverType == ServerType.HttpProxyPay)
|
|
{
|
|
m_testReloadCount = 0;
|
|
}
|
|
else
|
|
{
|
|
if(false == int.TryParse(m_app.GetCluster().GetAppParamByKey("testReload"), out m_testReloadCount))
|
|
{
|
|
m_testReloadCount = 0;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
private void SetLogReloadableParam()
|
|
{
|
|
TraceLog.SetLogLevel(LogLevel.ParseFromString(m_appParam.ServerConfig.loglevel));
|
|
TraceLog.SetSkipLogMsgID(m_appParam.ServerConfig.skipLogMsgID);
|
|
|
|
//修改shift文件大小和数量
|
|
if(m_appParam.ServerConfig.logshiftfilesize > 0)
|
|
{
|
|
LogDefaultParam.ShiftFileSize = m_appParam.ServerConfig.logshiftfilesize;
|
|
}
|
|
if (m_appParam.ServerConfig.logshiftfilecount > 0)
|
|
{
|
|
LogDefaultParam.ShiftFileCount = m_appParam.ServerConfig.logshiftfilecount;
|
|
}
|
|
}
|
|
|
|
//初始化,读取cluster的配置文件,这个将会建立管道配置
|
|
private int Init()
|
|
{
|
|
int iRet = InitShmCommand();
|
|
if(iRet != 0)
|
|
{
|
|
return iRet;
|
|
}
|
|
|
|
iRet = m_app.GetCluster().InitAllChannel();
|
|
if(iRet != 0)
|
|
{
|
|
TraceLog.Error("ServerEntry.Init Cluster.InitAllChannel failed ret {0}", iRet);
|
|
return iRet;
|
|
}
|
|
|
|
//初始化时区相关信息
|
|
AppTime.InitTimeZone();
|
|
|
|
//注册所有消息类型
|
|
ProtoRegister.Instance.RegisterAllPacket();
|
|
|
|
LoadScriptObj();
|
|
|
|
InitScript();
|
|
|
|
m_serverStartTime = AppTime.GetNowSysMs();
|
|
|
|
return 0;
|
|
}
|
|
|
|
private string GetMutexName()
|
|
{
|
|
// "Global\"代表全局命名mutex, 不同的终端看到的是同一个, 否则, 不同终端都可以创建同名不同实例的mutex
|
|
return "Global\\sog_" + ServerIDUtils.IDToString(m_app.ServerID);
|
|
}
|
|
|
|
private bool CheckAppIsAlreadyRunning()
|
|
{
|
|
string mutexname = GetMutexName();
|
|
|
|
try
|
|
{
|
|
System.Threading.Mutex mutex;
|
|
bool bRet = System.Threading.Mutex.TryOpenExisting(mutexname, out mutex);
|
|
|
|
if (bRet)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine(ex.ToString());
|
|
return false;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private void CreateMutex()
|
|
{
|
|
string mutexname = GetMutexName();
|
|
m_procMutex = new System.Threading.Mutex(true, mutexname);
|
|
}
|
|
|
|
static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs e)
|
|
{
|
|
Exception exception = e.ExceptionObject as Exception;
|
|
if (exception != null)
|
|
{
|
|
TraceLog.Error("UnhandledExceptionHandler be call");
|
|
TraceLog.Exception(exception);
|
|
Thread.Sleep(100);
|
|
}
|
|
}
|
|
|
|
private int InitShmCommand()
|
|
{
|
|
//加个预期之外的异常处理
|
|
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
|
|
|
|
if (m_appParam.RunMode == AppRunMode.None)
|
|
{
|
|
Console.WriteLine("server id {0} runmode init error", ServerIDUtils.IDToString(m_appParam.ServerID));
|
|
return 2;
|
|
}
|
|
|
|
//启动模式
|
|
if (m_appParam.RunMode == AppRunMode.Run)
|
|
{
|
|
if (CheckAppIsAlreadyRunning() == true)
|
|
{
|
|
string strError = string.Format("server id {0} name {1} already running,runmode Run,please check!"
|
|
, ServerIDUtils.IDToString(m_appParam.ServerID)
|
|
, m_appParam.ServerConfig.scriptTypeName);
|
|
|
|
Console.WriteLine(strError);
|
|
return 1;
|
|
}
|
|
|
|
CreateMutex();
|
|
|
|
TraceLog.Debug("==========================================================");
|
|
TraceLog.Debug("server id {0} starting at {1}", ServerIDUtils.IDToString(m_appParam.ServerID),DateTime.Now);
|
|
TraceLog.Debug("InitShmCommand server run in run mode,CreateShareCommand");
|
|
|
|
m_shareCommand = new ShareMemoryCommand(m_appParam.ServerID);
|
|
m_shareCommand.Create();
|
|
|
|
return 0;
|
|
}
|
|
//代理启动模式
|
|
else if(m_appParam.RunMode == AppRunMode.Start)
|
|
{
|
|
if (CheckAppIsAlreadyRunning() == true)
|
|
{
|
|
string strError = string.Format("server id {0} name {1} already running,runmode Start,please check!"
|
|
, ServerIDUtils.IDToString(m_appParam.ServerID)
|
|
, m_appParam.ServerConfig.scriptTypeName);
|
|
|
|
Console.WriteLine(strError);
|
|
return 1;
|
|
}
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
for(int i=0; i< m_appParam.Args.Length; i++)
|
|
{
|
|
if(m_appParam.Args[i] == "start")
|
|
{
|
|
continue;
|
|
}
|
|
|
|
sb.Append(m_appParam.Args[i]);
|
|
sb.Append(' ');
|
|
}
|
|
sb.Append("run");
|
|
|
|
string param = sb.ToString();
|
|
|
|
//防止进程访问log冲突,先关闭自己的log
|
|
TraceLog.ForceCloseLogFile();
|
|
|
|
System.Diagnostics.Process thisProcess = System.Diagnostics.Process.GetCurrentProcess();
|
|
|
|
string filename = "SogLoader";
|
|
if(OSUtils.IsWindows())
|
|
{
|
|
filename += ".exe";
|
|
}
|
|
|
|
string currentDir = System.IO.Directory.GetCurrentDirectory();
|
|
filename = currentDir + "/" + filename;
|
|
|
|
ProcessStartInfo startInfo = new ProcessStartInfo(filename, param);
|
|
startInfo.CreateNoWindow = true;
|
|
startInfo.WorkingDirectory = currentDir;
|
|
//startInfo.UseShellExecute = true;
|
|
|
|
//开启子进程,自己退出
|
|
using (Process subProcess = new Process())
|
|
{
|
|
subProcess.StartInfo = startInfo;
|
|
subProcess.EnableRaisingEvents = true;
|
|
subProcess.Start();
|
|
// AttachToProcess(subProcess.Id);
|
|
Thread.Sleep(10);
|
|
}
|
|
|
|
return 9998;
|
|
}
|
|
//hotfixcheck 模式
|
|
else if (m_appParam.RunMode == AppRunMode.HotfixCheck)
|
|
{
|
|
string errfile = "./" + ServerIDUtils.IDToString(m_appParam.ServerID) + "_hotfixcheckerror";
|
|
//先删除错误文件
|
|
try { File.Delete(errfile); } catch (Exception) { }
|
|
|
|
IScriptHotfixCheck oldDllfileCheck = ScriptLoader.LoadServerLogicDllHotfixCheck(m_appParam.ServerConfig.scriptfile);
|
|
IScriptHotfixCheck newDllfileCheck = ScriptLoader.LoadServerLogicDllHotfixCheck(m_appParam.hotfixcheckDllFileFullName);
|
|
string oldCheckString = oldDllfileCheck.GetCheckString();
|
|
string newCheckString = newDllfileCheck.GetCheckString();
|
|
TraceLog.Trace("old file {0} check = {1}", m_appParam.ServerConfig.scriptfile, oldCheckString);
|
|
TraceLog.Trace("new file {0} check = {1}", m_appParam.hotfixcheckDllFileFullName, newCheckString);
|
|
if (oldCheckString != newCheckString)
|
|
{
|
|
string checkError = string.Format("ServerEntry.InitShmCommand hotfixCheck failed! oldCheckString {0} != newCheckString {1}", oldCheckString, newCheckString);
|
|
TraceLog.Error(checkError);
|
|
//写错误文件
|
|
try { File.WriteAllText(errfile, checkError); } catch (Exception) { }
|
|
m_app.Alerter.AlertMsg(checkError);
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
TraceLog.Trace("new file {0} is same to old fil {1}", m_appParam.hotfixcheckDllFileFullName, m_appParam.ServerConfig.scriptfile);
|
|
}
|
|
|
|
return 9997;
|
|
}
|
|
//其他代理模式就是各种命令模式,写入命令后退出
|
|
else
|
|
{
|
|
m_shareCommand = new ShareMemoryCommand(m_appParam.ServerID);
|
|
|
|
bool attachSuccess = m_shareCommand.Attach();
|
|
if (attachSuccess == false)
|
|
{
|
|
string strError = string.Format("server id {0} name {1} not running,please start server use start param first!"
|
|
, ServerIDUtils.IDToString(m_appParam.ServerID)
|
|
, m_appParam.ServerConfig.scriptTypeName);
|
|
|
|
Console.WriteLine(strError);
|
|
return 1;
|
|
}
|
|
|
|
if (m_appParam.RunMode == AppRunMode.Stop)
|
|
{
|
|
m_shareCommand.WriteCommand("stop");
|
|
return 2;
|
|
}
|
|
|
|
if(m_appParam.RunMode == AppRunMode.Hotfix)
|
|
{
|
|
if (m_appParam.forceHotfix)
|
|
{
|
|
m_shareCommand.WriteCommand("hotfixforce");
|
|
}
|
|
else
|
|
{
|
|
m_shareCommand.WriteCommand("hotfix");
|
|
}
|
|
return 3;
|
|
}
|
|
|
|
//ReloadConfig可以带参数
|
|
if (m_appParam.RunMode == AppRunMode.ReloadConfig)
|
|
{
|
|
m_shareCommand.WriteCommand(m_appParam.CommandAllText);
|
|
return 4;
|
|
}
|
|
|
|
//GmCommand可以带参数
|
|
if (m_appParam.RunMode == AppRunMode.GmCommand)
|
|
{
|
|
m_shareCommand.WriteCommand(m_appParam.CommandAllText);
|
|
return 5;
|
|
}
|
|
|
|
if (m_appParam.RunMode == AppRunMode.ReloadCluster)
|
|
{
|
|
m_shareCommand.WriteCommand("reloadcluster");
|
|
return 7;
|
|
}
|
|
|
|
return 9999;
|
|
|
|
}
|
|
|
|
//return 0;
|
|
}
|
|
static void AttachToProcess(int pid)
|
|
{
|
|
try
|
|
{
|
|
Type dteType = Type.GetTypeFromProgID("VisualStudio.DTE.17.0"); // 适用于 VS 2022
|
|
if (dteType == null)
|
|
{
|
|
Console.WriteLine("未找到 Visual Studio");
|
|
return;
|
|
}
|
|
|
|
dynamic dte = Activator.CreateInstance(dteType, true);
|
|
dte.MainWindow.Activate();
|
|
dte.Debugger.AttachProcesses(dte.Debugger.LocalProcesses.Item(pid));
|
|
Console.WriteLine("成功附加到进程:" + pid);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine("附加失败:" + ex.Message);
|
|
}
|
|
}
|
|
private void TryReadShmCommand(long tMs)
|
|
{
|
|
if(m_lastReadShmCommandTime == 0)
|
|
{
|
|
m_lastReadShmCommandTime = tMs;
|
|
return;
|
|
}
|
|
|
|
//xx毫秒读一次,不存在性能问题
|
|
if(tMs - m_lastReadShmCommandTime >= 200)
|
|
{
|
|
m_lastReadShmCommandTime = tMs;
|
|
string strCommand = m_shareCommand.ReadCommand();
|
|
if (strCommand == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
TraceLog.Debug("server read command from shm, command: {0}", strCommand);
|
|
|
|
//设置这个供工作线程读取
|
|
m_serverCommand = strCommand;
|
|
}
|
|
}
|
|
|
|
//挂载事件,OnTick,OnMessage...
|
|
private void AttachScriptEvent()
|
|
{
|
|
m_app.OnClusterMessage += m_scriptObj.OnMessage;
|
|
}
|
|
|
|
//卸载事件,OnTick,OnMessage...
|
|
private void DetachScriptEvent()
|
|
{
|
|
m_app.OnClusterMessage -= m_scriptObj.OnMessage;
|
|
}
|
|
|
|
private void OnTick(long tMs)
|
|
{
|
|
//优先执行命令
|
|
if(string.IsNullOrEmpty(m_serverCommand) == false)
|
|
{
|
|
string strcommand = m_serverCommand;
|
|
m_serverCommand = null;
|
|
ProcessShmCommand(strcommand);
|
|
}
|
|
|
|
if (m_scriptObj != null)
|
|
{
|
|
m_scriptObj.OnTick(tMs);
|
|
}
|
|
|
|
//临时测试reload
|
|
TestReload(tMs);
|
|
}
|
|
|
|
private bool NeedTestReload()
|
|
{
|
|
return m_reloadedCount < m_testReloadCount;
|
|
}
|
|
|
|
private void TestReload(long tMs)
|
|
{
|
|
if (NeedTestReload() == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (m_needReloadTime == 0)
|
|
{
|
|
m_needReloadTime = tMs + 600000;
|
|
return;
|
|
}
|
|
|
|
//每10分钟reload一次
|
|
if (tMs > m_needReloadTime)
|
|
{
|
|
TraceLog.Debug("ServerEntry.TestReload reload now...");
|
|
|
|
m_reloadedCount++;
|
|
ReloadScriptDll(true);
|
|
m_needReloadTime = tMs + 600000;
|
|
}
|
|
}
|
|
|
|
//从磁盘加载dll文件
|
|
private void LoadScriptObj()
|
|
{
|
|
m_scriptObj = ScriptLoader.LoadServerLogicDll(m_appParam.ServerConfig.scriptfile, m_appParam.ServerConfig.scriptTypeName);
|
|
}
|
|
|
|
private bool ReloadScriptObj(bool force)
|
|
{
|
|
m_scriptObjReloaded = ScriptLoader.LoadServerLogicDll(m_appParam.ServerConfig.scriptfile, m_appParam.ServerConfig.scriptTypeName);
|
|
if (m_scriptObjReloaded == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
string oldCheckString = m_scriptObj.GetScriptHotfixCheck().GetCheckString();
|
|
string newCheckString = m_scriptObjReloaded.GetScriptHotfixCheck().GetCheckString();
|
|
if (oldCheckString != newCheckString)
|
|
{
|
|
string checkError = string.Format("ServerEntry.ReloadScriptObj hotfixCheck failed! oldCheckString {0} != newCheckString {1}", oldCheckString, newCheckString);
|
|
TraceLog.Error(checkError);
|
|
//如果非强制hotfix,check失败直接返回,不加继续加载逻辑了
|
|
if (force == false)
|
|
{
|
|
m_app.Alerter.AlertMsg(checkError);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
TraceLog.Debug("ServerEntry.ReloadScriptObj hotfixCheck success CheckString {0} bforce {1}", oldCheckString, force);
|
|
|
|
return m_scriptObjReloaded != null;
|
|
}
|
|
|
|
private void InitScript()
|
|
{
|
|
if(m_scriptObj == null)
|
|
{
|
|
Console.WriteLine("InitScript no script obj loaded {0}", m_appParam.ServerConfig.scriptTypeName);
|
|
return;
|
|
}
|
|
|
|
m_scriptObj.OnCreate(m_app);
|
|
|
|
AttachScriptEvent();
|
|
}
|
|
|
|
private void ReloadScriptDll(bool force)
|
|
{
|
|
if(ReloadScriptObj(force) == false)
|
|
{
|
|
Console.WriteLine("ReloadScriptDll no script obj loaded");
|
|
return;
|
|
}
|
|
|
|
DetachScriptEvent();
|
|
|
|
ServiceMgr.Instance.DisposeAllService();
|
|
|
|
//删除老的script对象
|
|
m_scriptObj.Dispose();
|
|
|
|
m_scriptObj = null;
|
|
|
|
//新的script对象
|
|
m_scriptObj = m_scriptObjReloaded;
|
|
m_scriptObjReloaded = null;
|
|
|
|
|
|
m_scriptObj.OnHotfix(m_app);
|
|
|
|
AttachScriptEvent();
|
|
|
|
TraceLog.Debug("ServerEntry.ReloadScriptDll file {0} class {1} success."
|
|
, m_appParam.ServerConfig.scriptfile, m_appParam.ServerConfig.scriptTypeName);
|
|
}
|
|
|
|
public void WorkThreadRunFun()
|
|
{
|
|
m_app.Run();
|
|
|
|
//正常进程退出sleep一下,确保log写完
|
|
Thread.Sleep(100);
|
|
|
|
//正常服务器stop,设置m_serverCanExit
|
|
m_serverCanExit = true;
|
|
}
|
|
|
|
private void MainThreadMonitorLoop()
|
|
{
|
|
long lastServerTickCount = 0;
|
|
long workThreadNoRunStartTime = 0;
|
|
long workThreadNoRunTickCount = 0;
|
|
|
|
while (m_serverCanExit == false)
|
|
{
|
|
lastServerTickCount = m_app.TotalTickCount;
|
|
|
|
long tLastMs = AppTime.GetNowSysMs();
|
|
//读取命令
|
|
TryReadShmCommand(tLastMs);
|
|
|
|
Thread.Sleep(100);
|
|
|
|
//启动前30秒由于需要编译,不判断
|
|
if (m_serverStartTime != 0
|
|
&& tLastMs - m_serverStartTime > 30000)
|
|
{
|
|
long newServerTickCount = m_app.TotalTickCount;
|
|
|
|
bool workThreadNoTick = false;
|
|
|
|
//都sleep 100 了,发现工作线程一次tick都没结束,不应该啊
|
|
if (newServerTickCount == lastServerTickCount)
|
|
{
|
|
if (workThreadNoRunStartTime == 0)
|
|
{
|
|
workThreadNoRunStartTime = tLastMs;
|
|
workThreadNoRunTickCount = newServerTickCount;
|
|
}
|
|
|
|
//工作线程没有响应,告警
|
|
if (workThreadNoRunTickCount == newServerTickCount)
|
|
{
|
|
workThreadNoTick = true;
|
|
if (AppTime.GetNowSysMs() - workThreadNoRunStartTime >= 5000)
|
|
{
|
|
TraceLog.Error("server id {0} dead at {1}", ServerIDUtils.IDToString(m_appParam.ServerID), DateTime.Now);
|
|
workThreadNoRunStartTime = 0;
|
|
|
|
m_app.Alerter.AlertMsg("dead");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (! workThreadNoTick)
|
|
{
|
|
if (workThreadNoRunStartTime != 0)
|
|
{
|
|
workThreadNoRunStartTime = 0;
|
|
workThreadNoRunTickCount = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//启动服务器
|
|
public void Start()
|
|
{
|
|
int bRet = Init();
|
|
if(bRet == 0)
|
|
{
|
|
m_workThread = new Thread(WorkThreadRunFun, 1024 * 1024 * 10);
|
|
//设置成后台线程,如果不是后台线程,线程不是主动关闭,则会一直运行,那怕进程主线程退出也没用
|
|
m_workThread.IsBackground = true;
|
|
m_workThread.Start();
|
|
|
|
//主线程循环,读取服务器命令输入,并监控逻辑线程
|
|
MainThreadMonitorLoop();
|
|
|
|
//到这里说明逻辑线程结束了,服务器需要退出
|
|
|
|
//游戏服务器退出的时候需要调用,资源释放使用
|
|
//这个需要在主线程运行,如果在游戏逻辑线程调用,有可能主线程正在readcommand,会抛出异常
|
|
if (m_shareCommand != null)
|
|
{
|
|
m_shareCommand.DeleteFile();
|
|
m_shareCommand.Close();
|
|
m_shareCommand = null;
|
|
}
|
|
|
|
if (m_procMutex != null)
|
|
{
|
|
m_procMutex.Dispose();
|
|
m_procMutex = null;
|
|
}
|
|
|
|
TraceLog.Debug("server id {0} stoped at {1}", ServerIDUtils.IDToString(m_appParam.ServerID), DateTime.Now);
|
|
|
|
}
|
|
else
|
|
{
|
|
//代理服务器退出的时候需要调用,资源释放使用
|
|
if (m_shareCommand != null)
|
|
{
|
|
m_shareCommand.Close();
|
|
m_shareCommand = null;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (bRet != 0)
|
|
{
|
|
//> 0 算是正常执行完了程序,比如reload等
|
|
if(bRet > 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
string strError = string.Format("call Init failed,server end");
|
|
|
|
try
|
|
{
|
|
TraceLog.Error(strError);
|
|
}
|
|
catch(Exception ex)
|
|
{
|
|
ex.Source = null;
|
|
}
|
|
|
|
Console.WriteLine(strError);
|
|
return;
|
|
}
|
|
}
|
|
|
|
//读取指令
|
|
private void ProcessShmCommand(string strCommand)
|
|
{
|
|
TraceLog.Debug("ProcessShmCommand cmd:{0}", strCommand);
|
|
|
|
if (strCommand == "stop")
|
|
{
|
|
ProcessShmCommand_Stop();
|
|
}
|
|
else if(strCommand == "hotfix")
|
|
{
|
|
ProcessShmCommand_Hotfix(false);
|
|
}
|
|
else if (strCommand == "hotfixforce")
|
|
{
|
|
ProcessShmCommand_Hotfix(true);
|
|
}
|
|
else if(strCommand == "reloadconfig")
|
|
{
|
|
ProcessShmCommand_ReloadConfig(null);
|
|
}
|
|
else if (strCommand == "reloadcluster")
|
|
{
|
|
ProcessShmCommand_ReloadCluster();
|
|
}
|
|
else
|
|
{
|
|
if(strCommand.Contains(' '))
|
|
{
|
|
string[] splitStr = strCommand.Split(' ');
|
|
if(splitStr.Length >= 2 && splitStr[0] == "gmcmd")
|
|
{
|
|
ProcessShmCommand_GmCommand(splitStr);
|
|
}
|
|
|
|
if (splitStr.Length == 2 && splitStr[0] == "reloadconfig")
|
|
{
|
|
ProcessShmCommand_ReloadConfig(splitStr[1]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ProcessShmCommand_Stop()
|
|
{
|
|
TraceLog.Debug("ProcessShmCommand_Stop");
|
|
|
|
m_app.StopServer();
|
|
|
|
m_scriptObj.OnStop();
|
|
|
|
return;
|
|
}
|
|
|
|
private void ProcessShmCommand_Hotfix(bool force)
|
|
{
|
|
TraceLog.Debug("ProcessShmCommand_Hotfix reload script dll bforce {0}", force);
|
|
|
|
ReloadScriptDll(force);
|
|
}
|
|
|
|
private void ProcessShmCommand_ReloadConfig(string excelConfigFile)
|
|
{
|
|
TraceLog.Debug("ProcessShmCommand_ReloadConfig {0}", excelConfigFile);
|
|
|
|
ReloadConfig(excelConfigFile);
|
|
|
|
TraceLog.Debug("ProcessShmCommand reloadConfig success param {0}", excelConfigFile);
|
|
}
|
|
|
|
//重新加载管道配置文件
|
|
private void ProcessShmCommand_ReloadCluster()
|
|
{
|
|
TraceLog.Debug("ProcessShmCommand_ReloadCluster {0}",m_app.AppParam.ClusterFileName);
|
|
|
|
m_app.GetCluster().ReloadClusterAppByConfig(m_app.AppParam.ClusterFileName);
|
|
}
|
|
|
|
private void ReloadConfig(string excelConfigFile)
|
|
{
|
|
//重新加载配置文件
|
|
m_appParam.Reload();
|
|
|
|
int iLogLevel = LogLevel.ParseFromString(m_appParam.ServerConfig.loglevel);
|
|
|
|
TraceLog.Debug("ProcessShmCommand_ReloadConfig set loglevel to {0}:{1}", m_appParam.ServerConfig.loglevel, iLogLevel);
|
|
//更新日志等级
|
|
SetLogReloadableParam();
|
|
|
|
//设置configFilePath
|
|
if(m_appParam.ServerConfig.configDataPath != null && m_appParam.ServerConfig.configDataPath != "")
|
|
{
|
|
GameConfigMgr.Instance.SetFilePath(m_appParam.ServerConfig.configDataPath);
|
|
}
|
|
else
|
|
{
|
|
GameConfigMgr.Instance.SetFilePath("../cfg/data/");
|
|
}
|
|
|
|
//可以传入nodesc表示不加载desc配置(策划配置表)
|
|
if(excelConfigFile != "nodesc")
|
|
{
|
|
//重新加载游戏策划excel配置文件
|
|
if (string.IsNullOrEmpty(excelConfigFile))
|
|
{
|
|
TraceLog.Debug("ProcessShmCommand_ReloadConfig GameConfigMgr ReadAllConfig ");
|
|
|
|
GameConfigMgr.Instance.ReadAllConfig();
|
|
}
|
|
else
|
|
{
|
|
TraceLog.Debug("ProcessShmCommand_ReloadConfig GameConfigMgr ReadOneConfig {0} ", excelConfigFile);
|
|
|
|
GameConfigMgr.Instance.ReadOneConfig(excelConfigFile);
|
|
}
|
|
}
|
|
|
|
m_scriptObj.OnReloadConfig(excelConfigFile);
|
|
}
|
|
|
|
private void ProcessShmCommand_GmCommand(string[] splitStr)
|
|
{
|
|
//TraceLog.Debug("ProcessShmCommand_GmCommand");
|
|
GmCommandMgr.Instance.HandlerGmCommandBySplit(splitStr);
|
|
}
|
|
}
|
|
}
|
|
|