Files
2026-06-01 12:46:52 +02:00

5386 lines
147 KiB
C++

// 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 <vld/vld.h>
//#pragma message( ">>>>>>VLD is activated<<<<<" )
//#include "Windows.h"
//#include <stdio.h>
#include "SFrame.h"
#include "w32_util.h"
#include "SBotManager.h"
#include "LuaVM.h"
#include "SGameScript.h"
#include "SBotScript.h"
#include "SSystemScript.h"
#include <kfile/KRealFileSystem.h>
#include <kfile/XFileBasedFS.h>
#include <kfile/KFileNameCipher.h>
#include <kfile/KOldEncodedFS.h>
#include <kfile/KPackingFileSystem.h>
#include <toolkit/XMemoryPool.h>
#include <toolkit/c_unimempool.h>
#include <mmo/ArTime.h>
#include "SSkillDB.H"
#include "SMotionDB.H"
#include "STenacityDB.H"
#include "SItemDB.h"
#include "GameUrlDefine.h"
#include "KUIWndManager.h"
#include "KUIWnd.h"
#include <dump/XExceptionHandler.h>
#include <toolkit/XModuleInfo.h>
#include <toolkit/XEnv.h>
#include <toolkit/XFileUtil.h>
#include <kfile/KFileManager.h>
#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 <toolkit/nsl.h>
#include <toolkit/nsluni.h>
#include <toolkit/nslreg.h>
#include "SStringDB.h"
#include "SLocalCommandDB.h"
#include <internet/XInternet.h>
//#include "Util.h"
#include "CEditBoxInfo.h"
#include <exdisp.h>
#include <comutil.h>
#include <mshtmhst.h>
#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 <network/XNetworkUtil.h>
#include <toolkit/XVerifyProcessSigner.h>
#include <toolkit/XThread.h>
#include <internal_render_include.h>
#include <internal_utility_include.h>
#include <external_lib_include.h>
//#include <crtdbg.h>
//#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 <xtrap/090628_513_Xtrap_C_Interface.h>
#include <xtrap/090109_009_XTrap4Launcher.h>
#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 <hack_shield/HShield.h>
#include <hack_shield/HSUpChk.h> // 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 <game_guard/NPGameLib.h>
//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 <Iphlpapi.h>
#include <assert.h>
#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 <atlbase.h>
#include <atlcom.h>
#include <atlhost.h>
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<IWebBrowser2> 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<IUnknown> 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<std::string> 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 <toolkit/XStringUtil.h>
volatile int m_nDummyInt = 0;
// For now, only handle two
const short c_nFontTagCnt = 68;
const char* g_szFontTag[] =
{
"<FONT:>" ,//01
"<#" ,//02
"<BR>" ,//03
"<P>" ,//04
"<$L>" ,//05
"<$>" ,//06
"<B>" ,//07
"</B>" ,//08
"<U>" ,//09
"</U>" ,//10
"<STRIKE>" ,//11
"</STRIKE>",//12
"<INV>" ,//13
"</INV>" ,//14
"<SHD>" ,//15
"</SHD>" ,//16
"<%%>" ,//17
"<%>" ,//18
"<SIZE:>" ,//19
"<LEFT>" ,//20
"<TOP>" ,//21
"<RIGHT>" ,//22
"<BOTTOM>" ,//23
"<HCENTER>",//24
"<VCENTER>",//25
"<OUT>" ,//26
"</OUT>" ,//27
"<GLOW>" ,//28
"</GLOW>" ,//29
"<SHADOW>" ,//30
"</SHADOW>",//31
"<@>" ,//32
"<2XGLOW>" ,//33
"</2XGLOW>",//34
"<OFFSET>" ,//35
"<size:>" ,//36
"<font:>" ,//37
"<p>" ,//38
"<$l>" ,//39
"<$>" ,//40
"<b>" ,//41
"</b>" ,//42
"<u>" ,//43
"</u>" ,//44
"<strike>" ,//45
"</strike>",//46
"<inv>" ,//47
"</inv>" ,//48
"<shd>" ,//49
"</shd>" ,//50
"<left>" ,//51
"<top>" ,//52
"<right>" ,//53
"<bottom>" ,//54
"<hcenter>",//55
"<vcenter>",//56
"<out>" ,//57
"</out>" ,//58
"<glow>" ,//59
"</glow>" ,//60
"<shadow>" ,//61
"</shadow>",//62
"<2xglow>" ,//63
"</2xglow>",//64
"<offset>" ,//65
"<bR>" ,//66
"<Br>" ,//67
"<br>" ,//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, &timestamp );
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 = "<WB>";
#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<IOleInPlaceActiveObject, &IID_IOleInPlaceActiveObject> 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<SGameWorld*>(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<int>(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<int>(p)))
// g_leakChecker.erase(reinterpret_cast<int>(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 );
}