#include "Mra.h" #include "MraOfflineMsg.h" #include "MraRTFMsg.h" #include "MraPlaces.h" void MraThreadProc (LPVOID lpParameter); DWORD MraGetNLBData (LPSTR lpszHost,SIZE_T dwHostBuffSize,WORD *pwPort); DWORD MraNetworkDispather (); DWORD MraCommandDispather (mrim_packet_header_t *pmaHeader,DWORD *pdwPingPeriod,DWORD *pdwNextPingSendTickTime,BOOL *pbContinue); //DWORD GetMraStatusFromMiradaStatus (DWORD dwMirandaStatus,DWORD dwXStatusMir,DWORD *pdwXStatusMra); //DWORD GetMiradaStatusFromMraStatus (DWORD dwMraStatus,DWORD dwXStatusMra,DWORD *pdwXStatusMir); //DWORD GetMraXStatusIDFromMraUriStatus (LPSTR lpszStatusUri,SIZE_T dwStatusUriSize); DWORD GetUL (LPBYTE *plpData); DWORDLONG GetUIDL (LPBYTE *plpData); MRA_GUID GetGUID (LPBYTE *plpData); DWORD GetLPS (LPBYTE lpbData,DWORD dwDataSize,LPBYTE *plpCurrentData,MRA_LPS *plpsString); DWORD StartConnect() { DWORD dwRetErrorCode=NO_ERROR; if (InterlockedExchangeAdd((volatile LONG*)&masMraSettings.dwGlobalPluginRunning,0)) { if (InterlockedCompareExchange((volatile LONG*)&masMraSettings.dwThreadWorkerRunning,TRUE,FALSE)==FALSE) {// поток ещё/уже не работал, поставили статус что работает и запускаем char szPass[MAX_PATH]; SIZE_T dwEMailSize=0,dwPasswordSize=0; DB_Mra_GetStaticStringA(NULL,"e-mail",NULL,0,&dwEMailSize); if (dwEMailSize>5 && GetPassDB(szPass,sizeof(szPass),&dwPasswordSize)) {// mir_forkthread InterlockedExchange((volatile LONG*)&masMraSettings.dwThreadWorkerLastPingTime,GetTickCount()); masMraSettings.hThreadWorker=mir_forkthread(MraThreadProc,NULL); if (masMraSettings.hThreadWorker==NULL) { dwRetErrorCode=GetLastError(); InterlockedExchange((volatile LONG*)&masMraSettings.dwThreadWorkerRunning,FALSE); MraSetStatus(ID_STATUS_OFFLINE,0); } }else{ MraThreadClean(); if (!(dwEMailSize>5)) { MraPopupShowFromAgentW(MRA_POPUP_TYPE_WARNING,0,TranslateW(L"Please, setup e-mail in options")); }else{ MraPopupShowFromAgentW(MRA_POPUP_TYPE_WARNING,0,TranslateW(L"Please, setup password in options")); } } SecureZeroMemory(szPass,sizeof(szPass)); }else{ DebugBreak(); } }else{ dwRetErrorCode=ERROR_OPERATION_ABORTED; //DebugBreak(); } return(dwRetErrorCode); } void MraThreadProc(LPVOID lpParameter) { DWORD dwRetErrorCode=NO_ERROR; if (TRUE) { BOOL bConnected=FALSE; char szHost[MAX_PATH]; DWORD dwConnectReTryCount,dwCurConnectReTryCount; NETLIBOPENCONNECTION nloc={0}; SleepEx(100,FALSE);// to prevent high CPU load by some status plugins like allwaysonline dwConnectReTryCount=DB_Mra_GetDword(NULL,"ConnectReTryCountMRIM",MRA_DEFAULT_CONN_RETRY_COUNT_MRIM); nloc.cbSize=sizeof(nloc); nloc.flags=NLOCF_V2; nloc.szHost=szHost; nloc.timeout=DB_Mra_GetDword(NULL,"TimeOutConnectMRIM",MRA_DEFAULT_TIMEOUT_CONN_MRIM); if (nloc.timeoutMRA_TIMEOUT_CONN_МАХ) nloc.timeout=MRA_TIMEOUT_CONN_МАХ; InterlockedExchange((volatile LONG*)&masMraSettings.dwThreadWorkerLastPingTime,GetTickCount()); if (MraGetNLBData((LPSTR)nloc.szHost,MAX_PATH,&nloc.wPort)==NO_ERROR) { dwCurConnectReTryCount=dwConnectReTryCount; do{ InterlockedExchange((volatile LONG*)&masMraSettings.dwThreadWorkerLastPingTime,GetTickCount()); masMraSettings.hConnection=(HANDLE)CallService(MS_NETLIB_OPENCONNECTION,(WPARAM)masMraSettings.hNetlibUser,(LPARAM)&nloc); }while(--dwCurConnectReTryCount && masMraSettings.hConnection==NULL); if (masMraSettings.hConnection) { bConnected=TRUE; } } if (bConnected==FALSE) if (DB_Mra_GetByte(NULL,"NLBFailDirectConnect",MRA_DEFAULT_NLB_FAIL_DIRECT_CONNECT)) { if (IsHTTPSProxyUsed(masMraSettings.hNetlibUser)) {// через https прокси только 443 порт nloc.wPort=MRA_SERVER_PORT_HTTPS; }else{ nloc.wPort=DB_Mra_GetWord(NULL,"ServerPort",MRA_DEFAULT_SERVER_PORT); if (nloc.wPort==MRA_SERVER_PORT_STANDART_NLB) nloc.wPort=MRA_SERVER_PORT_STANDART; } for(DWORD i=1;(iMRA_TIMEOUT_CONN_МАХ) nloc.timeout=MRA_TIMEOUT_CONN_МАХ; dwCurConnectReTryCount=dwConnectReTryCount; do{ InterlockedExchange((volatile LONG*)&masMraSettings.dwThreadWorkerLastPingTime,GetTickCount()); nls.hReadConns[0]=(HANDLE)CallService(MS_NETLIB_OPENCONNECTION,(WPARAM)masMraSettings.hNetlibUser,(LPARAM)&nloc); }while(--dwCurConnectReTryCount && nls.hReadConns[0]==NULL); if (nls.hReadConns[0]) { nls.cbSize=sizeof(nls); nls.dwTimeout=(1000*DB_Mra_GetDword(NULL,"TimeOutReceiveNLB",MRA_DEFAULT_TIMEOUT_RECV_NLB)); InterlockedExchange((volatile LONG*)&masMraSettings.dwThreadWorkerLastPingTime,GetTickCount()); while(MraGetStatus(0,0)!=ID_STATUS_OFFLINE && bContinue) { switch(CallService(MS_NETLIB_SELECT,0,(LPARAM)&nls)){ case SOCKET_ERROR: case 0:// Time out bContinue=FALSE; break; case 1: dwBytesReceived=Netlib_Recv(nls.hReadConns[0],(LPSTR)(btBuff+dwRcvBuffSizeUsed),(SIZEOF(btBuff)-dwRcvBuffSizeUsed),0); if (dwBytesReceived && dwBytesReceived!=SOCKET_ERROR) { dwRcvBuffSizeUsed+=dwBytesReceived; }else{ bContinue=FALSE; } break; } InterlockedExchange((volatile LONG*)&masMraSettings.dwThreadWorkerLastPingTime,GetTickCount()); } Netlib_CloseHandle(nls.hReadConns[0]); if (dwRcvBuffSizeUsed) {// received, work with data lpszPort=(LPSTR)MemoryFindByte(0,btBuff,dwRcvBuffSizeUsed,':'); if (lpszPort) { (*lpszPort)=0; lpszPort++; lstrcpynA(lpszHost,(LPSTR)btBuff,dwHostBuffSize); if (pwPort) (*pwPort)=(WORD)StrToUNum32(lpszPort,(dwRcvBuffSizeUsed-(lpszPort-(LPSTR)btBuff))); dwRetErrorCode=NO_ERROR; }else{ dwRetErrorCode=ERROR_INVALID_USER_BUFFER; ShowFormatedErrorMessage(L"NLB data corrupted",NO_ERROR); } }else{ dwRetErrorCode=GetLastError(); ShowFormatedErrorMessage(L"Can't get data for NLB, error",dwRetErrorCode); } }else{ dwRetErrorCode=GetLastError(); ShowFormatedErrorMessage(L"Can't connect to NLB server, error",dwRetErrorCode); } return(dwRetErrorCode); } DWORD MraNetworkDispather() { DWORD dwRetErrorCode=NO_ERROR; BOOL bContinue=TRUE; DWORD dwSelectRet,dwBytesReceived,dwDataCurrentBuffSize,dwDataCurrentBuffSizeUsed,dwPingPeriod=MAXDWORD,dwNextPingSendTickTime=MAXDWORD; SIZE_T dwRcvBuffSize=BUFF_SIZE_RCV,dwRcvBuffSizeUsed=0,dwDataCurrentBuffOffset=0; LPBYTE lpbBufferRcv; NETLIBSELECT nls={0}; mrim_packet_header_t *pmaHeader; nls.cbSize=sizeof(nls); nls.dwTimeout=NETLIB_SELECT_TIMEOUT; nls.hReadConns[0]=masMraSettings.hConnection; lpbBufferRcv=(LPBYTE)MEMALLOC(dwRcvBuffSize); masMraSettings.dwCMDNum=0; MraSendCMD(MRIM_CS_HELLO,NULL,0); InterlockedExchange((volatile LONG*)&masMraSettings.dwThreadWorkerLastPingTime,GetTickCount()); while(MraGetStatus(0,0)!=ID_STATUS_OFFLINE && bContinue) { dwSelectRet=CallService(MS_NETLIB_SELECT,0,(LPARAM)&nls); switch(dwSelectRet){ case SOCKET_ERROR: if (MraGetStatus(0,0)!=ID_STATUS_OFFLINE) { dwRetErrorCode=GetLastError(); ShowFormatedErrorMessage(L"Disconnected, socket error",dwRetErrorCode); } bContinue=FALSE; break; case 0:// Time out case 1: dwBytesReceived=GetTickCount(); InterlockedExchange((volatile LONG*)&masMraSettings.dwThreadWorkerLastPingTime,dwBytesReceived); if (dwNextPingSendTickTime<=dwBytesReceived) {// server ping dwNextPingSendTickTime=(dwBytesReceived+(dwPingPeriod*1000)); MraSendCMD(MRIM_CS_PING,NULL,0); } { DWORD dwCMDNum,dwFlags,dwAckType; HANDLE hContact; LPBYTE lpbData; SIZE_T dwDataSize; while (MraSendQueueFindOlderThan(masMraSettings.hSendQueueHandle,SEND_QUEUE_TIMEOUT,&dwCMDNum,&dwFlags,&hContact,&dwAckType,&lpbData,&dwDataSize)==NO_ERROR) { switch(dwAckType){ case ACKTYPE_ADDED: case ACKTYPE_AUTHREQ: case ACKTYPE_CONTACTS: //nothink to do break; case ACKTYPE_MESSAGE: ProtoBroadcastAckAsynchEx(PROTOCOL_NAMEA,hContact,dwAckType,ACKRESULT_FAILED,(HANDLE)dwCMDNum,(LPARAM)"Undefined message deliver error, time out",-1); break; case ACKTYPE_GETINFO: ProtoBroadcastAckAsynchEx(PROTOCOL_NAMEA,hContact,dwAckType,ACKRESULT_FAILED,(HANDLE)1,(LPARAM)NULL,0); break; case ACKTYPE_SEARCH: ProtoBroadcastAckAsynchEx(PROTOCOL_NAMEA,hContact,dwAckType,ACKRESULT_SUCCESS,(HANDLE)dwCMDNum,(LPARAM)NULL,0); break; case ICQACKTYPE_SMS: MEMFREE(lpbData); break; } MraSendQueueFree(masMraSettings.hSendQueueHandle,dwCMDNum); } } if (dwSelectRet==0) break;// Time out if ((dwRcvBuffSize-dwRcvBuffSizeUsed)=sizeof(mrim_packet_header_t)) {// packet header received if (pmaHeader->magic==CS_MAGIC) {// packet OK if ((dwDataCurrentBuffSizeUsed-sizeof(mrim_packet_header_t))>=pmaHeader->dlen) {// full packet received, may be more than one MraCommandDispather(pmaHeader,&dwPingPeriod,&dwNextPingSendTickTime,&bContinue); if ((dwDataCurrentBuffSizeUsed-sizeof(mrim_packet_header_t))>pmaHeader->dlen) {// move pointer to next packet in buffer dwDataCurrentBuffOffset+=(sizeof(mrim_packet_header_t)+pmaHeader->dlen); }else{// move pointer to begin of buffer if (dwRcvBuffSize>BUFF_SIZE_RCV) {// динамическое уменьшение буффера приёма dwRcvBuffSize=BUFF_SIZE_RCV; lpbBufferRcv=(LPBYTE)MEMREALLOC(lpbBufferRcv,dwRcvBuffSize); } dwDataCurrentBuffOffset=0; dwRcvBuffSizeUsed=0; break; } }else{// not all packet received, continue receiving if (dwDataCurrentBuffOffset) { memmove(lpbBufferRcv,(lpbBufferRcv+dwDataCurrentBuffOffset),dwDataCurrentBuffSizeUsed); dwRcvBuffSizeUsed=dwDataCurrentBuffSizeUsed; dwDataCurrentBuffOffset=0; } DebugPrintCRLFW(L"Not all packet received, continue receiving"); break; } }else{// bad packet DebugPrintCRLFW(L"Bad packet"); dwDataCurrentBuffOffset=0; dwRcvBuffSizeUsed=0; break; } }else{// packet to small, continue receiving DebugPrintCRLFW(L"Packet to small, continue receiving"); memmove(lpbBufferRcv,(lpbBufferRcv+dwDataCurrentBuffOffset),dwDataCurrentBuffSizeUsed); dwRcvBuffSizeUsed=dwDataCurrentBuffSizeUsed; dwDataCurrentBuffOffset=0; break; } } }else{// disconnected if (MraGetStatus(0,0)!=ID_STATUS_OFFLINE) { dwRetErrorCode=GetLastError(); ShowFormatedErrorMessage(L"Disconnected, socket read error",dwRetErrorCode); } bContinue=FALSE; } break; }// end switch }// end while MEMFREE(lpbBufferRcv); return(dwRetErrorCode); } DWORD MraCommandDispather(mrim_packet_header_t *pmaHeader,DWORD *pdwPingPeriod,DWORD *pdwNextPingSendTickTime,BOOL *pbContinue) { WCHAR szBuff[4096]={0}; DWORD dwDataSize,dwTemp,dwAckType; SIZE_T dwStringSize; MRA_LPS lpsString={0},lpsEMail={0}; HANDLE hContact=NULL; LPBYTE lpbData,lpbDataCurrent; lpbData=((((LPBYTE)pmaHeader))+sizeof(mrim_packet_header_t)); lpbDataCurrent=lpbData; dwDataSize=pmaHeader->dlen; switch(pmaHeader->msg){ case MRIM_CS_HELLO_ACK://Подтверждение установки соединения// UL ## ping_period ## Ожидаемая частота подтверждения соединения (в секундах) //CredUIPromptForCredentials //CYPTPROTECTMEMORY_BLOCK_SIZE=RTL_ENCRYPT_MEMORY_SIZE=8 //CryptProtectMemory(szBuff,sizeof(szBuff),CRYPTPROTECTMEMORY_SAME_PROCESS); if(GetPassDB((LPSTR)szBuff,SIZEOF(szBuff),&dwStringSize)) {//bit of a security hole here, since it's easy to extract a password from an edit box CHAR szEMail[MAX_EMAIL_LEN],szSelfVersionString[MAX_PATH],szUserAgentFormated[USER_AGENT_MAX+MAX_PATH],szValueName[MAX_PATH]; WCHAR wszStatusTitle[STATUS_TITLE_MAX+4],wszStatusDesc[STATUS_DESC_MAX+4]; DWORD dwStatus,dwXStatus,dwXStatusMir,dwFutureFlags; LPWSTR lpwszStatusTitle,lpwszStatusDesc; SIZE_T dwEMailSize,dwSelfVersionSize,dwStatusTitleSize,dwStatusDescSize,dwUserAgentFormatedSize; dwXStatusMir=MraGetXStatusInternal(); dwStatus=GetMraStatusFromMiradaStatus(masMraSettings.dwDesiredStatusMode,dwXStatusMir,&dwXStatus); if (IsXStatusValid(dwXStatusMir)) {// xstatuses mir_snprintf(szValueName,SIZEOF(szValueName),"XStatus%ldName",dwXStatusMir); if (DB_Mra_GetStaticStringW(NULL,szValueName,wszStatusTitle,(STATUS_TITLE_MAX+1),&dwStatusTitleSize)) {// custom xstatus name lpwszStatusTitle=wszStatusTitle; }else{// default xstatus name lpwszStatusTitle=TranslateW(lpcszXStatusNameDef[dwXStatusMir]); dwStatusTitleSize=lstrlenW(lpwszStatusTitle); } mir_snprintf(szValueName,SIZEOF(szValueName),"XStatus%ldMsg",dwXStatusMir); if (DB_Mra_GetStaticStringW(NULL,szValueName,wszStatusDesc,(STATUS_DESC_MAX+1),&dwStatusDescSize)) {// custom xstatus description lpwszStatusDesc=wszStatusDesc; }else{// default xstatus description lpwszStatusDesc=NULL; dwStatusDescSize=0; } }else{// not xstatuses lpwszStatusTitle=GetStatusModeDescriptionW(masMraSettings.dwDesiredStatusMode); dwStatusTitleSize=lstrlenW(lpwszStatusTitle); lpwszStatusDesc=NULL; dwStatusDescSize=0; } MraGetSelfVersionString(szSelfVersionString,SIZEOF(szSelfVersionString),&dwSelfVersionSize); if (DB_Mra_GetStaticStringA(NULL,"MirVerCustom",szUserAgentFormated,SIZEOF(szUserAgentFormated),&dwUserAgentFormatedSize)==FALSE) { dwUserAgentFormatedSize=mir_snprintf(szUserAgentFormated,SIZEOF(szUserAgentFormated),"client=\"magent\" name=\"Miranda IM\" title=\"%s\" version=\"777.%lu.%lu.%lu\" build=\"%lu\" protocol=\"%lu.%lu\"",szSelfVersionString,(((PLUGIN_VERSION_DWORD)>>24)&0xFF),(((PLUGIN_VERSION_DWORD)>>16)&0xFF),(((PLUGIN_VERSION_DWORD)>>8)&0xFF),((PLUGIN_VERSION_DWORD)&0xFF),PROTO_MAJOR(PROTO_VERSION),PROTO_MINOR(PROTO_VERSION));// "client=\"magent\" version=\"9.3\" build=\"777\"" } dwFutureFlags=((DB_Mra_GetByte(NULL,"RTFReceiveEnable",MRA_DEFAULT_RTF_RECEIVE_ENABLE)? FEATURE_FLAG_RTF_MESSAGE:0)|MRA_FEATURE_FLAGS); if (DB_Mra_GetStaticStringA(NULL,"e-mail",szEMail,SIZEOF(szEMail),&dwEMailSize)) { MraSendCommand_Login2W(szEMail,dwEMailSize,(LPSTR)szBuff,dwStringSize,dwStatus,lpcszStatusUri[dwXStatus],lstrlenA(lpcszStatusUri[dwXStatus]),lpwszStatusTitle,dwStatusTitleSize,lpwszStatusDesc,dwStatusDescSize,dwFutureFlags,szUserAgentFormated,dwUserAgentFormatedSize,szSelfVersionString,dwSelfVersionSize); }else{// no login (*pbContinue)=FALSE; } SecureZeroMemory(szBuff,sizeof(szBuff)); }else{// no password (*pbContinue)=FALSE; } (*pdwPingPeriod)=GetUL(&lpbDataCurrent); break; case MRIM_CS_LOGIN_ACK://Успешная авторизация masMraSettings.bLoggedIn=TRUE; (*pdwNextPingSendTickTime)=0;// force send ping MraSendCMD(MRIM_CS_PING,NULL,0); MraSetStatus(masMraSettings.dwDesiredStatusMode,masMraSettings.dwDesiredStatusMode); //(*((LPBYTE)NULL))=1;// force exception //while(TRUE) Sleep(1); // force infinite loop MraAvatarsQueueGetAvatarSimple(masMraSettings.hAvatarsQueueHandle,GAIF_FORCE,NULL,0); break; case MRIM_CS_LOGIN_REJ://Неверная авторизация //LPS ## reason ## причина отказа ProtoBroadcastAckAsynchEx(PROTOCOL_NAMEA,NULL,ACKTYPE_LOGIN,ACKRESULT_FAILED,NULL,LOGINERR_WRONGPASSWORD,0); GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString); dwStringSize=MultiByteToWideChar(MRA_CODE_PAGE,0,lpsString.lpszData,lpsString.dwSize,szBuff,SIZEOF(szBuff)); szBuff[dwStringSize]=0; MraPopupShowW(NULL,MRA_POPUP_TYPE_ERROR,0,TranslateW(L"Logon error: invalid login/password"),szBuff); (*pbContinue)=FALSE; break; case MRIM_CS_MESSAGE_ACK:// Доставка сообщения { DWORD dwMsgID,dwFlags; MRA_LPS lpsText,lpsRTFText,lpsMultiChatData; dwMsgID=GetUL(&lpbDataCurrent); dwFlags=GetUL(&lpbDataCurrent); GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsEMail);//LPS ## from ## Адрес отправителя GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsText);//LPS ## message ## текстовая версия сообщения //if (dwFlags&MESSAGE_FLAG_RTF) GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsRTFText);//LPS ## rtf-message ## форматированная версия сообщения if (dwFlags&MESSAGE_FLAG_MULTICHAT) GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsMultiChatData); // LPS multichat_data if (MraRecvCommand_Message((DWORD)_time32(NULL),dwFlags,&lpsEMail,&lpsText,&lpsRTFText,&lpsMultiChatData)==NO_ERROR) {// подтверждаем получение, только если удалось его обработать if ((dwFlags&MESSAGE_FLAG_NORECV)==0) {// need send delivery status MraSendCommand_MessageRecv(lpsEMail.lpszData,lpsEMail.dwSize,dwMsgID); } } } break; case MRIM_CS_MESSAGE_STATUS: if (MraSendQueueFind(masMraSettings.hSendQueueHandle,pmaHeader->seq,NULL,&hContact,&dwAckType,(LPBYTE*)&lpsString.lpszData,&lpsString.dwSize)==NO_ERROR) { dwTemp=GetUL(&lpbDataCurrent); switch(dwTemp){ case MESSAGE_DELIVERED:// Message delivered directly to user ProtoBroadcastAckAsynchEx(PROTOCOL_NAMEA,hContact,dwAckType,ACKRESULT_SUCCESS,(HANDLE)pmaHeader->seq,(LPARAM)NULL,0); break;//***deb возможны сбои из-за асинхронности тк там передаётся указатель case MESSAGE_REJECTED_NOUSER:// Message rejected - no such user ProtoBroadcastAckAsynchEx(PROTOCOL_NAMEA,hContact,dwAckType,ACKRESULT_FAILED,(HANDLE)pmaHeader->seq,(LPARAM)"Message rejected - no such user",-1); break; case MESSAGE_REJECTED_INTERR:// Internal server error ProtoBroadcastAckAsynchEx(PROTOCOL_NAMEA,hContact,dwAckType,ACKRESULT_FAILED,(HANDLE)pmaHeader->seq,(LPARAM)"Internal server error",-1); break; case MESSAGE_REJECTED_LIMIT_EXCEEDED:// Offline messages limit exceeded ProtoBroadcastAckAsynchEx(PROTOCOL_NAMEA,hContact,dwAckType,ACKRESULT_FAILED,(HANDLE)pmaHeader->seq,(LPARAM)"Offline messages limit exceeded",-1); break; case MESSAGE_REJECTED_TOO_LARGE:// Message is too large ProtoBroadcastAckAsynchEx(PROTOCOL_NAMEA,hContact,dwAckType,ACKRESULT_FAILED,(HANDLE)pmaHeader->seq,(LPARAM)"Message is too large",-1); break; case MESSAGE_REJECTED_DENY_OFFMSG:// User does not accept offline messages ProtoBroadcastAckAsynchEx(PROTOCOL_NAMEA,hContact,dwAckType,ACKRESULT_FAILED,(HANDLE)pmaHeader->seq,(LPARAM)"User does not accept offline messages",-1); break; case MESSAGE_REJECTED_DENY_OFFFLSH:// User does not accept offline flash animation ProtoBroadcastAckAsynchEx(PROTOCOL_NAMEA,hContact,dwAckType,ACKRESULT_FAILED,(HANDLE)pmaHeader->seq,(LPARAM)"User does not accept offline flash animation",-1); break; default: dwTemp=mir_snprintf((LPSTR)szBuff,SIZEOF(szBuff),"Undefined message deliver error, code: %lu",dwTemp); ProtoBroadcastAckAsynchEx(PROTOCOL_NAMEA,hContact,dwAckType,ACKRESULT_FAILED,(HANDLE)pmaHeader->seq,(LPARAM)szBuff,dwTemp); break; } MraSendQueueFree(masMraSettings.hSendQueueHandle,pmaHeader->seq); }else{// not found in queue if (GetUL(&lpbDataCurrent)!=MESSAGE_DELIVERED) MraPopupShowFromAgentW(MRA_POPUP_TYPE_DEBUG,0,TranslateW(L"MRIM_CS_MESSAGE_STATUS: not found in queue")); } break; case MRIM_CS_CONNECTION_PARAMS:// Изменение параметров соединения (*pdwPingPeriod)=GetUL(&lpbDataCurrent); (*pdwNextPingSendTickTime)=0;// force send ping MraSendCMD(MRIM_CS_PING,NULL,0); break; case MRIM_CS_USER_INFO: while (lpbDataCurrent<(lpbData+dwDataSize)) { GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString); if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpsString.lpszData,lpsString.dwSize,"MESSAGES.TOTAL",14)==CSTR_EQUAL) { GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString); masMraSettings.dwEmailMessagesTotal=StrToUNum32(lpsString.lpszData,lpsString.dwSize); }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpsString.lpszData,lpsString.dwSize,"MESSAGES.UNREAD",15)==CSTR_EQUAL) { GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString); masMraSettings.dwEmailMessagesUnRead=StrToUNum32(lpsString.lpszData,lpsString.dwSize); }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpsString.lpszData,lpsString.dwSize,"MRIM.NICKNAME",13)==CSTR_EQUAL) { GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString); DB_Mra_SetLPSStringW(NULL,"Nick",&lpsString); }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpsString.lpszData,lpsString.dwSize,"client.endpoint",15)==CSTR_EQUAL) { LPSTR lpszDelimiter; GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString); dwStringSize=WideCharToMultiByte(MRA_CODE_PAGE,0,lpsString.lpwszData,lpsString.dwSize,(LPSTR)szBuff,sizeof(szBuff),NULL,NULL); lpszDelimiter=(LPSTR)MemoryFind(0,szBuff,dwStringSize,":",1); if (lpszDelimiter) { (*lpszDelimiter)=0; lpszDelimiter=(LPSTR)szBuff; DB_Mra_SetDword(NULL,"IP",HTONL(inet_addr(lpszDelimiter))); } }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpsString.lpszData,lpsString.dwSize,"connect.xml",11)==CSTR_EQUAL) { DebugPrintA(lpsString.lpszData); GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString); DebugPrintCRLFW(lpsString.lpwszData); }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpsString.lpszData,lpsString.dwSize,"micblog.show_title",18)==CSTR_EQUAL) { DebugPrintA(lpsString.lpszData); GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString); DebugPrintCRLFW(lpsString.lpwszData); }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpsString.lpszData,lpsString.dwSize,"micblog.status.id",17)==CSTR_EQUAL) { DWORDLONG dwBlogStatusID; GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString); dwBlogStatusID=StrToUNum64(lpsString.lpszData,lpsString.dwSize); DB_Mra_WriteContactSettingBlob(NULL,DBSETTING_BLOGSTATUSID,&dwBlogStatusID,sizeof(DWORDLONG)); }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpsString.lpszData,lpsString.dwSize,"micblog.status.time",19)==CSTR_EQUAL) { GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString); DB_Mra_SetDword(NULL,DBSETTING_BLOGSTATUSTIME,StrToUNum32(lpsString.lpszData,lpsString.dwSize)); }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpsString.lpszData,lpsString.dwSize,"micblog.status.text",19)==CSTR_EQUAL) { GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString); DB_Mra_SetLPSStringW(NULL,DBSETTING_BLOGSTATUS,&lpsString); }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpsString.lpszData,lpsString.dwSize,"HAS_MYMAIL",10)==CSTR_EQUAL) {// ??? GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString); //DB_Mra_SetDword(NULL,DBSETTING_BLOGSTATUSTIME,StrToUNum32(lpsString.lpszData,lpsString.dwSize)); }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpsString.lpszData,lpsString.dwSize,"mrim.status.open_search",23)==CSTR_EQUAL) {// ??? GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString); //DB_Mra_SetDword(NULL,DBSETTING_BLOGSTATUSTIME,StrToUNum32(lpsString.lpszData,lpsString.dwSize)); }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpsString.lpszData,lpsString.dwSize,"rb.target.cookie",16)==CSTR_EQUAL) {// ??? GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString); //DB_Mra_SetDword(NULL,DBSETTING_BLOGSTATUSTIME,StrToUNum32(lpsString.lpszData,lpsString.dwSize)); }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpsString.lpszData,lpsString.dwSize,"show_web_history_link",21)==CSTR_EQUAL) {// ??? GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString); //DB_Mra_SetDword(NULL,DBSETTING_BLOGSTATUSTIME,StrToUNum32(lpsString.lpszData,lpsString.dwSize)); }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpsString.lpszData,lpsString.dwSize,"friends_suggest",15)==CSTR_EQUAL) {// ??? GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString); //DB_Mra_SetDword(NULL,DBSETTING_BLOGSTATUSTIME,StrToUNum32(lpsString.lpszData,lpsString.dwSize)); }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpsString.lpszData,lpsString.dwSize,"timestamp",9)==CSTR_EQUAL) {// ??? GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString); //DB_Mra_SetDword(NULL,DBSETTING_BLOGSTATUSTIME,StrToUNum32(lpsString.lpszData,lpsString.dwSize)); }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpsString.lpszData,lpsString.dwSize,"trusted_update",14)==CSTR_EQUAL) {// ??? GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString); //DB_Mra_SetDword(NULL,DBSETTING_BLOGSTATUSTIME,StrToUNum32(lpsString.lpszData,lpsString.dwSize)); }else{ #ifdef _DEBUG LPSTR lpszCurrentPos=(LPSTR)szBuff; memmove(lpszCurrentPos,lpsString.lpszData,lpsString.dwSize); lpszCurrentPos+=lpsString.dwSize; (*((WORD*)lpszCurrentPos))=(*((WORD*)": ")); lpszCurrentPos+=sizeof(WORD); GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString); memmove(lpszCurrentPos,lpsString.lpszData,lpsString.dwSize); lpszCurrentPos+=lpsString.dwSize; (*((WORD*)lpszCurrentPos))=(*((WORD*)szCRLF)); lpszCurrentPos+=sizeof(WORD);(*((WORD*)lpszCurrentPos))=0; DebugPrintCRLFA((LPSTR)szBuff); //MraPopupShowFromAgentW(MRA_POPUP_TYPE_DEBUG,0,szBuff); DebugBreak(); #endif } } MraUpdateEmailStatus(NULL,0,NULL,0,0,0); break; case MRIM_CS_OFFLINE_MESSAGE_ACK://Сообщение доставленное, пока пользователь не был подключен к сети { DWORD dwTime,dwFlags; MRA_LPS lpsText,lpsRTFText,lpsMultiChatData; LPBYTE lpbBuff=NULL; DWORDLONG dwMsgUIDL; dwMsgUIDL=GetUIDL(&lpbDataCurrent); GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString); if (MraOfflineMessageGet(&lpsString,&dwTime,&dwFlags,&lpsEMail,&lpsText,&lpsRTFText,&lpsMultiChatData,&lpbBuff)==NO_ERROR) { dwTemp=MraRecvCommand_Message(dwTime,dwFlags,&lpsEMail,&lpsText,&lpsRTFText,&lpsMultiChatData); if (dwTemp==NO_ERROR || dwTemp==ERROR_ACCESS_DENIED) {// подтверждаем получение, только если удалось его обработать MraSendCommand_OfflineMessageDel(dwMsgUIDL); }else{ ShowFormatedErrorMessage(L"Offline message processing error, message will not deleted from server",NO_ERROR); } }else{ ShowFormatedErrorMessage(L"Offline message processing error, message will not deleted from server",NO_ERROR); } MEMFREE(lpbBuff); } break; case MRIM_CS_AUTHORIZE_ACK://Информация об авторизации {// нас автоизовали, те разрешили нам получать уведомление об изменении статуса, значит юзер у нас в списке BOOL bAdded; BYTE btBuff[BUFF_SIZE_BLOB]; DBEVENTINFO dbei={0}; GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsEMail); hContact=MraHContactFromEmail(lpsEMail.lpszData,lpsEMail.dwSize,TRUE,TRUE,&bAdded); if (bAdded) MraUpdateContactInfo(hContact); if (IsEMailChatAgent(lpsEMail.lpszData,lpsEMail.dwSize)==FALSE) { dbei.cbSize=sizeof(dbei); dbei.szModule=PROTOCOL_NAMEA; dbei.timestamp=(DWORD)_time32(NULL); dbei.flags=0; dbei.eventType=EVENTTYPE_ADDED; //dbei.cbBlob=0; CreateBlobFromContact(hContact,NULL,0,(LPBYTE)&btBuff,SIZEOF(btBuff),&dwStringSize); dbei.cbBlob=dwStringSize; dbei.pBlob=btBuff; CallService(MS_DB_EVENT_ADD,(WPARAM)NULL,(LPARAM)&dbei); } GetContactBasicInfoW(hContact,NULL,NULL,NULL,&dwTemp,NULL,NULL,0,NULL,NULL,0,NULL,NULL,0,NULL); dwTemp&=~CONTACT_INTFLAG_NOT_AUTHORIZED; SetContactBasicInfoW(hContact,SCBIFSI_LOCK_CHANGES_EVENTS,SCBIF_SERVER_FLAG,0,0,0,dwTemp,0,NULL,0,NULL,0,NULL,0); DB_Mra_SetDword(hContact,"HooksLocked",TRUE); DBDeleteContactSetting(hContact,"CList","NotOnList"); DB_Mra_SetDword(hContact,"HooksLocked",FALSE); } break; case MRIM_CS_MPOP_SESSION://Ключ для web-авторизации // if (GetUL(&lpbDataCurrent)) { GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString); MraMPopSessionQueueSetNewMPopKey(masMraSettings.hMPopSessionQueue,lpsString.lpszData,lpsString.dwSize); MraMPopSessionQueueStart(masMraSettings.hMPopSessionQueue); }else{//error MraPopupShowFromAgentW(MRA_POPUP_TYPE_WARNING,0,TranslateW(L"Server error: cant get MPOP key for web authorize")); MraMPopSessionQueueFlush(masMraSettings.hMPopSessionQueue); } break; ///////////////////////////////////////////////////////////////////////////////////// case MRIM_CS_FILE_TRANSFER: { BOOL bAdded; DWORD dwIDRequest,dwFilesTotalSize; MRA_LPS lpsFiles={0},lpsFilesW={0},lpsAddreses={0}; GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsEMail);// LPS TO/FROM ANSI dwIDRequest=GetUL(&lpbDataCurrent);// DWORD id_request dwFilesTotalSize=GetUL(&lpbDataCurrent);// DWORD FILESIZE if (GetUL(&lpbDataCurrent))//LPS: { GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsFiles);// LPS Files (FileName;FileSize;FileName;FileSize;) ANSI if (GetUL(&lpbDataCurrent))// LPS DESCRIPTION { dwTemp=GetUL(&lpbDataCurrent);// ??? DebugBreakIf(dwTemp!=1); GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsFilesW);// LPS Files (FileName;FileSize;FileName;FileSize;) UNICODE } GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsAddreses);// LPS Conn (IP:Port;IP:Port;) ANSI } hContact=MraHContactFromEmail(lpsEMail.lpszData,lpsEMail.dwSize,TRUE,TRUE,&bAdded); if (bAdded) MraUpdateContactInfo(hContact); bAdded=FALSE; if (lpsFilesW.dwSize==0) { lpsFilesW.lpwszData=(LPWSTR)MEMALLOC((lpsFiles.dwSize+MAX_PATH)*sizeof(WCHAR)); if (lpsFilesW.lpwszData) { lpsFilesW.dwSize=MultiByteToWideChar(MRA_CODE_PAGE,0,lpsFiles.lpszData,lpsFiles.dwSize,lpsFilesW.lpwszData,(lpsFiles.dwSize+MAX_PATH)); bAdded=TRUE; } } if (lpsFilesW.dwSize) MraFilesQueueAddReceive(masMraSettings.hFilesQueueHandle,0,hContact,dwIDRequest,lpsFilesW.lpwszData,lpsFilesW.dwSize,lpsAddreses.lpszData,lpsAddreses.dwSize); if (bAdded) MEMFREE(lpsFilesW.lpwszData); } break; case MRIM_CS_FILE_TRANSFER_ACK: dwAckType=GetUL(&lpbDataCurrent);// DWORD status GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsEMail);// LPS TO/FROM dwTemp=GetUL(&lpbDataCurrent);// DWORD id_request GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString);// LPS DESCRIPTION switch(dwAckType){ case FILE_TRANSFER_STATUS_OK:// игнорируем, мы и так уже слушаем порт(ждём), то что кто то согласился ничего не меняет //hContact=MraHContactFromEmail(lpsEMail.lpszData,lpsEMail.dwSize,TRUE,TRUE,NULL); break; case FILE_TRANSFER_STATUS_DECLINE: MraFilesQueueCancel(masMraSettings.hFilesQueueHandle,dwTemp,FALSE); break; case FILE_TRANSFER_STATUS_ERROR: ShowFormatedErrorMessage(L"File transfer: error",NO_ERROR); MraFilesQueueCancel(masMraSettings.hFilesQueueHandle,dwTemp,FALSE); break; case FILE_TRANSFER_STATUS_INCOMPATIBLE_VERS: ShowFormatedErrorMessage(L"File transfer: incompatible versions",NO_ERROR); MraFilesQueueCancel(masMraSettings.hFilesQueueHandle,dwTemp,FALSE); break; case FILE_TRANSFER_MIRROR: MraFilesQueueSendMirror(masMraSettings.hFilesQueueHandle,dwTemp,lpsString.lpszData,lpsString.dwSize); break; default:// ## unknown error mir_sntprintf(szBuff,SIZEOF(szBuff),TranslateW(L"MRIM_CS_FILE_TRANSFER_ACK: unknown error, code: %lu"),dwAckType); ShowFormatedErrorMessage(szBuff,NO_ERROR); break; } break; ///////////////////////////////////////////////////////////////////////////////////// case MRIM_CS_USER_STATUS://Смена статуса другого пользователя { BOOL bAdded; DWORD dwStatus,dwXStatus,dwFutureFlags; MRA_LPS lpsSpecStatusUri,lpsStatusTitle,lpsStatusDesc,lpsUserAgentFormated; dwStatus=GetUL(&lpbDataCurrent); GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsSpecStatusUri); GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsStatusTitle); GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsStatusDesc); GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsEMail); dwFutureFlags=GetUL(&lpbDataCurrent);// com_support (>=1.14) GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsUserAgentFormated); if ((hContact=MraHContactFromEmail(lpsEMail.lpszData,lpsEMail.dwSize,TRUE,TRUE,&bAdded))) { if (bAdded) MraUpdateContactInfo(hContact); dwTemp=GetMiradaStatusFromMraStatus(dwStatus,GetMraXStatusIDFromMraUriStatus(lpsSpecStatusUri.lpszData,lpsSpecStatusUri.dwSize),&dwXStatus); MraContactCapabilitiesSet(hContact,dwFutureFlags); DB_Mra_SetByte(hContact,DBSETTING_XSTATUSID,(BYTE)dwXStatus); DB_Mra_SetLPSStringW(hContact,DBSETTING_XSTATUSNAME,&lpsStatusTitle); DB_Mra_SetLPSStringW(hContact,DBSETTING_XSTATUSMSG,&lpsStatusDesc); if (dwTemp!=ID_STATUS_OFFLINE)// пишем клиента только если юзер не отключён, иначе не затираем старое { if (lpsUserAgentFormated.dwSize) {// есть чё писать if (DB_Mra_GetByte(NULL,"MirVerRaw",MRA_DEFAULT_MIRVER_RAW)==FALSE) {// приводим к человеческому виду, если получится... MraGetVersionStringFromFormated(lpsUserAgentFormated.lpszData,lpsUserAgentFormated.dwSize,(LPSTR)szBuff,SIZEOF(szBuff),&dwStringSize); lpsUserAgentFormated.lpszData=(LPSTR)szBuff; lpsUserAgentFormated.dwSize=dwStringSize; } }else{// хз чё за клиент lpsUserAgentFormated.lpszData=MIRVER_UNKNOWN; lpsUserAgentFormated.dwSize=(sizeof(MIRVER_UNKNOWN)-1); } DB_Mra_SetLPSStringA(hContact,"MirVer",&lpsUserAgentFormated); } if (dwTemp==MraGetContactStatus(hContact)) {// меняем шило на шило, подозрительно? ;) if (dwTemp==ID_STATUS_OFFLINE) {// was/now invisible WCHAR szEMail[MAX_EMAIL_LEN]; DB_Mra_GetStaticStringW(hContact,"e-mail",szEMail,SIZEOF(szEMail),NULL); mir_sntprintf(szBuff,SIZEOF(szBuff),L"%s <%s> - %s",GetContactNameW(hContact),szEMail,TranslateW(L"invisible status changed")); MraPopupShowFromContactW(hContact,MRA_POPUP_TYPE_INFORMATION,0,szBuff); MraSetContactStatus(hContact,ID_STATUS_INVISIBLE); }else{// server or miranda bug or status change //DebugBreak(); } } MraSetContactStatus(hContact,dwTemp); SetExtraIcons(hContact); } } break; case MRIM_CS_LOGOUT:// Пользователь отключен из-за параллельного входа с его логином. if (GetUL(&lpbDataCurrent)==LOGOUT_NO_RELOGIN_FLAG) ShowFormatedErrorMessage(L"Another user connected with your login",NO_ERROR); (*pbContinue)=FALSE; break; case MRIM_CS_ADD_CONTACT_ACK: case MRIM_CS_MODIFY_CONTACT_ACK: if (MraSendQueueFind(masMraSettings.hSendQueueHandle,pmaHeader->seq,NULL,&hContact,&dwAckType,(LPBYTE*)&lpsString.lpszData,&lpsString.dwSize)==NO_ERROR) { dwTemp=GetUL(&lpbDataCurrent); switch(dwTemp){ case CONTACT_OPER_SUCCESS:// ## добавление произведено успешно if (pmaHeader->msg==MRIM_CS_ADD_CONTACT_ACK) SetContactBasicInfoW(hContact,0,(SCBIF_ID|SCBIF_SERVER_FLAG),GetUL(&lpbDataCurrent),0,0,CONTACT_INTFLAG_NOT_AUTHORIZED,0,NULL,0,NULL,0,NULL,0); break; case CONTACT_OPER_ERROR:// ## переданные данные были некорректны ShowFormatedErrorMessage(L"Sended data is invalid",NO_ERROR); break; case CONTACT_OPER_INTERR:// ## при обработке запроса произошла внутренняя ошибка ShowFormatedErrorMessage(L"Internal server error",NO_ERROR); break; case CONTACT_OPER_NO_SUCH_USER:// ## добавляемого пользователя не существует в системе SetContactBasicInfoW(hContact,0,SCBIF_SERVER_FLAG,0,0,0,-1,0,NULL,0,NULL,0,NULL,0); ShowFormatedErrorMessage(L"User does not registred",NO_ERROR); break; case CONTACT_OPER_INVALID_INFO:// ## некорректное имя пользователя ShowFormatedErrorMessage(L"Invalid user name",NO_ERROR); break; case CONTACT_OPER_USER_EXISTS:// ## пользователь уже есть в контакт-листе ShowFormatedErrorMessage(L"User allready added",NO_ERROR); break; case CONTACT_OPER_GROUP_LIMIT:// ## превышено максимально допустимое количество групп (20) ShowFormatedErrorMessage(L"Group limit is 20",NO_ERROR); break; default:// ## unknown error mir_sntprintf(szBuff,SIZEOF(szBuff),TranslateW(L"MRIM_CS_*_CONTACT_ACK: unknown server error, code: %lu"),dwTemp); MraPopupShowFromAgentW(MRA_POPUP_TYPE_DEBUG,0,szBuff); break; } MraSendQueueFree(masMraSettings.hSendQueueHandle,pmaHeader->seq); }else{// not found in queue MraPopupShowFromAgentW(MRA_POPUP_TYPE_DEBUG,0,TranslateW(L"MRIM_CS_*_CONTACT_ACK: not found in queue")); } break; case MRIM_CS_ANKETA_INFO: if (MraSendQueueFind(masMraSettings.hSendQueueHandle,pmaHeader->seq,NULL,&hContact,&dwAckType,(LPBYTE*)&lpsString.lpszData,&lpsString.dwSize)==NO_ERROR) { switch(GetUL(&lpbDataCurrent)){ case MRIM_ANKETA_INFO_STATUS_OK:// поиск успешно завершен { DWORD dwFeildsNum,dwMaxRows,dwServerTime,dwStatus; SIZE_T i; MRA_LPS *pmralpsFeilds,*pmralpsValues; dwFeildsNum=GetUL(&lpbDataCurrent); dwMaxRows=GetUL(&lpbDataCurrent); dwServerTime=GetUL(&lpbDataCurrent); pmralpsFeilds=(MRA_LPS*)MEMALLOC(((dwFeildsNum*2)+4)*sizeof(MRA_LPS)); if (pmralpsFeilds) { pmralpsValues=(pmralpsFeilds+dwFeildsNum); // read headers name for (i=0;i9) {// calc "Age" SYSTEMTIME stTime={0}; stTime.wYear=(WORD)StrToUNum32(pmralpsValues[i].lpszData,4); stTime.wMonth=(WORD)StrToUNum32((pmralpsValues[i].lpszData+5),2); stTime.wDay=(WORD)StrToUNum32((pmralpsValues[i].lpszData+8),2); DB_Mra_SetWord(hContact,"BirthYear",stTime.wYear); DB_Mra_SetByte(hContact,"BirthMonth",(BYTE)stTime.wMonth); DB_Mra_SetByte(hContact,"BirthDay",(BYTE)stTime.wDay); DB_Mra_SetWord(hContact,"Age",(WORD)GetYears(&stTime)); }else{ DB_Mra_DeleteValue(hContact,"BirthYear"); DB_Mra_DeleteValue(hContact,"BirthMonth"); DB_Mra_DeleteValue(hContact,"BirthDay"); DB_Mra_DeleteValue(hContact,"Age"); } }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,pmralpsFeilds[i].lpszData,pmralpsFeilds[i].dwSize,"City_id",7)==CSTR_EQUAL) { dwTemp=StrToUNum32(pmralpsValues[i].lpszData,pmralpsValues[i].dwSize); if (dwTemp) { for(SIZE_T j=0;mrapPlaces[j].lpszData;j++) { if (mrapPlaces[j].dwCityID==dwTemp) { DB_Mra_SetStringW(hContact,"City",mrapPlaces[j].lpszData); break; } } }else{ DB_Mra_DeleteValue(hContact,"City"); } }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,pmralpsFeilds[i].lpszData,pmralpsFeilds[i].dwSize,"Location",8)==CSTR_EQUAL) {//*** DB_Mra_SetLPSStringW(hContact,"About",&pmralpsValues[i]); }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,pmralpsFeilds[i].lpszData,pmralpsFeilds[i].dwSize,"Zodiac",6)==CSTR_EQUAL) { //*** }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,pmralpsFeilds[i].lpszData,pmralpsFeilds[i].dwSize,"BMonth",6)==CSTR_EQUAL) {// used Birthday //if (pmralpsValues[i].dwSize) DB_Mra_SetByte(hContact,"BirthMonth",(BYTE)StrToUNum32(pmralpsValues[i].lpszData,pmralpsValues[i].dwSize)); }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,pmralpsFeilds[i].lpszData,pmralpsFeilds[i].dwSize,"BDay",4)==CSTR_EQUAL) {// used Birthday //if (pmralpsValues[i].dwSize) DB_Mra_SetByte(hContact,"BirthDay",(BYTE)StrToUNum32(pmralpsValues[i].lpszData,pmralpsValues[i].dwSize)); }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,pmralpsFeilds[i].lpszData,pmralpsFeilds[i].dwSize,"Country_id",10)==CSTR_EQUAL) { dwTemp=StrToUNum32(pmralpsValues[i].lpszData,pmralpsValues[i].dwSize); if (dwTemp) { for(SIZE_T j=0;mrapPlaces[j].lpszData;j++) { if (mrapPlaces[j].dwCountryID==dwTemp) { DB_Mra_SetStringW(hContact,"Country",mrapPlaces[j].lpszData); break; } } }else{ DB_Mra_DeleteValue(hContact,"Country"); } }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,pmralpsFeilds[i].lpszData,pmralpsFeilds[i].dwSize,"Phone",5)==CSTR_EQUAL) { DB_Mra_DeleteValue(hContact,"Phone"); DB_Mra_DeleteValue(hContact,"Cellular"); DB_Mra_DeleteValue(hContact,"Fax"); if (pmralpsValues[i].dwSize) { LPSTR lpszCurPos; lpsString.lpszData=pmralpsValues[i].lpszData; lpszCurPos=(LPSTR)MemoryFindByte(0,pmralpsValues[i].lpszData,pmralpsValues[i].dwSize,','); if (lpszCurPos) { lpsString.dwSize=(lpszCurPos-lpsString.lpszData); }else{ lpsString.dwSize=((pmralpsValues[i].lpszData+pmralpsValues[i].dwSize)-lpsString.lpszData); } DB_Mra_SetLPSStringA(hContact,"Phone",&lpsString); if (lpszCurPos) { lpsString.lpszData=(++lpszCurPos); lpszCurPos=(LPSTR)MemoryFindByte((lpszCurPos-pmralpsValues[i].lpszData),pmralpsValues[i].lpszData,pmralpsValues[i].dwSize,','); if (lpszCurPos) { lpsString.dwSize=(lpszCurPos-lpsString.lpszData); }else{ lpsString.dwSize=((pmralpsValues[i].lpszData+pmralpsValues[i].dwSize)-lpsString.lpszData); } DB_Mra_SetLPSStringA(hContact,"Cellular",&lpsString); } if (lpszCurPos) { lpsString.lpszData=(++lpszCurPos); lpszCurPos=(LPSTR)MemoryFindByte((lpszCurPos-pmralpsValues[i].lpszData),pmralpsValues[i].lpszData,pmralpsValues[i].dwSize,','); if (lpszCurPos) { lpsString.dwSize=(lpszCurPos-lpsString.lpszData); }else{ lpsString.dwSize=((pmralpsValues[i].lpszData+pmralpsValues[i].dwSize)-lpsString.lpszData); } DB_Mra_SetLPSStringA(hContact,"Fax",&lpsString); } } }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,pmralpsFeilds[i].lpszData,pmralpsFeilds[i].dwSize,"mrim_status",11)==CSTR_EQUAL) { if (pmralpsValues[i].dwSize) { DWORD dwID,dwContactSeverFlags; GetContactBasicInfoW(hContact,&dwID,NULL,NULL,&dwContactSeverFlags,NULL,NULL,0,NULL,NULL,0,NULL,NULL,0,NULL); if (dwID==-1 || dwContactSeverFlags&CONTACT_INTFLAG_NOT_AUTHORIZED) {// для авторизованного нам и так присылают правильный статус dwStatus=StrHexToUNum32(pmralpsValues[i].lpszData,pmralpsValues[i].dwSize); MraSetContactStatus(hContact,GetMiradaStatusFromMraStatus(dwStatus,MRA_MIR_XSTATUS_NONE,NULL)); DB_Mra_SetByte(hContact,DBSETTING_XSTATUSID,(BYTE)MRA_MIR_XSTATUS_NONE); } } }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,pmralpsFeilds[i].lpszData,pmralpsFeilds[i].dwSize,"status_uri",10)==CSTR_EQUAL) { if (pmralpsValues[i].dwSize) { DWORD dwID,dwContactSeverFlags,dwXStatus; GetContactBasicInfoW(hContact,&dwID,NULL,NULL,&dwContactSeverFlags,NULL,NULL,0,NULL,NULL,0,NULL,NULL,0,NULL); if (dwID==-1 || dwContactSeverFlags&CONTACT_INTFLAG_NOT_AUTHORIZED) {// для авторизованного нам и так присылают правильный статус MraSetContactStatus(hContact,GetMiradaStatusFromMraStatus(dwStatus,GetMraXStatusIDFromMraUriStatus(pmralpsValues[i].lpszData,pmralpsValues[i].dwSize),&dwXStatus)); DB_Mra_SetByte(hContact,DBSETTING_XSTATUSID,(BYTE)dwXStatus); } } }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,pmralpsFeilds[i].lpszData,pmralpsFeilds[i].dwSize,"status_title",12)==CSTR_EQUAL) { if (pmralpsValues[i].dwSize) { DWORD dwID,dwContactSeverFlags; GetContactBasicInfoW(hContact,&dwID,NULL,NULL,&dwContactSeverFlags,NULL,NULL,0,NULL,NULL,0,NULL,NULL,0,NULL); if (dwID==-1 || dwContactSeverFlags&CONTACT_INTFLAG_NOT_AUTHORIZED) {// для авторизованного нам и так присылают правильный статус DB_Mra_SetLPSStringW(hContact,DBSETTING_XSTATUSNAME,&pmralpsValues[i]); } } }else if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,pmralpsFeilds[i].lpszData,pmralpsFeilds[i].dwSize,"status_desc",11)==CSTR_EQUAL) { if (pmralpsValues[i].dwSize) { DWORD dwID,dwContactSeverFlags; GetContactBasicInfoW(hContact,&dwID,NULL,NULL,&dwContactSeverFlags,NULL,NULL,0,NULL,NULL,0,NULL,NULL,0,NULL); if (dwID==-1 || dwContactSeverFlags&CONTACT_INTFLAG_NOT_AUTHORIZED) {// для авторизованного нам и так присылают правильный статус DB_Mra_SetLPSStringW(hContact,DBSETTING_XSTATUSMSG,&pmralpsValues[i]); } } }else{// for DEBUG ONLY #ifdef _DEBUG DebugPrintCRLFA(pmralpsFeilds[i].lpszData); DebugPrintCRLFA(pmralpsValues[i].lpszData); //DebugBreak(); #endif } } }else if (dwAckType==ACKTYPE_SEARCH) { WCHAR szNick[MAX_EMAIL_LEN]={0}, szFirstName[MAX_EMAIL_LEN]={0}, szLastName[MAX_EMAIL_LEN]={0}, szEMail[MAX_EMAIL_LEN]={0}; MRA_LPS mralpsUsernameValue={0}; PROTOSEARCHRESULT psr={0}; psr.cbSize=sizeof(psr); psr.flags=PSR_UNICODE; psr.nick=szNick; psr.firstName=szFirstName; psr.lastName=szLastName; psr.email=szEMail; psr.id=szEMail; for (i=0;iseq,(LPARAM)&psr); } }// end while MEMFREE(pmralpsFeilds); } } switch(dwAckType){ case ACKTYPE_GETINFO: ProtoBroadcastAckAsynchEx(PROTOCOL_NAMEA,hContact,dwAckType,ACKRESULT_SUCCESS,(HANDLE)1,(LPARAM)NULL,0); break; case ACKTYPE_SEARCH: default: ProtoBroadcastAckAsynchEx(PROTOCOL_NAMEA,hContact,dwAckType,ACKRESULT_SUCCESS,(HANDLE)pmaHeader->seq,(LPARAM)NULL,0); break; } break; case MRIM_ANKETA_INFO_STATUS_NOUSER:// не найдено ни одной подходящей записи SetContactBasicInfoW(hContact,0,SCBIF_SERVER_FLAG,0,0,0,-1,0,NULL,0,NULL,0,NULL,0); case MRIM_ANKETA_INFO_STATUS_DBERR:// ошибка базы данных case MRIM_ANKETA_INFO_STATUS_RATELIMERR:// слишком много запросов, поиск временно запрещен switch(dwAckType){ case ACKTYPE_GETINFO: ProtoBroadcastAckAsynchEx(PROTOCOL_NAMEA,hContact,dwAckType,ACKRESULT_FAILED,(HANDLE)1,(LPARAM)NULL,0); break; case ACKTYPE_SEARCH: ProtoBroadcastAckAsynchEx(PROTOCOL_NAMEA,hContact,dwAckType,ACKRESULT_SUCCESS,(HANDLE)pmaHeader->seq,(LPARAM)NULL,0); break; default: DebugBreak(); break; } break; default:// unknown DebugBreak(); break; } MraSendQueueFree(masMraSettings.hSendQueueHandle,pmaHeader->seq); }else{// not found in queue MraPopupShowFromAgentW(MRA_POPUP_TYPE_DEBUG,0,TranslateW(L"MRIM_ANKETA_INFO: not found in queue")); } break; case MRIM_CS_MAILBOX_STATUS: dwTemp=GetUL(&lpbDataCurrent); if (dwTemp > masMraSettings.dwEmailMessagesTotal) masMraSettings.dwEmailMessagesTotal+=(dwTemp-masMraSettings.dwEmailMessagesUnRead); dwAckType=masMraSettings.dwEmailMessagesUnRead;// save old value masMraSettings.dwEmailMessagesUnRead=dwTemp;// store new value if (DB_Mra_GetByte(NULL,"IncrementalNewMailNotify",MRA_DEFAULT_INC_NEW_MAIL_NOTIFY)==0 || dwAckType1)// все параметры правильно инициализированны! //if (dwGroupFlags&CONTACT_FLAG_GROUP && (dwGroupFlags&CONTACT_FLAG_REMOVED)==0) { #ifdef _DEBUG memmove(szBuff,mralpsGroupName.lpszData,mralpsGroupName.dwSize); szBuff[(mralpsGroupName.dwSize/sizeof(WCHAR))]=0; DebugPrintW(szBuff); mir_snprintf((LPSTR)szBuff,SIZEOF(szBuff),": flags: %lu (",dwGroupFlags); DebugPrintA((LPSTR)szBuff); if (dwGroupFlags&CONTACT_FLAG_REMOVED) DebugPrintA("CONTACT_FLAG_REMOVED, "); if (dwGroupFlags&CONTACT_FLAG_GROUP) DebugPrintA("CONTACT_FLAG_GROUP, "); if (dwGroupFlags&CONTACT_FLAG_INVISIBLE) DebugPrintA("CONTACT_FLAG_INVISIBLE, "); if (dwGroupFlags&CONTACT_FLAG_VISIBLE) DebugPrintA("CONTACT_FLAG_VISIBLE, "); if (dwGroupFlags&CONTACT_FLAG_IGNORE) DebugPrintA("CONTACT_FLAG_IGNORE, "); if (dwGroupFlags&CONTACT_FLAG_SHADOW) DebugPrintA("CONTACT_FLAG_SHADOW, "); if (dwGroupFlags&CONTACT_FLAG_AUTHORIZED) DebugPrintA("CONTACT_FLAG_AUTHORIZED, "); if (dwGroupFlags&CONTACT_FLAG_MULTICHAT) DebugPrintA("CONTACT_FLAG_MULTICHAT, "); if (dwGroupFlags&CONTACT_FLAG_UNICODE_NAME) DebugPrintA("CONTACT_FLAG_UNICODE_NAME, "); if (dwGroupFlags&CONTACT_FLAG_PHONE) DebugPrintA("CONTACT_FLAG_PHONE, "); DebugPrintCRLFA(")"); #endif//*/ } dwID++; }// end for (processing groups) DebugPrintCRLFW(L"Contacts:"); DebugPrintCRLFA(szContactMask); dwID=20; while (lpbDataCurrent<(lpbData+dwDataSize)) { dwControlParam=0; for(j=0;j5)// все параметры правильно инициализированны! if ((dwContactFlag&(CONTACT_FLAG_GROUP|CONTACT_FLAG_REMOVED))==0) { hContact=MraHContactFromEmail(lpsEMail.lpszData,lpsEMail.dwSize,TRUE,FALSE,&bAdded); if (hContact) { if (GetContactBasicInfoW(hContact,&dwTemp,NULL,NULL,NULL,NULL,NULL,0,NULL,NULL,0,NULL,NULL,0,NULL)==NO_ERROR && dwTemp!=-1) {//deb контакт уже в списке, нахуй дубликата!!!! dwTemp=dwTemp; //MraSendCommand_ModifyContactW(hContact,dwID,CONTACT_FLAG_REMOVED,dwGroupID,lpsEMail.lpszData,lpsEMail.dwSize,mralpsNick.lpszData,mralpsNick.dwSize,mralpsCustomPhones.lpszData,mralpsCustomPhones.dwSize); DebugBreak(); }else{ dwTemp=GetMiradaStatusFromMraStatus(dwStatus,GetMraXStatusIDFromMraUriStatus(lpsSpecStatusUri.lpszData,lpsSpecStatusUri.dwSize),&dwXStatus); if((dwContactFlag&CONTACT_FLAG_UNICODE_NAME)) mralpsNick.dwSize/=sizeof(WCHAR); if (bAdded) {// update user info SetContactBasicInfoW(hContact,SCBIFSI_LOCK_CHANGES_EVENTS,(SCBIF_ID|SCBIF_GROUP_ID|SCBIF_FLAG|SCBIF_SERVER_FLAG|SCBIF_STATUS|SCBIF_NICK|SCBIF_PHONES),dwID,dwGroupID,dwContactFlag,dwContactSeverFlags,dwTemp,NULL,0,mralpsNick.lpwszData,mralpsNick.dwSize,mralpsCustomPhones.lpszData,mralpsCustomPhones.dwSize); // request user info from server MraUpdateContactInfo(hContact); }else{//****deb - check group ID param SetContactBasicInfoW(hContact,SCBIFSI_LOCK_CHANGES_EVENTS,(SCBIF_ID|SCBIF_GROUP_ID|SCBIF_SERVER_FLAG|SCBIF_STATUS),dwID,dwGroupID,dwContactFlag,dwContactSeverFlags,dwTemp,NULL,0,mralpsNick.lpwszData,mralpsNick.dwSize,mralpsCustomPhones.lpszData,mralpsCustomPhones.dwSize); if (mralpsNick.dwSize==0) {// прописываем ник в листе на сервере lstrcpynW(szBuff,GetContactNameW(hContact),SIZEOF(szBuff)); mralpsNick.lpwszData=szBuff; mralpsNick.dwSize=lstrlenW(mralpsNick.lpwszData); MraSendCommand_ModifyContactW(hContact,dwID,dwContactFlag,dwGroupID,lpsEMail.lpszData,lpsEMail.dwSize,mralpsNick.lpwszData,mralpsNick.dwSize,mralpsCustomPhones.lpszData,mralpsCustomPhones.dwSize); } } MraContactCapabilitiesSet(hContact,dwFutureFlags); DB_Mra_SetByte(hContact,DBSETTING_XSTATUSID,(BYTE)dwXStatus); DB_Mra_SetLPSStringW(hContact,DBSETTING_XSTATUSNAME,&lpsStatusTitle); DB_Mra_SetLPSStringW(hContact,DBSETTING_XSTATUSMSG,&lpsStatusDesc); DB_Mra_SetDword(hContact,DBSETTING_BLOGSTATUSTIME,dwBlogStatusTime); DB_Mra_WriteContactSettingBlob(hContact,DBSETTING_BLOGSTATUSID,&dwBlogStatusID.QuadPart,sizeof(DWORDLONG)); DB_Mra_SetLPSStringW(hContact,DBSETTING_BLOGSTATUS,&lpsBlogStatus); DB_Mra_SetLPSStringW(hContact,DBSETTING_BLOGSTATUSMUSIC,&lpsBlogStatusMusic); if (IsXStatusValid(dwXStatus)) SetExtraIcons(hContact); if (dwTemp!=ID_STATUS_OFFLINE)// пишем клиента только если юзер не отключён, иначе не затираем старое { if (lpsUserAgentFormated.dwSize) {// есть чё писать if (DB_Mra_GetByte(NULL,"MirVerRaw",MRA_DEFAULT_MIRVER_RAW)==FALSE) { MraGetVersionStringFromFormated(lpsUserAgentFormated.lpszData,lpsUserAgentFormated.dwSize,(LPSTR)szBuff,SIZEOF(szBuff),&dwStringSize); lpsUserAgentFormated.lpszData=(LPSTR)szBuff; lpsUserAgentFormated.dwSize=dwStringSize; } }else{// хз чё за клиент lpsUserAgentFormated.lpszData=MIRVER_UNKNOWN; lpsUserAgentFormated.dwSize=(sizeof(MIRVER_UNKNOWN)-1); } DB_Mra_SetLPSStringA(hContact,"MirVer",&lpsUserAgentFormated); } if (dwContactSeverFlags&CONTACT_INTFLAG_NOT_AUTHORIZED) if (DB_Mra_GetByte(NULL,"AutoAuthRequestOnLogon",MRA_DEFAULT_AUTO_AUTH_REQ_ON_LOGON)) CallProtoService(PROTOCOL_NAMEA,MRA_REQ_AUTH,(WPARAM)hContact,0); } } } dwID++; }// end while (processing contacts) // post processing contact list { CHAR szEMail[MAX_EMAIL_LEN],szPhones[MAX_EMAIL_LEN]; WCHAR wszAuthMessage[MAX_PATH],wszNick[MAX_EMAIL_LEN]; SIZE_T dwEMailSize,dwNickSize,dwPhonesSize,dwAuthMessageSize; if (DB_Mra_GetStaticStringW(NULL,"AuthMessage",wszAuthMessage,SIZEOF(wszAuthMessage),&dwAuthMessageSize)==FALSE) {// def auth message lstrcpynW(wszAuthMessage,TranslateW(MRA_DEFAULT_AUTH_MESSAGE),SIZEOF(wszAuthMessage)); dwAuthMessageSize=lstrlenW(wszAuthMessage); } for(hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);hContact!=NULL;hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0)) { if (GetContactBasicInfoW(hContact,&dwID,NULL,NULL,NULL,NULL,szEMail,SIZEOF(szEMail),&dwEMailSize,NULL,0,NULL,NULL,0,NULL)==NO_ERROR) if (dwID==-1) { if (IsEMailChatAgent(szEMail,dwEMailSize)) {// чат: ещё раз запросим авторизацию, пометим как видимый в списке, постоянный DBDeleteContactSetting(hContact,"CList","Hidden"); DBDeleteContactSetting(hContact,"CList","NotOnList"); SetExtraIcons(hContact); MraSetContactStatus(hContact,ID_STATUS_ONLINE); lstrcpynW(szBuff,GetContactNameW(hContact),SIZEOF(szBuff)); MraSendCommand_AddContactW(hContact,(CONTACT_FLAG_VISIBLE|CONTACT_FLAG_MULTICHAT|CONTACT_FLAG_UNICODE_NAME),-1,szEMail,dwEMailSize,szBuff,lstrlenW(szBuff),NULL,0,NULL,0,0); }else{ if (DBGetContactSettingByte(hContact,"CList","NotOnList",0)==0) {// set extra icons and upload contact SetExtraIcons(hContact); if (DB_Mra_GetByte(NULL,"AutoAddContactsToServer",MRA_DEFAULT_AUTO_ADD_CONTACTS_TO_SERVER)) {//add all contacts to server GetContactBasicInfoW(hContact,NULL,&dwGroupID,NULL,NULL,NULL,NULL,0,NULL,wszNick,SIZEOF(wszNick),&dwNickSize,szPhones,SIZEOF(szPhones),&dwPhonesSize); MraSendCommand_AddContactW(hContact,(CONTACT_FLAG_VISIBLE|CONTACT_FLAG_UNICODE_NAME),dwGroupID,szEMail,dwEMailSize,wszNick,dwNickSize,szPhones,dwPhonesSize,wszAuthMessage,dwAuthMessageSize,0); } } } MraUpdateContactInfo(hContact); } } } }else{// контакт лист почемуто не получили // всех в offline и id в нестандарт for(HANDLE hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);hContact!=NULL;hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0)) {// функция сама проверяет принадлежность контакта к MRA SetContactBasicInfoW(hContact,SCBIFSI_LOCK_CHANGES_EVENTS,(SCBIF_ID|SCBIF_GROUP_ID|SCBIF_SERVER_FLAG|SCBIF_STATUS),-1,-2,0,0,ID_STATUS_OFFLINE,NULL,0,NULL,0,NULL,0); // request user info from server MraUpdateContactInfo(hContact); } if (dwTemp==GET_CONTACTS_ERROR) {// найденный контакт-лист некорректен ShowFormatedErrorMessage(L"MRIM_CS_CONTACT_LIST2: bad contact list",NO_ERROR); }else if (dwTemp==GET_CONTACTS_INTERR) {// произошла внутренняя ошибка ShowFormatedErrorMessage(L"MRIM_CS_CONTACT_LIST2: internal server error",NO_ERROR); }else{ mir_sntprintf(szBuff,SIZEOF(szBuff),TranslateW(L"MRIM_CS_CONTACT_LIST2: unknown server error, code: %lu"),dwTemp); MraPopupShowFromAgentW(MRA_POPUP_TYPE_DEBUG,0,szBuff); } } break; case MRIM_CS_SMS_ACK: dwTemp=GetUL(&lpbDataCurrent); if (MraSendQueueFind(masMraSettings.hSendQueueHandle,pmaHeader->seq,NULL,&hContact,&dwAckType,(LPBYTE*)&lpsString.lpszData,&lpsString.dwSize)==NO_ERROR) { char szEMail[MAX_EMAIL_LEN]; LPSTR lpszPhone; LPWSTR lpwszMessage; SIZE_T dwEMailSize,dwPhoneSize,dwMessageSize; if (DB_Mra_GetStaticStringA(NULL,"e-mail",szEMail,SIZEOF(szEMail),&dwEMailSize)) { dwPhoneSize=(*(DWORD*)lpsString.lpszData); dwMessageSize=lpsString.dwSize-(dwPhoneSize+sizeof(DWORD)+2); lpszPhone=(lpsString.lpszData+sizeof(DWORD)); lpwszMessage=(LPWSTR)(lpszPhone+dwPhoneSize+1); dwTemp=mir_snprintf((LPSTR)szBuff,SIZEOF(szBuff),"Mail.ruYesMail.ru, Russia%s-1-1955988055-%s%s0\r\n",szEMail,lpszPhone,lpszPhone); ProtoBroadcastAckAsynchEx(PROTOCOL_NAMEA,NULL,dwAckType,ACKRESULT_SENTREQUEST,(HANDLE)pmaHeader->seq,(LPARAM)szBuff,dwTemp); } MEMFREE(lpsString.lpszData); MraSendQueueFree(masMraSettings.hSendQueueHandle,pmaHeader->seq); }else{// not found in queue MraPopupShowFromAgentW(MRA_POPUP_TYPE_DEBUG,0,TranslateW(L"MRIM_CS_SMS_ACK: not found in queue")); } break; case MRIM_CS_PROXY: { DWORD dwIDRequest; MRA_LPS lpsAddreses={0}; MRA_GUID mguidSessionID; GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsEMail);// LPS to dwIDRequest=GetUL(&lpbDataCurrent);// DWORD id_request dwAckType=GetUL(&lpbDataCurrent);// DWORD data_type GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString);// LPS user_data GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsAddreses);// LPS lps_ip_port mguidSessionID=GetGUID(&lpbDataCurrent);// DWORD session_id[4] if (dwAckType==MRIM_PROXY_TYPE_FILES) {// файлы, on file recv if (MraMrimProxySetData(MraFilesQueueItemProxyByID(masMraSettings.hFilesQueueHandle,dwIDRequest),lpsEMail.lpszData,lpsEMail.dwSize,dwIDRequest,dwAckType,lpsString.lpszData,lpsString.dwSize,lpsAddreses.lpszData,lpsAddreses.dwSize,&mguidSessionID)==NO_ERROR) {// сессия передачи ещё жива/proxy enabled// set proxy info to file transfer context MraFilesQueueStartMrimProxy(masMraSettings.hFilesQueueHandle,dwIDRequest); }else{// дохлая сессия/не существующая MraSendCommand_ProxyAck(PROXY_STATUS_ERROR,lpsEMail.lpszData,lpsEMail.dwSize,dwIDRequest,dwAckType,lpsString.lpszData,lpsString.dwSize,lpsAddreses.lpszData,lpsAddreses.dwSize,mguidSessionID); DebugBreak(); } } //DebugBreak(); } break; case MRIM_CS_PROXY_ACK: { DWORD dwIDRequest; HANDLE hMraMrimProxyData; MRA_LPS lpsAddreses={0}; MRA_GUID mguidSessionID; dwTemp=GetUL(&lpbDataCurrent);// DWORD status GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsEMail);// LPS to dwIDRequest=GetUL(&lpbDataCurrent);// DWORD id_request dwAckType=GetUL(&lpbDataCurrent);// DWORD data_type GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString);// LPS user_data GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsAddreses);// LPS lps_ip_port mguidSessionID=GetGUID(&lpbDataCurrent);// DWORD session_id[4] if (dwAckType==MRIM_PROXY_TYPE_FILES) {// файлы, on file send if ((hMraMrimProxyData=MraFilesQueueItemProxyByID(masMraSettings.hFilesQueueHandle,dwIDRequest))) {// сессия передачи ещё жива/proxy enabled switch(dwTemp){ case PROXY_STATUS_DECLINE: MraFilesQueueCancel(masMraSettings.hFilesQueueHandle,dwIDRequest,FALSE); break; case PROXY_STATUS_OK: if (MraMrimProxySetData(hMraMrimProxyData,lpsEMail.lpszData,lpsEMail.dwSize,dwIDRequest,dwAckType,lpsString.lpszData,lpsString.dwSize,lpsAddreses.lpszData,lpsAddreses.dwSize,&mguidSessionID)==NO_ERROR) {// set proxy info to file transfer context MraFilesQueueStartMrimProxy(masMraSettings.hFilesQueueHandle,dwIDRequest); } break; case PROXY_STATUS_ERROR: ShowFormatedErrorMessage(L"Proxy File transfer: error",NO_ERROR); MraFilesQueueCancel(masMraSettings.hFilesQueueHandle,dwIDRequest,FALSE); break; case PROXY_STATUS_INCOMPATIBLE_VERS: ShowFormatedErrorMessage(L"Proxy File transfer: incompatible versions",NO_ERROR); MraFilesQueueCancel(masMraSettings.hFilesQueueHandle,dwIDRequest,FALSE); break; case PROXY_STATUS_NOHARDWARE: case PROXY_STATUS_MIRROR: case PROXY_STATUS_CLOSED: default: DebugBreak(); break; } }else{// дохлая сессия/не существующая DebugBreak(); } } /*if (dwTemp!=2) if ((hContact=MraHContactFromEmail(lpsEMail.lpszData,lpsEMail.dwSize,FALSE,TRUE,NULL))) if (MraGetContactStatus(hContact)==ID_STATUS_OFFLINE) { MraSetContactStatus(hContact,ID_STATUS_INVISIBLE); }*/ //DebugBreak(); } break; case MRIM_CS_PROXY_HELLO: // DWORD[4] Session_id DebugBreak(); break; case MRIM_CS_PROXY_HELLO_ACK: DebugBreak(); break; case MRIM_CS_NEW_MAIL: { DWORD dwDate,dwUIDL; dwTemp=GetUL(&lpbDataCurrent);// UL unread count GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsEMail);// LPS from GetLPS(lpbData,dwDataSize,&lpbDataCurrent,&lpsString);// LPS subject dwDate=GetUL(&lpbDataCurrent);// UL date dwUIDL=GetUL(&lpbDataCurrent);// UL uidl if (dwTemp > masMraSettings.dwEmailMessagesTotal) masMraSettings.dwEmailMessagesTotal+=(dwTemp-masMraSettings.dwEmailMessagesUnRead); dwAckType=masMraSettings.dwEmailMessagesUnRead;// save old value masMraSettings.dwEmailMessagesUnRead=dwTemp;// store new value if (DB_Mra_GetByte(NULL,"IncrementalNewMailNotify",MRA_DEFAULT_INC_NEW_MAIL_NOTIFY)==0 || dwAckTypelpszData==NULL || plpsRFTText->dwSize==0) dwFlags&=~MESSAGE_FLAG_RTF; }else{ dwFlags&=~MESSAGE_FLAG_RTF; } } if (dwFlags&MESSAGE_FLAG_MULTICHAT) { if (plpsMultiChatData) { if (plpsMultiChatData->lpszData==NULL || plpsMultiChatData->dwSize==0) dwFlags&=~MESSAGE_FLAG_MULTICHAT; }else{ dwFlags&=~MESSAGE_FLAG_MULTICHAT; } } // pre processing - extracting/decoding if (dwFlags&MESSAGE_FLAG_AUTHORIZE) {// extract auth message из обычного текста SIZE_T dwAuthPartsCount,dwAuthBuffSize=(plpsText->dwSize+32),dwAuthDataSize; LPBYTE lpbAuthData,lpbDataCurrent; MRA_LPS lpsAuthFrom,lpsAuthMessage; lpbAuthData=(LPBYTE)MEMALLOC(dwAuthBuffSize); if (lpbAuthData) { BASE64DecodeFormated(plpsText->lpszData,plpsText->dwSize,lpbAuthData,dwAuthBuffSize,&dwAuthDataSize); lpbDataCurrent=lpbAuthData; dwAuthPartsCount=GetUL(&lpbDataCurrent); if (GetLPS(lpbAuthData,dwAuthDataSize,&lpbDataCurrent,&lpsAuthFrom)==NO_ERROR) if (GetLPS(lpbAuthData,dwAuthDataSize,&lpbDataCurrent,&lpsAuthMessage)==NO_ERROR) { if (dwFlags&MESSAGE_FLAG_v1p16 && (dwFlags&MESSAGE_FLAG_CP1251)==0) {// unicode text memmove(lpbAuthData,lpsAuthMessage.lpszData,lpsAuthMessage.dwSize); lpwszMessage=(LPWSTR)lpbAuthData; dwMessageSize=(lpsAuthMessage.dwSize/sizeof(WCHAR)); }else{// преобразуем в юникод текст только если он в АНСИ и если это не Флэш мультик и будильник тоже не нуждается в этом lpwszMessage=(LPWSTR)MEMALLOC(((lpsAuthMessage.dwSize+MAX_PATH)*sizeof(WCHAR))); if (lpwszMessage) { dwMessageSize=MultiByteToWideChar(MRA_CODE_PAGE,0,lpsAuthMessage.lpszData,lpsAuthMessage.dwSize,lpwszMessage,(lpsAuthMessage.dwSize+MAX_PATH)); (*(lpwszMessage+dwMessageSize))=0; }else{// не удалось выделить память dwRetErrorCode=GetLastError(); } } } if (lpwszMessage!=(LPWSTR)lpbAuthData) MEMFREE(lpbAuthData); } }else{ /*// пупер затычка if (dwFlags&MESSAGE_FLAG_v1p16 && dwFlags&MESSAGE_FLAG_CP1251) {// и какая же кодировка у текста...мммм...бум гадать! DebugPrintW(L"Unknown message encoding: "); if (MemoryFindByte(0,plpsText->lpszData,(plpsText->dwSize-1),0)) {//ооо похоже это юникод! dwFlags&=~MESSAGE_FLAG_CP1251; DebugPrintCRLFW(plpsText->lpwszData); }else{// наверное анси dwFlags&=~MESSAGE_FLAG_v1p16; DebugPrintCRLFA(plpsText->lpszData); } }*/ if (dwFlags&(MESSAGE_FLAG_ALARM|MESSAGE_FLAG_FLASH|MESSAGE_FLAG_v1p16) && (dwFlags&MESSAGE_FLAG_CP1251)==0) {// unicode text lpwszMessage=plpsText->lpwszData; dwMessageSize=(plpsText->dwSize/sizeof(WCHAR)); }else{// преобразуем в юникод текст только если он в АНСИ и если это не Флэш мультик и будильник тоже не нуждается в этом lpwszMessage=(LPWSTR)MEMALLOC(((plpsText->dwSize+MAX_PATH)*sizeof(WCHAR))); if (lpwszMessage) { dwMessageSize=MultiByteToWideChar(MRA_CODE_PAGE,0,plpsText->lpszData,plpsText->dwSize,lpwszMessage,(plpsText->dwSize+MAX_PATH)); (*(lpwszMessage+dwMessageSize))=0; }else{// не удалось выделить память dwRetErrorCode=GetLastError(); } } if (dwFlags&(MESSAGE_FLAG_CONTACT|MESSAGE_FLAG_NOTIFY|MESSAGE_FLAG_SMS|MESSAGE_SMS_DELIVERY_REPORT|MESSAGE_FLAG_ALARM)) { // ничего не делаем, сообщение не содержит расширенной части или её содержимое игнорируется }else{ if ((dwFlags&MESSAGE_FLAG_RTF) && plpsRFTText) //MESSAGE_FLAG_FLASH there if (masMraSettings.lpfnUncompress)// only if uncompress function exist if (plpsRFTText->lpszData && plpsRFTText->dwSize) {// decode RTF SIZE_T dwRTFPartsCount,dwCompressedSize,dwRFTBuffSize=((plpsRFTText->dwSize*16)+8192),dwRTFDataSize; LPBYTE lpbRTFData,lpbCompressed,lpbDataCurrent; MRA_LPS lpsRTFString,lpsBackColour,lpsString; lpbRTFData=(LPBYTE)MEMALLOC(dwRFTBuffSize); lpbCompressed=(LPBYTE)MEMALLOC((plpsRFTText->dwSize+32)); if (lpbRTFData && lpbCompressed) { BASE64DecodeFormated(plpsRFTText->lpszData,plpsRFTText->dwSize,lpbCompressed,(plpsRFTText->dwSize+32),&dwCompressedSize); dwRTFDataSize=dwRFTBuffSize; if ((PUNCOMPRESS(masMraSettings.lpfnUncompress))(lpbRTFData,(DWORD*)&dwRTFDataSize,lpbCompressed,dwCompressedSize)==Z_OK) { lpbDataCurrent=lpbRTFData; dwRTFPartsCount=GetUL(&lpbDataCurrent);// колличество частей в некоторых случаях больше 2, тогда нужно игнорировать первый текст, тк там сообщения об ущербности if (GetLPS(lpbRTFData,dwRTFDataSize,&lpbDataCurrent,&lpsRTFString)==NO_ERROR) if (GetLPS(lpbRTFData,dwRTFDataSize,&lpbDataCurrent,&lpsBackColour)==NO_ERROR) { dwBackColour=(*(DWORD*)lpsBackColour.lpszData); if (dwFlags&MESSAGE_FLAG_FLASH) {// Флэш мультик в обычный текст// затирем lpwszMessage=plpsText->lpwszData, тк там затычка с текстом об ущербности if (dwRTFPartsCount==3) {// только анси текст с мультиком DebugBreak();// наверное это уже не должно приходить, ну разве что от совсем старых клиентов, 2008 GetLPS(lpbRTFData,dwRTFDataSize,&lpbDataCurrent,&lpsString); lpwszMessage=(LPWSTR)MEMALLOC(((lpsString.dwSize+MAX_PATH)*sizeof(WCHAR))); if (lpwszMessage) { memmove(lpwszMessage,lpsString.lpszData,lpsString.dwSize); dwMessageSize=MultiByteToWideChar(MRA_CODE_PAGE,0,lpsString.lpszData,lpsString.dwSize,lpwszMessage,(lpsString.dwSize+MAX_PATH)); (*(lpwszMessage+dwMessageSize))=0; }else{// не удалось выделить память dwRetErrorCode=GetLastError(); } }else if (dwRTFPartsCount==4) { GetLPS(lpbRTFData,dwRTFDataSize,&lpbDataCurrent,&lpsString); GetLPS(lpbRTFData,dwRTFDataSize,&lpbDataCurrent,&lpsString); lpwszMessage=(LPWSTR)MEMALLOC(lpsString.dwSize); if (lpwszMessage) { memmove(lpwszMessage,lpsString.lpszData,lpsString.dwSize); dwMessageSize=lpsString.dwSize; }else{// не удалось выделить память dwRetErrorCode=GetLastError(); } }else{ DebugBreak(); } }else{// РТФ текст if (dwRTFPartsCount>2) { GetLPS(lpbRTFData,dwRTFDataSize,&lpbDataCurrent,&lpsString); DebugBreak(); } lpszMessageExt=(LPSTR)MEMALLOC(lpsRTFString.dwSize); if (lpszMessageExt) { memmove(lpszMessageExt,lpsRTFString.lpszData,lpsRTFString.dwSize); dwMessageExtSize=lpsRTFString.dwSize; }else{// не удалось выделить память //dwRetErrorCode=GetLastError(); // не смертельно! DebugBreak(); } } } }else{ MEMFREE(lpszMessageExt); dwMessageExtSize=0; DebugBreak(); } } MEMFREE(lpbCompressed); MEMFREE(lpbRTFData); } } } // processing if (dwRetErrorCode==NO_ERROR) if (MraAntiSpamReceivedMessageW(plpsFrom->lpszData,plpsFrom->dwSize,dwFlags,lpwszMessage,dwMessageSize)==MESSAGE_NOT_SPAM) { if (dwFlags&(MESSAGE_FLAG_SMS|MESSAGE_SMS_DELIVERY_REPORT)) {// SMS //if (IsPhone(plpsFrom->lpszData,plpsFrom->dwSize)) char szPhone[MAX_EMAIL_LEN],szEMail[MAX_EMAIL_LEN],szTime[MAX_PATH]; LPSTR lpszMessageUTF,lpszBuff; LPWSTR lpwszMessageXMLEncoded; SIZE_T dwBuffLen,dwMessageXMLEncodedSize; INTERNET_TIME itTime; dwBuffLen=((dwMessageSize+MAX_PATH)*6); lpszMessageUTF=(LPSTR)MEMALLOC(dwBuffLen); lpwszMessageXMLEncoded=(LPWSTR)MEMALLOC((dwBuffLen*sizeof(WCHAR))); if (lpszMessageUTF && lpwszMessageXMLEncoded) { InternetTimeGetCurrentTime(&itTime); InternetTimeGetString(&itTime,szTime,SIZEOF(szTime),NULL); CopyNumber(szPhone,plpsFrom->lpszData,plpsFrom->dwSize); DB_Mra_GetStaticStringA(NULL,"e-mail",szEMail,SIZEOF(szEMail),NULL); EncodeXML(lpwszMessage,dwMessageSize,lpwszMessageXMLEncoded,dwBuffLen,&dwMessageXMLEncodedSize); WideCharToMultiByte(CP_UTF8,0,lpwszMessageXMLEncoded,dwMessageXMLEncodedSize,lpszMessageUTF,dwBuffLen,NULL,NULL); lpszBuff=(LPSTR)lpwszMessageXMLEncoded; if (dwFlags&MESSAGE_SMS_DELIVERY_REPORT) {// отчёт о неудаче доставки смс dwBuffLen=mir_snprintf(lpszBuff,(dwBuffLen*sizeof(WCHAR)),"%s-1-1955988055-%s%sNo%s015%s",szEMail,szPhone,szPhone,szTime,lpszMessageUTF); ProtoBroadcastAckAsynchEx(PROTOCOL_NAMEA,NULL,ICQACKTYPE_SMS,ACKRESULT_FAILED,(HANDLE)0,(LPARAM)lpszBuff,dwBuffLen); }else{// новое смс!!! dwBuffLen=mir_snprintf(lpszBuff,(dwBuffLen*sizeof(WCHAR)),"Mail.ru%s%sMail.ru%s",szEMail,szPhone,lpszMessageUTF,szTime); ProtoBroadcastAckAsynchEx(PROTOCOL_NAMEA,NULL,ICQACKTYPE_SMS,ACKRESULT_SUCCESS,(HANDLE)0,(LPARAM)lpszBuff,dwBuffLen); } }else{// не удалось выделить память dwRetErrorCode=GetLastError(); } MEMFREE(lpwszMessageXMLEncoded); MEMFREE(lpszMessageUTF); }else{ ccs.hContact=MraHContactFromEmail(plpsFrom->lpszData,plpsFrom->dwSize,TRUE,TRUE,&bAdded); if (bAdded) MraUpdateContactInfo(ccs.hContact); if (dwFlags&MESSAGE_FLAG_NOTIFY) {// user typing CallService(MS_PROTO_CONTACTISTYPING,(WPARAM)ccs.hContact,MAILRU_CONTACTISTYPING_TIMEOUT); }else{// text/contact/auth // typing OFF CallService(MS_PROTO_CONTACTISTYPING,(WPARAM)ccs.hContact,PROTOTYPE_CONTACTTYPING_OFF); if (dwFlags&MESSAGE_FLAG_MULTICHAT) {// MULTICHAT LPBYTE lpbMultiChatData,lpbDataCurrent; SIZE_T dwMultiChatDataSize; DWORD dwMultiChatEventType; MRA_LPS lpsEMailInMultiChat,lpsString,lpsMultichatName; lpbMultiChatData=(LPBYTE)plpsMultiChatData->lpszData; dwMultiChatDataSize=plpsMultiChatData->dwSize; lpbDataCurrent=lpbMultiChatData; dwMultiChatEventType=GetUL(&lpbDataCurrent);// type GetLPS(lpbMultiChatData,dwMultiChatDataSize,&lpbDataCurrent,&lpsMultichatName);// multichat_name GetLPS(lpbMultiChatData,dwMultiChatDataSize,&lpbDataCurrent,&lpsEMailInMultiChat); switch(dwMultiChatEventType){ case MULTICHAT_MESSAGE: MraChatSessionMessageAdd(ccs.hContact,lpsEMailInMultiChat.lpszData,lpsEMailInMultiChat.dwSize,lpwszMessage,dwMessageSize,dwTime);// LPS sender break; case MULTICHAT_ADD_MEMBERS: MraChatSessionMembersAdd(ccs.hContact,lpsEMailInMultiChat.lpszData,lpsEMailInMultiChat.dwSize,dwTime);// LPS sender GetLPS(lpbMultiChatData,dwMultiChatDataSize,&lpbDataCurrent,&lpsString);// CLPS members MraChatSessionSetIviter(ccs.hContact,lpsEMailInMultiChat.lpszData,lpsEMailInMultiChat.dwSize); case MULTICHAT_MEMBERS: { LPBYTE lpbMultiChatDataLocal,lpbDataCurrentLocal; SIZE_T i,dwMultiChatMembersCount,dwMultiChatDataLocalSize; if (dwMultiChatEventType==MULTICHAT_MEMBERS) lpsString=lpsEMailInMultiChat; lpbMultiChatDataLocal=(LPBYTE)lpsString.lpszData; dwMultiChatDataLocalSize=lpsString.dwSize; lpbDataCurrentLocal=lpbMultiChatDataLocal; dwMultiChatMembersCount=GetUL(&lpbDataCurrentLocal);// count for (i=0;ilpszData,plpsFrom->dwSize,lpsMultichatName.lpwszData,(lpsMultichatName.dwSize/sizeof(WCHAR)),NULL,0,NULL,0,0); break; default: DebugBreak(); break; } }else if (dwFlags&MESSAGE_FLAG_AUTHORIZE) {// auth request BYTE btBuff[BUFF_SIZE_BLOB]; BOOL bAutoGrandAuth=FALSE; if (IsEMailChatAgent(plpsFrom->lpszData,plpsFrom->dwSize)) { bAutoGrandAuth=FALSE; }else{ if (DBGetContactSettingByte(ccs.hContact,"CList","NotOnList",0)) {// временный контакт if (DB_Mra_GetByte(NULL,"AutoAuthGrandNewUsers",MRA_DEFAULT_AUTO_AUTH_GRAND_NEW_USERS)) bAutoGrandAuth=TRUE; }else{// постоянный контакт if (DB_Mra_GetByte(NULL,"AutoAuthGrandUsersInCList",MRA_DEFAULT_AUTO_AUTH_GRAND_IN_CLIST)) bAutoGrandAuth=TRUE; } } if (bAdded) DBWriteContactSettingByte(ccs.hContact,"CList","Hidden",1); if (bAutoGrandAuth) {// auto grand auth DBEVENTINFO dbei={0}; dbei.cbSize=sizeof(dbei); dbei.szModule=PROTOCOL_NAMEA; dbei.timestamp=_time32(NULL); dbei.flags=DBEF_READ; dbei.eventType=EVENTTYPE_AUTHREQUEST; dbei.pBlob=(PBYTE)btBuff; CreateBlobFromContact(ccs.hContact,lpwszMessage,dwMessageSize,btBuff,SIZEOF(btBuff),(SIZE_T*)&dbei.cbBlob); CallService(MS_DB_EVENT_ADD,(WPARAM)NULL,(LPARAM)&dbei); MraSendCommand_Authorize(plpsFrom->lpszData,plpsFrom->dwSize); }else{ ccs.szProtoService=PSR_AUTH; pre.szMessage=(LPSTR)btBuff; CreateBlobFromContact(ccs.hContact,lpwszMessage,dwMessageSize,btBuff,SIZEOF(btBuff),(SIZE_T*)&pre.lParam); CallService(MS_PROTO_CHAINRECV,0,(LPARAM)&ccs); } }else{ DBDeleteContactSetting(ccs.hContact,"CList","Hidden"); if (dwFlags&MESSAGE_FLAG_CONTACT) {// contacts received LPBYTE lpbBuffer,lpbBufferCurPos; lpbBuffer=(LPBYTE)MEMALLOC((dwMessageSize+MAX_PATH)); if (lpbBuffer) { ccs.szProtoService=PSR_CONTACTS; pre.flags=0; pre.szMessage=(LPSTR)lpbBuffer; pre.lParam=WideCharToMultiByte(MRA_CODE_PAGE,0,lpwszMessage,dwMessageSize,(LPSTR)lpbBuffer,(dwMessageSize+MAX_PATH),NULL,NULL); lpbBufferCurPos=lpbBuffer; while(TRUE) {// цикл замены ; на 0 lpbBufferCurPos=(LPBYTE)MemoryFindByte((lpbBufferCurPos-lpbBuffer),lpbBuffer,pre.lParam,';'); if (lpbBufferCurPos) {// founded (*lpbBufferCurPos)=0; lpbBufferCurPos++; }else{ break; } } CallService(MS_PROTO_CHAINRECV,0,(LPARAM)&ccs); MEMFREE(lpbBuffer); }else{// не удалось выделить память dwRetErrorCode=GetLastError(); } }else if (dwFlags&MESSAGE_FLAG_ALARM) {// alarm if (masMraSettings.heNudgeReceived) { NotifyEventHooks(masMraSettings.heNudgeReceived,(WPARAM)ccs.hContact,NULL); }else{ pre.flags=0; pre.szMessage=(LPSTR)TranslateTS(MRA_ALARM_MESSAGE); //pre.lParam=lstrlenA(pre.szMessage); ccs.szProtoService=PSR_MESSAGE; CallService(MS_PROTO_CHAINRECV,0,(LPARAM)&ccs); } }else{// standart message// flash animation if ((dwFlags&MESSAGE_FLAG_RTF) && (dwFlags&MESSAGE_FLAG_FLASH)==0 && lpszMessageExt && dwMessageExtSize && DB_Mra_GetByte(NULL,"RTFReceiveEnable",MRA_DEFAULT_RTF_RECEIVE_ENABLE)) {// пишем в ANSI, всё равно RTF pre.flags=0; pre.szMessage=lpszMessageExt; //pre.lParam=dwMessageExtSize; ccs.szProtoService=PSR_MESSAGE; CallService(MS_PROTO_CHAINRECV,0,(LPARAM)&ccs); }else{ LPSTR lpszMessageUTF;// some plugins can change pre.szMessage pointer and we failed to free it lpszMessageUTF=(LPSTR)MEMALLOC(((dwMessageSize+MAX_PATH)*sizeof(WCHAR))); if (lpszMessageUTF) { pre.szMessage=lpszMessageUTF; pre.flags=PREF_UTF; //pre.lParam= WideCharToMultiByte(CP_UTF8,0,lpwszMessage,dwMessageSize,lpszMessageUTF,((dwMessageSize+MAX_PATH)*sizeof(WCHAR)),NULL,NULL); ccs.szProtoService=PSR_MESSAGE; CallService(MS_PROTO_CHAINRECV,0,(LPARAM)&ccs); MEMFREE(lpszMessageUTF); }else{// не удалось выделить память dwRetErrorCode=GetLastError(); } } if (dwFlags&MESSAGE_FLAG_SYSTEM) { MraPopupShowW(ccs.hContact,MRA_POPUP_TYPE_INFORMATION,0,TranslateW(L"Mail.ru System notify"),(LPWSTR)pre.szMessage); } } } } } }else{// spam blocked if (DB_Mra_GetByte(NULL,"AntiSpamSendSpamReportToSrv",MRA_ANTISPAM_DEFAULT_SEND_SPAM_REPORT_TO_SERVER)) {// рапортуем о спаме //MraSendCommand_MessageAskW(1,(dwFlags|MESSAGE_FLAG_SPAMF_SPAM),plpsFrom->lpszData,plpsFrom->dwSize,plpsText->lpwszData,plpsText->dwSize,plpsRFTText->lpszData,plpsRFTText->dwSize); } dwRetErrorCode=ERROR_ACCESS_DENIED; } if (lpwszMessage!=plpsText->lpwszData && lpwszMessage!=(LPWSTR)lpszMessageExt) MEMFREE(lpwszMessage); MEMFREE(lpszMessageExt); return(dwRetErrorCode); } DWORD GetMraXStatusIDFromMraUriStatus(LPSTR lpszStatusUri,SIZE_T dwStatusUriSize) { DWORD dwRet=MRA_XSTATUS_UNKNOWN; if (lpszStatusUri) { for(SIZE_T i=0;lpcszStatusUri[i];i++) { if (CompareStringA(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NORM_IGNORECASE,lpcszStatusUri[i],-1,lpszStatusUri,dwStatusUriSize)==CSTR_EQUAL) { dwRet=i; break; } } } return(dwRet); } DWORD GetMraStatusFromMiradaStatus(DWORD dwMirandaStatus,DWORD dwXStatusMir,DWORD *pdwXStatusMra) { DWORD dwRet; if (IsXStatusValid(dwXStatusMir)) { if (pdwXStatusMra) (*pdwXStatusMra)=(dwXStatusMir+MRA_XSTATUS_INDEX_OFFSET-1); dwRet=STATUS_USER_DEFINED; }else{ switch(dwMirandaStatus){ case ID_STATUS_OFFLINE: if (pdwXStatusMra) (*pdwXStatusMra)=MRA_XSTATUS_OFFLINE; dwRet=STATUS_OFFLINE; break; case ID_STATUS_ONLINE: if (pdwXStatusMra) (*pdwXStatusMra)=MRA_XSTATUS_ONLINE; dwRet=STATUS_ONLINE; break; case ID_STATUS_AWAY: case ID_STATUS_NA: case ID_STATUS_ONTHEPHONE: case ID_STATUS_OUTTOLUNCH: if (pdwXStatusMra) (*pdwXStatusMra)=MRA_XSTATUS_AWAY; dwRet=STATUS_AWAY; break; case ID_STATUS_DND: case ID_STATUS_OCCUPIED: if (pdwXStatusMra) (*pdwXStatusMra)=MRA_XSTATUS_DND; dwRet=STATUS_USER_DEFINED; break; case ID_STATUS_FREECHAT: if (pdwXStatusMra) (*pdwXStatusMra)=MRA_XSTATUS_CHAT; dwRet=STATUS_USER_DEFINED; break; case ID_STATUS_INVISIBLE: if (pdwXStatusMra) (*pdwXStatusMra)=MRA_XSTATUS_INVISIBLE; dwRet=(STATUS_ONLINE|STATUS_FLAG_INVISIBLE); break; default: if (pdwXStatusMra) (*pdwXStatusMra)=MRA_XSTATUS_OFFLINE; dwRet=STATUS_OFFLINE; break; } } return(dwRet); } DWORD GetMiradaStatusFromMraStatus(DWORD dwMraStatus,DWORD dwXStatusMra,DWORD *pdwXStatusMir) { DWORD dwRet; if (pdwXStatusMir) (*pdwXStatusMir)=0; switch(dwMraStatus){ case STATUS_OFFLINE: dwRet=ID_STATUS_OFFLINE; break; case STATUS_ONLINE: dwRet=ID_STATUS_ONLINE; break; case STATUS_AWAY: dwRet=ID_STATUS_AWAY; break; case STATUS_UNDETERMINATED: dwRet=ID_STATUS_OFFLINE; break; case STATUS_USER_DEFINED: switch(dwXStatusMra){ //case MRA_XSTATUS_OFFLINE: dwRet=ID_STATUS_OFFLINE; break; //case MRA_XSTATUS_ONLINE: dwRet=ID_STATUS_ONLINE; break; //case MRA_XSTATUS_AWAY: dwRet=ID_STATUS_AWAY; break; //case MRA_XSTATUS_INVISIBLE: dwRet=ID_STATUS_INVISIBLE; break; case MRA_XSTATUS_DND: dwRet=ID_STATUS_DND; break; case MRA_XSTATUS_CHAT: dwRet=ID_STATUS_FREECHAT; break; case MRA_XSTATUS_UNKNOWN: if (pdwXStatusMir) (*pdwXStatusMir)=MRA_MIR_XSTATUS_UNKNOWN; dwRet=ID_STATUS_ONLINE; break; default: if (pdwXStatusMir) (*pdwXStatusMir)=(dwXStatusMra-MRA_XSTATUS_INDEX_OFFSET+1); dwRet=ID_STATUS_ONLINE; break; } break; default:// STATUS_FLAG_INVISIBLE if (dwMraStatus&STATUS_FLAG_INVISIBLE) { dwRet=ID_STATUS_INVISIBLE; }else{ dwRet=ID_STATUS_OFFLINE; DebugBreak(); } break; } return(dwRet); } DWORD GetUL(LPBYTE *plpData) { DWORD dwRet=(*(DWORD*)(*plpData)); (*plpData)+=sizeof(DWORD); return(dwRet); } DWORDLONG GetUIDL(LPBYTE *plpData) { DWORDLONG dwRet=(*(DWORDLONG*)(*plpData)); (*plpData)+=sizeof(DWORDLONG); return(dwRet); } MRA_GUID GetGUID(LPBYTE *plpData) { MRA_GUID guidRet=(*(MRA_GUID*)(*plpData)); (*plpData)+=sizeof(MRA_GUID); return(guidRet); } DWORD GetLPS(LPBYTE lpbData,DWORD dwDataSize,LPBYTE *plpCurrentData,MRA_LPS *plpsString) { DWORD dwRetErrorCode; LPBYTE lpbDataEnd=(lpbData+dwDataSize); if (lpbDataEnd>=((*plpCurrentData)+sizeof(DWORD))) {// хотябы длинна данных есть if (lpbDataEnd>=((*plpCurrentData)+sizeof(DWORD)+(*(DWORD*)(*plpCurrentData)))) {// все длинна данных в буфере равна или меньше размера буфера plpsString->dwSize=(*(DWORD*)(*plpCurrentData)); plpsString->lpszData=(LPSTR)((*plpCurrentData)+sizeof(DWORD)); (*plpCurrentData)+=(sizeof(DWORD)+plpsString->dwSize); dwRetErrorCode=NO_ERROR; }else{ plpsString->dwSize=0; plpsString->lpszData=NULL; dwRetErrorCode=ERROR_INVALID_USER_BUFFER; } }else{ plpsString->dwSize=0; plpsString->lpszData=NULL; dwRetErrorCode=ERROR_INVALID_USER_BUFFER; } return(dwRetErrorCode); }