// SFrame.cpp : Defines the entry point for the application. // Bypassed Bypassed Bypassed Damn // Do not delete // Runtime Error! // Program : c:\Program Files\NFLAVOR\Rappelz_cut\SFrame.exe R6002 // -floating point not loaded // Forced loading volatile float a = 1.f; extern "C" { extern int _fltused; volatile int _AVOID_FP_BUG = _fltused; }; // The issue above is related. // #include "stdafx.h" //#define VLD_FORCE_ENABLE //#include //#pragma message( ">>>>>>VLD is activated<<<<<" ) //#include "Windows.h" //#include #include "SFrame.h" #include "w32_util.h" #include "SBotManager.h" #include "LuaVM.h" #include "SGameScript.h" #include "SBotScript.h" #include "SSystemScript.h" #include #include #include #include #include #include #include #include #include "SSkillDB.H" #include "SMotionDB.H" #include "STenacityDB.H" #include "SItemDB.h" #include "GameUrlDefine.h" #include "KUIWndManager.h" #include "KUIWnd.h" #include #include #include #include #include #include "KThreadLoader.h" #include "GameDefine.h" #include "SGameOption.h" #include "SGameManager.h" #include "KCommandBuilder.h" #include "KTextRender.h" #include "KTextParser.h" #include "KTextEmoticonRender.h" #include "KUIControlEdit.h" #include #include #include #include "SStringDB.h" #include "SLocalCommandDB.h" #include //#include "Util.h" #include "CEditBoxInfo.h" #include #include #include #include "SWebCtrlInterface.h" #include "shellapi.h" #include "SDebug_Util.h" #include "KResourceManager.h" #include "SplashLoading/SplashLoading.h" #include "SCreatureEnhanceDB.h" #include "SEnhanceEffectDB.h" #include "Hooking.h" #include "STitleDB.h" #include "SMonsterCreatureDB.h" #ifdef CLOUD_LUA #include "SGameCloud.h" #endif #include #include #include #include #include #include //#include //#ifdef _DEBUG //#define new new(_NORMAL_BLOCK, __FILE__, __LINE__) //#endif #ifdef _COUNTRY_TL_ #include "./Localization/Thailand.h" #endif #ifdef _COUNTRY_ME_ #include "./Localization/MiddleEast.h" #endif #ifdef _USE_XTRAP_MODULE #include #include #endif #ifdef _EDIT_ENVIRONMENT_ #include "EditParameterDialog.h" #endif using namespace XSEH; #define MAX_LOADSTRING 100 // 전역 변수입니다. TCHAR szTitle[256]; // 제목 표시줄 텍스트입니다. TCHAR szWindowClass[MAX_LOADSTRING]; // 기본 창 클래스 이름입니다. TCHAR szFPS[32]; TCHAR BuildDate[16]; TCHAR BuildTime[16]; std::string g_strModulePath; //Bot Manager SBotManager * g_pSBotMng = NULL; bool g_bUserCamMode = false; // Manual mode for video recording support camera (toggled by typing //camera in the chat window) #ifdef _DEBUG bool g_bDebugMode = true; #else // 2010.11.10: Modified to allow setting g_bDebugMode if the account, which is not in developer mode, contains '@' - prodongi #ifdef _DEV bool g_bDebugMode = true; // Check if it is in developer mode or not. (It toggles when typing //debug in the chat window) #else bool g_bDebugMode = false; // Check if it is in developer mode or not. (It toggles when typing //debug in the chat window) #endif #endif bool g_bRenderUI = true; HHOOK g_hKeyBoardHook = NULL; HWND g_hWnd = NULL; HWND g_hWnd_Explorer = NULL; FILE* g_pFLog = NULL; HINSTANCE g_hInstance; extern const char * CLIENT_VER; DWORD g_dwFPS = 0; DWORD g_dwCount = 0; DWORD g_dwFPSTime = 0; bool g_bLogStringRate = false; DWORD g_dwKeyResumeTime = 0; bool g_bCheckHook = false; #ifdef _HACK_SHIELD_ bool g_bAhnHS = false; #endif bool g_bWindowFPS = false; int g_DP_Count[3]; int g_UsedMeshEXPoolCount[3]; int g_Poly_Count; int g_TexMem; bool g_bActiveRender = false; IWebBrowser2* g_pWebBrowser = NULL; bool g_bServerListFocus = false; bool g_bServerListSeen = false; bool g_bCharListSeen = false; bool g_bCleanupCOM = false; std::string g_strGuildFullDir; const char * g_pGuildDir = ".\\Guild_Icon\\"; //#define DISABLE_DEBUGGER_DETECTOR KPoint g_Help_url; KPoint g_Cash_url; KPoint g_Cash_add_url; DEVMODE g_dm; DEVMODE g_dm_apply; #ifdef _DEBUG int g_nMemAllocCnt[128]; #endif // This is the forward declaration of the functions in this code module. ATOM MyRegisterClass(HINSTANCE hInstance); HWND InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); // { [sonador][1.5.1] Improved keyboard input #ifdef _USE_KEYBOARD_HOOK LRESULT CALLBACK KeyboardProc( int code, WPARAM wParam, LPARAM lParam ); #else void ResetHotKeys(); LRESULT CALLBACK HotKeyProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ); #endif // } void SetURLNavigate( IWebBrowser2* pWebBrowser, const char * pURL ); void SetWebBrowserVisible( IWebBrowser2* pWebBrowser, bool bVisible ); bool ChangeDisplay(); bool RestoreDisplay(); void CheckDisplay(); void SetWindowStyle( bool bFullScreen ); BOOL CheckOSVersion(); #ifdef _HACK_SHIELD_ #include #include // sonador 7.4.4 핵쉴드 270 적용 #include "SGameVM.h" int __stdcall _AhnHS_Callback( long lCode, long lParamSize, void* pParam ); bool UpdateHackShieldService(); // sonador 7.4.4 핵쉴드 270 적용 bool StartHackShieldService(); void StopHackShieldService(); void PauseHackShieldService(); void ResumeHackShieldService(); bool g_bStartingHSService = false; #endif // #2.3.2.7 sonador #ifdef _DEV #define NO_GAMEGUARD #endif #include //CNPGameLib *g_pNpgl = NULL; CNPGameLib *g_pNpgl; bool StartnProtectService(); DWORD g_dwCheckGameMon = 0; bool g_bConnGameMon = true; std::vector< GameSecurityMsg* > g_SecurityMsg; DWORD g_dwhkTime = 0; //----------------------------------------------------------------------------- // External function-prototypes //----------------------------------------------------------------------------- extern HRESULT GetDXVersion( DWORD* pdwDirectXVersion, TCHAR* strDirectXVersion, int cchDirectXVersion, TCHAR & cDXVerLetter ); extern HWND g_hWnd; VARIANT_BOOL g_IsShowWebBrowser = false; bool g_IsShowWebBrowserChanged = false; std::string g_strDebugInfo_SUN("START"); BOOL CALLBACK About(HWND hDlg,UINT iMessage,WPARAM wParam,LPARAM lParam) { switch(iMessage) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: switch (wParam) { case IDOK: //ShellExecute( NULL, "open", "http://rappelz.nefficient.co.kr/rappelz/directx9c/dxwebsetup.exe", NULL, NULL, 0 ); ShellExecute( NULL, "open", "http://127.0.0.1/rappelz/directx9c/dxwebsetup.exe", NULL, NULL, 0 ); // Fraun 7/12/2025 nullifying gala spyware EndDialog(hDlg,0); return TRUE; case ID_CANCEL: EndDialog(hDlg,0); return TRUE; } break; } return FALSE; } // 1번째 네트웤 아답터의 맥어드레스를 돌려 준다 // 6바이트 짜리 unsigned char 로 구성되어져 있다. // 출력 함수는 아래 참조 // 터키 요청으로 추가 예정 // 서버랑 페킷이 완료 되면 추가 예정 //2009-08-12 : hunee // Prints the MAC address stored in a 6 byte array to stdout /* static void printMACaddress(unsigned char MACData[]) { printf("MAC Address: %02X-%02X-%02X-%02X-%02X-%02X\n", MACData[0], MACData[1], MACData[2], MACData[3], MACData[4], MACData[5]); }*/ /*#include #include #pragma comment(lib, "iphlpapi.lib") /* static unsigned char * getMACAddress() { // Fetches the MAC address and prints it static IP_ADAPTER_INFO adapterInfo[16]; DWORD bufLen = sizeof(adapterInfo); DWORD status = GetAdaptersInfo(adapterInfo, &bufLen); assert(status == ERROR_SUCCESS); PIP_ADAPTER_INFO pAdapterInfo = adapterInfo; return pAdapterInfo->Address; }*/ void InitWebBrowser( IWebBrowser2* pWebBrowser ) { if( pWebBrowser ) { //gmpbigsun( 20130321 ) : 유럽 페이지 이상으로 아래기능 제거 // pWebBrowser->put_ToolBar(VARIANT_FALSE); // 익스플로어 툴바 없앰 // pWebBrowser->put_MenuBar(VARIANT_FALSE); // 메뉴바 없앰 // pWebBrowser->put_AddressBar(VARIANT_FALSE);// 주소창 없앰 // pWebBrowser->put_StatusBar(VARIANT_FALSE); // 상태바 없앰 } } void SetWebWindowStyle( HWND hWebBrowser ) { // Window Style 변경 DWORD dwStyle = GetWindowLong(hWebBrowser, GWL_STYLE); dwStyle = WS_CHILD; //dwStyle &= ~WS_BORDER; //dwStyle &= ~WS_THICKFRAME; //dwStyle &= ~WS_CAPTION; //dwStyle &= ~WS_SYSMENU; //dwStyle &= ~WS_MINIMIZE; //dwStyle &= ~WS_VSCROLL; //dwStyle &= ~WS_HSCROLL; if( SetWindowLong((HWND)hWebBrowser, GWL_STYLE, dwStyle) == 0 ) { std::string strErr = CStringUtil::StringFormat( "Failed Explorer SetWindowStyle : %d", GetLastError() ); MessageBox( g_hWnd, strErr.c_str(), "Rappelz-Error", MB_ICONERROR|MB_OK ); } HWND hr_hWnd = ::SetParent( hWebBrowser, g_hWnd ); } #include #include #include typedef struct _web_browser_info_ { int nIndex; HWND hWnd; HWND hWndIE; IWebBrowser2* pWebBrowser; } _WEB_BROWSER_INFO_; static int g_nWebBrowserIndex = 0; std::vector<_WEB_BROWSER_INFO_> g_vWebBrowserInfoList; void DeleteAllWebBrowserInfo() { for( unsigned int i(0); g_vWebBrowserInfoList.size()>i; i++ ) { DestroyWindow( g_vWebBrowserInfoList[i].hWndIE ); DestroyWindow( g_vWebBrowserInfoList[i].hWnd ); } } IWebBrowser2* GetWebBrowser( int nWidth, int nHeight, int nAddWidth, int nAddHeight ) { CComQIPtr pWebBrowser; HWND hWnd=g_hWnd; RECT rcWnd, rWnd; GetClientRect(hWnd, &rcWnd); GetWindowRect(hWnd, &rWnd); rcWnd.left = 0; rcWnd.top = 0; int nAppWidth = rcWnd.right - rcWnd.left; int nAppHeight = rcWnd.bottom - rcWnd.top; int nCenterX = (nAppWidth - nWidth)/2 + nAddWidth; int nCenterY = (nAppHeight - nHeight)/2 + nAddHeight; // 자식창은 WS_POPUP으로 띄워야 한다. HWND hChild = CreateWindow( "static", NULL, WS_VISIBLE | WS_CHILD, nCenterX, nCenterY, nWidth, nHeight, g_hWnd, (HMENU)0, g_hInstance, (LPVOID) NULL); // 비주얼 스튜디오 7.1이라 AtlAxWin71 -> 2010(100) HWND hwndIE = CreateWindow( "AtlAxWin100", "Shell.Explorer.2", WS_CHILD|WS_VISIBLE, 0, 0, nWidth, nHeight, hChild, (HMENU)0, GetModuleHandle(NULL), NULL); if(!hwndIE) { if( hChild ) DestroyWindow( hChild ); return NULL; } CComPtr punkIE; if (AtlAxGetControl(hwndIE, &punkIE) == S_OK) { pWebBrowser = punkIE; if( pWebBrowser ) { pWebBrowser->put_Top( 0 ); pWebBrowser->put_Left( 0 ); pWebBrowser->put_Width( nWidth ); pWebBrowser->put_Height( nHeight ); // 2008.5.30 floyd #2.3.1.21 웹브라우저 창에 Drag&Drop으로 다른 페이지를 볼수 있게 하는 기능 제거 pWebBrowser->put_RegisterAsDropTarget( FALSE ); IOleObject *pIOleObj = NULL; HRESULT hResult = pWebBrowser->QueryInterface(IID_IOleObject, (void**)&pIOleObj); if (pIOleObj != NULL) { CWebCtrlInterFace* pWebCtrlInterFace = new CWebCtrlInterFace( hwndIE ); pWebCtrlInterFace->SetContextMenuMode( kNoContextMenu ); IOleClientSite *oldClientSite = NULL; hResult = pIOleObj->GetClientSite(&oldClientSite); if ( hResult == S_OK ) { if( oldClientSite ) { pWebCtrlInterFace->SetDefaultClientSite(oldClientSite); oldClientSite->Release(); } } hResult = pIOleObj->SetClientSite(pWebCtrlInterFace); } _WEB_BROWSER_INFO_ web_browser_info; web_browser_info.nIndex = g_nWebBrowserIndex++; web_browser_info.hWnd = hChild; web_browser_info.hWndIE = hwndIE; web_browser_info.pWebBrowser = pWebBrowser; g_vWebBrowserInfoList.push_back( web_browser_info ); return pWebBrowser; } } if( hChild ) DestroyWindow( hChild ); if( hwndIE ) DestroyWindow( hwndIE ); return NULL; } void CloseWebBrowser( IWebBrowser2* pWebBrowser ) { HWND hMoveWnd = NULL; for( unsigned int i(0); g_vWebBrowserInfoList.size()>i; i++ ) { if( g_vWebBrowserInfoList[i].pWebBrowser == pWebBrowser ) { hMoveWnd = g_vWebBrowserInfoList[i].hWnd; g_vWebBrowserInfoList[i].pWebBrowser->Stop(); g_vWebBrowserInfoList[i].pWebBrowser->Quit(); DestroyWindow( g_vWebBrowserInfoList[i].hWndIE ); DestroyWindow( g_vWebBrowserInfoList[i].hWnd ); g_vWebBrowserInfoList.erase( g_vWebBrowserInfoList.begin()+i ); break; } } } void SetWebBrowserMovePos( IWebBrowser2* pWebBrowser, int nX, int nY ) { HWND hMoveWnd = NULL; for( unsigned int i(0); g_vWebBrowserInfoList.size()>i; i++ ) { if( g_vWebBrowserInfoList[i].pWebBrowser == pWebBrowser ) { hMoveWnd = g_vWebBrowserInfoList[i].hWnd; break; } } if( hMoveWnd ) SetWindowPos(hMoveWnd,NULL,nX,nY,0,0,SWP_NOSIZE); } //가운데 위치 void SetWebBrowserCenterPos( IWebBrowser2* pWebBrowser, int nW, int nH ) { HWND hMoveWnd = NULL; for( unsigned int i(0); g_vWebBrowserInfoList.size()>i; i++ ) { if( g_vWebBrowserInfoList[i].pWebBrowser == pWebBrowser ) { hMoveWnd = g_vWebBrowserInfoList[i].hWnd; break; } } if( hMoveWnd ) { HWND hWnd=g_hWnd; RECT rcWnd, rWnd; GetClientRect(hWnd, &rcWnd); GetWindowRect(hWnd, &rWnd); rcWnd.left = 0; rcWnd.top = 0; int nAppWidth = rcWnd.right - rcWnd.left; int nAppHeight = rcWnd.bottom - rcWnd.top; int nCenterX = (nAppWidth - nW)/2; int nCenterY = (nAppHeight - nH)/2; if( hMoveWnd ) SetWindowPos(hMoveWnd,NULL,nCenterX+2,nCenterY,0,0,SWP_NOSIZE); } } void SetWebBrowserVisible( IWebBrowser2* pWebBrowser, bool bVisible ) { if( bVisible ) { g_IsShowWebBrowser = VARIANT_BOOL(true); } else { g_IsShowWebBrowser = VARIANT_BOOL(false); } g_IsShowWebBrowserChanged = true; if( pWebBrowser ) pWebBrowser->put_Visible( g_IsShowWebBrowser ); if( !g_IsShowWebBrowser ) ::SetFocus( g_hWnd ); } void SetVisibleNavigate( bool bVisible ) { if( !g_pWebBrowser ) return; if( bVisible ) { g_IsShowWebBrowser = VARIANT_BOOL(true); g_pWebBrowser->put_Visible( g_IsShowWebBrowser ); } else { g_pWebBrowser->put_Visible( g_IsShowWebBrowser ); CloseWebBrowser( g_pWebBrowser ); if( g_vWebBrowserInfoList.empty() ) g_IsShowWebBrowser = VARIANT_BOOL(false); g_pWebBrowser = NULL; } g_IsShowWebBrowserChanged = true; if( !g_IsShowWebBrowser ) ::SetFocus( g_hWnd ); } void CurURLRefresh( IWebBrowser2* pWebBrowser ) { if( pWebBrowser ) { BSTR url; if( pWebBrowser->get_LocationURL( &url ) == S_OK ) { /* static _variant_t vars = _variant_t( "http://rion:8080/client/guild/leader.aspx" ); _variant_t varurl = _variant_t(url); if( varurl == vars ) return;*/ char urlName [ 1024 ]; //AziaMafia Fix CODEPAGE CP_UTF8 // CP_ACP WideCharToMultiByte (CP_ACP, 0, url, -1, urlName, 1024, NULL, NULL ); SysFreeString ( url ); if ( strstr( urlName, "leader.aspx" ) ) { return; } } //BSTR url; //HRESULT hr = pWebBrowser->get_LocationURL( &url ); //if( hr == S_OK ) //{ // _variant_t vars, null; // VariantInit(&vars); // VariantInit(&null); // null.vt = VT_NULL; // vars = _variant_t(url); // pWebBrowser->Navigate2(&vars,&null,&null,&null,&null); // VariantClear(&vars); // VariantClear(&null); // SysFreeString( url ); //} pWebBrowser->Refresh(); } } void SetURLNavigate( IWebBrowser2* pWebBrowser, const char * pURL ) { if( pWebBrowser && pURL ) { //Google Page _variant_t vars, null; VariantInit(&vars); VariantInit(&null); null.vt = VT_NULL; vars = _variant_t(pURL); pWebBrowser->Navigate2(&vars,&null,&null,&null,&null); VariantClear(&vars); VariantClear(&null); } } void SetNavigate( const char * pURL, bool bVisible, int nAddWidth, int nAddHeight ) { if( g_pWebBrowser == NULL ) { g_pWebBrowser = GetWebBrowser( g_Cash_url.x, g_Cash_url.y, nAddWidth, nAddHeight ); if( g_pWebBrowser ) { HRESULT hrGetHWN = g_pWebBrowser->get_HWND( (long*)&g_hWnd_Explorer ); if( hrGetHWN == S_OK ) { SetWebWindowStyle( g_hWnd_Explorer ); } InitWebBrowser( g_pWebBrowser ); } } if( g_pWebBrowser && bVisible ) { //Google Page _variant_t vars, null; VariantInit(&vars); VariantInit(&null); null.vt = VT_NULL; vars = _variant_t(pURL); g_pWebBrowser->Navigate2(&vars,&null,&null,&null,&null); VariantClear(&vars); VariantClear(&null); } SetVisibleNavigate( bVisible ); } //INT_PTR CALLBACK ExplorerDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) //{ // switch( uMsg ) // { // case WM_COMMAND : // { // switch ( LOWORD( wParam ) ) // { // case IDC_BUTTON1: // { //Close // if( g_pWebBrowser ) // { // VARIANT_BOOL pBool=false; //The browser is invisible // g_pWebBrowser->put_Visible( pBool ); // } // ShowWindow( hwndDlg, SW_HIDE ); // } // break; // case IDC_BUTTON2: // { //Shop : Item // SetNavigate( "http://itemshop.rappelz.com/" ); // } // break; // case IDC_BUTTON3: // { //Cache 충전 // SetNavigate( "http://itemshop.rappelz.com/" ); // } // break; // } // } // break; // } // // return DefWindowProc(hwndDlg, uMsg, wParam, lParam); //} void InitScript(); //XCriticalSection xCS; //#define _WEB_DISP_MODE #define _EXCEPTION_PROCESS ////////////////////////////////////////////////////////////////////////// void WINAPI UserFunc( HANDLE hFile ) { #ifdef _WEB_DISP_MODE RestoreDisplay(); //강제 종료시 복구 #endif #ifdef _HACK_SHIELD_ if( g_bStartingHSService ) StopHackShieldService(); #endif #ifdef _EXCEPTION_PROCESS if( IDYES == MessageBox( g_hWnd, S( 828 ), "Rappelz-Client error", MB_YESNO ) ) { XModuleInfo cModuleInfo; cModuleInfo.Load( ::GetCurrentProcess() ); char szMyVersion[64] = ""; const WORD* pFileVerion = cModuleInfo.FileVersion(); s_sprintf( szMyVersion, _countof( szMyVersion ), "%d.%d.%d.%d", pFileVerion[0], pFileVerion[1], pFileVerion[2], pFileVerion[3] ); std::string strErr; std::string strPost; strPost += "exception="; strErr = XSEH::GetExceptionInfo(); nsl::replace( &strErr, "=", "-" ); nsl::replace( &strErr, "&", "." ); strPost += strErr; strPost += "&"; strPost += "address="; strErr = XSEH::GetExceptionAddress(); nsl::replace( &strErr, "=", "-" ); nsl::replace( &strErr, "&", "." ); strPost += strErr; strPost += "&"; strPost += "detail="; strErr = "Client Version: "; strErr += "v"; strErr += szMyVersion; strErr += XSEH::GetExceptionDetail(); nsl::replace( &strErr, "=", "-" ); nsl::replace( &strErr, "&", "." ); strPost += strErr; strErr = "SLog:"; strErr += g_strDebugInfo_SUN; strPost += strErr; /// 2010.11.30 - prodongi //XInternet::QueryHTTPRequest( "http://www.rappelz.com/clientErrLog.aspx", NULL, 0, strPost.c_str() ); //XInternet::QueryHTTPRequest( "http://api.rappelz-equation.fr/api/game/exception", NULL, 0, strPost.c_str() ); // Fraun 7/11/2025 nullrouting error report, to avoid sending extra info to galalab; changing it directly to rappelz.log XInternet::QueryHTTPRequest("http://127.0.0.1/nothing", NULL, 0, strPost.c_str()); SLOG(strPost.c_str()); } if( g_bCleanupCOM ) CoUninitialize(); #endif // WriteFile( hFile, "다운 된다. 대략 안 좋다~~~", (DWORD)strlen("다운 된다. 대략 안 좋다~~~"), &tmp, NULL ); } bool IsFile( const char *szFileName ) { FILE* pack_fp = fopen( szFileName, "rb" ); if( pack_fp ) { fclose(pack_fp); return true; } return false; } /// 2010.11.03 Retrieve the GameGuard INI file for either the live server or test server /// First, try to find the file for the live server. If not found, look for the test server file. /// If neither is found, return the live server file, because CNPGameLib handles the error. char const* getNProtectIniFileName(char const* oriFileName) { static std::string str; // Live server str = oriFileName; str += ".ini"; if (IsFile(str.c_str())) { return oriFileName; } // 테섭 str = oriFileName; str += "Test.ini"; if (IsFile(str.c_str())) { str = oriFileName; str += "Test"; return str.c_str(); } return oriFileName; } bool CheckAuthServerIP( const std::string& strAuthServerAddress ) { if( strAuthServerAddress.empty() == true ) { return false; } if (strAuthServerAddress == "127.0.0.1") return true; // Alucard machine XNetworkUtil::XNetworkInitHelper netInitHelper; // Change the authentication server address to an IP XAddr addr( strAuthServerAddress.c_str(), 0 ); struct sockaddr_in addr_in; if( XNetworkUtil::ConvAddr( addr, addr_in ) == false ) { return false; } if( XNetworkUtil::ConvAddr( addr_in, addr ) == false ) { return false; } std::string strAuthIP = addr.GetAddr(); // Fraun IP set 7/20/2025 ENV().Set( "auth_ip", strAuthIP ); std::set authIPsSet; authIPsSet.emplace("127.0.0.1"); // Localhost // Only IPs from authIPsSet and all local routing IPs (Starts from 192.168.xxx.xxx) are allowed if ( (authIPsSet.find(strAuthIP) != authIPsSet.end()) || strAuthIP.rfind("192.168.", 0) == 0 ) { return true; } return false; } bool InitResource() { // 2011.06.15 Dual client setup - prodongi std::string default_encoding = ENV().GetString( "locale", "CP949" ); nsl::uni::init( default_encoding.c_str() ); nsl::uni::set_resource_encoding( ENV().GetString( "res_locale", default_encoding.c_str()).c_str()); bool bExistOldPackingFile = false; bool bExistNewPackingFile1 = false; bExistOldPackingFile = IsFile( "data.dat" ); bExistNewPackingFile1 = IsFile( "data.000" ); if( bExistNewPackingFile1 == false /*&& bExistNewPackingFile2 == false*/ ) return false; #ifdef _HACK_SHIELD_ if( ENV().IsExist( "ahnhs" ) ) g_bAhnHS = true; #endif if( ENV().IsExist( "winfps" ) ) g_bWindowFPS = true; if( ENV().IsExist( "string_log" ) ) g_bLogStringRate = true; if( ENV().IsExist( "font_ratio" ) ) KTextRender::SetFreeTypeRatio( ENV().GetFloat( "font_ratio", 1.3f ) ); KTextParser::SetUseWordWrap( true ); KTextRender::GenerateRandColor(); // Make text consisting of only English/Numbers larger in Chinese... (Temporary until the font is found.) Southeast Asia exception if( stricmp( ENV().GetString( "locale" ).c_str(), "BIG5" ) == 0 && stricmp( ENV().GetString( "country" ).c_str(), "MASG" ) != 0 ) { KTextRender::SetFreeTypeYOffset( -1 ); KTextRender::EnableEnglishGrow(); } // Second resource if( ENV().IsExist( "secondres" ) ) { static KRealFileSystem _secondRes; std::string strSecond = ENV().GetString( "secondres" ).c_str(); XFileUtil::NomalizeDirectoryName( strSecond ); _secondRes.Init( strSecond.c_str() ); KFileManager::Instance().AddResourceSource( &_secondRes ); } #ifndef NDEBUG // } // { 웹서버 주소 // if( ENV().IsExist( "web" ) ) // { // static KRealFileSystem _web; // std::string strWeb = ENV().GetString( "web" ).c_str(); // // XFileUtil::NomalizeDirectoryName( strWeb ); // // _web.Init( strWeb.c_str() ); // KFileManager::Instance().AddResourceSource( &_web ); // } // } #endif // } { //서비스 지역 if( ENV().IsExist( "country" ) ) { static KRealFileSystem _web; std::string strWeb = ENV().GetString( "country" ).c_str(); XFileUtil::NomalizeDirectoryName( strWeb ); _web.Init( strWeb.c_str() ); KFileManager::Instance().AddResourceSource( &_web ); } } // { 개발용 메인 리소스 if( ENV().IsExist( "notenc" ) ) { static KRealFileSystem _mainRes; _mainRes.Init( ENV().GetString( "res", "./Resource/" ).c_str() ); KFileManager::Instance().AddResourceSource( &_mainRes ); } // } if( ENV().IsExist( "tserver" ) ) { static KRealFileSystem _server; std::string strServer = ENV().GetString( "tserver" ).c_str(); _server.Init( strServer.c_str() ); KFileManager::Instance().AddResourceSource( &_server ); } if( ENV().IsExist( "chat_mode" ) ) { static KRealFileSystem _chat; std::string strChatMode = ENV().GetString( "chat_mode" ).c_str(); _chat.Init( strChatMode.c_str() ); KFileManager::Instance().AddResourceSource( &_chat ); } struct _NEW_CIPHER : KFileSystemWrapper::NameCipher { virtual bool is_encoded_file_name( std::string & strFileName ) { return KFileNameCipher::IsEncodedName( strFileName ); }; virtual void encode_file_name( std::string & strFileName ) { KFileNameCipher::EncodeFileName( strFileName ); }; virtual void decode_file_name( std::string & strFileName ) { KFileNameCipher::DecodeFileName( strFileName ); }; }; static _NEW_CIPHER _new_cipher; if( !ENV().IsExist( "notenc" ) ) { static KRealFileSystem _encodedMainRes; static KFileSystemWrapper _newEncodedFS; _encodedMainRes.Init( ENV().GetString( "res", "./Resource/" ).c_str() ); _newEncodedFS.Init( &_encodedMainRes, &_new_cipher, false ); KFileManager::Instance().AddResourceSource( &_newEncodedFS ); } // { 신버젼 패킹 파일 if( bExistNewPackingFile1 ) { static KPackingFileSystem _newPacking( 8, 3, true ); static KFileSystemWrapper _packedEncodedFS; _newPacking.Init( "data.000", "data" ); _packedEncodedFS.Init( &_newPacking, &_new_cipher, true, true ); KFileManager::Instance().AddResourceSource( &_packedEncodedFS ); } if(GameRule::GetCurrentLocalBitSet() == GameRule::LOCAL_BITSET::JP) { g_Help_url.x = 900; g_Help_url.y = 700; } else if(GameRule::GetCurrentLocalBitSet() == GameRule::LOCAL_BITSET::CN) { g_Help_url.x = 620; g_Help_url.y = 633; } else { g_Help_url.x = 900; g_Help_url.y = 670; } if(GameRule::GetCurrentLocalBitSet() == GameRule::LOCAL_BITSET::KR) { g_Cash_url.x = 710; g_Cash_url.y = 654; g_Cash_add_url.x = 44; g_Cash_add_url.y = 0; } else if(GameRule::GetCurrentLocalBitSet() == GameRule::LOCAL_BITSET::CN) { g_Cash_url.x = 620; g_Cash_url.y = 634; g_Cash_add_url.x = 44; g_Cash_add_url.y = 0; } else if(GameRule::GetCurrentLocalBitSet() == GameRule::LOCAL_BITSET::JP) { g_Cash_url.x = 900; g_Cash_url.y = 700; g_Cash_add_url.x = 44; g_Cash_add_url.y = 0; } else { g_Cash_url.x = 620; g_Cash_url.y = 634; g_Cash_add_url.x = 0; g_Cash_add_url.y = 0; } if( ENV().IsExist( "help_url_w" ) ) g_Help_url.x = ENV().GetInt( "help_url_w", g_Help_url.x ); if( ENV().IsExist( "help_url_h" ) ) g_Help_url.y = ENV().GetInt( "help_url_h", g_Help_url.y ); if( ENV().IsExist( "cash_url_w" ) ) g_Cash_url.x = ENV().GetInt( "cash_url_w", g_Cash_url.x ); if( ENV().IsExist( "cash_url_h" ) ) g_Cash_url.y = ENV().GetInt( "cash_url_h", g_Cash_url.y ); if( ENV().IsExist( "cash_add_url_w" ) ) g_Cash_add_url.x = ENV().GetInt( "cash_add_url_w", g_Cash_add_url.x ); if( ENV().IsExist( "cash_add_url_h" ) ) g_Cash_add_url.y = ENV().GetInt( "cash_add_url_h", g_Cash_add_url.y ); // Preload some RDBs ::GetStringDB(); ::GetSkillDB(); ::GetSkillStageDB(); ::GetSkillTreeDisplayDB(); ::GetCharacterMotionEventDB(); ::GetMotionEventHanderDB(); ::GetMotionFxSetDB(); ::GetMotionSetDB(); ::GetTenacityDB(); ::GetLocalCommandDB(); // 2010.05.07 - prodongi ::GetCreatureEnhanceDB(); ::GetTitleDB(); #ifdef _EDIT_ENVIRONMENT_ ::GetEditParameterDialog(); #endif KSpriteManager::GetManager()->LoadSpriteSet("ui_frame.spr"); //KStream *pTp = KFileManager::Instance().CreateStreamFromResource( "m001_003.nfs" ); //KFileStream tmp( "temp.tmp", KFileStream::wronly ); //char buf[65535]; //pTp->Read( buf, pTp->GetLength() ); //tmp.Write( buf, pTp->GetLength() ); // UI caption handler static struct myUICaptionHandler : public KUIWnd::CaptionHandler { virtual void onSetCaption( std::string & caption ) { if( caption.empty() ) return; caption = GetStringDB().GetString( caption.c_str() ); std::vector< std::string > vList; while( nsl::regex::match( "#@([0-9]+)@#", caption.c_str(), &vList ) ) { nsl::replace( &caption, vList[0].c_str(), GetStringDB().GetString(atoi(vList[1].c_str() ) ) ); vList.clear(); } } } _handler; KUIWnd::SetCaptionHandler( &_handler ); return true; } #include volatile int m_nDummyInt = 0; // For now, only handle two const short c_nFontTagCnt = 68; const char* g_szFontTag[] = { "" ,//01 "<#" ,//02 "
" ,//03 "

