www.pudn.com > MirGui.rar > MirGame.cpp


// MirGame.cpp: implementation of the CMirGame class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include  
#include "MirGame.h" 
#include "mircode.h" 
#include "mirmsg.h" 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
#define	BUFFERLENGTH	4096 
FILE	*	g_fpLog, *g_fpGetLog, * g_fpPutLog; 
void	LogFile( char * pp ) 
{ 
	DWORD	dwTime = GetTickCount(); 
//	fprintf( g_fpLog, "Log at %d: %s\n", dwTime, pp ); 
} 
typedef struct 
{ 
	DWORD	dwGold; 
	WORD	wCmd; 
	BYTE	bProf; 
	BYTE	bHair; 
	BYTE	bSex; 
	BYTE	bOO; 
	WORD	wUnknow; 
	BYTE	bLevel; 
	BYTE	bunknow; 
	BYTE	ACHi; 
	BYTE	ACLow; 
	BYTE	MACHi; 
	BYTE	MACLow; 
	BYTE	DCHi; 
	BYTE	DCLow; 
	BYTE	MCHi; 
	BYTE	MCLow; 
	BYTE	SCHi; 
	BYTE	SCLow; 
	WORD	Hp; 
	WORD	Mp; 
	WORD	MaxHp; 
	WORD	MaxMp; 
	DWORD	dwUnknow; 
	DWORD	Exp; 
	DWORD	MaxExp; 
	WORD	BagWeight; 
	WORD	MaxBagWeight; 
	BYTE	BodyWeight; 
	BYTE	MaxBodyWeight; 
	BYTE	HandWeight; 
	BYTE	MaxHandWeight; 
}MMSGSETCHARINFO; 
 
DWORD	MessageProc( PVOID * p ) 
{ 
	CMirGame	*	pGame = (CMirGame*)p; 
	int		ierr = 0; 
	int		i = 0; 
	int		leftlen = 0; 
	char	*	pSearchString = NULL; 
	char	*	m_tmpBuffer; 
	char	*	m_tmpBuffer2; 
 
 
	if( pGame == 0 ) 
	{ 
		return 0; 
	} 
 
	m_tmpBuffer = new char[BUFFERLENGTH + 5]; 
	memset( (void*)m_tmpBuffer, 0, BUFFERLENGTH + 5 ); 
	m_tmpBuffer2 = new char[BUFFERLENGTH + 5]; 
	memset( (void*)m_tmpBuffer2, 0, BUFFERLENGTH + 5 ); 
 
 
	leftlen = 0; 
	pGame->LogSystem( "进入接收消息进程!" ); 
 
	while( pGame->m_bInGame ) 
	{ 
 
		Sleep( 1 ); 
		ierr = recv( pGame->m_sGame, m_tmpBuffer, BUFFERLENGTH, 0 ); 
		if( ierr == 0 ) 
		{ 
			pGame->Logout(); 
			break; 
		} 
		if( ierr != -1 ) 
		{ 
			for( i = 0;i < ierr;i ++ ) 
			{ 
				if( m_tmpBuffer[i] != '*' ) 
				{ 
					m_tmpBuffer2[leftlen++] = m_tmpBuffer[i]; 
				} 
				else 
				{ 
					pGame->m_MirMsg.SendString( pGame->m_sGame, "*" ); 
				} 
				if( m_tmpBuffer[i] == '!' ) 
				{ 
					m_tmpBuffer2[leftlen] = '\0'; 
					pGame->m_MsgQueue.PutMsg( m_tmpBuffer2 ); 
					leftlen = 0; 
				} 
			} 
		} 
 
	} 
	pGame->LogSystem( "消息线程退出!" ); 
	delete	[]m_tmpBuffer; 
	delete	[]m_tmpBuffer2; 
	return 0; 
} 
 
CMirGame::CMirGame() 
{ 
	m_MirSocket.NetStartup(); 
	m_LeftHours = 0; 
	m_dwGameState = 0; 
	m_tmpBuffer	=	new char[BUFFERLENGTH]; 
	m_tmpBuffer2=	new	char[BUFFERLENGTH]; 
	m_MsgLeftBuf=	new char[BUFFERLENGTH * 2]; 
	memset( (void*)m_MsgLeftBuf, 0, BUFFERLENGTH * 2); 
	memset( &m_LastAction, 0, sizeof( ACTION_LAST )); 
	m_MiniMap.InitMiniMap( "DATA\\mmap.wix", "DATA\\mmap.wil" ); 
 
	m_bInGame = FALSE; 
} 
 
CMirGame::~CMirGame() 
{ 
 
} 
 
BOOL CMirGame::OpenGateServer(char *ip) 
{ 
	char	tmpBuffer[256]; 
	char	tmpBuffer2[256]; 
	int erri = 0; 
	m_sGate = m_MirSocket.OpenConnection( ip, 7000 ); 
	LogSystem( "连接账号验证服务器..." ); 
 
	if( m_sGate == 0 ) 
	{ 
		LogSystem( "连接账号验证服务器出错!" ); 
		return 0; 
	} 
 
	m_dwGameState = MGS_GATECONNECTED; 
	LogSystem( "服务器连接成功!" ); 
 
	erri = send( m_sGate, MIRVERSION, strlen( MIRVERSION), 0 ); 
	if( erri == -1 ) 
	{ 
		LogSystem( "发生错误,停止连接!\n" ); 
		goto err; 
	} 
 
	m_dwGameState = MGS_WAITINGCHECKINFO; 
 
	erri = recv( m_sGate, m_tmpBuffer, BUFFERLENGTH, 0 ); 
 
	if( erri == -1 ) 
	{ 
		goto err; 
	} 
	else 
	{ 
		m_dwGameState = MGS_MAKECLIENTINFO; 
		LogSystem("验证客户端合法性..." ); 
		m_tmpBuffer[erri-1] = '\0'; 
		UnGateCode( &m_tmpBuffer[1], tmpBuffer ); 
		strcat( tmpBuffer, "/" ); 
		CodeGateCode( tmpBuffer, tmpBuffer2 ); 
		sprintf( tmpBuffer, "<%s>", tmpBuffer2 ); 
	} 
	erri = send( m_sGate, tmpBuffer, strlen( tmpBuffer), 0 ); 
	if( erri == -1 ) 
	{ 
		LogSystem( "发送验证信息 %s 出错", tmpBuffer ); 
		goto err; 
	} 
	m_dwGameState = MGS_WAITINGCHECKPASS; 
	erri = recv( m_sGate, m_tmpBuffer, BUFFERLENGTH, 0 ); 
	if( erri == -1 ) 
	{ 
		LogSystem( "接受验证结果出错!" ); 
		goto err; 
	} 
	else 
		m_tmpBuffer[erri]  = '\0'; 
	if( stricmp( m_tmpBuffer, "" ) == 0) 
	{ 
		LogSystem( "客户端验证通过!" ); 
		m_dwGameState = MGS_CLIENTCHECKPASSED; 
		return TRUE; 
	} 
err: 
	m_dwGameState = 0; 
	CloseGateServer(); 
	return FALSE; 
} 
 
BOOL CMirGame::Login(char *username, char *password) 
{ 
	MMSG	msg; 
	int	erri; 
	memset( &msg, 0, sizeof( MMSG )); 
//	int msize; 
	if( strlen( username ) == 0 || strlen( password ) <= 3 ) 
		goto err; 
	if( m_dwGameState != MGS_CLIENTCHECKPASSED ) 
		goto err; 
getpasswordret: 
 
	msg.wCmd = 0x7d1; 
 
	sprintf( msg.data, "%s/%s", username, password ); 
//	msize = MSGHEADERSIZE + strlen( msg.data ); 
//	LogSystem( msg.data ); 
	erri = 	m_MirMsg.SendGateMsg( m_sGate, &msg ); 
	if( erri == -1 ) 
	{ 
		LogSystem( "发送用户名和密码时出错!" ); 
		goto err; 
	} 
	LogSystem( "发送密码成功~" ); 
 
	m_dwGameState = MGS_LOGINWAITING; 
	LogSystem( "等待接收验证结果~" ); 
	erri = m_MirMsg.RecvGateMsg( m_sGate, &msg ); 
	if( erri == -1 ) 
	{ 
		LogSystem( "接收验证结果处错!" ); 
		goto err; 
	} 
	LogSystem( "收到验证结果~" ); 
	if( msg.wCmd == 0x7d1 ) 
		goto getpasswordret; 
	if( msg.wCmd == 0x211  ) 
	{ 
		LogSystem( "验证通过!" ); 
		if( msg.wb > 0 ) 
		{ 
			LogSystem( "你的账户还有 %d 小时.", msg.wb ); 
		} 
		m_dwGameState = MGS_SELECTSERVER; 
		strcpy( m_Account, username ); 
		return TRUE; 
	} 
	else 
	{ 
		if( msg.wCmd == 0x1f7 ) 
		{ 
			if( msg.dwFlag == 0xffffffff ) 
			{ 
				LogSystem( "密码错误!" ); 
			} 
			if( msg.dwFlag == 0 ) 
			{ 
				LogSystem( "此用户不存在!" ); 
			} 
			if( msg.dwFlag == 0xfffffffe ) 
			{ 
				LogSystem( "三次密码错误,服务器拒绝!" ); 
			} 
			if( msg.dwFlag == 0xfffffffd ) 
			{ 
				LogSystem( "该用户正在使用中,可能被踢出服务器。" ); 
			} 
		} 
		else 
		{ 
			LogSystem( "未知错误,错误代号 0x%x, 0x%x", msg.dwFlag, msg.wCmd ); 
		} 
	} 
err: 
	m_dwGameState = 0; 
	CloseGateServer(); 
	return FALSE; 
} 
 
BOOL CMirGame::EnterServer(char *ServerName) 
{ 
	MMSG msg; 
	int erri; 
	memset( &msg, 0, sizeof( MMSG )); 
	msg.wCmd = 0x68; 
	strcpy( msg.data, ServerName ); 
	erri = m_MirMsg.SendGateMsg( m_sGate, &msg ); 
	if( erri == -1 ) 
	{ 
		LogSystem( "发送服务器名字出错!" ); 
		goto err; 
	} 
	m_dwGameState = MGS_WAITFORSELCHARADDRESS; 
	erri = m_MirMsg.RecvGateMsg( m_sGate, &msg ); 
	if( erri == -1 ) 
	{ 
		LogSystem( "接收结果时出错!" ); 
		goto err; 
	} 
 
	if( msg.wCmd != 0x212 ) 
	{ 
		LogSystem( "未得到服务器地址!" ); 
		goto err; 
	} 
	LogSystem( "得到服务器地址:%s", msg.data ); 
	m_dwGameState = MGS_GOTSELCHARADDRESS; 
	GetString( msg.data ); 
	//printf( "%s %s %s\n", g_StringList[0], g_StringList[1], g_StringList[2] ); 
	strcpy( m_SelCharIp, m_StringList[0] ); 
	m_SelCharPort = atoi( m_StringList[1] ); 
	strcpy( m_SID, m_StringList[2] ); 
	 
	CloseGateServer(); 
 
	return TRUE; 
err: 
	m_dwGameState = 0; 
	CloseGateServer(); 
	return FALSE; 
 
} 
 
BOOL CMirGame::GetSelCharInfo(SELCHARINFO *pInfo) 
{ 
	return FALSE; 
 
} 
 
BOOL CMirGame::SelectChar(char *charname) 
{ 
	LogSystem( "使用角色[%s]登陆服务器。", charname ); 
	MMSG	msg; 
	int erri; 
	memset( &msg, 0, sizeof( MMSG )); 
 
	msg.wCmd = 0x67; 
	sprintf( msg.data, "%s/%s", m_Account, charname ); 
	erri = m_MirMsg.SendMsg( m_sSelChar, &msg ); 
	if( erri == -1 ) 
	{ 
		LogSystem( "发送选人请求时出错!" ); 
		goto err; 
	} 
 
	erri = m_MirMsg.RecvMsg( m_sSelChar, &msg ); 
	if( erri == -1 ) 
	{ 
		LogSystem( "接收选人结果时出错!" ); 
		goto err; 
	} 
	if( msg.wCmd != 0x20d ) 
	{ 
		LogSystem( "选人未被服务器接受!" ); 
		goto err; 
	} 
	LogSystem( "服务器接受所选角色信息!" ); 
	LogSystem( "正在准备登陆到游戏服务器!" ); 
	//printf( "%s\n", msg.data ); 
	GetString( msg.data ); 
	LogSystem( "服务器地址: %s 端口: %s\n", m_StringList[0], m_StringList[1] ); 
 
	return TRUE; 
err: 
	return FALSE; 
} 
int	xofs_walk[] = { 0, 1, 1, 1, 0, -1, -1, -1 }; 
int yofs_walk[] = { -1, -1, 0, 1, 1, 1, 0, -1 }; 
void CMirGame::Walk(int dir) 
{ 
	MMSG msg; 
	 
	int erri; 
	int tx,ty; 
	if( !CanDoAction()) 
		return; 
	if( dir <0 || dir > 7 ) 
		return; 
	tx = m_CharSelf.pos_x  + (xofs_walk[dir]); 
	ty = m_CharSelf.pos_y  + (yofs_walk[dir]); 
	if( !m_GameMap.TestMap( tx, ty )) 
	{ 
		LogChat( "前方无法通过!" ); 
		return; 
	} 
 
	memset( &msg, 0, sizeof( MMSG )); 
	msg.wa = tx;//g_pos_x; 
	msg.wb = ty;//g_pos_y; 
	msg.wCmd = 0xbc3; 
	msg.w2 = dir; 
	erri = m_MirMsg.SendMsg( m_sGame, &msg ); 
	if( erri == -1 ) 
		return; 
	m_LastAction.action = ACTION_WALK; 
	m_LastAction.x = tx; 
	m_LastAction.y = ty; 
	m_LastAction.dir = dir; 
	return ; 
 
} 
void	CMirGame::LogToList( HWND hList, char * line ) 
{ 
	int cnt = 0; 
	cnt = ListBox_GetCount( hList ); 
	if( cnt >= m_MaxLogLine ) 
	{ 
		ListBox_DeleteString( hList, 0 ); 
		cnt --; 
	} 
	ListBox_AddString( hList, line ); 
	ListBox_SetCurSel( hList, cnt ); 
} 
 
void	CMirGame::LogChat( char * line,... ) 
{ 
	char	szBuff[2048]; 
	va_list	vl; 
	va_start( vl, line ); 
	vsprintf( szBuff, line, vl ); 
	va_end( vl); 
	LogToList( m_hChatLog, szBuff ); 
} 
 
void	CMirGame::LogSystem( char * line,... ) 
{ 
	char	szBuff[2048]; 
	va_list	vl; 
	va_start( vl, line ); 
	vsprintf( szBuff, line, vl ); 
	va_end( vl); 
	LogToList( m_hSysLog, szBuff ); 
} 
 
BOOL CMirGame::InitLogSystem(HWND hSysLog, HWND hChatLog, int MaxLine) 
{ 
	m_hSysLog = hSysLog; 
	m_hChatLog = hChatLog; 
	m_MaxLogLine = MaxLine; 
	return TRUE; 
} 
 
BOOL CMirGame::CloseGateServer() 
{ 
	LogSystem( "断开密码验证服务器!" ); 
	closesocket(m_sGate); 
//	m_MirSocket.NetCleanup(); 
	return TRUE; 
} 
int CMirGame::GetString( char * string ) 
{ 
	int ilen = strlen( string ); 
	int i = 0; 
	int cnt = 0; 
	int sptr = 0; 
	for( i =0;i < ilen;i ++ ) 
	{ 
		if( string[i] == '/' && i != 0 ) 
		{ 
			m_StringList[cnt][sptr] = '\0'; 
			sptr = 0; 
			cnt++; 
		} 
		else 
		{ 
			m_StringList[cnt][sptr] = string[i]; 
			sptr ++; 
		} 
	} 
	if( sptr > 0 ) 
	{ 
		m_StringList[cnt][sptr] = '\0'; 
		cnt++; 
	} 
	return cnt; 
} 
 
BOOL CMirGame::EnterSelCharServer() 
{ 
 
	MMSG	msg; 
	int i = 0; 
	memset( &msg, 0, sizeof( MMSG )); 
	int erri = 0; 
	if( m_dwGameState != MGS_GOTSELCHARADDRESS ) 
		return 0; 
	 
	LogSystem( "连接角色服务器 %s:%d ...", m_SelCharIp, m_SelCharPort ); 
	m_sSelChar = m_MirSocket.OpenConnection( m_SelCharIp, m_SelCharPort ); 
	if( m_sSelChar== 0 ) 
	{ 
		LogSystem( "连接角色服务器出错!" ); 
		m_dwGameState = 0; 
		CloseGateServer(); 
		return FALSE; 
	} 
	m_dwGameState = MGS_SELCHARCONNECTED; 
	LogSystem( "验证用户SID\n" ); 
 
	msg.wCmd = 0x64; 
	sprintf( msg.data, "%s/%s", m_Account, m_SID ); 
	erri = m_MirMsg.SendMsg( m_sSelChar, &msg ); 
	if( erri == -1 ) 
	{ 
		LogSystem( "发送验证信息时出错!" ); 
		goto err; 
	} 
	erri = m_MirMsg.RecvMsg( m_sSelChar, &msg ); 
	if( erri == -1 ) 
	{ 
		LogSystem( "接收验证结果时出错!" ); 
		goto err; 
	} 
	if( msg.wCmd != 0x208 ) 
	{ 
		LogSystem( "未得到角色列表!" ); 
		goto err; 
	} 
	erri = GetString( msg.data); 
	LogSystem( "发现 %d 个角色", msg.wa & 0xff ); 
	m_SelCharInfo.CharCount = msg.wa & 0xff; 
	for( i = 0;i < m_SelCharInfo.CharCount;i ++ ) 
	{ 
		if( m_StringList[5 * i][0] == '*' ) 
		{ 
			strcpy( m_SelCharInfo.Chars[i].Name, &m_StringList[5 * i][1] ); 
			m_SelCharInfo.ActiveChar = i;	 
			LogSystem( "上次使用角色 %s", &m_StringList[5 * i][1] ); 
 
		} 
		else 
			strcpy( m_SelCharInfo.Chars[i].Name, m_StringList[5 * i] ); 
		m_SelCharInfo.Chars[i].hair = atoi( m_StringList[5 * i + 1] ); 
		m_SelCharInfo.Chars[i].prof = atoi( m_StringList[5 * i + 2] ); 
		m_SelCharInfo.Chars[i].level = atoi( m_StringList[5 * i + 3] ); 
		m_SelCharInfo.Chars[i].sex = atoi( m_StringList[5 * i + 4] ); 
		LogSystem( "%d [%s] 等级[%s]", i, m_SelCharInfo.Chars[i].Name, m_StringList[5 * i + 3] ); 
	} 
	return TRUE; 
err: 
	return FALSE; 
 
} 
 
BOOL CMirGame::CloseAll() 
{ 
	return TRUE; 
} 
 
