📄 client.cpp
字号:
#include <winsock2.h>
#include <iostream>
#include <windows.h>
#include <vector>
#include <string>
#include <algorithm>
#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<OnLineList> 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"<<endl;
return;
}
SOCKET client;
char szServerIP[30];
cout<<"请输入服务器ip地址:"<<endl;
cin>>szServerIP;
client=ConnectServer(szServerIP,PORT);
if(client==NULL)
{
cout<<"连接服务器失败!"<<endl;
return;
}
cout<<"已连接服务器!"<<endl;
//登陆注册环节
showLoginMenu(client);
//主游戏环节
showMainMenu(client);
}
//连接服务器函数
SOCKET ConnectServer(char* szServerIP,int port)
{
SOCKET sClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
sockaddr_in serverAddr;
serverAddr.sin_family=AF_INET;
serverAddr.sin_port=htons(port);
serverAddr.sin_addr.s_addr=inet_addr(szServerIP);
int nRet=connect(sClient,(sockaddr*)&serverAddr,sizeof(serverAddr));
if(nRet==SOCKET_ERROR)
{
cout<<"connect failed"<<endl;
return NULL;
}
return sClient;
}
//显示游戏主菜单
void showMainMenu(SOCKET sock)
{
if(!reborth)//正常登陆,非死亡过来
initGameCondition(sock);
bool bGameGoing=true;
while(bGameGoing)
{
int choice=-1;
char in='0';
ShowMapInfo(g_player.pos[0],g_player.pos[1]);
cout<<"************************************************************"<<endl;
cout<<"可选择的指令:"<<endl;
cout<<"1>探索地图"<<endl;
cout<<"2>对外发话"<<endl;
cout<<"3>查看状态"<<endl;
cout<<"4>显示地图"<<endl;
cout<<"5>向东行进"<<endl;
cout<<"6>向南行进"<<endl;
cout<<"7>向西行进"<<endl;
cout<<"8>向北行进"<<endl;
cout<<"9>使用物品"<<endl;
cout<<"0>退出游戏"<<endl;
ShowSystemInfo();
while(true)//检测输入
{
cin>>in;
if(in>'9'||in<'0')
{
cout<<"输入非法,请输入0-9"<<endl;
}
else
{
choice=in-'0';
break;
}
}
switch(choice)
{
case 1:
CreateGameEvent(sock);
break;
case 2:
ShowDialogMenu(sock);
break;
case 3:
ShowStatus(sock);
break;
case 4:
ShowMap();
break;
case 5:
if(!NextMapScence(EAST))
cout<<"已经到达地图边界!"<<endl;
break;
case 6:
if(!NextMapScence(SOUTH))
cout<<"已经到达地图边界!"<<endl;
break;
case 7:
if(!NextMapScence(WEST))
cout<<"已经到达地图边界!"<<endl;
break;
case 8:
if(!NextMapScence(NORTH))
cout<<"已经到达地图边界!"<<endl;
break;
case 9:
UseThinginPackage(sock);
break;
case 0:
SaveGameData(sock);
bGameGoing=false;
break;
default:
cout<<"输入非法,你可以输入数字0-9"<<endl;
break;
}
UpdateData(sock);
}
}
//登陆菜单
void showLoginMenu(SOCKET sock)
{
int choice;
char szName[20],szPass[20];
memset(szName,0,20);
memset(szPass,0,20);
bool isgoon=true;
while(isgoon)
{
system("cls");
cout<<"************************************************************"<<endl;
cout<<" 武林群侠传 "<<endl;
cout<<"************************************************************"<<endl;
cout<<"可选择的指令:"<<endl;
cout<<"1>登陆"<<endl;
cout<<"2>注册"<<endl;
cout<<"3>退出"<<endl;
cout<<"************************************************************"<<endl;
cout<<"请选择你的指令:"<<endl;
cin>>choice;
switch(choice)
{
case 1:
cout<<"************************************************************"<<endl;
cout<<"请输入你的用户名:";
cin>>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<<"************************************************************"<<endl;
cout<<"请输入你想注册的用户名:";
cin>>szName;
cout<<"请输入你想注册的密码:";
cin>>szPass;
cout<<"请再次输入你的密码:";
cin>>szrePass;
if(strcmp(szPass,szrePass)==0)
{
if(RegisterUser(sock,szName,szPass))
{
CreateRoleMenu(sock);
//cout<<"请用你注册的帐户登陆吧!"<<endl;
}
}
else
{
cout<<"你输入的两次密码前后不一致!"<<endl;
}
system("pause");
break;
case 3:
cout<<"感谢你的测试!按任意键退出"<<endl;
system("pause");
shutdown(sock,0);
closesocket(sock);
exit(0);
break;
default:
cout<<"输入非法,请选择1-3数字!"<<endl;
break;
}
}
}
//与服务器端验证帐户,
bool Auth(SOCKET sock,char*szName,char*szPass)
{
bool bAuth=false;
char szCmd[50];
memset(szCmd,0,50);
strcpy(szCmd,szName);
strcat(szCmd," ");
strcat(szCmd,szPass);
SCommand scmd;
scmd.CommandID=CMD_AUTHEN;
scmd.DataSize=(int)strlen(szCmd);
int nRet=send(sock,(char*)&scmd,sizeof(scmd),0);
if(nRet==SOCKET_ERROR)
{
cout<<"Auth::send() failed"<<endl;
return false;
}
nRet=send(sock,szCmd,(int)strlen(szCmd),0);
if(nRet==SOCKET_ERROR)
{
cout<<"Auth::send() failed"<<endl;
return false;
}
char szRet[31];
memset(szRet,0,31);
nRet=recv(sock,szRet,30,0);
if(nRet==SOCKET_ERROR)
{
cout<<"Auth::recv() failed"<<endl;
return false;
}
if(strcmp(szRet,"UP OK")==0)
{
cout<<"成功验证,"<<endl;
bAuth=true;
}
if(strcmp(szRet,"U NONE")==0)
{
cout<<"用户名错误!"<<endl;
bAuth=false;
}
if(strcmp(szRet,"P ERR")==0)
{
cout<<"密码错误!"<<endl;
bAuth=false;
}
return bAuth;
}
//注册帐户函数
bool RegisterUser(SOCKET sock,char* szName,char *szPass)
{
bool breg=false;
char szCmd[50];
memset(szCmd,0,50);
strcpy(szCmd,szName);
strcat(szCmd," ");
strcat(szCmd,szPass);
SCommand scmd;
scmd.CommandID=CMD_REGISTER;
scmd.DataSize=(int)strlen(szCmd);
int nRet=send(sock,(char*)&scmd,sizeof(scmd),0);
if(nRet==SOCKET_ERROR)
{
cout<<"Register::send() failed"<<endl;
return false;
}
nRet=send(sock,szCmd,(int)strlen(szCmd),0);
if(nRet==SOCKET_ERROR)
{
cout<<"Register::send() failed"<<endl;
return false;
}
char szRet[31];
memset(szRet,0,31);
nRet=recv(sock,szRet,30,0);
if(nRet==SOCKET_ERROR)
{
cout<<"Auth::recv() failed"<<endl;
return false;
}
if(strcmp(szRet,"REG OK")==0)
{
cout<<"注册成功!"<<endl;
breg=true;
}
if(strcmp(szRet,"REG ERR")==0)
{
cout<<"注册失败!"<<endl;
breg=false;
}
if(strcmp(szRet,"ERR REPEAT")==0)
{
cout<<"你注册的用户名已经注册了!"<<endl;
breg=false;
}
return breg;
}
//创建角色菜单
void CreateRoleMenu(SOCKET sock)
{
bool iswelldone=false;
player tplayer;
memset(&tplayer,0,sizeof(tplayer));
int choice;
char szName[20];
system("cls");
cout<<"************************************************************"<<endl;
cout<<" 创建角色界面 "<<endl;
cout<<"************************************************************"<<endl;
cout<<"请选择你的角色职业:"<<endl;
cout<<"1>战士"<<endl;
cout<<"2>法师"<<endl;
cout<<"3>道士"<<endl;
cout<<"************************************************************"<<endl;
while(!iswelldone)
{
cin>>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数字!"<<endl;
break;
}
}
iswelldone=false;
cout<<"************************************************************"<<endl;
cout<<"请选择你的性别:"<<endl;
cout<<"1>男"<<endl;
cout<<"2>女"<<endl;
cout<<"************************************************************"<<endl;
while(!iswelldone)
{
cin>>choice;
switch(choice)
{
case 1:
tplayer.ownSex=MALE;
iswelldone=true;
break;
case 2:
tplayer.ownSex=FEMALE;
iswelldone=true;
break;
default:
cout<<"输入非法,请输入1-2数字!"<<endl;
break;
}
}
iswelldone=false;
cout<<"************************************************************"<<endl;
cout<<"请选择你的昵称:";
while(!iswelldone)
{
cin>>szName;
if(strlen(szName)>=20)
{
cout<<"你的输入的字符太多!"<<endl;
continue;
}
else
{
strcpy(tplayer.nickName,szName);
iswelldone=true;
}
}
cout<<"************************************************************"<<endl;
cout<<"正在初始化角色属性"<<endl;
cout<<"************************************************************"<<endl;
//角色基本属性
tplayer.hp=100;
tplayer.mp=40;
tplayer.attack=18;
tplayer.defendence=10;
tplayer.celerity=5;
tplayer.exp=0;
//技能
tplayer.ownSkill[0]="飞龙在天";
tplayer.ownSkill[1]="null";
tplayer.ownSkill[2]="null";
tplayer.ownSkill[3]="null";
tplayer.ownSkill[4]="null";
tplayer.ownSkill[5]="null";
tplayer.ownSkill[6]="null";
//装备
tplayer.ownEquip[0]="null";
tplayer.ownEquip[1]="null";
tplayer.ownEquip[2]="null";
//金钱
tplayer.money=10;
//位置
tplayer.pos[0]=0;
tplayer.pos[1]=0;
//等级
tplayer.level=1;
tplayer.ownObject[0].ownObjectName="止血贴";
tplayer.ownObject[0].num=5;
tplayer.ownObject[1].ownObjectName="补气丸";
tplayer.ownObject[1].num=5;
//其余初始化为空
for(int i=2;i<OBJECTNUM;i++)
{
tplayer.ownObject[i].ownObjectName="null";
tplayer.ownObject[i].num=0;
}
SCommand scmd;
scmd.CommandID=CMD_CREATEROLE;
scmd.DataSize=sizeof(tplayer);
int nRet=send(sock,(char*)&scmd,sizeof(scmd),0);
if(nRet==SOCKET_ERROR)
{
cout<<"角色初始化失败,请确信你选择都是正确的!"<<endl;
return;
}
nRet=send(sock,(char*)&tplayer,sizeof(tplayer),0);
if(nRet==SOCKET_ERROR)
{
cout<<"发送初始化数据失败!"<<endl;
return;
}
char szRet[31];
memset(szRet,0,31);
nRet=recv(sock,szRet,sizeof(szRet),0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -