SimpleROHook Source Code Overview

2015年4月20日

SimpleROHook Source Code Overview

体調との折り合いを見ての作業だったので随分と時間が経過してしまっています。まだ少々弄らないといけないのですが、ソースコードを公開できるような体裁が整いました。なるべくスキルの無い人でも弄ることが出来るような構成にしたつもりです。c#が出来る人ならホストプログラムの方を作成できるのではないかと思います。

ツイッターを始めたので賛同者は記事にツイートしてください。人数次第で機能拡張など、どこまでやるかを考えます。

避難所雑談スレで突っ込みがありましたが、よくよく考えればその通りで、悪者は一人でいいとかそういう話ではありませんが、フォローしたい人だけフォローして下さい。世間の事情からフォローできない人は、コメント投稿をもって意思表示とします。
投稿されたコメントは意思表示の人数としてカウントします。表示承認しませんので外部には表示されません


2014-05-22-simplerohook-src-overview

クリックまたは保存してフルサイズでご覧ください。ソースコードの片りんはこちらで見ることが出来ますが、現行のコードはもう少し直感的に理解可能かと思います。

因みに以下のコードだけでプレイヤー直下に文字が表示できます。

// ゲームオブジェクト取得
CModeMgr *pcmode = g_pmodeMgr;
CGameMode *p_gamemode = (CGameMode*)pcmode->m_curMode;
std::stringstream putinfostr;

// プレイヤーオブジェクト取得
CPlayer *pPlayer = (CPlayer*)p_gamemode->m_world->m_player;

// 3D座標をスクリーンに投影
float fx,fy,oow;
ProjectVertex( pPlayer->m_pos,pView->m_viewMatrix,&fx,&fy,&oow);

//文字列表示
g_pSFastFont->DrawText((LPSTR)putinfostr.str().c_str(), (int)fx, (int)fy,D3DCOLOR_ARGB(255,255,255,255),2,NULL);

現行のコードでもjROの2014年5月20日のパッチで動作しなくなったM2Eには対応していません。良い機会なので、これに対応する方法をソースコードを交えて解説することで以後、ほかの誰かがソースコードを修正すれば使えるような形に出来ればと考えています。
残りのROライフを有意義に過ごすためのプロジェクトとでも申しましょうか…。

公開はgithubで行おうかと考えています。

コンパイルにはVisualStudio 2010、またはVisualStudio 2013 (Expressでも可) で行います。

VC++2010のビルドツールが必要なので、VisualStudio 2013の方は別途にVC++2010ExpressかVC++2010のインストールが必要です。必要なのはビルドツールだけなので最低限のインストールで構いません。これはC++の標準ライブラリのバージョンをROのexeで使用されているものと合わせるために必要です。DirectX7のライブラリが必要ですが、インストールするバージョンはこちらをご覧ください。

環境セットアップ関連は以下の記事を参考にして下さい。

Visual Studio 2013 の プラットフォーム ツールセット を拡充する | Planetleaf.com Lab.

まぁ、わりと夢物語が入っています。ここまでやって置いてなんですが、個人的にはお蔵入りでもいいかと思っています。
正直、公開直前になってパッチが当たってM2Eが死亡。盛大に予定が狂いました。泣きたい気持ちになっている人がここに居ます。

苦労してまでやる事かな…とか思ってみたり

追伸:イズルードはこんな感じで…
ro2014new_izulude

 

以下、こんなコードなら自分でも弄れるかもしれない的な事を判断するための材料にでもして下さい。

座標変換の計算式は、以前のバージョンではデバッガを使用して計算中の値を拾って、一般的な透視変換の式に当てはめたため微量の誤差がありました。

今回新たにクライアント内で実際に使われている透視変換のファンクションを解析して寸分たがわぬ計算式を復元しました。

nowProjectVertexCalcForm

CRendererという描画タスクのコアクラスからスクリーン系の補正値を拾う事で計算式を完成させています。この為、パッチによりクライアントのデータ構造が変化するとその都度解析、変更が必要ですが、コードがシンプルなのでメンテナンス性に優れています。

vert->x = viewvect.x * w * (*g_renderer)->m_hpc + (*g_renderer)->m_halfWidth;
vert->y = viewvect.y * w * (*g_renderer)->m_vpc + (*g_renderer)->m_halfHeight;
vert->z = (1500 / (1500.0f - 10.0f)) * (( 1.0f / w ) - 10.0f) * w;
vert->oow = w;
class CRenderer {
public:
	float m_hpc;
	float m_vpc;
	float m_hratio;
	float m_vratio;
	float m_aspectRatio;
	float m_screenXFactor;
	float m_screenYFactor;
	int m_xoffset;
	int m_yoffset;
	int m_width;
	int m_height;
	int m_halfWidth;
	int m_halfHeight;

 評価用コード

現状のコードのコピペで失礼。DirectXの初期描画時にCRoCodeBindクラスが生成され、クライアントのUIが描画される前にDrawOn3DMap関数が呼ばれ、クライアントの全ての描画が終わった後にDrawSRHDebug関数が呼ばれるというシンプルな物です。

散らばっていたコードをクラス化して体裁を整えただけなので、もう少し形状が変わるかもしれません。

ws2_32.dllのrecvがパケットを取得するとPacketQueueProc関数に処理が渡り、現状はパケットログが流れています。

gitの使い方をこれから覚えるという体たらくなので、しばらくお待ちください。コードを改修しつつ、やり方を解説できるくらいには覚えないといけませんね。やはりgitの導入と使い方、githubのアカウントの作り方とか、ここのサイトにまとまっていたほうがいいですかね…。

/*
    This file is part of SimpleROHook.

    SimpleROHook is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    SimpleROHook is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with SimpleROHook.  If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once

#include "shared.h"

#include "PerformanceCounter.h"
#include "SearchCode.h"
#include "FastFont/SFastFont.h"

// Required to create a dll for jRO.
//#define JRO_CLIENT_STRUCTURE
//

#include "ro/system.h"
#include "ro/mouse.h"
#include "ro/unit.h"
#include "ro/res.h"
#include "ro/ui.h"
#include "ro/object.h"
#include "ro/map.h"
#include "ro/task.h"

#define D3DFVF_CPOLVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
#define D3DCOLOR_ARGB(a,r,g,b) \
	((D3DCOLOR)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))

struct CPOLVERTEX {
	FLOAT x, y, z, rhw; // The transformed position for the vertex
	DWORD color;        // The vertex color
};

class CRoCodeBind
{
private:
	CRenderer** g_renderer;
	CModeMgr *g_pmodeMgr;
	CMouse* g_mouse;

	struct p_std_map_packetlen
	{
		struct p_std_map_packetlen *left, *parent, *right;
		DWORD key;
		int value;
	};

#define PACKETQUEUE_BUFFERSIZE 40960
	char m_packetqueuebuffer[PACKETQUEUE_BUFFERSIZE];
	unsigned int m_packetqueue_head;

#define ROPACKET_MAXLEN 0x2000
	int m_packetLenMap_table[ROPACKET_MAXLEN];
	int m_packetLenMap_table_index;

#define MAX_FLLORSKILLTYPE 0x100
	DWORD m_M2ESkillColor[MAX_FLLORSKILLTYPE];

	int GetTreeData(p_std_map_packetlen* node);

	void ProjectVertex(vector3d& src,matrix& vtm,float *x,float *y,float *oow);
	void ProjectVertex(vector3d& src,matrix& vtm,tlvertex3d *vert);

	void LoadIni(void);
	void SearchRagexeMemory(void);

	CSFastFont *g_pSFastFont;

public:
	CRoCodeBind(IDirect3DDevice7* d3ddevice);
	virtual ~CRoCodeBind();

	void DrawSRHDebug(IDirect3DDevice7* d3ddevice);
	void DrawOn3DMap(IDirect3DDevice7* d3ddevice);
	void DrawM2E(IDirect3DDevice7* d3ddevice);

	int GetPacketLength(int opcode);
	void PacketQueueProc(char *buf,int len);

	void SetMouseCurPos(int x,int y);
};

typedef void (__cdecl *tPlayStream)(const char *streamFileName,int playflag);


extern BOOL g_MouseFreeSw;
extern StSHAREDMEMORY *g_pSharedData;

extern tPlayStream funcRagexe_PlayStream;
extern CMouse* g_mouse;

extern CRoCodeBind* g_pRoCodeBind;

BOOL OpenSharedMemory(void);
BOOL ReleaceSharedMemory(void);

extern CPerformanceCounter g_PerformanceCounter;

 

#include "stdafx.h"
#include "../tinyconsole.h"
#include "RoCodeBind.h"

HANDLE         g_hMapObject = 0;
StSHAREDMEMORY *g_pSharedData = 0;

BOOL OpenSharedMemory(void)
{
	g_hMapObject = ::OpenFileMapping( FILE_MAP_ALL_ACCESS , FALSE, SHAREDMEMORY_OBJECTNAME );
	if( !g_hMapObject ){
		DEBUG_LOGGING_NORMAL( ("shared memory:Initialize Failed.") );
		return FALSE;
	}
	g_pSharedData = (StSHAREDMEMORY*)::MapViewOfFile(g_hMapObject,
		FILE_MAP_ALL_ACCESS,0,0,0);
	if(!g_pSharedData){
		DEBUG_LOGGING_NORMAL( ("shared memory:DataMap Failed.") );
		::CloseHandle( g_hMapObject);
		g_hMapObject = NULL;
		return FALSE;
	}
	return TRUE;
}
BOOL ReleaceSharedMemory(void)
{
	if(g_pSharedData){
		g_pSharedData->g_hROWindow = 0;
		::UnmapViewOfFile( g_pSharedData );
		g_pSharedData = NULL;
	}
	if(g_hMapObject){
		::CloseHandle( g_hMapObject);
		g_hMapObject = NULL;
	}
	return TRUE;
}

CPerformanceCounter g_PerformanceCounter(60);

CRoCodeBind* g_pRoCodeBind = NULL;



tPlayStream funcRagexe_PlayStream = NULL;


BOOL g_MouseFreeSw = FALSE;


LPDIRECTDRAWSURFACE7 g_pddsFontTexture = NULL;

static HRESULT CALLBACK TextureSearchCallback( DDPIXELFORMAT* pddpf,
                                               VOID* param )
{
    if( pddpf->dwFlags & (DDPF_LUMINANCE|DDPF_BUMPLUMINANCE|DDPF_BUMPDUDV) )
        return DDENUMRET_OK;
    if( pddpf->dwFourCC != 0 )
        return DDENUMRET_OK;
    if( pddpf->dwRGBBitCount != 16 )
        return DDENUMRET_OK;
    if(!(pddpf->dwFlags&DDPF_ALPHAPIXELS) )
        return DDENUMRET_OK;
	// get 16 bit with alphapixel format
    memcpy( (DDPIXELFORMAT*)param, pddpf, sizeof(DDPIXELFORMAT) );
    return DDENUMRET_CANCEL;
}

//void InitRODraw(IDirect3DDevice7* d3ddevice)
CRoCodeBind::CRoCodeBind(IDirect3DDevice7* d3ddevice) :
	m_packetLenMap_table_index(0),m_packetqueue_head(0),
	g_renderer(NULL),g_pmodeMgr(NULL),g_mouse(NULL),g_pSFastFont(NULL)
{
	SearchRagexeMemory();
	LoadIni();

	D3DDEVICEDESC7 ddDesc;
	d3ddevice->GetCaps( &ddDesc );

	DDSURFACEDESC2 ddsd;
	ZeroMemory( &ddsd, sizeof(DDSURFACEDESC2) );
	ddsd.dwSize          = sizeof(DDSURFACEDESC2);
	ddsd.dwFlags         = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|
							DDSD_PIXELFORMAT|DDSD_TEXTURESTAGE;
	ddsd.ddsCaps.dwCaps  = DDSCAPS_TEXTURE;
	ddsd.dwWidth         = 512;
	ddsd.dwHeight        = 512;

	if( ddDesc.deviceGUID == IID_IDirect3DHALDevice ){
		ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
	} else if( ddDesc.deviceGUID == IID_IDirect3DTnLHalDevice ){
		ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
	} else {
		ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
	}

	d3ddevice->EnumTextureFormats( TextureSearchCallback, &ddsd.ddpfPixelFormat );
	if( ddsd.ddpfPixelFormat.dwRGBBitCount ){
		LPDIRECTDRAWSURFACE7 pddsRender = NULL;
		LPDIRECTDRAW7        pDD = NULL;

		d3ddevice->GetRenderTarget( &pddsRender );
		if( pddsRender ){
			pddsRender->GetDDInterface( (VOID**)&pDD );
			pddsRender->Release();
		}
		if( pDD ){
			if( SUCCEEDED( pDD->CreateSurface( &ddsd, &g_pddsFontTexture, NULL )) ){
				DEBUG_LOGGING_NORMAL(( "font texture created." ));
			} else {
				DEBUG_LOGGING_NORMAL(( "failed create a font texture." ));
			}
			pDD->Release();
		}
		if( g_pddsFontTexture ){
			LOGFONT logfont;
			logfont.lfHeight         = -12;
			logfont.lfWidth          = 0;
			logfont.lfEscapement     = 0;
			logfont.lfOrientation    = 0;
			logfont.lfWeight         = FW_REGULAR;
			//
			logfont.lfItalic         = FALSE;
			logfont.lfUnderline      = FALSE;
			logfont.lfStrikeOut      = FALSE;
			logfont.lfCharSet        = DEFAULT_CHARSET;
			logfont.lfOutPrecision   = OUT_DEFAULT_PRECIS; 
			logfont.lfClipPrecision  = CLIP_DEFAULT_PRECIS; 
			logfont.lfQuality        = NONANTIALIASED_QUALITY; 
			logfont.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE; 
			_tcscpy_s(logfont.lfFaceName,_T("MS Pゴシック"));

			g_pSFastFont = new CSFastFont;
			g_pSFastFont->CreateFastFont(&logfont,d3ddevice,g_pddsFontTexture,0);
		}
	}

}

//void ReleaseRODraw(void)
CRoCodeBind::~CRoCodeBind(void)
{
	if( g_pSFastFont )
		delete g_pSFastFont;
	if( g_pddsFontTexture ){
		g_pddsFontTexture->Release();
		g_pddsFontTexture = NULL;
	}
}

void CRoCodeBind::SetMouseCurPos(int x,int y)
{
	if( g_mouse ){
		g_mouse->m_xPos = x;
		g_mouse->m_yPos = y;
	}
}

void vector3d::MatrixMult(struct vector3d& v, struct matrix& m)
{
	x = v.x * m.v11 + v.y * m.v21 + v.z * m.v31 + m.v41;
	y = v.x * m.v12 + v.y * m.v22 + v.z * m.v32 + m.v42;
	z = v.x * m.v13 + v.y * m.v23 + v.z * m.v33 + m.v43;
}

// CRenderer::ProjectVertex
void CRoCodeBind::ProjectVertex(vector3d& src,matrix& vtm,float *x,float *y,float *oow)
{
	if( !g_renderer && !*g_renderer )return;

	vector3d viewvect;
	viewvect.MatrixMult( src , vtm );

	float w = 1.0f / viewvect.z;

	*x = viewvect.x * w * (*g_renderer)->m_hpc + (*g_renderer)->m_xoffset;
	*y = viewvect.y * w * (*g_renderer)->m_vpc + (*g_renderer)->m_yoffset;
	*oow = w;
}

// CRenderer::ProjectVertex
void CRoCodeBind::ProjectVertex(vector3d& src,matrix& vtm,tlvertex3d *vert)
{
	if( !g_renderer && !*g_renderer )return;

	vector3d viewvect;
	viewvect.MatrixMult( src , vtm );

	float w = 1.0f / viewvect.z;

	vert->x = viewvect.x * w * (*g_renderer)->m_hpc + (*g_renderer)->m_halfWidth;
	vert->y = viewvect.y * w * (*g_renderer)->m_vpc + (*g_renderer)->m_halfHeight;
	vert->z = (1500 / (1500.0f - 10.0f)) * (( 1.0f / w ) - 10.0f) * w;
	vert->oow = w;
}


void CRoCodeBind::LoadIni(void)
{
	if( g_pSharedData ){

		int sectionsize;
		char Sectionbuf[32768];
		char *pkey;
		char filename[MAX_PATH];

		if( ::WideCharToMultiByte(CP_ACP,0,
			g_pSharedData->configfilepath,wcslen(g_pSharedData->configfilepath)+1,
			filename,sizeof(filename),
			NULL,NULL) ){

		DEBUG_LOGGING_NORMAL( ("LoadIni startup") );
		DEBUG_LOGGING_NORMAL( ("%s",filename) );

			sectionsize = GetPrivateProfileSection(_T("M2E"),Sectionbuf,32768,filename);
			pkey = Sectionbuf;

			for(int ii = 0;ii < MAX_FLLORSKILLTYPE;ii++)
				m_M2ESkillColor[ii]=0;

			
			while(*pkey!='\0'){
				int index;
				DWORD color;

				char *ptemp;
				ptemp = pkey;

				std::string linestring(ptemp);

				pkey += linestring.length();

				sscanf_s(linestring.c_str(),"Skill%x=%x",&index,&color);
				m_M2ESkillColor[index] = color;
				pkey++;
			}
		}
	}
}

void CRoCodeBind::DrawSRHDebug(IDirect3DDevice7* d3ddevice)
{
	if( !g_pSharedData )return;
	if( !g_renderer )return;
	if( !*g_renderer )return;

	if( g_pSharedData->show_framerate ){
		std::stringstream str;
		str << g_PerformanceCounter.GetFrameRate() << "fps : "<<(int)g_PerformanceCounter.GetTotalTick() << std::endl;

		g_pSFastFont->DrawText((LPSTR)str.str().c_str(), 0, 0,D3DCOLOR_ARGB(255,255,255,255),0,NULL);
	}

	if( g_pSharedData->objectinformation ){
		std::stringstream str;
		CModeMgr *pcmode = g_pmodeMgr;
		//str.str("");
		CGameMode *p_gamemode = (CGameMode*)pcmode->m_curMode;

		if( p_gamemode && pcmode->m_curModeType == 1 
		 && p_gamemode->m_world && p_gamemode->m_view && p_gamemode->m_world->m_attr ){
			CView *pView = p_gamemode->m_view;

			C3dAttr *pAttr = p_gamemode->m_world->m_attr;

			if( p_gamemode->m_world->m_player ){
				std::stringstream putinfostr;
				C3dAttr *pattr = p_gamemode->m_world->m_attr;

				CPlayer *pPlayer = (CPlayer*)p_gamemode->m_world->m_player;

				// CRenderObject
				str << "m_BodyAni = "      << (int)pPlayer->m_BodyAni << "\n";
				str << "m_BodyAct = "      << (int)pPlayer->m_BodyAct << "\n";
				str << "m_BodyAniFrame = " << (int)pPlayer->m_BodyAniFrame << "\n";
				str << "m_sprRes = "       << std::hex << pPlayer->m_sprRes << "\n";
				str << "m_actRes = "       << std::hex << pPlayer->m_actRes << "\n\n";
				// CAbleToMakeEffect
				str << "m_efId = "         << pPlayer->m_efId << "\n";
				str << "m_Sk_Level = "     << pPlayer->m_Sk_Level << "\n\n";

				// CGameActor
				str << "m_moveDestX/Y = " << std::dec 
					<< pPlayer->m_moveDestX << ","
					<< pPlayer->m_moveDestY << "\n\n";
				str << "m_speed = " << pPlayer->m_speed << "\n\n";

				str << "m_clevel = " << pPlayer->m_clevel << "\n";
				str << "m_gid = " << std::hex << (unsigned long)pPlayer->m_gid << "\n";
				str << "m_job = " << std::hex << (unsigned long)pPlayer->m_job << "\n";
				str << "m_sex = " << std::hex << (unsigned long)pPlayer->m_sex << "\n\n";

				unsigned char *pdump = (unsigned char*)&pPlayer->m_efId;
				for(int ii = 0;ii < 64 ;ii++){
					str << std::setfill('0') << std::setw(2) << std::hex << (int)pdump[ii] << ",";
					if( (ii % 0x10)==0x0f ){
						str << std::endl;
					}
				}
				str << std::endl;

				matrix *pm = &p_gamemode->m_view->m_viewMatrix;
				str << "m_viewMatrix\n"
					<< pm->v11 << " , "
					<< pm->v12 << " , "
					<< pm->v13 << "\n"
					<< pm->v21 << " , "
					<< pm->v22 << " , "
					<< pm->v23 << "\n"
					<< pm->v31 << " , "
					<< pm->v32 << " , "
					<< pm->v33 << "\n"
					<< pm->v41 << " , "
					<< pm->v42 << " , "
					<< pm->v43 << std::endl;

				str << "CRenderer = " << *g_renderer << "\n"
					<< "m_hpc = " << (*g_renderer)->m_hpc << "\n"
					<< "m_vpc = " << (*g_renderer)->m_vpc << "\n"
					<< "m_hratio = " << (*g_renderer)->m_hratio << "\n"
					<< "m_vratio = " << (*g_renderer)->m_vratio << "\n"
					<< "m_aspectRatio = " << (*g_renderer)->m_aspectRatio << "\n"
					<< "m_screenXFactor = " << (*g_renderer)->m_screenXFactor << "\n"
					<< "m_screenYFactor = " << (*g_renderer)->m_screenYFactor << "\n"
					<< "m_xoffset = " << (*g_renderer)->m_xoffset << "\n"
					<< "m_yoffset = " << (*g_renderer)->m_yoffset << "\n"
					<< "m_width = " << (*g_renderer)->m_width << "\n"
					<< "m_height = " << (*g_renderer)->m_height << "\n"
					<< "m_halfWidth = " << (*g_renderer)->m_halfWidth << "\n"
					<< "m_halfHeight = " << (*g_renderer)->m_halfHeight << "\n"
					<< "m_curFrame = " << (*g_renderer)->m_curFrame << "\n"
					<< "m_bRGBBitCount = " << (*g_renderer)->m_bRGBBitCount << "\n"
					<< "m_fpsFrameCount = " << (*g_renderer)->m_fpsFrameCount << "\n"
					<< "m_dwScreenWidth = " << (*g_renderer)->m_dwScreenWidth << "\n"
					<< "m_dwScreenHeight = " << (*g_renderer)->m_dwScreenHeight << "\n"
					<< std::endl;

				//
				//  world position to cell position
				//
				long cx,cy;
				pattr->ConvertToCellCoor(pPlayer->m_pos.x,pPlayer->m_pos.z,cx,cy);
				//
				//
				//
				putinfostr << "(" << cx << "," << cy << ")" << std::endl;

				int sx,sy;
				float fx,fy,oow;
				ProjectVertex( pPlayer->m_pos,pView->m_viewMatrix,&fx,&fy,&oow);
				sx = (int)fx;
				sy = (int)fy;


				g_pSFastFont->DrawText((LPSTR)putinfostr.str().c_str(), sx, sy,D3DCOLOR_ARGB(255,255,255,255),2,NULL);
			}

			int skillnums = p_gamemode->m_world->m_skillList.size();
			str << " m_skillList size =" << skillnums << "\n";

			int itemnums = p_gamemode->m_world->m_itemList.size();
			str << " m_itemList size =" << itemnums << "\n";

			std::list<CItem*> itemList = p_gamemode->m_world->m_itemList;
			for( std::list<CItem*>::iterator it = itemList.begin() ; it != itemList.end() ; it++ )
			{
				CItem *pItem = *it;
				if( pItem ){
					long cx,cy;
					pAttr->ConvertToCellCoor(pItem->m_pos.x,pItem->m_pos.z,cx,cy);

					std::stringstream putinfostr;
					putinfostr << "(" << cx << "," << cy << ")" << std::endl;
					//putinfostr << pItem->m_itemName << std::endl;
				//	putinfostr << "aid = " << pItem->m_aid << std::endl;
					putinfostr << "itemid = " << pItem->m_itemid2 << std::endl;

					int sx,sy;
					float fx,fy,oow;
					ProjectVertex( pItem->m_pos,pView->m_viewMatrix,&fx,&fy,&oow);
					sx = (int)fx;
					sy = (int)fy;

					g_pSFastFont->DrawText((LPSTR)putinfostr.str().c_str(), sx, sy,D3DCOLOR_ARGB(255,255,255,255),2,NULL);
				}
			}


			int actornums = p_gamemode->m_world->m_actorList.size();
			str << " m_actorList size =" << actornums << "\n";
			std::list<CGameActor*> actorList = p_gamemode->m_world->m_actorList;
			for( std::list<CGameActor*>::iterator it = actorList.begin() ; it != actorList.end() ; it++ )
			{
				CGameActor *pGameActor = *it;
				if( pGameActor ){
					long cx,cy;
					pAttr->ConvertToCellCoor(pGameActor->m_pos.x,pGameActor->m_pos.z,cx,cy);

					std::stringstream putinfostr;
					putinfostr << "(" << cx << "," << cy << ")" << std::endl;
				//	putinfostr << "dest(" << pGameActor->m_moveDestX << "," << pGameActor->m_moveDestY << ")" << std::endl;
					putinfostr << "lv = " << pGameActor->m_clevel << std::endl;
					putinfostr << "job = " << pGameActor->m_job << std::endl;

					int sx,sy;
					float fx,fy,oow;
					ProjectVertex( pGameActor->m_pos,pView->m_viewMatrix,&fx,&fy,&oow);
					sx = (int)fx;
					sy = (int)fy;

					g_pSFastFont->DrawText((LPSTR)putinfostr.str().c_str(), sx, sy,D3DCOLOR_ARGB(255,255,255,255),2,NULL);
				}
			}
			
		}
		str << std::endl;
		g_pSFastFont->DrawText((LPSTR)str.str().c_str(), 0, 16,D3DCOLOR_ARGB(255,255,255,255),0,NULL);
	}
	g_pSFastFont->Flush();

}

void CRoCodeBind::DrawOn3DMap(IDirect3DDevice7* d3ddevice)
{
	DrawM2E(d3ddevice);
}

void CRoCodeBind::DrawM2E(IDirect3DDevice7* d3ddevice)
{
	if( !g_pSharedData )return;
	if( g_pSharedData->m2e == FALSE )return;
	if( !g_pmodeMgr )return;

	CModeMgr *pcmode = g_pmodeMgr;
	CWorld *pWorld;
	CView *pView;

	if( pcmode->m_curMode && pcmode->m_curModeType == 1 ){
		CGameMode *pGamemode = (CGameMode*)pcmode->m_curMode;
		pWorld = pGamemode->m_world;
		pView  = pGamemode->m_view;

		DWORD _state_zenable;
		DWORD _state_zwriteenable;
		DWORD _state_zbias;
		DWORD _state_fogenable;
		DWORD _state_specularenable;
		DWORD _state_alphafunc;
		DWORD _state_alpharef;
		DWORD _state_srcblend;
		DWORD _state_destblend;

		d3ddevice->GetRenderState(D3DRENDERSTATE_ZENABLE,        &_state_zenable);
		d3ddevice->GetRenderState(D3DRENDERSTATE_ZWRITEENABLE,   &_state_zwriteenable);
		d3ddevice->GetRenderState(D3DRENDERSTATE_ZBIAS,          &_state_zbias);
		d3ddevice->GetRenderState(D3DRENDERSTATE_FOGENABLE,      &_state_fogenable);
		d3ddevice->GetRenderState(D3DRENDERSTATE_SPECULARENABLE, &_state_specularenable);
		d3ddevice->GetRenderState(D3DRENDERSTATE_ALPHAFUNC,      &_state_alphafunc);
		d3ddevice->GetRenderState(D3DRENDERSTATE_ALPHAREF,       &_state_alpharef);
		d3ddevice->GetRenderState(D3DRENDERSTATE_SRCBLEND ,      &_state_srcblend);
		d3ddevice->GetRenderState(D3DRENDERSTATE_DESTBLEND,      &_state_destblend);

		d3ddevice->SetTexture(0, NULL);
		d3ddevice->SetRenderState(D3DRENDERSTATE_ZENABLE, D3DZB_TRUE);
		d3ddevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE);
		d3ddevice->SetRenderState(D3DRENDERSTATE_ZBIAS, 2);
		d3ddevice->SetRenderState(D3DRENDERSTATE_FOGENABLE    ,FALSE);
		d3ddevice->SetRenderState(D3DRENDERSTATE_SPECULARENABLE   ,FALSE);
		d3ddevice->SetRenderState(D3DRENDERSTATE_ALPHAFUNC,D3DCMP_GREATER);
		d3ddevice->SetRenderState(D3DRENDERSTATE_ALPHAREF,0x00);
		d3ddevice->SetRenderState(D3DRENDERSTATE_SRCBLEND ,D3DBLEND_SRCALPHA );
		d3ddevice->SetRenderState(D3DRENDERSTATE_DESTBLEND,D3DBLEND_INVSRCALPHA);

		if( pWorld && pView && pWorld->m_attr ){
			C3dAttr *pAttr = pWorld->m_attr;

			int skillnums = pWorld->m_skillList.size();
			std::list<CSkill*> skillList = pWorld->m_skillList;

			for( std::list<CSkill*>::iterator it = skillList.begin() ; it != skillList.end() ; it++ )
			{
				CSkill *pSkill = *it;
				//
				if( pSkill && pSkill->m_job < 0x100 && m_M2ESkillColor[pSkill->m_job] ){
					DWORD color = m_M2ESkillColor[pSkill->m_job];
					CPOLVERTEX vertex[4] =
					{
						{   0.0,  0.0,   0.0f,  1.0f, color },
						{ 100.0,  0.0,   0.0f,  1.0f, color },
						{   0.0,100.0,   0.0f,  1.0f, color },
						{ 100.0,100.0,   0.0f,  1.0f, color }
					};

					long cx,cy;
					CAttrCell *pCell;
					vector3d centerpos(pSkill->m_pos),polvect[4];

					pAttr->ConvertToCellCoor(centerpos.x,centerpos.z,cx,cy);
					pCell = pAttr->GetCell(cx, cy);

					polvect[0].Set(centerpos.x -2.4f, pCell->h1 ,centerpos.z -2.4f);
					polvect[1].Set(centerpos.x +2.4f, pCell->h2 ,centerpos.z -2.4f);
					polvect[2].Set(centerpos.x -2.4f, pCell->h3 ,centerpos.z +2.4f);
					polvect[3].Set(centerpos.x +2.4f, pCell->h4 ,centerpos.z +2.4f);

					for(int ii = 0; ii < 4; ii ++){
						tlvertex3d tlv3d;
						ProjectVertex( polvect[ii] , pView->m_viewMatrix,&tlv3d );

						vertex[ii].x = tlv3d.x;
						vertex[ii].y = tlv3d.y;
						vertex[ii].z = tlv3d.z;
						vertex[ii].rhw = tlv3d.oow;
					}
					d3ddevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_CPOLVERTEX, vertex, 4, 0);
				}
			}
		}
		d3ddevice->SetRenderState(D3DRENDERSTATE_ZENABLE,        _state_zenable);
		d3ddevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE,   _state_zwriteenable);
		d3ddevice->SetRenderState(D3DRENDERSTATE_ZBIAS,          _state_zbias);
		d3ddevice->SetRenderState(D3DRENDERSTATE_FOGENABLE,      _state_specularenable);
		d3ddevice->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, _state_specularenable);
		d3ddevice->SetRenderState(D3DRENDERSTATE_ALPHAFUNC,      _state_alphafunc);
		d3ddevice->SetRenderState(D3DRENDERSTATE_ALPHAREF,       _state_alpharef);
		d3ddevice->SetRenderState(D3DRENDERSTATE_SRCBLEND ,      _state_srcblend);
		d3ddevice->SetRenderState(D3DRENDERSTATE_DESTBLEND,      _state_destblend);
	}
}



 int CRoCodeBind::GetPacketLength(int opcode)
{
	int result = -1;

	if( opcode < m_packetLenMap_table_index )
	{
		result = m_packetLenMap_table[ opcode ];
	}
	return result;
}

int CRoCodeBind::GetTreeData(p_std_map_packetlen* node)
{
	if ( node->parent == NULL || node->key >= ROPACKET_MAXLEN || node->key == 0)
		return m_packetLenMap_table_index;

	GetTreeData( node->left );

	if( m_packetLenMap_table_index < (int)node->key )
		 m_packetLenMap_table_index = node->key;

	m_packetLenMap_table[ node->key ] = node->value;
	//DEBUG_LOGGING_NORMAL( ("[ %08X ] = %d",node->key,node->value) );

	GetTreeData( node->right );

	return m_packetLenMap_table_index;
}


void CRoCodeBind::PacketQueueProc(char *buf,int len)
{
	if( len > 0 ){
		if( m_packetqueue_head + len >= PACKETQUEUE_BUFFERSIZE ){
			DEBUG_LOGGING_NORMAL( ("packet buffer has overflowed.\n") );
			return;
		}
		memcpy( &m_packetqueuebuffer[m_packetqueue_head] , buf,
			len);
		m_packetqueue_head += len;
		while( m_packetqueue_head > 1 ){
			unsigned short opcode = *(unsigned short*)m_packetqueuebuffer;
			unsigned int packetlength;

			if( m_packetqueue_head == 4 && len == 4 ){
				packetlength = 4;
			}else{
				packetlength = GetPacketLength( opcode );
				if( packetlength == -1 ){
					if( m_packetqueue_head < 4 )break;
					packetlength = *(unsigned int*)m_packetqueuebuffer;
					packetlength >>= 16;
				}
			}
			if( m_packetqueue_head >= packetlength ){
				if( g_pSharedData && g_pSharedData->write_packetlog ){
					std::stringstream str;
					str << "[" << std::setfill('0') << std::setw(8) << timeGetTime() << "] R ";
					for(int ii = 0;ii < (int)packetlength ;ii++)
						str << std::setfill('0') << std::setw(2) << std::hex << std::uppercase << (int)(unsigned char)m_packetqueuebuffer[ii] << " ";
					str << std::flush;
					//DEBUG_LOGGING_NORMAL( ("Opcode %04X size = %d / %d\n",opcode,packetlength,packetqueue_head) );
					DEBUG_LOGGING_NORMAL(( str.str().c_str() ));
				}

				m_packetqueue_head -= packetlength;
				if( m_packetqueue_head ){
					memmove( m_packetqueuebuffer, &m_packetqueuebuffer[packetlength],
						m_packetqueue_head );
				}
			}else{
				break;
			}
		}
	}
}

typedef int (__stdcall *Func_CRagConnection__GetPacketSize)(DWORD opcode);

void CRoCodeBind::SearchRagexeMemory(void)
{
	// CZ_UIYourItemWnd::SendMsg CZ_REQ_WEAR_EQUIP handler
	// Marker '1' CModeMgr g_modeMgr (C++ Class Instance)
	// Marker '2' CModeMgr::GetGameMode
	// Marker '3' CRagConnection::instanceR
	// Marker '4' CRagConnection::GetPacketSize
	// Marker '5' CRagConnection::SendPacket
	// Marker '6' UIWindowMgr g_windowMgr (C++ Class Instance)
	// Marker '7' UIWindowMgr::DeleteWindow
	// based RagFree.exe iRO vc6
	CSearchCode UIYourItemWnd__SendMsg_0A9Handler_TypeA(
		"b9*1******"		// mov     ecx,dword L008208d0 ; CModeMgr__g_modeMgr
		"e8*2******"		// call    near F0052c0e0 ; CModeMgr__GetGameMode
		"668b536c"			// mov     dx,[ebx+06ch]
		"668b4370"			// mov     ax,[ebx+070h]
		"8d4dec"			// lea     ecx,[ebp-014h]
		"66c745eca900"		// mov     word [ebp-014h],word 000a9h
		"51"				// push    ecx
		"68a9000000"		// push    dword 0000000a9h
		"668955ee"			// mov     [ebp-012h],dx
		"668945f0"			// mov     [ebp-010h],ax
		"e8*3******"		// call    near F004190f0 ; CRagConnection__instanceR
		"8bc8"				// mov     ecx,eax
		"e8*4******"		// call    near F00419030 ; CRagConnection__GetPacketSize
		"50"				// push    eax
		"e8********"		// call    near F004190f0 ; CRagConnection__instanceR
		"8bc8"				// mov     ecx,eax
		"e8*5******"		// call    near F00418f00 ; CRagConnection__SendPacket
		"68**000000"		// push    dword 00000008ah
		"b9*6******"		// mov     ecx,dword L007e7220 ; UIWindowMgr__g_windowMgr
		"e8*7******"		// call    near F00502390 ; UIWindowMgr__DeleteWindow
		);
	// F2P_Ragexe.exe iRO vc9
	CSearchCode UIYourItemWnd__SendMsg_0A9Handler_TypeB(
		"b9*1******"		// mov     ecx,dword L00812088 ; CModeMgr__g_modeMgr
		"e8*2******"		// call    near F0051eeb0 ; CModeMgr__GetGameMode
		"668b4e**"			// mov     cx,[esi+06ch]
		"668b56**"			// mov     dx,[esi+070h]
		"b8a9000000"		// mov     eax,dword 0000000a9h
		"6689442408"		// mov     [esp+008h],ax
		"8d442408"			// lea     eax,[esp+008h]
		"50"				// push    eax
		"68a9000000"		// push    dword 0000000a9h
		"66894c2412"		// mov     [esp+012h],cx
		"6689542414"		// mov     [esp+014h],dx
		"e8*3******"		// call    near F006335a0 ; CRagConnection__instanceR
		"8bc8"				// mov     ecx,eax
		"e8*4******"		// call    near F006336d0 ; CRagConnection__GetPacketSize
		"50"				// push    eax
		"e8********"		// call    near F006335a0 ; CRagConnection__instanceR
		"8bc8"				// mov     ecx,eax
		"e8*5******"		// call    near F00633550 ; CRagConnection__SendPacket
		"688a000000"		// push    dword 00000008ah
		"b9*6******"		// mov     ecx,dword L0083df40 ; UIWindowMgr__g_windowMgr
		"e8*7******"		// call    near F004f8270 ; UIWindowMgr__DeleteWindow
		);
	// based 2011-12-01aRagexe.exe iRO vc9
	CSearchCode UIYourItemWnd__SendMsg_0A9Handler_TypeC(
		"b9*1******"		// mov     ecx,dword L008371f8 ; CModeMgr__g_modeMgr
		"e8*2******"		// call    near F0054a7a0 ; CModeMgr__GetGameMode
		"668b4e**"			// mov     cx,[esi+07ch]
		"668b96**000000"	// mov     dx,[esi+000000080h]
		"b8a9000000"		// mov     eax,dword 0000000a9h
		"6689442408"		// mov     [esp+008h],ax
		"8d442408"			// lea     eax,[esp+008h]
		"50"				// push    eax
		"68a9000000"		// push    dword 0000000a9h
		"66894c2412"		// mov     [esp+012h],cx
		"6689542414"		// mov     [esp+014h],dx
		"e8*3******"		// call    near F0065d4d0 ; CRagConnection__instanceR
		"8bc8"				// mov     ecx,eax
		"e8*4******"		// call    near F0065cf90 ; CRagConnection__GetPacketSize
		"50"				// push    eax
		"e8********"		// call    near F0065d4d0 ; CRagConnection__instanceR
		"8bc8"				// mov     ecx,eax
		"e8*5******"		// call    near F0065d3f0 ; CRagConnection__SendPacket
		"688a000000"		// push    dword 00000008ah
		"b9*6******"		// mov     ecx,dword L008626b8 ; UIWindowMgr__g_windowMgr
		"e8*7******"		// call    near F00523770 ; UIWindowMgr__DeleteWindow
		);
	// 2014-03-14aRagexe.exe jRO
	CSearchCode UIYourItemWnd__SendMsg_0A9Handler_TypeD(
		"b9*1******"		// mov     ecx,dword L00812088 ; CModeMgr__g_modeMgr
		"e8*2******"		// call    near F0051eeb0 ; CModeMgr__GetGameMode
		"668b****"			// mov     cx,[esi+06ch]
		"668b****"			// mov     dx,[esi+070h]
		"b9a9000000"		// mov     eax,dword 0000000a9h
		"6689****"			// mov     [esp+008h],ax
		"8d****"			// lea     eax,[esp+008h]
		"51"				// push    eax
		"68a9000000"		// push    dword 0000000a9h
		"668955**"			// mov     [ebp-012h],dx
		"668945**"			// mov     [ebp-010h],ax
		"e8*3******"		// call    near F006335a0 ; CRagConnection__instanceR
		"8bc8"				// mov     ecx,eax
		"e8*4******"		// call    near F006336d0 ; CRagConnection__GetPacketSize
		"50"				// push    eax
		"e8********"		// call    near F006335a0 ; CRagConnection__instanceR
		"8bc8"				// mov     ecx,eax
		"e8*5******"		// call    near F00633550 ; CRagConnection__SendPacket
		"688a000000"		// push    dword 00000008ah
		"b9*6******"		// mov     ecx,dword L0083df40 ; UIWindowMgr__g_windowMgr
		"e8*7******"		// call    near F004f8270 ; UIWindowMgr__DeleteWindow
		);
	// 2014-03-18 Ragexe.exe iRO link time 20140226 155100
	CSearchCode UIYourItemWnd__SendMsg_0A9Handler_TypeE(
		"b9*1******"        //         mov     ecx,dword L0099f930 ; CModeMgr__g_modeMgr
		"e8*2******"        //         call    near F005a5eb0 ; CModeMgr__GetGameMode
		"668b96********"    //         mov     dx,[esi+00000008ch]
		"668b86********"    //         mov     ax,[esi+000000090h]
		"b9a9000000"        //         mov     ecx,dword 0000000a9h
		"66894d**"          //         mov     [ebp-034h],cx
		"8d4d**"            //         lea     ecx,[ebp-034h]
		"51"                //         push    ecx
		"68a9000000"        //         push    dword 0000000a9h
		"668955**"          //         mov     [ebp-032h],dx
		"668945**"          //         mov     [ebp-030h],ax
		"e8*3******"        //         call    near F00716fc0 ; CRagConnection__instanceR
		"8bc8"              //         mov     ecx,eax
		"e8*4******"        //         call    near F007168e0 ; CRagConnection__GetPacketSize
		"50"                //         push    eax
		"e8********"        //         call    near F00716fc0 ; CRagConnection__instanceR
		"8bc8"              //         mov     ecx,eax
		"e8*5******"        //         call    near F00716ee0 ; CRagConnection__SendPacket
		"688a000000"        //         push    dword 00000008ah
		"b9*6******"        //         mov     ecx,dword L009d21c0 ; UIWindowMgr__g_windowMgr
		"e8*7******"        //         call    near F00573a40 ; UIWindowMgr__DeleteWindow
		);

	CSearchCode CMouse_Init_vc6(
		"a1********"		// mov     eax,[ g_hInstance ]
		"53"				// push    ebx
		"56"				// push    esi
		"33db"				// xor     ebx,ebx
		"57"				// push    edi
		"8bf1"				// mov     esi,ecx
		"53"				// push    ebx
		"56"				// push    esi
		"6800070000"		// push    dword 000000700h
		"50"				// push    eax
		);
	CSearchCode CMouse_Init_vc9(
		"a1********"		// mov     eax,[ g_hInstance ]
		"53"				// push    ebx
		"56"				// push    esi
		"33db"				// xor     ebx,ebx
		"53"				// push    ebx
		"8bf1"				// mov     esi,ecx
		"56"				// push    esi
		"6800070000"		// push    dword 000000700h
		"50"				// push    eax
		);
	CSearchCode winmain_init_CMouse_Init_call(
		"b9*1******"		// mov     ecx,g_mouse
		"e8*2******"		// call    near CMouse__Init
		"a1*3******"		// mov     eax, g_renderer__CRenderer
		);

	CSearchCode funcPlayStrem_based_HighPrest_exe(
		"55"                //   push    ebp
		"8bec"              //   mov     ebp,esp
		"a1*1******"        //   mov     eax,[L006f2534] ; g_soundMode
		"53"                //   push    ebx
		"85c0"              //   test    eax,eax
		"56"                //   push    esi
		"0f84c5000000"      //   jz      near C0040afa7
		"8b5d08"            //   mov     ebx,dword [ebp+008h] ;+streamFileName
		"be********"        //   mov     esi,dword L0074e7c4
		"8bc3"              //   mov     eax,ebx
		"8a10"              //   mov     dl,[eax]
		"8aca"              //   mov     cl,dl
		"3a16"              //   cmp     dl,[esi]
		"751c"              //   jnz     C0040af10                            
		"84c9"              //   test    cl,cl
		);
	CSearchCode funcPlayStrem_based_RagFree_exe(
		"55"                //   push    ebp
		"8bec"              //   mov     ebp,esp
		"81ec00010000"      //   sub     esp,dword 000000100h
		"a1*1******"        //   mov     eax,[L00775d44] ; g_soundMode
		"53"                //   push    ebx
		"85c0"              //   test    eax,eax
		"56"                //   push    esi
		"0f8417010000"      //   jz      near C0041b6bf
		"8b5d08"            //   mov     ebx,dword [ebp+008h] ;+streamFileName
		"be********"        //   mov     esi,dword L007cd9b4
		"8bc3"              //   mov     eax,ebx
		"8a10"              //   mov     dl,[eax]
		"8aca"              //   mov     cl,dl
		"3a16"              //   cmp     dl,[esi]
		"751c"              //   jnz     C0041b5d6                            
		"84c9"              //   test    cl,cl
		);
	CSearchCode funcPlayStrem_based_2011111201aRagexe_exe(
		"81ec04010000"      //   sub     esp,dword 000000104h
		"a1*1******"        //   mov     eax,[L00845990] ; g_soundMode
		"33c4"              //   xor     eax,esp
		"89842400010000"    //   mov     dword [esp+000000100h],eax
		"833d********00"    //   cmp     dword [L0084459c],byte +000h
		"56"                //   push    esi
		"8bb4240c010000"    //   mov     esi,dword [esp+00000010ch] ;+streamFileName
		"0f8406010000"      //   jz      near C0065fd9f
		"b9********"        //   mov     ecx,dword L008e348c
		"8bc6"              //   mov     eax,esi
		"8a10"              //   mov     dl,[eax]
		"3a11"              //   cmp     dl,[ecx]
		"751a"              //   jnz     C0065fcc0                                  
		"84d2"              //   test    dl,dl
		);
	CSearchCode funcPlayStrem_based_20140226_155100iRagexe_exe(
		// F00719260
		"55"                //   push    ebp
		"8bec"              //   mov     ebp,esp
		"81ec********"      //   sub     esp,dword 000000104h
		"a1*1******"        //   mov     eax,[L009b63d0] ; g_soundMode
		"33c5"              //   xor     eax,ebp
		"8945**"            //   mov     dword [ebp-004h],eax
		"833d********00"    //   cmp     dword [L00aa1610],byte +000h
		"56"                //   push    esi
		"8b75**"            //   mov     esi,dword [ebp+008h]
		"0f84********"      //   jz      near C00719393
		);

	LPBYTE pRagexeBase;
	MEMORY_BASIC_INFORMATION mbi;
	DWORD temp_eax,temp_ecx,temp_edx,temp_esp;

	pRagexeBase = (LPBYTE)::GetModuleHandle(NULL);
	pRagexeBase += 0x1000;

	if( ::VirtualQuery( pRagexeBase,&mbi,sizeof(mbi) ) )
	{
		DWORD ptr_CMouse_Init = 0;

		p_std_map_packetlen *packetLenMap = 0;

		DEBUG_LOGGING_NORMAL( ("MEMORY_BASIC_INFORMATION lpAddres:%08X",pRagexeBase) );
		DEBUG_LOGGING_NORMAL( ("mbi.AllocationBase = %08X",mbi.AllocationBase) );
		DEBUG_LOGGING_NORMAL( ("mbi.BaseAddress    = %08X",mbi.BaseAddress) );
		DEBUG_LOGGING_NORMAL( ("mbi.RegionSize     = %08X",mbi.RegionSize) );

		// snatch the packetLenMap
		for( UINT ii = 0; ii < mbi.RegionSize - 1000 ; ii++ )
		{
			LPBYTE pBase = (LPBYTE)mbi.BaseAddress;

			if( UIYourItemWnd__SendMsg_0A9Handler_TypeA.PatternMatcher( &pBase[ii] ) )
			{
				DWORD GetPacketSizeAddr;
				GetPacketSizeAddr = 
					UIYourItemWnd__SendMsg_0A9Handler_TypeA.Get4BIndexDWORD( &pBase[ii] , '4' );
				__asm push 0x0A9
				__asm call GetPacketSizeAddr
				__asm mov temp_esp,esp

				p_std_map_packetlen *plen = (p_std_map_packetlen*)
					*(DWORD*) (*(DWORD*)(temp_esp-19*4) + 4);

				g_pmodeMgr = (CModeMgr*)UIYourItemWnd__SendMsg_0A9Handler_TypeA
					.GetImmediateDWORD( &pBase[ii], '1' );

				DEBUG_LOGGING_NORMAL( ("TypeA GetPacketSizeAddr %08X",GetPacketSizeAddr) );
				DEBUG_LOGGING_NORMAL( (" esp = %08X",temp_esp) );
				while(1)
				{
					if( plen->key > 0xffff || (plen->key == 0 && plen->value == 0) ){
						packetLenMap = plen;
						DEBUG_LOGGING_NORMAL( ("packetLenMap = %08X",packetLenMap) );
						break;
					}
					plen = plen->parent;
				}
				break;
			}else
			if( UIYourItemWnd__SendMsg_0A9Handler_TypeB.PatternMatcher( &pBase[ii] ) )
			{
				DWORD GetPacketSizeAddr;
				GetPacketSizeAddr = 
					UIYourItemWnd__SendMsg_0A9Handler_TypeB.Get4BIndexDWORD( &pBase[ii] , '4' );
				__asm push 0x0A9
				__asm call GetPacketSizeAddr
				__asm mov temp_eax,eax
				__asm mov temp_ecx,ecx
				__asm mov temp_edx,edx
				p_std_map_packetlen *plen;
				if( temp_eax == temp_edx ){
					plen = (p_std_map_packetlen*)temp_ecx;
				}else{
					plen = (p_std_map_packetlen*)temp_edx;
				}

				g_pmodeMgr = (CModeMgr*)UIYourItemWnd__SendMsg_0A9Handler_TypeB
					.GetImmediateDWORD( &pBase[ii], '1' );

				DEBUG_LOGGING_NORMAL( ("TypeB GetPacketSizeAddr     = %08X eax = %08X ecx = %08X edx =%08X",
					GetPacketSizeAddr,temp_eax,temp_ecx,temp_edx) );
				while(1)
				{
					if( plen->key > 0xffff || (plen->key == 0 && plen->value == 0) ){
						packetLenMap = plen;
						DEBUG_LOGGING_NORMAL( ("packetLenMap = %08X",packetLenMap) );
						break;
					}
					plen = plen->parent;
				}
				break;
			}else
			if( UIYourItemWnd__SendMsg_0A9Handler_TypeC.PatternMatcher( &pBase[ii] ) )
			{
				DWORD GetPacketSizeAddr;
				Func_CRagConnection__GetPacketSize GetPacketSize;
				GetPacketSizeAddr = 
					UIYourItemWnd__SendMsg_0A9Handler_TypeC.Get4BIndexDWORD( &pBase[ii] , '4' );
				GetPacketSize = (Func_CRagConnection__GetPacketSize)GetPacketSizeAddr;
				//GetPacketSize(0x0A9);
				__asm push 0x0A9
				__asm call GetPacketSizeAddr
				__asm mov temp_ecx,ecx
				p_std_map_packetlen *plen = (p_std_map_packetlen*)temp_ecx;

				g_pmodeMgr = (CModeMgr*)UIYourItemWnd__SendMsg_0A9Handler_TypeC
					.GetImmediateDWORD( &pBase[ii], '1' );

				DEBUG_LOGGING_NORMAL( ("TypeC GetPacketSizeAddr     = %08X ecx = %08X",GetPacketSizeAddr,temp_ecx) );
				while(1)
				{
					if( plen->key > 0xffff || (plen->key == 0 && plen->value == 0) ){
						packetLenMap = plen;
						DEBUG_LOGGING_NORMAL( ("packetLenMap = %08X",packetLenMap) );
						break;
					}
					plen = plen->parent;
				}
				break;
			}else
			if( UIYourItemWnd__SendMsg_0A9Handler_TypeD.PatternMatcher( &pBase[ii] ) )
			{
				DWORD GetPacketSizeAddr;
				Func_CRagConnection__GetPacketSize GetPacketSize;
				GetPacketSizeAddr = 
					UIYourItemWnd__SendMsg_0A9Handler_TypeD.Get4BIndexDWORD( &pBase[ii] , '4' );
				GetPacketSize = (Func_CRagConnection__GetPacketSize)GetPacketSizeAddr;
				//GetPacketSize(0x0A9);
				__asm push 0x0A9
				__asm call GetPacketSizeAddr
				__asm mov temp_ecx,ecx
				p_std_map_packetlen *plen = (p_std_map_packetlen*)temp_ecx;

				g_pmodeMgr = (CModeMgr*)UIYourItemWnd__SendMsg_0A9Handler_TypeD
					.GetImmediateDWORD( &pBase[ii], '1' );

				DEBUG_LOGGING_NORMAL( ("TypeD GetPacketSizeAddr     = %08X ecx = %08X",GetPacketSizeAddr,temp_ecx) );
				while(1)
				{
					if( plen->key > 0xffff || (plen->key == 0 && plen->value == 0) ){
						packetLenMap = plen;
						DEBUG_LOGGING_NORMAL( ("packetLenMap = %08X",packetLenMap) );
						break;
					}
					plen = plen->parent;
				}
				break;
			}else
			if( UIYourItemWnd__SendMsg_0A9Handler_TypeE.PatternMatcher( &pBase[ii] ) )
			{
				DWORD GetPacketSizeAddr;
				Func_CRagConnection__GetPacketSize GetPacketSize;
				GetPacketSizeAddr = 
					UIYourItemWnd__SendMsg_0A9Handler_TypeE.Get4BIndexDWORD( &pBase[ii] , '4' );
				GetPacketSize = (Func_CRagConnection__GetPacketSize)GetPacketSizeAddr;
				//GetPacketSize(0x0A9);
				__asm push 0x0A9
				__asm call GetPacketSizeAddr
				__asm mov temp_ecx,ecx
				p_std_map_packetlen *plen = (p_std_map_packetlen*)temp_ecx;

				g_pmodeMgr = (CModeMgr*)UIYourItemWnd__SendMsg_0A9Handler_TypeE
					.GetImmediateDWORD( &pBase[ii], '1' );

				DEBUG_LOGGING_NORMAL( ("TypeE GetPacketSizeAddr     = %08X ecx = %08X",GetPacketSizeAddr,temp_ecx) );
				while(1)
				{
					if( plen->key > 0xffff || (plen->key == 0 && plen->value == 0) ){
						packetLenMap = plen;
						DEBUG_LOGGING_NORMAL( ("packetLenMap = %08X",packetLenMap) );
						break;
					}
					plen = plen->parent;
				}
				break;
			}
		}

		// get CMouse instance
		for( UINT ii = 0; ii < mbi.RegionSize - CMouse_Init_vc6.GetSize() ; ii++ )
		{
			LPBYTE pBase = (LPBYTE)mbi.BaseAddress;
			if( CMouse_Init_vc6.PatternMatcher( &pBase[ii] )
			 || CMouse_Init_vc9.PatternMatcher( &pBase[ii] )
				)
			{
				ptr_CMouse_Init = (DWORD)( &pBase[ii] );
				DEBUG_LOGGING_NORMAL( ("find CMouse::Init = %08X",pBase + ii) );
				break;
			}
		}
		if( ptr_CMouse_Init )
		{
			for( int ii = mbi.RegionSize - winmain_init_CMouse_Init_call.GetSize(); ii >= 0 ; ii-- )
			{
				LPBYTE pBase = (LPBYTE)mbi.BaseAddress;
				if( winmain_init_CMouse_Init_call.PatternMatcher( &pBase[ii] ) )
				{
					DEBUG_LOGGING_NORMAL( ("find CMouse::Init call : %08X",pBase + ii) );
					if( winmain_init_CMouse_Init_call.NearJmpAddressMatcher( &pBase[ii],'2',ptr_CMouse_Init ) )
					{
						g_mouse = (CMouse*)winmain_init_CMouse_Init_call.GetImmediateDWORD(&pBase[ii],'1');
						g_renderer = (CRenderer**)winmain_init_CMouse_Init_call.GetImmediateDWORD(&pBase[ii],'3');
						
						DEBUG_LOGGING_NORMAL( ("find g_mouse = %08X",g_mouse) );
						DEBUG_LOGGING_NORMAL( ("find *g_renderer = %08X",g_renderer) );
						break;
					}
				}
			}
		}

		// get the address of PlayStream function 
		for( UINT ii = 0; ii < mbi.RegionSize - funcPlayStrem_based_HighPrest_exe.GetSize() ; ii++ )
		{
			LPBYTE pBase = (LPBYTE)mbi.BaseAddress;

			if( funcPlayStrem_based_20140226_155100iRagexe_exe.PatternMatcher( &pBase[ii] )	)
			{
				funcRagexe_PlayStream = (tPlayStream)&pBase[ii];
				DWORD pPlayStream;
				pPlayStream = (DWORD)&pBase[ii];
				DEBUG_LOGGING_NORMAL( ("based_20140226_155100iRagexe : %08X",&pBase[ii]) );
				DEBUG_LOGGING_NORMAL( ("g_soundMode == %08X",(char*)funcPlayStrem_based_20140226_155100iRagexe_exe.GetImmediateDWORD(&pBase[ii],'1')) );
				DEBUG_LOGGING_NORMAL( ("void PlayStream(const char *streamFileName) = %08X",pPlayStream) );
				break;
			}
			if( funcPlayStrem_based_HighPrest_exe.PatternMatcher( &pBase[ii] )	)
			{
				funcRagexe_PlayStream = (tPlayStream)&pBase[ii];
				DWORD pPlayStream;
				pPlayStream = (DWORD)&pBase[ii];
				DEBUG_LOGGING_NORMAL( ("based_HighPrest_exe : %08X",&pBase[ii]) );
				DEBUG_LOGGING_NORMAL( ("g_soundMode == %08X",(char*)funcPlayStrem_based_HighPrest_exe.GetImmediateDWORD(&pBase[ii],'1')) );
				DEBUG_LOGGING_NORMAL( ("void PlayStream(const char *streamFileName) = %08X",pPlayStream) );
				break;
			}
			if( funcPlayStrem_based_RagFree_exe.PatternMatcher( &pBase[ii] )	)
			{
				funcRagexe_PlayStream = (tPlayStream)&pBase[ii];
				DWORD pPlayStream;
				pPlayStream = (DWORD)&pBase[ii];
				DEBUG_LOGGING_NORMAL( ("based_RagFree_exe : %08X",&pBase[ii]) );
				DEBUG_LOGGING_NORMAL( ("g_soundMode == %08X",(char*)funcPlayStrem_based_RagFree_exe.GetImmediateDWORD(&pBase[ii],'1')) );
				DEBUG_LOGGING_NORMAL( ("void PlayStream(const char *streamFileName,int playflag) = %08X",pPlayStream) );
				break;
			}
			if( funcPlayStrem_based_2011111201aRagexe_exe.PatternMatcher( &pBase[ii] )	)
			{
				funcRagexe_PlayStream = (tPlayStream)&pBase[ii];
				DWORD pPlayStream;
				pPlayStream = (DWORD)&pBase[ii];
				DEBUG_LOGGING_NORMAL( ("based_2011111201aRagexe_exe : %08X",&pBase[ii]) );
				DEBUG_LOGGING_NORMAL( ("g_soundMode == %08X",(char*)funcPlayStrem_based_2011111201aRagexe_exe.GetImmediateDWORD(&pBase[ii],'1')) );
				DEBUG_LOGGING_NORMAL( ("void PlayStream(const char *streamFileName,int playflag) = %08X",pPlayStream) );
				break;
			}
		}

		// put packetlengthmap
		if( packetLenMap ){
			int packetnums = GetTreeData( packetLenMap->parent );
			if( packetnums ){
				std::stringstream onelinestr;
				for(int ii = 0;ii < packetnums ;ii++){
					if( (ii % 0x40)==0 ){
						onelinestr << "# 0x" << std::setfill('0') << std::setw(4) << std::hex << ii;
						DEBUG_LOGGING_NORMAL(( onelinestr.str().c_str() ));
						onelinestr.str("");
					}
					if( (ii % 0x10)==0 ){
						onelinestr << " ";
					}
					onelinestr << std::setfill(' ') << std::setw(4) << std::dec << m_packetLenMap_table[ii] << ",";
					if( (ii % 0x10)==0x0f ){
						DEBUG_LOGGING_NORMAL(( onelinestr.str().c_str() ));
						onelinestr.str("");
					}
				}
				DEBUG_LOGGING_NORMAL(( onelinestr.str().c_str() ));
				DEBUG_LOGGING_NORMAL(( "" ));
			}
		}

	}
}