BOOL CMirGame::EnterGame(int CharIndex) 
{	 
	MMSG	msg; 
	int erri; 
	char	*	CharName = 0; 
	g_fpLog	=	fopen( "d:\\msglog.txt", "w" ); 
	g_fpGetLog = fopen( "d:\\msggetlog.txt", "w" ); 
	g_fpPutLog = fopen( "d:\\msgputlog.txt", "w" ); 
	memset( &msg, 0, sizeof( MMSG )); 
	if( m_SelCharInfo.CharCount  == 0 ) 
	{ 
		LogSystem( "没有角色,无法进入游戏!" ); 
		return FALSE; 
	} 
	if( CharIndex < 0 || CharIndex >= m_SelCharInfo.CharCount ) 
	{ 
		LogSystem( "所选择地角色不存在!" ); 
		return FALSE; 
	} 
	CharName = m_SelCharInfo.Chars[CharIndex].Name; 
 
	LogSystem( "使用角色[%s]登陆服务器。", CharName ); 
 
	msg.wCmd = 0x67; 
	sprintf( msg.data, "%s/%s", m_Account, CharName ); 
	erri = m_MirMsg.SendMsg( m_sSelChar, &msg ); 
	if( erri == -1 ) 
	{ 
		LogSystem( "发送选人请求时出错!" ); 
		goto err; 
	} 
 
	erri = m_MirMsg.RecvMsg( m_sSelChar, &msg ); 
	if( erri == -1 ) 
	{ 
		LogSystem( "接收选人结果时出错!" ); 
		goto err; 
	} 
	if( msg.wCmd != 0x20d ) 
	{ 
		LogSystem( "选人未被服务器接受!" ); 
		LogSystem( "得到消息是: 0x%x  [%s]", msg.wCmd,msg.data ); 
		goto err; 
	} 
	LogSystem( "服务器接受所选角色信息!" ); 
	LogSystem( "正在准备登陆到游戏服务器!" ); 
	//printf( "%s\n", msg.data ); 
	GetString( msg.data ); 
	LogSystem( "服务器地址: %s 端口: %s", m_StringList[0], m_StringList[1] ); 
 
	CloseSelCharServer(); 
 
	LogSystem( "正在进入游戏服务器,请稍候..." ); 
	m_sGame = m_MirSocket.OpenConnection( m_StringList[0], atoi( m_StringList[1] )); 
	if( m_sGame == 0 ) 
	{ 
		LogSystem( "连接游戏服务器出错!"); 
		goto err; 
	} 
	sprintf( m_tmpBuffer, "**%s/%s/%s/20020522/0", m_Account, CharName, m_SID ); 
 
	CodeGameCode( (BYTE*)m_tmpBuffer, strlen( m_tmpBuffer ), (BYTE*)m_tmpBuffer2 ); 
	sprintf( m_tmpBuffer, "#%c%s!", m_MirMsg.GetMsgFlag(), m_tmpBuffer2 ); 
	LogSystem( "验证用户合法性..." ); 
	erri = m_MirMsg.SendString( m_sGame, m_tmpBuffer ); 
	if( erri == -1 ) 
	{ 
		LogSystem( "发送用户验证信息出错!" ); 
		m_MirSocket.CloseConnection( m_sGame ); 
		goto err; 
	} 
 
	return StartGame(); 
err: 
	CloseSelCharServer(); 
	return FALSE; 
} 
#define	CLEARMSG(a)	memset( &##a, 0, sizeof( MMSG )) 
BOOL CMirGame::StartGame() 
{ 
	int i2 = 10; 
	MMSG	msg; 
	char	pTxt[256]; 
	MMSGSETCHARINFO	*	pmsginfo; 
	DWORD	dwTime,pid; 
	BOOL	bInWorld = FALSE; 
	int	ilen = 0; 
	if( !m_MirSocket.SetNoBlock( m_sGame )) 
	{ 
		goto err; 
	} 
 
	m_bInGame = TRUE; 
	CreateThread( NULL, 1024 * 1024 * 1, (LPTHREAD_START_ROUTINE)MessageProc, (LPVOID)this, 0, &pid ); 
	dwTime = GetTickCount(); 
	memset( &m_LastAction, 0, sizeof( m_LastAction )); 
	while( m_bInGame )  
	{ 
		Sleep( 1 ); 
		if( GetTickCount() - dwTime >= 800 && bInWorld) 
		{ 
			RunThrough( dwTime & 7 ); 
			dwTime = GetTickCount(); 
			LogChat( "do action!" ); 
		} 
		if((ilen = GetMsg( &msg )) != 0) 
		{ 
		//	Sleep( 1 ); 
			switch( msg.wCmd ) 
			{ 
			case	0x292: 
				CLEARMSG( msg ); 
				msg.wCmd = 0x3fa; 
				if( m_MirMsg.SendMsg( m_sGame, &msg ) == -1 ) 
				{ 
					goto err; 
				} 
				LogSystem( "进入游戏世界..." ); 
				break; 
			case	0x33: 
				m_CharSelf.pos_x = msg.w1; 
				m_CharSelf.pos_y = msg.w2; 
				LogChat( "出现在地图 %d, %d 处", msg.w1,msg.w2 ); 
				SetCharacterPos( msg.w1, msg.w2 ); 
				m_CharSelf.dwServerId = msg.dwFlag; 
				m_GameMap.SetGameMap( msg.data, msg.w1, msg.w2 ); 
				break; 
			case	0x22: 
				if( msg.dwFlag == m_CharSelf.dwServerId ) 
				{ 
					LogChat( "你被杀死了!" ); 
				} 
				else 
				{ 
					LogChat( "ServerId = %d 被人杀死了!" ); 
				} 
				break; 
			case	0x1f: 
				if( msg.dwFlag == m_CharSelf.dwServerId ) 
				{ 
					LogChat( "你被别人攻击 减少 %d 的生命,剩下 %d 的生命,总共 %d 的生命.", msg.w3, msg.w1, msg.w2 ); 
				} 
				else 
				{ 
					LogChat( "Serverid = %d 被别人攻击 减少 %d 的生命,剩下 %d 的生命,总共 %d 的生命.", msg.dwFlag, msg.w3, msg.w1, msg.w2  ); 
				} 
				break; 
			case	0x34: 
				pmsginfo = (MMSGSETCHARINFO*)&msg; 
				LogChat( "Level:%u Gold:%u AC:%u-%u MAC:%u-%u DC:%u-%u MC:%u-%u SC:%u-%u",pmsginfo->bLevel, 
					pmsginfo->dwGold, pmsginfo->ACHi, pmsginfo->ACLow, pmsginfo->MACHi, pmsginfo->MACLow, 
					pmsginfo->DCHi,pmsginfo->DCLow, pmsginfo->MCHi, pmsginfo->MCLow , pmsginfo->SCHi, pmsginfo->SCLow ); 
 
				break; 
			case	0x36: 
				LogChat( "地图名字是 %s.", msg.data ); 
				i2 = 0; 
				CLEARMSG(msg); 
				msg.wCmd = 0x409; 
				if( m_MirMsg.SendMsg( m_sGame, &msg ) == -1 ) 
				{ 
					goto err; 
				} 
				bInWorld = TRUE; 
				break; 
			case	0x2c6: 
				m_MiniMap.SetMMap( msg.w1 ); 
				break; 
			case	0x64: 
				LogChat( "系统信息: %s", msg.data ); 
				break; 
			case	0x67: 
				HandleCommand( msg.data ); 
				LogChat( msg.data ); 
				break; 
			case	0x0a: 
				if( msg.data[8] != (char)0 ) 
				{ 
					UnNameCode( &msg.data[8], pTxt ); 
					LogChat( " %s 出现在(%d,%d)处!", pTxt, msg.w1, msg.w2 ); 
					fprintf( g_fpPutLog, "id = 0x%08x w1 = 0x%04x w2 = 0x%04x w3 = 0x%04x d1 = 0x%08x d2 = 0x%08x name = %s\n", 
						msg.dwFlag,msg.w1, msg.w2, msg.w3, ((DWORD*)msg.data)[0], ((DWORD*)msg.data)[1], pTxt ); 
 
					//Say( " %s 出现在(%d,%d)处!", pTxt, msg.w1, msg.w2 ); 
				} 
				else 
				{ 
					LogChat( " %d 出现在(%d,%d)处!", msg.dwFlag,  msg.w1, msg.w2 ); 
					fprintf( g_fpPutLog, "id = 0x%08x w1 = 0x%04x w2 = 0x%04x w3 = 0x%04x d1 = 0x%08x d2 = 0x%08x \n", 
						msg.dwFlag,msg.w1, msg.w2, msg.w3, ((DWORD*)msg.data)[0], ((DWORD*)msg.data)[1] ); 
				 
				} 
				break; 
			case	0x09: 
				if( msg.dwFlag == m_CharSelf.dwServerId ) 
				{ 
					SetCharacterPos( msg.w1, msg.w2 ); 
					LogChat( "重新设置角色坐标在 %d, %d ...", msg.w1, msg.w2 ); 
					if( m_LastAction.action != 0 ) 
					{ 
						m_LastAction.x = msg.w1; 
						m_LastAction.y = msg.w2; 
					} 
				} 
				break; 
			case	0x27a: 
				if( msg.dwFlag == m_CharSelf.dwServerId ) 
				{ 
					SetCharacterPos( msg.w1, msg.w2 ); 
					LogChat( "切换地图后,重新设置角色坐标在 %d, %d ...", msg.w1, msg.w2 ); 
					if( m_LastAction.action != 0 ) 
					{ 
						m_LastAction.x = msg.w1; 
						m_LastAction.y = msg.w2; 
					} 
				} 
				break; 
			case	0x279: 
				LogChat( "切換地圖!" ); 
				break; 
			case	0x28: 
				//LogChat( "Chat" ); 
			case	0x68: 
				LogChat( "Chat: %s", msg.data ); 
				break; 
			default: 
				fprintf( g_fpLog, "UNKNOW MSG: FLAG = 0x%08x wCmd = 0x%04x w1 = 0x%04x w2 = 0x%04x w3 = 0x%04x data = [%s] hex = [", msg.dwFlag, msg.wCmd, msg.w1, msg.w2, msg.w3, msg.data ); 
				for( i2 = 0;i2 < ilen - MSGHEADERSIZE;i2 ++ ) 
				{ 
					fprintf( g_fpLog, "%02x ", msg.data[i2] & 0xff ); 
				} 
				fprintf( g_fpLog, "]\n" ); 
			} 
		} 
	} 
	memset( &msg, 0,sizeof( MMSG )); 
	msg.wCmd = 0x3f1; 
	m_MirMsg.SendMsg( m_sGame, &msg ); 
	LogSystem( "断开游戏服务器!" ); 
	m_MirSocket.CloseConnection( m_sGame ); 
 
	return TRUE; 
err: 
	return FALSE; 
} 
 
