www.pudn.com > MUDGame.rar > Server.cpp


#define _SERVER_INCLUDE_ 
 
#include "XMLEngine.h" 
 
 
//#include "..\Common Include\CommonInclude.h" 
 
 
#pragma comment(lib,"ws2_32.lib") 
 
using namespace std; 
 
 
 
#define PORT	5050 
 
 
 
bool g_bExit=false; 
 
 
//global functions declaration 
 
void doRecvCmd(vector&vecSockInfo,int idx); 
void doRecvData(vector&vecSockInfo,int idx); 
void doExecCmd(_ConnectionPtr,vector&vecSockInfo,int idx); 
void doAuthen(_ConnectionPtr conn,vector&vecSockInfo,int idx); 
void doReg(_ConnectionPtr conn,vector&vecSockInfo,int idx); 
void doInitRole(_ConnectionPtr conn,vector&vecSockInfo,int idx); 
void doGetRoleInfo(_ConnectionPtr conn,vector&vecSockInfo,int idx,char * uName); 
void doGetOnLineList(vector&vecSockInfo,int idx); 
void doGetObjectInfo(CXMLEngine&,vector&vecSockInfo,int idx); 
void doSaveMessage(vector&vecSockInfo,int idx); 
void doGetMessage(vector&vecSockInfo,int idx); 
void doCheckNPC(CXMLEngine&,vector&vecSockInfo,int idx); 
void doGetNPCInfo(CXMLEngine&,vector&vecSockInfo,int idx); 
void doUpdateData(_ConnectionPtr conn,vector&vecSockInfo,int idx); 
void doGetLevelInfo(CXMLEngine&,vector&vecSockInfo,int); 
void doGetMonsterInfo(CXMLEngine&,vector&vecSockInfo,int idx); 
void doGetSkillInfo(CXMLEngine&,vector&vecSockInfo,int idx); 
void doNotice(vector&vecSockInfo,int idx); 
void doUpdateAfterFight(_ConnectionPtr,vector&vecSockInfo,int idx); 
 
 
_ConnectionPtr CreateConnection(const char *); 
bool cmpInDBwithStr(const _ConnectionPtr& connPtr,char* str1,char* str2,DBopCmd); 
 
template 
void EraseByIndex(vector&vec,int index) 
{ 
	vector::iterator it; 
	it=vec.begin()+index; 
	vec.erase(it); 
} 
 
 
 
 
CXMLEngine xmlEngine("serverdata.xml"); 
 
//end global functions declaration 
 
 
 
//global var 
vector vecOnLineRoles; 
vector g_vecMessageList; 
 
//end global var 
 
