#include "LogClient.h" #include "LogStruct.h" #include #include #include #include #include #include #include #include XCriticalSection g_csLock; std::vector< XSyncStreamConnection* > g_vConnectionVector; __declspec( thread ) XSyncStreamConnection* g_pLogServerConnection = NULL; __declspec( thread ) DWORD g_nLogThreadId = 0; __declspec( thread ) XSyncStreamConnection* g_pChatLogServerConnection = NULL; __declspec( thread ) DWORD g_nChatLogThreadId = 0; volatile bool g_bWriteLog = true; volatile bool g_bWriteChatLog = false; static void chat_log_error( XSyncStreamConnection* pConn, const char *szLogError ); XSyncStreamConnection * GetLogServerConnection() { char szLogTag[256]; s_sprintf( szLogTag, _countof( szLogTag ), "log.connect_%s", XGetThreadName() ); if( !g_pLogServerConnection ) { ENV().Set( szLogTag, 0 ); g_csLock.Lock(); g_pLogServerConnection = new XSyncStreamConnection; g_vConnectionVector.push_back( g_pLogServerConnection ); g_csLock.UnLock(); } if( !g_pLogServerConnection->IsConnected() ) { XAddr addr( ENV().GetString( "log.ip", "127.0.0.1" ).c_str(), ENV().GetInt( "log.port", 4516 ) ); if( !g_pLogServerConnection->Connect( addr ) ) { //_cprint( "cannot connect log server: ip: %s, port: %d\n", addr.GetAddr(), addr.GetPort() ); //FILELOG( "cannot connect log server: ip: %s, port: %d", addr.GetAddr(), addr.GetPort() ); return NULL; } ENV().Set( szLogTag, 1 ); g_nLogThreadId = GetCurrentThreadId(); LOG::Log11N4S( LM_SERVER_LOGIN, 0, 0, 0, g_nLogThreadId, 0, 0, 0, 0, 0, 0, 0, "", 0, "", 0, XGetThreadName(), LOG::STR_NTS, ENV().GetString( "log.server_name" ).c_str(), LOG::STR_NTS ); } return g_pLogServerConnection; } XSyncStreamConnection * GetChatLogServerConnection() { char szLogTag[256]; s_sprintf( szLogTag, _countof( szLogTag ), "log.chat.connect_%s", XGetThreadName() ); if( !g_pChatLogServerConnection ) { ENV().Set( szLogTag, 0 ); g_csLock.Lock(); g_pChatLogServerConnection = new XSyncStreamConnection; g_vConnectionVector.push_back( g_pChatLogServerConnection ); g_csLock.UnLock(); } if( !g_pChatLogServerConnection->IsConnected() ) { if( !g_pChatLogServerConnection->Connect( XAddr( ENV().GetString( "log.chat.ip", "127.0.0.1" ).c_str(), ENV().GetInt( "log.chat.port", 4520 ) ) ) ) { return NULL; } ENV().Set( szLogTag, 1 ); g_nChatLogThreadId = GetCurrentThreadId(); char szBuffer[ 1024 ]; memset( szBuffer, 0, sizeof( szBuffer ) ); LS_CHAT * pMsg = new ( szBuffer ) LS_CHAT(); pMsg->id = LM_SERVER_LOGIN; pMsg->nReceiverAccountID = g_nChatLogThreadId; pMsg->nReceiverAccountLength = static_cast< unsigned char >( strlen( XGetThreadName() ) ); pMsg->nChatLength = static_cast< unsigned short >( strlen( ENV().GetString( "log.server_name" ).c_str() ) ); pMsg->size += pMsg->nReceiverAccountLength + pMsg->nChatLength; s_memcpy( pMsg + 1, sizeof( szBuffer ) - sizeof( LS_CHAT ), XGetThreadName(), pMsg->nReceiverAccountLength ); s_memcpy( reinterpret_cast< char * >( pMsg + 1 ) + pMsg->nReceiverAccountLength, sizeof( szBuffer ) - sizeof( LS_CHAT ) - pMsg->nReceiverAccountLength, ENV().GetString( "log.server_name" ).c_str(), pMsg->nChatLength ); if( g_pChatLogServerConnection->Write( pMsg, pMsg->size ) != pMsg->size ) { chat_log_error( g_pChatLogServerConnection, "DISCONNECTED" ); } } return g_pChatLogServerConnection; } static void log_error( XSyncStreamConnection* pConn, const char *szLogError ) { pConn->Close(); //g_bWriteLog = false; char szLogTag[256]; s_sprintf( szLogTag, _countof( szLogTag ), "log.connect_%s", XGetThreadName() ); std::vector< XSyncStreamConnection* >::iterator it = std::find( g_vConnectionVector.begin(), g_vConnectionVector.end(), pConn ); if( it != g_vConnectionVector.end() ) { g_vConnectionVector.erase( it ); if( pConn == g_pLogServerConnection ) { g_pLogServerConnection = NULL; } delete pConn; } ENV().Set( szLogTag, 0 ); } static void chat_log_error( XSyncStreamConnection* pConn, const char *szLogError ) { pConn->Close(); //g_bWriteChatLog = false; char szLogTag[256]; s_sprintf( szLogTag, _countof( szLogTag ), "log.chat.connect_%s", XGetThreadName() ); std::vector< XSyncStreamConnection* >::iterator it = std::find( g_vConnectionVector.begin(), g_vConnectionVector.end(), pConn ); if( it != g_vConnectionVector.end() ) { g_vConnectionVector.erase( it ); if( pConn == g_pChatLogServerConnection ) { g_pChatLogServerConnection = NULL; } delete pConn; } ENV().Set( szLogTag, 0 ); } void LOG::Init( const char *szServerName ) { // ENV().LoadFromFile 함수가 호출된 이후에 호출되는 경우 이와 같이 변수에 값을 초기화해야 파일의 설정이 유지 됨 g_bWriteLog = (ENV().GetInt( "log.working", 1 ) != 0); g_bWriteChatLog = (ENV().GetInt( "log.chat.working", 0 ) != 0); ENV().Bind( "log.working", (bool*)&g_bWriteLog ); ENV().Bind( "log.chat.working", (bool*)&g_bWriteChatLog ); ENV().Set( "log.server_name", szServerName ); if( ENV().IsExist( "log.disable" ) ) g_bWriteLog = false; } void LOG::DeInit() { g_bWriteLog = false; g_bWriteChatLog = false; for( std::vector< XSyncStreamConnection* >::iterator it = g_vConnectionVector.begin() ; it != g_vConnectionVector.end() ; ++it ) { if( (*it)->IsConnected() ) (*it)->Close(); delete (*it); } g_vConnectionVector.clear(); } void LOG::Log11N4S( unsigned short id, const __int64 & n1, const __int64 & n2, const __int64 & n3, const __int64 & n4, const __int64 & n5, const __int64 & n6, const __int64 & n7, const __int64 & n8, const __int64 & n9, const __int64 & n10, const __int64 & n11, const char * szStr1, int len1, const char * szStr2, int len2, const char * szStr3, int len3, const char * szStr4, int len4 ) { if( !g_bWriteLog ) return; XSyncStreamConnection* pConn = GetLogServerConnection(); if( !pConn ) return; LS_11N4S header; header.thread_id = g_nLogThreadId; header.id = id; header.n1 = n1; header.n2 = n2; header.n3 = n3; header.n4 = n4; header.n5 = n5; header.n6 = n6; header.n7 = n7; header.n8 = n8; header.n9 = n9; header.n10 = n10; header.n11 = n11; if( szStr1 ) { if( len1 == LOG::STR_NTS ) { len1 = (int) strlen( szStr1 ); } } else { len1 = 0; } if( szStr2 ) { if( len2 == LOG::STR_NTS ) { len2 = (int) strlen( szStr2 ); } } else { len2 = 0; } if( szStr3 ) { if( len3 == LOG::STR_NTS ) { len3 = (int) strlen( szStr3 ); } } else { len3 = 0; } if( szStr4 ) { if( len4 == LOG::STR_NTS ) { len4 = (int) strlen( szStr4 ); } } else { len4 = 0; } header.size += (unsigned short)(len1 + len2 + len3 + len4); header.string_length_1 = (unsigned short)len1; header.string_length_2 = (unsigned short)len2; header.string_length_3 = (unsigned short)len3; header.string_length_4 = (unsigned short)len4; if( pConn->Write( &header, sizeof(header) ) != sizeof(header) || pConn->Write( szStr1, (unsigned short)len1 ) != len1 || pConn->Write( szStr2, (unsigned short)len2 ) != len2 || pConn->Write( szStr3, (unsigned short)len3 ) != len3 || pConn->Write( szStr4, (unsigned short)len4 ) != len4 ) { log_error( pConn, "DISCONNECTED" ); std::string strLog; XStringUtil::Format( strLog, "%lu\t%hu\t%I64d\t%I64d\t%I64d\t%I64d\t%I64d\t%I64d\t%I64d\t%I64d\t%I64d\t%I64d\t%I64d", header.thread_id, header.id, header.n1, header.n2, header.n3, header.n4, header.n5, header.n6, header.n7, header.n8, header.n9, header.n10, header.n11 ); strLog += "\t"; if( header.string_length_1 ) strLog.append( szStr1, header.string_length_1 ); strLog += "\t"; if( header.string_length_2 ) strLog.append( szStr2, header.string_length_2 ); strLog += "\t"; if( header.string_length_3 ) strLog.append( szStr3, header.string_length_3 ); strLog += "\t"; if( header.string_length_4 ) strLog.append( szStr4, header.string_length_4 ); FileLogHandler::GetFileLogHandler()->LogStringEx( NULL, "LostLogs", strLog.c_str() ); } } void LOG::LogChat( const int nSenderAccountID, const int nSenderCharacterID, const unsigned char nChatType, const int nSenderPosX, const int nSenderPosY, const int nReceiverAccountID, const int nReceiverCharacterID, const char * pszSenderAccount, const int nSenderAccountLength, const char * pszSenderCharacter, const int nSenderCharacterLength, const char * pszReceiverAccount, const int nReceiverAccountLength, const char * pszReceiverCharacter, const int nReceiverCharacterLength, const char * pszChat, const unsigned short nChatLength ) { if( !g_bWriteChatLog ) return; XSyncStreamConnection* pConn = GetChatLogServerConnection(); if( !pConn ) return; char szBuffer[ 16384 ]; memset( szBuffer, 0, sizeof( szBuffer ) ); LS_CHAT * pMsg = new ( szBuffer ) LS_CHAT(); pMsg->thread_id = g_nChatLogThreadId; pMsg->id = 0; // 채팅 로그만을 나타내므로 이 함수에서는 사용되지 않음(서버 로그인 메시지만 별도로 사용 됨) pMsg->nSenderAccountID = nSenderAccountID; pMsg->nSenderCharacterID = nSenderCharacterID; pMsg->nChatType = nChatType; pMsg->nSenderPosX = nSenderPosX; pMsg->nSenderPosY = nSenderPosY; pMsg->nReceiverAccountID = nReceiverAccountID; pMsg->nReceiverCharacterID = nReceiverCharacterID; if( nSenderAccountLength == STR_NTS ) pMsg->nSenderAccountLength = static_cast< unsigned char >( strlen( pszSenderAccount ) ); else pMsg->nSenderAccountLength = static_cast< unsigned char >( nSenderAccountLength ); if( nSenderCharacterLength == STR_NTS ) pMsg->nSenderCharacterLength = static_cast< unsigned char >( strlen( pszSenderCharacter ) ); else pMsg->nSenderCharacterLength = static_cast< unsigned char >( nSenderCharacterLength ); if( nReceiverAccountLength == STR_NTS ) pMsg->nReceiverAccountLength = static_cast< unsigned char >( strlen( pszReceiverAccount ) ); else pMsg->nReceiverAccountLength = static_cast< unsigned char >( nReceiverAccountLength ); if( nReceiverCharacterLength == STR_NTS ) pMsg->nReceiverCharacterLength = static_cast< unsigned char >( strlen( pszReceiverCharacter ) ); else pMsg->nReceiverCharacterLength = static_cast< unsigned char >( nReceiverCharacterLength ); if( nChatLength == STR_NTS ) pMsg->nChatLength = static_cast< unsigned short >( strlen( pszChat ) ); else pMsg->nChatLength = nChatLength; pMsg->size += pMsg->nSenderAccountLength + pMsg->nSenderCharacterLength + pMsg->nReceiverAccountLength + pMsg->nReceiverCharacterLength + pMsg->nChatLength; char * pszStringBuffer = reinterpret_cast< char * >( pMsg + 1 ); s_memcpy( pszStringBuffer, sizeof( szBuffer ) - sizeof( LS_CHAT ), pszSenderAccount, pMsg->nSenderAccountLength ); pszStringBuffer += pMsg->nSenderAccountLength; s_memcpy( pszStringBuffer, sizeof( szBuffer ) - sizeof( LS_CHAT ) - pMsg->nSenderAccountLength, pszSenderCharacter, pMsg->nSenderCharacterLength ); pszStringBuffer += pMsg->nSenderCharacterLength; s_memcpy( pszStringBuffer, sizeof( szBuffer ) - sizeof( LS_CHAT ) - pMsg->nSenderAccountLength - pMsg->nSenderCharacterLength, pszReceiverAccount, pMsg->nReceiverAccountLength ); pszStringBuffer += pMsg->nReceiverAccountLength; s_memcpy( pszStringBuffer, sizeof( szBuffer ) - sizeof( LS_CHAT ) - pMsg->nSenderAccountLength - pMsg->nSenderCharacterLength - pMsg->nReceiverAccountLength, pszReceiverCharacter, pMsg->nReceiverCharacterLength ); pszStringBuffer += pMsg->nReceiverCharacterLength; s_memcpy( pszStringBuffer, sizeof( szBuffer ) - sizeof( LS_CHAT ) - pMsg->nSenderAccountLength - pMsg->nSenderCharacterLength - pMsg->nReceiverAccountLength - pMsg->nReceiverCharacterLength, pszChat, pMsg->nChatLength ); if( pConn->Write( pMsg, pMsg->size ) != pMsg->size ) { chat_log_error( pConn, "DISCONNECTED" ); std::string strLog; XStringUtil::Format( strLog, "%lu\t%d\t%d\t%u\t%d\t%d\t%d\t%d", pMsg->thread_id, pMsg->nSenderAccountID, pMsg->nSenderCharacterID, (unsigned int)pMsg->nChatType, pMsg->nSenderPosX, pMsg->nSenderPosY, pMsg->nReceiverAccountID, pMsg->nReceiverCharacterID ); strLog += "\t"; if( pMsg->nSenderAccountLength ) strLog.append( pszSenderAccount, pMsg->nSenderAccountLength ); strLog += "\t"; if( pMsg->nSenderCharacterLength ) strLog.append( pszSenderCharacter, pMsg->nSenderCharacterLength ); strLog += "\t"; if( pMsg->nReceiverAccountLength ) strLog.append( pszReceiverAccount, pMsg->nReceiverAccountLength ); strLog += "\t"; if( pMsg->nReceiverCharacterLength ) strLog.append( pszReceiverCharacter, pMsg->nReceiverCharacterLength ); strLog += "\t"; if( pMsg->nChatLength ) strLog.append( pszChat, pMsg->nChatLength ); FileLogHandler::GetFileLogHandler()->LogStringEx( NULL, "LostChatLogs", strLog.c_str() ); } }