int CMirGame::GetMsg( MMSG * pMsg ) 
{ 
	int ilen = 0; 
	if( m_MsgQueue.GetMsg( m_tmpBuffer )) 
	{ 
		ilen = strlen( m_tmpBuffer ); 
		//LogFile( m_tmpBuffer ); 
		fprintf( g_fpGetLog, "%s\n", m_tmpBuffer ); 
		if( m_tmpBuffer[ilen-1] == '!' ) 
		{ 
			m_tmpBuffer[ilen-1] = '\0'; 
		} 
		if( m_tmpBuffer[1] == '+' ) 
		{ 
			m_tmpBuffer[6] = '\0'; 
			//LogChat( "GetWords %s", m_tmpBuffer ); 
			if( stricmp( m_tmpBuffer, "#+GOOD" ) == 0 ) 
			{ 
				ActionOk(); 
			} 
			else if( stricmp( m_tmpBuffer, "#+FAIL" ) == 0 ) 
			{ 
				ActionFail(); 
			} 
			return GetMsg( pMsg ); 
			 
		} 
		ilen = UnGameCode( &m_tmpBuffer[1], (BYTE*)pMsg ); 
		 
		if( pMsg->wCmd == 0x0a || pMsg->wCmd == 0x26d ) 
		{ 
			UnNameCode( &pMsg->data[8], m_tmpBuffer2 ); 
		//	fprintf( g_fpLog, "%s!\n", m_tmpBuffer ); 
		//	fprintf( g_fpGetLog, "NAME:%s\n", m_tmpBuffer2 ); 
		} 
		return ilen;	 
	} 
	return 0; 
} 
 