void main() 
{ 
	_ConnectionPtr m_pConnection; 
 
 
	::CoInitialize(NULL); 
 
 
	//数据库位置 
	char dbSource[10]="my.mdb"; 
 
 
	WSADATA wsd; 
 
	if(WSAStartup(0x0202,&wsd)==0) 
	{ 
		cout<<"服务器正常启动!"< vecSocketInfo; 
 
	SOCKET sListen=socket(AF_INET,SOCK_STREAM,0); 
 
 
	sockaddr_in serverAddr; 
	serverAddr.sin_family=AF_INET; 
	serverAddr.sin_addr.s_addr=htonl(INADDR_ANY); 
	serverAddr.sin_port=htons(PORT); 
 
	if(bind(sListen,(sockaddr *)&serverAddr,sizeof(serverAddr))==0) 
	{ 
		cout<<"服务器已绑定!"<State) 
		m_pConnection->Close(); 
	m_pConnection=NULL; 
 
} 
 
 
//处理接受的命令 
void doRecvCmd(vector&vecSockInfo,int idx) 
{ 
	SocketInfo *sockInfo=&vecSockInfo[idx]; 
 
	int nRet=recv(sockInfo->socket,(char*)&sockInfo->scmd,sizeof(sockInfo->scmd),0); 
	//如果用户正常登陆,再用closesocket关闭,socket会返回0 
	//如果用户直接关闭程序会返回SOCKET_ERROR,强行关闭 
	if(nRet==SOCKET_ERROR||nRet==0) 
	{ 
		cout<<"客户端"<socket<<"已退出!"<::iterator iter=vecOnLineRoles.begin();iter!=vecOnLineRoles.end();iter++) 
		{ 
			if(strcmp(iter->uName,sockInfo->username)==0) 
			{ 
				vecOnLineRoles.erase(iter); 
			} 
		}*/ 
		for(UINT i=0;iusername)==0) 
			{ 
				EraseByIndex(vecOnLineRoles,i); 
			} 
		} 
		sockInfo->socket=INVALID_SOCKET; 
		EraseByIndex(vecSockInfo,idx); 
		return; 
	} 
 
	//有些命令是不需要数据的,在此过滤 
	switch(sockInfo->scmd.CommandID) 
	{ 
	case CMD_GETROLEINFO: 
		sockInfo->scurrop=execCmd; 
		return; 
	case CMD_GETOLLIST: 
		sockInfo->scurrop=execCmd; 
		return; 
	case CMD_GETMESSAGE: 
		sockInfo->scurrop=execCmd; 
		return; 
	} 
 
	//没有过滤的都有数据需要接受 
	sockInfo->scurrop=recvData; 
} 
 
 
//接受数据函数 
void doRecvData(vector&vecSockInfo,int idx) 
{ 
	SocketInfo* sockinfo=&vecSockInfo[idx]; 
	sockinfo->data=new char[sockinfo->scmd.DataSize+1]; 
	memset(sockinfo->data,0,sockinfo->scmd.DataSize+1); 
	 
 
	int nRet=recv(sockinfo->socket,sockinfo->data,sockinfo->scmd.DataSize,0); 
	if(nRet==SOCKET_ERROR||nRet==0) 
	{ 
		cout<<"客户端"<socket<<"已退出!"<username)==0) 
			{ 
				EraseByIndex(vecOnLineRoles,i); 
			} 
		} 
		sockinfo->socket=INVALID_SOCKET; 
		EraseByIndex(vecSockInfo,idx); 
		return; 
	} 
 
	sockinfo->scurrop=execCmd; 
} 
 
//处理命令函数,命令分发 
void doExecCmd(_ConnectionPtr conn,vector&vecSockInfo,int idx) 
{ 
	SocketInfo *sockinfo=&vecSockInfo[idx]; 
	switch(sockinfo->scmd.CommandID) 
	{ 
	case CMD_AUTHEN: 
		doAuthen(conn,vecSockInfo,idx); 
		break; 
	case CMD_REGISTER: 
		doReg(conn,vecSockInfo,idx); 
		break; 
	case CMD_CREATEROLE: 
		doInitRole(conn,vecSockInfo,idx); 
		break; 
	case CMD_GETROLEINFO: 
		doGetRoleInfo(conn,vecSockInfo,idx,sockinfo->username); 
		break; 
	case CMD_GETOLLIST: 
		doGetOnLineList(vecSockInfo,idx); 
		break; 
	case CMD_GETOBJECTINFO: 
		doGetObjectInfo(xmlEngine,vecSockInfo,idx); 
		break; 
	case CMD_SPEAK: 
		doSaveMessage(vecSockInfo,idx); 
		break; 
	case CMD_GETMESSAGE: 
		doGetMessage(vecSockInfo,idx); 
		break; 
	case CMD_CHECKHASNPC: 
		doCheckNPC(xmlEngine,vecSockInfo,idx); 
		break; 
	case CMD_GETNPCINFO: 
		doGetNPCInfo(xmlEngine,vecSockInfo,idx); 
		break; 
	case CMD_UPDATE: 
		doUpdateData(conn,vecSockInfo,idx); 
		break; 
	case CMD_GETLEVELINFO: 
		doGetLevelInfo(xmlEngine,vecSockInfo,idx); 
		break; 
	case CMD_GETMONSTERINFO: 
		doGetMonsterInfo(xmlEngine,vecSockInfo,idx); 
		break; 
	case CMD_GETSKILLINFO: 
		doGetSkillInfo(xmlEngine,vecSockInfo,idx); 
		break; 
	case CMD_NOTICE: 
		doNotice(vecSockInfo,idx); 
		break; 
	case CMD_UPDATEROLEINFO: 
		doUpdateAfterFight(conn,vecSockInfo,idx); 
		break; 
	default: 
		break; 
	} 
 
 
	sockinfo->scurrop=recvCmd; 
} 
 
