#include "stdafx.h" #include "IOCPServer.h" #include "ServerSocketItem.h" #include "WebServerDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #endif #define PACKET_SIZE 4096 #define BUFFER_OVERFLOW 8192 #define REQUEST_METHOD_POST 0 #define REQUEST_METHOD_GET 1 CServerSocketItem::CServerSocketItem(WORD id, WORD socket, DWORD dwClientAddr, CIOCPServer* pIOCPServer, IClientSocket* pClientSocket) : CTCPSocket(id, socket, dwClientAddr, pIOCPServer) { m_pClientSocket = pClientSocket; } CServerSocketItem::~CServerSocketItem() { } bool CServerSocketItem::Close() { m_pIOCPServer->Disconnect(getID()); return true; } bool CServerSocketItem::processRecvData(void* data, DWORD len) { switch (len) { case 0: SendResult(_T("{\"result\":%d}"), 1); break; case SOCKET_ERROR: if (GetLastError() != WSAEWOULDBLOCK) { TCHAR szError[256]; _tprintf_s(szError, sizeof(szError), _T("ERROR in OnReceive(): %d"), GetLastError()); SaveLog(_T("%s"), szError, TraceLevel_Exception); } break; default: if (len != SOCKET_ERROR && len != 0) { try { if ( false==m_ParseData.ParseRequests((LPBYTE)data, len) ) { SendResult(_T("{\"result\":%d}"), 1); break; } m_ParseData.ProcessRequests(); CString strUrl; m_ParseData.GetServerVariable(_T("script_name"), strUrl); if ( strUrl.Compare(_T("/active.do"))==0 ) { bool bRet = ExecuteRequest(); if ( bRet ) break; } else { SendResult(_T("{\"result\":%d}"), 1); if ( strUrl == _T("/favicon.ico") ) break; } CTraceService::TraceString(_T("请求地址错误: ") + strUrl, TraceLevel_Exception); } catch(...) { SendResult(_T("{\"result\":%d}"), 1); throw ; } } break; } return true; } bool CServerSocketItem::ExecuteRequest() { int nRequestMethod = m_ParseData.GetRequestMethod(); if (REQUEST_METHOD_POST == nRequestMethod) { m_ParseData.ParseQueryString(m_ParseData.m_FormVars); SaveLog(_T("%s"), m_ParseData.m_FormVars); } else { m_ParseData.ParseQueryString(m_ParseData.m_QueryParams); SaveLog(_T("%s"), m_ParseData.m_QueryParams); } CString strWay; m_ParseData.GetQueryString(_T("way"), strWay); int nWay = _ttoi(strWay.GetBuffer()); switch(nWay) { case eWebNull: case eWebCardLib: { WebSetCardLibRequest(); break; } case eWebCheatUser: { WebSetCheatUserRequest(); break; } case eWebCardLibGlobalCfg: { WebCardLibGlobalCfgRequest(); break; } default: { return false; } } return true; } //设置牌库 bool CServerSocketItem::WebSetCardLibRequest() { CString strLibID, strSet, strLibKindID, strLibCustomID, strLibCardData, strSign; m_ParseData.GetQueryString(_T("id"), strLibID); m_ParseData.GetQueryString(_T("set"), strSet); m_ParseData.GetQueryString(_T("kid"), strLibKindID); m_ParseData.GetQueryString(_T("cid"), strLibCustomID); m_ParseData.GetQueryString(_T("data"), strLibCardData); m_ParseData.GetQueryString(_T("sign"), strSign); CString strData; strData.Format(_T("way=%d&id=%s&set=%s&kid=%s&cid=%s&data=%s&%s"), eWebCardLib, strLibID, strSet, strLibKindID, strLibCustomID, strLibCardData, CWebServerDlg::g_strVerifyKey); TCHAR szMD5Result[33]; CWHEncrypt::MD5Encrypt(strData, szMD5Result); if (strSign.CompareNoCase(szMD5Result) == 0) { CMD_CS_SetCardLib mCardLib; ZeroMemory(&mCardLib, sizeof(CMD_CS_SetCardLib)); mCardLib.dwID = atoi(strLibID.GetBuffer()); mCardLib.dwCustomID = atoi(strLibCustomID.GetBuffer()); mCardLib.cbFlag = atoi(strSet.GetBuffer()); mCardLib.wKindID = atoi(strLibKindID.GetBuffer()); CString strSub; int nCount = 0; while (AfxExtractSubString(strSub, strLibCardData, nCount, ',')) { ASSERT(nCount <= LEN_CARD_LIB); if (nCount > LEN_CARD_LIB) { break; } TCHAR* lpStrEnd = NULL; mCardLib.cbData[nCount] = (BYTE)_tcstol(strSub.GetBuffer(), &lpStrEnd, 16); nCount++; mCardLib.cbCount++; } m_pClientSocket->SendData(MDM_CS_WEB_SERVICE, SUB_CS_C_SET_CARD_LIB, &mCardLib, sizeof(CMD_CS_SetCardLib)); SendResult(_T("{\"result\":%d}"), OPER_SUCCESSED); } else { SendResult(_T("{\"result\":%d}"), OPER_VERIFY_ERROR); SaveLog(_T("%s"), "请求验证错误!"); } return true; } //设置作弊玩家 bool CServerSocketItem::WebSetCheatUserRequest() { CString strUserID, strSet, strLibIndex, strLibStartTime, strLibStopTime, strSign; m_ParseData.GetQueryString(_T("uid"), strUserID); m_ParseData.GetQueryString(_T("set"), strSet); m_ParseData.GetQueryString(_T("sign"), strSign); m_ParseData.GetQueryString(_T("index"), strLibIndex); m_ParseData.GetQueryString(_T("stime"), strLibStartTime); m_ParseData.GetQueryString(_T("etime"), strLibStopTime); CString strData; strData.Format(_T("way=%d&uid=%s&set=%s&index=%s&stime=%s&etime=%s&%s"), eWebCheatUser, strUserID, strSet, strLibIndex, strLibStartTime, strLibStopTime, CWebServerDlg::g_strVerifyKey); TCHAR szMD5Result[33]; CWHEncrypt::MD5Encrypt(strData, szMD5Result); if ( strSign.CompareNoCase(szMD5Result) == 0 ) { CMD_CS_SetCheatUser mCheatUser; ZeroMemory(&mCheatUser, sizeof(CMD_CS_SetCheatUser)); mCheatUser.dwUserID = atoi(strUserID.GetBuffer()); mCheatUser.cbFlag = atoi(strSet.GetBuffer()); if (strLibStartTime.GetLength()>0 && strLibStopTime.GetLength()>0) { try { CTime cTime = CTime::GetCurrentTime(); CString strDateTime; strDateTime.Format(_T("%s %s"), cTime.Format("%Y-%m-%d"), strLibStartTime); mCheatUser.dwStartLibTime = CWHService::ConvertDateTimeToDWORD(strDateTime); strDateTime.Format(_T("%s %s"), cTime.Format("%Y-%m-%d"), strLibStopTime); mCheatUser.dwStopLibTime = CWHService::ConvertDateTimeToDWORD(strDateTime); } catch (...) { mCheatUser.dwStartLibTime = 0; mCheatUser.dwStopLibTime = 0; mCheatUser.cbFlag = 0; } } else { mCheatUser.cbFlag = 0; } m_pClientSocket->SendData(MDM_CS_WEB_SERVICE, SUB_CS_C_SET_CHEAT_USER, &mCheatUser, sizeof(CMD_CS_SetCheatUser)); SendResult(_T("{\"result\":%d}"), OPER_SUCCESSED); } else { SendResult(_T("{\"result\":%d}"), OPER_VERIFY_ERROR); SaveLog(_T("%s"), "请求验证错误!"); } return true; } //牌库全局配置; bool CServerSocketItem::WebCardLibGlobalCfgRequest() { CString strSet, strLibKindID, strCardLibCount, strLibStartTime, strLibStopTime, strSign; m_ParseData.GetQueryString(_T("set"), strSet); m_ParseData.GetQueryString(_T("kid"), strLibKindID); m_ParseData.GetQueryString(_T("libcount"), strCardLibCount); m_ParseData.GetQueryString(_T("stime"), strLibStartTime); m_ParseData.GetQueryString(_T("etime"), strLibStopTime); m_ParseData.GetQueryString(_T("sign"), strSign); CString strData; strData.Format(_T("way=%d&set=%s&kid=%s&libcount=%s&stime=%s&etime=%s&%s"), eWebCardLibGlobalCfg, strSet, strLibKindID, strCardLibCount, strLibStartTime, strLibStopTime, CWebServerDlg::g_strVerifyKey); TCHAR szMD5Result[33]; CWHEncrypt::MD5Encrypt(strData, szMD5Result); if (strSign.CompareNoCase(szMD5Result) == 0) { CMD_CS_CardLibGlobalCfg mGlobalCfg; ZeroMemory(&mGlobalCfg, sizeof(CMD_CS_CardLibGlobalCfg)); mGlobalCfg.cbFlag = atoi(strSet.GetBuffer()); mGlobalCfg.wKindID = atoi(strLibKindID.GetBuffer()); mGlobalCfg.dwLibCount = atoi(strCardLibCount.GetBuffer()); if (strLibStartTime.GetLength() > 0 && strLibStopTime.GetLength() > 0) { try { mGlobalCfg.dwStartLibTime = CWHService::ConvertDateTimeToDWORD(strLibStartTime); mGlobalCfg.dwStopLibTime = CWHService::ConvertDateTimeToDWORD(strLibStopTime); } catch (...) { mGlobalCfg.dwStartLibTime = 0; mGlobalCfg.dwStopLibTime = 0; mGlobalCfg.cbFlag = 0; } } else { mGlobalCfg.cbFlag = 0; } m_pClientSocket->SendData(MDM_CS_WEB_SERVICE, SUB_CS_C_CARD_LIB_GLOBAL_CFG, &mGlobalCfg, sizeof(CMD_CS_CardLibGlobalCfg)); SendResult(_T("{\"result\":%d}"), OPER_SUCCESSED); } else { SendResult(_T("{\"result\":%d}"), OPER_VERIFY_ERROR); SaveLog(_T("%s"), "请求验证错误!"); } return true; } bool CServerSocketItem::HttpResponse(LPCTSTR lpszMessage) { CString strHeader; CString strResult = lpszMessage; // HTTP version strHeader = _T("HTTP/1.0 "); // status strHeader += _T("200 OK\r\n"); // servername strHeader += _T("Server: Web Server\r\n"); // content type strHeader += _T("Content-Type: text/html\r\n"); // file length CString strLength; strLength.Format(_T("Content-Length: %d\r\n"), strResult.GetLength()); strHeader += strLength; SYSTEMTIME systemTime; GetSystemTime(&systemTime); // get internet time TCHAR buff[INTERNET_RFC1123_BUFSIZE] = {0}; InternetTimeFromSystemTime(&systemTime, INTERNET_RFC1123_FORMAT, buff, INTERNET_RFC1123_BUFSIZE); // modified strHeader += _T("Last-Modified: "); strHeader += CString(buff); //在http1.1中,client和server都是默认对方支持长链接的, //如果client使用http1.1协议,但又不希望使用长链接,则需要在header中指明connection的值为close; //如果server方也不想支持长链接,则在response中也需要明确说明connection的值为close. // connection strHeader += _T("Connection: close"); strHeader += _T("\r\n\r\n"); strHeader += lpszMessage; m_pIOCPServer->SendData(getID(), strHeader.GetBuffer(), strHeader.GetLength()); //Close(); return true; } //发送结果 bool CServerSocketItem::SendResult(LPCTSTR pstrFormat, ...) { try { CString strResult; // format and write the data we were given va_list args; va_start(args, pstrFormat); strResult.FormatV(pstrFormat, args); va_end(args); HttpResponse(strResult); } catch(CMemoryException *e) { e->Delete(); return false; } catch(...) { return false; } return true; }