#include "Utility.h" #include #include #include "XmlManager.h" char g_szVersion[256]; //使用sigexception,不再使用SigRegister, by dzj, 09.08.31#ifndef ACE_WIN32 //////exception catching in linux, backtrace the stack; //SigRegister g_sigRegister; //#endif //ACE_WIN32 ////////////////////////////////////////////////////////////////////////////////////// //memory leak detect, added by dzj, 08.01.04 //#ifdef ACE_WIN32 // #ifdef _DEBUG // #include "ace/Global_Macros.h" // #include "ace/Guard_T.h" // ACE_Thread_Mutex g_MemoryAllocLock;//内存分配锁; // void* __cdecl operator new( size_t nSize, const char* lpszFileName, int nLine ) // { // //将new时的文件与行号传入,否则dump出来的泄漏位置是在crtdbg.h中的某处而不是真正的源文件; // ACE_GUARD_RETURN( ACE_Thread_Mutex, guard, g_MemoryAllocLock, NULL ); // static bool isFlagSet = false; // if ( !isFlagSet )//第一次使用new时设置memory dump标记,以检测使用new的静态变量; // { // _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); // isFlagSet = true; // } // return _malloc_dbg( nSize, _NORMAL_BLOCK, lpszFileName, nLine ); // } // // void __cdecl operator delete( void* p, const char*, int ) // { // ACE_GUARD( ACE_Thread_Mutex, guard, g_MemoryAllocLock ); // _free_dbg( p, _CLIENT_BLOCK ); // } // #endif //_DEBUG //#endif //ACE_WIN32 //memory leak detect, added by dzj, 08.01.04 ////////////////////////////////////////////////////////////////////////////////////// bool g_isGlobeStop = false; #ifdef WIN32 BOOL WindowsTSTHandler( DWORD sigType ) { if ( sigType == CTRL_C_EVENT ) { printf( "收到ctrl-c,退出...\n" ); g_isGlobeStop = true; } return FALSE; } #else //WIN32 #include static void sig_tstp_handler(int signo) { g_isGlobeStop = true; return; } #endif //WIN32 //交互式中止进程执行 void SetTSTP() { #ifdef WIN32 if ( !SetConsoleCtrlHandler( (PHANDLER_ROUTINE)WindowsTSTHandler, TRUE ) ) { printf( "设置ctrl-c处理句柄失败\n" ); } return; #else //WIN32 struct sigaction act, oact; StructMemSet( act, 0, sizeof(act) ); StructMemSet( oact, 0, sizeof(oact) ); act.sa_handler = sig_tstp_handler; sigemptyset( &act.sa_mask); act.sa_flags = 0; if ( 0 != sigaction( SIGTSTP, &act, &oact) ) { printf( "设置ctrl-c处理句柄失败\n" ); } return; #endif //WIN32 } ///取当前时间; void GetCurTime( int& cyear/*年*/, int& cmon/*月*/, int& cmday/*日*/ , int& chour/*时*/, int& cmin/*分*/, int& csec/*秒*/, int& cwday/*星期*/ , int& cmsec/*毫秒*/ ) { tm curTm; #ifdef WIN32 _timeb curTime; _ftime_s( &curTime ); localtime_s( &curTm, &(curTime.time) ); cyear = curTm.tm_year; cmon = curTm.tm_mon; cmday = curTm.tm_mday; chour = curTm.tm_hour; cmin = curTm.tm_min; csec = curTm.tm_sec; cwday = curTm.tm_wday; cmsec = curTime.millitm; #else //WIN32 timeval curTime; gettimeofday( &curTime, NULL ); localtime_r( &(curTime.tv_sec), &curTm ); cyear = curTm.tm_year; cmon = curTm.tm_mon; cmday = curTm.tm_mday; chour = curTm.tm_hour; cmin = curTm.tm_min; csec = curTm.tm_sec; cwday = curTm.tm_wday; cmsec = curTime.tv_usec / 1000; #endif //WIN32 } bool RandRate(float fRate) { if(fRate >= 1) fRate = 1.0f; if( fRate <= 0) fRate = 0.0f; float fRandom = (float)( RAND%100 ) / (float)100; return fRandom < fRate; } //返回一个在a,b区间的数 b一定要大于等于a int RandNumber( int a, int b ) { if( a > b) { return 0; } if( a == b) { return a; } return RAND%(b-a+1) + a; } bool ReadVersion(const char* pszFileName) { TRY_BEGIN; std::ifstream fileStream; fileStream.open( pszFileName ); //读取txt文件 fileStream.read( g_szVersion, ARRAY_SIZE(g_szVersion) ); fileStream.close(); return true; TRY_END; return false; } int g_iDaemon; int g_iLogType; bool g_bGmShield = false; bool g_bTimeCheck = true; unsigned int g_maxMapSrvPlayerNum = MAP_SRV_PLAYERNUM_MAX;//mapsrv中的最大人数; unsigned int g_manedMapID = 0;//本mapsrv管理的地图ID号,从命令行参数中传入,若命令行参数中未指定(==0),则通过selfconfig以及mapmanconfig综合得到; int Print_usage (int argc, ACE_TCHAR *argv[]) { ACE_UNUSED_ARG(argc); ACE_UNUSED_ARG(argv); ACE_DEBUG((LM_DEBUG, "\nusage: %s" "\n-d " "\n-ln " "\n-pn " "\n", argv[0])); return 0; } // 参数解析 int Parse_args(int argc, ACE_TCHAR *argv[]) { // 无参数直接返回 if (argc == 1) return 0; // 解析参数 int c = 0; ACE_Get_Opt get_opt(argc, argv, ACE_TEXT ("dl:ghm:p:")); int iret =0; while((c = get_opt()) != EOF) { switch (c) { case 'd': { g_iDaemon = 1; break; } case 'l': { g_iLogType = ACE_OS::atoi(get_opt.opt_arg()); break; } case 'g': { g_bGmShield = true; D_DEBUG("GM屏蔽模式开启\n"); break; } case 'h': { g_bTimeCheck = false; D_DEBUG("屏蔽心跳开启\n"); break; } case 'm': { g_manedMapID = ACE_OS::atoi(get_opt.opt_arg());//管理的地图号; break; } case 'p': { g_maxMapSrvPlayerNum = ACE_OS::atoi(get_opt.opt_arg());//mapsrv容许的最大人数; if ( g_maxMapSrvPlayerNum <= 1 ) { g_maxMapSrvPlayerNum = 1; } if ( g_maxMapSrvPlayerNum >= MAP_SRV_PLAYERNUM_MAX ) { g_maxMapSrvPlayerNum = MAP_SRV_PLAYERNUM_MAX; } break; } default: Print_usage(argc,argv); return 0; } } return iret; } int SetDaemon(int iDaemon) { #ifndef ACE_WIN32 if(iDaemon == 1) ACE::daemonize(); #else ACE_UNUSED_ARG( iDaemon ); #endif/*ACE_WIN32*/ return 0; } int SetLog(const char* pszlogFile, int iLogType) { if(iLogType == 1) //file { ACE_LOG_MSG->clr_flags (ACE_Log_Msg::STDERR); ACE_LOG_MSG->set_flags (ACE_Log_Msg::OSTREAM); const char *filename = pszlogFile; ofstream *pOutFileStream = NEW ofstream(filename, ios::out | ios::trunc); if(NULL == pOutFileStream) return -1; ACE_LOG_MSG->msg_ostream(pOutFileStream, 1); } else if(iLogType == 2) //all { //ACE_LOG_MSG->clr_flags (ACE_Log_Msg::STDERR); ACE_LOG_MSG->set_flags (ACE_Log_Msg::OSTREAM); const char *filename = pszlogFile; ofstream *pOutFileStream = NEW ofstream(filename, ios::out | ios::trunc); if(NULL == pOutFileStream) return -1; ACE_LOG_MSG->msg_ostream(pOutFileStream, 1); } return 0; } CLogException::CLogException(void) { m_bDir = false; m_pFile = NULL; StructMemSet(m_szCurrHour, 0x00, sizeof(m_szCurrHour)); } CLogException::~CLogException(void) { ACE_OS::fclose(m_pFile); } int CLogException::Log(const char *pszFmt, ...) { ACE_Guard lock(m_lock); if(!m_bDir) { if(!CheckDirectory("Exception")) { if(!CreateDirectory("Exception")) return -1; } m_bDir = true; } time_t now = ACE_OS::time(); tm nowTM; char szNow[11]; ACE_OS::localtime_r(&now, &nowTM); ACE_OS::strftime(szNow, sizeof(szNow), "%Y%m%d%H", &nowTM); char szNowTimeStamp[20] ={0}; ACE_OS::strftime(szNowTimeStamp, sizeof(szNowTimeStamp), "%Y-%m-%d %H:%M:%S", &nowTM); if(ACE_OS::strncmp(m_szCurrHour, szNow, sizeof(m_szCurrHour)) != 0) { if(ACE_OS::strncmp(m_szCurrHour, "", sizeof(m_szCurrHour)) != 0) { // 关闭旧的文件 ACE_OS::fclose(m_pFile); StructMemSet(m_szCurrHour, 0x00, sizeof(m_szCurrHour)); } // 当前文件 char szFileName[30] = {0}; ACE_OS::snprintf(szFileName, sizeof(szFileName), "Exception/%s.txt", szNow); // 如果文件不存在则创建 if(!CheckFile(szFileName)) { if(!CreateFile(szFileName)) return -1; } // 打开文件 m_pFile = ACE_OS::fopen(szFileName, "a"); if(m_pFile != NULL) { StructMemCpy(m_szCurrHour, szNow, sizeof(m_szCurrHour)); } } va_list argp; va_start (argp, pszFmt); char temp[500] = {0}; int nReturnCount = 0; nReturnCount += ACE_OS::snprintf(temp, sizeof(temp), "[%s]", szNowTimeStamp); nReturnCount += ACE_OS::vsnprintf(temp + nReturnCount, sizeof(temp) - nReturnCount, pszFmt, argp); if(nReturnCount > 0) { ACE_OS::fwrite(temp, nReturnCount, 1, m_pFile); ACE_OS::fflush(m_pFile); } va_end (argp); return nReturnCount; } bool CLogException::CheckDirectory(const char *pszDirName) { if(ACE_OS::access(pszDirName, F_OK) < 0) return false; return true; } bool CLogException::CheckFile(const char *pszFileName) { if(ACE_OS::access(pszFileName, F_OK) < 0) return false; return true; } bool CLogException::CreateDirectory(const char *pszDirName) { if(ACE_OS::mkdir(pszDirName) == -1) return false; return true; } bool CLogException::CreateFile(const char *pszFileName) { m_pFile = ACE_OS::fopen(pszFileName, "a"); if(NULL == m_pFile) return false; return true; } bool IsXMLValid( CElement* pEle, const char* attName, int nRecord ) { if ( NULL == pEle->GetAttr( attName ) ) { D_ERROR( "服务器配置XML文件第%d条记录属性%s失败\n", nRecord, attName ); return false; } return true; }