void doUpdateAfterFight(_ConnectionPtr conn,vector&vecSockInfo,int idx) 
{ 
	SocketInfo* sock=&vecSockInfo[idx]; 
 
	player* tplayer=(player*)sock->data; 
 
	char dbcom[512]; 
	memset(dbcom,0,512); 
 
	sprintf(dbcom,"update role set hp=%d,mp=%d,attack=%d,defendence=%d,celerity=%d,exp=%d,tael=%d,lv=%d,\ 
		objectnum1=%d,objectnum2=%d,objectnum3=%d,objectnum4=%d,objectnum5=%d,objectnum6=%d,objectnum7=%d,\ 
		objectnum8=%d,objectnum9=%d,objectnum10=%d where username='%s'",tplayer->hp,tplayer->mp,tplayer->attack,tplayer->defendence,\ 
		tplayer->celerity,tplayer->exp,tplayer->money,tplayer->level,tplayer->ownObject[0].num,tplayer->ownObject[1].num,\ 
		tplayer->ownObject[2].num,tplayer->ownObject[3].num,tplayer->ownObject[4].num,tplayer->ownObject[5].num,\ 
		tplayer->ownObject[6].num,tplayer->ownObject[7].num,tplayer->ownObject[8].num,tplayer->ownObject[9].num,sock->username); 
 
	_variant_t counts; 
 
	conn->Execute(dbcom,&counts,adCmdText); 
 
	if(counts.intVal==1) 
	{ 
		char res[20]; 
		memset(res,0,20); 
 
		strcpy(res,"UP OK"); 
 
		send(sock->socket,res,sizeof(res),0); 
	} 
	else 
	{ 
		char res[20]; 
		memset(res,0,20); 
 
		strcpy(res,"UP ERR"); 
 
		send(sock->socket,res,sizeof(res),0); 
 
	} 
 
 
} 
 
 
//宝物通知信息处理 
void doNotice(vector&vecSockInfo,int idx) 
{ 
	SocketInfo* sock=&vecSockInfo[idx]; 
	 
	GameMessage mess; 
	memset(&mess,0,sizeof(mess)); 
 
	char* head="SYS"; 
 
	sprintf(mess.message,"%s %s",head,sock->data); 
 
	for(UINT i=0;i&vecSockInfo,int idx) 
{ 
	SocketInfo* sock=&vecSockInfo[idx]; 
 
	skill sk; 
	memset(&sk,0,sizeof(sk)); 
 
	if(xmleng.FillWithSkillData(sock->data,sk)) 
	{ 
		send(sock->socket,(char*)&sk,sizeof(sk),0); 
	} 
 
	delete[] sock->data; 
} 
 
//获取怪物信息 
void doGetMonsterInfo(CXMLEngine& xmleng,vector&vecSockInfo,int idx) 
{ 
	SocketInfo* sock=&vecSockInfo[idx]; 
 
	monster mon; 
	memset(&mon,0,sizeof(mon)); 
 
	if(xmleng.FillWithMonsterInfo(sock->data,mon)) 
	{ 
		send(sock->socket,(char*)&mon,sizeof(mon),0); 
	} 
 
	delete[] sock->data; 
} 
 
//获取等级信息 
void doGetLevelInfo(CXMLEngine& xmleng,vector&vecSockInfo,int idx) 
{ 
	SocketInfo* sock=&vecSockInfo[idx]; 
	 
	LevelInfo lvi; 
	memset(&lvi,0,sizeof(lvi)); 
 
	if(xmleng.FillWithLevelInfo(sock->data,lvi)) 
	{ 
		send(sock->socket,(char*)&lvi,sizeof(lvi),0); 
	} 
 
	delete[] sock->data; 
 
} 
 
 
//通用更新函数 
void doUpdateData(_ConnectionPtr conn,vector&vecSockInfo,int idx) 
{ 
	SocketInfo* sock=&vecSockInfo[idx]; 
	updateNewDS* updata=(updateNewDS*)sock->data; 
 
 
	char dbcom[256]; 
	memset(dbcom,0,256); 
	switch(updata->opType) 
	{ 
	case DBOP_TYPE_NUM: 
		sprintf(dbcom,"update role set %s=%d where username='%s'",updata->op,updata->num,sock->username); 
		break; 
	case DBOP_TYPE_STRING: 
		sprintf(dbcom,"update role set %s='%s' where username='%s'",updata->op,updata->item,sock->username); 
		break; 
	case DBOP_TYPE_ALL: 
		char *pbuf=updata->op; 
		char firstop[20],secondop[20]; 
		memset(firstop,0,20); 
		memset(secondop,0,20); 
		int index=0; 
		while(*pbuf!=' ') 
		{ 
			firstop[index++]=*pbuf++; 
		} 
		firstop[index]='\0'; 
 
		*pbuf++; 
		 
		index=0; 
		while(*pbuf!='\0') 
		{ 
			secondop[index++]=*pbuf++; 
		} 
		secondop[index]='\0'; 
 
		sprintf(dbcom,"update role set %s='%s',%s=%d where username='%s'",firstop,updata->item,secondop,updata->num,sock->username); 
		break; 
	} 
 
 
	_variant_t counts; 
 
	conn->Execute(dbcom,&counts,adCmdText); 
 
 
	if(counts.intVal==1) 
	{ 
		char szSend[20]; 
		memset(szSend,0,20); 
		strcpy(szSend,"UP OK"); 
		send(sock->socket,szSend,sizeof(szSend),0); 
	} 
	else 
	{ 
		char szSend[20]; 
		memset(szSend,0,20); 
		strcpy(szSend,"UP ERR"); 
		send(sock->socket,szSend,sizeof(szSend),0); 
	} 
 
 
	delete[] sock->data; 
 
} 
 
 
 
void doGetNPCInfo(CXMLEngine& xmleng,vector&vecSockInfo,int idx) 
{ 
	SocketInfo* sock=&vecSockInfo[idx]; 
	npc npcdata; 
	memset(&npcdata,0,sizeof(npcdata)); 
	if(xmleng.FillWithNPCInfo(sock->data,npcdata)) 
	{ 
		send(sock->socket,(char*)&npcdata,sizeof(npcdata),0); 
	} 
 
	delete[] sock->data; 
} 
 
 
void doCheckNPC(CXMLEngine& xmleng,vector&vecSockInfo,int idx) 
{ 
	 
	SocketInfo* sock=&vecSockInfo[idx]; 
	if(xmleng.CheckNPC(sock->data)) 
	{ 
		bool hasnpc=true; 
		send(sock->socket,(char*)&hasnpc,sizeof(hasnpc),0); 
	} 
	else 
	{ 
		bool hasnpc=false; 
		send(sock->socket,(char*)&hasnpc,sizeof(hasnpc),0); 
	} 
 
 
	delete[] sock->data; 
} 
 
 
//服务器端暂存信息函数 
//消息大小:512bytes 
//消息格式:		|					信息头					|消息内容| 
//消息头格式:		|   [none]/[接受玩家用户名]|发话玩家昵称	| 
// 
void doSaveMessage(vector&vecSockInfo,int idx) 
{ 
	SocketInfo* sock=&vecSockInfo[idx]; 
	GameMessage* pGM=(GameMessage*)sock->data; 
 
	g_vecMessageList.push_back(*pGM); 
	 
} 
 
//获取信息函数 
void doGetMessage(vector&vecSockInfo,int idx) 
{ 
	int messNum=0; 
	SocketInfo* sock=&vecSockInfo[idx]; 
	for(UINT i=0;iusername)==0) 
			messNum++; 
	} 
 
	 
	send(sock->socket,(char*)&messNum,sizeof(messNum),0); 
 
	while(messNum) 
	{ 
		for(UINT i=0;iusername)==0) 
			{ 
				send(sock->socket,g_vecMessageList[i].message,sizeof(g_vecMessageList[i].message),0); 
				EraseByIndex(g_vecMessageList,i); 
				messNum--; 
				break; 
			} 
		} 
	} 
} 
 
