//========================================================================== // 档名 : PhoneMsg.cpp // 功用 : 石器时代[简讯]按钮的功能实作(V3.0后新增的功能) // 撰写人 : 林 昌 磊 (Leiboy) // 初版完成日期 : 2002年01月26日 // 第二版更新日期 : 2002年02月02日==>新增Multithread(函式五) // 第三版更新日期 : 2002年02月20日==>将MFC改写成Winsock方式!(本版为已完成版!) // 第四版完成日期 : 2002年02月26日==>新增DNS(函式七) // 线上正式运作日期 : 2002年03月04日 // 补充说明 : 游戏中成功地传送一通简讯每次将扣WGS点数五点! //========================================================================== //先做版本的控制 #include "../systeminc/version.h" #ifdef __PHONEMESSAGE #include #include "time.h" #include "../systeminc/system.h" #include "../systeminc/loadrealbin.h" #include "../systeminc/anim_tbl.h" #include "../systeminc/login.h" #include "../systeminc/menu.h" #include "../systeminc/map.h" #include "../systeminc/ime_sa.h" #include "../systeminc/t_music.h" #include "../systeminc/field.h" #include "../systeminc/pc.h" #include "../wgs/descrypt.h" #include "../other/caryIme.h" #define MSG_SURE_D 26288 //确定(按下)(黄色的) #define MSG_SURE_U 26289 //确定(弹起)(黄色的) #define MSG_CANCEL_U 26284 //取消(未按下) #define MSG_CANCEL_D 26285 //取消(按下) #define MSG_CLEAR_U 26298 //清除(弹起) #define MSG_CLEAR_D 26299 //清除(按下) //Messsage 的Log 专用区 Begin #ifdef _STONDEBUG_ char logstr[512]; #define logfilename "message.log" #endif //Messsage 的Log 专用区 End BOOL QueryMyIP(char HostName[]); //石器简讯Server IP : 210.64.97.17 char *MsgIP; #define SMSDomainName "sms.hwaei.com.tw" //目前所采用的ASP filename #define ASPname "//sms//stoneage.asp" //2002 Feb. 20后启用! int myvalue; char seqno[14]; //Wayia_seqno //************************************************ //函式一 : 处理主程式与ASP间沟通的专用函式 //回传值 : 0 --- 处理完毕 & 简讯发送成功 // 1 --- 简讯发送失败 // 2 --- 手机号码参数错误 // 3 --- 手机讯息参数错误(过长) // 4 --- 网路端错误 // 5 --- WGS点数(或通数)已不足!!(小于五点) // 6 --- 连线逾时(或DNS失败) // 7 --- ASP回传错误 //************************************************ int SendPhoneMsg(char pid[16], char ppw[16], char pps[], char pms[]) { if(!QueryMyIP(SMSDomainName)) return 6; if((pps[0] =='\0') || (lstrlen(pps) != 10)) return 2; if((pps[0] != '0') || (pps[1] != '9')) return 2; int dv,i=0; do { dv = isdigit(pps[i+2]); i++; }while( dv && (i<8)); if(!dv) return 2; //和Jason讨论后,新订的文字上限为66bytes!! Feb. 5,2002 //保留16bytes给玩家名称用! Feb.22,2002 int x=0,mc=0; do { if(IsDBCSLeadByte(pms[x])) x+=2; else x++; mc++; }while(x < lstrlen(pms)); if((mc<1) || (mc>50)) return 3; char extpms[120]; if(lstrlen(pc.name)>16) return 3; else #ifdef _FIX_URLENCODE // WON ADD 北京修正简讯无法加空格的问题 { char OutTmp[768]; char *pInTmp,*pOutTmp; char Hex[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; // do encoding pInTmp=pms; pOutTmp=OutTmp; // ZeroMemory(OutTmp,sizeof(OutTmp)); while (*pInTmp) { // if(isalnum(*pInTmp)&&(!IsDBCSLeadByte(*pInTmp))) if ( (*pInTmp> '0') && (*pInTmp < '9') || (*pInTmp> 'a') && (*pInTmp < 'z') || (*pInTmp> 'A') && (*pInTmp < 'Z') ) *pOutTmp++ = *pInTmp; else { // if(isspace(*pInTmp)) if(*pInTmp==0x20&&(!IsDBCSLeadByte(*pInTmp))) *pOutTmp++ = '+'; else { *pOutTmp++ = '%'; *pOutTmp++ = Hex[(*pInTmp>>4)&0x0f]; *pOutTmp++ = Hex[(*pInTmp)&0x0f]; } } pInTmp++; } *pOutTmp = '\0'; sprintf_s(extpms,"%s:%s",pc.name,OutTmp); } #else sprintf_s(extpms,"%s:%s",pc.name,pms); #endif SOCKET hSock; SOCKADDR_IN stName; fd_set rfds,wfds; timeval tmTimeOut; DWORD timeout; char *result; int len, cnt, ret; tmTimeOut.tv_usec=0; tmTimeOut.tv_sec=0; if( INVALID_SOCKET != ( hSock = socket( AF_INET, SOCK_STREAM, 0) ) ) { DWORD flg = 1; if( SOCKET_ERROR != ioctlsocket( hSock, FIONBIO, &flg)) { ZeroMemory( &stName, sizeof(struct sockaddr)); stName.sin_addr.s_addr = inet_addr(MsgIP); stName.sin_family = PF_INET; stName.sin_port = htons(80); ret = connect( hSock, (LPSOCKADDR)&stName, sizeof(struct sockaddr) ); if( SOCKET_ERROR != ret || WSAEWOULDBLOCK == WSAGetLastError() ) { timeout = TimeGetTime(); while(1) { FD_ZERO( &wfds); FD_SET( hSock, &wfds); if( select( NULL, (fd_set*)NULL, &wfds, (fd_set*)NULL, &tmTimeOut)>0 && FD_ISSET( hSock, &wfds)) break; DWORD curtime = TimeGetTime(); if( (timeout+5000) < curtime ) { closesocket(hSock); return 6; } Sleep(1); } cnt = 0; char buf[1024]; sprintf_s(buf,"GET //sms//stoneage.asp?ID=%s&PWD=%s&TEL=%s&MSG=%s",pid,ppw,pps,extpms); strcat_s(buf," HTTP/1.1\r\nAccept: text/*\r\nUser-Agent: StoneAge\r\n"); sprintf_s(buf,"%sHost: %s\r\n\r\n",buf,MsgIP); len = lstrlen(buf); timeout = TimeGetTime(); while(len) { DWORD stime = TimeGetTime(); if( (timeout+3000) < stime ) { closesocket(hSock); return 6; } FD_ZERO( &wfds); FD_SET( hSock, &wfds); select( NULL, (fd_set*)NULL, &wfds, (fd_set*)NULL, &tmTimeOut); if( !FD_ISSET( hSock, &wfds) ) { Sleep(1); continue; } ret = send( hSock, &buf[cnt], len, 0); if( SOCKET_ERROR == ret) { closesocket(hSock); return 4; } cnt += ret; len -= ret; if(len<1) break; } Sleep(500); len = 1024; cnt = 0; timeout = TimeGetTime(); while(1) { DWORD rtime = TimeGetTime(); if( (timeout+3000) < rtime ) { closesocket(hSock); return 6; } FD_ZERO( &rfds); FD_SET( hSock, &rfds); select( NULL, &rfds, (fd_set*)NULL, (fd_set*)NULL, &tmTimeOut); if( !FD_ISSET( hSock, &rfds) ) { Sleep(1); continue; } ret = recv( hSock, &buf[cnt], len, 0); if( SOCKET_ERROR == ret) { closesocket(hSock); return 4; } if( 0 == ret) break; buf[cnt+ret] = 0; result = strstr( buf, "\r\n\r\n") + 4; if(result) break; cnt += ret; len -= ret; } } } closesocket(hSock); if(result[0]=='\0') return 4; if(result[0]=='1') { #ifdef _STONDEBUG_ lstrcpy(logstr,"失败 "); lstrcat(logstr,pps); sprintf_s(logstr,"%s %s",logstr,extpms); #endif return 1; } else { result++; if(lstrlen(result) < 14) return 7; int j=0; i=0; do { seqno[i] = result[i]; if(result[i] == '0') j++; i++; }while(i<14); seqno[14] = 0; if(j == 14) return 5; #ifdef _STONDEBUG_ lstrcpy(logstr,"成功-"); lstrcat(logstr,seqno); lstrcat(logstr," "); lstrcat(logstr,pps); sprintf_s(logstr,"%s %s",logstr,extpms); #endif } return 0; } else return 4; } //************************************************ //函式二 : 产生Log档(于Local端目录下)的专用函式 //回传值 : None //附 注 : 只有Debug mode才在硬碟写入log档!! //************************************************ #ifdef _STONDEBUG_ void WriteLog( char cData[], char cFile[]) { char totals[1024]; struct tm nowTime; time_t longTime; time( &longTime ); localtime_s(&nowTime, &longTime ); sprintf_s(totals,"%02d/%02d/%02d %02d:%02d:%02d ",(nowTime.tm_year % 100), nowTime.tm_mon+1, nowTime.tm_mday, nowTime.tm_hour, nowTime.tm_min, nowTime.tm_sec); lstrcat(totals,cData); lstrcat(totals,"\r\n"); FILE *fp; fp = fopen(logfilename, "a" ); if(fp) { fprintf(fp,totals); fclose(fp); } } #endif static int mx = 20, my = 10; STR_BUFFER pno,ptext; static STR_BUFFER *MsgFocus[] ={ &pno, &ptext }; static int MsgFocusSw; //************************************************ //函式三 : 资料输入栏位的初始化函式 //回传值 : None //************************************************ void InitMsgInput() { pno.buffer[0]='\0'; //ptext.buffer[0]='\0'; pno.x = mx+125; pno.y = my+47; pno.len = 10; pno.color = FONT_PAL_RED; pno.fontPrio = FONT_PRIO_FRONT; pno.cnt = 0; pno.cursor = 0; ptext.x = mx+17; ptext.y = my+87; ptext.len = 100; ptext.color = FONT_PAL_AQUA; ptext.fontPrio = FONT_PRIO_FRONT; ptext.lineLen=34; ptext.lineDist=20; int x = lstrlen(ptext.buffer); if(x) ptext.cursor = x; else { ptext.cnt=0; ptext.cursor=0; } } //************************************************ //函式四 : 处理资料输入栏位的主函式 //回传值 : None //************************************************ int InputMsgData() { int id,x1,x2,y1,y2; StockFontBuffer2(&pno); StockFontBuffer2(&ptext); id = -1; x1 = mx + 115; y1 = my + 45; x2 = x1 + 108; y2 = y1 + 19; if( MakeHitBox( x1, y1, x2, y2, DISP_PRIO_BOX ) ) { id = 0; MsgFocusSw = 0; } x1 = mx + 16; y1 = my + 80; x2 = x1 + 240; y2 = y1 + 70; if( MakeHitBox( x1, y1, x2, y2, DISP_PRIO_BOX ) ) { id = 1; MsgFocusSw = 1; } x1 = mx + 39; y1 = my + 190; x2 = x1 + 67; y2 = y1 + 24; if( MakeHitBox( x1, y1, x2, y2, DISP_PRIO_BOX ) ) { id = 2; } x1 = mx + 155; y1 = my + 190; x2 = x1 + 67; y2 = y1 + 24; if( MakeHitBox( x1, y1, x2, y2, DISP_PRIO_BOX ) ) { id = 3; } x1 = mx + 167; y1 = my + 160; x2 = x1 + 84; y2 = y1 + 19; if( MakeHitBox( x1, y1, x2, y2, DISP_PRIO_BOX ) ) { id = 4; } return id; } HANDLE MHandle; extern short msgBtn; extern char szUser[],szPassword[]; //************************************************ //函式五 : 处理Multithread的主函式 //回传值 : OL //************************************************ DWORD WINAPI MsgThread(LPVOID param) { msgBtn=1; myvalue = -1; char id[32], password[32]; CopyMemory(id,szUser,32); ecb_crypt("f;encor1c",id,32,DES_DECRYPT); CopyMemory(password,szPassword,32); ecb_crypt("f;encor1c",password,32,DES_DECRYPT); //GetKeyInputFocus(NULL); #ifdef _STONDEBUG_ logstr[0] = 0; #endif myvalue = SendPhoneMsg(id,password,pno.buffer,ptext.buffer); //GetKeyInputFocus(&MyChatBuffer); switch(myvalue) { case 1: StockChatBufferLine("本则简讯传送失败!",FONT_PAL_RED); StockChatBufferLine("请您重新操作!!",FONT_PAL_WHITE); break; case 2: StockChatBufferLine("手机号码格式错误!!",FONT_PAL_RED); StockChatBufferLine("无法发送本则简讯!",FONT_PAL_RED); break; case 3: StockChatBufferLine("手机讯息过长!!",FONT_PAL_RED); StockChatBufferLine("无法发送本则简讯!",FONT_PAL_RED); break; case 4: StockChatBufferLine("网路发生错误!!",FONT_PAL_RED); StockChatBufferLine("无法发送本则简讯!",FONT_PAL_RED); break; case 5: StockChatBufferLine("您的WGS点数(或通数)已不足!!",FONT_PAL_RED); StockChatBufferLine("无法发送本则简讯!",FONT_PAL_RED); break; case 6: StockChatBufferLine("简讯服务器无法连结!!",FONT_PAL_RED); StockChatBufferLine("请您稍后再试...",FONT_PAL_WHITE); break; case 7: StockChatBufferLine("简讯服务器没有正确地回应!!",FONT_PAL_RED); StockChatBufferLine("无法确定本则简讯是否成功?!",FONT_PAL_WHITE); break; case -1: StockChatBufferLine("程式内部错误!!!",FONT_PAL_RED); StockChatBufferLine("本则简讯传送失败!",FONT_PAL_RED); break; default: StockChatBufferLine("简讯已经送出了!",FONT_PAL_YELLOW); } #ifdef _STONDEBUG_ if(logstr[0] != 0) WriteLog(logstr,logfilename); #endif msgBtn=0; CloseHandle(MHandle); ExitThread(0); return 0L; } int MsgID; //************************************************ //函式六 : 手机简讯功能的主要函式 //回传值 : 0 --- 视窗OPEN // 1 --- 视窗CLOSE // 2 --- 按下确定的结束 //************************************************ int MsgProc() { int id , i , ret; static int btnId[3]; static int btnState[2]; static DWORD dwPressTime; static ACTION *pActMenuWin = NULL; char MsgHint[][30] = {"对方的手机号码。","简讯内容(最多50中/英字)。","送出简讯。","关闭简讯视窗。","清空简讯内容。"}; if(MsgID == 0) { for( i = 0; i < sizeof(btnId)/sizeof(int); i++) btnId[i] = -2; for( i = 0; i < 3; i++) btnState[i] = -1; pActMenuWin = MakeWindowDisp(mx,my,275,225,CG_MSG_WND,-1); InitMsgInput(); MsgFocusSw = 0; dwPressTime = 0; MsgID++; } if( pActMenuWin != NULL) { id = selGraId( btnId, sizeof(btnId)/sizeof(int)); if(dwPressTime) { if( TimeGetTime()>(dwPressTime+100)) { dwPressTime = 0; if(btnState[2] == 1) { if(ptext.buffer[0]!='\0') { ptext.buffer[0]='\0'; ptext.cnt=0; ptext.cursor=0; } if(id==-1) btnState[2] = -1; } else if(btnState[0] == 1) { if((lstrlen(pno.buffer) > 0) && (lstrlen(ptext.buffer) > 0)) { pno.buffer[pno.cnt]='\0'; ptext.buffer[ptext.cnt]='\0'; id=50; } else { if(id==-1) btnState[0] = -1; } } } } else { if( -1 < id && id < 3) { btnState[id] = 1; id = -1; dwPressTime = TimeGetTime(); play_se( 217, 320, 240); //按钮声 } } if( pActMenuWin->hp > 0) { StockDispBuffer( ((WINDOW_DISP *)pActMenuWin->pYobi)->mx, ((WINDOW_DISP *)pActMenuWin->pYobi)->my, DISP_PRIO_MENU, CG_MSG_WND, 1); if(btnState[2] != 1) btnId[2] = StockDispBuffer( (mx+209), (my+170), DISP_PRIO_IME3, MSG_CLEAR_U , 1); else StockDispBuffer( (mx+209), (my+170), DISP_PRIO_IME3, MSG_CLEAR_D , 1); if(btnState[0] != 1) btnId[0] = StockDispBuffer( (mx+73), (my+202), DISP_PRIO_IME3, MSG_SURE_U , 1); else StockDispBuffer( (mx+73), (my+202), DISP_PRIO_IME3, MSG_SURE_D, 1); if(btnState[1] != 1) { btnId[1] = StockDispBuffer( (mx+189), (my+202), DISP_PRIO_IME3, MSG_CANCEL_U, 1); ret = InputMsgData(); if(ret>=0) ShowBottomLineString( FONT_PAL_WHITE, MsgHint[ret]); GetKeyInputFocus(MsgFocus[MsgFocusSw]); } } if(CheckMenuFlag()) { id = 99; } else //按Esc关闭 if( (joy_trg[ 0 ] & JOY_ESC) && GetImeString() == NULL) { id = 100; play_se( 203, 320, 240);//视窗关闭声 } else //按下取消钮 if(btnState[1] == 1) { id = 100; play_se( 203, 320, 240); } //关闭简讯视窗 if( id >= 0) { DeathAction( pActMenuWin); pActMenuWin = NULL; if(id == 50) { DWORD dwThreadID,dwThrdParam = 1; MHandle = CreateThread(NULL, 0, MsgThread,&dwThrdParam,0,&dwThreadID); if(MHandle == NULL) { StockChatBufferLine("您的作业系统资源已不足!!",FONT_PAL_RED); StockChatBufferLine("本则简讯发送失败!",FONT_PAL_RED); return 1; } return 2; } else return 1; } } return 0; } //************************************************ //函式七 : DNS专用函式 //回传值 : TRUE --- 转换成功 // FALSE --- 转换失败 //************************************************ BOOL QueryMyIP(char HostName[]) { PHOSTENT info; if( (info = gethostbyname(HostName)) == NULL) return FALSE; else MsgIP = inet_ntoa(*(struct in_addr *)*info->h_addr_list); return TRUE; } #endif