" ,//04 "<$L>" ,//05 "<$>" ,//06 "" ,//07 "" ,//08 "" ,//09 "" ,//10 "" ,//11 "",//12 "" ,//13 "" ,//14 "" ,//15 "" ,//16 "<%%>" ,//17 "<%>" ,//18 "" ,//19 "" ,//20 "" ,//21 "" ,//22 "" ,//23 "",//24 "",//25 "" ,//26 "" ,//27 "" ,//28 "" ,//29 "" ,//30 "",//31 "<@>" ,//32 "<2XGLOW>" ,//33 "",//34 "" ,//35 "" ,//36 "" ,//37 "

" ,//38 "<$l>" ,//39 "<$>" ,//40 "" ,//41 "" ,//42 "" ,//43 "" ,//44 "" ,//45 "",//46 "" ,//47 "" ,//48 "" ,//49 "" ,//50 "" ,//51 "" ,//52 "" ,//53 "" ,//54 "",//55 "",//56 "" ,//57 "" ,//58 "" ,//59 "" ,//60 "" ,//61 "",//62 "<2xglow>" ,//63 "",//64 "" ,//65 "
" ,//66 "
" ,//67 "
" ,//68 }; const short c_nEmoticonCnt = 228; const char* g_szAniName[] = { // 2010.10.04 - prodongi /* "static_common_rank00", "static_common_rank01", "static_common_rank02", "static_common_rank03", "static_common_rank04", "static_common_rank05", //아이템 랭크 "static_common_rank06", // #2.1.13 */ "common_mark_rank_player01", "common_mark_rank_player02", "common_mark_rank_player03", "common_mark_rank_player04", "common_mark_rank_player05", "common_mark_rank_player06", //아이템 랭크 "common_mark_rank_player07", // #2.1.13 "static_common_setitem00_able", // #2.1.2.6.1 "static_common_setitem00_disable", "static_common_setitem01_able", "static_common_setitem01_disable", "static_common_setitem02_able", "static_common_setitem02_disable", "static_common_setitem_plus", "static_creature_star00", "static_creature_star01", "static_creature_star02",//크리쳐 별 // 2010.08.26 - prodongi /* "static_creature_rank00", "static_creature_rank01", "static_creature_rank02", "static_creature_rank03", "static_creature_rank04", "static_creature_rank05",//크리쳐 랭크 */ // 2010.10.04 - prodongi /* "game_creature_mark_rank00", "game_creature_mark_rank01", "game_creature_mark_rank02", "game_creature_mark_rank03", "game_creature_mark_rank04", "game_creature_mark_rank05",//크리쳐 랭크 */ "game_creature_mark_rank01", "game_creature_mark_rank02", "game_creature_mark_rank03", "game_creature_mark_rank04", "game_creature_mark_rank05", "game_creature_mark_rank06",//크리쳐 랭크 //AziaMAfia Pet Rarity "game_creature_mark_rank07", "game_creature_mark_rank08", "game_creature_mark_rank09", "game_creature_mark_rank10", "game_creature_mark_rank11", "static_tooltip_symbolnormal", //nomal "static_tooltip_symbolfire", //fire "static_tooltip_symbolwind", //wind "static_tooltip_symbollightness", //light "static_tooltip_symbolwater", //water "static_tooltip_symbolearth", //earth "static_tooltip_symboldarkness", //dark "icon_soulstone_agi_basic1_s", "icon_soulstone_agi_basic2_s", "icon_soulstone_agi_basic3_s", "icon_soulstone_agi_basic4_s", "icon_soulstone_agi_basic5_s", "icon_soulstone_agi_basic6_s", "icon_soulstone_agi_basic7_s", "icon_soulstone_dex_basic1_s", "icon_soulstone_dex_basic2_s", "icon_soulstone_dex_basic3_s", "icon_soulstone_dex_basic4_s", "icon_soulstone_dex_basic5_s", "icon_soulstone_dex_basic6_s", "icon_soulstone_dex_basic7_s", "icon_soulstone_int_basic1_s", "icon_soulstone_int_basic2_s", "icon_soulstone_int_basic3_s", "icon_soulstone_int_basic4_s", "icon_soulstone_int_basic5_s", "icon_soulstone_int_basic6_s", "icon_soulstone_int_basic7_s", "icon_soulstone_men_basic1_s", "icon_soulstone_men_basic2_s", "icon_soulstone_men_basic3_s", "icon_soulstone_men_basic4_s", "icon_soulstone_men_basic5_s", "icon_soulstone_men_basic6_s", "icon_soulstone_men_basic7_s", "icon_soulstone_str_basic1_s", "icon_soulstone_str_basic2_s", "icon_soulstone_str_basic3_s", "icon_soulstone_str_basic4_s", "icon_soulstone_str_basic5_s", "icon_soulstone_str_basic6_s", "icon_soulstone_str_basic7_s", "icon_soulstone_vit_basic1_s", "icon_soulstone_vit_basic2_s", "icon_soulstone_vit_basic3_s", "icon_soulstone_vit_basic4_s", "icon_soulstone_vit_basic5_s", "icon_soulstone_vit_basic6_s", "icon_soulstone_vit_basic7_s", "icon_soulstone_str_rare1_s", "icon_soulstone_str_rare2_s", "icon_soulstone_str_rare3_s", "icon_soulstone_str_rare4_s", "icon_soulstone_str_rare5_s", "icon_soulstone_str_rare6_s", "icon_soulstone_str_rare7_s", "icon_soulstone_str_epic1_s", "icon_soulstone_str_epic2_s", "icon_soulstone_str_epic3_s", "icon_soulstone_str_epic4_s", "icon_soulstone_str_epic5_s", "icon_soulstone_str_epic6_s", "icon_soulstone_str_epic7_s", "icon_soulstone_vit_rare1_s", "icon_soulstone_vit_rare2_s", "icon_soulstone_vit_rare3_s", "icon_soulstone_vit_rare4_s", "icon_soulstone_vit_rare5_s", "icon_soulstone_vit_rare6_s", "icon_soulstone_vit_rare7_s", "icon_soulstone_vit_epic1_s", "icon_soulstone_vit_epic2_s", "icon_soulstone_vit_epic3_s", "icon_soulstone_vit_epic4_s", "icon_soulstone_vit_epic5_s", "icon_soulstone_vit_epic6_s", "icon_soulstone_vit_epic7_s", "icon_soulstone_dex_rare1_s", "icon_soulstone_dex_rare2_s", "icon_soulstone_dex_rare3_s", "icon_soulstone_dex_rare4_s", "icon_soulstone_dex_rare5_s", "icon_soulstone_dex_rare6_s", "icon_soulstone_dex_rare7_s", "icon_soulstone_dex_epic1_s", "icon_soulstone_dex_epic2_s", "icon_soulstone_dex_epic3_s", "icon_soulstone_dex_epic4_s", "icon_soulstone_dex_epic5_s", "icon_soulstone_dex_epic6_s", "icon_soulstone_dex_epic7_s", "icon_soulstone_agi_rare1_s", "icon_soulstone_agi_rare2_s", "icon_soulstone_agi_rare3_s", "icon_soulstone_agi_rare4_s", "icon_soulstone_agi_rare5_s", "icon_soulstone_agi_rare6_s", "icon_soulstone_agi_rare7_s", "icon_soulstone_agi_epic1_s", "icon_soulstone_agi_epic2_s", "icon_soulstone_agi_epic3_s", "icon_soulstone_agi_epic4_s", "icon_soulstone_agi_epic5_s", "icon_soulstone_agi_epic6_s", "icon_soulstone_agi_epic7_s", "icon_soulstone_int_rare1_s", "icon_soulstone_int_rare2_s", "icon_soulstone_int_rare3_s", "icon_soulstone_int_rare4_s", "icon_soulstone_int_rare5_s", "icon_soulstone_int_rare6_s", "icon_soulstone_int_rare7_s", "icon_soulstone_int_epic1_s", "icon_soulstone_int_epic2_s", "icon_soulstone_int_epic3_s", "icon_soulstone_int_epic4_s", "icon_soulstone_int_epic5_s", "icon_soulstone_int_epic6_s", "icon_soulstone_int_epic7_s", "icon_soulstone_men_rare1_s", "icon_soulstone_men_rare2_s", "icon_soulstone_men_rare3_s", "icon_soulstone_men_rare4_s", "icon_soulstone_men_rare5_s", "icon_soulstone_men_rare6_s", "icon_soulstone_men_rare7_s", "icon_soulstone_men_epic1_s", "icon_soulstone_men_epic2_s", "icon_soulstone_men_epic3_s", "icon_soulstone_men_epic4_s", "icon_soulstone_men_epic5_s", "icon_soulstone_men_epic6_s", "icon_soulstone_men_epic7_s", /// 2011.12.06 - prodongi "icon_soulstone_agi_unique7_s", "icon_soulstone_chaser_unique7_s", "icon_soulstone_commerce_agi_unique7_s", "icon_soulstone_commerce_chaser_unique7_s", "icon_soulstone_commerce_dex_unique7_s", "icon_soulstone_commerce_edge_unique7_s", "icon_soulstone_commerce_energy_unique7_s", "icon_soulstone_commerce_hunter_unique7_s", "icon_soulstone_commerce_int_unique7_s", "icon_soulstone_commerce_magical_unique7_s", "icon_soulstone_commerce_men_unique7_s", "icon_soulstone_commerce_pen_unique7_s", "icon_soulstone_commerce_perfect_unique7_s", "icon_soulstone_commerce_save_unique7_s", "icon_soulstone_commerce_str_unique7_s", "icon_soulstone_commerce_vit_unique7_s", "icon_soulstone_dex_unique7_s", "icon_soulstone_edge_unique7_s", "icon_soulstone_energy_unique7_s", "icon_soulstone_hunter_unique7_s", "icon_soulstone_int_unique7_s", "icon_soulstone_magical_unique7_s", "icon_soulstone_men_unique7_s", "icon_soulstone_pen_unique7_s", "icon_soulstone_perfect_unique7_s", "icon_soulstone_save_unique7_s", "icon_soulstone_str_unique7_s", "icon_soulstone_vit_unique7_s", /// 2019.06.21 - G4ngor "icon_soulstone_commerce_agi_unique8_s", "icon_soulstone_commerce_chaser_unique8_s", "icon_soulstone_commerce_dex_unique8_s", "icon_soulstone_commerce_edge_unique8_s", "icon_soulstone_commerce_energy_unique8_s", "icon_soulstone_commerce_hunter_unique8_s", "icon_soulstone_commerce_int_unique8_s", "icon_soulstone_commerce_magical_unique8_s", "icon_soulstone_commerce_men_unique8_s", "icon_soulstone_commerce_pen_unique8_s", "icon_soulstone_commerce_perfect_unique8_s", "icon_soulstone_commerce_save_unique8_s", "icon_soulstone_commerce_str_unique8_s", "icon_soulstone_commerce_vit_unique8_s", "static_common_socket_itemslot", "icon_effectstone_fire_tooltip", "icon_effectstone_wind_tooltip", "icon_effectstone_light_tooltip", "icon_effectstone_water_tooltip", "icon_effectstone_earth_tooltip", "icon_effectstone_dark_tooltip", "icon_item_flystone_fire2_tooltip", "icon_item_flystone_wind2_tooltip", "icon_item_flystone_light2_tooltip", "icon_item_flystone_water2_tooltip", "icon_item_flystone_earth2_tooltip", "icon_item_flystone_dark2_tooltip", "common_mark_titanium_guild_notice", "common_mark_titanium_guild_memo", /// 2011.09.28 퀘스트 난이도 - prodongi "common_mark_quest_difficulty_easy", "common_mark_quest_difficulty_nomal", "common_mark_quest_difficulty_hard", "icon_soulstone8_normal_orange_s", "icon_soulstone8_normal_purple_s", "icon_soulstone8_normal_blue_s", "icon_soulstone8_normal_sky_s", "icon_soulstone8_normal_red_s", "icon_soulstone8_normal_yellow_s", "icon_soulstone8_normal_green_s", }; // 나중에.. 디비에 넣거나, 테이블을 구성해야 한다. // ex // field : emoticon_id, emoticon_type, emoticon_filter, emoticon_flag(고정크기,원본크기등), emoticon_ani, emoticon_spr const char* g_szEmoticonFilter[] = { "#@1R@#", "#@2R@#", "#@3R@#", "#@4R@#", "#@5R@#", "#@6R@#", "#@7R@#", // #2.1.13 "#@SETPART_ARMO_ON@#", // #2.1.2.6.1 "#@SETPART_ARMO_OFF@#", "#@SETPART_HAND_ON@#", "#@SETPART_HAND_OFF@#", "#@SETPART_HELM_ON@#", "#@SETPART_HELM_OFF@#", "#@SETPART_PLUS@#", "#@1S@#", "#@2S@#", "#@3S@#", "#@C1R@#", "#@C2R@#", "#@C3R@#", "#@C4R@#", "#@C5R@#", "#@C6R@#", //AziaMAfia Pet Rarity "#@C7R@#", "#@C8R@#", "#@C9R@#", "#@C10R@#", "#@C11R@#", "#@NOMAL@#", "#@FIRE@#", "#@WIND@#", "#@LIGHT@#", "#@WATER@#", "#@EARTH@#", "#@DARK@#", "#@agi_basic1@#", "#@agi_basic2@#", "#@agi_basic3@#", "#@agi_basic4@#", "#@agi_basic5@#", "#@agi_basic6@#", "#@agi_basic7@#", "#@dex_basic1@#", "#@dex_basic2@#", "#@dex_basic3@#", "#@dex_basic4@#", "#@dex_basic5@#", "#@dex_basic6@#", "#@dex_basic7@#", "#@int_basic1@#", "#@int_basic2@#", "#@int_basic3@#", "#@int_basic4@#", "#@int_basic5@#", "#@int_basic6@#", "#@int_basic7@#", "#@men_basic1@#", "#@men_basic2@#", "#@men_basic3@#", "#@men_basic4@#", "#@men_basic5@#", "#@men_basic6@#", "#@men_basic7@#", "#@str_basic1@#", "#@str_basic2@#", "#@str_basic3@#", "#@str_basic4@#", "#@str_basic5@#", "#@str_basic6@#", "#@str_basic7@#", "#@vit_basic1@#", "#@vit_basic2@#", "#@vit_basic3@#", "#@vit_basic4@#", "#@vit_basic5@#", "#@vit_basic6@#", "#@vit_basic7@#", "#@str_rare1@#", "#@str_rare2@#", "#@str_rare3@#", "#@str_rare4@#", "#@str_rare5@#", "#@str_rare6@#", "#@str_rare7@#", "#@str_epic1@#", "#@str_epic2@#", "#@str_epic3@#", "#@str_epic4@#", "#@str_epic5@#", "#@str_epic6@#", "#@str_epic7@#", "#@vit_rare1@#", "#@vit_rare2@#", "#@vit_rare3@#", "#@vit_rare4@#", "#@vit_rare5@#", "#@vit_rare6@#", "#@vit_rare7@#", "#@vit_epic1@#", "#@vit_epic2@#", "#@vit_epic3@#", "#@vit_epic4@#", "#@vit_epic5@#", "#@vit_epic6@#", "#@vit_epic7@#", "#@dex_rare1@#", "#@dex_rare2@#", "#@dex_rare3@#", "#@dex_rare4@#", "#@dex_rare5@#", "#@dex_rare6@#", "#@dex_rare7@#", "#@dex_epic1@#", "#@dex_epic2@#", "#@dex_epic3@#", "#@dex_epic4@#", "#@dex_epic5@#", "#@dex_epic6@#", "#@dex_epic7@#", "#@agi_rare1@#", "#@agi_rare2@#", "#@agi_rare3@#", "#@agi_rare4@#", "#@agi_rare5@#", "#@agi_rare6@#", "#@agi_rare7@#", "#@agi_epic1@#", "#@agi_epic2@#", "#@agi_epic3@#", "#@agi_epic4@#", "#@agi_epic5@#", "#@agi_epic6@#", "#@agi_epic7@#", "#@int_rare1@#", "#@int_rare2@#", "#@int_rare3@#", "#@int_rare4@#", "#@int_rare5@#", "#@int_rare6@#", "#@int_rare7@#", "#@int_epic1@#", "#@int_epic2@#", "#@int_epic3@#", "#@int_epic4@#", "#@int_epic5@#", "#@int_epic6@#", "#@int_epic7@#", "#@men_rare1@#", "#@men_rare2@#", "#@men_rare3@#", "#@men_rare4@#", "#@men_rare5@#", "#@men_rare6@#", "#@men_rare7@#", "#@men_epic1@#", "#@men_epic2@#", "#@men_epic3@#", "#@men_epic4@#", "#@men_epic5@#", "#@men_epic6@#", "#@men_epic7@#", /// 2011.12.06 - prodongi "#@agi_unique7@#", "#@chaser_unique7@#", "#@commerce_agi_unique7@#", "#@commerce_chaser_unique7@#", "#@commerce_dex_unique7@#", "#@commerce_edge_unique7@#", "#@commerce_energy_unique7@#", "#@commerce_hunter_unique7@#", "#@commerce_int_unique7@#", "#@commerce_magical_unique7@#", "#@commerce_men_unique7@#", "#@commerce_pen_unique7@#", "#@commerce_perfect_unique7@#", "#@commerce_save_unique7@#", "#@commerce_str_unique7@#", "#@commerce_vit_unique7@#", "#@dex_unique7@#", "#@edge_unique7@#", "#@energy_unique7@#", "#@hunter_unique7@#", "#@int_unique7@#", "#@magical_unique7@#", "#@men_unique7@#", "#@pen_unique7@#", "#@perfect_unique7@#", "#@save_unique7@#", "#@str_unique7@#", "#@vit_unique7@#", /// Alucard "#@commerce_agi_unique8@#", "#@commerce_chaser_unique8@#", "#@commerce_dex_unique8@#", "#@commerce_edge_unique8@#", "#@commerce_energy_unique8@#", "#@commerce_hunter_unique8@#", "#@commerce_int_unique8@#", "#@commerce_magical_unique8@#", "#@commerce_men_unique8@#", "#@commerce_pen_unique8@#", "#@commerce_perfect_unique8@#", "#@commerce_save_unique8@#", "#@commerce_str_unique8@#", "#@commerce_vit_unique8@#", "#@socket_empty@#", "#@fx_fire@#", "#@fx_wind@#", "#@fx_light@#", "#@fx_water@#", "#@fx_earth@#", "#@fx_dark@#", "#@fx_fire2@#", "#@fx_wind2@#", "#@fx_light2@#", "#@fx_water2@#", "#@fx_earth2@#", "#@fx_dark2@#", "#@guild_notice@#", "#@guild_memo@#", "#@quest_easy@#", "#@quest_normal@#", "#@quest_hard@#", "#@_normal_orange@#", "#@_normal_purple@#", "#@_normal_blue@#", "#@_normal_sky@#", "#@_normal_red@#", "#@_normal_yellow@#", "#@_normal_green@#", NULL }; #ifdef _USE_XTRAP_MODULE void XTrapThread(void* pArg) { int delay = 20000; // 20초 for (;;) { Sleep(delay); XTrap_C_CallbackAlive(delay); } } #endif /// 2010.11.11 - prodongi void _getModulePath(); bool _isValidDxVersion(); void _setDebugFlag(); bool _isValidResolution(); void _setTitle(); void _parsingLocaleInfo(); void _initEmoticonList(); void _setEditBoxFontTag(); void _initGuildIcon(); void _initCom(); void _initAtlModule(CComModule& _Module); void _initBotManager(HWND hWnd, HINSTANCE hInstance); void _initBotManagerUIScript(); void _mainLoop(MSG& msg); void _saveLogStringRate(); void _clearWebBrowser(); void _clearMain(HANDLE& hMutex, CComModule* _Module); void _deleteSGObj(); //gmpbigsun( 20130726 ) : static 변수를 없애서 leak을 잡자. #ifdef _HACK_SHIELD_ void _startHackShieldService(); #endif bool _startNProtectService(); bool _checkDoubleExecute(HANDLE& hMutex); #ifndef _COUNTRY_ME_ bool _setLocaleFontInfo(); #endif #ifdef _DEBUG void _saveMemAllocCount(); #endif enum { VALID_PARENT_SUCCESS = 0, VALID_PARENT_GETPATH_FAILED = 1<<1, VALID_PARENT_PARENT_SIGNER_FAILED = 1<<2, VALID_PARENT_MY_SIGNER_FAILED = 1<<3, VALID_PARENT_ENVIRONMENT_VALUE_FAILED = 1<<4, VALID_PARENT_WAIT_HANDLE_VALUE_FAILED = 1<<5, VALID_PARENT_SETEVENT_FAILED = 1<<6, VALID_PARENT_CLOSEHANDLE_FAILED = 1<<7, }; DWORD ValidParentProcess( std::wstring* msg, SYSTEMTIME* my_timestamp ) { DWORD dwResultMask = 0; std::string strMyProcessName = XProcess::GetProcessFileName( ::GetCurrentProcess() ); XStringUtil::ToLower( strMyProcessName ); // 디지털 서명 확인 bool bCheckSigner = (ENV().GetInt( "check_digital_signer", 0 ) != 0); if( bCheckSigner == true ) { std::wstring strParentProcess = XProcess::GetParentProcessFullPath(); if( strParentProcess.empty() == true ) { std::string strParent = strMyProcessName + "_PARENT"; char szPath[MAX_PATH] = { 0, }; if( ::GetEnvironmentVariable( strParent.c_str(), szPath, _countof( szPath ) ) > 0 ) { wchar_t szWPath[MAX_PATH] = { 0, }; //AziaMafia Fix CODEPAGE CP_UTF8 //::MultiByteToWideChar( ::GetACP(), 0, szPath, -1, szWPath, _countof( szWPath ) ); ::MultiByteToWideChar(::GetACP(), 0, szPath, -1, szWPath, _countof( szWPath ) ); strParentProcess = szWPath; } } if( strParentProcess.empty() == true ) { dwResultMask |= VALID_PARENT_GETPATH_FAILED; } BYTE bySerialNumber[16] = { 0x0d, 0xf9, 0xee, 0x3c, 0xfb, 0xc6, 0xd8, 0xde, 0xe0, 0x77, 0x7f, 0x92, 0x63, 0xce, 0x06, 0xdf }; if( XVerifyProcessSigner( strParentProcess, L"Gala Lab Corp.", bySerialNumber, sizeof( bySerialNumber ), NULL, msg ) == false ) { dwResultMask |= VALID_PARENT_PARENT_SIGNER_FAILED; } wchar_t szMyPath[MAX_PATH] = { 0, }; //AziaMafia Fix CODEPAGE CP_UTF8 //::MultiByteToWideChar( ::GetACP(), 0, strMyProcessName.c_str(), -1, szMyPath, _countof( szMyPath ) ); ::MultiByteToWideChar(::GetACP(), 0, strMyProcessName.c_str(), -1, szMyPath, _countof( szMyPath ) ); std::wstring strMyProcessTemp = szMyPath; if( XVerifyProcessSigner( strMyProcessTemp, L"Gala Lab Corp.", bySerialNumber, sizeof( bySerialNumber ), my_timestamp, msg ) == false ) { dwResultMask |= VALID_PARENT_MY_SIGNER_FAILED; } } std::string strRunWaitHandle = strMyProcessName + "_RUNNER"; char szWaitHandle[64] = { 0, }; if( ::GetEnvironmentVariable( strRunWaitHandle.c_str(), szWaitHandle, _countof( szWaitHandle ) ) <= 0 ) { dwResultMask |= VALID_PARENT_ENVIRONMENT_VALUE_FAILED; } HANDLE hRunWait = reinterpret_cast< HANDLE >( _atoi64( szWaitHandle ) ); if( hRunWait == NULL ) { dwResultMask |= VALID_PARENT_WAIT_HANDLE_VALUE_FAILED; } if( ::SetEvent( hRunWait ) == FALSE ) { dwResultMask |= VALID_PARENT_SETEVENT_FAILED; } if( ::CloseHandle( hRunWait ) == FALSE ) { dwResultMask |= VALID_PARENT_CLOSEHANDLE_FAILED; } return dwResultMask; } ////////////////////////////////////////////////////////////////////////// //Main int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { g_pNpgl = NULL; std::wstring valild_msg; SYSTEMTIME timestamp; DWORD dwIsValidParent = ValidParentProcess( &valild_msg, ×tamp ); DWORD dwValidParentLastError = ::GetLastError(); #ifdef _USE_XTRAP_MODULE char XTrapKey[] = "660970B4CA79D814E13D6D9844CFE862A476DA4508687AF092D5D482BB89FDCFEACF088691D3EBC25799F4E785CF821D1F8847AE46380D24DE516E28FC67A34D0F7D04245246E41FB1670C4E95407619E96980387320B6505436FCED87B1E5752B95727C"; // XTrap_L_Patch(XTrapKey, 0, 60); XTrap_C_Start(XTrapKey, NULL); #endif _getModulePath(); /// 2010.11.11 - prodongi GetLog().LogStart(); ENV().ParseCmdLine(); #ifdef _COUNTRY_ME_ SGameOperationManager* pGameOperationManager = new SGameOperationManager; #endif if( InitResource() == false ) { // Game exit MessageBox( g_hWnd, "Not Found Resource\nGame Exit!!!", "Rappelz-Error", MB_OK|MB_ICONERROR ); SLOG("Not Found Resource!"); GetLog().OutputFile(LOGFILE_NAME); return 0; } #ifdef _HACK_SHIELD_ _startHackShieldService(); /// 2010.11.11 - prodongi #endif bool bNProtectAble = (ENV().GetInt( "use_nprotect", 1 ) != 0); #ifdef FRAUN_NO_GG // Fraun 7/11/2025 disabling GameGuard bNProtectAble = false; #endif #ifdef _DEV bNProtectAble = false; #endif if( bNProtectAble == true && _startNProtectService() == false ) { return 0; } // 2010.05.04 - prodongi bool applySplash = true; cSplashLoading splashLoading(applySplash); if (applySplash) nCmdShow = SW_HIDE; splashLoading.begin(hInstance); // Execute Check /// 2010.11.11 - prodongi HANDLE hMutex = NULL; bool bAllowDoubleExecute = (ENV().GetInt( "allow_double_exec", 0 ) != 0); #ifdef _DEV bAllowDoubleExecute = true; #endif if( bAllowDoubleExecute == false && _checkDoubleExecute(hMutex) == false ) { return 0; } //_CrtSetBreakAlloc(1880332); strcpy(BuildDate, __DATE__); strcpy(BuildTime, __TIME__); /// 2010.11.11 - prodongi if (!_isValidDxVersion()) { return 0; } #ifndef DISABLE_DEBUGGER_DETECTOR if( IsDebuggerPresent() ) { m_nDummyInt = 1; MessageBox( NULL, "Debugger detected!!\nplease disable it and restart the application.", "ERROR", MB_ICONWARNING| MB_OK ); SLOG("Debugger Detected!"); GetLog().OutputFile(LOGFILE_NAME); return 0; } #endif GetGameOption(); MSG msg; HACCEL hAccelTable; memset( &msg, 0, sizeof(msg) ); #ifdef _EXCEPTION_PROCESS #ifdef _DEV StartExceptionHandler( "SFrame" ); #else StartExceptionHandler( "SFrame", false ); #endif SetUserFunc( UserFunc ); #endif #ifdef _DEBUG _setDebugFlag(); /// 2010.11.12 - prodongi #endif //gmpbigsun( 20130311 ) : for autobuild if( true == ENV().IsExist( "ImmTerminate" ) ) return 0; #ifdef _DEV bool bCheckSigner = (ENV().GetInt( "check_digital_signer", 0 ) != 0); if( bCheckSigner == false ) { dwIsValidParent = VALID_PARENT_SUCCESS; } #endif if( CheckAuthServerIP( ENV().GetString( "auth_ip", "" ) ) == false ) { MessageBox( g_hWnd, "Invalid Server IP.\nGame Exit!!!", "Rappelz-Error", MB_OK|MB_ICONERROR ); return 0; } if (!_isValidResolution()) { MessageBox(g_hWnd, "Invalid resolution", "Rappelz - Error", MB_OK | MB_ICONERROR); return 0; } _setTitle(); /// 2010.11.11 - prodongi #ifdef _COMPANY strcat( szTitle, " Release Company" ); #endif #ifdef _DEV strcat( szTitle, " Dev" ); #endif // Initialize Thai word breaker #ifdef _COUNTRY_TL_ LocalizationTL::g_TEWordBreak.LoadDic(); LocalizationTL::g_TEWordBreak.wcut = ""; #endif LoadString(hInstance, IDC_SFRAME, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // Perform application initialization HWND hWnd = InitInstance( hInstance, nCmdShow ); if( !hWnd ) { SLOG("Program initialize error!"); GetLog().OutputFile(LOGFILE_NAME); return 0; } g_hInstance = hInstance; g_hWnd = hWnd; // [sonador][1.5.1] Keyboard input improvements #ifdef _USE_KEYBOARD_HOOK g_hKeyBoardHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC) KeyboardProc, NULL, GetCurrentThreadId()); #endif #ifdef _EDIT_ENVIRONMENT_ // Initialize dialog parameters for editing environment parameters GetEditParameterDialog().SetParam(g_hInstance, g_hWnd); #endif initKeyboardHook(); // 2010.06.17 - prodongi CheckOSVersion(); _parsingLocaleInfo(); /// 2010.11.11 - prodongi #ifndef _COUNTRY_ME_ // sonador #2.4.10.2 if (!_setLocaleFontInfo()) { return 0; } #endif _initEmoticonList(); /// 2010.11.11 - prodongi _setEditBoxFontTag(); /// 2010.11.11 - prodongi CEditBoxInfo::SetUseClipException( true ); #define BUFSIZE MAX_PATH _initGuildIcon(); #define _EXPLORER_ #ifdef _EXPLORER_ _initCom(); /// 2010.11.11 - prodongi CComModule _Module; _initAtlModule(_Module); #endif #ifdef CLOUD_LUA CreateCloudDB(); #endif _initBotManager(hWnd, hInstance); /// 2010.11.12 - prodongi InitScript(); _initBotManagerUIScript(); /// 2010.11.12 - prodongi hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_SFRAME); // 윈도우 핸들이 생성된 후, 그리고 모든 그래픽, UI 관련 초기화가 끝난 후 SetHwnd() 호출 if( g_pNpgl != NULL ) { g_pNpgl->SetHwnd( g_hWnd ); } #ifdef _USE_XTRAP_MODULE XTrap_C_KeepAlive(); _beginthread(XTrapThread, 0, NULL); #endif splashLoading.end(g_hWnd); // 2010.05.04 - prodongi /// 2010.11.11 - prodongi _mainLoop(msg); SLOG("Game Main-loop Finished"); #ifdef CLOUD_LUA DestroyCloudDB(); #endif _clearMain(hMutex, &_Module); _deleteSGObj(); return (int) msg.wParam; } // // Function: MyRegisterClass() // // Purpose: Registers a window class. // // Description: // // Use this function only if you need compatibility with the Win32 system // before the 'RegisterClassEx' function, which was added in Windows 95. // You must call this function to get the 'correct format' small icon // associated with the application. // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(wcex); wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_SFRAME); wcex.hCursor = NULL;//LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wcex.lpszMenuName = 0; wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); return RegisterClassEx(&wcex); } // // 함수: InitInstance(HANDLE, int) // // 목적: 인스턴스 핸들을 저장하고 주 창을 만듭니다. // // 설명: // // 이 함수를 통해 인스턴스 핸들을 전역 변수에 저장하고 // 주 프로그램 창을 만든 다음 표시합니다. // HWND InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; DWORD dwStyle = 0; //전체 모드일때, 캡션 보더 사용안함. if( ENV().IsExist( "full" ) ) { // TODO : 우선 1024 해상도로 맞춰둔다 옵션 적용되면 삭제 dwStyle = WS_POPUPWINDOW; } else { if( ENV().IsExist( "win" ) ) { // TODO : 우선 1024 해상도로 맞춰둔다 옵션 적용되면 삭제 #ifdef _DEV if( GetGameOption().GetFullWindowMode() ) // 전체 창 모드라면 { dwStyle = WS_POPUPWINDOW; //전체 창 모드 } else #endif { dwStyle = WS_OVERLAPPEDWINDOW; //윈도우 모드 } } else { if( GetGameOption().GetWinMode() == 1 ) { int sx = GetSystemMetrics(SM_CXSCREEN); int sy = GetSystemMetrics(SM_CYSCREEN); if( sx == 1024 && sy == 768 ) { dwStyle = WS_POPUPWINDOW; //1024x768 예외처리 dwStyle &= ~WS_SYSMENU; } else { dwStyle = WS_OVERLAPPEDWINDOW; //윈도우 모드 dwStyle |= WS_SYSMENU; dwStyle |= WS_MINIMIZEBOX; } } else { dwStyle = WS_POPUPWINDOW; //전체모드 dwStyle &= ~WS_SYSMENU; } } } dwStyle &= ~WS_THICKFRAME; dwStyle &= ~WS_MAXIMIZEBOX; //Explorer dwStyle |= WS_CLIPCHILDREN; dwStyle |= WS_CLIPSIBLINGS; RECT rect; rect.left = rect.top = 0; rect.right = RES_1024; rect.bottom = RES_768; // rect.right = RES_1280;//RES_1024; // rect.bottom = RES_1024;//RES_768; #ifdef _WEB_DISP_MODE CheckDisplay(); #endif GetCommandBuilder(); rect.right = GetGameOption().GetResolution_Width(); rect.bottom = GetGameOption().GetResolution_Height(); KUIWndManager::SetResolution( KSize(rect.right, rect.bottom) ); AdjustWindowRect( &rect, dwStyle, FALSE ); int nW = rect.right - rect.left; int nH = rect.bottom - rect.top; g_hWnd= hWnd = CreateWindow(szWindowClass, szTitle, dwStyle, CW_USEDEFAULT, 0, nW, nH, NULL, NULL, hInstance, NULL); if( hWnd ) { ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); } // 중문은 윈도 타이틀 다르게.. //홍콩, //대만 if( stricmp( ENV().GetString( "locale" ).c_str(), "BIG5" ) == 0 ) { //KTextRender::SetDefaultCodePage( 950 ); //FreeType에 영향 if( stricmp( ENV().GetString( "country" ).c_str(), "HK" ) == 0 ) { wchar_t szTChnName[] = { 0x795E, 0x9B54, 0x50B3, 0x8AAA, 0 }; ::SetWindowTextW( g_hWnd, szTChnName ); } else if( stricmp( ENV().GetString( "country" ).c_str(), "TW" ) == 0 || stricmp( ENV().GetString( "country" ).c_str(), "MASG" ) == 0 ) { wchar_t szTChnName[] = { 0x81F3, 0x5C0A, 0x4E5D, 0x5C01, 0 }; ::SetWindowTextW( g_hWnd, szTChnName ); } KUIControl::SetBlankWidth( 30 ); KTextParser::SetUseWordWrap( false ); } //태국 if( stricmp( ENV().GetString( "locale" ).c_str(), "CP874" ) == 0 && stricmp( ENV().GetString( "country" ).c_str(), "TL" ) == 0 ) { //KTextRender::SetDefaultCodePage( 874 ); //wchar_t szTChnName[] = { 0x5c01, 0x5370, 0x4f20, 0x8bf4, 0 }; //::SetWindowTextW( g_hWnd, szTChnName ); KUIControl::SetBlankWidth( 30 ); KTextParser::SetUseWordWrap( false ); } //터키 /*if( stricmp( ENV().GetString( "locale" ).c_str(), "CP1254" ) == 0 && stricmp( ENV().GetString( "country" ).c_str(), "TR" ) == 0 ) { KTextRender::SetDefaultCodePage( 1254 ); //wchar_t szTChnName[] = { 0x5c01, 0x5370, 0x4f20, 0x8bf4, 0 }; //::SetWindowTextW( g_hWnd, szTChnName ); KUIControl::SetBlankWidth( 30 ); KTextParser::SetUseWordWrap( false ); }*/ //중국 if( stricmp( ENV().GetString( "locale" ).c_str(), "CP936" ) == 0 && stricmp( ENV().GetString( "country" ).c_str(), "CN" ) == 0 ) { //KTextRender::SetDefaultCodePage( 936 ); wchar_t szTChnName[] = { 0x65B0, 0x5C01, 0x5370, 0x4F20, 0x8BF4, 0 }; ::SetWindowTextW( g_hWnd, szTChnName ); KUIControl::SetBlankWidth( 30 ); KTextParser::SetUseWordWrap( false ); } else if( stricmp( ENV().GetString( "country" ).c_str(), "HK" ) == 0 ) { wchar_t szTChnName[] = { 39764, 31070, 20659, 0 }; ::SetWindowTextW( g_hWnd, szTChnName ); KUIControl::SetBlankWidth( 30 ); KTextParser::SetUseWordWrap( false ); } // sonador 0.2.2 Country-specific local bitset integration and separation of Europe if( stricmp( ENV().GetString( "locale" ).c_str(), "windows-1252" ) == 0 ) { // KTextRender::SetDefaultCodePage( 1252 ); } // sonador #2.1.8 else if( stricmp( ENV().GetString( "locale" ).c_str(), "windows-1251" ) == 0 ) { //KTextRender::SetDefaultCodePage( 1251 ); } // sonador #2.4.10.1 else if( stricmp( ENV().GetString( "locale" ).c_str(), "windows-1256" ) == 0 ) { //KTextRender::SetDefaultCodePage( 1256 ); #ifdef _COUNTRY_ME_ //g_pGameOperationManager->SetDefaultCodePage( 1256 ); #endif } // 2010.09.03 - prodongi else if (stricmp(ENV().GetString("locale").c_str(), "Shift-JIS") == 0 ) { KUIControl::SetBlankWidth( 10 ); } // 2010.09.20 - prodongi if(GameRule::GetCurrentLocalBitSet() == GameRule::LOCAL_BITSET::KR) { KUIControl::SetBlankWidth(5); } if( ENV().IsExist( "alwaysontop" ) ) { // 항상 제일 위에 둔다 SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); } //RECT frect; //frect.left = 0; //frect.top = 0; //frect.right = GetGameOption().GetResolution_Width(); //frect.bottom = GetGameOption().GetResolution_Height(); //HDC dc = ::GetDC( hWnd ); //HBRUSH black_brush = (HBRUSH)::GetStockObject( BLACK_BRUSH ); //::FillRect( dc, &frect, black_brush ); //::ReleaseDC( hWnd, dc ); #ifdef _WEB_DISP_MODE if( GetGameOption().GetWinMode() == 0 ) { if( !ENV().IsExist( "win" ) ) { ChangeDisplay(); } } #endif return hWnd; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { //Web Browser Key Proc // if( ( WM_KEYDOWN == message || WM_KEYUP == message ) && g_IsShowWebBrowser ) if( ( WM_KEYDOWN == message || WM_KEYUP == message ) && g_IsShowWebBrowser && !g_bServerListFocus ) { if( wParam == VK_DELETE || wParam == VK_TAB || (wParam >= 0x60 && wParam < 0x70) || //VK_NUMPAD0 - VK_NUMPAD9 (wParam >= 0x30 && wParam < 0x40) || //ASCII '0' - '9' (0x30 - 0x39) (wParam >= 0x41 && wParam < 0x5B) ) //ASCII 'A' - 'Z' (0x41 - 0x5A) { // Ctrl + N을막기위해 일단 Ctrl키 입력자체를 막음 2009.10.26 sfreer if( g_pWebBrowser && GetAsyncKeyState(VK_CONTROL) == 0 /*&& !ControlKeyCheck*/ ) { CComQIPtr pIOIPAO(g_pWebBrowser) ; if(pIOIPAO) { MSG msg; msg.message = message; msg.wParam = wParam; msg.lParam = lParam; pIOIPAO->TranslateAccelerator(&msg); return 0; } } } else { //웹페이지 처리이므로 게임엔 주지 않음 return 0; } } #ifdef _HACK_SHIELD_ // { 키보드 메시지 들어 오면, 후킹 검사 내려감. if( WM_SYSKEYDOWN == message || WM_KEYDOWN == message ) { g_dwKeyResumeTime = GetSafeTickCount(); if( g_bCheckHook == false ) { if( g_bAhnHS ) SetWindowText( g_hWnd, "_AhnHS_PauseService( AHNHS_CHKOPT_MESSAGEHOOK )" ); _AhnHS_PauseService( AHNHS_CHKOPT_MESSAGEHOOK ); } g_bCheckHook = true; } #endif // { alt 키 메뉴 뜨는것 막음 if ( message == WM_SYSCOMMAND ) { if( wParam == SC_KEYMENU ) return 0; } // } if( message == WM_SYSKEYDOWN ) { if( wParam == VK_F4 ) return 0; } if(g_pSBotMng) { g_pSBotMng->WndProc( hWnd, message, wParam, lParam ); } #ifdef _EDIT_ENVIRONMENT_ if( message == WM_CLOSE ) { // 환경 파라미터 편집을 위한 다이얼로그 파괴 GetEditParameterDialog().End(); return 0; } #else if( message == WM_CLOSE ) return 0; #endif if ( message == WM_ACTIVATE || message == WM_SYNCPAINT ) { // 로그가 너무 많이 출력되서 일단 주석 //_oprint( "!!!!!!!!!! WM_ACTIVATE !!!!!!!!!!!\n" ); ResetHotKeys(); } if( g_hWnd == hWnd ) { switch( message ) { case WM_IME_SETCONTEXT : /*_performance_print( "* WM_IME_SETCONTEXT %d\n", wParam );*/ lParam = 0; break; case WM_IME_COMPOSITION : /*_performance_print( "* WM_IME_COMPOSITION %d\n", wParam ); */ KUIControlEdit::PostWndMsgToFocusEdit( message, wParam, lParam ); return 0L; case WM_IME_NOTIFY : /*_performance_print( "* WM_IME_NOTIFY %d\n", wParam );*/ KUIControlEdit::PostWndMsgToFocusEdit( message, wParam, lParam ); return 0L; case WM_IME_STARTCOMPOSITION : /*_performance_print( "* WM_IME_STARTCOMPOSITION %d\n", wParam ); */ return 0L; case WM_IME_ENDCOMPOSITION : /*_performance_print( "* WM_IME_ENDCOMPOSITION %d\n", wParam );*/ break; case WM_IME_CONTROL : /*_performance_print( "* WM_IME_CONTROL %d\n", wParam );*/ break; case WM_IME_COMPOSITIONFULL : /*_performance_print( "* WM_IME_COMPOSITIONFULL %d\n", wParam );*/ break; case WM_IME_SELECT : /*_performance_print( "* WM_IME_SELECT %d\n", wParam );*/ break; case WM_IME_CHAR : /*_performance_print( "* WM_IME_CHAR %d\n", wParam );*/ break; case WM_IME_REQUEST : /*_performance_print( "* WM_IME_REQUEST %d\n", wParam );*/ break; case WM_IME_KEYDOWN : /*_performance_print( "* WM_IME_KEYDOWN %d\n", wParam );*/ break; case WM_IME_KEYUP : /*_performance_print( "* WM_IME_KEYUP %d\n", wParam );*/ break; } } return DefWindowProc(hWnd, message, wParam, lParam); } // { [sonador][1.5.1] 키보드 입력 개선 #ifdef _USE_KEYBOARD_HOOK LRESULT CALLBACK KeyboardProc( int code, WPARAM wParam, LPARAM lParam ) { static GameHotKeystrcut HotKey; // static bool bShift, bAlt, bCtrl, bTab; static WPARAM sParam; static BYTE s_Key[256]; //Key State Map sParam = wParam; #ifndef _RELEASE int nDebug = LOWORD( wParam ); #endif //ALT, CTRL, SHIFT만 눌렀을 경우에는 메세지가 안 간다. if( HIWORD( lParam ) & KF_UP ) { if( LOWORD( wParam ) == VK_SHIFT ) { if( HotKey.bShift ) { HotKey.bShift = false; // g_pSBotMng->onHotkey(bShift, bAlt, bCtrl, LOWORD( sParam ) ); // _oprint( "_SHIFT Off\n" ); } } if( LOWORD( wParam ) == VK_MENU ) { if( HotKey.bAlt ) { HotKey.bAlt = false; // g_pSBotMng->onHotkey(bShift, bAlt, bCtrl, LOWORD( sParam ) ); // _oprint( "_ALT Off\n" ); } } if( LOWORD( wParam ) == VK_CONTROL ) { if( HotKey.bCtrl ) { HotKey.bCtrl = false; // g_pSBotMng->onHotkey(bShift, bAlt, bCtrl, LOWORD( sParam ) ); // _oprint( "_CONTROL Off\n" ); } } if( LOWORD( wParam ) == VK_TAB ) { if( HotKey.bTab ) { HotKey.bTab = false; } } if( s_Key[LOWORD( sParam )] || LOWORD(sParam) == VK_SNAPSHOT ) { s_Key[LOWORD( sParam )] = false; HotKey.Virtual_Key = LOWORD( sParam ); HotKey.bUp = TRUE; if( g_pSBotMng ) g_pSBotMng->onHotkey( HotKey ); // _oprint( "WPARAM %d\n", LOWORD( sParam ) ); } } else { if( LOWORD( wParam ) == VK_SHIFT ) { if( !HotKey.bShift ) { HotKey.bShift = true; // g_pSBotMng->onHotkey(bShift, bAlt, bCtrl, LOWORD( sParam ) ); // _oprint( "_SHIFT On\n" ); } } if( LOWORD( wParam ) == VK_MENU ) { if( !HotKey.bAlt ) { HotKey.bAlt = true; // g_pSBotMng->onHotkey(bShift, bAlt, bCtrl, LOWORD( sParam ) ); // _oprint( "_ALT On\n" ); } } if( LOWORD( wParam ) == VK_CONTROL ) { if( !HotKey.bCtrl ) { HotKey.bCtrl = true; // g_pSBotMng->onHotkey(bShift, bAlt, bCtrl, LOWORD( sParam ) ); // _oprint( "_CONTROL On\n" ); } } if( LOWORD( wParam ) == VK_TAB ) { if( !HotKey.bTab ) { HotKey.bTab = true; } } if( !s_Key[LOWORD( sParam )] ) { s_Key[LOWORD( sParam )] = true; HotKey.Virtual_Key = LOWORD( sParam ); HotKey.bUp = FALSE; if( g_pSBotMng ) g_pSBotMng->onHotkey( HotKey ); // _oprint( "WPARAM %d\n", LOWORD( sParam ) ); } } return CallNextHookEx( g_hKeyBoardHook, code, wParam, lParam ); } #else static GameHotKeystrcut HotKey; static BYTE s_Key[256] = {0, }; //Key State Map // #2.3.1.28 void ResetHotKeys() { SHORT sKey; sKey = GetKeyState( VK_MENU ); HotKey.Virtual_Key = VK_MENU; HotKey.bAlt = ((sKey & 0x1000) == 0x1000); HotKey.bUp = ((sKey & 0x1000) == 0); s_Key[ VK_MENU ] = sKey & 0x1000; if( g_pSBotMng ) g_pSBotMng->onHotkey( HotKey ); sKey = GetKeyState( VK_CONTROL ); HotKey.Virtual_Key = VK_MENU; HotKey.bCtrl = ((sKey & 0x1000) == 0x1000); HotKey.bUp = ((sKey & 0x1000) == 0); s_Key[ VK_MENU ] = sKey & 0x1000; if( g_pSBotMng ) g_pSBotMng->onHotkey( HotKey ); sKey = GetKeyState( VK_SHIFT ); HotKey.Virtual_Key = VK_SHIFT; HotKey.bShift = ((sKey & 0x1000) == 0x1000); HotKey.bUp = ((sKey & 0x1000) == 0); s_Key[ VK_MENU ] = sKey & 0x1000; if( g_pSBotMng ) g_pSBotMng->onHotkey( HotKey ); sKey = GetKeyState( VK_TAB); HotKey.Virtual_Key = VK_TAB; HotKey.bTab = ((sKey & 0x1000) == 0x1000); HotKey.bUp = ((sKey & 0x1000) == 0); s_Key[ VK_MENU ] = sKey & 0x1000; if( g_pSBotMng ) g_pSBotMng->onHotkey( HotKey ); // 알탭후 알트 눌려져있는 문제때문에 추가해봄. by 정동섭 HotKey.bAlt = false; } #include "SGameInterface.h" #include "SGameSystem.h" #include "SGameWorld.h" #include "SGame.h" #include "SUIChattingWnd.h" extern SGameSystem* g_pCurrentGameSystem; // 2011.11.04 - servantes LRESULT CALLBACK HotKeyProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) { // static bool bShift, bAlt, bCtrl, bTab; static WPARAM virtualKey; //BEGIN------------------------------------------------------------------------------------------------- //gmpbigsun( 20130108, #22935 ) : 키보드 후킹에서 VK_RETRUN을 포커싱관계에 상관없이 처리되고있었다. //본 함수에서 채팅창 포커싱을 주게끔하는 로직이 포함되어있어서 현재 많은 EditBox중 포커싱이 있는경우 //채팅창과 관계(포커싱)없다면 무시하도록 수정되었다. if( wParam == VK_RETURN ) { if( KUIControlEdit::IsFocusEdit() && g_pCurrentGameSystem ) { SUIChattingWnd* pChatWnd = NULL; SGameWorld* pGameWorld = dynamicCast(g_pCurrentGameSystem->GetGame()); if( pGameWorld ) { SGameManager* pGameManager = pGameWorld->GetGameManager(); if( pGameManager ) { SGameInterface* pGameInterface = pGameManager->GetGameInterface(); if( pGameInterface ) pChatWnd = (SUIChattingWnd*)pGameInterface->GetUIWindow( TOGGLE_WINDOW::UIWINDOW_CHATTING ); } } if( pChatWnd ) { //채팅창에 포커스가 있을경우만 VK_RETURN처리한다. if( false == pChatWnd->GetFocusEdit() ) return ::DefWindowProc( hWnd, message, wParam, lParam ); } } } //END------------------------------------------------------------------------------------------------- // take correct virtual key... if( wParam == VK_PROCESSKEY ) { virtualKey = ::ImmGetVirtualKey( hWnd ); } else { virtualKey = wParam; } #ifndef _RELEASE int nDebug = LOWORD( wParam ); #endif switch( message ) { case WM_SYSCOMMAND: break; case WM_SYSKEYDOWN: if( virtualKey == VK_SHIFT ) { if( !HotKey.bShift ) { HotKey.bShift = true; } } if( virtualKey == VK_CONTROL ) { if( !HotKey.bCtrl ) { HotKey.bCtrl = true; } } if( virtualKey == VK_MENU ) { if( !HotKey.bAlt ) { HotKey.bAlt = true; } } if( virtualKey == VK_TAB ) { if( !HotKey.bTab ) { HotKey.bTab = true; } } if( !s_Key[LOWORD( virtualKey )] ) { s_Key[LOWORD( virtualKey )] = true; HotKey.Virtual_Key = LOWORD( virtualKey ); HotKey.bUp = FALSE; if( g_pSBotMng ) { g_pSBotMng->onHotkey( HotKey ); // #2.3.1.29 // alt + F6 동작 오류 수정 // WM_SYSKEYDOWN 메시지 처리후 ::DefWindowProc 을 호출하여 WM_SYSKEYUP 메시지가 전달되지 않아서 발생한 문제. // 결국 F6 키가 눌러졌다가 다시 때지는 순간을 알 수 없었기 때문에 항상 눌려져 있는 상태로 기록되어 있었다. /// 2011.06.10 mantis 13776 alt+f4를 막음 - prodongi if (VK_F4 == wParam) return 1L; // return 1L; return ::DefWindowProc( hWnd, message, wParam, lParam ); //2011.05.06 - servantes } } break; case WM_SYSKEYUP: //_oprint( "syskeyup: %d\n", virtualKey ); if( virtualKey == VK_SHIFT ) { if( HotKey.bShift ) { HotKey.bShift = false; } } if( virtualKey == VK_CONTROL ) { if( HotKey.bCtrl ) { HotKey.bCtrl = false; } } if( virtualKey == VK_MENU ) { //_oprint("!!! alt up syskeyup 1 !!!\n" ); if( HotKey.bAlt ) { HotKey.bAlt = false; //_oprint("!!! alt up syskeyup 2 !!!\n" ); } } if( virtualKey == VK_TAB ) { if( HotKey.bTab ) { HotKey.bTab = false; } } if( s_Key[LOWORD( virtualKey )] || LOWORD( virtualKey ) == VK_SNAPSHOT ) { s_Key[LOWORD( virtualKey )] = false; HotKey.Virtual_Key = LOWORD( virtualKey ); HotKey.bUp = TRUE; if( g_pSBotMng ) { g_pSBotMng->onHotkey( HotKey ); // #2.3.1.29 // alt + F6 동작 오류 수정 // WM_SYSKEYDOWN 메시지 처리후 ::DefWindowProc 을 호출하여 WM_SYSKEYUP 메시지가 전달되지 않아서 발생한 문제. // 결국 F6 키가 눌러졌다가 다시 때지는 순간을 알 수 없었기 때문에 항상 눌려져 있는 상태로 기록되어 있었다. /// 2011.06.10 mantis 13776 alt+f4를 막음 - prodongi if (VK_F4 == wParam) return 1L; // return 1L; return ::DefWindowProc( hWnd, message, wParam, lParam ); //2011.05.06 - servantes } } break; case WM_KEYDOWN: //_oprint( "keydown: %d\n", virtualKey ); if( virtualKey == VK_SHIFT ) { if( !HotKey.bShift ) { HotKey.bShift = true; } } if( virtualKey == VK_CONTROL ) { if( !HotKey.bCtrl ) { HotKey.bCtrl = true; } } if( virtualKey == VK_MENU ) { //_oprint("!!! alt down keydown 1 !!!\n" ); if( !HotKey.bAlt ) { HotKey.bAlt = true; //_oprint("!!! alt down keydown 2 !!!\n" ); } } if( virtualKey == VK_TAB ) { if( !HotKey.bTab ) { HotKey.bTab = true; } } if( !s_Key[LOWORD( virtualKey )] ) { s_Key[LOWORD( virtualKey )] = true; HotKey.Virtual_Key = LOWORD( virtualKey ); HotKey.bUp = FALSE; if( g_pSBotMng ) g_pSBotMng->onHotkey( HotKey ); } break; case WM_KEYUP: //_oprint( "keyup: %d\n", virtualKey ); if( virtualKey == VK_SHIFT ) { if( HotKey.bShift ) { HotKey.bShift = false; } } if( virtualKey == VK_CONTROL ) { if( HotKey.bCtrl ) { HotKey.bCtrl = false; } } if( virtualKey == VK_MENU ) { //_oprint("!!! alt up keyup 1 !!!\n" ); if( HotKey.bAlt ) { HotKey.bAlt = false; //_oprint("!!! alt up keyup 2 !!!\n" ); } } if( virtualKey == VK_TAB ) { if( HotKey.bTab ) { HotKey.bTab = false; } } if( s_Key[LOWORD( virtualKey )] || LOWORD( virtualKey ) == VK_SNAPSHOT ) { s_Key[LOWORD( virtualKey )] = false; HotKey.Virtual_Key = LOWORD( virtualKey ); HotKey.bUp = TRUE; if( g_pSBotMng ) g_pSBotMng->onHotkey( HotKey ); } break; default: break; } return 0L; } #endif // } void ScriptLog( const char *szStr ); void InitScript() { //Lua Init LUA()->Init(); LUA()->InitThread(); //기존 스크립트 화일 Load - RunFile // std::string strTmpFile = KResourceManager::GetTempFileName( "어쩌구.lua" ); //Object LUA()->RegisterFunction( "spell" , SCRIPT_Spell ); LUA()->RegisterFunction( "skill" , SCRIPT_Skill ); LUA()->RegisterFunction( "attack", SCRIPT_Attack ); LUA()->RegisterFunction( "move" , SCRIPT_Move ); //bot manage LUA()->RegisterFunction( "botadd" , SCRIPT_BotAdd ); LUA()->RegisterFunction( "botdel" , SCRIPT_BotDel ); LUA()->RegisterFunction( "botlist", SCRIPT_BotList ); LUA()->RegisterFunction( "botsel" , SCRIPT_BotSelect ); //System LUA()->RegisterFunction( "log" , SCRIPT_ReportLog ); LUA()->RegisterFunction( "profile", SCRIPT_Profile ); //option LUA()->RegisterFunction( "set_music" , SCRIPT_SetMusic ); LUA()->RegisterFunction( "set_sound" , SCRIPT_SetSound ); LUA()->RegisterFunction( "set_volume", SCRIPT_SetVolume ); //게임 이펙트 LUA()->RegisterFunction( "playFX" , SCRIPT_FX ); LUA()->RegisterFunction( "playSound", SCRIPT_PlaySound ); LUA()->RegisterFunction( "playattackFX", SCRIPT_ATTACK_FX ); //게임 컨텐츠 LUA()->RegisterFunction( "getItemClass", SCRIPT_GetItemClass ); LUA()->RegisterFunction( "getMaterial" , SCRIPT_GetMaterial ); LUA()->RegisterFunction( "getGroundMaterial" , SCRIPT_GetGroundMaterial ); LUA()->RegisterFunction( "getMovingType", SCRIPT_GetMovingType ); //스크립트 디버그 연결~ _oprint( ">>>>>>>>>>>>>>>script_file Loading...start=====================\n" ); LUA()->BindLogOutputFunction( ScriptLog ); std::string strScript = KFileManager::Instance().CreateTemporaryFileFromResource( "FX_Script.lua" ); if( strScript.length() ) { LUA()->RunFile( strScript.c_str() ); KFileManager::Instance().DeleteTemporaryFile( "FX_Script.lua" ); } else { _oprint( "File Not Found : FX_Script.lua\n" ); } _oprint( ">>>>>>>>>>>>>>>script_file Loaded...end=====================\n" ); //상태 관련 정보 가져오기 LUA()->RegisterFunction( "gethp", SCRIPT_GetHP ); LUA()->RegisterFunction( "getmp", SCRIPT_GetMP ); LUA()->RegisterFunction( "getmax_hp", SCRIPT_GetMax_HP ); LUA()->RegisterFunction( "getmax_mp", SCRIPT_GetMax_MP ); //크리처 동작 LUA()->RegisterFunction( "c_standby", SCRIPT_C_Standby ); LUA()->RegisterFunction( "c_move", SCRIPT_C_Move ); LUA()->RegisterFunction( "c_attack", SCRIPT_C_Attack ); LUA()->RegisterFunction( "c_skill", SCRIPT_C_Skill ); LUA()->RegisterFunction( "c_idle", SCRIPT_C_Idle ); _oprint( ">>>>>>>>>>>>>>>creature_script_file Loading...start=====================\n" ); LUA()->BindLogOutputFunction( ScriptLog ); strScript = KFileManager::Instance().CreateTemporaryFileFromResource( "CreatureState_Script.lua" ); if( strScript.length() ) { LUA()->RunFile( strScript.c_str() ); KFileManager::Instance().DeleteTemporaryFile( "CreatureState_Script.lua" ); } else { _oprint( "File Not Found : CreatureState_Script.lua\n" ); } _oprint( ">>>>>>>>>>>>>>>creature_script_file Loaded...end=====================\n" ); //지역 관련 LUA()->RegisterFunction( "lc_in", SCRIPT_LC_In ); LUA()->RegisterFunction( "lc_out", SCRIPT_LC_Out ); LUA()->RegisterFunction( "lc_local", SCRIPT_LC_Local ); LUA()->RegisterFunction( "lc_world", SCRIPT_LC_World ); _oprint( ">>>>>>>>>>>>>>>local_script_file Loading...start=====================\n" ); LUA()->BindLogOutputFunction( ScriptLog ); strScript = KFileManager::Instance().CreateTemporaryFileFromResource( "Location_Script.lua" ); if( strScript.length() ) { LUA()->RunFile( strScript.c_str() ); KFileManager::Instance().DeleteTemporaryFile( "CreatureState_Script.lua" ); } else { _oprint( "File Not Found : CreatureState_Script.lua\n" ); } _oprint( ">>>>>>>>>>>>>>>local_script_file Loaded...end=====================\n" ); // { [sonador] 날씨 관련 스크립트 LUA()->RegisterFunction( "get_current_weather_theme", SCRIPT_WEATHER_GetTheme ); LUA()->RegisterFunction( "set_current_weather_theme", SCRIPT_WEATHER_SetTheme ); LUA()->RegisterFunction( "set_thunder_attribute", SCRIPT_WEATHER_SetThunderAttribute ); LUA()->RegisterFunction( "set_lightning_attribute", SCRIPT_WEATHER_SetLightningAttribute ); _oprint( ">>>>>>>>>>>>>>>weather_script_file Loading...start=====================\n" ); LUA()->BindLogOutputFunction( ScriptLog ); strScript = KFileManager::Instance().CreateTemporaryFileFromResource( "weather_script.lua" ); if( strScript.length() ) { LUA()->RunFile( strScript.c_str() ); KFileManager::Instance().DeleteTemporaryFile( "weather_script.lua" ); } else { _oprint( "File Not Found : weather_script.lua\n" ); } _oprint( ">>>>>>>>>>>>>>>weather_script_file Loaded...end=====================\n" ); // 환경값 설정용 스크립트 LUA()->RegisterFunction( "set_environment_info", SCRIPT_ENVIRONMENT_GetAttribute ); // } [sonador] 날씨 관련 스크립트 //게임 UIWindows AddOn 관련 LUA()->RegisterFunction( "init_addon_list", SCRIPT_UIWINDOWS_InitAddonList ); LUA()->RegisterFunction( "create_addon", SCRIPT_UIWINDOWS_CreateAddOn ); _oprint( ">>>>>>>>>>>>>>>uiwindows_addon_script Loading...start=====================\n" ); LUA()->BindLogOutputFunction( ScriptLog ); strScript = KFileManager::Instance().CreateTemporaryFileFromResource( "UIWindows_addon_script.lua" ); if( strScript.length() ) { LUA()->RunFile( strScript.c_str() ); KFileManager::Instance().DeleteTemporaryFile( "UIWindows_addon_script.lua" ); } else { _oprint( "File Not Found : UIWindows_addon_script.lua\n" ); } _oprint( ">>>>>>>>>>>>>>>uiwindows_addon_script Loaded...end=====================\n" ); #ifdef DISTANCE_VIEW _oprint( ">>>>>>>>>>>>>>>skybox_script_file Loading...start=====================\n" ); LUA()->BindLogOutputFunction( ScriptLog ); // strScript = KFileManager::Instance().CreateTemporaryFileFromResource( "skybox_script.lua" ); strScript = KFileManager::Instance().CreateTemporaryFileFromResource( "skybox_script2.lua" ); if( strScript.length() ) { LUA()->RunFile( strScript.c_str() ); // KFileManager::Instance().DeleteTemporaryFile( "skybox_script.lua" ); KFileManager::Instance().DeleteTemporaryFile( "skybox_script2.lua" ); } else { _oprint( "File Not Found : skybox_script.lua\n" ); } LUA()->RegisterFunction( "set_current_skybox_theme_sky", SCRIPT_SKYBOX_SetTheme_sky ); LUA()->RegisterFunction( "set_current_skybox_theme_distance_view", SCRIPT_SKYBOX_SetTheme_distanceView ); LUA()->RegisterFunction( "load_localmodelinfo", SCRIPT_SKYBOX_load_localmodelinfo ); // LUA()->RunString( "read_local_model_info()" ); _oprint( ">>>>>>>>>>>>>>>skybox_script_file Loaded...end=====================\n" ); #endif #ifdef CLOUD_LUA strScript = KFileManager::Instance().CreateTemporaryFileFromResource( "cloud_script.lua" ); if( strScript.length() > 0 ) { LUA()->RunFile( strScript.c_str() ); KFileManager::Instance().DeleteTemporaryFile( "cloud_script.lua" ); } LUA()->RegisterFunction( "load_kind", SCRIPT_CLOUD_LoadKind ); LUA()->RegisterFunction( "load_thickness", SCRIPT_CLOUD_LoadThickness ); LUA()->RegisterFunction( "load_thickness_gap", SCRIPT_CLOUD_LoadThicknessGap ); LUA()->RegisterFunction( "load_size", SCRIPT_CLOUD_LoadSize ); LUA()->RegisterFunction( "load_texture_group", SCRIPT_CLOUD_LoadTextureGroup ); LUA()->RegisterFunction( "load_middle_texture_group", SCRIPT_CLOUD_LoadMiddleTextureGroup ); LUA()->RegisterFunction( "load_dark_texture_group", SCRIPT_CLOUD_LoadDarkTextureGroup ); LUA()->RegisterFunction( "load_distribution", SCRIPT_CLOUD_LoadDistribution ); LUA()->RegisterFunction( "load_height_random_gap", SCRIPT_CLOUD_LoadHeightRandomGap ); LUA()->RegisterFunction( "load_layer_gap", SCRIPT_CLOUD_LoadLayerGap ); LUA()->RegisterFunction( "load_move_dir", SCRIPT_CLOUD_LoadMoveDir ); LUA()->RegisterFunction( "load_path", SCRIPT_CLOUD_LoadPath ); LUA()->RegisterFunction( "load_type", SCRIPT_CLOUD_LoadType ); LUA()->RegisterFunction( "load_appear_layer", SCRIPT_CLOUD_LoadAppearLayer ); LUA()->RegisterFunction( "load_layer_set", SCRIPT_CLOUD_LoadLayerSet ); // LUA()->RunString( "loadCloudInfo()" ); std::string function_call; XStringUtil::Format( function_call, "loadCloudInfo()" ); LUA()->RunString( function_call.c_str() ); #endif } std::string GetOSInfo() { //프로세스 메모리 얻는 것 넣어야 함. // GetProcessMemoryInfo(); OSVERSIONINFO info; memset( &info, 0, sizeof(info) ); info.dwOSVersionInfoSize = sizeof(info); if( !GetVersionEx( &info ) ) return "Unknown OS"; std::string strName = "Windows "; switch( info.dwPlatformId ) { case VER_PLATFORM_WIN32s: { strName += "Win32s "; break; } case VER_PLATFORM_WIN32_WINDOWS: { if( info.dwMajorVersion == 4 && info.dwMinorVersion == 0 ) strName += "95 "; if( info.dwMajorVersion == 4 && info.dwMinorVersion == 10 ) strName += "98 "; if( info.dwMajorVersion == 4 && info.dwMinorVersion == 90 ) strName += "Me "; break; } case VER_PLATFORM_WIN32_NT: { if( info.dwMajorVersion == 3 && info.dwMinorVersion == 51 ) strName += "NT 3.51 "; if( info.dwMajorVersion == 4 && info.dwMinorVersion == 0 ) strName += "NT 4.0 "; if( info.dwMajorVersion == 5 && info.dwMinorVersion == 0 ) strName += "2000 "; if( info.dwMajorVersion == 5 && info.dwMinorVersion == 1 ) strName += "XP "; if( info.dwMajorVersion == 5 && info.dwMinorVersion == 2 ) strName += "2003 "; } } strName += info.szCSDVersion; strName += " "; char buf[256]; sprintf( buf, "(%d.%d.%d)", info.dwMajorVersion, info.dwMinorVersion, info.dwBuildNumber ); strName += buf; return strName; } bool RestoreDisplay() { //화면 해상도 복구 DEVMODE _devmode = g_dm; if( g_dm_apply.dmPelsWidth != _devmode.dmPelsWidth || g_dm_apply.dmPelsHeight != _devmode.dmPelsHeight ) { if( _devmode.dmPelsWidth != GetGameOption().GetResolution_Width() || _devmode.dmPelsHeight != GetGameOption().GetResolution_Height() ) { ChangeDisplaySettings( &_devmode, 0 ); g_dm_apply = _devmode; return true; } } return false; } bool ChangeDisplay() { //화면 해상도 복구 DEVMODE _devmode = g_dm; if( g_dm_apply.dmPelsWidth != GetGameOption().GetResolution_Width() || g_dm_apply.dmPelsHeight != GetGameOption().GetResolution_Height() ) { _devmode.dmPelsWidth = GetGameOption().GetResolution_Width(); _devmode.dmPelsHeight = GetGameOption().GetResolution_Height(); ChangeDisplaySettings( &_devmode, 0 ); g_dm_apply = _devmode; return true; } return false; } void SetWindowStyle( bool bFullScreen ) { DWORD dwStyle = 0; //전체 모드일때, 캡션 보더 사용안함. if(bFullScreen) { dwStyle = WS_POPUPWINDOW; dwStyle &= ~WS_SYSMENU; dwStyle &= ~WS_MINIMIZEBOX; } else { dwStyle = WS_OVERLAPPEDWINDOW; dwStyle &= ~WS_SYSMENU; dwStyle |= WS_MINIMIZEBOX; } dwStyle &= ~WS_THICKFRAME; dwStyle &= ~WS_MAXIMIZEBOX; //Explorer dwStyle |= WS_CLIPCHILDREN; dwStyle |= WS_CLIPSIBLINGS; SetWindowLong((HWND) g_hWnd, GWL_STYLE, dwStyle); if(!bFullScreen) { //int x, y, cx, cy, sx, sy; int cx, cy, sx, sy; cx = GetGameOption().GetResolution_Width() + GetSystemMetrics(SM_CXFIXEDFRAME) * 2; cy = GetGameOption().GetResolution_Height() + GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFIXEDFRAME) * 2; sx = GetSystemMetrics(SM_CXSCREEN); sy = GetSystemMetrics(SM_CYSCREEN); //SetWindowPos((HWND) m_cs.hWnd, HWND_NOTOPMOST, (sx - cx) / 2, (sy - cy) / 2, cx, cy, SWP_SHOWWINDOW); SetWindowPos((HWND) g_hWnd, HWND_NOTOPMOST, (sx - cx) / 2, (sy - cy) / 2, cx, cy, 0); } else { int cx, cy; cx = GetGameOption().GetResolution_Width(); cy = GetGameOption().GetResolution_Height(); SetWindowPos((HWND) g_hWnd, HWND_NOTOPMOST, 0, 0, cx, cy, 0); } ShowWindow((HWND) g_hWnd, SW_SHOW); } void CheckDisplay() { ZeroMemory(&g_dm , sizeof(g_dm) ); ZeroMemory(&g_dm_apply, sizeof(g_dm_apply)); TCHAR msg[10000] = _T(""); DISPLAY_DEVICE dd; dd.cb = sizeof(dd); DWORD dev = 0; // device index int id = 1; // monitor number, as used by Display Properties > Settings while (EnumDisplayDevices(0, dev, &dd, 0)) { if (!(dd.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER)) { // ignore virtual mirror displays // get information about the monitor attached to this display adapter. dualhead cards // and laptop video cards can have multiple monitors attached DISPLAY_DEVICE ddMon; ZeroMemory(&ddMon, sizeof(ddMon)); ddMon.cb = sizeof(ddMon); DWORD devMon = 0; // please note that this enumeration may not return the correct monitor if multiple monitors // are attached. this is because not all display drivers return the ACTIVE flag for the monitor // that is actually active while (EnumDisplayDevices(dd.DeviceName, devMon, &ddMon, 0)) { if (ddMon.StateFlags & DISPLAY_DEVICE_ACTIVE) break; devMon++; } if (!*ddMon.DeviceString) { EnumDisplayDevices(dd.DeviceName, 0, &ddMon, 0); if (!*ddMon.DeviceString) lstrcpy(ddMon.DeviceString, _T("Default Monitor")); } // get information about the display's position and the current display mode DEVMODE dm; ZeroMemory(&dm, sizeof(dm)); dm.dmSize = sizeof(dm); if (EnumDisplaySettingsEx(dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm, 0) == FALSE) EnumDisplaySettingsEx(dd.DeviceName, ENUM_REGISTRY_SETTINGS, &dm, 0); if( id == 1) { g_dm = dm; g_dm_apply = g_dm; } // get the monitor handle and workspace HMONITOR hm = 0; MONITORINFO mi; ZeroMemory(&mi, sizeof(mi)); mi.cbSize = sizeof(mi); if (dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) { // display is enabled. only enabled displays have a monitor handle POINT pt = { dm.dmPosition.x, dm.dmPosition.y }; hm = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL); if (hm) GetMonitorInfo(hm, &mi); } // format information about this monitor TCHAR buf[1000]; // 1. MyMonitor on MyVideoCard wsprintf(buf, _T("%d. %s on %s\r\n"), id, ddMon.DeviceString, dd.DeviceString); lstrcat(msg, buf); // status flags: primary, disabled, removable buf[0] = _T('\0'); if (!(dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) lstrcat(buf, _T("disabled, ")); else if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) lstrcat(buf, _T("primary, ")); if (dd.StateFlags & DISPLAY_DEVICE_REMOVABLE) lstrcat(buf, _T("removable, ")); if (*buf) { buf[lstrlen(buf) - 2] = _T('\0'); lstrcat(buf, _T("\r\n")); lstrcat(msg, buf); } // width x height @ x,y - bpp - refresh rate // note that refresh rate information is not available on Win9x wsprintf(buf, _T("%d x %d @ %d,%d - %d-bit - %d Hz\r\n"), dm.dmPelsWidth, dm.dmPelsHeight, dm.dmPosition.x, dm.dmPosition.y, dm.dmBitsPerPel, dm.dmDisplayFrequency); lstrcat(msg, buf); if (hm) { // workspace and monitor handle // workspace: x,y - x,y HMONITOR: handle wsprintf(buf, _T("workspace: %d,%d - %d,%d HMONITOR: 0x%X\r\n"), mi.rcWork.left, mi.rcWork.top, mi.rcWork.right, mi.rcWork.bottom, hm); lstrcat(msg, buf); } // device name wsprintf(buf, _T("Device: %s\r\n\r\n"), *ddMon.DeviceName ? ddMon.DeviceName : dd.DeviceName); lstrcat(msg, buf); id++; } dev++; } } // { 힙 펜스 (힙 깨진거 찾기 위함. #ifndef _DEBUG const int HEAP_FENCE_BEGIN = 0xFA3FDEED; const int HEAP_FENCE_END = 0xDC8FBEEF; //#define DETECT_HEAP_OVERRUN //#define USE_MEMORY_POOL /* 라펠즈 프로파일링 결과에 따르면, 약 10분정도 플레이시 블럭 크기별로 아래 횟수만큼 할당/해제가 일어난다. 해서 48바이트 이하의 할당은 메모리 풀에서 관리하도록 한다. 이는 USE_MEMORY_POOL 로 사용 가능하다. (상위 10개) 32 1583004 8 1113468 16 1037935 24 1011784 48 486685 40 365477 12 320878 72 300097 104 252618 13 249758 */ #ifdef USE_MEMORY_POOL static bool s_bPoolInitComplete = false; int g_nMemAllocCnt[128]; int POOL_MASK = 0x80000000; XCriticalSection & getHeapCS() { static XCriticalSection cs; return cs; } //#define _USE_OLD_POOL #ifndef _USE_OLD_POOL #ifdef DETECT_HEAP_OVERRUN #define PAREN 8 #else #define PAREN 0 #endif struct MemPool { c_unimempool< 8 + 4 + PAREN > Mem8; c_unimempool< 16 + 4 + PAREN > Mem16; c_unimempool< 32 + 4 + PAREN > Mem32; c_unimempool< 24 + 4 + PAREN > Mem24; c_unimempool< 48 + 4 + PAREN > Mem48; }; static MemPool* s_pool = NULL; struct Module { Module() { s_pool = new MemPool; s_bPoolInitComplete = true; } ~Module() { MemPool* p = s_pool; s_pool = NULL; delete p; } }; void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc) { static size_t cnt; if ( size == 0 ) // to make D3DX happy - by Tyburn size = 1; char *p; if ( size > 48 || !s_pool ) { p = (char*)malloc( size + 4 + PAREN ); *((size_t *)p) = size; } else { THREAD_SYNCRONIZE( getHeapCS() ); if( size == 32 ) p = (char*)s_pool->Mem32.alloc(); else if( size == 24 ) p = (char*)s_pool->Mem24.alloc(); else if( size <= 8 ) p = (char*)s_pool->Mem8.alloc(); else if( size <= 16 ) p = (char*)s_pool->Mem16.alloc(); else if( size <= 48 ) p = (char*)s_pool->Mem48.alloc(); *((size_t *)p) = size | POOL_MASK; } if( size < 128 ) interlocked_increment( &g_nMemAllocCnt[size] ); #ifdef DETECT_HEAP_OVERRUN unsigned int *begin = (unsigned int *)( p + 4 ); unsigned int *end = (unsigned int *)( p + 4 + PAREN/2 + size ); *begin = HEAP_FENCE_BEGIN; *end = HEAP_FENCE_END; //if(s_bLeackCheck) //{ // g_leakChecker.add(reinterpret_cast(p), StackTrace(2, 1)); //} #endif return p + 4 + PAREN/2; } void operator delete( void * p ) throw() { if( !p ) return; char *p2 = (char*)p; p2 -= 4 + PAREN/2; size_t *alloc_size = (size_t *)p2; bool bIsPoolMemory = false; if( *alloc_size & POOL_MASK ) { *alloc_size &= ( ~POOL_MASK ); bIsPoolMemory = true; } #ifdef DETECT_HEAP_OVERRUN unsigned int *begin = (unsigned int *)( p2 + 4 ); unsigned int *end = (unsigned int *)( p2 + *alloc_size + 8 ); if( *begin != HEAP_FENCE_BEGIN || *end != HEAP_FENCE_END ) { char buf[256]; sprintf( buf, "%08X : %08X : %d", *begin, *end, *alloc_size ); MessageBox( NULL, buf, "HEAP!", MB_OK ); } #endif if ( bIsPoolMemory ) { if ( s_pool ) { size_t size = *alloc_size; THREAD_SYNCRONIZE( getHeapCS() ); if( size == 32 ) s_pool->Mem32.free( p2 ); else if( size == 24 ) s_pool->Mem24.free( p2 ); else if( size <= 8 ) s_pool->Mem8.free( p2 ); else if( size <= 16 ) s_pool->Mem16.free( p2 ); else if( size <= 48 ) s_pool->Mem48.free( p2 ); } else assert(0); } else free( p2 ); //if(s_bLeackCheck) //{ // if(g_leakChecker.has(reinterpret_cast(p))) // g_leakChecker.erase(reinterpret_cast(p)); //} } #undef PAREN #else static bool s_bPoolInitComplete = false; static XMemoryPool* getMemoryPool( size_t size ) { #ifndef USE_MEMORY_POOL return 0; #endif if( !s_bPoolInitComplete ) return NULL; #ifdef DETECT_HEAP_OVERRUN static XMemoryPool s_Mem8( 8 + 12 ); static XMemoryPool s_Mem32( 32 + 12 ); static XMemoryPool s_Mem16( 16 + 12 ); static XMemoryPool s_Mem24( 24 + 12 ); static XMemoryPool s_Mem48( 48 + 12 ); #else static XMemoryPool s_Mem8( 8 + 4 ); static XMemoryPool s_Mem32( 32 + 4 ); static XMemoryPool s_Mem16( 16 + 4 ); static XMemoryPool s_Mem24( 24 + 4 ); static XMemoryPool s_Mem48( 48 + 4 ); #endif s_bPoolInitComplete = true; if( size == 32 ) return &s_Mem32; else if( size == 24 ) return &s_Mem24; else if( size <= 8 ) return &s_Mem8; else if( size <= 16 ) return &s_Mem16; else if( size <= 48 ) return &s_Mem48; return NULL; } void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc) { static size_t cnt; if( size == 0 ) return (void*)0x00000001; XMemoryPool *pPool = getMemoryPool( size ); char *p; if( pPool ) { THREAD_SYNCRONIZE( getHeapCS() ); p = (char*)pPool->Alloc(); } else p = (char*)malloc( size + 12 ); size_t *alloc_size = (size_t *)p; #ifdef _DEBUG if( size < 128 ) interlocked_increment( &g_nMemAllocCnt[size] ); #endif if( pPool ) { *alloc_size |= POOL_MASK; } else { *alloc_size = size; } // { 일정 횟수당 한번씩 디버거 붙어 있는지 검사해서 네트웍을 깨버린다. #ifndef DISABLE_DEBUGGER_DETECTOR #ifndef _DEBUG ++cnt; if( cnt > 1000 ) { if( is_debugger_present() ) XBasicCipher::BreakCipher( (int)p ); cnt -= 1000; } #endif #endif // } #ifdef DETECT_HEAP_OVERRUN unsigned int *begin = (unsigned int *)( p + 4 ); unsigned int *end = (unsigned int *)( p + size + 8 ); *begin = HEAP_FENCE_BEGIN; *end = HEAP_FENCE_END; return p + 8; #else return p + 4; #endif } void operator delete( void * p ) throw() { if( !p || p == (void*)0x00000001 ) return; char *p2 = (char*)p; #ifdef DETECT_HEAP_OVERRUN p2 -= 8; #else p2 -= 4; #endif size_t *alloc_size = (size_t *)p2; bool bIsPoolMemory = false; if( *alloc_size & POOL_MASK ) { *alloc_size &= ( ~POOL_MASK ); bIsPoolMemory = true; } #ifdef DETECT_HEAP_OVERRUN unsigned int *begin = (unsigned int *)( p2 + 4 ); unsigned int *end = (unsigned int *)( p2 + *alloc_size + 8 ); if( *begin != HEAP_FENCE_BEGIN || *end != HEAP_FENCE_END ) { char buf[256]; sprintf( buf, "%08X : %08X : %d", *begin, *end, *alloc_size ); MessageBox( g_hWnd, buf, "HEAP!", MB_OK ); } #endif XMemoryPool *pPool = getMemoryPool( *alloc_size ); if( bIsPoolMemory ) { if( pPool ) { THREAD_SYNCRONIZE( getHeapCS() ); pPool->Free( p2 ); } else { assert( 0 ); } } else free( p2 ); } #endif // _USE_OLD_POOL #endif // USE_MEMORY_POOL #endif // _DEBUG // } #ifdef _HACK_SHIELD_ int __stdcall _AhnHS_Callback( long lCode, long lParamSize, void* pParam ) { // sonador 7.4.2 안랩 측 핵쉴드 버그 수정(callback function 내의 static variable 제거) bool bDtectAlReadyHooked = true; bool bDtectAutoMouse = true; bool bDtectHookFuntion = true; bool bDtectDriveFailed = true; bool bDtectSpeedHack = true; bool bDtectSpeedHack_app = true; bool bDtectMessageHook = true; bool bDtectKDTrace = true; bool bDtectKDTraceChanged = true; bool bDtectSpeedHackRatio = true; bool bDtectGameHack = true; bool bDtectGeneralHack = true; bool bDtectModuleChange = true; bool bDetectAutoMacro = true; // sonador 7.4.1 AHNHS_ACTAPC_DETECT_AUTOMACRO 관련 callback 처리 bool bDetectNanoEngineFailed = true; // sonador 7.4.4 핵쉴드 270 적용 bool bDetectCodeMismatch = true; // bool bExitGame = false; GameSecurityMsg::MSG_TYPE msgtype = GameSecurityMsg::MSG_MAX; switch( lCode ) { /* case AHNHS_ACTAPC_DETECT_ALREADYHOOKED: //"일부 API가 이미 후킹되어 있는 상태입니다. (그러나 실제로는 이를 차단하고 있기 때문에 후킹프로그램은 동작하지 않습니다.)"; { //운영 룰 : 아무것도 안함 if( bDtectAlReadyHooked ) { msgtype = GameSecurityMsg::MSG_HACK_SHIELD_DETECT_ALREADYHOOKED; bDtectAlReadyHooked = false; } break; }*/ case AHNHS_ACTAPC_DETECT_AUTOMOUSE: //"오토마우스 행위가 감지되었습니다."; { //운영 룰 : 메세지 출력 및 종료 if( bDtectAutoMouse ) { msgtype = GameSecurityMsg::MSG_HACK_SHIELD_DETECT_AUTOMOUSE; bDtectAutoMouse = false; bExitGame = true; } break; } case AHNHS_ACTAPC_DETECT_HOOKFUNCTION: //"보호 API에 대한 후킹 행위가 감지되었습니다."; { //운영 룰 : 메세지 출력 및 종료 if( bDtectHookFuntion ) { msgtype = GameSecurityMsg::MSG_HACK_SHIELD_DETECT_HOOKFUNCTION; bDtectHookFuntion = false; bExitGame = true; } break; } case AHNHS_ACTAPC_DETECT_DRIVERFAILED: //"해킹 차단 드라이버가 로드되지 않았습니다."; { //운영 룰 : 메세지 출력 및 종료 if( bDtectDriveFailed ) { msgtype = GameSecurityMsg::MSG_HACK_SHIELD_DETECT_DRIVERFAILED; bDtectDriveFailed = false; bExitGame = true; } break; } case AHNHS_ACTAPC_DETECT_SPEEDHACK: //"스피드핵류의 프로그램에 의해 시스템 시간이 변경되었습니다."; { //운영 룰 : 메세지 출력 및 종료 if( bDtectSpeedHack ) { msgtype = GameSecurityMsg::MSG_HACK_SHIELD_DETECT_SPEEDHACK; bDtectSpeedHack = false; bExitGame = true; } break; } case AHNHS_ACTAPC_DETECT_SPEEDHACK_APP: //"스피드핵류의 프로그램에 의해 시스템 시간이 변경되었습니다."; { //운영 룰 : 메세지 출력 및 종료 if( bDtectSpeedHack_app ) { msgtype = GameSecurityMsg::MSG_HACK_SHIELD_DETECT_SPEEDHACK_APP; bDtectSpeedHack_app = false; bExitGame = true; } break; } case AHNHS_ACTAPC_DETECT_MESSAGEHOOK: //"메시지 후킹이 시도되었으며 이를 차단하지 못했습니다."; { //운영 룰 : 메세지 출력 및 종료 if( bDtectMessageHook ) { msgtype = GameSecurityMsg::MSG_HACK_SHIELD_DETECT_MESSAGEHOOK; bDtectMessageHook = false; bExitGame = true; } break; } case AHNHS_ACTAPC_DETECT_KDTRACE: //"디버거 트래이싱이 발생했다.(커널 디버거 활성화, 이후 브레이크 포인터 처리)"; { //운영 룰 : 메세지 출력 및 종료 if( bDtectKDTrace ) { msgtype = GameSecurityMsg::MSG_HACK_SHIELD_DETECT_KDTRACE; bDtectKDTrace = false; bExitGame = true; } break; } case AHNHS_ACTAPC_DETECT_KDTRACE_CHANGED: //"설치된 디버거 트래이싱이 변경되었다."; { //운영 룰 : 메세지 출력 및 종료 if( bDtectKDTraceChanged ) { msgtype = GameSecurityMsg::MSG_HACK_SHIELD_DETECT_KDTRACE_CHANGED; bDtectKDTraceChanged = false; bExitGame = true; } break; } case AHNHS_ACTAPC_DETECT_SPEEDHACK_RATIO: //"스피드핵 감지 옵션이 'GAME'이 경우 이 콜백으로 최근 5초동안의 시간정보가 전달됩니다."; { if( bDtectSpeedHackRatio ) { msgtype = GameSecurityMsg::MSG_HACK_SHIELD_DETECT_SPEEDHACK_RATIO; bDtectSpeedHackRatio = false; } break; } case AHNHS_ENGINE_DETECT_GAME_HACK: //"게임 해킹툴의 실행이 발견되었습니다."; { //운영 룰 : 메세지 출력 및 종료 if( bDtectGameHack ) { msgtype = GameSecurityMsg::MSG_HACK_SHIELD_DETECT_GAME_HACK; bDtectGameHack = false; bExitGame = true; } break; } case AHNHS_ENGINE_DETECT_GENERAL_HACK: //"일반 해킹툴(트로이목마 종류)이 발견되었습니다."; { //운영 룰 : 메세지 출력 Yes, No if( bDtectGeneralHack ) { msgtype = GameSecurityMsg::MSG_HACK_SHIELD_DETECT_GENERAL_HACK; bDtectGeneralHack = false; bExitGame = true; } break; } case AHNHS_ACTAPC_DETECT_MODULE_CHANGE: //"핵쉴드 관련모듈이 변경되었습니다."; { //운영 룰 : 메세지 출력 if( bDtectModuleChange ) { msgtype = GameSecurityMsg::MSG_HACK_SHIELD_DETECT_MODULE_CHANGE; bDtectModuleChange = false; bExitGame = true; } break; } case AHNHS_ACTAPC_DETECT_AUTOMACRO: // sonador 7.4.1 AHNHS_ACTAPC_DETECT_AUTOMACRO 관련 callback 처리 { if( bDetectAutoMacro ) { msgtype = GameSecurityMsg::MSG_HACK_SHIELD_DETECT_AUTOMACRO; bDetectAutoMacro = false; bExitGame = true; } break; } case AHNHS_ACTAPC_DETECT_ENGINEFAILED: // sonador 7.4.4 핵쉴드 270 적용 { if( bDetectNanoEngineFailed ) { msgtype = GameSecurityMsg::MSG_HACK_SHIELD_DETECT_ENGINEFAILED; bDetectNanoEngineFailed = false; bExitGame = true; } break; } case AHNHS_ACTAPC_DETECT_CODEMISMATCH: // sonacor 7.4.4 핵쉴드 270 적용 { if( bDetectCodeMismatch ) { msgtype = GameSecurityMsg::MSG_HACK_SHIELD_DETECT_CODEMISMATCH; bDetectCodeMismatch = false; bExitGame = true; } break; } } if( bExitGame ) { GameSecurityMsg* pSecurityMsg = new GameSecurityMsg; pSecurityMsg->nMsgType = msgtype; pSecurityMsg->nNativeCode = static_cast< unsigned long >( lCode ); // sonador 7.4.3 해킹 툴 감지후 종료 프로세스 구현 g_SecurityMsg.push_back( pSecurityMsg ); } return 1; } // sonador 7.4.4 핵쉴드 270 적용 bool UpdateHackShieldService() { TCHAR *pEnd = NULL; TCHAR lpszUpdateDir[MAX_PATH] = { 0, }; GetModuleFileName(NULL, lpszUpdateDir, MAX_PATH); pEnd = _tcsrchr( lpszUpdateDir, _T('\\')) + 1; if (!pEnd) { TCHAR strResult[1024]; _sntprintf( strResult, 1024, TEXT("HackShieldService Failed - %s"), lpszUpdateDir ); MessageBox( NULL, strResult, TEXT("Error"), MB_OK | MB_ICONERROR ); return false; } *pEnd = _T('\0'); lstrcat(lpszUpdateDir, _T("HackShield")); int nResult = _AhnHS_HSUpdate( lpszUpdateDir, 600000 ); // sonador 7.4.6 스마트 업데이트 대기 시간 수정 if( nResult != HACKSHIELD_ERROR_SUCCESS ) { std::string strerr; switch( nResult ) { case HSERROR_ENVFILE_NOTREAD: strerr = S( 4132 ); break; // "HSUpdate.env 파일을 읽을 수 없습니다." case HSERROR_ENVFILE_NOTWRITE: strerr = S( 4133 ); break; // "HSUpdate.env 파일을 쓸 수 없습니다." case HSERROR_NETWORK_CONNECT_FAIL: strerr = S( 4134 ); break; // "해당 서버에 연결할 수 없습니다." case HSERROR_LIB_NOTEDIT_REG: strerr = S( 4135 ); break; // "네트워크 결과 입력 중에 오류가 발생하였습니다." case HSERROR_NOTFINDFILE: strerr = S( 4136 ); break; // "HackShield 업데이트 프로그램 관련 파일을 찾을 수 없습니다." case HSERROR_PROTECT_LISTLOAD_FAIL: strerr = S( 4137 ); break; // "HSUpdate.pt 인증 파일을 찾을 수 없습니다." case HSERROR_HSUPDATE_TIMEOUT: strerr = S( 4138 ); break; // "HackShield 업데이트 프로그램이 업데이트 전송 시간을 초과하였습니다." default: strerr = S( 4139 ); break; // "HackShield 업데이트 오류" } strerr = nsl::format( "%s(%d)\n", strerr.c_str(), nResult ); /* if( g_pFLog ) { fprintf( g_pFLog, "%d%s\n", nResult, strerr.c_str() ); fflush( g_pFLog ); } */ MessageBox( g_hWnd, strerr.c_str(), "Rappelz-HackShield", MB_OK | MB_ICONERROR ); return false; } return true; } bool StartHackShieldService() { TCHAR *pEnd = NULL; TCHAR szFullFileName[MAX_PATH] = { 0, }; GetModuleFileName(NULL, szFullFileName, MAX_PATH); pEnd = _tcsrchr( szFullFileName, _T('\\')) + 1; if (!pEnd) { TCHAR strResult[1024]; _sntprintf( strResult, 1024, TEXT("HackShieldService Failed - %s"), szFullFileName ); MessageBox( NULL, strResult, TEXT("Error"), MB_OK | MB_ICONERROR ); return false; } *pEnd = _T('\0'); lstrcat(szFullFileName, _T("HackShield\\EhSvc.dll")); #ifdef 국내 // const int nGameCode = 2802; //Trial // const char* szLicense = "619B435F75BB9AB73733DD71"; //Trial const int nGameCode = 2803; //Commercial const char* szLicense = "4DBC3A48AE1B5DA2FFC82149"; //Commercial #endif #ifdef 미국 const int nGameCode = 2804; const char* szLicense = "1C7DF61A08F7C881CECEBA22"; #endif #ifdef _HONGKONG_ const int nGameCode = 2802; const char* szLicense = "619B435F75BB9AB73733DD71"; #endif #ifdef _JAPAN_ const int nGameCode = 2802; const char* szLicense = "619B435F75BB9AB73733DD71"; #endif #ifdef 중국 const int nGameCode = 2805; const char* szLicense = "33C5A763CA347F50C77820FE"; #endif #ifdef 독일 const int nGameCode = 6912; //Original const char* szLicense = "2422F23A8217FD6E295891A9"; //Original #endif #ifdef 프랑스 const int nGameCode = 6912; //Original const char* szLicense = "2422F23A8217FD6E295891A9"; //Original #endif #ifdef _RELEASE //배포용 옵션 // const DWORD dwOption = AHNHS_CHKOPT_ALL | AHNHS_ALLOW_SVCHOST_OPENPROCESS | AHNHS_ALLOW_LSASS_OPENPROCESS | AHNHS_ALLOW_CSRSS_OPENPROCESS | AHNHS_DISPLAY_HACKSHIELD_LOGO; #ifdef _COUNTRY_CN_ const DWORD dwOption = AHNHS_CHKOPT_READWRITEPROCESSMEMORY \ | AHNHS_CHKOPT_KDTRACER \ | AHNHS_CHKOPT_OPENPROCESS \ | AHNHS_CHKOPT_AUTOMOUSE \ | AHNHS_CHKOPT_PROCESSSCAN \ | AHNHS_CHKOPT_HSMODULE_CHANGE \ | AHNHS_USE_LOG_FILE \ | AHNHS_ALLOW_SVCHOST_OPENPROCESS \ | AHNHS_ALLOW_LSASS_OPENPROCESS \ | AHNHS_ALLOW_CSRSS_OPENPROCESS \ | AHNHS_DONOT_TERMINATE_PROCESS \ | AHNHS_CHKOPT_SPEEDHACK \ | AHNHS_CHKOPT_MESSAGEHOOK; #else const DWORD dwOption = AHNHS_CHKOPT_READWRITEPROCESSMEMORY \ | AHNHS_CHKOPT_KDTRACER \ | AHNHS_CHKOPT_OPENPROCESS \ | AHNHS_CHKOPT_AUTOMOUSE \ | AHNHS_CHKOPT_PROCESSSCAN \ | AHNHS_CHKOPT_HSMODULE_CHANGE \ | AHNHS_USE_LOG_FILE \ | AHNHS_ALLOW_SVCHOST_OPENPROCESS \ | AHNHS_ALLOW_LSASS_OPENPROCESS \ | AHNHS_ALLOW_CSRSS_OPENPROCESS \ | AHNHS_DONOT_TERMINATE_PROCESS \ | AHNHS_DISPLAY_HACKSHIELD_LOGO \ | AHNHS_CHKOPT_MESSAGEHOOK; // SetHook 동작 안 됨. //| AHNHS_CHKOPT_SPEEDHACK 노트북 문제로 제거 되었음. #endif #else //디버깅용 옵션 const DWORD dwOption = AHNHS_CHKOPT_READWRITEPROCESSMEMORY \ | AHNHS_CHKOPT_OPENPROCESS \ | AHNHS_CHKOPT_AUTOMOUSE \ | AHNHS_CHKOPT_MESSAGEHOOK \ | AHNHS_CHKOPT_PROCESSSCAN \ | AHNHS_CHKOPT_HSMODULE_CHANGE \ | AHNHS_USE_LOG_FILE \ | AHNHS_ALLOW_SVCHOST_OPENPROCESS | AHNHS_ALLOW_LSASS_OPENPROCESS | AHNHS_ALLOW_CSRSS_OPENPROCESS | AHNHS_DISPLAY_HACKSHIELD_LOGO; #endif const unsigned int unSHackSensingRatio = AHNHS_SPEEDHACK_SENSING_RATIO_NORMAL; /* if( g_pFLog == NULL ) g_pFLog = fopen( "rappelz_HShield.log", "a+" ); */ int nResult = _AhnHS_Initialize( szFullFileName , _AhnHS_Callback , nGameCode , szLicense , dwOption , unSHackSensingRatio ); if( nResult == HS_ERR_OK ) { // 함수 호출 성공 int nStartSVResult = _AhnHS_StartService(); if( nStartSVResult != HS_ERR_OK ) { std::string strerr; switch( nStartSVResult ) { case HS_ERR_START_ENGINE_FAILED: strerr = S( 4107 ); break; //"해킹 프로그램 감지 엔진을 시작할 수 없습니다."; case HS_ERR_ALREADY_SERVICE_RUNNING: strerr = S( 4108 ); break; //"이미 핵쉴드 서비스가 실행 중입니다."; case HS_ERR_DRV_FILE_CREATE_FAILED: strerr = S( 4109 ); break; //"핵 쉴드 드라이버 파일을 생성할 수 없습니다."; case HS_ERR_REG_DRV_FILE_FAILED: strerr = S( 4110 ); break; //"핵 쉴드 드라이버를 등록할 수 없습니다."; case HS_ERR_START_DRV_FAILED: strerr = S( 4111 ); break; //"핵 쉴드 드라이버를 시작할 수 없습니다."; } /* if( g_pFLog ) { fprintf( g_pFLog, "%d%s\n", nStartSVResult, strerr.c_str() ); fflush( g_pFLog ); } */ MessageBox( g_hWnd, strerr.c_str(), "Rappelz-HackShield", MB_OK | MB_ICONERROR ); return false; } // MessageBox( g_hWnd, "HackShield 성공적으로 수행됨", "HackShield", MB_OK ); g_bStartingHSService = true; } else { std::string strerr; switch( nResult ) { case HS_ERR_UNKNOWN: strerr = S( 4112 ); break; //"알 수 없는 오류가 발생했습니다."; break; //"알 수 없는 오류가 발생했습니다."; case HS_ERR_INVALID_PARAM: strerr = S( 4113 ); break; //"올바르지 않은 인자입니다."; break; //"올바르지 않은 인자입니다."; case HS_ERR_NOT_INITIALIZED: strerr = S( 4114 ); break; //"핵쉴드 모듈이 초기화되지 않은 상태입니다."; break; //"핵쉴드 모듈이 초기화되지 않은 상태입니다."; case HS_ERR_COMPATIBILITY_MODE_RUNNING: strerr = S( 4115 ); break; //"현재 프로세스가 호환성 모드로 실행되었습니다."; break; //"현재 프로세스가 호환성 모드로 실행되었습니다."; case HS_ERR_INVALID_LICENSE: strerr = S( 4116 ); break; //"올바르지 않은 라이센스 키입니다."; break; //"올바르지 않은 라이센스 키입니다."; case HS_ERR_INVALID_FILES: strerr = S( 4117 ); break; //"잘못된 파일 설치되었습니다. 프로그램을 재설치하시기 바랍니다."; break; //"잘못된 파일 설치되었습니다. 프로그램을 재설치하시기 바랍니다."; case HS_ERR_INIT_DRV_FAILED: strerr = S( 4118 ); break; //"해킹 차단 기능 드라이버 초기하에 실패하여 해킹 차단 기능이 정상 동작할 수 없습니다."; break; //"해킹 차단 기능 드라이버 초기하에 실패하여 해킹 차단 기능이 정상 동작할 수 없습니다."; case HS_ERR_ANOTHER_SERVICE_RUNNING: strerr = S( 4119 ); break; //"다른 게임이나 프로세스에서 핵쉴드를 이미 사용하고 있습니다."; break; //"다른 게임이나 프로세스에서 핵쉴드를 이미 사용하고 있습니다."; case HS_ERR_ALREADY_INITIALIZED: strerr = S( 4120 ); break; //"이미 핵쉴드 모듈이 초기화되어 있습니다."; break; //"이미 핵쉴드 모듈이 초기화되어 있습니다."; case HS_ERR_DEBUGGER_DETECT: strerr = S( 4121 ); break; //"컴퓨터에서 디버거 실행이 감지되었습니다. 디버거의 실행을 중지시킨 뒤에 다시 실행시켜주시기바랍니다."; break; //"컴퓨터에서 디버거 실행이 감지되었습니다. 디버거의 실행을 중지시킨 뒤에 다시 실행시켜주시기바랍니다."; case HS_ERR_EXECUTABLE_FILE_CRACKED: strerr = S( 4122 ); break; //"실행 파일의 코드가 크랙 되었습니다."; break; //"실행 파일의 코드가 크랙 되었습니다."; case HS_ERR_NEED_ADMIN_RIGHTS: strerr = S( 4123 ); break; //"ADMIN 권한이 필요합니다."; break; //"ADMIN 권한이 필요합니다."; case HS_ERR_START_ENGINE_FAILED: strerr = S( 4124 ); break; //"해킹 프로그램 감지 엔진을 시작할 수 없습니다."; break; //"해킹 프로그램 감지 엔진을 시작할 수 없습니다."; case HS_ERR_ALREADY_SERVICE_RUNNING: strerr = S( 4125 ); break; //"이미 핵 쉴드 서비스가 실행 중입니다."; break; //"이미 핵 쉴드 서비스가 실행 중입니다."; case HS_ERR_DRV_FILE_CREATE_FAILED: strerr = S( 4126 ); break; //"핵 쉴드 드라이버 파일을 생성할 수 없습니다."; break; //"핵 쉴드 드라이버 파일을 생성할 수 없습니다."; case HS_ERR_REG_DRV_FILE_FAILED: strerr = S( 4127 ); break; //"핵 쉴드 드라이버를 등록할 수 없습니다."; break; //"핵 쉴드 드라이버를 등록할 수 없습니다."; case HS_ERR_START_DRV_FAILED: strerr = S( 4128 ); break; //"핵 쉴드 드라이버를 시작할 수 없습니다."; break; //"핵 쉴드 드라이버를 시작할 수 없습니다."; case HS_ERR_SERVICE_NOT_RUNNING: strerr = S( 4129 ); break; //"핵 쉴드 서비스가 실행되고 있지 않은 상태입니다."; break; //"핵 쉴드 서비스가 실행되고 있지 않은 상태입니다."; case HS_ERR_SERVICE_STILL_RUNNING: strerr = S( 4130 ); break; //"핵 쉴드 서비스가 아직 실행중인 상태입니다."; break; //"핵 쉴드 서비스가 아직 실행중인 상태입니다."; case HS_ERR_NEED_UPDATE: strerr = S( 4131 ); break; //"핵 쉴드 모듈의 업데이트가 필요합니다."; break; //"핵 쉴드 모듈의 업데이트가 필요합니다."; } /* if( g_pFLog ) { fprintf( g_pFLog, "%d%s\n", nResult, strerr.c_str() ); fflush( g_pFLog ); } */ MessageBox( g_hWnd, strerr.c_str(), "Rappelz-HackShield", MB_OK | MB_ICONERROR ); return false; } _AhnHS_SaveFuncAddress( 7, _AhnHS_Callback, StartHackShieldService, WndProc, HotKeyProc, &SGameVM::onReadEvent, &SGameManager::PendMessage, &SGameManager::ReqMove ); return true; } void StopHackShieldService() { _AhnHS_StopService(); _AhnHS_Uninitialize(); } void PauseHackShieldService() { _AhnHS_PauseService( AHNHS_CHKOPT_MESSAGEHOOK ); } void ResumeHackShieldService() { _AhnHS_ResumeService( AHNHS_CHKOPT_MESSAGEHOOK ); } #endif BOOL CALLBACK NPGameMonCallback(DWORD dwMsg, DWORD dwArg) { static bool bDtectCommClose = true; static bool bDtectInitError = true; static bool bDtectSpeedHack = true; static bool bDtectGameHackKilled = true; static bool bDtectGameHackDetect = true; static bool bDtectGamehack_Doubt = true; bool bExitGame = false; GameSecurityMsg::MSG_TYPE msgtype = GameSecurityMsg::MSG_MAX; std::string strHackMsg; switch (dwMsg) { case NPGAMEMON_COMM_ERROR: //GameMon과의 통신 채널이 끊어졌습니다. case NPGAMEMON_COMM_CLOSE: { if( bDtectCommClose ) { msgtype = GameSecurityMsg::MSG_NPROTECT_COMM_CLOSE; bDtectCommClose = false; bExitGame = true; } } break; case NPGAMEMON_INIT_ERROR: //GameMon 실행 에러 { if( bDtectInitError ) { msgtype = GameSecurityMsg::MSG_NPROTECT_INIT_ERROR; bDtectInitError = false; bExitGame = true; XStringUtil::Format( strHackMsg, "게임가드 초기화 에러 : %lu", dwArg ); } } break; case NPGAMEMON_SPEEDHACK: //스피드핵이 감지되었습니다 { if( bDtectSpeedHack ) { msgtype = GameSecurityMsg::MSG_NPROTECT_SPEEDHACK; bDtectSpeedHack = false; bExitGame = true; XStringUtil::Format( strHackMsg, "스피드핵이 감지되었습니다." ); } } break; case NPGAMEMON_GAMEHACK_KILLED: //게임핵이 발견되었습니다 { if( bDtectGameHackKilled ) { msgtype = GameSecurityMsg::MSG_NPROTECT_GAMEHACK_KILLED; bDtectGameHackKilled = false; bExitGame = true; //XStringUtil::Format( strHackMsg, "게임핵이 발견되었습니다.\r\n%s", npgl.GetInfo() ); XStringUtil::Format( strHackMsg, "게임핵이 발견되었습니다.\r\n%s", g_pNpgl->GetInfo() ); } } break; case NPGAMEMON_GAMEHACK_DETECT: //게임핵이 발견되었습니다 { if( bDtectGameHackDetect ) { msgtype = GameSecurityMsg::MSG_NPROTECT_GAMEHACK_DETECT; bDtectGameHackDetect = false; bExitGame = true; XStringUtil::Format( strHackMsg, "게임핵이 발견되었습니다.\r\n%s", g_pNpgl->GetInfo() ); } } break; case NPGAMEMON_GAMEHACK_DOUBT: { if( bDtectGamehack_Doubt ) { msgtype = GameSecurityMsg::MSG_NPROTECT_GAMEHACK_DOUBT; bDtectGamehack_Doubt = false; bExitGame = true; XStringUtil::Format( strHackMsg, "게임이나 게임가드가 변조되었습니다." ); } } break; case NPGAMEMON_GAMEHACK_REPORT: { DWORD dwHackInfoSize = 0; LPBYTE pHackInfo = NULL; pHackInfo = g_pNpgl->GetHackInfo( &dwHackInfoSize ); if( pHackInfo && dwHackInfoSize > 0 ) { //SendToHackLog( pHackInfo, dwHackInfoSiz e); // 서버로 데이터 전송 } } break; case NPGAMEMON_CHECK_CSAUTH2: { GG_AUTH_DATA authData; memcpy(&authData, (PVOID)dwArg, sizeof(authData)); if( g_pSBotMng->GameGuardSendToServer( &authData ) == false ) { /* if( g_pFLog ) { fprintf( g_pFLog, "%s\n", "if( sizeof( TS_CS_GAME_GUARD_AUTH_ANSWER ) != sizeof( GG_AUTH_DATA ) )" ); fflush( g_pFLog ); }*/ } } break; case NPGAMEMON_CHECK_CSAUTH3: { PCSAuth3Data pCSAuth3 = (PCSAuth3Data)dwArg; g_pSBotMng->GameGuardSendToServer( pCSAuth3 ); } break; } if( bExitGame ) { /* if( g_pFLog == NULL ) g_pFLog = fopen( "rappelz_nProtect.log", "a+" ); if( g_pFLog && !strHackMsg.empty() ) { fprintf( g_pFLog, "%s\n", strHackMsg.c_str() ); fflush( g_pFLog ); } */ #ifdef _DEV SLOG("nPROTECT - %s\n", strHackMsg.c_str()); #endif GameSecurityMsg* pSecurityMsg = new GameSecurityMsg; pSecurityMsg->nMsgType = msgtype; pSecurityMsg->nNativeCode = static_cast< unsigned long >( dwMsg ); // sonador 7.4.3 해킹 툴 감지후 종료 프로세스 구현 g_SecurityMsg.push_back( pSecurityMsg ); } return TRUE; } bool StartnProtectService() { DWORD dwResult = g_pNpgl->Init(); if (dwResult != NPGAMEMON_SUCCESS) { std::string strerr; // ‘6. 주요에러코드’를 참조하여 상황에 맞는 메시지를 출력해줍니다. switch (dwResult) { case NPGAMEMON_ERROR_EXIST: strerr = S( 769 ); break; //"게임가드가 실행 중 입니다. 잠시 후나 재부팅 후에 다시 실행해보시기 바랍니다." case NPGAMEMON_ERROR_GAME_EXIST: strerr = S( 770 ); break; //"게임이 중복 실행되었거나 게임가드가 이미 실행 중 입니다. 게임 종료 후 다시 실행해보시기 바랍니다." case NPGAMEMON_ERROR_INIT: { if (GGGetLastError() == 14000) strerr = S( 183 ); // 게임가드에서 가상머신을 차단하였을 때 출력되는 메세지 else strerr = S( 771 ); //"게임가드 초기화 에러입니다. 재부팅 후 다시 실행해보거나 충돌할 수 있는 다른 프로그램들을 종료한 후 실행해 보시기 바랍니다." } break; case NPGAMEMON_ERROR_AUTH_GAMEGUARD: case NPGAMEMON_ERROR_NFOUND_GG: case NPGAMEMON_ERROR_AUTH_INI: case NPGAMEMON_ERROR_CORRUPT_INI: case NPGAMEMON_ERROR_CORRUPT_INI2: case NPGAMEMON_ERROR_NFOUND_INI: strerr = S( 772 ); break; //"게임가드 파일이 없거나 변조되었습니다. 게임가드 셋업 파일을 설치해보시기 바랍니다." case NPGAMEMON_ERROR_CRYPTOAPI: strerr = S( 773 ); break; //"윈도우의 일부 시스템 파일이 손상되었습니다. 인터넷 익스플로러(IE)를 다시 설치해보시기 바랍니다." case NPGAMEMON_ERROR_EXECUTE: strerr = S( 774 ); break; //"게임가드 실행에 실패했습니다. 게임가드 셋업 파일을 다시 설치해보시기 바랍니다." case NPGAMEMON_ERROR_ILLEGAL_PRG: strerr = S( 775 ); break; //"불법 프로그램이 발견되었습니다. 불필요한 프로그램을 종료한 후 다시 실행해보시기 바랍니다." case NPGMUP_ERROR_ABORT: strerr = S( 776 ); break; //"게임가드 업데이트를 취소하셨습니다. 접속이 계속 되지 않을 경우 인터넷 및 개인 방화벽 설정을 조정해 보시기 바랍니다." case NPGMUP_ERROR_CONNECT: // case HOOK_TIMEOUT: strerr = S( 777 ); break; //"바이러스나 스파이웨어로 인해 후킹이 실패하였습니다. 최신백신을 받으신 후 컴퓨터 전체검사를 해봅니다." case NPGAMEMON_ERROR_GAMEGUARD: strerr = S( 778 ); break; //"게임가드 초기화 에러 또는 구버젼의 게임가드 파일입니다. 게임가드 셋업파일을 다시 설치하고 게임을 실행해봅니다." case NPGMUP_ERROR_PARAM: strerr = S( 779 ); break; //"ini 파일이 없거나 변조되었습니다. 게임가드 셋업 파일을 설치하면 해결할 수 있습니다." case NPGMUP_ERROR_INIT: strerr = S( 780 ); break; //"npgmup.des 초기화 에러입니다. 게임가드폴더를 삭제후 다시 게임실행을 해봅니다." case 128: strerr = S( 781 ); break; //"검증되지 않은 Windows XP x64 버전을 실행한 경우입니다. 최신으로 버전으로 설치후 게임실행을 해봅니다." case NPGMUP_ERROR_DOWNCFG: strerr = S( 783 ); break; //"게임가드 업데이트 서버 접속에 실패하였습니다. 잠시 후 재시도 해보거나, 개인 방화벽이 있다면 설정을 조정해 보시기 바랍니다." case NPGMUP_ERROR_AUTH: strerr = S( 784 ); break; //"게임가드 업데이트를 완료하지 못 했습니다. 바이러스 백신을 일시 중시 시킨 후 재시도 해보시거나, PC 관리 프로그램을 사용하시면 설정을 조정해 보시기 바랍니다." case NPGAMEMON_ERROR_NPSCAN: strerr = S( 785 ); break; //"바이러스 및 해킹툴 검사 모듈 로딩에 실패 했습니다. 메모리 부족이거나 바이러스에 의한 감염일 수 있습니다." case NPGG_ERROR_COLLISION: //"게임가드와 충돌 프로그램이 발겫되었습니다." default: { // 적절한 종료 메시지 출력 strerr = S( 791 ); break; //"게임가드 실행 중 에러가 발생하였습니다. 게임 폴더 안의 GameGuard 폴더에 있는 *.erl 파일들을 Game1@inca.co.kr로 첨부하여 메일 보내주시기 바랍니다." } break; } if( g_pFLog == NULL ) g_pFLog = fopen( "rappelz_nProtect.log", "a+" ); if( g_pFLog ) { fprintf( g_pFLog, "%lu %s\n", dwResult, strerr.c_str() ); fflush( g_pFLog ); } #ifdef _DEV SLOG("%lu %s\n", dwResult, strerr.c_str()); #endif strerr = CStringUtil::StringFormat( "err code[%d]:%s", dwResult, strerr.c_str() ); MessageBox( g_hWnd, strerr.c_str(), "Rappelz-nProtect", MB_OK | MB_ICONERROR ); return false; } return true; } typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); BOOL CheckOSVersion() { OSVERSIONINFOEX osvi; SYSTEM_INFO si; PGNSI pGNSI; BOOL bOsVersionInfoEx; ZeroMemory(&si, sizeof(si)); ZeroMemory(&osvi, sizeof(osvi)); // Try calling GetVersionEx using the OSVERSIONINFOEX structure. // If that fails, try using the OSVERSIONINFO structure. osvi.dwOSVersionInfoSize = sizeof(osvi); if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) ) { osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) ) return FALSE; } // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise. pGNSI = (PGNSI) GetProcAddress( GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo"); if(NULL != pGNSI) pGNSI(&si); else GetSystemInfo(&si); switch (osvi.dwPlatformId) { // Test for the Windows NT product family. case VER_PLATFORM_WIN32_NT: // Test for the specific product. // windows vista, windows 7 OS일 경우 bold 태그 예외를 둔다. // 일본 시스템 메세지 깨짐 문제 수정. kappamind, 2010.01.21 // if ( ( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0 ) || // ( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1 ) // ) if( ( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion >= 0 ) ) //gmpbigsun(20130617) : window vista, 7, 8 { if( osvi.wProductType == VER_NT_WORKSTATION ) { KTextRender::SetOSandLocale( true, ENV().GetString( "locale", "CP949" ).c_str() ); _performance_print("Windows Vista or 7 or 8 "); } else _performance_print ("Windows Server \"Longhorn\" " ); } if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 ) { #if(_WIN32_WINNT >= 0x0501) if( GetSystemMetrics(SM_SERVERR2) ) printf( "Microsoft Windows Server 2003 \"R2\" "); else if( osvi.wProductType == VER_NT_WORKSTATION && si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) { printf( "Microsoft Windows XP Professional x64 Edition "); } else printf ("Microsoft Windows Server 2003, "); #endif /* _WIN32_WINNT >= 0x0501 */ } if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 ) _performance_print ("Microsoft Windows XP "); if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 ) _performance_print ("Microsoft Windows 2000 "); if ( osvi.dwMajorVersion <= 4 ) _performance_print ("Microsoft Windows NT "); // Test for specific product on Windows NT 4.0 SP6 and later. if( bOsVersionInfoEx ) { // Test for the workstation type. if ( osvi.wProductType == VER_NT_WORKSTATION && si.wProcessorArchitecture!=PROCESSOR_ARCHITECTURE_AMD64) { if( osvi.dwMajorVersion == 4 ) _performance_print ( "Workstation 4.0 " ); else if( osvi.wSuiteMask & VER_SUITE_PERSONAL ) _performance_print ( "Home Edition " ); else _performance_print ( "Professional " ); } // Test for the server type. else if ( osvi.wProductType == VER_NT_SERVER || osvi.wProductType == VER_NT_DOMAIN_CONTROLLER ) { if(osvi.dwMajorVersion==5 && osvi.dwMinorVersion==2) { if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64 ) { if( osvi.wSuiteMask & VER_SUITE_DATACENTER ) _performance_print ( "Datacenter Edition for Itanium-based Systems" ); else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) _performance_print ( "Enterprise Edition for Itanium-based Systems" ); } else if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 ) { if( osvi.wSuiteMask & VER_SUITE_DATACENTER ) _performance_print ( "Datacenter x64 Edition " ); else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) _performance_print ( "Enterprise x64 Edition " ); else _performance_print( "Standard x64 Edition " ); } else { if( osvi.wSuiteMask & VER_SUITE_DATACENTER ) _performance_print ( "Datacenter Edition " ); else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) _performance_print ( "Enterprise Edition " ); else if ( osvi.wSuiteMask & VER_SUITE_BLADE ) _performance_print ( "Web Edition " ); else _performance_print ( "Standard Edition " ); } } else if(osvi.dwMajorVersion==5 && osvi.dwMinorVersion==0) { if( osvi.wSuiteMask & VER_SUITE_DATACENTER ) _performance_print ( "Datacenter Server " ); else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) _performance_print ( "Advanced Server " ); else _performance_print ( "Server " ); } else // Windows NT 4.0 { if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) _performance_print ("Server 4.0, Enterprise Edition " ); else _performance_print ( "Server 4.0 " ); } } } // Test for specific product on Windows NT 4.0 SP5 and earlier else { HKEY hKey; TCHAR szProductType[BUFSIZE]; DWORD dwBufLen = sizeof( szProductType ); LONG lRet; lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\ProductOptions"), 0, KEY_QUERY_VALUE, &hKey ); if( lRet != ERROR_SUCCESS ) return FALSE; lRet = RegQueryValueEx( hKey, TEXT("ProductType"), NULL, NULL, (LPBYTE) szProductType, &dwBufLen); RegCloseKey( hKey ); if( (lRet != ERROR_SUCCESS) || (dwBufLen > sizeof( szProductType )) ) return FALSE; if ( lstrcmpi( TEXT("WINNT"), szProductType) == 0 ) _performance_print( "Workstation " ); if ( lstrcmpi( TEXT("LANMANNT"), szProductType) == 0 ) _performance_print( "Server " ); if ( lstrcmpi( TEXT("SERVERNT"), szProductType) == 0 ) _performance_print( "Advanced Server " ); _performance_print( "%d.%d ", osvi.dwMajorVersion, osvi.dwMinorVersion ); } // Display service pack (if any) and build number. if( osvi.dwMajorVersion == 4 && lstrcmpi( osvi.szCSDVersion, TEXT("Service Pack 6") ) == 0 ) { HKEY hKey; LONG lRet; // Test for SP6 versus SP6a. lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Hotfix\\Q246009"), 0, KEY_QUERY_VALUE, &hKey ); if( lRet == ERROR_SUCCESS ) _performance_print( "Service Pack 6a (Build %d)\n", osvi.dwBuildNumber & 0xFFFF ); else // Windows NT 4.0 prior to SP6a { _performance_print( TEXT("%s (Build %d)\n"), osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF); } RegCloseKey( hKey ); } else // not Windows NT 4.0 { _performance_print( TEXT("%s (Build %d)\n"), osvi.szCSDVersion, osvi.dwBuildNumber & 0xFFFF ); } break; // Test for the Windows Me/98/95. case VER_PLATFORM_WIN32_WINDOWS: if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0) { _performance_print ("Microsoft Windows 95 "); if (osvi.szCSDVersion[1]=='C' || osvi.szCSDVersion[1]=='B') _performance_print("OSR2 " ); } if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10) { _performance_print ("Microsoft Windows 98 "); if ( osvi.szCSDVersion[1]=='A' || osvi.szCSDVersion[1]=='B') _performance_print("SE " ); } if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90) { _performance_print ("Microsoft Windows Millennium Edition\n"); } break; case VER_PLATFORM_WIN32s: _performance_print ("Microsoft Win32s\n"); break; } return TRUE; } // 젠장-_-; /// 2010.11.11 - prodongi void _getModulePath() { _setmaxstdio( 512 ); { TCHAR *pEnd = NULL; TCHAR szFullFileName[MAX_PATH] = { 0, }; GetModuleFileName(NULL, szFullFileName, MAX_PATH); pEnd = _tcsrchr( szFullFileName, _T('\\')) + 1; if (!pEnd) { //에러 } else { *pEnd = _T('\0'); SetCurrentDirectory(szFullFileName); lstrcat(szFullFileName, _T("cam") ); g_strModulePath = szFullFileName; DWORD dwAttr = GetFileAttributes( g_strModulePath.c_str() ); if( INVALID_FILE_ATTRIBUTES == dwAttr ) { CreateDirectory( g_strModulePath.c_str(), NULL ); } } } } /// 2010.11.11 - prodongi #ifdef _HACK_SHIELD_ void startHackShieldService() { // sonador 7.4.4 핵쉴드 270 적용 if( !UpdateHackShieldService() ) { SLOG("Hackshield Update Failed!"); GetLog().OutputFile(LOGFILE_NAME); return 0; } if( !StartHackShieldService() ) { StopHackShieldService(); SLOG("Hackshield Start Failed!"); GetLog().OutputFile(LOGFILE_NAME); return 0; } //빌드용 if( ENV().IsExist( "crcbuild" ) ) { StopHackShieldService(); GetLog().OutputFile(LOGFILE_NAME); return 0; } } #endif bool _startNProtectService() { int nLocalBitSet = GameRule::GetCurrentLocalBitSet(); if( nLocalBitSet == GameRule::LOCAL_BITSET::KR ) { g_pNpgl = new CNPGameLib( getNProtectIniFileName( "RappelzKR" ) ); } else if( nLocalBitSet == GameRule::LOCAL_BITSET::DE || nLocalBitSet == GameRule::LOCAL_BITSET::FR || nLocalBitSet == GameRule::LOCAL_BITSET::IT || nLocalBitSet == GameRule::LOCAL_BITSET::PL ) { g_pNpgl = new CNPGameLib( "RappelzGB" ); } else if( nLocalBitSet == GameRule::LOCAL_BITSET::TR) { g_pNpgl = new CNPGameLib( "RappelzTR" ); } else if( nLocalBitSet == GameRule::LOCAL_BITSET::RU) { g_pNpgl = new CNPGameLib( getNProtectIniFileName( "RappelzRU" ) ); } else if( nLocalBitSet == GameRule::LOCAL_BITSET::ID) { g_pNpgl = new CNPGameLib( "RappelzID" ); } else if( nLocalBitSet == GameRule::LOCAL_BITSET::US) { g_pNpgl = new CNPGameLib( "RappelzUS" ); } else if( nLocalBitSet == GameRule::LOCAL_BITSET::ME) { g_pNpgl = new CNPGameLib( getNProtectIniFileName( "RappelzDU" ) ); } if( g_pNpgl == NULL ) { return true; } if( !StartnProtectService() ) { delete g_pNpgl; g_pNpgl = NULL; SLOG("NProtect Start Failed!"); GetLog().OutputFile(LOGFILE_NAME); return false; } return true; } bool _checkDoubleExecute(HANDLE& hMutex) { hMutex = CreateMutex(NULL, TRUE, "Global\\wbc_sbc"); DWORD dwLastError = GetLastError(); if(dwLastError==ERROR_ALREADY_EXISTS || dwLastError==ERROR_ACCESS_DENIED ) { std::string strErr; XStringUtil::Format( strErr, "Execute Error %d", dwLastError ); MessageBox( 0, strErr.c_str(), "Rappelz-Error", MB_OK ); SLOG("Duplicate Execute Error!"); GetLog().OutputFile(LOGFILE_NAME); return false; } return true; } //#endif bool _isValidDxVersion() { //DX 버전 검사 HRESULT hr; TCHAR strResult[128]; union { DWORD dwDirectXVersion; char cVersion[4]; } DXVERSION; TCHAR strDirectXVersion[10]; TCHAR cDXVerLetter; cDXVerLetter = ' '; hr = GetDXVersion( &DXVERSION.dwDirectXVersion, strDirectXVersion, 10, cDXVerLetter ); _oprint( "DX %d.%d(%c) [%s]\n", DXVERSION.cVersion[2], DXVERSION.cVersion[1], cDXVerLetter, strDirectXVersion ); if( SUCCEEDED(hr) ) { if( DXVERSION.dwDirectXVersion > 0 ) { //9.0c 보다 낮으면 실행 안됨 if( ( DXVERSION.cVersion[2] < 9 ) || ( DXVERSION.cVersion[2] == 9 && DXVERSION.cVersion[1] == 0 && cDXVerLetter < 'c' ) ) { _sntprintf( strResult, 128, TEXT("DirectX %s installed\n Need DirectX 9.0c or higher"), strDirectXVersion ); strResult[127] = 0; MessageBox( NULL, strResult, TEXT("Rappelz-DirectX Version:"), MB_OK | MB_ICONINFORMATION ); // 다른 나라도 지원되게 해야함. // DialogBox(hInstance, MAKEINTRESOURCE(IDD_DOWN_BOX), NULL, About); SLOG("Too low DirectX Version!"); GetLog().OutputFile(LOGFILE_NAME); return false; } } else { _tcsncpy( strResult, TEXT("DirectX not installed"), 128 ); strResult[127] = 0; MessageBox( NULL, strResult, TEXT("Rappelz-DirectX Version:"), MB_OK | MB_ICONINFORMATION ); // 다른 나라도 지원되게 해야함. // DialogBox(hInstance, MAKEINTRESOURCE(IDD_DOWN_BOX), NULL, About); SLOG("DirectX file missed!"); GetLog().OutputFile(LOGFILE_NAME); return false; } } else { _sntprintf( strResult, 128, TEXT("Unknown version of DirectX installed") ); strResult[127] = 0; MessageBox( NULL, strResult, TEXT("Rappelz-DirectX Version:"), MB_OK | MB_ICONINFORMATION ); // 다른 나라도 지원되게 해야함. // DialogBox(hInstance, MAKEINTRESOURCE(IDD_DOWN_BOX), NULL, About); SLOG("Unknown Version of DirectX Detected!"); GetLog().OutputFile(LOGFILE_NAME); return false; } return true; } void _setDebugFlag() { /*int tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); // 현재 플래그 얻음. // tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF; // Leak 체크 플래그 추가 //tmpDbgFlag |= _CRTDBG_DELAY_FREE_MEM_DF; // 블럭들을 실제로 해제하지 않는 플래그 추가. //tmpDbgFlag |= _CRTDBG_CHECK_ALWAYS_DF; // alloc/dealloc에 대해 메모리 점검 수행 플래그 추가. // _CrtSetDbgFlag(tmpDbgFlag); // 새로운 플래그 설정. */ // http://msdn.microsoft.com/ko-kr/library/x98tx3cf(VS.80).aspx // _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); // _CrtSetBreakAlloc(8761666); // 8761637 // 740312 } bool _isValidResolution() { // 2010.07.12 최저 해상도 체크(최저 해상도 수치가 define 된게 없다,,)- prodongi UINT minWidth = 1024; UINT minHeight = (GameRule::isSoutheastAsia()) ? 720 : 768; if (minWidth > GetGameOption().GetResolution_Width() || minHeight > GetGameOption().GetResolution_Height()) { char msg[MAX_PATH]; sprintf(msg, "The minimum resolution is %d x %d", minWidth, minHeight); MessageBox( 0, msg, "Error", MB_OK|MB_ICONINFORMATION ); return false; } return true; } void _setTitle() { if(GameRule::GetCurrentLocalBitSet() == GameRule::LOCAL_BITSET::KR) { if( ENV().IsExist( "main_server" ) ) { strcpy( szTitle, "Rappelz" ); } else { strcpy( szTitle, "Rappelz - Test Server" ); } } else { strcpy( szTitle, "Rappelz" ); } } void _parsingLocaleInfo() { if(GetLocaleOption().parsingOptionFile("localeinfo.ini") == false) { MessageBox(NULL, "'localeinfo' File Not Found","error", MB_OK); } } #ifndef _COUNTRY_ME_ // sonador #2.4.10.2 bool _setLocaleFontInfo() { //------------------------------------------ // 멀티폰트 적용. // FONT_01 KTextRender::AddFreeTypeFont( KTextRender::KDEFAULT_FONT_01, GetLocaleOption().GetValueString("font_01", "NanumGothic.otf") ); // FONT_02 KTextRender::AddFreeTypeFont( KTextRender::KDEFAULT_FONT_02, GetLocaleOption().GetValueString("font_02", "NanumGothicExtraBold.otf") ); // 2010.08.26 - prodongi KTextRender::AddFreeTypeFont( KTextRender::KDEFAULT_FONT_03, GetLocaleOption().GetValueString("font_03", "NanumMyungjo.otf") ); // Default /// 2010.11.09 font_default가 설정 안되어 있을 경우에 Tahoma.ttf를 읽도록 한다 - prodongi if( !KTextRender::AddFreeTypeFont( KTextRender::KDEFAULT_FONT_NAME, GetLocaleOption().GetValueString("font_default", "Tahoma.ttf") ) ) { //에러메시지.. MessageBox( g_hWnd, "Fontfile not found", "Rappelz-Error", MB_ICONERROR|MB_OK ); return false; } /// 2010.11.05 - prodongi if( !KTextRender::AddFreeTypeFont( KTextRender::KDEFAULT_FONT_NAME2, GetLocaleOption().GetValueString("font_default", "Tahoma.ttf") ) ) { //에러메시지.. MessageBox( g_hWnd, "Fontfile not found", "Rappelz-Error", MB_ICONERROR|MB_OK ); return false; } KTextRender::SetFontHinting( KTextRender::KDEFAULT_FONT_NAME, GetLocaleOption().GetValueInt( "FONT_DEFAULT_HINTING", 0 ) ); KTextRender::SetFontHinting( KTextRender::KDEFAULT_FONT_01, GetLocaleOption().GetValueInt( "FONT_01_HINTING", 0 ) ); KTextRender::SetFontHinting( KTextRender::KDEFAULT_FONT_02, GetLocaleOption().GetValueInt( "FONT_02_HINTING", 0 ) ); KTextRender::SetFontHinting( KTextRender::KDEFAULT_FONT_03, GetLocaleOption().GetValueInt( "FONT_03_HINTING", 0 ) ); return true; } #endif void _initEmoticonList() { KTextEmoticonRender::SetSprName( "ui_frame.spr" ); //이모티콘 리스트 초기화 for( int i(0); c_nEmoticonCnt>i; i++ ) { KTextEmoticonRender::AddFilter( g_szEmoticonFilter[i], g_szAniName[i] ); #ifdef _COUNTRY_ME_ KTextParser::AddEmoticonFilter( g_szEmoticonFilter[i], g_szAniName[i] );// KUIControl_ME는 KTextParser을 통해 이모티콘을 필터링함. #endif } } void _setEditBoxFontTag() { for( int i(0); c_nFontTagCnt>i; i++ ) { CEditBoxInfo::AddClipException( g_szFontTag[i], ">" ); } } void _initGuildIcon() { TCHAR DirBuffer[BUFSIZE]; DWORD dwBufLen = sizeof(DirBuffer); DWORD dwRet; dwRet = GetCurrentDirectory( dwBufLen, DirBuffer ); if( dwRet == 0 ) { std::string strErr = CStringUtil::StringFormat( "GetCurrentDirectory failed (%d)\n", GetLastError() ); MessageBox( g_hWnd, strErr.c_str(), "Rappelz-Error", MB_ICONERROR|MB_OK ); } else { g_strGuildFullDir = DirBuffer; g_strGuildFullDir += "\\Guild_Icon\\"; //길드 아이콘 리소스 폴더 추가 static KStdioFileSystem _guild_icon; //길드 아이콘 폴더 생성 strcpy( DirBuffer, "Guild_Icon" ); if( !CreateDirectory( DirBuffer, NULL ) ) { DWORD dwErr = GetLastError(); if( dwErr == ERROR_ALREADY_EXISTS ) { _guild_icon.Init( g_strGuildFullDir.c_str() ); KFileManager::Instance().AddResourceSource( &_guild_icon ); } else if( dwErr == ERROR_PATH_NOT_FOUND ) { std::string strErr = CStringUtil::StringFormat( "CreateDirectory failed (%d)\n", GetLastError() ); MessageBox( g_hWnd, strErr.c_str(), "Rappelz-Error", MB_ICONERROR|MB_OK ); } } else { _guild_icon.Init( g_strGuildFullDir.c_str() ); KFileManager::Instance().AddResourceSource( &_guild_icon ); } } } void _initCom() { //// Explorer // Instantiate a browser HRESULT hrCoInit = CoInitialize(NULL); g_bCleanupCOM = SUCCEEDED(hrCoInit); } void _initAtlModule(CComModule& _Module) { //CComModule _Module; HRESULT hrModule = _Module.Init(NULL, g_hInstance, &LIBID_ATLLib); if( hrModule != S_OK ) { assert(0); } AtlAxWinInit(); } void _initBotManager(HWND hWnd, HINSTANCE hInstance) { g_pSBotMng = new SBotManager( hWnd, hInstance ); SBotManager::m_pBotThis = g_pSBotMng; } void _initBotManagerUIScript() { if( g_pSBotMng->GetCurBot() ) g_pSBotMng->GetCurBot()->InitializeScriptForGameUI(); } void _mainLoop(MSG& msg) { DWORD dwOldTime = GetSafeTickCount(); DWORD dwRealTime = 0; DWORD dwPrevFileManagerProcTime = 0; DWORD dwCursorAniTime = 0; char pszClassName[256]; pszClassName[_countof(pszClassName) - 1] = '\0'; while (1) { int t = PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ); if ( t ) { if ( GetMessage( &msg, NULL, 0, 0 ) == FALSE ) break; if( g_IsShowWebBrowser ) { if(msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST) { GetClassName(msg.hwnd, pszClassName, _countof( pszClassName )); if(strcmp(pszClassName, "Internet Explorer_Server") == 0) { SendMessage(g_hWnd, msg.message, msg.wParam, msg.lParam); } } if( g_bServerListFocus && msg.message == WM_KEYDOWN && msg.wParam == VK_RETURN ) { SendMessage(g_hWnd, msg.message, msg.wParam, msg.lParam); } } // [sonador] Replacing keyboard hooking with WM messages #if !defined( _USE_KEYBOARD_HOOK ) if( !::HotKeyProc( msg.hwnd, msg.message, msg.wParam, msg.lParam ) ) { #endif TranslateMessage(&msg); DispatchMessage(&msg); #if !defined( _USE_KEYBOARD_HOOK ) } #endif } else { // For this to be possible, it is necessary to store synchronized time. // Screenshots are taken at that synchronized time. // I am thinking that each message is stored separately and used at the synchronized time... dwRealTime = GetSafeTickCount(); // If processing & rendering consume too much CPU, thread loading can be delayed. // So, if something is being loaded in a thread, we give it a suitable Sleep(). //if( KThreadResource::GetPendingWork() ) Sleep( 0 ); { { DWORD dwTm = GetSafeTickCount(); if( !g_SecurityMsg.empty() ) { if( g_dwhkTime == 0 ) g_dwhkTime = dwTm; if( dwTm - g_dwhkTime > 5000 ) { g_dwhkTime = dwTm; if( g_pSBotMng->GetCurBot() && g_pSBotMng->GetCurBot()->GetActiveGame() ) { GameSecurityMsg* pSecurityMsg = g_SecurityMsg[0]; g_pSBotMng->ProcSecurityMsg( pSecurityMsg ); g_SecurityMsg.erase( g_SecurityMsg.begin() ); } } } #ifdef _HACK_SHIELD_ if( g_bCheckHook ) { if( g_dwKeyResumeTime == 0 ) g_dwKeyResumeTime = dwTm; // If nothing is done for about 3 minutes, it becomes active again if( dwTm - g_dwKeyResumeTime > 180000 ) { if( g_bAhnHS ) SetWindowText( g_hWnd, "_AhnHS_ResumeService( AHNHS_CHKOPT_MESSAGEHOOK )" ); g_dwKeyResumeTime = 0; g_bCheckHook = false; _AhnHS_ResumeService( AHNHS_CHKOPT_MESSAGEHOOK ); } } #endif if( g_bConnGameMon && g_pNpgl != NULL ) { if( g_dwCheckGameMon == 0 ) g_dwCheckGameMon = dwTm; if( dwTm - g_dwCheckGameMon > 30000 ) { //if (npgl.Check() != NPGAMEMON_SUCCESS) if( g_pNpgl->Check() != NPGAMEMON_SUCCESS ) { GameSecurityMsg* pSecurityMsg = new GameSecurityMsg; pSecurityMsg->nMsgType = GameSecurityMsg::MSG_NPROTECT_COMM_CLOSE; g_SecurityMsg.push_back( pSecurityMsg ); g_bConnGameMon = false; } } } // Main Process function g_pSBotMng->Process(); dwTm = GetSafeTickCount() - dwTm; if( dwTm > 300 ) { _oprint( "CAUTION: Process time: %d !!!!!!\n", dwTm ); } } { DWORD dwTm = GetSafeTickCount(); g_pSBotMng->Render(); dwTm = GetSafeTickCount() - dwTm; if( dwTm > 300 ) { _oprint( "CAUTION: Render time: %d !!!!!!\n", dwTm ); } } { // Every 1 minute, check if there is any stream cache to discard and delete it if( dwPrevFileManagerProcTime + 6000 < dwRealTime ) { KFileManager::Instance().RemoveUnnecessaryStream(); dwPrevFileManagerProcTime = dwRealTime; } } } g_dwCount++; g_dwFPSTime += dwRealTime - dwOldTime; dwCursorAniTime += dwRealTime - dwOldTime; if(g_dwFPSTime >= 1000) { float fTime = (float)g_dwFPSTime / 1000.0f; g_dwFPS = DWORD( (float)g_dwCount / fTime ); if( g_bWindowFPS ) { sprintf( szFPS, "FPS : %d", g_dwFPS ); SetWindowText( g_hWnd, szFPS ); } g_dwFPSTime = 0; g_dwCount = 0; } dwOldTime = dwRealTime; // _oprint( "%d\n", GetArTime() ); } } } void _saveLogStringRate() { /// g_StringOccurMap는 언제 클리어 해주나? - prodongi if( g_bLogStringRate ) { extern std::map< int, int > g_StringOccurMap; FILE *fp = fopen( "string_occur_rate.txt", "w" ); std::map< int, int >::iterator it; for( it = g_StringOccurMap.begin(); it != g_StringOccurMap.end(); ++it ) { fprintf( fp, "%d\t%d\n", it->first, it->second ); } fclose( fp ); } } #ifdef _DEBUG /// 2010.11.12 - prodongi void _saveMemAllocCount() { FILE *fp = fopen( "mem_alloc.txt", "w" ); for( int i = 0; i < 128; ++i ) { fprintf( fp, "%3d\t%d\n", i, g_nMemAllocCnt[i] ); } fclose( fp ); } #endif void _clearWebBrowser() { if( g_pWebBrowser ) { CloseWebBrowser( g_pWebBrowser ); g_pWebBrowser = NULL; } } void _clearMain(HANDLE& hMutex, CComModule* _Module) { #ifdef _HACK_SHIELD_ StopHackShieldService(); #endif if( hMutex != NULL ) { ReleaseMutex(hMutex); CloseHandle(hMutex); } /// 2010.11.12 - prodongi _saveLogStringRate(); /* if( g_bLogStringRate ) { extern std::map< int, int > g_StringOccurMap; FILE *fp = fopen( "string_occur_rate.txt", "w" ); std::map< int, int >::iterator it; for( it = g_StringOccurMap.begin(); it != g_StringOccurMap.end(); ++it ) { fprintf( fp, "%d\t%d\n", it->first, it->second ); } fclose( fp ); } */ #ifdef _DEBUG /// 2010.11.12 - prodongi _saveMemAllocCount(); /* FILE *fp = fopen( "mem_alloc.txt", "w" ); for( int i = 0; i < 128; ++i ) { fprintf( fp, "%3d\t%d\n", i, g_nMemAllocCnt[i] ); } fclose( fp ); */ #endif KFileManager::Instance().RemoveAllStream(); // if( g_hWnd_Dlg ) DestroyWindow( g_hWnd_Dlg ); // /// 2010.11.12 - prodongi _clearWebBrowser(); /* if( g_pWebBrowser ) { CloseWebBrowser( g_pWebBrowser ); g_pWebBrowser = NULL; } */ if( g_pFLog ) fclose( g_pFLog ); DeleteAllWebBrowserInfo(); SAFE_DELETE( g_pSBotMng ); LUA()->DeInit(); #ifdef _USE_KEYBOARD_HOOK UnhookWindowsHookEx( g_hKeyBoardHook ); #endif // 2010.06.17 - prodongi delKeyboardHook(); #ifdef _EXCEPTION_PROCESS EndExceptionHandler(); #endif // rdb 몇가지는 미리 로드 //::GetSkillDB().Clear(); //::GetSkillStageDB().Clear(); //::GetCharacterMotionEventDB().Clear(); //::GetMotionEventHanderDB().Clear(); //::GetMotionFxSetDB().Clear(); //::GetMotionSetDB().Clear(); //::GetTenacityDB().Clear(); //::GetStringDB().Clear(); //::GetItemDB().Clear(); //::GetDefaultItemDB().Clear(); //::GetAbuseDB().Clear(); // _CrtCheckMemory(); // 메모리 체크 결과를 보여줌. //#ifdef _DEBUG // _CrtDumpMemoryLeaks(); // 메모리 Leak 체크 결과를 보여줌. //#endif #ifdef _EXPLORER_ AtlAxWinTerm(); if (_Module) _Module->Term(); #endif nsl::uni::deinit(); if( g_bCleanupCOM ) CoUninitialize(); #ifdef _WEB_DISP_MODE RestoreDisplay(); #endif if (g_pNpgl != NULL) { delete g_pNpgl; g_pNpgl = NULL; } GetLog().OutputFile(LOGFILE_NAME); } void _deleteSGObj( ) { SAFE_DELETE( SBanWordDB::m_pThis ); SAFE_DELETE( SStringDB::m_pThis ); SAFE_DELETE( SItemReferenceDB::m_pThis ); SAFE_DELETE( SItemDB::m_pThis ); SAFE_DELETE( SNpcResourceDB::m_pThis ); SAFE_DELETE( SMonsterDB::m_pThis ); SAFE_DELETE( SPetDB::m_pThis ); SAFE_DELETE( SCreatureDB::m_pThis ); SAFE_DELETE( SCreatureEnhanceDB::m_pThis ); SAFE_DELETE( SCreatureFarmDB::m_pThis ); SAFE_DELETE( SSkillDB::m_pThis ); //10 SAFE_DELETE( STenacityDB::m_pThis ); SAFE_DELETE( SQuestDB::m_pThis ); SAFE_DELETE( SQuestLinkDB::m_pThis ); SAFE_DELETE( SCombineDB::m_pThis ); SAFE_DELETE( SDecomposeDB::m_pThis ); SAFE_DELETE( SItemEffectResourceDB::m_pThis ); SAFE_DELETE( SDefaultTextureResourceDB::m_pThis ); SAFE_DELETE( SDefaultTextureIconResourceDB::m_pThis ); SAFE_DELETE( SMixCategoryDB::m_pThis ); //20 //SAFE_DELETE( SEnhanceFXDB::m_pThis ); SAFE_DELETE( SExpDB::m_pThis ); SAFE_DELETE( SFieldPropResourceDB::m_pThis ); SAFE_DELETE( SMotionSetDB::m_pThis ); SAFE_DELETE( SWorldLocationDB::m_pThis ); SAFE_DELETE( SLowQualityWaterDB::m_pThis ); SAFE_DELETE( SBattleArenaBeginAreaDB::m_pThis ); SAFE_DELETE( SResourceDB::m_pThis ); SAFE_DELETE( SLocalCommandDB::m_pThis ); SAFE_DELETE( STitleDB::m_pThis ); //30 SAFE_DELETE( SJobDB::m_pThis ); SAFE_DELETE( SHuntaHolicResourceDB::m_pThis ); SAFE_DELETE( SDungeonResourceDB::m_pThis ); SAFE_DELETE( SMonsterMotionSetDB::m_pThis ); SAFE_DELETE( SCharacterMotionDB::m_pThis ); SAFE_DELETE( SMotionEventHanderDB::m_pThis ); SAFE_DELETE( SMotionFxSetDB::m_pThis ); SAFE_DELETE( SMonstarCreatureDB::m_pThis ); //SAFE_DELETE( SEnhanceEffectDB::m_pThis ); }