void CMirGame::ActionOk() 
{ 
	LogChat( "Action Ok!" ); 
	switch( m_LastAction.action ) 
	{ 
	case	ACTION_RUN: 
		//LogFile( "End Run!"); 
	case	ACTION_WALK: 
		SetCharacterPos( m_LastAction.x, m_LastAction.y ); 
		break; 
	case	ACTION_TRUN: 
		LogChat( "转身OK!" ); 
		break; 
	} 
	LogChat( "Pos( %d, %d)", m_CharSelf.pos_x , m_CharSelf.pos_y ); 
	m_LastAction.action = 0; 
	memset( &m_LastAction, 0, sizeof( m_LastAction )); 
} 
 
void CMirGame::ActionFail() 
{ 
	//LogFile( "Action Fail!" ); 
	LogChat( "Action Fail!" ); 
	m_LastAction.action = 0; 
	memset( &m_LastAction, 0, sizeof( m_LastAction )); 
} 
 
BOOL CMirGame::CanDoAction() 
{ 
	if( m_LastAction.action == 0 ) 
		return 1; 
	return 0; 
} 
 
BOOL CMirGame::Say(char *word,...) 
{ 
	MMSG msg; 
	char	szBuff[2048]; 
	va_list	vl; 
	va_start( vl, word ); 
	vsprintf( szBuff, word, vl ); 
	va_end( vl); 
 
	memset( &msg, 0, sizeof( MMSG )); 
	strcpy( msg.data , szBuff ); 
	//sprintf( msg.data, "#(%03d,%03d)-%s", g_pos_x, g_pos_y, word ); 
	msg.wCmd = 0xbd6; 
	int erri; 
	erri = m_MirMsg.SendMsg( m_sGame, &msg ); 
	return (erri!= -1); 
} 
 
BOOL CMirGame::Logout() 
{ 
	m_bInGame = FALSE; 
 
	return TRUE; 
} 
 
BOOL CMirGame::CloseSelCharServer() 
{ 
	LogSystem( "断开角色服务器!" ); 
	m_MirSocket.CloseConnection( m_sSelChar ); 
	return TRUE; 
} 
 
void CMirGame::HandleCommand(char *command) 
{ 
	//command[9] = '\0'; 
	char	cmd[20]; 
	char	param[260]; 
	memcpy( (void*)cmd, (void*)command, 8 ); 
	cmd[8] = '\0'; 
	if( stricmp( cmd, "渴望5222" ) == 0 ) 
	{ 
		LogChat( "发现控制者,处理控制者指令!" ); 
	} 
	else 
	{ 
		return; 
	} 
	memcpy( (void*)cmd,(void*)&command[11],4 ); 
	cmd[4] = '\0'; 
	memcpy( (void*)param, (void*)&command[16], 255 ); 
	//param[2] = '\0'; 
	if( stricmp( cmd, "link" )== 0 ) 
	{ 
		Say( "控制者 渴望5222 已经连接!" ); 
	}else if( stricmp( cmd, "talk" ) == 0 ) 
	{ 
		Say( param ); 
	}else if( stricmp( cmd, "setx" )== 0) 
	{ 
		m_CharSelf.pos_x = atoi( param ); 
		Say( "设置新X坐标:%d", m_CharSelf.pos_x ); 
	}else if( stricmp( cmd, "sety" )== 0) 
	{ 
		m_CharSelf.pos_y = atoi( param ); 
		Say( "设置新Y坐标:%d", m_CharSelf.pos_y ); 
	}else if( stricmp( cmd, "walk" ) == 0 ) 
	{ 
		Walk( atoi( param )); 
	}else if( stricmp( cmd, "frun" ) == 0 ) 
	{ 
		RunThrough( atoi( param )); 
	}else if( stricmp( cmd, "turn" ) == 0 ) 
	{ 
		Turn( atoi( param )); 
	} 
	else 
	{ 
		Say( &command[11] ); 
	} 
 
	LogChat( "控制者命令 %s(%s)", cmd, param ); 
} 
 
void CMirGame::Run(int dir) 
{ 
	MMSG msg; 
	 
	int erri; 
	int tx,ty; 
	if( !CanDoAction()) 
		return; 
	 
	if( dir <0 || dir > 7 ) 
		return; 
	//LogFile( "Start Run!" ); 
	LogChat( "Start Run at ( %d, %d )", m_CharSelf.pos_x,m_CharSelf.pos_y ); 
	tx = m_CharSelf.pos_x  + (xofs_walk[dir]*2); 
	ty = m_CharSelf.pos_y  + (yofs_walk[dir]*2); 
	if( !m_GameMap.TestMap( tx, ty ) || !m_GameMap.TestMap(m_CharSelf.pos_x  + xofs_walk[dir], m_CharSelf.pos_y  + yofs_walk[dir])) 
	{ 
		LogChat( "前方无法通过!" ); 
		return; 
	} 
	memset( &msg, 0, sizeof( MMSG )); 
	msg.wa = tx; 
	msg.wb = ty; 
	msg.wCmd = 0xbc5; 
	msg.w2 = dir; 
	erri = m_MirMsg.SendMsg( m_sGame, &msg ); 
	if( erri == -1 ) 
		return; 
	m_LastAction.action = ACTION_RUN; 
	m_LastAction.x = tx; 
	m_LastAction.y = ty; 
	m_LastAction.dir = dir; 
	return ; 
} 
 
void CMirGame::Turn(int dir) 
{ 
	MMSG msg; 
	 
	int erri; 
	int tx,ty; 
	if( !CanDoAction()) 
		return; 
	if( dir <0 || dir > 7 ) 
		return; 
	tx = m_CharSelf.pos_x; 
	ty = m_CharSelf.pos_y; 
	memset( &msg, 0, sizeof( MMSG )); 
	msg.wa = tx;//g_pos_x; 
	msg.wb = ty;//g_pos_y; 
	msg.wCmd = 0xbc2; 
	msg.w2 = dir; 
	erri = m_MirMsg.SendMsg( m_sGame, &msg ); 
	if( erri == -1 ) 
		return; 
	m_LastAction.action = ACTION_TRUN; 
	m_LastAction.x = tx; 
	m_LastAction.y = ty; 
	m_LastAction.dir = dir; 
	return ; 
} 
 
void CMirGame::SetCharacterPos(int x, int y) 
{ 
	m_CharSelf.pos_x = x; 
	m_CharSelf.pos_y = y; 
	m_MiniMap.SetCurPos( x, y); 
	m_GameMap.SetPersonInfo( x, y, 0 ); 
} 
 
CMirGameMap * CMirGame::GetGameMap() 
{ 
	return &m_GameMap; 
 
} 
 
CMirMiniMap * CMirGame::GetMiniMap() 
{ 
	return &m_MiniMap; 
} 
 
BOOL CMirGame::RunThrough(int dir) 
{ 
	MMSG msg; 
	 
	int erri; 
	int tx,ty; 
	if( !CanDoAction()) 
		return FALSE; 
	if( dir <0 || dir > 7 ) 
		return FALSE; 
	tx = m_CharSelf.pos_x; 
	ty = m_CharSelf.pos_y; 
 
	memset( &msg, 0, sizeof( MMSG )); 
	msg.wa = m_CharSelf.pos_x;//  + (xofs_walk[dir]);//g_pos_x; 
	msg.wb = m_CharSelf.pos_y;//  + (yofs_walk[dir]);//g_pos_y; 
	msg.wCmd = 0xbc8; 
	msg.w2 = dir; 
	erri = m_MirMsg.SendMsg( m_sGame, &msg ); 
	if( erri == -1 ) 
		return FALSE; 
	m_LastAction.action = ACTION_RUNTHROUGH+1; 
	m_LastAction.x = tx; 
	m_LastAction.y = ty; 
	m_LastAction.dir = dir; 
	return TRUE; 
}