//获取相关资源信息 
void doGetObjectInfo(CXMLEngine& xmleng,vector&vecSockInfo,int idx) 
{ 
	SocketInfo* sockinfo=&vecSockInfo[idx]; 
	Myobject mobj; 
	memset(&mobj,0,sizeof(Myobject)); 
	/*char oname[20]; 
	memset(oname,0,sizeof(oname)); 
	strcpy(oname,sockinfo->data);*/ 
	 
	xmleng.FillWithObjectData(sockinfo->data,mobj); 
 
	/*int datasize=sizeof(mobj); 
	send(sockinfo->socket,(char *)&datasize,sizeof(int),0);*/ 
	 
	send(sockinfo->socket,(char *)&mobj,sizeof(mobj),0); 
 
 
	delete[] sockinfo->data; 
 
} 
 
//获取玩家在线列表 
void doGetOnLineList(vector&vecSockInfo,int idx) 
{ 
	SocketInfo* sock=&vecSockInfo[idx]; 
	int olnum=0; 
	olnum=(int)vecOnLineRoles.size(); 
 
	//发送在线玩家个数 
	send(sock->socket,(char*)&olnum,sizeof(olnum),0); 
 
	if(olnum>0) 
	{ 
		for(vector::iterator iter=vecOnLineRoles.begin();iter!=vecOnLineRoles.end();iter++) 
		{			 
			OnLineList tempOLR; 
			memset(&tempOLR,0,sizeof(tempOLR)); 
			strcpy(tempOLR.uName,iter->uName); 
			strcpy(tempOLR.nName,iter->nName); 
			tempOLR.pos[0]=iter->pos[0]; 
			tempOLR.pos[1]=iter->pos[1]; 
			send(sock->socket,(char*)&tempOLR,sizeof(tempOLR),0); 
		} 
	} 
 
} 
 
//获取角色信息 次函数仅仅在第一次登陆游戏调用,由于本函数极其笨重,效率太低。 
void doGetRoleInfo(_ConnectionPtr conn,vector&vecSockInfo,int idx,char * uName) 
{ 
		_RecordsetPtr recptr; 
		SocketInfo* sock=&vecSockInfo[idx]; 
		char tName[20]; 
		memset(tName,0,20); 
		strcpy(tName,uName); 
		char dbcomstr[256]; 
		sprintf(dbcomstr,"select * from role where username='%s'",tName); 
		_variant_t counts; 
		recptr=conn->Execute(dbcomstr,&counts,adCmdText); 
 
		if(!recptr->adoEOF) 
		{ 
			recptr->MoveFirst(); 
		} 
		else 
		{ 
			char szSend[20]; 
			memset(szSend,0,20); 
			strcpy(szSend,"GETRI ERR"); 
			send(sock->socket,szSend,(int)strlen(szSend),0);	 
			return; 
		} 
 
		_variant_t var; 
		char* temp; 
		OnLineList m_ol; 
		memset(&m_ol,0,sizeof(m_ol)); 
		player tplayer; 
		memset(&tplayer,0,sizeof(tplayer)); 
		var=recptr->GetCollect("nickname"); 
		temp=_com_util::ConvertBSTRToString((_bstr_t)var); 
		strcpy(m_ol.nName,temp); 
		strcpy(tplayer.nickName,temp); 
		var=recptr->GetCollect("hp"); 
		tplayer.hp=atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
		var=recptr->GetCollect("mp"); 
		tplayer.mp=atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
		var=recptr->GetCollect("attack"); 
		tplayer.attack=atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
		var=recptr->GetCollect("defendence"); 
		tplayer.defendence=atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
		var=recptr->GetCollect("celerity"); 
		tplayer.celerity=atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
		var=recptr->GetCollect("occupation"); 
		tplayer.ownOccup=(occupation)atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
		var=recptr->GetCollect("sex"); 
		tplayer.ownSex=(sex)atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
		var=recptr->GetCollect("exp"); 
		tplayer.exp=atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
		var=recptr->GetCollect("mapx"); 
		tplayer.pos[0]=atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
		m_ol.pos[0]=tplayer.pos[0]; 
		var=recptr->GetCollect("mapy"); 
		tplayer.pos[1]=atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
		m_ol.pos[1]=tplayer.pos[1]; 
		var=recptr->GetCollect("tael"); 
		tplayer.money=atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
		var=recptr->GetCollect("lv"); 
		tplayer.level=atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
		var=recptr->GetCollect("skill1"); 
		tplayer.ownSkill[0]=_com_util::ConvertBSTRToString((_bstr_t)var); 
		var=recptr->GetCollect("skill2"); 
		tplayer.ownSkill[1]=_com_util::ConvertBSTRToString((_bstr_t)var); 
		var=recptr->GetCollect("skill3"); 
		tplayer.ownSkill[2]=_com_util::ConvertBSTRToString((_bstr_t)var); 
		var=recptr->GetCollect("skill4"); 
		tplayer.ownSkill[3]=_com_util::ConvertBSTRToString((_bstr_t)var); 
		var=recptr->GetCollect("skill5"); 
		tplayer.ownSkill[4]=_com_util::ConvertBSTRToString((_bstr_t)var); 
		var=recptr->GetCollect("skill6"); 
		tplayer.ownSkill[5]=_com_util::ConvertBSTRToString((_bstr_t)var); 
		var=recptr->GetCollect("skill7"); 
		tplayer.ownSkill[6]=_com_util::ConvertBSTRToString((_bstr_t)var); 
		var=recptr->GetCollect("equipname1"); 
		tplayer.ownEquip[0]=_com_util::ConvertBSTRToString((_bstr_t)var); 
		var=recptr->GetCollect("equipname2"); 
		tplayer.ownEquip[1]=_com_util::ConvertBSTRToString((_bstr_t)var); 
		var=recptr->GetCollect("equipname3"); 
		tplayer.ownEquip[2]=_com_util::ConvertBSTRToString((_bstr_t)var); 
		var=recptr->GetCollect("objectname1"); 
		tplayer.ownObject[0].ownObjectName=_com_util::ConvertBSTRToString((_bstr_t)var); 
		var=recptr->GetCollect("objectnum1"); 
		tplayer.ownObject[0].num=atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
		var=recptr->GetCollect("objectname2"); 
		tplayer.ownObject[1].ownObjectName=_com_util::ConvertBSTRToString((_bstr_t)var); 
		var=recptr->GetCollect("objectnum2"); 
		tplayer.ownObject[1].num=atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
		var=recptr->GetCollect("objectname3"); 
		tplayer.ownObject[2].ownObjectName=_com_util::ConvertBSTRToString((_bstr_t)var); 
		var=recptr->GetCollect("objectnum3"); 
		tplayer.ownObject[2].num=atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
		var=recptr->GetCollect("objectname4"); 
		tplayer.ownObject[3].ownObjectName=_com_util::ConvertBSTRToString((_bstr_t)var); 
		var=recptr->GetCollect("objectnum4"); 
		tplayer.ownObject[3].num=atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
		var=recptr->GetCollect("objectnum4"); 
		tplayer.ownObject[4].num=atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
		var=recptr->GetCollect("objectname5"); 
		tplayer.ownObject[4].ownObjectName=_com_util::ConvertBSTRToString((_bstr_t)var); 
		var=recptr->GetCollect("objectnum5"); 
		tplayer.ownObject[4].num=atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
		var=recptr->GetCollect("objectname6"); 
		tplayer.ownObject[5].ownObjectName=_com_util::ConvertBSTRToString((_bstr_t)var); 
		var=recptr->GetCollect("objectnum6"); 
		tplayer.ownObject[5].num=atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
		var=recptr->GetCollect("objectname7"); 
		tplayer.ownObject[6].ownObjectName=_com_util::ConvertBSTRToString((_bstr_t)var); 
		var=recptr->GetCollect("objectnum7"); 
		tplayer.ownObject[6].num=atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
		var=recptr->GetCollect("objectname8"); 
		tplayer.ownObject[7].ownObjectName=_com_util::ConvertBSTRToString((_bstr_t)var); 
		var=recptr->GetCollect("objectnum8"); 
		tplayer.ownObject[7].num=atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
		var=recptr->GetCollect("objectname9"); 
		tplayer.ownObject[8].ownObjectName=_com_util::ConvertBSTRToString((_bstr_t)var); 
		var=recptr->GetCollect("objectnum9"); 
		tplayer.ownObject[8].num=atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
		var=recptr->GetCollect("objectname10"); 
		tplayer.ownObject[9].ownObjectName=_com_util::ConvertBSTRToString((_bstr_t)var); 
		var=recptr->GetCollect("objectnum10"); 
		tplayer.ownObject[9].num=atoi(_com_util::ConvertBSTRToString((_bstr_t)var)); 
 
		 
		strcpy(m_ol.uName,sock->username); 
		vecOnLineRoles.push_back(m_ol); 
 
		//发送角色数信息数据大小 
		int datasize=sizeof(tplayer); 
		send(sock->socket,(char*)&datasize,sizeof(datasize),0); 
 
		//发送角色初始化信息数据 
		send(sock->socket,(char*)&tplayer,sizeof(tplayer),0); 
 
 
		recptr->Close(); 
		recptr=NULL; 
} 
 
 
//创建角色函数 
void doInitRole(_ConnectionPtr conn,vector&vecSockInfo,int idx) 
{ 
	SocketInfo* sockinfo=&vecSockInfo[idx]; 
	player* temp=(player*)sockinfo->data; 
	char szSend[30]; 
	memset(szSend,0,20); 
	char dbstr[1024]; 
	memset(dbstr,0,1024); 
	_variant_t counts; 
	sprintf(dbstr,"insert into role (username,nickname,hp,mp,attack,defendence,celerity,occupation,sex,exp,mapx,mapy,tael,lv,\ 
				  skill1,skill2,skill3,skill4,skill5,skill6,skill7,equipname1,equipname2,equipname3,\ 
				  objectname1,objectnum1,objectname2,objectnum2,objectname3,objectnum3,objectname4,objectnum4,objectname5,objectnum5,\ 
				  objectname6,objectnum6,objectname7,objectnum7,objectname8,objectnum8,objectname9,objectnum9,objectname10,objectnum10)\ 
				  values ('%s','%s',%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,'%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s',%d,'%s',%d,'%s',%d,'%s',%d,'%s',%d,'%s',%d,'%s',%d,'%s',%d,'%s',%d,'%s',%d)",\ 
				  sockinfo->username,temp->nickName,temp->hp,temp->mp,temp->attack,temp->defendence,temp->celerity,temp->ownOccup,temp->ownSex,temp->exp,temp->pos[0],temp->pos[1],temp->money,temp->level,\ 
				  temp->ownSkill[0].c_str(),temp->ownSkill[1].c_str(),temp->ownSkill[2].c_str(),temp->ownSkill[3].c_str(),temp->ownSkill[4].c_str(),temp->ownSkill[5].c_str(),temp->ownSkill[6].c_str(),\ 
				  temp->ownEquip[0].c_str(),temp->ownEquip[1].c_str(),temp->ownEquip[2].c_str(),temp->ownObject[0].ownObjectName.c_str(),temp->ownObject[0].num,temp->ownObject[1].ownObjectName.c_str(),temp->ownObject[1].num,\ 
				  temp->ownObject[2].ownObjectName.c_str(),temp->ownObject[2].num,temp->ownObject[3].ownObjectName.c_str(),temp->ownObject[3].num,temp->ownObject[4].ownObjectName.c_str(),temp->ownObject[4].num,\ 
				  temp->ownObject[5].ownObjectName.c_str(),temp->ownObject[5].num,temp->ownObject[6].ownObjectName.c_str(),temp->ownObject[6].num,temp->ownObject[7].ownObjectName.c_str(),temp->ownObject[7].num,\ 
				  temp->ownObject[8].ownObjectName.c_str(),temp->ownObject[8].num,temp->ownObject[9].ownObjectName.c_str(),temp->ownObject[9].num); 
	conn->Execute(dbstr,&counts,adCmdText); 
 
	if(counts.intVal==1) 
	{ 
		strcpy(szSend,"CR OK"); 
		send(sockinfo->socket,szSend,sizeof(szSend),0); 
	} 
	else 
	{ 
		strcpy(szSend,"CR ERR"); 
		send(sockinfo->socket,szSend,sizeof(szSend),0); 
	} 
	 
	 
	delete[] sockinfo->data; 
} 
 
 
 
