Files
mir_server/server/DBServer/main.cpp
aixianling 5c9f1dae4a init
2025-01-09 17:45:40 +08:00

401 lines
9.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "StdAfx.h"
#ifdef WIN32
#include <dbghelp.h>
#include <mbctype.h>
#include <conio.h>
#else
// #include "client/linux/handler/exception_handler.h"
#endif
#include <string>
#include <iostream>
#include "PathThreadLocale.h"
bool DBEngineRunning = true ;
//定义转储文件名称
extern const TCHAR szExceptionDumpFile[] = _T("./DBEngine.dmp");
BOOL SetupDBEngineConfig(CDBServer *lpDBEngine, const char *pszConfigFileName = NULL);
VOID ServerMain(int argc, char **argv);
VOID ServiceRun(int argc, char** argv);
//数据引擎版本号
#define DBEGN_KN_VERION MAKEFOURCC(17, 3, 1, 1)
//数据引擎的数据结构版本
//#define DBSDATATYPE_VERSION 0x010A1B0A
#ifndef WIN32
/*
static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor,
void* context,
bool succeeded)
{
printf("Dump path: %s\n", descriptor.path());
return succeeded;
}
*/
static void signal_handler(int sig_num)
{
if( sig_num == SIGHUP ||
sig_num == SIGINT ||
sig_num == SIGTERM )
{
OutputMsg( rmTip, _T("正在停止网关管理器...") );
DBEngineRunning = false;
}
}
#endif
#ifndef WIN32
int _kbhit(void)
{
struct termios oldt, newt;
int ch;
int oldf;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
ch = getchar();
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
fcntl(STDIN_FILENO, F_SETFL, oldf);
if(ch != EOF)
{
ungetc(ch, stdin);
return 1;
}
return 0;
}
#endif
#ifdef WIN32
int initLocalePath()
{
//_MB_CP_SBCS 视所有字符均作为单字节字符以便同时支持UTF8以及MBCS
//Use single-byte code page.
//When the code page is set to _MB_CP_SBCS, a routine such as _ismbblead always returns false.
_setmbcp(_MB_CP_SBCS);
//★关键★ 设置"C"locale视所有字符均作为单字节字符以便同时支持UTF8以及MBCS
return InstallThreadLocalePath("C");
}
#endif
void TestMemory()
{
#ifdef _DEBUG
#else
/*
DWORD dwStart = GetTickCount();
for(int i = 0; i < 1000000; i++) { char *p = (char*)malloc(i%1000000); free(p); }
DWORD dwEnd = GetTickCount();
printf("***********************",dwEnd - dwStart);
printf("100wMemoryTest:%d ms\n",dwEnd - dwStart);
*/
#endif
}
#ifdef WIN32
class CDbService : public CWinService
{
public:
CDbService(LPCSTR pServiceName, DWORD dwServiceType = SERVICE_WIN32_OWN_PROCESS):CWinService(pServiceName, dwServiceType){};
int AppMain()
{
SetCurrentDirectory("../"); //CWinService里会把当前目录改成exe允许的目录所以这里再转一下
CFileLogger flog(_T("log/DBServer_%s.log"), getCurrentTimeDesc());
CDBServer *pDBEngine = new CDBServer();
if ( !SetupDBEngineConfig(pDBEngine) )
{
OutputMsg( rmError, _T("读入配置文件失败,服务停止!"));
}
else if ( pDBEngine->Startup() )
{
while (!m_boServiceExit)
{
Sleep(1000);
}
pDBEngine->Shutdown();
}
delete pDBEngine;
return 0;
}
};
#endif
int main(int argc, TCHAR* argv[])
{
#ifdef WIN32
SetUnhandledExceptionFilter( DefaultUnHandleExceptionFilter );
#else
//seh_init();
/*
google_breakpad::MinidumpDescriptor descriptor(".");
google_breakpad::ExceptionHandler eh(descriptor,
NULL,
dumpCallback,
NULL,
true,
-1);
*/
(void)signal(SIGHUP, SIG_IGN);
(void)signal(SIGINT, signal_handler);
(void)signal(SIGTERM, signal_handler);
(void)signal(SIGPIPE, SIG_IGN);
#endif
InitDefMsgOut();
#ifdef WIN32
CoInitialize(NULL);
#endif
CTimeProfDummy::SetOpenFlag(false);
#ifdef WIN32
//flog.SetNeedOutput(true);
#else
if (argc >=2)
{
// flog.SetNeedOutput(true);
}
else
{
// flog.SetNeedOutput(false);
}
#endif
#ifdef WIN32
if (initLocalePath())
{
OutputMsg( rmError, _T("can not set locale path") );
getc(stdin);
return -2;
}
#endif
CTimeProfDummy::SetOpenFlag(false);
#ifndef _SERVICE
//if (argc == 2 && _tcsncicmp("/cmd",argv[1],4)==0)//平时调试用
{
#ifdef WIN32
SetCurrentDirectory("../");
#else
std::string filename(argv[1]);
size_t found = filename.find_last_of("/\\");
filename = filename.substr(0, found);
if( filename[0] == '.' && filename.length()==1 )
filename = "./" ;
SetCurrentDirectory(filename.c_str());
#endif
ServerMain(argc, argv);
}
#else
//else
{
ServiceRun(argc, argv);
}
#endif
#ifdef WIN32
CoUninitialize();
#endif
UninitDefMsgOut();
#ifdef _MLIB_DUMP_MEMORY_LEAKS_
_CrtDumpMemoryLeaks();
#endif
return 0;
}
#ifdef WIN32
VOID ServiceRun(int argc, char** argv)
{
LPTSTR sCmd = NULL;
if (argc >= 2)
{
sCmd = argv[1];
}
TestMemory();
CDbService service("DbService");
service.Run(sCmd);
}
BOOL WINAPI CustomConsoleCtrlHandler(DWORD dwCtrlType)
{
if (dwCtrlType == CTRL_CLOSE_EVENT)
{
Beep( 600, 200 );
printf( "Ctrl-Close event\n\n" );
return TRUE;
}
else
return FALSE;
}
#endif
VOID ServerMain(int argc, char **argv)
{
const char *pszConfigFileName = NULL;
if (argc >= 2)
{
pszConfigFileName = argv[1];
}else
{
pszConfigFileName = "DBServerLinux.txt";
}
int nError;
TCHAR sCmdBuf[512];
CFileLogger flog(_T("./log/DBServer_%s.log"), getCurrentTimeDesc());
CDBServer *pDBEngine = new CDBServer();
CDBServer::s_pDBEngine = pDBEngine;
//SetConsoleCtrlHandler(CustomConsoleCtrlHandler, TRUE);
//DeleteMenu(GetSystemMenu(GetConsoleWindow(), FALSE), SC_CLOSE, MF_BYCOMMAND);
#ifdef WIN32
if (initLocalePath())
{
OutputMsg( rmError, _T("can not set locale path") );
getc(stdin);
return ;
}
#endif
if ( !SetupDBEngineConfig(pDBEngine,pszConfigFileName) )
{
OutputMsg( rmError, _T("读入配置文件失败,服务停止!"));
}
else if ( pDBEngine->Startup() )
{
//设置窗口标题
CTimeProfMgr::getSingleton().InitMgr();
char *pBuff = (char*)malloc(256);
in_addr ia;
ia.s_addr = DBEGN_KN_VERION;
strcpy(pBuff, pDBEngine->getServerName());
strcat(pBuff,"-V");
strcat(pBuff,inet_ntoa(ia));
SetConsoleTitle(pBuff);
free(pBuff);
pBuff =NULL;
TestMemory();
OutputMsg( rmTip, _T("-------------------------------------------") );
OutputMsg( rmTip, _T("数据服务器启动成功,核心版本号是%s"), inet_ntoa(ia) );
//OutputMsg( rmTip, _T("数据结构版本号是:%X"), DBSDATATYPE_VERSION );
// OutputMsg( rmTip, _T("角色基础数据结构大小是:%d"), sizeof(DBCHARBASICDATA) );
OutputMsg( rmTip, _T("quit命令可以停止服务并退出程序") );
OutputMsg( rmTip, _T("lgr 命令可以重新加载游戏网关路由表") );
OutputMsg( rmTip, _T("-------------------------------------------") );
unsigned long long startTick = _getTickCount();
while ( pDBEngine->GetDbStartFlag() )
{
#ifdef _MSC_VER
sCmdBuf[0] = 0;
if(_kbhit())
{
//_getts(sCmdBuf);
std::cin >> (sCmdBuf);
}
else
{
Sleep(100);
continue;
}
//重新加载路由命令
if ( _tcsncicmp(sCmdBuf, _T("lgr"), 3) == 0 )
{
nError = pDBEngine->LoadGameServerRoute();
if ( nError >= 0 )
OutputMsg( rmTip, _T("已加载%d个游戏网关路由数据"), nError);
else OutputMsg( rmError, _T("加载游戏网关路由数据失败"));
continue;
}
//退出命令
if ( _tcsncicmp(sCmdBuf, _T("\\q"), 2) == 0
|| _tcsncicmp(sCmdBuf, _T("exit"), 4) == 0
|| _tcsncicmp(sCmdBuf, _T("quit"), 4) == 0 )
{
OutputMsg( rmTip, _T("正在停止网关管理器...") );
break;
}
else if ( _tcsncicmp(sCmdBuf, _T("spf"), 3) ==0)
{
CTimeProfMgr::getSingleton().dump();
pDBEngine->TraceGameServerRoute();
}
// asi interval (interval:save time interval, s)
else if (_tcsncicmp(sCmdBuf, _T("asi"), 3) == 0)
{
char *pParam = sCmdBuf + 3;
while (*pParam == ' ')
pParam++;
if (pParam)
{
UINT_PTR nInterval = atoi(pParam);
if (nInterval > 0)
CDBDataCache::s_nActorCacheSaveInterval = nInterval*1000;
}
}
else if(_tcsncicmp(sCmdBuf,"dmp",3) ==0 )
{
DebugBreak();
}
else if(_tcsncicmp(sCmdBuf,"opentrace",9) ==0 )
{
CTimeProfDummy::SetOpenFlag(true);
}
else if(_tcsncicmp(sCmdBuf,"closetrace",10) ==0 )
{
CTimeProfDummy::SetOpenFlag(false);
}
else if(_tcsncicmp(sCmdBuf,"memory",6) ==0 )
{
pDBEngine->Trace();
}
#else
if (!DBEngineRunning) break;
#endif
Sleep(10);
}
//pDBEngine->Shutdown();
}
delete pDBEngine;
}
BOOL SetupDBEngineConfig(CDBServer *lpDBEngine, const char *pszConfigFileName)
{
CDBConfig config;
if ( !config.ReadConfig(pszConfigFileName) )
return FALSE;
lpDBEngine->RunEsqlFile(config.m_EsqlToolPath,config.DbConf.szDbName);
lpDBEngine->SetServerName(config.ServerName);
lpDBEngine->SetServerIndex(config.ServerIndex);
lpDBEngine->SetGateServiceAddress(config.GateAddr.szAddr, config.GateAddr.nPort);
//lpDBEngine->SetSessionServerAddress(config.SessionAddr.szAddr, config.SessionAddr.nPort);
lpDBEngine->SetNameSyncServerAddress(config.NameAddr.szAddr, config.NameAddr.nPort);
lpDBEngine->SetDataServiceAddress(config.DataAddr.szAddr, config.DataAddr.nPort);
lpDBEngine->SetSQLConfig(config.DbConf.szHost, config.DbConf.nPort, config.DbConf.szDbName, config.DbConf.szUser, config.DbConf.szPassWord,config.DbConf.boUtf8 > 0 ? true : false);
//启动日志客户端
lpDBEngine->SetLogServerAddress(config.LogAddr.szAddr, config.LogAddr.nPort);
//lpDBEngine->SetDBCenterAddress(config.DBCenterAddr.szAddr, config.DBCenterAddr.nPort);
lpDBEngine->LoadNameGroup(config.m_sPrefixList, /*config.m_sConnectList,*/ config.m_sStuffixList);
return TRUE;
}