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


#include  
#include  
#include  
#include  
#include  
#include  
#include "tinyxml.h" 
 
#define _CLIENT_INCLUDE_ 
 
#include "..\Common Include\CommonInclude.h" 
 
#define PORT	5050 
#pragma comment(lib,"ws2_32.lib") 
#pragma comment(lib,"tinyxmld") 
#pragma comment(lib,"winmm") 
 
using namespace std; 
 
 
//网络部分函数 
SOCKET ConnectServer(char* szServerIP,int port); 
 
 
 
//游戏部分函数 
void showLoginMenu(SOCKET); 
void showMainMenu(SOCKET); 
bool initGameCondition(SOCKET); 
void CreateRoleMenu(SOCKET sock); 
bool Auth(SOCKET sock,char*szName,char*szPass); 
bool RegisterUser(SOCKET sock,char* szName,char *szPass); 
void ShowMap(); 
bool GetOnlineRoleList(SOCKET); 
void ShowSystemInfo(); 
void ShowStatus(SOCKET); 
char* GetStringByOccuType(occupation occ); 
void ShowMapInfo(int mapx,int mapy); 
void UpdateData(SOCKET); 
bool NextMapScence(dir); 
void SaveGameData(SOCKET); 
void CreateGameEvent(SOCKET); 
void GetTreasureEvent(SOCKET); 
void MeetEnemyEvent(SOCKET); 
void DefaultEvent(SOCKET); 
void ColorTextOut(const char * str,bool bUnderLine); 
int GetEquipValueByString(SOCKET,string&); 
bool GetObjectInfo(SOCKET,string&,Myobject&); 
void UseThinginPackage(SOCKET sock); 
void ShowDialogMenu(SOCKET); 
void GetGameMessage(SOCKET); 
char* GetStringByObjType(objectType ot); 
void SetHMTop(SOCKET); 
void SellObject(SOCKET); 
bool GetMonsterInfo(SOCKET,monster&); 
void CalculateRoleInfo(SOCKET,int&,int&,int&); 
void GetSkillParamByString(SOCKET sock,string& str,skill&); 
void UpdateAfterFight(SOCKET); 
 
 
//全局变量 
player g_player; 
vector g_OnLineRoles; 
const char* g_szfile="clientdata.xml"; 
int hpTop;//用来控制HP上限 
int mpTop;//用来控制mp上限 
bool reborth=false;//是否重生 
 
void main(int argc,char* argv[]) 
{ 
	system("title 武林群侠传"); 
	 
	//SetConsoleTitle("武林群侠传"); 
	//HANDLE hWnd; 
	//hWnd=GetStdHandle(STD_OUTPUT_HANDLE); 
	//SetConsoleTextAttribute(hWnd,FOREGROUND_GREEN|FOREGROUND_BLUE|COMMON_LVB_UNDERSCORE); 
	WSADATA wsd; 
	if(WSAStartup(0x0202,&wsd)!=0) 
	{ 
		cout<<"wsastartup() failed"<>szServerIP; 
 
	client=ConnectServer(szServerIP,PORT); 
	if(client==NULL) 
	{ 
		cout<<"连接服务器失败!"<探索地图"<对外发话"<查看状态"<显示地图"<向东行进"<向南行进"<向西行进"<向北行进"<使用物品"<退出游戏"<>in; 
			if(in>'9'||in<'0') 
			{ 
				cout<<"输入非法,请输入0-9"<登陆"<注册"<退出"<>choice; 
		switch(choice) 
		{ 
		case 1: 
			cout<<"************************************************************"<>szName; 
			cout<<"请输入你的密码:"; 
			cin>>szPass; 
			if(Auth(sock,szName,szPass)) 
			{ 
				isgoon=false; 
			} 
			else system("pause"); 
			break; 
		case 2: 
			char szrePass[20]; 
			memset(szrePass,0,20); 
			cout<<"************************************************************"<>szName; 
			cout<<"请输入你想注册的密码:"; 
			cin>>szPass; 
			cout<<"请再次输入你的密码:"; 
			cin>>szrePass; 
			if(strcmp(szPass,szrePass)==0) 
			{ 
				if(RegisterUser(sock,szName,szPass)) 
				{ 
					CreateRoleMenu(sock); 
					//cout<<"请用你注册的帐户登陆吧!"<战士"<法师"<道士"<>choice; 
		switch(choice) 
		{ 
		case 1: 
			tplayer.ownOccup=OC_WARRIOR; 
			iswelldone=true; 
			break; 
		case 2: 
			tplayer.ownOccup=OC_RABBI; 
			iswelldone=true; 
			break; 
		case 3: 
			tplayer.ownOccup=OC_DOCTOR; 
			iswelldone=true; 
			break; 
		default: 
			cout<<"输入非法,请输入1-3数字!"<男"<女"<>choice; 
		switch(choice) 
		{ 
		case 1: 
			tplayer.ownSex=MALE; 
			iswelldone=true; 
			break; 
		case 2: 
			tplayer.ownSex=FEMALE; 
			iswelldone=true; 
			break; 
		default: 
			cout<<"输入非法,请输入1-2数字!"<>szName; 
		if(strlen(szName)>=20) 
		{ 
			cout<<"你的输入的字符太多!"<=5&&random<50) 
	{ 
		//遇敌事件 
		MeetEnemyEvent(sock); 
	} 
	if(random>=50) 
	{ 
		//一般描述事件 
		DefaultEvent(sock); 
	} 
 
} 
 
 
//获得宝物事件,概率为5% 
void GetTreasureEvent(SOCKET sock) 
{ 
	srand(timeGetTime()); 
	int item=rand()%5; 
	 
	bool welldone=false; 
 
	ColorTextOut("[系统]由于你的人品爆发,你获得了传说中的宝物!",false); 
	cout<等级增加->属性值增加(基本属性及新技能),金钱增加,没有装备掉落 
// 
void MeetEnemyEvent(SOCKET sock) 
{	 
	monster mon; 
	int totalAK=0,totalDF=0,totalCT=0;//综合伤害值,防御值,敏捷值 
 
	CalculateRoleInfo(sock,totalAK,totalDF,totalCT); 
 
	if(!GetMonsterInfo(sock,mon)) 
	{ 
		cout<<"从服务器端读取怪物数据失败"< sklib;//技能库信息 
	vector mdlib;//药品库信息 
 
 
	//统计拥有技能,以获取技能参数 
	for(int i=0;i=mon.ct)//玩家先出手 
		{ 
			PL:cout<<"*************技能攻击**************"<>in; 
				if(in>'9'||in<'0') 
				{ 
					//cout<<"输入非法,请输入0-9"<0) 
				{ 
					cout<<"你使出了一招——"; 
					ColorTextOut(g_player.ownSkill[choice].c_str(),false); 
					cout<0)//怪物防御太高了 
						temphp=sklib[choice].damage-mon.defence; 
					else temphp=1;//至少一点血 
					cout<0) 
					{ 
						g_player.hp+=mdlib[whatuse].value; 
						g_player.ownObject[hpindex].num--; 
					} 
				} 
				else 
				{ 
					if(g_player.ownObject[mpindex].num-1>0) 
					{ 
						g_player.mp+=mdlib[whatuse].value; 
						g_player.ownObject[mpindex].num--; 
					} 
				} 
 
				goto GW; 
 
			} 
			else//使用物理攻击 
			{ 
				WL:if((g_player.attack-mon.defence)>0) 
					temphp=g_player.attack-mon.defence; 
				else temphp=1; 
 
				mon.hp-=temphp; 
			 
 
				if(mon.hp<=0)//战斗胜利 
				{ 
					g_player.exp+=mon.hasexp; 
					g_player.money+=mon.hasmoney; 
 
					//奖励提示: 
					ColorTextOut("[系统]你获得了",false); 
					cout<0)//mp够发动技能 
				{ 
					ColorTextOut("惊叹!!!",false); 
					cout<0)//玩家防御太高了 
						temphp=mon.skilldamage-g_player.defendence; 
					else temphp=1;//最少1点血 
 
					mon.mp-=mon.needmp; 
					g_player.hp-=temphp; 
					cout<<"你一声闷哼,中招了,耗去了"<0) 
					temphp=mon.attack-g_player.defendence; 
				else temphp=1; 
				g_player.hp-=temphp; 
 
				cout<<"你被耗去了"<=10) 
						if((g_player.money-50*g_player.level)>0) 
							g_player.money-=50*g_player.level; 
						else g_player.money=0; 
 
 
					system("pause");//暂停 
					reborth=true; 
					showMainMenu(sock); 
 
					//退出战斗 
					return; 
 
				} 
				else goto PL; 
				 
			} 
 
		} 
	} 
 
	ColorTextOut("[系统]退出战斗模式",false); 
	UpdateAfterFight(sock);	 
} 
 
 
void UpdateAfterFight(SOCKET sock) 
{ 
 
	//先判断是否达到升级条件 
	SCommand scom; 
	scom.CommandID=CMD_GETLEVELINFO; 
 
	char lv[3]; 
	itoa((g_player.level+1),lv,10);//取得下一级的数据 
 
	scom.DataSize=(int)strlen(lv); 
 
	int nRet=send(sock,(char*)&scom,sizeof(scom),0); 
	if(nRet==SOCKET_ERROR) 
	{ 
		cout<<"UpdateAfterFight()发送数据出错,请检查网络!"<li.needexp)//升级后数据的更改 
	{ 
		g_player.level++; 
		g_player.hp=li.hp; 
		g_player.mp=li.mp; 
		g_player.attack=li.attack; 
		g_player.defendence=li.defendence; 
		g_player.celerity=li.celerity; 
		g_player.exp-=li.needexp; 
		if(strcmp(li.hasskill,"null")!=0)//等级提高,学习新技能 
		{ 
			int i=0; 
			for(;i SuperMarket; 
	char* curScence=map[g_player.pos[0]][g_player.pos[1]]; 
	SCommand scom; 
	scom.CommandID=CMD_CHECKHASNPC; 
	scom.DataSize=(int)strlen(curScence); 
 
	int nRet=send(sock,(char*)&scom,sizeof(scom),0); 
	if(nRet==SOCKET_ERROR) 
	{ 
		cout<<"DefaultEvent()发送数据出错,请检查网络!"<够买"<抛售"<离开"<>in; 
			if(in<'0'||in>'4') 
				return; 
			else	choice=in-'0'; 
 
			switch(choice) 
			{ 
			case 1: 
				cout<<"请选择你要够买物品的序号:(序号外任意键退出)"<>itemchoice; 
				if(itemchoice>=objnum||itemchoice<0) 
					break; 
				cout<<"请输入你要够买的数量:"<>itemnum; 
				 
				if(SuperMarket[itemchoice].buy*itemnum>g_player.money) 
					cout<<"你的钱不够!"<>choice; 
	if(choice>=index||choice<0) 
	{ 
		cout<<"输入非法,请输入数字0-"<>itemnum; 
 
	Myobject mobj; 
	memset(&mobj,0,sizeof(mobj)); 
 
 
	bool bfirstsucess=false; 
	bool bsecondsucess=false; 
 
	SCommand scom; 
	memset(&scom,0,sizeof(scom)); 
	updateNewDS useupdata; 
	memset(&useupdata,0,sizeof(useupdata)); 
	updateNewDS effupdata; 
	memset(&effupdata,0,sizeof(effupdata)); 
	if(GetObjectInfo(sock,g_player.ownObject[choice].ownObjectName,mobj)) 
	{ 
 
		if(g_player.ownObject[choice].num0) 
		{ 
			g_player.ownObject[choice].num-=itemnum; 
 
			useupdata.num=g_player.ownObject[choice].num; 
			sprintf(useupdata.op,"objectnum%d",choice+1);//数据库从1开始 
			useupdata.opType=DBOP_TYPE_NUM; 
			strcpy(useupdata.item,"null");				 
		} 
		else if(g_player.ownObject[choice].num-itemnum==0)//该物品全卖 
		{ 
			g_player.ownObject[choice].num-=itemnum; 
			g_player.ownObject[choice].ownObjectName="null"; 
 
			useupdata.num=g_player.ownObject[choice].num; 
			sprintf(useupdata.op,"objectname%d objectnum%d",choice+1,choice+1);//数据库从1开始 
			useupdata.opType=DBOP_TYPE_ALL; 
			strcpy(useupdata.item,"null"); 
 
		} 
 
		//公共部分 
		g_player.money+=(mobj.buy*itemnum)/2; 
 
		effupdata.num=g_player.money; 
		strcpy(effupdata.op,"tael"); 
		effupdata.opType=DBOP_TYPE_NUM; 
		strcpy(effupdata.item,"null"); 
 
		scom.CommandID=CMD_UPDATE; 
		scom.DataSize=sizeof(useupdata); 
 
		int nRet=send(sock,(char*)&scom,sizeof(scom),0); 
		if(nRet==SOCKET_ERROR) 
		{ 
			cout<<"SellObject()发送数据出错,请检查网络!"<::iterator iter=g_OnLineRoles.begin();iter!=g_OnLineRoles.end();iter++) 
		{ 
			cout<<"["<nName<<"    "; 
			if(i%4==0) 
				cout<>choice; 
 
		if(choice>(int)(g_OnLineRoles.size()-1)||choice<0) 
			return; 
 
		cout<<"请输入你要说的内容:"<>diag; 
		 
		//消息封装 
		strcat(rebuilt,g_player.nickName); 
		strcat(rebuilt," "); 
		strcat(rebuilt,diag); 
 
		strcpy(mess.message,rebuilt); 
		strcpy(mess.recver,g_OnLineRoles[choice].uName); 
 
		SCommand scom; 
		scom.CommandID=CMD_SPEAK; 
		scom.DataSize=sizeof(mess); 
		int nRet=send(sock,(char*)&scom,sizeof(scom),0); 
		if(nRet==SOCKET_ERROR) 
		{ 
			cout<<"发送说话数据出错,请检查网络!"<=0) 
		{ 
			g_player.pos[1]-=1; 
		} 
		else bGone=false; 
		break; 
	case NORTH: 
		if(g_player.pos[0]-1>=0) 
		{ 
			g_player.pos[0]-=1; 
		} 
		else bGone=false; 
		break; 
	} 
	return bGone; 
} 
 
 
 
//根据mapx,mapy值显示地图信息 
void ShowMapInfo(int mapx,int mapy) 
{ 
	TiXmlDocument doc(g_szfile); 
	if(!doc.LoadFile()) 
	{ 
		cout<<"导入地图数据时,出现错误!请核实你的客户端资源!"<FirstChild()->FirstChild(); 
	for(;node;node=node->NextSibling()) 
	{ 
		if(node->FirstChild()->Type()==TiXmlNode::ELEMENT) 
		{ 
			if(strcmp(node->FirstChild()->ToElement()->GetText(),curMapName)==0) 
			{ 
				ColorTextOut("[系统]",false); 
				cout<FirstChild()->NextSibling()->ToElement()->GetText()<::iterator iter=g_OnLineRoles.begin();iter!=g_OnLineRoles.end();iter++) 
	{ 
		cout<<"["<nName<<"    "; 
		if(i%4==0) 
			cout<>in; 
		if(in>'9'||in<'0') 
		{ 
			break; 
		} 
	 
		choice=in-'0';//还原成数字 
 
		 
		if(g_player.ownObject[choice].ownObjectName=="null") 
		{ 
			cout<<"改格子没有存放任何物品!"<hpTop)//大于hp上限 
						g_player.hp=hpTop; 
					effupdata.num=g_player.hp; 
					strcpy(effupdata.op,"hp"); 
					strcpy(effupdata.item,"null"); 
					effupdata.opType=DBOP_TYPE_NUM; 
 
					break; 
				case OT_MP: 
 
					g_player.ownObject[choice].num-=1; 
 
					//当某物品用完了 
					if(g_player.ownObject[choice].num==0) 
					{ 
						//使用数据 
						strcpy(useupdata.item,"null"); 
						useupdata.opType=DBOP_TYPE_ALL; 
						useupdata.num=0; 
						sprintf(useupdata.op,"objectname%d,objcetnum%d",choice+1,choice+1); 
 
						//更新本地状态 
						g_player.ownObject[choice].ownObjectName="null"; 
						g_player.ownObject[choice].num=0; 
				 
					} 
					else//还有某物品剩余 
					{					 
						useupdata.num=g_player.ownObject[choice].num; 
						sprintf(useupdata.op,"objectnum%d",choice+1); 
						strcpy(useupdata.item,"null"); 
						useupdata.opType=DBOP_TYPE_NUM; 
					} 
 
					//效果数据,公共部分 
					g_player.mp+=mobj.value; 
					if(g_player.hp>mpTop)//大于hp上限 
						g_player.mp=mpTop; 
					effupdata.num=g_player.mp; 
					strcpy(effupdata.op,"mp"); 
					strcpy(effupdata.item,"null"); 
					effupdata.opType=DBOP_TYPE_NUM; 
 
 
					break; 
 
 
				//装备的更新 
				//从背包里减去该装备,在装备栏增加该装备,原已有装备,交换之。当换上的装备有多余时,需一格空间存储换下来的装备,如无,则换装失败 
				// 
				//装备类物品使用 
				 
				case OT_ARMOUR: 
					if(g_player.ownEquip[0]=="null")//原来装备为空 
					{ 
						if(g_player.ownObject[choice].num>1)//背包里有多件本装备 
						{ 
							//本地数据修改 
							g_player.ownObject[choice].num-=1; 
 
							//数据报封装 
							useupdata.num=g_player.ownObject[choice].num; 
							sprintf(useupdata.op,"objectnum%d",choice+1); 
							strcpy(useupdata.item,"null"); 
							useupdata.opType=DBOP_TYPE_NUM; 
 
							//身上装备数据修改 
							g_player.ownEquip[0]=g_player.ownObject[choice].ownObjectName; 
 
							//身上装备数据包封装 
							sprintf(effupdata.op,"equipname%d",1); 
							strcpy(effupdata.item,g_player.ownEquip[0].c_str()); 
							effupdata.opType=DBOP_TYPE_STRING; 
							effupdata.num=0; 
 
						} 
						else//仅此一件 
						{ 
 
							//身上装备数据修改 
							g_player.ownEquip[0]=g_player.ownObject[choice].ownObjectName; 
 
							//身上装备数据包封装 
							sprintf(effupdata.op,"equipname%d",1); 
							strcpy(effupdata.item,g_player.ownEquip[0].c_str()); 
							effupdata.opType=DBOP_TYPE_STRING; 
							effupdata.num=0; 
 
 
							//换下装备数据修改 
							g_player.ownObject[choice].ownObjectName="null"; 
							g_player.ownObject[choice].num-=1; 
 
							//数据包封装 
							useupdata.num=g_player.ownObject[choice].num; 
							strcpy(useupdata.item,g_player.ownObject[choice].ownObjectName.c_str()); 
							sprintf(useupdata.op,"objectname%d objectnum&d",choice+1,choice+1); 
							useupdata.opType=DBOP_TYPE_ALL; 
 
							 
 
						} 
						 
					} 
					else//原来已有装备,换装 
					{ 
						//转换中间量 
						string temp; 
						temp=g_player.ownEquip[0]; 
						bool bGeted=false;//找到标识 
						bool bInsert=false; 
						 
						if(g_player.ownObject[choice].num>1)//背包里有多于1件的该装备 
						{ 
							for(int i=0;i1)//背包里有多件本装备 
						{ 
							//换上装备数据修改 
							g_player.ownObject[choice].num-=1; 
 
							//换上装备数据报封装 
							useupdata.num=g_player.ownObject[choice].num; 
							sprintf(useupdata.op,"objectnum%d",choice+1); 
							strcpy(useupdata.item,"null"); 
							useupdata.opType=DBOP_TYPE_NUM; 
 
 
							//身上装备数据修改 
							g_player.ownEquip[1]=g_player.ownObject[choice].ownObjectName; 
 
							//身上装备数据修改 
							sprintf(effupdata.op,"equipname%d",2); 
							strcpy(effupdata.item,g_player.ownEquip[1].c_str()); 
							effupdata.opType=DBOP_TYPE_STRING; 
							effupdata.num=0; 
 
 
 
						} 
						else//仅此一件 
						{ 
							//身上装备数据修改 
							g_player.ownEquip[1]=g_player.ownObject[choice].ownObjectName; 
 
							//身上装备数据修改 
							sprintf(effupdata.op,"equipname%d",2); 
							strcpy(effupdata.item,g_player.ownEquip[1].c_str()); 
							effupdata.opType=DBOP_TYPE_STRING; 
							effupdata.num=0; 
 
 
 
							//换上装备数据修改 
							g_player.ownObject[choice].ownObjectName="null"; 
							g_player.ownObject[choice].num-=1; 
 
							//换上装备数据包封装 
							useupdata.num=g_player.ownObject[choice].num; 
							strcpy(useupdata.item,g_player.ownObject[choice].ownObjectName.c_str()); 
							sprintf(useupdata.op,"objectname%d objectnum&d",choice+1,choice+1); 
							useupdata.opType=DBOP_TYPE_ALL; 
 
 
							 
 
						} 
						 
					} 
					else//原来已有装备,换装 
					{ 
						//转换中间量 
						string temp; 
						temp=g_player.ownEquip[1]; 
						bool bGeted=false;//找到标识 
						bool bInsert=false; 
						 
						if(g_player.ownObject[choice].num>1)//背包里有多于1件的该装备 
						{ 
							for(int i=0;i1)//背包里有多件本装备 
						{ 
							//本地数据修改 
							g_player.ownObject[choice].num-=1; 
 
							//数据报封装 
							useupdata.num=g_player.ownObject[choice].num; 
							sprintf(useupdata.op,"objectnum%d",choice+1); 
							strcpy(useupdata.item,"null"); 
							useupdata.opType=DBOP_TYPE_NUM; 
 
							//身上装备数据修改 
							g_player.ownEquip[2]=g_player.ownObject[choice].ownObjectName; 
 
							//身上装备数据包封装 
							sprintf(effupdata.op,"equipname%d",3); 
							strcpy(effupdata.item,g_player.ownEquip[2].c_str()); 
							effupdata.opType=DBOP_TYPE_STRING; 
							effupdata.num=0; 
 
						} 
						else//仅此一件 
						{ 
							//身上装备数据修改 
							g_player.ownEquip[2]=g_player.ownObject[choice].ownObjectName; 
 
							//身上装备数据包封装 
							sprintf(effupdata.op,"equipname%d",3); 
							strcpy(effupdata.item,g_player.ownEquip[2].c_str()); 
							effupdata.opType=DBOP_TYPE_STRING; 
							effupdata.num=0; 
 
 
							//换下装备数据修改 
							g_player.ownObject[choice].ownObjectName="null"; 
							g_player.ownObject[choice].num-=1; 
 
							//数据包封装 
							useupdata.num=g_player.ownObject[choice].num; 
							strcpy(useupdata.item,g_player.ownObject[choice].ownObjectName.c_str()); 
							sprintf(useupdata.op,"objectname%d objectnum%d",choice+1,choice+1); 
							useupdata.opType=DBOP_TYPE_ALL; 
 
						} 
						 
					} 
					else//原来已有装备,换装 
					{ 
						//转换中间量 
						string temp; 
						temp=g_player.ownEquip[2]; 
						bool bGeted=false;//找到标识 
						bool bInsert=false; 
						 
						if(g_player.ownObject[choice].num>1)//背包里有多于1件的该装备 
						{ 
							for(int i=0;i