📄 loginregdeal.cpp
字号:
// LoginRegDeal.cpp: implementation of the LoginRegDeal class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "LoginReg.h"
#include "LoginRegDeal.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
extern CShareMemory<NODE_STRUCT> *svr_recv_queue; //接收队列
extern CShareMemory<NODE_STRUCT> *svr_send_queue; //发送队列
char* split(char* &text,const char *seps);
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
LoginRegDeal::LoginRegDeal(CListBoxExt *pListBox,CString configfile)
{
this->configfile = configfile;
m_pMsgList = pListBox;
ReadFromConfig();
}
LoginRegDeal::~LoginRegDeal()
{
//终止线程
for(int i = 0; i < threadnum; i++)
{
if(pRecvThread[i] != NULL){
pRecvThread[i]->SuspendThread();
TerminateThread(pRecvThread[i]->m_hThread,0);
delete pRecvThread[i];
}
}
delete(svr_recv_queue);
delete(svr_send_queue);
}
void LoginRegDeal::SetThreadNo(int no)
{
threadno = no;
}
int LoginRegDeal::GetThreadNo()
{
return threadno;
}
void LoginRegDeal::GetDataBasepara(CString &sdatabase,CString &sdbusername,CString &sdbpassword,CString &slogdir)
{
sdatabase = this->database;
sdbpassword = this->dbpassword;
sdbusername = this->dbusername;
slogdir = this->logdir;
}
//读配置文件
void LoginRegDeal::ReadFromConfig()
{
char buf[1024];
threadnum = ::GetPrivateProfileInt("THREAD","threadnum",10,configfile);
::GetPrivateProfileString("DB","database","",buf,sizeof(buf),configfile);
database =buf;
::GetPrivateProfileString("DB","username","",buf,sizeof(buf),configfile);
dbusername = buf;
::GetPrivateProfileString("DB","password","",buf,sizeof(buf),configfile);
dbpassword = buf;
::GetPrivateProfileString("LOG","loginlogdir","",buf,sizeof(buf),configfile);
logdir = buf;
logfile = logdir + "LoginReg.log";
}
BOOL LoginRegDeal::Init()
{
// DbpInit();
//实例化一个共享内存对象
svr_recv_queue = new CShareMemory<NODE_STRUCT> (LOGIN_RECV_KEY);
if(!svr_recv_queue->Init(QUEUE_LENGTH)){
AddMsg("初始化接收共享内存时产生错误!","系统错误",MB_OK|MB_ICONSTOP);
exit(-1);
}
else{
AddMsg("初始化接收共享内存成功");
}
svr_send_queue = new CShareMemory<NODE_STRUCT> (LOGIN_SEND_KEY);
if(!svr_send_queue->Init(QUEUE_LENGTH)){
AddMsg("初始化发送共享内存时产生错误!","系统错误",MB_OK|MB_ICONSTOP);
exit(-1);
}
else{
AddMsg("初始化发送共享内存成功");
}
return true;
}
UINT LoginRegDeal::Run()
{
Init();
for(int i = 0; i < threadnum; i++)
{
SetThreadNo(i+1);
pRecvThread[i] = AfxBeginThread(RecvThreadFunc,this,THREAD_PRIORITY_NORMAL);
Sleep(100);
}
AddMsg("五子棋服务程序初始化完成!");
return PBL_Error_OK;
}
//功能:写LOG
//参数:sLogFile为Log文件名,sFileName指名哪个文件写LOG
//参数:nLine表明在第X行写LOG,fmt见printf...
BOOL LoginRegDeal::WriteLog(const char *fmt,...)
{
va_list args;
FILE *fp;
time_t t;
struct tm *ptm;
time(&t);
ptm = localtime(&t);
if((fp = fopen(logfile, "a+t")) == NULL)
return FALSE;
fprintf(fp,"[%04d%02d%02d %02d:%02d:%02d] ",
ptm->tm_year + 1900,
ptm->tm_mon +1,
ptm->tm_mday,
ptm->tm_hour,
ptm->tm_min,
ptm->tm_sec);
va_start(args, fmt);
vfprintf(fp,fmt,args);
fprintf(fp,"\n");
va_end(args);
fclose(fp);
return TRUE;
}
//功能:向监视窗口添加一条信息
//参数:csMsg是要显示的信息
void LoginRegDeal::AddMsg(LPCTSTR fmt , ...)
{
va_list args;
CTime ctTime = CTime::GetCurrentTime();
CString csTime = ctTime.Format("[%Y-%m-%d %H:%M:%S]");
char szBuf[1024];
va_start(args, fmt);
vsprintf(szBuf,fmt,args);
va_end(args);
csTime = csTime + " " + szBuf;
if(m_pMsgList->GetCount() > MAXSHOWLINES-1){
m_pMsgList->DeleteMessage(0);
}
m_pMsgList->AddMessage(csTime);
WriteLog(csTime);
}
/************************************************************************
函数功能:用户注册处理
************************************************************************/
void LoginRegDeal::UserReg(TDBPEx *dbp,NODE_STRUCT recvnode){
char sqlbuf[1024]={0};
char *tempstr;
char *body;
CString nickname,phonenum,password,picture,sex,age,usertype;
CString userid;
body = recvnode.body;
while(true){
sprintf(sqlbuf,"select useridseq.nextval from dual");
dbp->SQLExecDirect(sqlbuf,FALSE);
if(dbp->SQLFetch() == PBL_Error_OK)
{
dbp->SQLGetDataStr(1,userid);
}
dbp->SQLFreeStmt();
sprintf(sqlbuf,"select specialid from UserSpecialId where specialid = '%s'",userid);
dbp->SQLExecDirect(sqlbuf,FALSE);
if(dbp->SQLFetch() == PBL_Error_OK)
{
dbp->SQLFreeStmt();
continue;
}
else{
break;
}
}
tempstr=split(body,SUBDIVISION);
nickname = tempstr;
tempstr=split(body,SUBDIVISION);
phonenum = tempstr;
tempstr=split(body,SUBDIVISION);
password = tempstr;
tempstr=split(body,SUBDIVISION);
picture = tempstr;
tempstr=split(body,SUBDIVISION);
sex = tempstr;
tempstr=split(body,SUBDIVISION);
age = tempstr;
tempstr=split(body,SUBDIVISION);
usertype = tempstr;
//如果是usertype为1,则判断手机号码(需补充)
//用户信息插入
sprintf
(
sqlbuf,
"insert into User_info(userid,nickname,password,phonenum,picture,sex,age,usertype) values('%s','%s','%s','%s','%s','%s',%d,'%s')",
userid,nickname,password,phonenum,picture,sex,atoi(age),usertype
);
if( dbp->SQLExecDirect(sqlbuf,TRUE,TRUE) == PBL_Error_FAIL )
{
WriteLog(logfile,"UserReg: DB INSERT ERROR!");
strcpy( recvnode.err_code, LOGIN_ERR );
}
else
{
//用户状态表插入
sprintf( sqlbuf,
"insert into User_status(userid,status,phonenum,queuenum,ipaddress,\
connectport) values('%s','%s','%s',%d,'%u')",
userid, "00", phonenum, recvnode.queuenum,recvnode.clientip,recvnode.clientport);
if( dbp->SQLExecDirect(sqlbuf,TRUE,TRUE) == PBL_Error_FAIL )
{
//用户注册表删除
WriteLog(logfile,"UserReg: DB INSERT ERROR!");
sprintf( sqlbuf, "delete User_info where userid='%s'", userid );
if( dbp->SQLExecDirect(sqlbuf,TRUE,TRUE) == PBL_Error_FAIL )
{
WriteLog(logfile,"UserReg: DB Delete ERROR!");
strcpy( recvnode.err_code, LOGIN_ERR );
}
strcpy( recvnode.err_code, LOGIN_ERR );
}
else
{
//响应信息:是否注册成功(0:成功 1:失败)
sprintf( recvnode.body, "%s;%s", "0", userid );
}
}
svr_send_queue->Insert(&recvnode);
}
/************************************************************************
函数功能:用户登陆处理程序
************************************************************************/
void LoginRegDeal::UserLoad(TDBPEx *dbp,NODE_STRUCT recvnode)
{
char sqlbuf[1024];
int update_version = 0;
char *tempstr;
char *body;
CString userid,password,version,nickname,picture,sex,usertype,age,gamemoney;
CString status="01",ipaddress;
short queuenum,connectport;
/* 解析包体内容 */
body = recvnode.body;
tempstr=split(body,SUBDIVISION);
userid = tempstr;
tempstr=split(body,SUBDIVISION);
password = tempstr;
tempstr=split(body,SUBDIVISION);
version = tempstr;
//查询是否重复登陆
/* 数据库查询用户ID、密码 */
sprintf( sqlbuf, "select nickname,picture,sex,usertype,age,gamemoney from User_info where userid='%s' and password='%s'", userid, password );
dbp->SQLExecDirect(sqlbuf,FALSE);
if(dbp->SQLFetch() == PBL_Error_OK)
{
dbp->SQLGetDataStr(1,nickname);
dbp->SQLGetDataStr(2,picture);
dbp->SQLGetDataStr(3,sex);
dbp->SQLGetDataStr(4,usertype);
dbp->SQLGetDataStr(5,age);
dbp->SQLGetDataStr(6,gamemoney);
dbp->SQLFreeStmt();
sprintf(sqlbuf,"select status,queuenum,ipaddress,connectport from user_status where userid = '%s'",userid);
dbp->SQLExecDirect(sqlbuf,FALSE);
if(dbp->SQLFetch() == PBL_Error_OK)
{
dbp->SQLGetDataStr(1,status);
dbp->SQLGetDataSInt(2,queuenum);
dbp->SQLGetDataStr(3,ipaddress);
dbp->SQLGetDataSInt(4,connectport);
}
dbp->SQLFreeStmt();
//用户状态表更新
sprintf( sqlbuf, "update User_status set status='01',ipaddress='%s',connectport=%d,queuenum=%d,\
logindate=SYSDATE where userid='%s'",recvnode.clientip,recvnode.clientport,recvnode.queuenum,userid);
dbp->SQLExecDirect(sqlbuf,TRUE,TRUE);
//响应信息
sprintf( recvnode.body,
"%s;%d;%s;%s;%s;%s;%s;%s",
"0", update_version, nickname, picture, sex, usertype, age, gamemoney );
svr_send_queue->Insert(&recvnode);
if(strcmp(status,"00")!=0){ //帐号正在使用,强迫注销
strcpy(recvnode.operate_id,"004");
strcpy(recvnode.clientip,ipaddress);
recvnode.clientport = connectport;
recvnode.queuenum = queuenum;
strcpy(recvnode.body,"");
svr_send_queue->Insert(&recvnode);
}
}
else
{
dbp->SQLFreeStmt();
//响应信息
sprintf( recvnode.body, "%s;%d;%s;%s;%s;%s;%s;%s", "1", update_version, "", "", "", "", "", "" );
svr_send_queue->Insert(&recvnode);
}
}
/************************************************************************
函数功能:用户资料修改
************************************************************************/
void LoginRegDeal::UserInfoModify(TDBPEx *dbp,NODE_STRUCT recvnode){
char sqlbuf[1024]={0};
char *tempstr;
char *body;
CString nickname,phonenum,password,picture,sex,age,usertype;
CString userid;
body = recvnode.body;
tempstr=split(body,SUBDIVISION);
userid = tempstr;
tempstr=split(body,SUBDIVISION);
nickname = tempstr;
tempstr=split(body,SUBDIVISION);
phonenum = tempstr;
tempstr=split(body,SUBDIVISION);
password = tempstr;
tempstr=split(body,SUBDIVISION);
picture = tempstr;
tempstr=split(body,SUBDIVISION);
sex = tempstr;
tempstr=split(body,SUBDIVISION);
age = tempstr;
tempstr=split(body,SUBDIVISION);
usertype = tempstr;
//如果是usertype为1,则判断手机号码(需补充)
//更新用户状态
sprintf( sqlbuf, "update User_status set ipaddress='%s',connectport=%d,queuenum=%d,\
where userid='%s'",recvnode.clientip,recvnode.clientport,recvnode.queuenum,userid);
dbp->SQLExecDirect(sqlbuf,TRUE,TRUE);
//用户信息插入
sprintf
(
sqlbuf,
"update User_info set nickname='%s',password='%s',phonenum='%s',picture='%s',sex='%s',\
age=%d ,usertype='%s' where userid = '%s'",nickname,password,phonenum,picture,sex,\
atoi(age),usertype,userid
);
if( dbp->SQLExecDirect(sqlbuf,TRUE,TRUE) == PBL_Error_FAIL )
{
WriteLog(logfile,"UserInfoModify: DB INSERT ERROR!");
strcpy( recvnode.err_code, LOGIN_ERR );
}
sprintf(recvnode.body,"0;%s",userid);
svr_send_queue->Insert(&recvnode);
}
/*****************************************************
函数名: split
输入参数: char* &text,const char *seps
返回值: 每次分割得到的字符串
功能描述: 将字符串text使用seps进行分割
例如: text = "123;456;;789"
seps = ";"
结果: 123
456
789
使用方法:
char* input = text;
char* output = NULL;
while( input != NULL )
{
output = split( input, seps );
printf( " %s\n", output );
}
注意: 输入参数text将被改变
*****************************************************/
char* split(char* &text,const char *seps)
{
if(text == NULL){
return NULL;
}
char* ret = text;
char* tmp = strstr(text,seps);
if (tmp != NULL)
{
text = tmp + strlen(seps);
*tmp = '\0';
}
else
text = NULL;
return ret;
}
//登录服务程序处理线程
UINT RecvThreadFunc(LPVOID pParam)
{
// CWnd *thisdlg;
// HWND thiswnd;
HANDLE cvscThread = NULL;
int threadno; //表示当前线程编号
CString database,dbusername,dbpassword,logdir;
int nNodeLength; //判断存在共享内存的节点数
// char chesscontent[227] = {0};
CString chesstemp;
char service_id[NODE_SERVICEID_LENGTH]; //业务代码
char operate_id[NODE_OPERATEID_LENGTH]; //各业务操作码(00:表示进入房间,01:表示用户离开房间 02:表示开始游戏 03:表示游戏操作
// char room_id[NODE_ROOM_LENGTH]; //房间号,同一个游戏唯一
// char table_id[NODE_TABLE_LENGTH]; //游戏的桌号,同房间里唯一
//char firuserid[NODE_USERID_LENGTH]; //第一个用户id,也作为第一个用户的网络id
// char err_code[ERR_CODE_LENGTH]; //错误码
// char gameing_table_id[NODE_ROOM_LENGTH + NODE_TABLE_LENGTH]; //正在进行游戏的桌号
NODE_STRUCT recvNode;
TDBPEx * dbp;
LoginRegDeal *loginregdeal=(LoginRegDeal *)pParam;
threadno = loginregdeal->GetThreadNo();
loginregdeal->GetDataBasepara(database,dbusername,dbpassword,logdir);
//创建数据库连接对象
dbp = new TDBPEx("LoginRegServer"+threadno,database,dbusername,dbpassword,logdir);
if (dbp && dbp->IsReady())
{
loginregdeal->AddMsg("线程%d 创建dbp对象成功!",threadno);
}
else
{
loginregdeal->AddMsg("线程%d 创建dbp对象失败!",threadno);
}
dbp->Run();
// threadstop = false;
while(true)
{
if (dbp)
{
if (!dbp->IsConnect())
{
if (dbp->Connect() == PBL_Error_FAIL)
{
loginregdeal->AddMsg("[RecvThreadFunc]:线程%d dbp连接数据库失败!",threadno);
Sleep(1000);
continue;
}
else
{
loginregdeal->AddMsg("[RecvThreadFunc]:线程%d dbp连接数据库成功!",threadno);
}
}
}
nNodeLength = svr_recv_queue->GetLength();
if(nNodeLength == 0){
Sleep(100);
continue;
}
nNodeLength = svr_recv_queue->GetNodes(&recvNode,1);
if(nNodeLength != 0)
{
strcpy(service_id, recvNode.service_id);
strcpy(operate_id, recvNode.operate_id);
}
else
{
continue;
}
if(strcmp(operate_id,"000") == 0) //用户注册
{
loginregdeal->UserReg(dbp,recvNode);
}
else if(strcmp(operate_id,"001") == 0) //用户登录
{
loginregdeal->UserLoad(dbp,recvNode);
}
else if(strcmp(operate_id,"002") == 0) //用户资料修改
{
loginregdeal->UserInfoModify(dbp,recvNode);
}
else if(strcmp(operate_id,"003")==0 ) //用户下线请求
{
}
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -