www.pudn.com > gamedata.rar > serverselect.c


// serverlogin.cpp : Defines the entry point for the application. 
// 
//#define WIN32_LEAN_AND_MEAN 
#include "stdafx.h" 
#include "resource.h" 
 
#define MAX_CHAR      1024 
 
BYTE G_BYTE_DOII_XorTable[D_XORTABLE_LENGTH] = { 0x31, 0x54, 0x76, 0x58, 0x42, 0x22, 0x12, 0x53 }; 
BYTE G_BYTE_XorTable[D_XORTABLE_LENGTH]; 
 
struct logindata 
{ 
    SOCKET      sock;                     
    char        InBuffer[4];         // 输入 
    OVERLAPPED  ovIn;          
    int         nOutBufIndex;        
    char        OutBuffer[MAXCHAR];  // 输出 
    OVERLAPPED  ovOut; 
    DWORD       dwWritten; 
 
	char        id[32]; 
	char        password[32]; 
	int         vip; 
	char        idcard[32]; 
 
	int         num[5]; 
	int         char_number; 
}; 
 
struct GAMESERVERINFO 
{ 
	int  index; 
	char name[50]; 
	char ip[50]; 
	int  port; 
}; 
 
#define MAX_LOADSTRING 100 
 
TBBUTTON tbButtons[] =  
{ 
	{ 0, IDM_STARTSERVICE,	TBSTATE_ENABLED,	TBSTYLE_BUTTON, 0L, 0}, 
	{ 1, IDM_STOPSERVICE,	TBSTATE_ENABLED,	TBSTYLE_BUTTON, 0L, 0},	 
	{ 2, IDM_FONTCOLOR,		TBSTATE_ENABLED,	TBSTYLE_BUTTON, 0L, 0}, 
	{ 3, IDM_BACKCOLOR,		TBSTATE_ENABLED,	TBSTYLE_BUTTON, 0L, 0}, 
}; 
 
TCHAR szTitle[MAX_LOADSTRING];								// The title bar text 
TCHAR szWindowClass[MAX_LOADSTRING];								// The title bar text 
HANDLE ghCompletionPort; 
 
struct GAMESERVERINFO pServerInfo; 
struct optiondata option; 
 
// Foward declarations of functions included in this code module: 
ATOM				MyRegisterClass(HINSTANCE hInstance); 
BOOL				InitInstance(HINSTANCE, int); 
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM); 
LRESULT CALLBACK	About(HWND, UINT, WPARAM, LPARAM); 
DWORD WINAPI        ServerThread(LPVOID pVoid); 
 
void SaveLog(char *p) 
{ 
	FILE *fp = fopen("c:\\Select.txt", "a+"); 
 
	if(fp != NULL)  
	{ 
		fprintf(fp,"%s\n",p); 
 
		fclose(fp); 
	} 
 
} 
 
BOOL getprobabilitystatus(int probability) 
{ 
	if ((rand()%10001)<= probability) 
		return TRUE; 
 
	return FALSE; 
}; 
 
BOOL getpercentageprobabilitystatus(int probability) 
{ 
	if ((rand()%101)<= probability) 
		return TRUE; 
 
	return FALSE; 
} 
 
void Encode1(BYTE buf, int data) 
{	 
	buf = data % 256; 
} 
	 
void Encode2(BYTE buf[2], int data) 
{ 
	buf[0] = (data / 256) % 256; 
	buf[1] = data % 256; 
} 
	 
void Encode4(BYTE buf[4], unsigned long data) 
{ 
	buf[0] = (char)(BYTE)((data / 256 / 256 / 256) % 256); 
	buf[1] = (char)(BYTE)((data / 256 / 256) % 256); 
	buf[2] = (char)(BYTE)((data / 256) % 256); 
	buf[3] = (char)(BYTE)(data % 256); 
} 
 
int Decode1(const BYTE *buf) 
{ 
	return buf[0]; 
} 
	 
int Decode2(BYTE n1, BYTE n2) 
{ 
	return ((int)n1 * (int)n2 * 256 + (int)n2); 
} 
	 
unsigned long Decode4(const BYTE buf[4]) 
{ 
	return buf[0] * 256 * 256 * 256 + buf[1] * 256 * 256 + buf[2] * 256 + buf[3]; 
} 
 
void GetExeDir(char* szExeDir) 
{ 
	char buf[MAX_PATH]; 
	char *cptr; 
 
	GetModuleFileNameA(NULL, buf, MAX_PATH); 
 
	//move pointer to end of string 
	cptr = buf + lstrlenA(buf); 
 
	//find the end of the path 
	do 
	{ 
		cptr--; 
	} while (*cptr != '\\'); 
	cptr++; 
	*cptr='\0'; 
	strcpy(szExeDir,buf); 
} 
 
int myrand(int min, int max) 
{ 
	if( min == max ) return min; 
 
	return (rand() % (max-min+1)) + min; 
} 
 
int DisplayErrorMsg(char *filename, SQLHANDLE hstmt) 
{ 
	SQLCHAR       SqlState[6], Msg[1024]; 
	SQLINTEGER    NativeError; 
	SQLSMALLINT   i, MsgLen; 
	SQLRETURN     rc2; 
	char		  logstr[512]; 
	memcpy(logstr, NULL, 0); 
 
	i = 1; 
	while ((rc2 = SQLGetDiagRec(SQL_HANDLE_STMT, hstmt, i, SqlState, &NativeError, Msg, sizeof(Msg), &MsgLen)) != SQL_NO_DATA) 
 
  //  rc2 = SQLGetDiagRec(SQL_HANDLE_STMT, hstmt, i, SqlState, &NativeError, Msg, sizeof(Msg), &MsgLen); 
	{ 
		sprintf(logstr, "*** %s, %d, %s, %d ***\r\n", SqlState, NativeError, Msg, MsgLen); 
	    SaveLog(logstr); 
 
		i++; 
	} 
 
	if( strcmp((char *)SqlState, "08S01") == 0 ) 
		return -1; 
	else 
		return 0; 
} 
 
SQLHDBC connectDB(char dsn[24], char uid[24], char pwd[24]) 
{ 
	SQLRETURN nResult;  
	SQLHENV henv; 
	SQLHDBC hdbc; 
 
	if (SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv) != SQL_SUCCESS)	 
		return NULL; 
 
	if(SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER) != SQL_SUCCESS) return FALSE; 
 
	if ((nResult = SQLAllocHandle(SQL_HANDLE_DBC, henv, (SQLHDBC FAR *)&hdbc)) != SQL_SUCCESS)    
	{  
		//   DisplayError(nResult, hWnd, SQL_HANDLE_ENV, henv);  
		return NULL;   
	} 
   
    nResult = SQLConnect(hdbc, (LPSTR)dsn, SQL_NTS, (LPSTR)uid, SQL_NTS,(LPSTR)pwd, SQL_NTS); 
    
    if (nResult != SQL_SUCCESS && nResult != SQL_SUCCESS_WITH_INFO) 
    { 
//      DisplayError(nResult, hWnd, SQL_HANDLE_DBC, hdbc); 
     
        SQLFreeHandle(SQL_HANDLE_DBC, hdbc); 
     
        return NULL; 
    } 
     
    return hdbc; 
} 
 
void disconnectDB(SQLHDBC hdbc, SQLHSTMT hstmt) 
{ 
    SQLRETURN retcode; 
 
    if (hstmt != NULL) 
    { 
        retcode = SQLFreeHandle(SQL_HANDLE_STMT, hstmt); 
        if (retcode != SQL_SUCCESS) 
            return; 
    } 
    if (hdbc != NULL) 
    { 
        retcode = SQLDisconnect(hdbc); 
        if (retcode != SQL_SUCCESS) 
            return; 
    } 
    if (hdbc != NULL) 
    { 
        retcode = SQLFreeHandle(SQL_HANDLE_DBC, hdbc); 
        if (retcode != SQL_SUCCESS) 
            return; 
    } 
         
/* 
    retcode = SQLFreeStmt(hstmt, SQL_DROP); 
    //*S调用SQLDisconnect函数关闭连接,例如: 
    retcode = SQLDisconnect(hdbc); 
    //*S调用SQLFreeConnect函数释放连接句柄及其相关的系统资源,例如: 
    retcode = SQLFreeConnect(hdbc); 
    //*S调用SQLFreeEnv函数释放环境句柄及其相关的系统资源,停止ODBC操作,例如: 
 //   retcode = SQLFreeEnv(henv); 
*/ 
} 
 
BOOL checkaccount(struct logindata  *login, char* id, char* psd) 
{ 
	SQLHSTMT		hstmt; 
    SQLHDBC         hdbc; 
	SQLRETURN		retcode; 
	BOOL			bData,	retval; 
	char			szSQL[1024]; 
	SQLINTEGER Indexind, nPoints; 
 
	memset( szSQL, 0x00, 1024 ); 
	Indexind = SQL_NTS; nPoints = 0; bData = TRUE;	retval = FALSE; hstmt = NULL; 
 
	//	wsprintf(szSQL, TEXT("SELECT * FROM TBL_ACCOUNT WHERE FLD_ID='%s' AND FLD_PASSWORD='%s'"), id, psd); 
	sprintf(szSQL, "SELECT * FROM TBL_ACCOUNT WHERE FLD_ID='%s'", id); 
 
    hdbc    = connectDB(option.accountdsn, option.accountuid, option.accountpwd); 
	retcode = SQLAllocHandle((SQLSMALLINT)SQL_HANDLE_STMT, hdbc, &hstmt); 
 
	if (retcode == SQL_SUCCESS) 
	{ 
		retcode = SQLExecDirect (hstmt, (unsigned char *)szSQL, 1024); 
 
		if (retcode == SQL_SUCCESS|| retcode == SQL_SUCCESS_WITH_INFO)  
		{ 
			retcode = SQLFetch(hstmt); 
 
			if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)  
			{ 
				SQLGetData(hstmt, 1,  SQL_INTEGER,   &login->vip,       0,  &Indexind);      //  
			//	SQLGetData(hstmt, 17, SQL_C_TINYINT, &login->time,      0,  &Indexind); 
				SQLGetData(hstmt, 12, SQL_C_CHAR,    login->idcard,     50,  &Indexind);     // 身份证 
 
			//	sprintf(tmp1, "%d", login->vip); 
			//	MessageBoxA(NULL, tmp1, "", 0); 
				strcpy(login->id, id); 
				strcpy(login->password, psd); 
 
				retval = TRUE; 
			} 
		} 
		else  
		{		 
            DisplayErrorMsg("checkaccount", hstmt); 
 
			retval = FALSE; 
		} 
	} 
	else   
		retval = FALSE; 
 
    disconnectDB(hdbc, hstmt); 
 
	return retval; 
} 
 
BOOL loadidchar(char *id, struct OBJECT_INFO info[3]) 
{ 
	SQLHSTMT		hstmt; 
    SQLHDBC         hdbc; 
	char            tmp[255]; 
	SQLRETURN		retcode; 
	BOOL			bData,	retval; 
	char			szSQL[1024]; 
	SQLINTEGER Indexind, nPoints; 
	int a, i; 
 
	memset( szSQL, 0x00, 1024 ); 
	Indexind = SQL_NTS, nPoints = 0; hstmt = NULL; bData = TRUE; retval = FALSE; 
 
    a = i = 0; 
	sprintf(szSQL, "SELECT * FROM TBL_CHAR WHERE FLD_ID='%s'", id); 
 
    hdbc    = connectDB(option.chardsn, option.charuid, option.charpwd); 
	retcode = SQLAllocHandle((SQLSMALLINT)SQL_HANDLE_STMT, hdbc, &hstmt); 
 
	if (retcode == SQL_SUCCESS) 
	{ 
		retcode = SQLExecDirect (hstmt, (unsigned char *)szSQL, 1024); 
		if (retcode == SQL_SUCCESS|| retcode == SQL_SUCCESS_WITH_INFO)  
		{ 
			while(retcode=SQLFetch(hstmt)!=SQL_NO_DATA)  
			{ 
				SQLGetData(hstmt, 1,  SQL_C_CHAR,     info[a].id,              32,   &Indexind);     // 帐号 
				SQLGetData(hstmt, 2,  SQL_C_CHAR,     info[a].name,            32,   &Indexind);     // 角色名称 
				SQLGetData(hstmt, 3,  SQL_C_CHAR,     info[a].appellation,     32,   &Indexind);     // 称号 
				SQLGetData(hstmt, 4,  SQL_INTEGER,    &info[a].job,            0,    &Indexind);     // 职业 
				SQLGetData(hstmt, 5,  SQL_C_CHAR,     tmp,                     32,   &Indexind);     // 经验 
				info[a].exp = atol(tmp); 
				SQLGetData(hstmt, 6,  SQL_INTEGER,    &info[a].level,          0,    &Indexind);     // 等级 
				SQLGetData(hstmt, 7,  SQL_C_CHAR,     tmp,                     255,  &Indexind);     // 脸型 
				sscanf(tmp, "%d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d", 
					&info[a].face[0],  &info[a].face[1],  &info[a].face[2],  &info[a].face[3],  &info[a].face[4],  &info[a].face[5], 
					&info[a].face[6],  &info[a].face[7],  &info[a].face[8],  &info[a].face[9],  &info[a].face[10], &info[a].face[11], 
					&info[a].face[12], &info[a].face[13], &info[a].face[14], &info[a].face[15], &info[a].face[16], &info[a].face[17], 
					&info[a].face[18], &info[a].face[19]); 
				SQLGetData(hstmt, 8,  SQL_C_CHAR,     tmp,                     255,  &Indexind);     // 学习的魔法 
				sscanf(tmp, "%d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d", 
					&info[a].spell_[0],  &info[a].spell_[1],  &info[a].spell_[2],  &info[a].spell_[3],  &info[a].spell_[4], 
					&info[a].spell_[5],  &info[a].spell_[6],  &info[a].spell_[7],  &info[a].spell_[8],  &info[a].spell_[9], 
					&info[a].spell_[10], &info[a].spell_[11]); 
				SQLGetData(hstmt, 9,  SQL_INTEGER,    &info[a].direction,      0,    &Indexind);     // 方向 
				SQLGetData(hstmt, 10,  SQL_C_CHAR,    tmp,                     32,   &Indexind);     // 战斗经验 
				info[a].fight_exp = atol(tmp); 
				SQLGetData(hstmt, 11, SQL_INTEGER,    &info[a].pkexp,          0,    &Indexind);     // PK值 
				SQLGetData(hstmt, 12, SQL_C_CHAR,     tmp,                     32,   &Indexind);     // 钱 
				info[a].money = atol(tmp); 
				SQLGetData(hstmt, 13, SQL_INTEGER,    &info[a].life_now,       0,    &Indexind);     // 现在的生命数值 
				SQLGetData(hstmt, 14, SQL_INTEGER,    &info[a].mental_now,     0,    &Indexind);     // 现在的精神数值 
				SQLGetData(hstmt, 15, SQL_INTEGER,    &info[a].brawn_now ,     0,    &Indexind);     // 现在的体力数值 
				SQLGetData(hstmt, 16, SQL_INTEGER,    &info[a].biglifenumber,  0,    &Indexind);     // 现在的大号生命数值 
				SQLGetData(hstmt, 17, SQL_INTEGER,    &info[a].bigspellnumber, 0,    &Indexind);     // 现在的大号精神数值 
				SQLGetData(hstmt, 18, SQL_INTEGER,    &info[a].force,          0,    &Indexind);     // 力量 
				SQLGetData(hstmt, 19, SQL_INTEGER,    &info[a].somatic,        0,    &Indexind);     // 体质 
				SQLGetData(hstmt, 20, SQL_INTEGER,    &info[a].celerity,       0,    &Indexind);     // 敏捷 
				SQLGetData(hstmt, 21, SQL_INTEGER,    &info[a].wisdom,         0,    &Indexind);     // 智慧 
				SQLGetData(hstmt, 22, SQL_INTEGER,    &info[a].intellect,      0,    &Indexind);     // 智力 
				SQLGetData(hstmt, 23, SQL_INTEGER,    &info[a].citizenlevel,   0,    &Indexind);     // 市民等级 
				SQLGetData(hstmt, 24, SQL_INTEGER,    &info[a].citizenexp,     0,    &Indexind);     // 市民经验 
				SQLGetData(hstmt, 25, SQL_INTEGER,    &info[a].surplusskill1,  0,    &Indexind);     // 剩余点数 
				SQLGetData(hstmt, 26, SQL_INTEGER,    &info[a].surplusskill2,  0,    &Indexind);     // 剩余点数 
				SQLGetData(hstmt, 27, SQL_INTEGER,    &info[a].surplusskill3,  0,    &Indexind);     // 剩余点数 
				SQLGetData(hstmt, 28, SQL_C_CHAR,     tmp,                     255,  &Indexind);     // 技能 
				sscanf(tmp, "%d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d", 
					&info[a].skill1[0],  &info[a].skill1[1],  &info[a].skill1[2],  &info[a].skill1[3],  &info[a].skill1[4], 
					&info[a].skill1[5],  &info[a].skill1[6],  &info[a].skill1[7],  &info[a].skill1[8],  &info[a].skill1[9], 
					&info[a].skill1[10], &info[a].skill1[11], &info[a].skill1[12], &info[a].skill1[13], &info[a].skill1[14], 
					&info[a].skill1[15], &info[a].skill1[16], &info[a].skill1[17], &info[a].skill1[18], &info[a].skill1[19]); 
				SQLGetData(hstmt, 29, SQL_C_CHAR,     tmp,                     255,  &Indexind);     // 超能 
				sscanf(tmp, "%d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d", 
					&info[a].skill2[0],  &info[a].skill2[1],  &info[a].skill2[2],  &info[a].skill2[3],  &info[a].skill2[4], 
					&info[a].skill2[5],  &info[a].skill2[6],  &info[a].skill2[7],  &info[a].skill2[8],  &info[a].skill2[9], 
					&info[a].skill2[10], &info[a].skill2[11]); 
 
				for (i=0;i<39;i++) 
				{	 
					SQLGetData(hstmt, (SQLSMALLINT)(30 + i), SQL_C_CHAR,     tmp,                 255,  &Indexind); // 物品			 
					sscanf(tmp, "%d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d",		 
						&info[a].Novelity[i][0],  &info[a].Novelity[i][1],  &info[a].Novelity[i][2],  &info[a].Novelity[i][3],  &info[a].Novelity[i][4],		 
						&info[a].Novelity[i][5],  &info[a].Novelity[i][6],  &info[a].Novelity[i][7],  &info[a].Novelity[i][8],  &info[a].Novelity[i][9], 
						&info[a].Novelity[i][10], &info[a].Novelity[i][11], &info[a].Novelity[i][12], &info[a].Novelity[i][13], &info[a].Novelity[i][14], 
						&info[a].Novelity[i][15], &info[a].Novelity[i][16]); 
				} 
 
				SQLGetData(hstmt, 69, SQL_INTEGER,    &info[a].menow1,         0,    &Indexind);     //  位置 
				SQLGetData(hstmt, 70, SQL_INTEGER,    &info[a].menow2,         0,    &Indexind);     //  位置 
				SQLGetData(hstmt, 71, SQL_INTEGER,    &info[a].now_x,          0,    &Indexind);     //  坐标x 
				SQLGetData(hstmt, 72, SQL_INTEGER,    &info[a].now_y,          0,    &Indexind);     //  坐标y 
				SQLGetData(hstmt, 73, SQL_INTEGER,    &info[a].serverindex,    0,    &Indexind);     //  服务器号 
 
				info[a].have = TRUE; 
 
				a++; 
 
				if (a>=3) break; 
				 
				retval = TRUE; 
			}	 
		} 
		else  
		{ 
			DisplayErrorMsg("loadidchar", hstmt); 
 
			retval = FALSE; 
		} 
	} 
	else   
        retval = FALSE; 
 
    disconnectDB(hdbc, hstmt); 
 
	return retval; 
} 
 
BOOL findcharfull(char *id) 
{ 
	SQLHSTMT		hstmt; 
    SQLHDBC         hdbc; 
	SQLRETURN		retcode; 
	BOOL			bData,	retval; 
	char			szSQL[1024]; 
	SQLINTEGER Indexind, nPoints; 
	int a, i; 
 
	memset( szSQL, 0x00, 1024 ); 
	Indexind = SQL_NTS, nPoints = 0; hstmt = NULL; bData = TRUE; retval = FALSE; 
 
    a = i = 0; 
	sprintf(szSQL, "SELECT * FROM TBL_CHAR WHERE FLD_ID='%s'", id); 
 
    hdbc    = connectDB(option.chardsn, option.charuid, option.charpwd); 
	retcode = SQLAllocHandle((SQLSMALLINT)SQL_HANDLE_STMT, hdbc, &hstmt); 
     
	if (retcode == SQL_SUCCESS) 
	{ 
		retcode = SQLExecDirect (hstmt, (unsigned char *)szSQL, 1024); 
 
		if (retcode == SQL_SUCCESS|| retcode == SQL_SUCCESS_WITH_INFO)  
		{ 
			while(retcode=SQLFetch(hstmt)!=SQL_NO_DATA)  
			{ 
				a++; 
 
				if (a>=3)  
                { 
                    disconnectDB(hdbc, hstmt); 
					return TRUE; 
				}	 
			} 
            retval = FALSE; 
		} 
		else  
		{	 
            DisplayErrorMsg("findcharfull", hstmt); 	 
             
            retval = FALSE; 
		} 
	} 
	else   
		retval = FALSE; 
 
    disconnectDB(hdbc, hstmt); 
 
	return retval; 
} 
 
BOOL scanchar(char *id, char *name) 
{ 
	SQLHSTMT		hstmt; 
    SQLHDBC         hdbc; 
	SQLRETURN		retcode; 
	BOOL			bData,	retval; 
	char			szSQL[1024]; 
	SQLINTEGER Indexind, nPoints; 
 
	memset( szSQL, 0x00, 1024 ); 
	Indexind = SQL_NTS; nPoints = 0; 
	bData = TRUE;	retval = FALSE; hstmt = NULL; 
 
	sprintf(szSQL, "SELECT * FROM TBL_CHAR WHERE FLD_ID='%s' AND FLD_CHAR_NAME='%s'", id, name); 
 
    hdbc    = connectDB(option.chardsn, option.charuid, option.charpwd); 
	retcode = SQLAllocHandle((SQLSMALLINT)SQL_HANDLE_STMT, hdbc, &hstmt); 
 
	if (retcode == SQL_SUCCESS) 
	{ 
		retcode = SQLExecDirect (hstmt, (unsigned char *)szSQL, 1024); 
 
		if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) 
		{ 
			retcode = SQLFetch(hstmt); 
 
			if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)  
			{ 
				retval = TRUE; 
			} 
		} 
		else  
		{ 
			DisplayErrorMsg("scanchar", hstmt); 
 
			retval = FALSE; 
		} 
	} 
	else   
		retval = FALSE; 
 
    disconnectDB(hdbc, hstmt); 
     
	return retval; 
} 
 
BOOL newchar(struct OBJECT_INFO info) 
{ 
	SQLHSTMT		hstmt; 
    SQLHDBC         hdbc; 
	SQLRETURN		retcode; 
	char			szSQL[8196]; 
    BOOL            retval; 
	int i; 
	char face[255]; 
	char spell[100]; 
	char skill1[255]; 
	char skill2[100]; 
	char item[39][100]; 
 
	memset( szSQL, 0x00, 8196); hstmt = NULL; 
 
	sprintf(face, "%d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d", 
		info.face[0],  info.face[1],  info.face[2],  info.face[3],  info.face[4],  info.face[5], 
		info.face[6],  info.face[7],  info.face[8],  info.face[9],  info.face[10], info.face[11], 
		info.face[12], info.face[13], info.face[14], info.face[15], info.face[16], info.face[17], 
		info.face[18], info.face[19]); 
 
	sprintf(spell, "%d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d", 
		info.spell_[0],  info.spell_[1],  info.spell_[2],  info.spell_[3],  info.spell_[4], 
		info.spell_[5],  info.spell_[6],  info.spell_[7],  info.spell_[8],  info.spell_[9], 
		info.spell_[10], info.spell_[11]); 
 
	sprintf(skill1, "%d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d", 
		info.skill1[0],  info.skill1[1],  info.skill1[2],  info.skill1[3],  info.skill1[4], 
		info.skill1[5],  info.skill1[6],  info.skill1[7],  info.skill1[8],  info.skill1[9], 
		info.skill1[10], info.skill1[11], info.skill1[12], info.skill1[13], info.skill1[14], 
		info.skill1[15], info.skill1[16], info.skill1[17], info.skill1[18], info.skill1[19]); 
 
	sprintf(skill2, "%d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d", 
		info.skill2[0],  info.skill2[1],  info.skill2[2],  info.skill2[3],  info.skill2[4], 
		info.skill2[5],  info.skill2[6],  info.skill2[7],  info.skill2[8],  info.skill2[9], 
		info.skill2[10], info.skill2[11]); 
 
	for(i=0;i<39;i++) 
	{ 
		sprintf(item[i], "%d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d - %d", 
			info.Novelity[i][0],  info.Novelity[i][1],  info.Novelity[i][2],  info.Novelity[i][3],  info.Novelity[i][4],		 
			info.Novelity[i][5],  info.Novelity[i][6],  info.Novelity[i][7],  info.Novelity[i][8],  info.Novelity[i][9], 
			info.Novelity[i][10], info.Novelity[i][11], info.Novelity[i][12], info.Novelity[i][13], info.Novelity[i][14], 
			info.Novelity[i][15], info.Novelity[i][16]); 
	} 
 
	//																																																																																																																																																																																																																																																																																																	    01    02    03    04    05    06    07    08    09    10    11    12    13    14    15    16    17    18    19    20    21    22    23    24    25    26    27    28    29    30    31    32    33    34    35    36    37    38    39				 
	sprintf(szSQL, "INSERT INTO TBL_CHAR (FLD_ID, FLD_CHAR_NAME, FLD_APPELLATION, FLD_JOB, FLD_EXP, FLD_LEVEL, FLD_FACE, FLD_SPELL, FLD_DIRECTION, FLD_FIGHT_EXP, FLD_PK, FLD_MONEY, FLD_NUMBER1_NOW, FLD_NUMBER2_NOW, FLD_NUMBER3_NOW, FLD_NUMBER1__NOW, FLD_NUMBER2__NOW, FLD_ATTRIBUTION1, FLD_ATTRIBUTION2, FLD_ATTRIBUTION3, FLD_ATTRIBUTION4, FLD_ATTRIBUTION5, FLD_CITIZEN_LEVEL, FLD_CITIZEN_EXP, FLD_SKILL1, FLD_SKILL2, FLD_SKILL3, FLD_SKILL_NUMBER1, FLD_SKILL_NUMBER2, FLD_ITEM1, FLD_ITEM2, FLD_ITEM3, FLD_ITEM4, FLD_ITEM5, FLD_ITEM6, FLD_ITEM7, FLD_ITEM8, FLD_ITEM9, FLD_ITEM10, FLD_ITEM11, FLD_ITEM12, FLD_ITEM13, FLD_ITEM14, FLD_ITEM15, FLD_ITEM16, FLD_ITEM17, FLD_ITEM18, FLD_ITEM19, FLD_ITEM20, FLD_ITEM21, FLD_ITEM22, FLD_ITEM23, FLD_ITEM24, FLD_ITEM25, FLD_ITEM26, FLD_ITEM27, FLD_ITEM28, FLD_ITEM29, FLD_ITEM30, FLD_ITEM31, FLD_ITEM32, FLD_ITEM33, FLD_ITEM34, FLD_ITEM35, FLD_ITEM36, FLD_ITEM37, FLD_ITEM38, FLD_ITEM39, FLD_MENOW1, FLD_MENOW2, FLD_ME_X, FLD_ME_Y, FLD_SERVER_INDEX) VALUES ('%s', '%s', '%s', '%d', '%d', '%d', '%s', '%s', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d')",  
		info.id, info.name, info.appellation, info.job, info.exp, info.level, face, spell, info.direction, info.fight_exp, info.pkexp, info.money, info.life_now, info.mental_now, info.brawn_now, 
		info.biglifenumber, info.bigspellnumber, info.force, info.somatic, info.celerity, info.wisdom, info.intellect, info.citizenlevel, info.citizenexp, info.surplusskill1,  
		info.surplusskill2, info.surplusskill3, skill1, skill2, item[0], item[1], item[2], item[3], item[4], item[5], item[6], item[7], item[8], item[9], item[10], item[11], item[12], 
		item[13], item[14], item[15], item[16], item[17], item[18], item[19], item[20], item[21], item[22], item[23], item[24], item[25], item[26], item[27], item[28], item[29], item[30], 
		item[31], item[32], item[33], item[34], item[35], item[36], item[37], item[38], info.menow1, info.menow2, info.now_x, info.now_y, info.serverindex); 
 
//	LogFileWrite((char*)szSQL); 
 
    hdbc    = connectDB(option.chardsn, option.charuid, option.charpwd); 
	retcode = SQLAllocHandle((SQLSMALLINT)SQL_HANDLE_STMT, hdbc, &hstmt); 
 
    if(retcode == SQL_SUCCESS) 
    { 
        retcode = SQLExecDirect (hstmt, (unsigned char *)szSQL, 8196); 
         
        if (retcode == SQL_SUCCESS|| retcode == SQL_SUCCESS_WITH_INFO)  
        { 
            retval = TRUE; 
        } 
        else 
        { 
            DisplayErrorMsg("newchar", hstmt); 
             
            retval = FALSE; 
        } 
    } 
     
    else 
        retval = FALSE; 
 
    disconnectDB(hdbc, hstmt); 
 
	return retval; 
} 
 
BOOL deletechar(char *id, char *name) 
{ 
	SQLHSTMT		hstmt; 
    SQLHDBC         hdbc; 
	SQLRETURN		retcode; 
	BOOL			bData,	retval; 
	char			szSQL[1024]; 
	SQLINTEGER Indexind, nPoints; 
 
	Indexind = SQL_NTS, nPoints = 0; 
	memset( szSQL, 0x00, 1024 ); 
	bData = TRUE;	retval = FALSE; hstmt = NULL; 
 
	sprintf(szSQL, "DELETE FROM TBL_CHAR WHERE FLD_ID='%s' AND FLD_CHAR_NAME='%s'", id, name); 
 
    hdbc    = connectDB(option.chardsn, option.charuid, option.charpwd); 
	retcode = SQLAllocHandle((SQLSMALLINT)SQL_HANDLE_STMT, hdbc, &hstmt); 
 
	if (retcode == SQL_SUCCESS) 
	{ 
		retcode = SQLExecDirect (hstmt, (unsigned char *)szSQL, 1024); 
 
		if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)  
		{ 
			retval = TRUE; 
		} 
		else  
		{ 
			DisplayErrorMsg("deletechar", hstmt); 
 
			retval = FALSE; 
		} 
 
	} 
	else   
		retval = FALSE; 
	 
    disconnectDB(hdbc, hstmt); 
     
	return retval; 
} 
 
void Encode_Decode(LPBYTE lpTarget, LPBYTE lpSource, int nLen) 
{ 
	BYTE	l_BYTE_Xor1 = (WORD)nLen * D_WORD_XOR1MUL, l_BYTE_Xor3; 
 
	WORD	l_WORD_Xor3 = D_WORD_XOR3BASE, nCir; 
 
	for (nCir=0; nCir<(WORD)nLen; nCir++)  
	{ 
		l_BYTE_Xor3    = HIBYTE(l_WORD_Xor3); 
		lpTarget[nCir] = lpSource[nCir] ^ l_BYTE_Xor1 ^ G_BYTE_XorTable[nCir % D_XORTABLE_LENGTH] ^ l_BYTE_Xor3; 
		l_WORD_Xor3   *= D_WORD_XOR3MUL; 
	} 
} 
 
BOOL loadserverdata() 
{ 
	FILE *fp; 
 
	char szfilepath[256]; 
	char szfilename[256]; 
	char n1[20], n2[20]; 
 
	GetExeDir(szfilepath); 
 
	sprintf(szfilename, "%sselectdata\\server.inf", szfilepath); 
 
	fp = fopen(szfilename, "r"); 
 
	if(fp != NULL)  
	{ 
 
		//      0    1    2 
		fscanf(fp, "%s - %s - %s - %s\n",		 
				pServerInfo.name, pServerInfo.ip, n1, n2); 
				 
				pServerInfo.index      = atoi(n1); 
				pServerInfo.port       = atoi(n2); 
 
		fclose(fp); 
	} 
	else 
	{ 
		return FALSE; 
	} 
 
	return TRUE; 
} 
 
int sendblank(struct logindata  *login, char *id) 
{ 
	char *tmp; 
   
	// 00 01 02 03 04 05 06 07 08 09 
 
	// 01 00 00 00 0D 01 00 02 00 09 67 6F 75 7A 61 69 64 75 69 
 
	int i, t1, ret; 
 
	LPBYTE lpTarget; 
	LPBYTE lpSource; 
 
	t1 = strlen(id); 
 
	lpTarget =  (LPBYTE)malloc(10 + t1); 
	lpSource =  (LPBYTE)malloc(10 + t1); 
 
	lpSource[0] = 0x01; 
	lpSource[1] = 0x00; 
	lpSource[2] = 0x00;     
	lpSource[3] = 0x00; 
	lpSource[4] = 0x0D; 
	lpSource[5] = 0x01; 
	lpSource[6] = 0x00; 
	lpSource[7] = 0x02; 
	lpSource[8] = 0x00; 
	lpSource[9] = (BYTE)t1; 
 
	for (i=0;isock, tmp, 17 + t1, 0); 
 
	free(tmp); 
	free(lpTarget); 
	free(lpSource); 
 
	return ret; 
} 
 
int sendcreateerror(struct logindata  *login) 
{ 
	// 05 00 00 00 1B 00 帐号存在 
	char *tmp; 
	int i, ret; 
 
	LPBYTE lpTarget; 
	LPBYTE lpSource; 
 
	lpTarget =  (LPBYTE)malloc(6); 
	lpSource =  (LPBYTE)malloc(6); 
 
	lpSource[0] = 0x00; 
	lpSource[1] = 0x00; 
	lpSource[2] = 0x00;     
	lpSource[3] = 0x00; 
	lpSource[4] = 0x1B; 
	lpSource[5] = 0x00; 
 
	Encode_Decode(lpTarget, lpSource, 6); 
 
	tmp =  (char*)malloc(13); 
 
	strcpy(tmp, ""); 
 
	tmp[0]  = (char)0xAA; 
	tmp[1]  = (char)0x55; 
	tmp[2]  = (char)(BYTE)(13 - 6); 
	tmp[3]  = (char)0x00; 
	tmp[4]  = (char)0xF9; 
 
	for (i=0; i<6; i++) 
	{ 
		tmp[5+i] = (char)lpTarget[i]; 
	} 
 
	tmp[13 - 2] = (char)0x55; 
	tmp[13 - 1] = (char)0xAA; 
 
	ret = send(login->sock, tmp, 13, 0); 
 
	free(lpTarget); 
	free(lpSource); 
	free(tmp); 
 
	return ret; 
} 
 
int sendcreateinfo(struct logindata *login, struct OBJECT_INFO info, int index) 
{ 
	char *tmp; 
	BYTE buf[2]; 
 
	// 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26  
	// 04 00 00 00 13 01 00 09 41 41 41 41 41 41 5B 46 5D 0D 00 0F 00 0F 00 0B 00 0B 00 
	// 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00  
	// 64 00 1F 00 32 00 64 00 1F 00 32 00  
	// 00 00 00 01 00 00 02 00 00 03 00 00 04 00 00 05 00 00 06 00 00 07 00 00 08 00 00 09 00 00 0A 00 00 0B 00 00 0C 00 00 0D 00 00 0E 00 00 0F 00 00 10 00 00 11 00 00 12 00 00 13 00 00  
	// FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  
	// 0D 32 31 38 2E 38 39 2E 31 37 31 2E 38 39 E0 2E 00 00 
 
	int t1, t2, t3, i, ret; 
	LPBYTE lpTarget; 
	LPBYTE lpSource; 
 
	t1 = strlen(info.name); 
	t2 = strlen(info.ip); 
	t3 = 22 + 12 + 60 + 28 + 5 + 18 + t1 + t2; 
 
	lpTarget = (LPBYTE)malloc(t1 + t2 + t3); 
	lpSource = (LPBYTE)malloc(t1 + t2 + t3); 
 
	lpSource[0] = 0x00; 
	lpSource[1] = 0x00; 
	lpSource[2] = 0x00; 
	lpSource[3] = 0x00; 
	lpSource[4] = 0x13; 
	lpSource[5] = 0x01; 
	lpSource[6] = (BYTE)index; 
	lpSource[7] = (BYTE)t1; 
 
	for(i=0;isock, tmp, t3 + 7, 0); 
 
	free(lpTarget); 
	free(lpSource); 
	free(tmp); 
 
	return ret; 
} 
 
int senduserinfo(struct logindata *login, struct OBJECT_INFO info[3], char *id) 
{ 
	char *tmp; 
	int t1, t2, t3, t4, t5, i, j, n; 
    // 00 01 02 03 04 05 06 07 08 09 
	// 01 00 00 00 0D 01 00 02 00 09 67 6F 75 7A 61 69 64 75 69 
	LPBYTE lpTarget; 
	LPBYTE lpSource; 
 
	BYTE buf[2]; 
 
	int num, ret; 
 
	lpTarget = (LPBYTE)malloc(700); 
	lpSource = (LPBYTE)malloc(700); 
 
	num = 0; 
 
	if (info[0].have == TRUE) { num ++; login->char_number ++; } 
	if (info[1].have) { num ++; login->char_number ++; } 
	if (info[2].have) { num ++; login->char_number ++; } 
 
	lpSource[0] = 0x00; 
	lpSource[1] = 0x00; 
	lpSource[2] = 0x00; 
	lpSource[3] = 0x00; 
	lpSource[4] = 0x0D; 
	lpSource[5] = 0x01; 
	lpSource[6] = (BYTE)num; 
 
 
	n = 6; 
	t4 = 0; 
	for(i=0;isock, tmp, t4 + 7, 0); 
 
	free(lpTarget); 
	free(lpSource); 
	free(tmp); 
 
	return ret; 
 
/* 
    04 00 00 00 13 01 00 09 41 41 41 41 41 41 5B 46 5D  
	0D 00 0F 00 0F 00 0B 00 0B 00 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
	01 00 64 00 1F 00 32 00 64 00 1F 00 32 00  
    00 00 00 01 00 00 02 00 00 03 00 00 04 00 00 05 00 00 06 00 00 07 00 00 08 00 00 09 00 00 0A 00 00 0B 00 00 0C 00 00 0D 00 00 0E 00 00 0F 00 00 10 00 00 11 00 00 12 00 00 13 00 00  
    FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  
    0D 32 31 38 2E 38 39 2E 31 37 31 2E 38 39 E0 2E 00 00 
 
 
	02 00 00 00 0D 01 01 00 0D 31 31 31 31 31 31 31 31 31 31 5B 42 5D  
	0D 00 0E 00 10 00 0C 00 0A 00  
	00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
	01 00 5E 00 1E 00 30 00 5E 00 1E 00 30 00  
	00 00 00 01 00 00 02 00 00 03 00 00 04 00 00 05 00 00 06 00 00 07 00 00 08 00 00 09 00 00 0A 00 00 0B 00 00 0C 00 00 0D 00 00 0E 00 00 0F 00 00 10 00 00 11 00 00 12 00 00 13 00 00  
	FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  
	0D 36 31 2E 31 32 39 2E 35 38 2E 31 37 32 E0 2E 00 00 02 00 09 67 6F 75 7A 61 69 64 75 69 
 
 
01 00 00 00 0D 01 03 00 0F B9 B7 E1 CC B6 D3 B4 F3 B6 D3 B3 A4 5B 43 5D 18 00 42 00 11 00 0C 00 0A 00 00 00 00 00 00 00 00 00 00 02 03 04 00  
03 00 00 00 00 00 00 41 00 E2 02 5E 00 D8 00 D6 02 5E 00 D8 00 00 00 14 01 00 0F 02 00 00 03 00 00 04 00 00 05 00 00 06 00 00  
07 00 00 08 00 00 09 00 00 0A 00 00 0B 00 00 0C 00 00 0D 00 00 0E 00 00 0F 00 00 10 00 00 11 00 00 12 00 00 13 00 00 FF FF 60  
01 FF FF FF FF 4C 01 9D 02 FF FF FF FF 59 02 63 02 FF FF FF FF FF FF FF FF 0D 36 31 2E 31 32 39 2E 35 38 2E 31 37 33 E0 2E 
 
00 00 01 0F B9 B7 E1 CC B6 D3 D0 A1 B6 D3 B3 A4 5B 43 5D 4F 00 14 00 19 00 0A 00 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
03 00 00 00 00 00 02 50 00 03 02 E4 00 9A 00 B4 01 D0 00 9A 00 00 00 00 01 00 00 02 00 00 03 00 00 04 00 00 05 00 00 06 00 00  
07 00 00 08 00 00 09 00 00 0A 00 14 0B 00 08 0C 00 14 0D 00 02 0E 00 00 0F 00 00 10 00 00 11 00 00 12 00 00 13 00 00 54 01 35  
02 FF FF FF FF BB 01 41 01 FF FF FF FF 6C 01 75 01 FF FF FF FF FF FF FF FF 0D 36 31 2E 31 32 39 2E 35 38 2E 31 37 33 E0 2E  
 
00 00 02 0D B9 B7 E1 CC B6 D3 D6 C7 C4 D2 5B 43 5D 0F 00 0B 00 0A 00 2A 00 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
00 00 00 00 01 3F 00 01 01 ED 01 6B 00 F9 00 F7 01 6D 00 00 00 00 01 00 00 02 00 00 03 00 00 04 00 00 05 00 06 06 00 10 07 00  
00 08 00 0B 09 00 00 0A 00 00 0B 00 00 0C 00 00 0D 00 00 0E 00 00 0F 00 00 10 00 00 11 00 00 12 00 00 13 00 00 48 00 FB 00 FF  
FF FF FF CA 01 A8 00 FF FF FF FF 14 01 72 01 FF FF FF FF FF FF FF FF 0D 36 31 2E 31 32 39 2E 35 38 2E 31 37 33 E0 2E  
 
00 00 03 00 09 67 6F 75 7A 61 69 64 75 69 
*/ 
} 
 
int senddelchar(struct logindata  *login, int index) 
{ 
	// 13 00 00 00 15 01 02 删除帐号 
	char *tmp; 
	int i, ret; 
 
	LPBYTE lpTarget; 
	LPBYTE lpSource; 
 
	lpTarget =  (LPBYTE)malloc(7); 
	lpSource =  (LPBYTE)malloc(7); 
 
	lpSource[0] = 0x00; 
	lpSource[1] = 0x00; 
	lpSource[2] = 0x00;     
	lpSource[3] = 0x00; 
	lpSource[4] = 0x15; 
	lpSource[5] = 0x01; 
	lpSource[6] = (BYTE)index; 
 
	Encode_Decode(lpTarget, lpSource, 7); 
 
	tmp =  (char*)malloc(14); 
 
	strcpy(tmp, ""); 
 
	tmp[0]  = (char)0xAA; 
	tmp[1]  = (char)0x55; 
	tmp[2]  = (char)(BYTE)(14 - 6); 
	tmp[3]  = (char)0x00; 
	tmp[4]  = (char)0xF9; 
 
	for (i=0; i<7; i++) 
	{ 
		tmp[5+i] = (char)lpTarget[i]; 
	} 
 
	tmp[14 - 2] = (char)0x55; 
	tmp[14 - 1] = (char)0xAA; 
 
	ret = send(login->sock, tmp, 14, 0); 
 
	free(lpTarget); 
	free(lpSource); 
	free(tmp); 
 
	return ret; 
 
} 
 
int senddeletecharerror(struct logindata  *login) 
{ 
	// 02 00 00 00 15 00 06  
	char *tmp; 
	int i, ret; 
 
	LPBYTE lpTarget; 
	LPBYTE lpSource; 
 
	lpTarget =  (LPBYTE)malloc(7); 
	lpSource =  (LPBYTE)malloc(7); 
 
	lpSource[0] = 0x00; 
	lpSource[1] = 0x00; 
	lpSource[2] = 0x00;     
	lpSource[3] = 0x00; 
	lpSource[4] = 0x15; 
	lpSource[5] = 0x00; 
	lpSource[6] = 0x06; 
 
	Encode_Decode(lpTarget, lpSource, 7); 
 
	tmp =  (char*)malloc(14); 
 
	strcpy(tmp, ""); 
 
	tmp[0]  = (char)0xAA; 
	tmp[1]  = (char)0x55; 
	tmp[2]  = (char)(BYTE)(14 - 6); 
	tmp[3]  = (char)0x00; 
	tmp[4]  = (char)0xF9; 
 
	for (i=0; i<7; i++) 
	{ 
		tmp[5+i] = (char)lpTarget[i]; 
	} 
 
	tmp[14 - 2] = (char)0x55; 
	tmp[14 - 1] = (char)0xAA; 
 
	ret = send(login->sock, tmp, 14, 0); 
 
	free(lpTarget); 
	free(lpSource); 
	free(tmp); 
 
	return ret; 
 
} 
 
int sendcreateok(struct logindata  *login) 
{ 
	// 06 00 00 00 1B 01   帐号可以使用 
	char *tmp; 
	int i, ret; 
 
	LPBYTE lpTarget; 
	LPBYTE lpSource; 
 
	lpTarget =  (LPBYTE)malloc(6); 
	lpSource =  (LPBYTE)malloc(6); 
 
	lpSource[0] = 0x00; 
	lpSource[1] = 0x00; 
	lpSource[2] = 0x00;     
	lpSource[3] = 0x00; 
	lpSource[4] = 0x1B; 
	lpSource[5] = 0x01; 
 
	Encode_Decode(lpTarget, lpSource, 6); 
 
	tmp =  (char*)malloc(13); 
 
	strcpy(tmp, ""); 
 
	tmp[0]  = (char)0xAA; 
	tmp[1]  = (char)0x55; 
	tmp[2]  = (char)(BYTE)(13 - 6); 
	tmp[3]  = (char)0x00; 
	tmp[4]  = (char)0xF9; 
 
	for (i=0; i<6; i++) 
	{ 
		tmp[5+i] = (char)lpTarget[i]; 
	} 
 
	tmp[13 - 2] = (char)0x55; 
	tmp[13 - 1] = (char)0xAA; 
 
	ret = send(login->sock, tmp, 13, 0); 
 
	free(lpTarget); 
	free(lpSource); 
	free(tmp); 
 
	return ret; 
} 
 
int request(struct logindata  *login, int job) 
{ 
	int t1, t2, t3, t4, t5, num; 
	char *tmp; 
	int i, ret; 
 
	LPBYTE lpTarget; 
	LPBYTE lpSource; 
 
	if (job<0 || job >= 4) return -1; 
 
	num = 80; 
 
	if (job == 0) // 拳 体质多 
	{ 
		t1 = myrand(8, 19);  // 20 
		t2 = myrand(18, 29); // 30 
		t3 = myrand(8, 19); 
		t4 = myrand(8, 19); 
		t5 = num - (t1 + t2 + t3 + t4); 
	} 
	else if (job == 1) // 法师 智慧多 
	{ 
		t1 = myrand(8, 19);  // 20 
		t2 = myrand(8, 19); // 30 
		t3 = myrand(8, 19); 
		t4 = myrand(18, 29); 
		t5 = num - (t1 + t2 + t3 + t4); 
	} 
	else if (job == 2) // 剑   力量多 
	{ 
		t1 = myrand(18, 29);  // 20 
		t2 = myrand(8, 19); // 30 
		t3 = myrand(8, 19); 
		t4 = myrand(8, 19); 
		t5 = num - (t1 + t2 + t3 + t4); 
	} 
	else if (job == 3) // 枪   敏捷多 
	{ 
		t1 = myrand(8, 19);  // 20 
		t2 = myrand(8, 19);  // 30 
		t3 = myrand(18, 29); 
		t4 = myrand(8, 19); 
		t5 = num - (t1 + t2 + t3 + t4); 
	} 
 
	// 00 01 02 03 04 05 06 07 08 09 
	// 02 00 00 00 18 0D 0F 0F 0B 0B  
 
	lpTarget =  (LPBYTE)malloc(10); 
	lpSource =  (LPBYTE)malloc(10); 
 
	lpSource[0] = 0x00; 
	lpSource[1] = 0x00; 
	lpSource[2] = 0x00;     
	lpSource[3] = 0x00; 
	lpSource[4] = 0x18; 
	lpSource[5] = (BYTE)t1; 
	lpSource[6] = (BYTE)t2; 
	lpSource[7] = (BYTE)t3; 
	lpSource[8] = (BYTE)t4; 
	lpSource[9] = (BYTE)t5; 
 
	Encode_Decode(lpTarget, lpSource, 10); 
 
	tmp =  (char*)malloc(17); 
 
	strcpy(tmp, ""); 
 
	tmp[0]  = (char)0xAA; 
	tmp[1]  = (char)0x55; 
	tmp[2]  = (char)(BYTE)(17 - 6); 
	tmp[3]  = (char)0x00; 
	tmp[4]  = (char)0xF9; 
 
	for (i=0; i<10; i++) 
	{ 
		tmp[5+i] = (char)lpTarget[i]; 
	} 
 
	tmp[17 - 2] = (char)0x55; 
	tmp[17 - 1] = (char)0xAA; 
 
	ret = send(login->sock, tmp, 17, 0); 
 
	if (ret != SOCKET_ERROR) 
	{ 
		login->num[0] = t1; 
		login->num[1] = t2; 
		login->num[2] = t3; 
		login->num[3] = t4; 
		login->num[4] = t5; 
	} 
 
	free(lpTarget); 
	free(lpSource); 
	free(tmp); 
 
	return ret; 
} 
 
int createchar(struct logindata *login, LPBYTE lpTarget) 
{ 
	// 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 
	// 05 00 00 00 12 03 31 31 31 00 05 31 31 31 31 31 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 
	int i, j, t1, t2; 
	char id[64], name[64], tmp[2]; 
 
	struct OBJECT_INFO info; 
//	OBJECT_INFO tempinfo[3]; 
 
	strcpy(id, ""); 
	strcpy(name, ""); 
 
	for (i=0; i<(int)lpTarget[5]; i++) 
	{ 
		sprintf(tmp, "%c", (char)lpTarget[6 + i]);	 
		strcat(id, tmp); 
	} 
 
	t1 = (int)lpTarget[5] + 7; 
	t2 = (int)lpTarget[5] + 8 + (int)lpTarget[t1]; 
	 
	for (i=0; i<(int)lpTarget[t1]; i++) 
	{ 
		sprintf(tmp, "%c", (char)lpTarget[t1 + 1 + i]);	 
		strcat(name, tmp); 
	} 
 
	// 存在就退出 
	if(scanchar(id, name)) 
	{ 
		sendcreateerror(login); return -1; 
	} 
 
	if(findcharfull(id)) 
	{ 
		sendcreateerror(login); return -1; 
	} 
 
//	finddata(id, tempinfo); 
/* 
		for(i=0;i<3;i++) 
		{ 
			if (tempinfo[i].have) 
				User[n].index ++; 
		} 
 
		if (n == 3) 
		{ 
			User[n].index = 2; 
			sendcreateerror(s); 
			return; 
		} 
*/ 
 
	strcpy(info.id, id); 
	strcpy(info.name, name); 
 
	strcpy(info.team, "\\"); 
	strcpy(info.appellation, "\\"); 
 
	//strcpy(info.team, "\\"); 
	//strcpy(info.appellation, "\\"); 
 
	info.surplusskill1 = 1; 
	info.surplusskill2 = 1; 
	info.surplusskill3 = 0; 
	info.direction     = 0; 
	info.pkexp         = 0; 
 
//	MessageBoxA(NULL, info.name, name, 0); 
 
	info.level = 1; 
	info.citizenlevel = 5; 
	info.citizenexp   = 0; 
	info.exp          = 0; 
	info.fight_exp    = 0; 
	info.money        = 10000000; 
 
    info.force           = login->num[0];         // 力量 
	info.somatic         = login->num[1];         // 体质 
	info.celerity        = login->num[2];         // 敏捷 
	info.wisdom          = login->num[3];         // 智慧 
	info.intellect       = login->num[4];         // 智力 
 
	info.life_now        = info.somatic * 6 + info.level * 3; 
	info.life_max        = info.somatic * 6 + info.level * 3; 
	info.mental_now      = info.wisdom * 6 + info.level * 3; 
	info.mental_max      = info.wisdom * 6 + info.level* 3; 
	info.brawn_now       = info.somatic * 4 + info.level* 2;  
	info.brawn_max       = info.somatic * 4 + info.level* 2; 
	info.biglifenumber   = 65535; 
	info.bigspellnumber  = 65535; 
 
	for (i=0;i<12;i++) 
		info.spell_[i] = 0xFF; 
 
	for (i=0;i<20;i++) 
		info.skill1[i] = 0; 
 
	for (i=0;i<12;i++) 
		info.skill2[i] = 0; 
 
	for(i=0;i<20;i++) 
	{ 
		info.face[i] = lpTarget[t2 + i]; 
	} 
 
	info.job = info.face[19]; 
 
	for(i=0;i<11;i++) 
		info.spell_[i]  = 0xFF; 
 
 
	for(i=0; i<39; i++) 
	{ 
		for(j=0; j<18; j++) 
		{ 
		//	info.Novelity[i][j] = temp_info.Novelity[i][j]; 
 
			if (j==2 || j==3) 
				info.Novelity[i][j] = 0xFF; 
			else 
				info.Novelity[i][j] = 0x00; 
		} 
	} 
 
	info.menow1 = 1;//temp_info.menow1; 
	info.menow2 = 0;//temp_info.menow2; 
	info.now_x  = 196; //temp_info.now_x; 
	info.now_y  = 1406;//temp_info.now_y; 
 
	strcpy(info.ip, pServerInfo.ip); 
	info.port = pServerInfo.port; 
 
	if (newchar(info)) 
	{ 
		login->char_number ++; 
		sendcreateinfo(login, info, login->char_number - 1); 
	} 
 
	return 0; 
} 
 
void loaduser(struct logindata *login, char *id) 
{ 
	struct OBJECT_INFO info[3]; 
 
	int i; 
 
//	try 
//	{ 
		strcpy(login->id, id); 
 
		info[0].have = FALSE; info[1].have = FALSE; info[2].have = FALSE; 
 
		loadidchar(id, info); 
 
		for(i=0;i<3;i++) 
		{ 
			strcpy(info[i].ip, pServerInfo.ip); 
			info[i].port = pServerInfo.port; 
		} 
 
		if ((!info[0].have) && (!info[1].have) && (!info[2].have)) 
			sendblank(login, id); 
		else 
			senduserinfo(login, info, id); 
//	} 
//	catch(...) 
///	{ 
///		sendblank(login, id); 
//	} 
 
//	free(&info); 
} 
 
void scan_char(struct logindata *login, LPBYTE lpTarget) 
{ 
	// 19 00 00 00 1B 03 31 31 31 
	char name[64], tmp[2]; 
 
	int i; 
 
	strcpy(name, ""); 
 
	for (i=0; i<(int)lpTarget[5]; i++) 
	{ 
		sprintf(tmp, "%c", (char)lpTarget[6 + i]);	 
		strcat(name, tmp); 
	} 
 
//	try 
//	{ 
		if(scanchar(login->id, name))			 
			sendcreateerror(login);	 
		else 
			sendcreateok(login); 
//	} 
//	catch(...) 
//	{ 
//		sendcreateerror(login); 
//	} 
} 
 
int delchar(struct logindata *login, LPBYTE lpTarget) 
{ 
	// 13 00 00 00 15 01 02 
 
	// 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 
	// 06 00 00 00 14 03 31 31 31 03 31 32 33 02 03 31 31 31 25 31 39 32 2E 31 36 38 2E 31 2E 31 30 31 39 32 2E 31 36 38 2E 30 2E 31 32 31 38 2E 36 39 2E 31 39 30 2E 31 33 30  
	// 07 00 00 00 14 03 31 31 31 04 31 32 33 31 01 04 35 35 35 35 25 31 39 32 2E 31 36 38 2E 31 2E 31 30 31 39 32 2E 31 36 38 2E 30 2E 31 32 31 38 2E 36 39 2E 31 39 30 2E 31 33 30  
 
	// 05 00 00 00 14 09 67 6F 75 7A 61 69 64 75 69 04 35 34 34 35 00 12 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 0C 31 39 32 2E 31 36 38 2E 31 2E 32 31 
 
	char id[64], name[64], tmp[2], idcard[64]; 
 
	int t1, t2, i; 
 
 
	strcpy(id, ""); 
	strcpy(name, ""); 
	strcpy(idcard, ""); 
 
	for (i=0; i<(int)lpTarget[5]; i++) 
	{ 
		sprintf(tmp, "%c", (char)lpTarget[6 + i]);	 
		strcat(id, tmp); 
	} 
 
	t1 = (int)lpTarget[5] + 7; 
	t2 = (int)lpTarget[5] + 8 + lpTarget[t1 - 1]; 
	 
	for (i=0; i<(int)lpTarget[t1 - 1]; i++) 
	{ 
		sprintf(tmp, "%c", (char)lpTarget[t1 + i]);	 
		strcat(name, tmp); 
	} 
 
	for (i=0; i<(int)lpTarget[t2]; i++) 
	{ 
		sprintf(tmp, "%c", (char)lpTarget[t2 + 1 + i]);	 
		strcat(idcard, tmp); 
	} 
 
	// 提交认证信息 
	if (checkaccount(login, login->id, "")) 
	{ 
	//	; 
	//	MessageBox(NULL, idcard, login->idcard, 0); 
		// 02 00 00 00 15 00 06  
 
		if (strcmp(login->idcard, idcard) != 0)	 
		{ 
			senddeletecharerror(login); return -1; 
		} 
 
		if (strcmp(login->id, id) == 0)	 
		{	 
			if (deletechar(id, name)) 
			{	 
				login->char_number --;	 
				senddelchar(login, lpTarget[t2 - 1]); 
			} 
		} 
	} 
	else 
	{ 
		senddeletecharerror(login); return -1; 
	} 
 
	return 0; 
} 
 
void loginuser(struct logindata *login, LPBYTE lpTarget, int len) 
{ 
	// 00 01 02 03 04 05 06 07 
	// 0B 00 00 00 0C 09 67 6F 75 7A 61 69 64 75 69 02 00 01 00 00 00 
	int i; 
 
	char id[32]; 
	char tmp[2]; 
 
//	t1 = finduser(s); 
 
//	if (t1 == 1501) closesocket(s); 
 
//	id = (char*)malloc((int)lpTarget[5]); 
 
//	free(id); 
	strcpy(id, ""); 
 
	for (i=0; i<(int)lpTarget[5]; i++) 
	{ 
		sprintf(tmp, "%c", (char)lpTarget[6 + i]);	 
		strcat(id, tmp); 
	} 
 
	loaduser(login, id); 
} 
 
 
int debug2(struct logindata *login) 
{ 
	// 00 01 02 03 04 05 06 07 08 09 10 11 12 
    // 08 00 00 00 EB 
 
	char *tmp; 
	int i, ret; 
 
	LPBYTE lpSource; 
	LPBYTE lpTarget; 
 
	lpTarget = (LPBYTE)malloc(5); 
	lpSource = (LPBYTE)malloc(5); 
 
	lpSource[0]  = 0x00; 
	lpSource[1]  = 0x00; 
	lpSource[2]  = 0x00; 
	lpSource[3]  = 0x00; 
	lpSource[4]  = 0xEB; 
 
	Encode_Decode(lpTarget, lpSource, 5); 
 
	tmp =  (char*)malloc(12); 
	strcpy(tmp, ""); 
 
	tmp[0]  = (char)0xAA; 
	tmp[1]  = (char)0x55; 
	tmp[2]  = (char)(BYTE)(12 - 6); 
	tmp[3]  = (char)0x00; 
	tmp[4]  = (char)0xF9; 
 
	for (i=0; i<5; i++) 
	{ 
		tmp[5+i] = (char)lpTarget[i]; 
	} 
 
	tmp[12 - 2] = (char)0x55; 
	tmp[12 - 1] = (char)0xAA; 
 
	ret = send(login->sock, tmp, 12, 0); 
 
	free(lpTarget); 
	free(lpSource); 
	free(tmp); 
 
	return ret; 
 
} 
 
BOOL reconnect(SQLHENV  henv, SQLHDBC  hdbc, char dsn[24], char uid[24], char pwd[24]) 
{ 
	SQLRETURN nResult;  
 
	if ((nResult = SQLAllocHandle(SQL_HANDLE_DBC, henv, (SQLHDBC FAR *)&hdbc)) != SQL_SUCCESS)    
	{  
		//   DisplayError(nResult, hWnd, SQL_HANDLE_ENV, henv);  
		return FALSE;   
	} 
   nResult = SQLConnect(hdbc, (LPSTR)dsn, SQL_NTS, (LPSTR)uid, SQL_NTS,(LPSTR)pwd, SQL_NTS); 
   if (nResult != SQL_SUCCESS && nResult != SQL_SUCCESS_WITH_INFO)  
   { 
//      DisplayError(nResult, hWnd, SQL_HANDLE_DBC, hdbc); 
      SQLFreeHandle(SQL_HANDLE_DBC, hdbc); 
      return FALSE; 
   } 
 
   return TRUE; 
} 
 
BOOL FAR PASCAL InitSQLEnvironment() 
{ 
   // Allocate an Environment Handle 
   if (SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&option.account_henv) != SQL_SUCCESS) 
      return FALSE; 
 
   if(SQLSetEnvAttr(option.account_henv, SQL_ATTR_ODBC_VERSION, 
                         (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER) != SQL_SUCCESS) return FALSE; 
 
   if (SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&option.char_henv) != SQL_SUCCESS) 
      return FALSE; 
 
   if(SQLSetEnvAttr(option.char_henv, SQL_ATTR_ODBC_VERSION, 
                         (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER) != SQL_SUCCESS) return FALSE; 
 
   return TRUE; 
 
} 
 
BOOL FAR PASCAL ConnectDatabase() 
{ 
   SQLRETURN nResult;                // Result code 
 
   if ((nResult = SQLAllocHandle(SQL_HANDLE_DBC, option.account_henv, (SQLHDBC FAR *)&option.account_hdbc)) != SQL_SUCCESS) { 
   //   DisplayError(nResult, hWnd, SQL_HANDLE_ENV, henv); 
      return (FALSE); 
   } 
 
   nResult = SQLConnect(option.account_hdbc, (LPSTR)option.accountdsn, SQL_NTS, (LPSTR)option.accountuid, SQL_NTS,(LPSTR)option.accountpwd, SQL_NTS); 
 
   // if failed to connect, free the allocated hdbc before return 
   if (nResult != SQL_SUCCESS && nResult != SQL_SUCCESS_WITH_INFO) { 
//      DisplayError(nResult, hWnd, SQL_HANDLE_DBC, hdbc); 
      SQLFreeHandle(SQL_HANDLE_DBC, option.account_hdbc); 
      return (FALSE); 
   } 
 
   if ((nResult = SQLAllocHandle(SQL_HANDLE_DBC, option.char_henv, (SQLHDBC FAR *)&option.char_hdbc)) != SQL_SUCCESS) { 
   //   DisplayError(nResult, hWnd, SQL_HANDLE_ENV, henv); 
      return (FALSE); 
   } 
 
   nResult = SQLConnect(option.char_hdbc, (LPSTR)option.chardsn, SQL_NTS, (LPSTR)option.charuid, SQL_NTS,(LPSTR)option.charpwd, SQL_NTS); 
 
   // if failed to connect, free the allocated hdbc before return 
   if (nResult != SQL_SUCCESS && nResult != SQL_SUCCESS_WITH_INFO) { 
//      DisplayError(nResult, hWnd, SQL_HANDLE_DBC, hdbc); 
      SQLFreeHandle(SQL_HANDLE_DBC, option.account_hdbc); 
      return (FALSE); 
   } 
 
   // display any connection information if driver returns SQL_SUCCESS_WITH_INFO 
   //if (nResult == SQL_SUCCESS_WITH_INFO) 
   //   DisplayError(nResult, hWnd, SQL_HANDLE_DBC, hdbc); 
 
   return TRUE; 
} 
 
void ReadPack(struct logindata *login) 
{ 
    int     i = 0; 
    BOOL    bResult; 
    int     err; 
    DWORD     numRead; 
 
    while (++i) 
    { 
        // 读取一个单字符 
        bResult = ReadFile( 
                    (HANDLE)login->sock, 
                    login->InBuffer, 
                    1, 
                    &numRead, 
                    &login->ovIn); 
 
        // 这里,等待一个信息包. 
        if (bResult) 
		{ 
            return; 
		} 
 
        err = GetLastError(); 
 
        // 获取状态,这里并不代表错误 
        if (err == ERROR_IO_PENDING) 
            return; 
 
        if ( err == ERROR_INVALID_USER_BUFFER || 
             err == ERROR_NOT_ENOUGH_QUOTA || 
             err == ERROR_NOT_ENOUGH_MEMORY ) 
        { 
            if (i == 5)  
            { 
                Sleep(50);  // 等待并重试 
                continue; 
            } 
 
      //      printf("IssueRead -系统溢出连接池"); 
        } 
		 
 
        break; 
    } 
	 
 
  //  fprintf(stderr, "IssueRead - 读信息失败.\n"); 
	 
} 
 
// 
// 确保我们运行在正确的版本下 Windows NT (3.51, 4.0, or later) 
// 
BOOL CheckOsVersion() 
{ 
    OSVERSIONINFO   ver; 
    BOOL            bResult; 
 
    ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 
 
    bResult = GetVersionEx((LPOSVERSIONINFO) &ver); 
 
    if ((!bResult) || 
         (ver.dwPlatformId != VER_PLATFORM_WIN32_NT)) 
    { 
        MessageBox(NULL, "you must have windows NT 3.51 or later\n", "信息", 0); 
 
		return FALSE; 
    } 
	return TRUE; 
} 
 
DWORD WINAPI ThreadFunc(LPVOID pVoid) 
{ 
 
    BOOL    bResult; 
    DWORD   dwNumRead; 
    struct logindata *pCntx; 
    LPOVERLAPPED lpOverlapped; 
	char tmp[16]; 
	int t1, i; 
	BYTE lpTarget[4048]; 
	BYTE lpSource[4048]; 
 
    UNREFERENCED_PARAMETER(pVoid); 
 
    // 无限循环从 I/O completion port 获取信息. 
    for (;;) 
    { 
        bResult = GetQueuedCompletionStatus( 
               ghCompletionPort, 
               &dwNumRead, 
               &(DWORD)pCntx, 
               &lpOverlapped, 
               INFINITE 
            ); 
 
        if (bResult == FALSE 
            && lpOverlapped == NULL) 
        { 
//            FatalError( 
  //              "ThreadFunc - GetQueuedCompletionStatus()错误.\n"); 
        } 
        else if (bResult == FALSE 
            && lpOverlapped != NULL) 
        {     
			CloseHandle(pCntx->ovOut.hEvent); 
            closesocket(pCntx->sock); 
        } 
 
        else if (dwNumRead == 0) 
        { 
			CloseHandle(pCntx->ovOut.hEvent); 
            closesocket(pCntx->sock); 
        } 
 
        else 
        { 
            char *pch = &pCntx->OutBuffer[pCntx->nOutBufIndex++]; 
            *pch++ = pCntx->InBuffer[0]; 
          //  *pch = '\0';   
 
			if ((((BYTE)pCntx->OutBuffer[0] != 0xAA ) || ((BYTE)pCntx->OutBuffer[1] != 0x55)) && (pCntx->nOutBufIndex == 2)) 
			{ 
				memcpy(pCntx->OutBuffer, 0, 0); 
				pCntx->nOutBufIndex = 0; 
			} 
			 
			if ((((BYTE)pCntx->OutBuffer[0] != 0xAA ) || ((BYTE)pCntx->OutBuffer[1] != 0x55) || (((BYTE)pCntx->OutBuffer[4] != 0xD5) && ((BYTE)pCntx->OutBuffer[4] != 0xF9))) && (pCntx->nOutBufIndex==5)) 
			{ 
				memcpy(pCntx->OutBuffer, 0, 0); 
				pCntx->nOutBufIndex = 0; 
			} 
 
			if(((BYTE)pCntx->OutBuffer[0] == 0xAA) && ((BYTE)pCntx->OutBuffer[1] == 0x55) &&  
				((int)(BYTE)pCntx->OutBuffer[2] + (int)(BYTE)pCntx->OutBuffer[3] * 256 + 6 == pCntx->nOutBufIndex) && (pCntx->nOutBufIndex==8)) 
			{ 
				if ((BYTE)pCntx->OutBuffer[4] == 0xD5) 
				{	    
					tmp[0] = (char)0xAA;	 
			    	tmp[1] = (char)0x55;		     
					tmp[2] = (char)0x0A;			     
					tmp[3] = (char)0x00;	    	 
					tmp[4] = (char)0xD6;    	 
					tmp[5] = (char)0x10;		     
					tmp[6] = (char)0x10;	     
					tmp[7] = (char)0x10;	     
					tmp[8] = (char)0x10;		      
					tmp[9] = (char)0x10;		     
					tmp[10] = (char)0x10;		     
					tmp[11] = (char)0x10;			 
					tmp[12] = (char)0x10;	    	 
					tmp[13] = (char)0x00;	     
					tmp[14] = (char)0x55;	     
					tmp[15] = (char)0xAA; 
 
					send(pCntx->sock, tmp, 16, 0); 
 
					memcpy(pCntx->OutBuffer, 0, 0); 
					pCntx->nOutBufIndex = 0; 
				} 
			} 
			else if(((BYTE)pCntx->OutBuffer[0] == 0xAA) && ((BYTE)pCntx->OutBuffer[1] == 0x55) &&  
				((BYTE)pCntx->OutBuffer[2] + (BYTE)pCntx->OutBuffer[3] * 256 + 6 == pCntx->nOutBufIndex) && (pCntx->nOutBufIndex>=12)) 
			{ 
		//		userstatus(pCntx, pCntx->OutBuffer, pCntx->nOutBufIndex); 
	 
				switch ((BYTE)pCntx->OutBuffer[4]) 
				{	 
					case 0xF9: 
		 
						t1 = (int)(BYTE)pCntx->OutBuffer[2] + (int)(BYTE)pCntx->OutBuffer[3] * 255 + (int)(BYTE)pCntx->OutBuffer[3] + 6 - 7; 
			 
					//	lpTarget = (LPBYTE)malloc(t1);	 
					//	lpSource = (LPBYTE)malloc(t1); 
			 
						for (i=0; iOutBuffer[5+i];	 
						} 
 
						Encode_Decode(lpTarget, lpSource, t1); 
 
						switch (lpTarget[4])			 
						{				 
							// 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 
							// AA 55 14 00 F9 58 4B F4 58 13 94 B3 A0 85 90 85 72 5D 0C 62 4E E0 9E 5C 55 AA 			 
						    case 0x0C:		     
								loginuser(pCntx, lpTarget, t1); 
					        	break; 
								// 04 00 00 00 12 09 67 6F 75 7A 61 69 64 75 69 00 06 41 41 41 41 41 41 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00		 
							case 0x12: // 请求建立新人物						 
								createchar(pCntx, lpTarget);			 
								break;	 
							case 0x14:		 
								delchar(pCntx, lpTarget);		 
								break;		 
								// 02 00 00 00 17 00		 
							case 0x17: // 请求新人物数值			 
								request(pCntx, lpTarget[5]);			 
								break;			 
								// 19 00 00 00 1B 03 31 31 31			 
							case 0x1B:				 
								scan_char(pCntx, lpTarget);			 
								break;		 
							case 0xEB:	 
								debug2(pCntx);				 
								break; 
						} 
						break; 
				} 
	 
				memcpy(pCntx->OutBuffer, 0, 0); 
				pCntx->nOutBufIndex = 0; 
			} 
            // 开始读取 
            ReadPack(pCntx); 
        } 
    } 
 
    return 0; 
} 
 
 
void CreateWorkerThreads() 
{ 
    SYSTEM_INFO  sysinfo; 
    DWORD        dwThreadId; 
    DWORD        dwThreads; 
    DWORD        i; 
 
    GetSystemInfo(&sysinfo); 
    dwThreads = sysinfo.dwNumberOfProcessors * 2 + 2; 
 
    for (i=0; isock = newsocket; 
        pKey->ovOut.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//为写信息包过程设置(事件对象) event . 
        pKey->ovOut.hEvent = (HANDLE)((DWORD)pKey->ovOut.hEvent | 0x1);  
     
        CreateIoCompletionPort(                                   //为请求绑定端口 
                (HANDLE)newsocket, 
                ghCompletionPort, 
                (DWORD)pKey,    
                0); 
 
		sprintf(tmp, "%d.%d.%d.%d 连接", clientAddress.sin_addr.S_un.S_un_b.s_b1,  
					clientAddress.sin_addr.S_un.S_un_b.s_b2, 
					clientAddress.sin_addr.S_un.S_un_b.s_b3, 
					clientAddress.sin_addr.S_un.S_un_b.s_b4); 
 
		InsertLogMsg(tmp); 
 
        ReadPack(pKey);                                          // 完成第一次读操作 
    } 
//	uninstallsqldata(); 
	return 0; 
} 
 
int APIENTRY WinMain(HINSTANCE hInstance, 
                     HINSTANCE hPrevInstance, 
                     LPSTR     lpCmdLine, 
                     int       nCmdShow) 
{ 
 	// TODO: Place code here. 
	MSG msg; 
//	HACCEL hAccelTable; 
	char szfilepath[256]; 
	char szfilename[256]; 
	char tmp[24]; 
 
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); 
	LoadString(hInstance, IDC_SERVERSELECT, szWindowClass, MAX_LOADSTRING); 
 
	GetExeDir(szfilepath); 
 
	sprintf(szfilename, "%sserverselect.ini", szfilepath); 
 
	GetPrivateProfileString("ODBC",   "ACCOUNT_DSN",      "", option.accountdsn,       24, szfilename); 
	GetPrivateProfileString("ODBC",   "ACCOUNT_UID",      "", option.accountuid,       24, szfilename); 
	GetPrivateProfileString("ODBC",   "ACCOUNT_PWD",      "", option.accountpwd,       24, szfilename); 
	GetPrivateProfileString("ODBC",   "CHAR_DSN",         "", option.chardsn,          24, szfilename); 
	GetPrivateProfileString("ODBC",   "CHAR_UID",         "", option.charuid,          24, szfilename); 
	GetPrivateProfileString("ODBC",   "CHAR_PWD",         "", option.charpwd,          24, szfilename); 
	GetPrivateProfileString("ODBC",   "LOG_DSN",          "", option.logdsn,           24, szfilename); 
	GetPrivateProfileString("ODBC",   "LOG_UID",          "", option.loguid,           24, szfilename); 
	GetPrivateProfileString("ODBC",   "LOG_PWD",          "", option.logpwd,           24, szfilename); 
	GetPrivateProfileString("SERVER", "PORT",             "", tmp,                     24, szfilename); 
	option.port = atoi(tmp); 
 
	if (!CheckOsVersion()) 
		return 0; 
 
	MyRegisterClass(hInstance); 
 
	// Perform application initialization: 
	if (!InitInstance (hInstance, nCmdShow))  
	{ 
		return FALSE; 
	} 
 
    // CloseHandle(hThread); 
	// Main message loop: 
	while (GetMessage(&msg, NULL, 0, 0))  
	{ 
		TranslateMessage(&msg); 
		DispatchMessage(&msg); 
	} 
 
	return msg.wParam; 
} 
 
 
 
// 
//  FUNCTION: MyRegisterClass() 
// 
//  PURPOSE: Registers the window class. 
// 
//  COMMENTS: 
// 
//    This function and its usage is only necessary if you want this code 
//    to be compatible with Win32 systems prior to the 'RegisterClassEx' 
//    function that was added to Windows 95. It is important to call this function 
//    so that the application will get 'well formed' small icons associated 
//    with it. 
// 
ATOM MyRegisterClass(HINSTANCE hInstance) 
{ 
    WNDCLASS  wc; 
 
    wc.style            = CS_GLOBALCLASS|CS_HREDRAW|CS_VREDRAW; 
    wc.lpfnWndProc      = (WNDPROC)WndProc; 
    wc.cbClsExtra       = 0; 
    wc.cbWndExtra       = 0; 
    wc.hIcon            = LoadIcon((HINSTANCE)hInstance, MAKEINTRESOURCE(IDI_SERVERSELECT)); 
    wc.hInstance        = (HINSTANCE)hInstance; 
    wc.hCursor          = LoadCursor(NULL, IDC_ARROW); 
    wc.hbrBackground    = (HBRUSH)(COLOR_WINDOW + 1); 
    wc.lpszMenuName     = MAKEINTRESOURCE(IDR_MAINMENU); 
    wc.lpszClassName    = _SELECT_SERVER_CLASS; 
 
	return RegisterClass(&wc); 
} 
 
void SwitchMenuItem(BOOL fFlag) 
{ 
	HMENU hMainMenu = GetMenu(option.hMainWnd); 
	HMENU hMenu = GetSubMenu(hMainMenu, 0); 
 
	if (fFlag) 
	{ 
		EnableMenuItem(hMenu, IDM_STARTSERVICE, MF_GRAYED|MF_BYCOMMAND); 
		EnableMenuItem(hMenu, IDM_STOPSERVICE, MF_ENABLED|MF_BYCOMMAND); 
 
		SendMessage(option.hToolBar, TB_SETSTATE, (WPARAM)IDM_STARTSERVICE, (LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0)); 
		SendMessage(option.hToolBar, TB_SETSTATE, (WPARAM)IDM_STOPSERVICE, (LPARAM)MAKELONG(TBSTATE_ENABLED, 0)); 
 
		InsertLogMsg("开始服务"); 
	} 
	else 
	{ 
		EnableMenuItem(hMenu, IDM_STARTSERVICE, MF_ENABLED|MF_BYCOMMAND); 
		EnableMenuItem(hMenu, IDM_STOPSERVICE, MF_GRAYED|MF_BYCOMMAND); 
 
		SendMessage(option.hToolBar, TB_SETSTATE, (WPARAM)IDM_STARTSERVICE, (LPARAM)MAKELONG(TBSTATE_ENABLED, 0)); 
		SendMessage(option.hToolBar, TB_SETSTATE, (WPARAM)IDM_STOPSERVICE, (LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0)); 
 
		InsertLogMsg("停止服务"); 
	} 
} 
 
int AddNewLogMsg() 
{ 
	LV_ITEM		lvi; 
	TCHAR		szText[64]; 
 
	int nCount = ListView_GetItemCount(option.hLogMsgWnd); 
 
	if (nCount >= 50) 
	{ 
		ListView_DeleteItem(option.hLogMsgWnd, 0); 
		nCount--; 
	} 
 
	lvi.mask		= LVIF_TEXT; 
	lvi.iItem		= nCount; 
	lvi.iSubItem	= 0; 
	 
	_tstrdate(szText); 
 
	lvi.pszText = szText; 
	 
	ListView_InsertItem(option.hLogMsgWnd, &lvi); 
 
	_tstrtime(szText); 
 
	ListView_SetItemText(option.hLogMsgWnd, nCount, 1, szText); 
 
	return nCount; 
} 
 
void InsertLogMsg(char *lpszMsg) 
{ 
	int nCount = AddNewLogMsg(); 
 
	if (strlen(lpszMsg) <= 256) 
	{ 
		ListView_SetItemText(option.hLogMsgWnd, nCount, 2, lpszMsg); 
		ListView_Scroll(option.hLogMsgWnd, 0, 8); 
	} 
} 
 
void SetFontColor() 
{ 
	CHOOSECOLOR color; 
	static COLORREF acrCustClr[16];  
 
	memset( &color, 0, sizeof( color ) ); 
	color.hwndOwner		= option.hMainWnd; 
	color.lStructSize	= sizeof( color ); 
	color.Flags			= CC_FULLOPEN | CC_RGBINIT; 
	color.rgbResult		= ListView_GetTextColor(option.hLogMsgWnd ); 
	color.lpCustColors	= acrCustClr; 
 
	if ( !ChooseColor( &color ) ) 
		return; 
 
	ListView_SetTextColor(option.hLogMsgWnd, color.rgbResult ); 
 
	InvalidateRect(option.hLogMsgWnd, NULL, TRUE ); 
} 
 
 
void SetBackColor() 
{ 
	CHOOSECOLOR color; 
	static COLORREF acrCustClr[16];  
 
	memset( &color, 0, sizeof( color ) ); 
	color.hwndOwner		= option.hMainWnd; 
	color.lStructSize	= sizeof( color ); 
	color.Flags			= CC_FULLOPEN | CC_RGBINIT; 
	color.rgbResult		= ListView_GetBkColor(option.hLogMsgWnd ); 
	color.lpCustColors	= acrCustClr; 
 
	if ( !ChooseColor( &color ) ) 
		return; 
 
	ListView_SetTextBkColor(option.hLogMsgWnd, color.rgbResult ); 
	ListView_SetBkColor(option.hLogMsgWnd, color.rgbResult ); 
 
	InvalidateRect(option.hLogMsgWnd, NULL, TRUE ); 
} 
 
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) 
{ 
 	DWORD dwStyle; 
	int i; 
  	int	nStatusPartsWidths[_NUMOFMAX_STATUS_PARTS]; 
	int nCnt; 
	RECT rcMainWnd, rcToolBar, rcStatusBar; 
	LV_COLUMN	lvc; 
	char		szText[64]; 
	INITCOMMONCONTROLSEX icex; 
 
	option.hInst = hInstance; 
	dwStyle = WS_THICKFRAME | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_BORDER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX; 
 
//	OleInitialize(NULL); 
 
	icex.dwSize = sizeof(INITCOMMONCONTROLSEX); 
	icex.dwICC = ICC_LISTVIEW_CLASSES | ICC_BAR_CLASSES | ICC_INTERNET_CLASSES | ICC_TAB_CLASSES; 
 
	InitCommonControlsEx(&icex); 
 
    option.hMainWnd = CreateWindowEx(0, _SELECT_SERVER_CLASS, _SELECT_SERVER_TITLE,  
							dwStyle | WS_VISIBLE, 
							CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,                  
							NULL, NULL, (HINSTANCE)hInstance, NULL); 
 
	option.hToolBar = CreateToolbarEx(option.hMainWnd, WS_CHILD|CCS_TOP|WS_VISIBLE|SBS_SIZEGRIP, 
									_IDW_TOOLBAR, sizeof(tbButtons) / sizeof(TBBUTTON), (HINSTANCE)hInstance, IDB_TOOLBAR, 
									(LPCTBBUTTON)&tbButtons, sizeof(tbButtons) / sizeof(TBBUTTON), 
									_BMP_CX, _BMP_CY, _BMP_CX, _BMP_CY, sizeof(TBBUTTON)); 
 
	GetClientRect(option.hMainWnd, &rcMainWnd); 
	GetWindowRect(option.hToolBar, &rcToolBar); 
 
	option.hStatusBar = CreateWindowEx(0L, STATUSCLASSNAME, _T(""), WS_CHILD|WS_VISIBLE|SBS_SIZEGRIP, 
									0, rcMainWnd.bottom - _STATUS_HEIGHT, (rcMainWnd.right - rcMainWnd.left), _STATUS_HEIGHT, option.hMainWnd, (HMENU)_IDW_STATUSBAR, option.hInst, NULL); 
	nCnt = 0; 
	 
	for (i = _NUMOFMAX_STATUS_PARTS - 1; i >= 0; i--) 
		nStatusPartsWidths[nCnt++] = (rcMainWnd.right - rcMainWnd.left) - (90 * i); 
 
	SendMessage(option.hStatusBar, SB_SETPARTS, _NUMOFMAX_STATUS_PARTS, (LPARAM)nStatusPartsWidths); 
	SendMessage(option.hStatusBar, SB_SETTEXT, MAKEWORD(0, 0), (LPARAM)_TEXT("服务器关闭")); 
//	SendMessage(option.hStatusBar, SB_SETTEXT, MAKEWORD(1, 0), (LPARAM)_TEXT("在线 0 人")); 
//	SendMessage(option.hStatusBar, SB_SETTEXT, MAKEWORD(2, 0), (LPARAM)_TEXT("怪物 0 个")); 
//	SendMessage(option.hStatusBar, SB_SETTEXT, MAKEWORD(3, 0), (LPARAM)_TEXT("矿石 0 个")); 
 
	GetWindowRect(option.hStatusBar, &rcStatusBar); 
 
    option.hLogMsgWnd = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, _TEXT(""),  
							WS_CHILD|WS_VISIBLE|WS_BORDER|LVS_REPORT|LVS_EDITLABELS, 
							0, (rcToolBar.bottom - rcToolBar.top) - 2, (rcMainWnd.right - rcMainWnd.left),  
							(rcMainWnd.bottom - rcMainWnd.top) - (rcToolBar.bottom - rcToolBar.top) + 2 
							- (rcStatusBar.bottom - rcStatusBar.top), 
							option.hMainWnd, NULL, (HINSTANCE)hInstance, NULL); 
 
	ListView_SetExtendedListViewStyleEx(option.hLogMsgWnd, 0, LVS_EX_FULLROWSELECT); 
 
	lvc.mask	= LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; 
	lvc.fmt		= LVCFMT_LEFT; 
	lvc.cx		= 100; 
	lvc.pszText	= szText; 
 
	for (i = 0; i < 3; i++) 
	{ 
		lvc.iSubItem = i; 
		LoadString((HINSTANCE)hInstance, IDS_LVS_LABEL1 + i, szText, sizeof(szText)); 
		 
		ListView_InsertColumn(option.hLogMsgWnd, i, &lvc); 
	} 
	 
	ListView_SetColumnWidth(option.hLogMsgWnd, 2, 220 ); 
 
	SendMessage(option.hToolBar, TB_SETSTATE, (WPARAM)IDM_STOPSERVICE, (LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0)); 
 
	ShowWindow(option.hMainWnd, SW_SHOW); 
	UpdateWindow(option.hMainWnd); 
 
	InvalidateRect(option.hMainWnd, NULL, TRUE ); 
 
	return TRUE; 
} 
 
void OnCommand(WPARAM wParam, LPARAM lParam) 
{ 
	HANDLE hThread; 
	DWORD  dwThreadId; 
	int i; 
 
	switch (LOWORD(wParam)) 
	{ 
		case IDM_STARTSERVICE: // 开始服务 
		{ 
			if (!loadserverdata()) 
				return;  
			InsertLogMsg("加载服务器列表成功"); 
 
			if(!InitSQLEnvironment()) 
				return; 
			InsertLogMsg("初始化ODBC环境成功"); 
			if(!ConnectDatabase()) 
				return; 
			InsertLogMsg("安装ODBC成功"); 
 
			for(i=0; i<8; i++) 
			{	 
				G_BYTE_XorTable[i] = 0x10 ^ G_BYTE_DOII_XorTable[i]; 
			} 
  			InsertLogMsg("安装密钥成功"); 
 
			hThread = CreateThread(NULL, 0, ServerThread, NULL, 0, &dwThreadId); 
 
			return; 
		} 
		case IDM_STOPSERVICE: // 停止服务 
		{ 
		//	g_fTerminated = TRUE; 
 
		//	ClearSocket(g_gcSock); 
 
			SwitchMenuItem(FALSE); 
			SendMessage(option.hStatusBar, SB_SETTEXT, MAKEWORD(0, 0), (LPARAM)_TEXT("服务器关闭")); 
 
			return; 
		} 
		case IDM_FONTCOLOR: 
			SetFontColor(); 
			return; 
		case IDM_BACKCOLOR: 
			SetBackColor(); 
			return; 
		case ID_MENU_TALK: 
		//	DialogBox(hInst, (LPCTSTR)IDD_TALK_DIALOG, option.hMainWnd, (DLGPROC)TalkConfig); 
			return; 
		case ID_MENU_ABOUT: 
		{ 
			DialogBox(option.hInst, (LPCTSTR)IDD_ABOUTBOX, option.hMainWnd, (DLGPROC)About); 
			return; 
		} 
	} 
} 
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
	RECT rcToolBar, rcMain, rcStatusBar; 
	int	nStatusPartsWidths[_NUMOFMAX_STATUS_PARTS]; 
	int i, nCnt; 
	TCHAR	szMsg[128]; 
	TCHAR	szTitle[128]; 
 
	switch (message) 
	{ 
 
		case WM_INITDIALOG: 
			return TRUE; 
		case WM_COMMAND: 
			OnCommand(wParam, lParam); 
			return TRUE; 
/*		case WM_ERASEBKGND: 
			return TRUE; // ORZ: 濒糊芭府绰 巴 力芭 
		case WM_PAINT: 
			return TRUE; 
			*/ 
		case WM_SIZE: 
		{ 
			if (option.hToolBar && option.hMainWnd && option.hStatusBar)  
			{ 
				GetWindowRect(option.hToolBar, &rcToolBar); 
				GetClientRect(option.hMainWnd, &rcMain); 
				GetWindowRect(option.hStatusBar, &rcStatusBar); 
 
				MoveWindow(option.hToolBar, 0, 0, LOWORD(lParam), (rcToolBar.bottom - rcToolBar.top), TRUE); 
				MoveWindow(option.hStatusBar, 0, rcMain.bottom - (rcStatusBar.bottom - rcStatusBar.top),  
								LOWORD(lParam), (rcStatusBar.bottom - rcStatusBar.top), TRUE); 
				MoveWindow(option.hLogMsgWnd, 0, (rcToolBar.bottom - rcToolBar.top) - 2, (rcMain.right - rcMain.left),  
								(rcMain.bottom - rcMain.top) - (rcToolBar.bottom - rcToolBar.top) - (rcStatusBar.bottom - rcStatusBar.top) + 2,  
								TRUE); 
				nCnt = 0; 
 
				for (i = _NUMOFMAX_STATUS_PARTS - 1; i >= 0 ; i--) 
					nStatusPartsWidths[nCnt++] = (rcStatusBar.right - rcStatusBar.left) - (90 * i); 
 
				SendMessage(option.hStatusBar, SB_SETPARTS, _NUMOFMAX_STATUS_PARTS, (LPARAM)nStatusPartsWidths); 
 
			//	InvalidateRect(option.hStatusBar, NULL, TRUE ); 
 
			//	ShowWindow(option.hStatusBar, SW_SHOW); 
			} 
 
			break; 
		} 
		 
		case WM_CLOSE: 
		{ 
 
			LoadString(option.hInst, IDS_PROGRAM_QUIT, szMsg, sizeof(szMsg)); 
			LoadString(option.hInst, IDS_PROGRAM_TITLE, szTitle, sizeof(szTitle)); 
 
			if (MessageBox(option.hMainWnd, szMsg, szTitle, MB_ICONINFORMATION|MB_YESNO) == IDYES) 
			{			 
//				ClearServerSocket(); 
//				DisconnectFromServer(); 
 
//				savelumpinfo(Lump_info); 
 
				OnCommand(IDM_STOPSERVICE, 0L); 
 
//				CoUninitialize(); 
 
				WSACleanup(); 
 
				PostQuitMessage(0); 
			} 
 
			return 0L; 
		} 
	} 
 
	return (DefWindowProc(hWnd, message, wParam, lParam)); 
} 
 
// Mesage handler for about box. 
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
	switch (message) 
	{ 
		case WM_INITDIALOG: 
				return TRUE; 
 
		case WM_COMMAND: 
			if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)  
			{ 
				EndDialog(hDlg, LOWORD(wParam)); 
				return TRUE; 
			} 
			break; 
	} 
    return FALSE; 
}