385 lines
13 KiB
C++
385 lines
13 KiB
C++
|
|
#include "LogClient.h"
|
|
#include "LogStruct.h"
|
|
|
|
#include <vector>
|
|
|
|
#include <network/XSyncStreamConnection.h>
|
|
#include <toolkit/ILock.h>
|
|
#include <logging/FileLog.h>
|
|
|
|
#include <toolkit/XThread.h>
|
|
#include <toolkit/XEnv.h>
|
|
#include <toolkit/XStringUtil.h>
|
|
#include <toolkit/XConsole.h>
|
|
|
|
|
|
|
|
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() );
|
|
}
|
|
}
|