l2-unlegits/l2detect/main.cpp
alexey.min 4c4ea452d7 Intercept conect on start again
l2c_getUserSkills() done (usage example in sources)
2012-05-12 19:14:08 +00:00

393 lines
9.5 KiB
C++

#include "stdafx.h"
#include "Resource.h"
//#include "mymem.h"
#include "utils.h"
#include "Logger.h"
// lists
#include "CharArray.h"
#include "ClanList.h"
#include "NpcArray.h"
#include "GIArray.h"
#include "WorldObjectTree.h"
// listeners
#include "LoginListener.h"
#include "GameListener.h"
#include "GameClient.h"
// windows
#include "RadarDllWnd.h"
#include "ConfigIni.h"
// net hook
#include "net_hook.h"
// scripting
#include "ScriptEngine.h"
// global app instance handle
HINSTANCE g_hinst;
// global app configuration
CConfig g_cfg;
FILE *g_errorLogFile = NULL; // log file
// global listeners
LoginListener *g_plogin;
GameListener *g_pgame;
GameClient *g_game_client;
int int_dll_was_init = 0;
/** Initializes DLL. returns 0 on success **/
int InitDLL();
/** Uninitializes DLL **/
int UninitDLL();
/** */
void DllThreadStart();
extern void CleanupDirectDraw();
BOOL WINAPI DllMain( HINSTANCE hInstDLL, ULONG reason, LPVOID lpvReserved )
{
lpvReserved = NULL;
if( reason == DLL_PROCESS_ATTACH )
{
//MessageBox( 0, TEXT("DLL_PROCESS_ATTACH"), NULL, 0 );
if( int_dll_was_init ) return TRUE;
InterlockedIncrement( (LONG *)&int_dll_was_init );
g_hinst = hInstDLL;
DisableThreadLibraryCalls( hInstDLL );
//
DllThreadStart();
}
else if( reason == DLL_PROCESS_DETACH )
{
//MessageBox( 0, TEXT("DLL_PROCESS_DETTACH"), NULL, 0 );
if( int_dll_was_init == 0 ) return TRUE;
InterlockedDecrement( (LONG *)&int_dll_was_init );
UninitDLL();
}
return TRUE;
}
#ifdef _DEBUG
void test_GetClassInfoEx()
{
WNDCLASSEXW wc;
if( GetClassInfoExW( NULL, WC_TABCONTROLW, &wc ) )
{
MessageBox( NULL, TEXT("GetClassInfoExW() OK"), TEXT("Test"), 0 );
}
else
{
TCHAR tstr[128];
wsprintf( tstr, TEXT("GetClassInfoExW() failed! Error %u"), (unsigned int)GetLastError() );
MessageBox( NULL, tstr, TEXT("Test"), 0 );
}
}
#endif /* _DEBUG */
DWORD WINAPI DllThread(LPVOID lpParam)
{
UNREFERENCED_PARAMETER(lpParam);
#ifdef _DEBUG
//test_GetClassInfoEx();
#endif /* _DEBUG */
if( InitDLL() )
{
return 12345;
}
#ifdef _DEBUG
//test_GetClassInfoEx();
#endif /* _DEBUG */
if( !Hook_ValidateAlign() )
{
MessageBox( NULL, TEXT("Structure alignment error!"), TEXT("Alignment error!"), MB_ICONSTOP );
RaiseException( EXCEPTION_DATATYPE_MISALIGNMENT, 0, 0, NULL );
return 123456;
}
// install hook over ws2_32.dll!connect()
// SEH only under msvc
#ifdef _MSC_VER
__try
{
#endif
if( !Hook_IsWinsockConnectOrig() )
{
log_error( LOG_WARNING, "Seems like ws2_32.dll!connect() is already hooked by someone...\n" );
log_error( LOG_WARNING, "Some firewall/protection sofware?\n" );
log_error( LOG_WARNING, "I'll try to set up my hook, but program may not function correctly later.\n" );
}
if( !Hook_CheckVirtualProtect() )
{
log_error( LOG_WARNING, "Seems like kernel32.dll!VirtualProtectEx() is hooked, so...\n" );
log_error( LOG_WARNING, "Maybe we're running in GameGuard protected program?\n" );
log_error( LOG_WARNING, "Be careful!\n" );
}
Hook_InterceptConnect_my();
if( !Hook_ValidateInterception_my() )
{
log_error( LOG_ERROR, "Seems like my try to intercept ws2_32.dll!connect() failed.\n" );
log_error( LOG_ERROR, "All network connections will not be intercepted!\n" );
}
//Hook_InterceptConnect_Dis(); // this unused..
#ifdef _MSC_VER
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
ErrorLogger_LogLastError( "Exception occured during call to Hook_InterceptConnect_my()", GetLastError() );
log_error( LOG_ERROR, "We will try to continue execution...\n" );
ErrorLogger_FlushLogFile();
}
#endif
L2PNet_setFunction( L2PFUNC_CONNECT, (void *)connect_l2packets_my );
/*int i;
i = 6;
while( i >= 0 )
{
Hook_ValidateInterception_my();
Sleep( 10000 );
i--;
}*/
//UninitDLL();
return 0;
}
void DllThreadStart()
{
HANDLE hThread = NULL;
DWORD dwTID = 0;
hThread = (HANDLE)_beginthreadex( NULL, 0,
(unsigned int (__stdcall *)(void *))DllThread, NULL, 0,
(unsigned int *)&dwTID );
if( hThread != NULL ) CloseHandle( hThread );
}
#ifdef L2D_INIT_SSL_LIBRARY
bool InitSSL()
{
SSL_load_error_strings();
SSL_library_init();
void *rndbuf = malloc(1024);
if( rndbuf )
{
RAND_seed( rndbuf, 1024 );
free( rndbuf );
return true;
}
return false;
}
#endif
//#define L2D_INIT_COMMON_CONTROLS
#ifdef L2D_INIT_COMMON_CONTROLS
#pragma comment( lib, "comctl32" )
#endif
void AreWeInIngameMode()
{
TCHAR tszEvtName[256];
wsprintf( tszEvtName, TEXT("L2Detect Outgame Event_%d"), (unsigned)GetCurrentProcessId() );
HANDLE hEvtDbg = OpenEvent( EVENT_MODIFY_STATE, FALSE, tszEvtName );
if( hEvtDbg == NULL ) // ingame
{
g_cfg.isInGameMode = true;
CloseHandle( hEvtDbg );
log_error( LOG_OK, "Running in ingame mode...\n" );
}
else
{
g_cfg.isInGameMode = false;
log_error( LOG_OK, "Running in outgame mode...\n" );
}
}
/** Initializes DLL. returns 0 on success **/
int InitDLL()
{
// init common controls?
//MyInitCommonControls();
#ifdef L2D_INIT_COMMON_CONTROLS
//MyInitCommonControlsEx();
#endif
// read global app config
g_cfg.SetDefault();
if( !g_cfg.ReadConfig( _T("L2Detect.ini") ) ) g_cfg.SetDefault();
// determine INGAME or OUTGAME mode. NOW
AreWeInIngameMode();
// setup L2Packets Net Layer
L2PNet_InitDefault();
L2PacketNames_Init();
// setup Logger
ErrorLogger_Init();
ErrorLogger_SetLogFile( NULL );
#ifdef _DEBUG
ErrorLogger_SetAutoPrependErrorType( true );
g_errorLogFile = fopen( "L2Detect.log", "wt" );
ErrorLogger_SetLogFile( g_errorLogFile );
ErrorLogger_Enable( true );
//ErrorLogger_EnableLoggingToConsole( true );
log_error( LOG_DEBUG, "InitDLL() called! int_dll_was_init = %d\n", int_dll_was_init );
ErrorLogger_FlushLogFile();
#endif
// Init COM
HRESULT comRes = CoInitialize( NULL );
if( comRes != S_OK )
{
log_error( LOG_ERROR, "CoInitialize() failed: HRESULT = %d (GetLastError() = %u)\n",
comRes, (unsigned int)GetLastError() );
}
// init MyMem after logger
//MyMem_Init();
// init OpenSSL
#ifdef L2D_INIT_SSL_LIBRARY
InitSSL();
#endif
// init L2 Data
char outErrMsg[512] = {0};
L2Data_init();
L2Data_DB_Init( outErrMsg, "L2Detect_items.sqlite3db", "L2Detect_mobs.sqlite3db", "L2Detect_skills.sqlite3db" );
if( outErrMsg[0] ) MessageBoxA( NULL, outErrMsg, "L2Data_DB_Init() error!", MB_ICONSTOP );
L2Data_SM_init();
// setup binTrees
CharArray_Init();
ClanList_Init();
NpcArray_Init();
GIArray::getInstance();
WorldObjectTree_Init();
// create listeners
// create LoginListener only in outgame mode
g_plogin = NULL;
if( g_cfg.isInGameMode == false )
{
g_plogin = new LoginListener();
if( !g_plogin->start() )
{
log_error( LOG_ERROR, "Login server listener creation failed!\n" );
MessageBox( NULL, TEXT("Login server listener creation failed!"),
TEXT("Init error!"), MB_ICONSTOP );
return 1;
}
} // create LoginListener only in outgame mode
g_pgame = new GameListener();
if( !g_pgame->start() )
{
log_error( LOG_ERROR, "Game server listener creation failed!\n" );
MessageBox( NULL, TEXT("Game server listener creation failed!"),
TEXT("Init error!"), MB_ICONSTOP );
return 1;
}
// create global GameClient object (important!!!!!)
g_game_client = new GameClient();
// instantiate ScriptEngine
ScriptEngine::getInstance()->init();
#ifdef _DEBUG
ErrorLogger_FlushLogFile();
#endif
RadarDllWindowStart( g_hinst );
return 0; // ALL OK
}
/** Uninitializes DLL **/
int UninitDLL()
{
log_error( LOG_DEBUG, "UninitDLL() called! int_dll_was_init = %d\n", int_dll_was_init );
// delete ScriptEngine
ScriptEngine::freeInstance();
// stop listeners
log_error( LOG_DEBUG, "Signaling listeners to exit...\n" );
if( g_plogin ) g_plogin->signalStop(); // LoginListener may not be started in ingame mode at all
g_pgame->signalStop();
// wait for stop
if( g_plogin ) // LoginListener may not be started in ingame mode at all
{
log_error( LOG_DEBUG, "Waiting for login listener to stop (10 secs)...\n" );
if( !g_plogin->waitStopped( 10000 ) )
{
log_error( LOG_WARNING, "Login listener wait timeout expired... :( \n" );
g_plogin->terminateThread();
}
else log_error( LOG_DEBUG, "Login listener wait OK\n" );
delete g_plogin;
g_plogin = NULL;
}
log_error( LOG_DEBUG, "Waiting for game listener to stop (10 secs)...\n" );
if( !g_pgame->waitStopped( 10000 ) )
{
log_error( LOG_WARNING, "Game listener wait timeout expired... :( \n" );
g_pgame->terminateThread();
}
else log_error( LOG_DEBUG, "Game listener wait OK\n" );
delete g_pgame;
g_pgame = NULL;
delete g_game_client;
#ifdef _DEBUG
ErrorLogger_FlushLogFile();
#endif
//
// Cleanup
//
// close database
L2Data_DB_Free();
L2Data_SM_free();
// save global app config
g_cfg.SaveConfig();
// clean binTrees
CharArray_Free();
ClanList_Free();
NpcArray_Free();
GIArray::freeInstance();
WorldObjectTree_Free();
// close MyMem before logger
//MyMem_Free();
if( g_cfg.isInGameMode ) CleanupDirectDraw();
// Uninitialize COM
CoUninitialize();
// close log
#ifdef _DEBUG
log_error( LOG_OK, "Closing log. Last message.. Bye!\n" );
ErrorLogger_FlushLogFile();
ErrorLogger_SetLogFile( NULL );
if( g_errorLogFile ) fclose( g_errorLogFile );
g_errorLogFile = NULL;
#endif
// shutdown winsock
//WSACleanup();
//L2PNet_Cleanup();
return 0;
}