//验证处理函数 
void doAuthen(_ConnectionPtr conn,vector&vecSockInfo,int idx) 
{ 
	_RecordsetPtr recdset; 
	SocketInfo *sockinfo=&vecSockInfo[idx]; 
	char *pBuf=sockinfo->data; 
	int curidx=0; 
	char szName[20]; 
	memset(szName,0,20); 
	char szPass[20]; 
	memset(szPass,0,20); 
	while(*pBuf!=' ') 
	{ 
		szName[curidx++]=*pBuf++; 
	} 
	szName[curidx]='\0'; 
	 
	*pBuf++; 
 
	curidx=0; 
	while(*pBuf!='\0') 
	{ 
		szPass[curidx++]=*pBuf++; 
	} 
	szPass[curidx]='\0'; 
 
 
	char szSend[30]; 
	memset(szSend,0,30); 
	char cmdstr[256]; 
	memset(cmdstr,0,256); 
	bool bUserExist=false; 
 
	recdset.CreateInstance(__uuidof(Recordset)); 
 
 
	sprintf(cmdstr,"SELECT userpass FROM account WHERE username='%s'",szName); 
	 
	if(conn!=NULL) 
	{ 
		try 
		{ 
			recdset->Open(cmdstr,conn.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText); 
		}catch(_com_error *e) 
		{ 
			cout<ErrorMessage()<adoEOF) 
		{ 
			recdset->MoveFirst(); 
		} 
		else 
		{ 
			strcpy(szSend,"U NONE"); 
			send(sockinfo->socket,szSend,sizeof(szSend),0); 
			return; 
		} 
 
		var=recdset->GetCollect("userpass"); 
		if(var.vt!=VT_NULL) 
			retpass=_com_util::ConvertBSTRToString((_bstr_t)var); 
 
		if(strcmp(szPass,retpass)==0) 
		{ 
			strcpy(szSend,"UP OK"); 
			send(sockinfo->socket,szSend,sizeof(szSend),0); 
			strcpy(sockinfo->username,szName); 
			sockinfo->isAuthen=true; 
		} 
 
		if(strcmp(szPass,retpass)!=0) 
		{ 
			strcpy(szSend,"P ERR"); 
			send(sockinfo->socket,szSend,sizeof(szSend),0); 
		} 
 
	}catch(_com_error *e) 
	{ 
		cout<ErrorMessage()<data; 
 
 
	recdset->Close(); 
	recdset=NULL; 
 
} 
 
 
 
//注册处理函数 
void doReg(_ConnectionPtr conn,vector&vecSockInfo,int idx) 
{ 
	_RecordsetPtr recdset; 
	SocketInfo* sockinfo=&vecSockInfo[idx]; 
	char *pBuf=sockinfo->data; 
	int curidx=0; 
	char szName[20]; 
	memset(szName,0,20); 
	char szPass[20]; 
	memset(szPass,0,20); 
	while(*pBuf!=' ') 
	{ 
		szName[curidx++]=*pBuf++; 
	} 
	szName[curidx]='\0'; 
	 
	*pBuf++; 
 
	curidx=0; 
	while(*pBuf!='\0') 
	{ 
		szPass[curidx++]=*pBuf++; 
	} 
	szPass[curidx]='\0'; 
 
	//注册时,把用户名保存下来,为注册角色准备; 
	strcpy(sockinfo->username,szName); 
 
	variant_t counts; 
	char szSend[30]; 
	char dbcom[256]; 
	char dbselect[256]; 
	memset(dbselect,0,256); 
	memset(szSend,0,30); 
	memset(dbcom,0,256); 
 
	//验证用户名不能重复 
	sprintf(dbselect,"select * from account where username='%s'",szName); 
	recdset=conn->Execute(dbselect,&counts,adCmdText); 
	if(!recdset->adoEOF) 
	{ 
		strcpy(szSend,"ERR REPEAT"); 
		send(sockinfo->socket,szSend,sizeof(szSend),0); 
		delete[] sockinfo->data; 
		return; 
	} 
 
	sprintf(dbcom,"insert into account (username,userpass) values('%s','%s')",szName,szPass); 
	recdset=conn->Execute(dbcom,&counts,adCmdText); 
	 
	if(counts.intVal==1) 
	{ 
		strcpy(szSend,"REG OK"); 
		send(sockinfo->socket,szSend,sizeof(szSend),0); 
	} 
	else 
	{ 
		strcpy(szSend,"REG ERR"); 
		send(sockinfo->socket,szSend,sizeof(szSend),0); 
	} 
	 
	 
	delete[] sockinfo->data; 
 
	/*m_pRs=m_pCmd("insert ..."...)  不需要Close 
	//m_pRs=m_pCmd("select..."...) 需要Close 
 
	recdset->Close();会异常 
	*/ 
} 
 
//打开数据库连接 
_ConnectionPtr CreateConnection(const char * temp) 
{ 
	_ConnectionPtr conn; 
 
	conn.CreateInstance(__uuidof(Connection)); 
 
	char connstr[80]; 
 
	sprintf(connstr,"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s",temp); 
	//2007版的数据库支持 
	//Provider=Microsoft.ACE.OLEDB.12.0;Data Source="d:\xxx.accdb" 
	try 
	{ 
		conn->Open(connstr,"","",adModeUnknown); 
		cout<<"已连接数据库!"<