summaryrefslogtreecommitdiff
path: root/protocols/MRA/src/Mra_proto.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/MRA/src/Mra_proto.cpp')
-rw-r--r--protocols/MRA/src/Mra_proto.cpp1966
1 files changed, 0 insertions, 1966 deletions
diff --git a/protocols/MRA/src/Mra_proto.cpp b/protocols/MRA/src/Mra_proto.cpp
deleted file mode 100644
index 39999c7557..0000000000
--- a/protocols/MRA/src/Mra_proto.cpp
+++ /dev/null
@@ -1,1966 +0,0 @@
-#include "stdafx.h"
-#include "MraOfflineMsg.h"
-#include "MraRTFMsg.h"
-#include "MraPlaces.h"
-
-DWORD CMraProto::StartConnect()
-{
- if (m_bShutdown)
- return ERROR_OPERATION_ABORTED;
-
- // поток ещё/уже не работал, поставили статус что работает и запускаем
- if (InterlockedCompareExchange((volatile LONG*)&m_dwThreadWorkerRunning, TRUE, FALSE))
- return 0;
-
- CMStringA szEmail;
- if (!mraGetStringA(NULL, "e-mail", szEmail))
- return 0;
-
- CMStringA szPass;
- if (szEmail.GetLength() <= 5)
- MraPopupShowFromAgentW(MRA_POPUP_TYPE_WARNING, TranslateT("Please, setup e-mail in options"));
- else if (!GetPassDB(szPass))
- MraPopupShowFromAgentW(MRA_POPUP_TYPE_WARNING, TranslateT("Please, setup password in options"));
- else {
- InterlockedExchange((volatile LONG*)&m_dwThreadWorkerLastPingTime, GetTickCount());
- if (INVALID_HANDLE_VALUE != ForkThreadEx(&CMraProto::MraThreadProc, nullptr, nullptr))
- return 0; /* OK. */
- MraPopupShowFromAgentW(MRA_POPUP_TYPE_ERROR, TranslateT("Thread creation failure"));
- }
- InterlockedExchange((volatile LONG*)&m_dwThreadWorkerRunning, FALSE);
- return ERROR_OPERATION_ABORTED;
-}
-
-void CMraProto::MraThreadProc(LPVOID)
-{
- BOOL bConnected = FALSE;
- CMStringA szHost;
- DWORD dwConnectReTryCount, dwCurConnectReTryCount;
-
- Thread_SetName("MRA: ProtoThreadProc");
-
- SleepEx(100, FALSE);// to prevent high CPU load by some status plugins like allwaysonline
-
- dwConnectReTryCount = getDword("ConnectReTryCountMRIM", MRA_DEFAULT_CONN_RETRY_COUNT_MRIM);
-
- NETLIBOPENCONNECTION nloc = { 0 };
- nloc.cbSize = sizeof(nloc);
- nloc.flags = NLOCF_V2;
- nloc.timeout = getDword("TimeOutConnectMRIM", MRA_DEFAULT_TIMEOUT_CONN_MRIM);
- if (nloc.timeout < MRA_TIMEOUT_CONN_MIN) nloc.timeout = MRA_TIMEOUT_CONN_MIN;
- if (nloc.timeout > MRA_TIMEOUT_CONN_MAX) nloc.timeout = MRA_TIMEOUT_CONN_MAX;
-
- InterlockedExchange((volatile LONG*)&m_dwThreadWorkerLastPingTime, GetTickCount());
- if (MraGetNLBData(szHost, &nloc.wPort) == NO_ERROR) {
- nloc.szHost = szHost;
- //nloc.szHost = "217.69.141.245";
- //nloc.wPort = 443;
- //nloc.flags |= NLOCF_SSL;
- dwCurConnectReTryCount = dwConnectReTryCount;
- do {
- InterlockedExchange((volatile LONG*)&m_dwThreadWorkerLastPingTime, GetTickCount());
- m_hConnection = Netlib_OpenConnection(m_hNetlibUser, &nloc);
- }
- while (--dwCurConnectReTryCount && m_hConnection == nullptr);
-
- if (m_hConnection)
- bConnected = TRUE;
- }
-
- if (bConnected == FALSE)
- if (getByte("NLBFailDirectConnect", MRA_DEFAULT_NLB_FAIL_DIRECT_CONNECT)) {
- if (IsHTTPSProxyUsed(m_hNetlibUser))
- nloc.wPort = MRA_SERVER_PORT_HTTPS;
- else {
- nloc.wPort = getWord("ServerPort", MRA_DEFAULT_SERVER_PORT);
- if (nloc.wPort == MRA_SERVER_PORT_STANDART_NLB) nloc.wPort = MRA_SERVER_PORT_STANDART;
- }
-
- for (DWORD i = 1; (i < MRA_MAX_MRIM_SERVER && m_iStatus != ID_STATUS_OFFLINE); i++) {
- szHost.Format("mrim%lu.mail.ru", i);
-
- dwCurConnectReTryCount = dwConnectReTryCount;
- do {
- InterlockedExchange((volatile LONG*)&m_dwThreadWorkerLastPingTime, GetTickCount());
- m_hConnection = Netlib_OpenConnection(m_hNetlibUser, &nloc);
- }
- while (--dwCurConnectReTryCount && m_hConnection == nullptr);
-
- if (m_hConnection) {
- bConnected = TRUE;
- break;
- }
- }
- }
-
- if (bConnected && m_iStatus != ID_STATUS_OFFLINE)
- MraNetworkDispatcher();
- else {
- if (bConnected == FALSE) {
- ShowFormattedErrorMessage(L"Can't connect to MRIM server, error", GetLastError());
- ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, nullptr, LOGINERR_NONETWORK);
- }
- }
-
- MraMPopSessionQueueFlush(hMPopSessionQueue);
- NETLIB_CLOSEHANDLE(m_hConnection);
- dwCMDNum = 0;
-
- InterlockedExchange((volatile LONG*)&m_dwThreadWorkerRunning, FALSE);
- SetStatus(ID_STATUS_OFFLINE);
-}
-
-DWORD CMraProto::MraGetNLBData(CMStringA &szHost, WORD *pwPort)
-{
- DWORD dwRetErrorCode;
-
- BOOL bContinue = TRUE;
- BYTE btBuff[MAX_PATH];
- DWORD dwConnectReTryCount, dwCurConnectReTryCount;
- LPSTR lpszPort;
- size_t dwBytesReceived, dwRcvBuffSizeUsed = 0;
- NETLIBSELECT nls = { 0 };
- NETLIBOPENCONNECTION nloc = { 0 };
-
- dwConnectReTryCount = getDword("ConnectReTryCountNLB", MRA_DEFAULT_CONN_RETRY_COUNT_NLB);
-
- nloc.cbSize = sizeof(nloc);
- nloc.flags = NLOCF_V2;
- if (mraGetStringA(NULL, "Server", szHost))
- nloc.szHost = szHost;
- else
- nloc.szHost = MRA_DEFAULT_SERVER;
-
- if (IsHTTPSProxyUsed(m_hNetlibUser))
- nloc.wPort = MRA_SERVER_PORT_HTTPS;
- else
- nloc.wPort = getWord("ServerPort", MRA_DEFAULT_SERVER_PORT);
-
- nloc.timeout = getDword("TimeOutConnectNLB", MRA_DEFAULT_TIMEOUT_CONN_NLB);
- if (nloc.timeout < MRA_TIMEOUT_CONN_MIN) nloc.timeout = MRA_TIMEOUT_CONN_MIN;
- if (nloc.timeout > MRA_TIMEOUT_CONN_MAX) nloc.timeout = MRA_TIMEOUT_CONN_MAX;
-
- dwCurConnectReTryCount = dwConnectReTryCount;
- do {
- InterlockedExchange((volatile LONG*)&m_dwThreadWorkerLastPingTime, GetTickCount());
- nls.hReadConns[0] = Netlib_OpenConnection(m_hNetlibUser, &nloc);
- }
- while (--dwCurConnectReTryCount && nls.hReadConns[0] == nullptr);
-
- if (nls.hReadConns[0]) {
- nls.dwTimeout = 1000 * getDword("TimeOutReceiveNLB", MRA_DEFAULT_TIMEOUT_RECV_NLB);
- InterlockedExchange((volatile LONG*)&m_dwThreadWorkerLastPingTime, GetTickCount());
-
- while (m_iStatus != ID_STATUS_OFFLINE && bContinue) {
- switch (Netlib_Select(&nls)) {
- case SOCKET_ERROR:
- case 0:// Time out
- bContinue = FALSE;
- break;
- case 1:
- dwBytesReceived = Netlib_Recv(nls.hReadConns[0], (LPSTR)(btBuff + dwRcvBuffSizeUsed), (int)(_countof(btBuff) - dwRcvBuffSizeUsed), 0);
- if (dwBytesReceived && dwBytesReceived != SOCKET_ERROR)
- dwRcvBuffSizeUsed += dwBytesReceived;
- else
- bContinue = FALSE;
- break;
- }
- InterlockedExchange((volatile LONG*)&m_dwThreadWorkerLastPingTime, GetTickCount());
- }
- Netlib_CloseHandle(nls.hReadConns[0]);
-
- if (dwRcvBuffSizeUsed) {
- lpszPort = (LPSTR)MemoryFindByte(0, btBuff, dwRcvBuffSizeUsed, ':');
- if (lpszPort) {
- (*lpszPort) = 0;
- lpszPort++;
-
- szHost = (LPSTR)btBuff;
- if (pwPort) (*pwPort) = (WORD)StrToUNum32(lpszPort, (dwRcvBuffSizeUsed - (lpszPort - (LPSTR)btBuff)));
- dwRetErrorCode = NO_ERROR;
- }
- else {
- dwRetErrorCode = ERROR_INVALID_USER_BUFFER;
- ShowFormattedErrorMessage(L"NLB data corrupted", NO_ERROR);
- }
- }
- else {
- dwRetErrorCode = GetLastError();
- ShowFormattedErrorMessage(L"Can't get data for NLB, error", dwRetErrorCode);
- }
- }
- else {
- dwRetErrorCode = GetLastError();
- ShowFormattedErrorMessage(L"Can't connect to NLB server, error", dwRetErrorCode);
- }
-
- return dwRetErrorCode;
-}
-
-DWORD CMraProto::MraNetworkDispatcher()
-{
- DWORD dwRetErrorCode = NO_ERROR;
-
- bool bContinue = true;
- DWORD dwDataCurrentBuffSize, dwDataCurrentBuffSizeUsed;
- size_t dwRcvBuffSize = BUFF_SIZE_RCV, dwRcvBuffSizeUsed = 0, dwDataCurrentBuffOffset = 0;
- LPBYTE lpbBufferRcv;
- mrim_packet_header_t *pmaHeader;
-
- NETLIBSELECT nls = { sizeof(nls) };
- nls.dwTimeout = 30000;
- nls.hReadConns[0] = m_hConnection;
-
- lpbBufferRcv = (LPBYTE)mir_calloc(dwRcvBuffSize);
-
- m_dwNextPingSendTickTime = m_dwPingPeriod = MAXDWORD;
- dwCMDNum = 0;
- MraSendCMD(MRIM_CS_HELLO, nullptr, 0);
- while (m_iStatus != ID_STATUS_OFFLINE && bContinue) {
- int iSelectRet = Netlib_Select(&nls);
- if (SOCKET_ERROR == iSelectRet) {
- if (m_iStatus != ID_STATUS_OFFLINE) {
- dwRetErrorCode = GetLastError();
- ShowFormattedErrorMessage(L"Disconnected, socket error", dwRetErrorCode);
- }
- break;
- }
- // Time out or normal
- m_dwThreadWorkerLastPingTime = GetTickCount();
- /* Server ping. */
- if (m_dwNextPingSendTickTime <= m_dwThreadWorkerLastPingTime) {
- nls.dwTimeout = (m_dwPingPeriod * 1000);
- m_dwNextPingSendTickTime = (m_dwThreadWorkerLastPingTime + nls.dwTimeout);
- MraSendCMD(MRIM_CS_PING, nullptr, 0);
- } else {
- if (MAXDWORD != m_dwNextPingSendTickTime)
- nls.dwTimeout = (m_dwNextPingSendTickTime - m_dwThreadWorkerLastPingTime);
- }
- { /* Remove old items from send queue. */
- DWORD dwCmdNum, dwFlags, dwAckType;
- MCONTACT hContact;
- LPBYTE lpbData;
- size_t dwDataSize;
- while (!MraSendQueueFindOlderThan(hSendQueueHandle, SEND_QUEUE_TIMEOUT, &dwCmdNum, &dwFlags, &hContact, &dwAckType, &lpbData, &dwDataSize)) {
- switch (dwAckType) {
- case ACKTYPE_ADDED:
- case ACKTYPE_AUTHREQ:
- case ACKTYPE_CONTACTS:
- //nothing to do
- break;
- case ACKTYPE_MESSAGE:
- ProtoBroadcastAck(hContact, dwAckType, ACKRESULT_FAILED, (HANDLE)dwCmdNum, (LPARAM)"Undefined message deliver error, time out");
- break;
- case ACKTYPE_GETINFO:
- ProtoBroadcastAck(hContact, dwAckType, ACKRESULT_FAILED, (HANDLE)1, 0);
- break;
- case ACKTYPE_SEARCH:
- ProtoBroadcastAck(hContact, dwAckType, ACKRESULT_SUCCESS, (HANDLE)dwCmdNum, 0);
- break;
- case ICQACKTYPE_SMS:
- ProtoBroadcastAck(NULL, dwAckType, ACKRESULT_FAILED, (HANDLE)dwCmdNum, 0);
- mir_free(lpbData);
- break;
- }
- MraSendQueueFree(hSendQueueHandle, dwCmdNum);
- }
- }
-
- if (iSelectRet == 0) // Time out
- continue;
-
- // expand receive buffer dynamically
- if ((dwRcvBuffSize - dwRcvBuffSizeUsed) < BUFF_SIZE_RCV_MIN_FREE) {
- dwRcvBuffSize += BUFF_SIZE_RCV;
- lpbBufferRcv = (LPBYTE)mir_realloc(lpbBufferRcv, dwRcvBuffSize);
- }
-
- DWORD dwBytesReceived = Netlib_Recv(nls.hReadConns[0], (LPSTR)(lpbBufferRcv + dwRcvBuffSizeUsed), (int)(dwRcvBuffSize - dwRcvBuffSizeUsed), 0);
- if ( !dwBytesReceived || dwBytesReceived == SOCKET_ERROR) { // disconnected
- if (m_iStatus != ID_STATUS_OFFLINE) {
- dwRetErrorCode = GetLastError();
- debugLogA("Disconnected, socket read error %d", dwRetErrorCode);
- }
- break;
- }
-
- dwRcvBuffSizeUsed += dwBytesReceived;
- while (TRUE) {
- dwDataCurrentBuffSize = (int)(dwRcvBuffSize - dwDataCurrentBuffOffset);
- dwDataCurrentBuffSizeUsed = (int)(dwRcvBuffSizeUsed - dwDataCurrentBuffOffset);
- pmaHeader = (mrim_packet_header_t*)(lpbBufferRcv + dwDataCurrentBuffOffset);
-
- // packet header received
- if (dwDataCurrentBuffSizeUsed < sizeof(mrim_packet_header_t)) { // packet to small, continue receiving
- debugLogW(L"Packet to small, continue receiving\n");
- memmove(lpbBufferRcv, (lpbBufferRcv + dwDataCurrentBuffOffset), dwDataCurrentBuffSizeUsed);
- dwRcvBuffSizeUsed = dwDataCurrentBuffSizeUsed;
- dwDataCurrentBuffOffset = 0;
- break;
- }
- if (pmaHeader->magic != CS_MAGIC) { // bad packet
- debugLogW(L"Bad packet\n");
- dwDataCurrentBuffOffset = 0;
- dwRcvBuffSizeUsed = 0;
- break;
- }
- // packet OK
- if ((dwDataCurrentBuffSizeUsed - sizeof(mrim_packet_header_t)) < pmaHeader->dlen) { // not all packet received, continue receiving
- if (dwDataCurrentBuffOffset) {
- memmove(lpbBufferRcv, (lpbBufferRcv + dwDataCurrentBuffOffset), dwDataCurrentBuffSizeUsed);
- dwRcvBuffSizeUsed = dwDataCurrentBuffSizeUsed;
- dwDataCurrentBuffOffset = 0;
- }
- debugLogW(L"Not all packet received, continue receiving\n");
- break;
- }
- // full packet received, may be more than one
- bContinue = MraCommandDispatcher(pmaHeader);
-
- // move pointer to next packet in buffer
- if (dwDataCurrentBuffSizeUsed - sizeof(mrim_packet_header_t) > pmaHeader->dlen)
- dwDataCurrentBuffOffset += sizeof(mrim_packet_header_t)+pmaHeader->dlen;
- // move pointer to begin of buffer
- else {
- // динамическое уменьшение буффера приёма
- if (dwRcvBuffSize > BUFF_SIZE_RCV) {
- dwRcvBuffSize = BUFF_SIZE_RCV;
- lpbBufferRcv = (LPBYTE)mir_realloc(lpbBufferRcv, dwRcvBuffSize);
- }
- dwDataCurrentBuffOffset = 0;
- dwRcvBuffSizeUsed = 0;
- break;
- }
- }
- }
- mir_free(lpbBufferRcv);
-
- return dwRetErrorCode;
-}
-
-//Подтверждение установки соединения// UL ## ping_period ## Ожидаемая частота подтверждения соединения (в секундах)
-bool CMraProto::CmdHelloAck(BinBuffer &buf)
-{
- buf >> m_dwPingPeriod;
-
- CMStringA szPass;
- if (!GetPassDB(szPass))
- return false;
-
- char szValueName[MAX_PATH];
- CMStringA szUserAgentFormatted, szEmail;
- CMStringW wszStatusTitle, wszStatusDesc;
-
- DWORD dwXStatusMir = m_iXStatus, dwXStatus;
- DWORD dwStatus = GetMraStatusFromMiradaStatus(m_iDesiredStatus, dwXStatusMir, &dwXStatus);
- if (IsXStatusValid(dwXStatusMir)) {// xstatuses
- mir_snprintf(szValueName, "XStatus%ldName", dwXStatusMir);
- if (!mraGetStringW(NULL, szValueName, wszStatusTitle))
- wszStatusTitle = TranslateW(lpcszXStatusNameDef[dwXStatusMir]);
-
- mir_snprintf(szValueName, "XStatus%ldMsg", dwXStatusMir);
- mraGetStringW(NULL, szValueName, wszStatusDesc);
- }
- else wszStatusTitle = Clist_GetStatusModeDescription(m_iDesiredStatus, 0);
-
- CMStringA szSelfVersionString = MraGetSelfVersionString();
- if (!mraGetStringA(NULL, "MirVerCustom", szUserAgentFormatted))
- szUserAgentFormatted.Format(
- "client=\"magent\" name=\"Miranda NG\" title=\"%s\" version=\"777.%lu.%lu.%lu\" build=\"%lu\" protocol=\"%lu.%lu\"",
- szSelfVersionString.c_str(), __FILEVERSION_STRING, PROTO_VERSION_MAJOR, PROTO_VERSION_MINOR);
-
- DWORD dwFutureFlags = (getByte("RTFReceiveEnable", MRA_DEFAULT_RTF_RECEIVE_ENABLE) ? FEATURE_FLAG_RTF_MESSAGE : 0) | MRA_FEATURE_FLAGS;
-
- if (!mraGetStringA(NULL, "e-mail", szEmail))
- return false;
-
- MraLogin2W(szEmail, szPass, dwStatus, lpcszStatusUri[dwXStatus], wszStatusTitle, wszStatusDesc, dwFutureFlags, szUserAgentFormatted, szSelfVersionString);
- return true;
-}
-
-// Successful authorization
-bool CMraProto::CmdLoginAck()
-{
- m_bLoggedIn = TRUE;
- m_dwNextPingSendTickTime = 0; // force send ping
- MraSendCMD(MRIM_CS_PING, nullptr, 0);
- SetStatus(m_iDesiredStatus);
- MraAvatarsQueueGetAvatarSimple(hAvatarsQueueHandle, GAIF_FORCE, NULL);
- return true;
-}
-
-// Unsuccessful authorization //LPS ## reason ## причина отказа
-bool CMraProto::CmdLoginRejected(BinBuffer &buf)
-{
- ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, nullptr, LOGINERR_WRONGPASSWORD);
-
- CMStringA reason; buf >> reason;
- MraPopupShowW(NULL, MRA_POPUP_TYPE_ERROR, TranslateT("Logon error: invalid login/password"), _A2T(reason.c_str()));
- return false;
-}
-
-// Message delivery
-//LPS ## from ## Адрес отправителя
-//LPS ## message ## текстовая версия сообщения
-//LPS ## rtf-message ## форматированная версия сообщения
-bool CMraProto::CmdMessageAck(BinBuffer &buf)
-{
- DWORD dwMsgID, dwFlags;
- CMStringA szEmail, szText, szRTFText, szMultiChatData;
- buf >> dwMsgID >> dwFlags >> szEmail >> szText >> szRTFText;
- if (dwFlags & MESSAGE_FLAG_MULTICHAT)
- buf >> szMultiChatData; // LPS multichat_data
-
- // подтверждаем получение, только если удалось его обработать
- if (MraRecvCommand_Message((DWORD)_time32(nullptr), dwFlags, szEmail, szText, szRTFText, szMultiChatData) == NO_ERROR)
- if ((dwFlags & MESSAGE_FLAG_NORECV) == 0)
- MraMessageRecv(szEmail, dwMsgID);
- return true;
-}
-
-bool CMraProto::CmdMessageStatus(ULONG seq, BinBuffer &buf)
-{
- DWORD dwAckType, dwTemp = buf.getDword();
- MCONTACT hContact;
- if (!MraSendQueueFind(hSendQueueHandle, seq, nullptr, &hContact, &dwAckType, nullptr, nullptr)) {
- switch (dwTemp) {
- case MESSAGE_DELIVERED:// Message delivered directly to user
- ProtoBroadcastAckAsync(hContact, dwAckType, ACKRESULT_SUCCESS, (HANDLE)seq, 0);
- break;//***deb возможны сбои из-за асинхронности тк там передаётся указатель
- case MESSAGE_REJECTED_NOUSER:// Message rejected - no such user
- ProtoBroadcastAck(hContact, dwAckType, ACKRESULT_FAILED, (HANDLE)seq, (LPARAM)"Message rejected - no such user");
- break;
- case MESSAGE_REJECTED_INTERR:// Internal server error
- ProtoBroadcastAck(hContact, dwAckType, ACKRESULT_FAILED, (HANDLE)seq, (LPARAM)"Internal server error");
- break;
- case MESSAGE_REJECTED_LIMIT_EXCEEDED:// Offline messages limit exceeded
- ProtoBroadcastAck(hContact, dwAckType, ACKRESULT_FAILED, (HANDLE)seq, (LPARAM)"Offline messages limit exceeded");
- break;
- case MESSAGE_REJECTED_TOO_LARGE:// Message is too large
- ProtoBroadcastAck(hContact, dwAckType, ACKRESULT_FAILED, (HANDLE)seq, (LPARAM)"Message is too large");
- break;
- case MESSAGE_REJECTED_DENY_OFFMSG:// User does not accept offline messages
- ProtoBroadcastAck(hContact, dwAckType, ACKRESULT_FAILED, (HANDLE)seq, (LPARAM)"User does not accept offline messages");
- break;
- case MESSAGE_REJECTED_DENY_OFFFLSH:// User does not accept offline flash animation
- ProtoBroadcastAck(hContact, dwAckType, ACKRESULT_FAILED, (HANDLE)seq, (LPARAM)"User does not accept offline flash animation");
- break;
- default:
- ProtoBroadcastAck(hContact, dwAckType, ACKRESULT_FAILED, (HANDLE)seq, (LPARAM)CMStringA().Format("Undefined message delivery error, code: %lu", dwTemp));
- break;
- }
- MraSendQueueFree(hSendQueueHandle, seq);
- }
- // not found in queue
- else if (dwTemp != MESSAGE_DELIVERED)
- MraPopupShowFromAgentW(MRA_POPUP_TYPE_DEBUG, TranslateT("MRIM_CS_MESSAGE_STATUS: not found in queue"));
- return true;
-}
-
-bool CMraProto::CmdUserInfo(BinBuffer &buf)
-{
- CMStringA szString;
- CMStringW szStringW;
- while (!buf.eof()) {
- buf >> szString;
- if (szString == "MESSAGES.TOTAL") {
- buf >> szString;
- dwEmailMessagesTotal = atoi(szString);
- }
- else if (szString == "MESSAGES.UNREAD") {
- buf >> szString;
- m_dwEmailMessagesUnread = atoi(szString);
- }
- else if (szString == "MRIM.NICKNAME") {
- buf >> szStringW;
- mraSetStringW(NULL, "Nick", szStringW);
- }
- else if (szString == "client.endpoint") {
- buf >> szStringW;
- szString = szStringW;
- int lpszDelimiter = szString.Find(':');
- if (lpszDelimiter != -1) {
- CMStringA szAddr(szString, lpszDelimiter);
- setDword("IP", ntohl(inet_addr(szAddr.c_str())));
- }
- }
- else if (szString == "connect.xml") {
- debugLogA(szString);
- buf >> szStringW;
- debugLogW(szStringW);
- }
- else if (szString == "micblog.show_title") {
- debugLogA(szString);
- buf >> szString;
- debugLogW(szStringW);
- }
- else if (szString == "micblog.status.xml") {
- debugLogA(szString);
- buf >> szString;
- debugLogA(szString);
- }
- else if (szString == "micblog.status.id") {
- buf >> szStringW;
- DWORDLONG dwBlogStatusID = _wtoi64(szStringW);
- mraWriteContactSettingBlob(NULL, DBSETTING_BLOGSTATUSID, &dwBlogStatusID, sizeof(DWORDLONG));
- }
- else if (szString == "micblog.status.time") {
- buf >> szStringW;
- setDword(DBSETTING_BLOGSTATUSTIME, _wtoi(szStringW));
- }
- else if (szString == "micblog.status.text") {
- buf >> szStringW;
- mraSetStringW(NULL, DBSETTING_BLOGSTATUS, szStringW);
- }
- else if (szString == "HAS_MYMAIL" || szString == "mrim.status.open_search" || szString == "rb.target.cookie" ||
- szString == "show_web_history_link" || szString == "friends_suggest" || szString == "timestamp" ||
- szString == "trusted_update" || szString == "mrim.wp.dating") {
- debugLogA(szString);
- buf >> szStringW;
- debugLogW(szStringW);
- }
- else _CrtDbgBreak();
- }
- MraUpdateEmailStatus("", "", false);
- return true;
-}
-
-//Сообщение доставленное, пока пользователь не был подключен к сети
-bool CMraProto::CmdOfflineMessageAck(BinBuffer &buf)
-{
- CMStringA szEmail, szText, lpsRTFText, lpsMultiChatData, szString;
- DWORDLONG dwMsgUIDL;
- buf >> dwMsgUIDL >> szString;
-
- DWORD dwTime, dwFlags;
- if (MraOfflineMessageGet(szString, dwTime, dwFlags, szEmail, szText, lpsRTFText, lpsMultiChatData) == NO_ERROR) {
- DWORD dwTemp = MraRecvCommand_Message(dwTime, dwFlags, szEmail, szText, lpsRTFText, lpsMultiChatData);
- if (dwTemp == NO_ERROR || dwTemp == ERROR_ACCESS_DENIED)
- MraOfflineMessageDel(dwMsgUIDL);
- else
- ShowFormattedErrorMessage(L"Offline message processing error, message will not deleted from server", NO_ERROR);
- }
- else ShowFormattedErrorMessage(L"Offline message processing error, message will not deleted from server", NO_ERROR);
-
- return true;
-}
-
-// Auth confirmation
-bool CMraProto::CmdAuthAck(BinBuffer &buf)
-{
- CMStringA szEmail;
- buf >> szEmail;
-
- BOOL bAdded;
- MCONTACT hContact = MraHContactFromEmail(szEmail, TRUE, TRUE, &bAdded);
- if (bAdded)
- MraUpdateContactInfo(hContact);
-
- if (IsEMailChatAgent(szEmail) == FALSE) {
- CMStringA szBuff = CreateBlobFromContact(hContact, L"");
-
- DBEVENTINFO dbei = {};
- dbei.flags = DBEF_UTF;
- dbei.szModule = m_szModuleName;
- dbei.timestamp = (DWORD)_time32(nullptr);
- dbei.eventType = EVENTTYPE_ADDED;
- dbei.cbBlob = szBuff.GetLength();
- dbei.pBlob = (PBYTE)szBuff.GetString();
- db_event_add(0, &dbei);
- }
-
- DWORD dwTemp;
- GetContactBasicInfoW(hContact, nullptr, nullptr, nullptr, &dwTemp, nullptr, nullptr, nullptr, nullptr);
- dwTemp &= ~CONTACT_INTFLAG_NOT_AUTHORIZED;
- SetContactBasicInfoW(hContact, SCBIFSI_LOCK_CHANGES_EVENTS, SCBIF_SERVER_FLAG, 0, 0, 0, dwTemp, 0, nullptr, nullptr, nullptr);
- setDword(hContact, "HooksLocked", TRUE);
- db_unset(hContact, "CList", "NotOnList");
- setDword(hContact, "HooksLocked", FALSE);
- return true;
-}
-
-// Web auth key
-bool CMraProto::CmdPopSession(BinBuffer &buf)
-{
- DWORD dwTemp = buf.getDword();
- if (dwTemp) {
- CMStringA szString; buf >> szString;
- if (NO_ERROR == MraMPopSessionQueueSetNewMPopKey(hMPopSessionQueue, szString)) {
- MraMPopSessionQueueStart(hMPopSessionQueue);
- return true;
- }
- }
- //error
- MraPopupShowFromAgentW(MRA_POPUP_TYPE_WARNING, TranslateT("Server error: can't get MPOP key for web authorize"));
- MraMPopSessionQueueFlush(hMPopSessionQueue);
-
- return true;
-}
-
-bool CMraProto::CmdFileTransfer(BinBuffer &buf)
-{
- DWORD dwIDRequest, dwFilesTotalSize, dwTemp;
- CMStringA szFiles, szEmail, szAddresses;
- CMStringW wszFilesW;
-
- buf >> szEmail >> dwIDRequest >> dwFilesTotalSize >> dwTemp;
- if (dwTemp) {
- buf >> szFiles >> dwTemp;
- if (dwTemp) { // LPS DESCRIPTION
- buf >> dwTemp >> wszFilesW;
- _ASSERTE(dwTemp != 1);
- }
- buf >> szAddresses;
- }
-
- BOOL bAdded = FALSE;
- MCONTACT hContact = MraHContactFromEmail(szEmail, TRUE, TRUE, &bAdded);
- if (bAdded)
- MraUpdateContactInfo(hContact);
-
- if (wszFilesW.IsEmpty())
- wszFilesW = szFiles;
-
- if (!wszFilesW.IsEmpty())
- MraFilesQueueAddReceive(hFilesQueueHandle, 0, hContact, dwIDRequest, wszFilesW, szAddresses);
- return true;
-}
-
-bool CMraProto::CmdFileTransferAck(BinBuffer &buf)
-{
- CMStringA szEmail, szString;
- DWORD dwAckType, dwTemp;
- buf >> dwAckType >> szEmail >> dwTemp >> szString;
-
- switch (dwAckType) {
- case FILE_TRANSFER_STATUS_OK:// игнорируем, мы и так уже слушаем порт(ждём), то что кто то согласился ничего не меняет
- //hContact = MraHContactFromEmail(szEmail.lpszData, szEmail.dwSize, TRUE, TRUE, NULL);
- break;
- case FILE_TRANSFER_STATUS_DECLINE:
- MraFilesQueueCancel(hFilesQueueHandle, dwTemp, FALSE);
- break;
- case FILE_TRANSFER_STATUS_ERROR:
- ShowFormattedErrorMessage(L"File transfer: error", NO_ERROR);
- MraFilesQueueCancel(hFilesQueueHandle, dwTemp, FALSE);
- break;
- case FILE_TRANSFER_STATUS_INCOMPATIBLE_VERS:
- ShowFormattedErrorMessage(L"File transfer: incompatible versions", NO_ERROR);
- MraFilesQueueCancel(hFilesQueueHandle, dwTemp, FALSE);
- break;
- case FILE_TRANSFER_MIRROR:
- MraFilesQueueSendMirror(hFilesQueueHandle, dwTemp, szString);
- break;
- default:// ## unknown error
- wchar_t szBuff[1024];
- mir_snwprintf(szBuff, TranslateT("MRIM_CS_FILE_TRANSFER_ACK: unknown error, code: %lu"), dwAckType);
- ShowFormattedErrorMessage(szBuff, NO_ERROR);
- break;
- }
- return true;
-}
-
-// Смена статуса другого пользователя
-bool CMraProto::CmdUserStatus(BinBuffer &buf)
-{
- DWORD dwStatus, dwXStatus, dwFutureFlags;
- CMStringA szSpecStatusUri, szUserAgentFormatted, szEmail;
- CMStringW szStatusTitle, szStatusDesc;
- buf >> dwStatus >> szSpecStatusUri >> szStatusTitle >> szStatusDesc >> szEmail >> dwFutureFlags >> szUserAgentFormatted;
-
- BOOL bAdded;
- if (MCONTACT hContact = MraHContactFromEmail(szEmail, TRUE, TRUE, &bAdded)) {
- if (bAdded)
- MraUpdateContactInfo(hContact);
-
- DWORD dwTemp = GetMirandaStatusFromMraStatus(dwStatus, GetMraXStatusIDFromMraUriStatus(szSpecStatusUri), &dwXStatus);
-
- MraContactCapabilitiesSet(hContact, dwFutureFlags);
- setByte(hContact, DBSETTING_XSTATUSID, (BYTE)dwXStatus);
- if (dwXStatus) {
- mraSetStringW(hContact, DBSETTING_XSTATUSNAME, szStatusTitle);
- mraSetStringW(hContact, DBSETTING_XSTATUSMSG, szStatusDesc);
- }
- else {
- delSetting(hContact, DBSETTING_XSTATUSNAME);
- delSetting(hContact, DBSETTING_XSTATUSMSG);
- }
-
- if (dwTemp != ID_STATUS_OFFLINE) { // пишем клиента только если юзер не отключён, иначе не затираем старое
- if (!szUserAgentFormatted.IsEmpty()) {
- if (getByte("MirVerRaw", MRA_DEFAULT_MIRVER_RAW) == FALSE)
- szUserAgentFormatted = MraGetVersionStringFromFormatted(szUserAgentFormatted);
- }
- else szUserAgentFormatted = (szEmail.Find("@uin.icq") == -1) ? MIRVER_UNKNOWN : "ICQ client";
-
- mraSetStringA(hContact, "MirVer", szUserAgentFormatted);
- }
-
- if (dwTemp == MraGetContactStatus(hContact)) {// меняем шило на шило, подозрительно? ;)
- if (dwTemp == ID_STATUS_OFFLINE) { // was/now invisible
- CMStringW wszEmail, wszBuff;
- mraGetStringW(hContact, "e-mail", wszEmail);
- wszBuff.Format(L"%s <%s> - %s", Clist_GetContactDisplayName(hContact), wszEmail.c_str(), TranslateT("invisible status changed"));
- MraPopupShowFromContactW(hContact, MRA_POPUP_TYPE_INFORMATION, wszBuff);
-
- MraSetContactStatus(hContact, ID_STATUS_INVISIBLE);
- }
- }
- MraSetContactStatus(hContact, dwTemp);
- SetExtraIcons(hContact);
- }
- return true;
-}
-
-bool CMraProto::CmdContactAck(int cmd, int seq, BinBuffer &buf)
-{
- DWORD dwAckType; MCONTACT hContact;
- if (!MraSendQueueFind(hSendQueueHandle, seq, nullptr, &hContact, &dwAckType, nullptr, nullptr)) {
- DWORD dwTemp = buf.getDword();
- switch (dwTemp) {
- case CONTACT_OPER_SUCCESS:// ## добавление произведено успешно
- if (cmd == MRIM_CS_ADD_CONTACT_ACK) {
- DWORD dwFlags = SCBIF_ID | SCBIF_SERVER_FLAG, dwGroupID = 0;
- ptrW grpName(db_get_wsa(hContact, "CList", "Group"));
- if (grpName) {
- dwFlags |= SCBIF_GROUP_ID;
- dwGroupID = MraMoveContactToGroup(hContact, -1, grpName);
- }
- SetContactBasicInfoW(hContact, 0, dwFlags, buf.getDword(), dwGroupID, 0, CONTACT_INTFLAG_NOT_AUTHORIZED, 0, nullptr, nullptr, nullptr);
- }
- break;
- case CONTACT_OPER_ERROR:// ## переданные данные были некорректны
- ShowFormattedErrorMessage(L"Data been sent are invalid", NO_ERROR);
- break;
- case CONTACT_OPER_INTERR:// ## при обработке запроса произошла внутренняя ошибка
- ShowFormattedErrorMessage(L"Internal server error", NO_ERROR);
- break;
- case CONTACT_OPER_NO_SUCH_USER:// ## добавляемого пользователя не существует в системе
- SetContactBasicInfoW(hContact, 0, SCBIF_SERVER_FLAG, 0, 0, 0, -1, 0, nullptr, nullptr, nullptr);
- ShowFormattedErrorMessage(L"No such user to add", NO_ERROR);
- break;
- case CONTACT_OPER_INVALID_INFO:// ## некорректное имя пользователя
- ShowFormattedErrorMessage(L"Invalid user name", NO_ERROR);
- break;
- case CONTACT_OPER_USER_EXISTS:// ## пользователь уже есть в контакт-листе
- ShowFormattedErrorMessage(L"User already added", NO_ERROR);
- break;
- case CONTACT_OPER_GROUP_LIMIT:// ## превышено максимально допустимое количество групп (20)
- ShowFormattedErrorMessage(L"Group limit is 20", NO_ERROR);
- break;
- default:// ## unknown error
- wchar_t szBuff[1024];
- mir_snwprintf(szBuff, TranslateT("MRIM_CS_*_CONTACT_ACK: unknown server error, code: %lu"), dwTemp);
- MraPopupShowFromAgentW(MRA_POPUP_TYPE_DEBUG, szBuff);
- break;
- }
- MraSendQueueFree(hSendQueueHandle, seq);
- }
- else MraPopupShowFromAgentW(MRA_POPUP_TYPE_DEBUG, TranslateT("MRIM_CS_*_CONTACT_ACK: not found in queue"));
- return true;
-}
-
-bool CMraProto::CmdAnketaInfo(int seq, BinBuffer &buf)
-{
- DWORD dwAckType, dwFlags; MCONTACT hContact;
- if (MraSendQueueFind(hSendQueueHandle, seq, &dwFlags, &hContact, &dwAckType, nullptr, nullptr)) {
- MraPopupShowFromAgentW(MRA_POPUP_TYPE_DEBUG, TranslateT("MRIM_ANKETA_INFO: not found in queue"));
- return true;
- }
-
- switch (buf.getDword()) {
- case MRIM_ANKETA_INFO_STATUS_NOUSER:// не найдено ни одной подходящей записи
- SetContactBasicInfoW(hContact, 0, SCBIF_SERVER_FLAG, 0, 0, 0, -1, 0, nullptr, nullptr, nullptr);
- case MRIM_ANKETA_INFO_STATUS_DBERR:// ошибка базы данных
- case MRIM_ANKETA_INFO_STATUS_RATELIMERR:// слишком много запросов, поиск временно запрещен
- switch (dwAckType) {
- case ACKTYPE_GETINFO:
- ProtoBroadcastAck(hContact, dwAckType, ACKRESULT_FAILED, (HANDLE)1, 0);
- break;
- case ACKTYPE_SEARCH:
- ProtoBroadcastAck(hContact, dwAckType, ACKRESULT_SUCCESS, (HANDLE)seq, 0);
- break;
- }
- break;
-
- case MRIM_ANKETA_INFO_STATUS_OK:
- // поиск успешно завершен
- DWORD dwFieldsNum, dwMaxRows, dwServerTime;
- DWORD dwID, dwContactSeverFlags, dwStatus, dwXStatus;
- buf >> dwFieldsNum >> dwMaxRows >> dwServerTime;
-
- CMStringA *pmralpsFields = new CMStringA[dwFieldsNum];
- CMStringA val;
- CMStringW valW, StatusNameW, StatusMsgW;
-
- /* Default contact statuses in mail.ru format. */
- dwStatus = STATUS_OFFLINE;
- dwXStatus = MRA_XSTATUS_OFFLINE;
-
- // read headers name
- for (DWORD i = 0; i < dwFieldsNum; i++) {
- buf >> pmralpsFields[i];
- debugLogA(pmralpsFields[i] + " ");
- }
-
- while (!buf.eof()) {
- // write to DB and exit loop
- if (dwAckType == ACKTYPE_GETINFO && hContact) {
- setDword(hContact, "InfoTS", (DWORD)_time32(nullptr));
- //MRA_LPS mralpsUsernameValue;
- for (DWORD i = 0; i < dwFieldsNum; i++) {
- CMStringA &fld = pmralpsFields[i];
- if (fld == "Nickname") {
- buf >> valW;
- mraSetStringW(hContact, "Nick", valW);
- }
- else if (fld == "FirstName") {
- buf >> valW;
- mraSetStringW(hContact, "FirstName", valW);
- }
- else if (fld == "LastName") {
- buf >> valW;
- mraSetStringW(hContact, "LastName", valW);
- }
- else if (fld == "Sex") {
- buf >> val;
- switch (atoi(val)) {
- case 1:// мужской
- setByte(hContact, "Gender", 'M');
- break;
- case 2:// женский
- setByte(hContact, "Gender", 'F');
- break;
- default:// а фиг его знает
- delSetting(hContact, "Gender");
- break;
- }
- }
- else if (fld == "Birthday") {
- buf >> val;
- if (val.GetLength() > 9) {// calc "Age"
- SYSTEMTIME stTime = { 0 };
- stTime.wYear = (WORD)StrToUNum32(val.c_str(), 4);
- stTime.wMonth = (WORD)StrToUNum32(val.c_str() + 5, 2);
- stTime.wDay = (WORD)StrToUNum32(val.c_str() + 8, 2);
- setWord(hContact, "BirthYear", stTime.wYear);
- setByte(hContact, "BirthMonth", (BYTE)stTime.wMonth);
- setByte(hContact, "BirthDay", (BYTE)stTime.wDay);
- setWord(hContact, "Age", (WORD)GetYears(&stTime));
- }
- else {
- delSetting(hContact, "BirthYear");
- delSetting(hContact, "BirthMonth");
- delSetting(hContact, "BirthDay");
- delSetting(hContact, "Age");
- }
- }
- else if (fld == "City_id") {
- buf >> val;
- DWORD dwTemp = atoi(val);
- if (dwTemp) {
- for (size_t j = 0; mrapPlaces[j].lpszData; j++) {
- if (mrapPlaces[j].dwCityID == dwTemp) {
- mraSetStringW(hContact, "City", mrapPlaces[j].lpszData);
- break;
- }
- }
- }
- else delSetting(hContact, "City");
- }
- else if (fld == "Location") {
- buf >> valW;
- mraSetStringW(hContact, "About", valW);
- }
- else if (fld == "Country_id") {
- buf >> val;
- DWORD dwTemp = atoi(val);
- if (dwTemp) {
- for (size_t j = 0; mrapPlaces[j].lpszData; j++) {
- if (mrapPlaces[j].dwCountryID == dwTemp) {
- mraSetStringW(hContact, "Country", mrapPlaces[j].lpszData);
- break;
- }
- }
- }
- else delSetting(hContact, "Country");
- }
- else if (fld == "Phone") {
- delSetting(hContact, "Phone");
- delSetting(hContact, "Cellular");
- delSetting(hContact, "Fax");
-
- buf >> val;
- if (val.GetLength()) {
- int iStart = 0;
- CMStringA szPhone = val.Tokenize(",", iStart);
- if (iStart != -1) {
- mraSetStringA(hContact, "Phone", szPhone);
- szPhone = val.Tokenize(",", iStart);
- }
- if (iStart != -1) {
- mraSetStringA(hContact, "Cellular", szPhone);
- szPhone = val.Tokenize(",", iStart);
- }
- if (iStart != -1)
- mraSetStringA(hContact, "Fax", szPhone);
- }
- }
- else if (fld == "mrim_status") {
- buf >> val;
- if (val.GetLength())
- dwStatus = atoi(val);
- }
- else if (fld == "status_uri") {
- buf >> val;
- if (val.GetLength())
- dwXStatus = GetMraXStatusIDFromMraUriStatus(val);
- }
- else if (fld == "status_title") {
- buf >> StatusNameW;
- }
- else if (fld == "status_desc") {
- buf >> StatusMsgW;
- }
- else {// for DEBUG ONLY
- buf >> val;
- debugLogA("%s = %s\n", fld.c_str(), val.c_str());
- }
- } /* for */
- // для авторизованного нам и так присылают правильный статус
- GetContactBasicInfoW(hContact, &dwID, nullptr, nullptr, &dwContactSeverFlags, nullptr, nullptr, nullptr, nullptr);
- if (dwID == -1 || (dwContactSeverFlags & CONTACT_INTFLAG_NOT_AUTHORIZED)) {
- /* Convert mail.ru statuses to miranda. */
- dwStatus = GetMirandaStatusFromMraStatus(dwStatus, dwXStatus, &dwXStatus);
- MraSetContactStatus(hContact, dwStatus);
- setByte(hContact, DBSETTING_XSTATUSID, (BYTE)dwXStatus);
- if (StatusNameW.GetLength())
- mraSetStringW(hContact, DBSETTING_XSTATUSNAME, StatusNameW);
- if (StatusMsgW.GetLength())
- mraSetStringW(hContact, DBSETTING_XSTATUSMSG, StatusMsgW);
- }
- }
- else if (dwAckType == ACKTYPE_SEARCH) {
- wchar_t szNick[MAX_EMAIL_LEN] = { 0 },
- szFirstName[MAX_EMAIL_LEN] = { 0 },
- szLastName[MAX_EMAIL_LEN] = { 0 },
- szEmail[MAX_EMAIL_LEN] = { 0 };
- CMStringA mralpsUsernameValue;
- PROTOSEARCHRESULT psr = { 0 };
-
- psr.cbSize = sizeof(psr);
- psr.flags = PSR_UNICODE;
- psr.nick.w = szNick;
- psr.firstName.w = szFirstName;
- psr.lastName.w = szLastName;
- psr.email.w = szEmail;
- psr.id.w = szEmail;
-
- for (DWORD i = 0; i < dwFieldsNum; i++) {
- CMStringA &fld = pmralpsFields[i];
- if (fld == "Username") {
- buf >> val;
- mralpsUsernameValue = val;
- }
- else if (fld == "Domain") { // имя было уже задано ранее
- buf >> val;
- wcsncpy_s(szEmail, _A2T(mralpsUsernameValue + "@" + val), _TRUNCATE);
- }
- else if (fld == "Nickname") {
- buf >> valW;
- wcsncpy_s(szNick, valW, _TRUNCATE);
- }
- else if (fld == "FirstName") {
- buf >> valW;
- wcsncpy_s(szFirstName, valW, _TRUNCATE);
- }
- else if (fld == "LastName") {
- buf >> valW;
- wcsncpy_s(szLastName, valW, _TRUNCATE);
- }
- else buf >> val;
- }
- ProtoBroadcastAck(hContact, dwAckType, ACKRESULT_DATA, (HANDLE)seq, (LPARAM)&psr);
- }
- }
-
- delete[] pmralpsFields;
-
- switch (dwAckType) {
- case ACKTYPE_GETINFO:
- ProtoBroadcastAck(hContact, dwAckType, ACKRESULT_SUCCESS, (HANDLE)1, 0);
- break;
- case ACKTYPE_SEARCH:
- default:
- ProtoBroadcastAck(hContact, dwAckType, ACKRESULT_SUCCESS, (HANDLE)seq, 0);
- break;
- }
- break;
- }
- MraSendQueueFree(hSendQueueHandle, seq);
- return true;
-}
-
-bool CMraProto::CmdGame(BinBuffer &buf)
-{
- MCONTACT hContact;
- CMStringA szEmail, szData;
- DWORD dwGameSessionID, dwGameMsg, dwGameMsgID, dwTemp;
- buf >> szEmail >> dwGameSessionID >> dwGameMsg >> dwGameMsgID >> dwTemp >> szData;
-
- switch (dwGameMsg) {
- case GAME_CONNECTION_INVITE:
- if (m_iStatus != ID_STATUS_INVISIBLE)
- MraGame(szEmail, dwGameSessionID, GAME_DECLINE, dwGameMsgID, szData);
- break;
- case GAME_CONNECTION_ACCEPT:
- break;
- case GAME_DECLINE:
- break;
- case GAME_INC_VERSION:
- break;
- case GAME_NO_SUCH_GAME:// user invisible
- if ((hContact = MraHContactFromEmail(szEmail, FALSE, TRUE, nullptr)))
- if (MraGetContactStatus(hContact) == ID_STATUS_OFFLINE)
- MraSetContactStatus(hContact, ID_STATUS_INVISIBLE);
- break;
- case GAME_JOIN:
- break;
- case GAME_CLOSE:
- break;
- case GAME_SPEED:
- break;
- case GAME_SYNCHRONIZATION:
- break;
- case GAME_USER_NOT_FOUND:
- break;
- case GAME_ACCEPT_ACK:
- break;
- case GAME_PING:
- break;
- case GAME_RESULT:
- break;
- case GAME_MESSAGES_NUMBER:
- break;
- default:
- wchar_t szBuff[1024];
- mir_snwprintf(szBuff, TranslateT("MRIM_CS_GAME: unknown internal game message code: %lu"), dwGameMsg);
- MraPopupShowFromAgentW(MRA_POPUP_TYPE_DEBUG, szBuff);
- break;
- }
- return true;
-}
-
-bool CMraProto::CmdClist2(BinBuffer &buf)
-{
- DWORD dwTemp = buf.getDword();
- if (dwTemp == GET_CONTACTS_OK) { // received contact list
- m_groups.destroy();
-
- DWORD dwGroupsCount, dwContactFlag = 0, dwGroupID = 0, dwContactSeverFlags = 0, dwStatus = 0, dwXStatus, dwFutureFlags = 0, dwBlogStatusTime = 0;
- ULARGE_INTEGER dwBlogStatusID;
- CMStringA szGroupMask, szContactMask, szEmail, szString;
- CMStringA szCustomPhones, szSpecStatusUri, szUserAgentFormatted;
- CMStringW wszNick, wszString, wszGroupName, wszStatusTitle, wszStatusDesc, wszBlogStatus, wszBlogStatusMusic;
- buf >> dwGroupsCount >> szGroupMask >> szContactMask;
-
- int iGroupMode = getByte("GroupMode", 100);
-
- debugLogA("Groups: %s\n", szGroupMask.c_str());
- DWORD dwID = 0;
- for (DWORD i = 0; i < dwGroupsCount; i++) { //groups handle
- DWORD dwControlParam = 0, dwGroupFlags = 0;
- for (int j = 0; j < szGroupMask.GetLength(); j++) { //enumerating parameters
- switch (szGroupMask[j]) {
- case 's'://LPS
- buf >> wszString;
- break;
- case 'u'://UL
- buf >> dwTemp;
- break;
- }
-
- if (j == 0 && szGroupMask[j] == 'u') { // GroupFlags
- dwGroupFlags = dwTemp;
- dwControlParam++;
- }
- else if (j == 1 && szGroupMask[j] == 's') { // GroupName
- wszGroupName = wszString;
- dwControlParam++;
- }
- }
-
- // add/modify group
- if (dwControlParam > 1) { // все параметры правильно инициализированны!
- if (!(dwGroupFlags & CONTACT_FLAG_REMOVED)) {
- m_groups.insert(new MraGroupItem(dwID, dwGroupFlags, wszGroupName));
- Clist_GroupCreate(0, wszGroupName);
- }
-
- debugLogW(L"'%s', flags: %lu (", wszGroupName.c_str(), dwGroupFlags);
- if (dwGroupFlags & CONTACT_FLAG_REMOVED) debugLogA("CONTACT_FLAG_REMOVED, ");
- if (dwGroupFlags & CONTACT_FLAG_GROUP) debugLogA("CONTACT_FLAG_GROUP, ");
- if (dwGroupFlags & CONTACT_FLAG_INVISIBLE) debugLogA("CONTACT_FLAG_INVISIBLE, ");
- if (dwGroupFlags & CONTACT_FLAG_VISIBLE) debugLogA("CONTACT_FLAG_VISIBLE, ");
- if (dwGroupFlags & CONTACT_FLAG_IGNORE) debugLogA("CONTACT_FLAG_IGNORE, ");
- if (dwGroupFlags & CONTACT_FLAG_SHADOW) debugLogA("CONTACT_FLAG_SHADOW, ");
- if (dwGroupFlags & CONTACT_FLAG_AUTHORIZED) debugLogA("CONTACT_FLAG_AUTHORIZED, ");
- if (dwGroupFlags & CONTACT_FLAG_MULTICHAT) debugLogA("CONTACT_FLAG_MULTICHAT, ");
- if (dwGroupFlags & CONTACT_FLAG_UNICODE_NAME) debugLogA("CONTACT_FLAG_UNICODE_NAME, ");
- if (dwGroupFlags & CONTACT_FLAG_PHONE) debugLogA("CONTACT_FLAG_PHONE, ");
- debugLogA(")");
- }
- dwID++;
- }
-
- debugLogA("Contacts: %s\n", szContactMask.c_str());
- dwID = 20;
- while (!buf.eof()) {
- DWORD dwControlParam = 0;
- for (int j = 0; j < szContactMask.GetLength(); j++) { //enumerating parameters
- BYTE fieldType = szContactMask[j];
- if (fieldType == 'u')
- buf >> dwTemp;
-
- if (j == 0 && fieldType == 'u') { // Flags
- dwContactFlag = dwTemp;
- dwControlParam++;
- }
- else if (j == 1 && fieldType == 'u') { // Group id
- dwGroupID = dwTemp;
- dwControlParam++;
- }
- else if (j == 2 && fieldType == 's') { // Email
- buf >> szEmail;
- dwControlParam++;
- }
- else if (j == 3 && fieldType == 's') { // Nick
- buf >> wszNick;
- dwControlParam++;
- }
- else if (j == 4 && fieldType == 'u') { // Server flags
- dwContactSeverFlags = dwTemp;
- dwControlParam++;
- }
- else if (j == 5 && fieldType == 'u') { // Status
- dwStatus = dwTemp;
- dwControlParam++;
- }
- else if (j == 6 && fieldType == 's') { // Custom Phone number,
- buf >> szCustomPhones;
- dwControlParam++;
- }
- else if (j == 7 && fieldType == 's') { // spec_status_uri
- buf >> szSpecStatusUri;
- dwControlParam++;
- }
- else if (j == 8 && fieldType == 's') { // status_title
- buf >> wszStatusTitle;
- dwControlParam++;
- }
- else if (j == 9 && fieldType == 's') { // status_desc
- buf >> wszStatusDesc;
- dwControlParam++;
- }
- else if (j == 10 && fieldType == 'u') { // com_support (future flags)
- dwFutureFlags = dwTemp;
- dwControlParam++;
- }
- else if (j == 11 && fieldType == 's') { // user_agent (formated string)
- buf >> szUserAgentFormatted;
- dwControlParam++;
- }
- else if (j == 12 && fieldType == 'u') { // BlogStatusID
- dwBlogStatusID.LowPart = dwTemp;
- dwControlParam++;
- }
- else if (j == 13 && fieldType == 'u') { // BlogStatusID
- dwBlogStatusID.HighPart = dwTemp;
- dwControlParam++;
- }
- else if (j == 14 && fieldType == 'u') { // BlogStatusTime
- dwBlogStatusTime = dwTemp;
- dwControlParam++;
- }
- else if (j == 15 && fieldType == 's') { // BlogStatus
- buf >> wszBlogStatus;
- dwControlParam++;
- }
- else if (j == 16 && fieldType == 's') { // BlogStatusMusic
- buf >> wszBlogStatusMusic;
- dwControlParam++;
- }
- else if (j == 17 && fieldType == 's') { // BlogStatusSender // ignory
- buf >> szString;
- dwControlParam++;
- }
- else if (j == 18 && fieldType == 's') { // geo data ?
- buf >> szString;
- dwControlParam++;
- }
- else if (j == 19 && fieldType == 's') { // ?????? ?
- buf >> szString;
- dwControlParam++;
- _ASSERTE(szString.GetLength());
- }
- else {
- if (fieldType == 's') {
- buf >> szString;
- if (szString.GetLength()) {
- debugLogA(szString + " ");
- }
- }
- else if (fieldType == 'u') {
- char szBuff[50];
- mir_snprintf(szBuff, "%lu, ", dwTemp);//;
- debugLogA("%s ", szBuff);
- }
- else _CrtDbgBreak();
- }
- }
-
- debugLogA("ID: %lu, Group id: %lu, %s: flags: %lu (", dwID, dwGroupID, szEmail.c_str(), dwContactFlag);
- if (dwContactFlag & CONTACT_FLAG_REMOVED) debugLogA("CONTACT_FLAG_REMOVED, ");
- if (dwContactFlag & CONTACT_FLAG_GROUP) debugLogA("CONTACT_FLAG_GROUP, ");
- if (dwContactFlag & CONTACT_FLAG_INVISIBLE) debugLogA("CONTACT_FLAG_INVISIBLE, ");
- if (dwContactFlag & CONTACT_FLAG_VISIBLE) debugLogA("CONTACT_FLAG_VISIBLE, ");
- if (dwContactFlag & CONTACT_FLAG_IGNORE) debugLogA("CONTACT_FLAG_IGNORE, ");
- if (dwContactFlag & CONTACT_FLAG_SHADOW) debugLogA("CONTACT_FLAG_SHADOW, ");
- if (dwContactFlag & CONTACT_FLAG_AUTHORIZED) debugLogA("CONTACT_FLAG_AUTHORIZED, ");
- if (dwContactFlag & CONTACT_FLAG_MULTICHAT) debugLogA("CONTACT_FLAG_MULTICHAT, ");
- if (dwContactFlag & CONTACT_FLAG_UNICODE_NAME) debugLogA("CONTACT_FLAG_UNICODE_NAME, ");
- if (dwContactFlag & CONTACT_FLAG_PHONE) debugLogA("CONTACT_FLAG_PHONE, ");
- debugLogA(")");
-
- debugLogA(": server flags: %lu (", dwContactSeverFlags);
- if (dwContactSeverFlags & CONTACT_INTFLAG_NOT_AUTHORIZED) debugLogA("CONTACT_INTFLAG_NOT_AUTHORIZED, ");
- debugLogA(")");
-
- // add/modify contact
- if (dwGroupID != 103)//***deb filtering phone/sms contats
- if (_strnicmp(szEmail, "phone", 5))
- if (dwControlParam > 5)// все параметры правильно инициализированны!
- if ((dwContactFlag & (CONTACT_FLAG_GROUP | CONTACT_FLAG_REMOVED)) == 0) {
- BOOL bAdded;
- MCONTACT hContact = MraHContactFromEmail(szEmail, TRUE, FALSE, &bAdded);
- if (hContact) {
- // already in list, remove the duplicate
- if (GetContactBasicInfoW(hContact, &dwTemp, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr) == NO_ERROR && dwTemp != -1) {
- _CrtDbgBreak();
- }
- else {
- dwTemp = GetMirandaStatusFromMraStatus(dwStatus, GetMraXStatusIDFromMraUriStatus(szSpecStatusUri), &dwXStatus);
-
- 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, nullptr, &wszNick, &szCustomPhones);
- // request user info from server
- MraUpdateContactInfo(hContact);
- }
- else {
- if (iGroupMode == 100) { // first start
- ptrW tszGroup(db_get_wsa(hContact, "CList", "Group"));
- if (tszGroup)
- dwGroupID = MraMoveContactToGroup(hContact, dwGroupID, tszGroup);
- }
-
- SetContactBasicInfoW(hContact, SCBIFSI_LOCK_CHANGES_EVENTS, (SCBIF_ID | SCBIF_GROUP_ID | SCBIF_SERVER_FLAG | SCBIF_STATUS),
- dwID, dwGroupID, dwContactFlag, dwContactSeverFlags, dwTemp, nullptr, &wszNick, &szCustomPhones);
- if (wszNick.IsEmpty()) { // set the server-side nick
- wszNick = Clist_GetContactDisplayName(hContact);
- MraModifyContact(hContact, &dwID, &dwContactFlag, &dwGroupID, &szEmail, &wszNick, &szCustomPhones);
- }
- }
-
- MraContactCapabilitiesSet(hContact, dwFutureFlags);
- setByte(hContact, DBSETTING_XSTATUSID, (BYTE)dwXStatus);
- mraSetStringW(hContact, DBSETTING_XSTATUSNAME, wszStatusTitle);
- mraSetStringW(hContact, DBSETTING_XSTATUSMSG, wszStatusDesc);
- setDword(hContact, DBSETTING_BLOGSTATUSTIME, dwBlogStatusTime);
- mraWriteContactSettingBlob(hContact, DBSETTING_BLOGSTATUSID, &dwBlogStatusID.QuadPart, sizeof(DWORDLONG));
- mraSetStringW(hContact, DBSETTING_BLOGSTATUS, wszBlogStatus);
- mraSetStringW(hContact, DBSETTING_BLOGSTATUSMUSIC, wszBlogStatusMusic);
- if (IsXStatusValid(dwXStatus) || wszBlogStatus.GetLength())
- SetExtraIcons(hContact);
-
- if (dwTemp != ID_STATUS_OFFLINE) { // пишем клиента только если юзер не отключён, иначе не затираем старое
- if (!szUserAgentFormatted.IsEmpty()) {
- if (getByte("MirVerRaw", MRA_DEFAULT_MIRVER_RAW) == FALSE)
- szUserAgentFormatted = MraGetVersionStringFromFormatted(szUserAgentFormatted);
- }
- else szUserAgentFormatted = MIRVER_UNKNOWN;
- mraSetStringA(hContact, "MirVer", szUserAgentFormatted);
- }
-
- if (dwContactSeverFlags & CONTACT_INTFLAG_NOT_AUTHORIZED)
- if (getByte("AutoAuthRequestOnLogon", MRA_DEFAULT_AUTO_AUTH_REQ_ON_LOGON))
- CallProtoService(m_szModuleName, MRA_REQ_AUTH, hContact, 0);
- }
- }
- }
- dwID++;
- }// end while (processing contacts)
-
- // post processing contact list
- {
- CMStringA email, phones;
- CMStringW wszAuthMessage, nick;
-
- if (mraGetStringW(NULL, "AuthMessage", wszAuthMessage) == FALSE) // def auth message
- wszAuthMessage = TranslateW(MRA_DEFAULT_AUTH_MESSAGE);
-
- for (auto &hContact : AccContacts()) {
- if (GetContactBasicInfoW(hContact, &dwID, nullptr, nullptr, nullptr, nullptr, &email, nullptr, nullptr) == NO_ERROR)
- if (dwID == -1) {
- if (IsEMailChatAgent(email)) {// чат: ещё раз запросим авторизацию, пометим как видимый в списке, постоянный
- db_unset(hContact, "CList", "Hidden");
- db_unset(hContact, "CList", "NotOnList");
- SetExtraIcons(hContact);
- MraSetContactStatus(hContact, ID_STATUS_ONLINE);
-
- CMStringW wszCustomName = Clist_GetContactDisplayName(hContact);
- MraAddContact(hContact, (CONTACT_FLAG_VISIBLE | CONTACT_FLAG_MULTICHAT), -1, email, wszCustomName);
- }
- else {
- if (db_get_b(hContact, "CList", "NotOnList", 0) == 0) { // set extra icons and upload contact
- SetExtraIcons(hContact);
- if (getByte("AutoAddContactsToServer", MRA_DEFAULT_AUTO_ADD_CONTACTS_TO_SERVER)) { //add all contacts to server
- GetContactBasicInfoW(hContact, nullptr, &dwGroupID, nullptr, nullptr, nullptr, nullptr, &nick, &phones);
- MraAddContact(hContact, (CONTACT_FLAG_VISIBLE | CONTACT_FLAG_UNICODE_NAME), dwGroupID, email, nick, &phones, &wszAuthMessage);
- }
- }
- }
- MraUpdateContactInfo(hContact);
- }
- }
- }
- setByte("GroupMode", 1);
- }
- else { // контакт лист почемуто не получили
- // всех в offline и id в нестандарт
- for (auto &hContact : AccContacts()) {
- SetContactBasicInfoW(hContact, SCBIFSI_LOCK_CHANGES_EVENTS, (SCBIF_ID | SCBIF_GROUP_ID | SCBIF_SERVER_FLAG | SCBIF_STATUS),
- -1, -2, 0, 0, ID_STATUS_OFFLINE, nullptr, nullptr, nullptr);
- // request user info from server
- MraUpdateContactInfo(hContact);
- }
-
- if (dwTemp == GET_CONTACTS_ERROR) // найденный контакт-лист некорректен
- ShowFormattedErrorMessage(L"MRIM_CS_CONTACT_LIST2: bad contact list", NO_ERROR);
- else if (dwTemp == GET_CONTACTS_INTERR) // произошла внутренняя ошибка
- ShowFormattedErrorMessage(L"MRIM_CS_CONTACT_LIST2: internal server error", NO_ERROR);
- else {
- wchar_t szBuff[1024];
- mir_snwprintf(szBuff, TranslateT("MRIM_CS_CONTACT_LIST2: unknown server error, code: %lu"), dwTemp);
- MraPopupShowFromAgentW(MRA_POPUP_TYPE_DEBUG, szBuff);
- }
- }
- return true;
-}
-
-bool CMraProto::CmdProxy(BinBuffer &buf)
-{
- DWORD dwIDRequest, dwAckType;
- CMStringA szAddresses, szEmail, szString;
- MRA_GUID mguidSessionID;
-
- buf >> szEmail >> dwIDRequest >> dwAckType >> szString >> szAddresses >> mguidSessionID;
- if (dwAckType == MRIM_PROXY_TYPE_FILES) { // файлы, on file recv
- // set proxy info to file transfer context
- if (!MraMrimProxySetData(MraFilesQueueItemProxyByID(hFilesQueueHandle, dwIDRequest), szEmail, dwIDRequest, dwAckType, szString, szAddresses, &mguidSessionID))
- MraFilesQueueStartMrimProxy(hFilesQueueHandle, dwIDRequest);
- else { // empty/invalid session
- MraProxyAck(PROXY_STATUS_ERROR, szEmail, dwIDRequest, dwAckType, szString, szAddresses, mguidSessionID);
- _CrtDbgBreak();
- }
- }
- return true;
-}
-
-bool CMraProto::CmdProxyAck(BinBuffer &buf)
-{
- DWORD dwIDRequest, dwTemp, dwAckType;
- HANDLE hMraMrimProxyData;
- CMStringA szAddresses, szEmail, szString;
- MRA_GUID mguidSessionID;
- buf >> dwTemp >> szEmail >> dwIDRequest >> dwAckType >> szString >> szAddresses >> mguidSessionID;
-
- if (dwAckType == MRIM_PROXY_TYPE_FILES) { // on file send
- if ((hMraMrimProxyData = MraFilesQueueItemProxyByID(hFilesQueueHandle, dwIDRequest))) {
- switch (dwTemp) {
- case PROXY_STATUS_DECLINE:
- MraFilesQueueCancel(hFilesQueueHandle, dwIDRequest, FALSE);
- break;
- case PROXY_STATUS_OK:
- // set proxy info to file transfer context
- if (!MraMrimProxySetData(hMraMrimProxyData, szEmail, dwIDRequest, dwAckType, szString, szAddresses, &mguidSessionID))
- MraFilesQueueStartMrimProxy(hFilesQueueHandle, dwIDRequest);
- break;
- case PROXY_STATUS_ERROR:
- ShowFormattedErrorMessage(L"Proxy File transfer: error", NO_ERROR);
- MraFilesQueueCancel(hFilesQueueHandle, dwIDRequest, FALSE);
- break;
- case PROXY_STATUS_INCOMPATIBLE_VERS:
- ShowFormattedErrorMessage(L"Proxy File transfer: incompatible versions", NO_ERROR);
- MraFilesQueueCancel(hFilesQueueHandle, dwIDRequest, FALSE);
- break;
- case PROXY_STATUS_NOHARDWARE:
- case PROXY_STATUS_MIRROR:
- case PROXY_STATUS_CLOSED:
- default:
- _CrtDbgBreak();
- break;
- }
- }
- else _CrtDbgBreak();
- }
- return true;
-}
-
-bool CMraProto::CmdNewMail(BinBuffer &buf)
-{
- DWORD dwDate, dwUIDL, dwUnreadCount;
- CMStringA szEmail, szString;
- buf >> dwUnreadCount >> szEmail >> szString >> dwDate >> dwUIDL;
-
- if (dwUnreadCount > dwEmailMessagesTotal)
- dwEmailMessagesTotal += (dwUnreadCount - m_dwEmailMessagesUnread);
-
- DWORD dwSave = m_dwEmailMessagesUnread;
- m_dwEmailMessagesUnread = dwUnreadCount;// store new value
- if (getByte("IncrementalNewMailNotify", MRA_DEFAULT_INC_NEW_MAIL_NOTIFY) == 0 || dwSave < dwUnreadCount || dwUnreadCount == 0)
- MraUpdateEmailStatus(szEmail, szString, false);
- return true;
-}
-
-bool CMraProto::CmdBlogStatus(BinBuffer &buf)
-{
- DWORD dwTime, dwFlags;
- CMStringA szEmail, szString;
- CMStringW wszText;
- DWORDLONG dwBlogStatusID;
-
- buf >> dwFlags >> szEmail >> dwBlogStatusID >> dwTime >> wszText >> szString;
-
- if (MCONTACT hContact = MraHContactFromEmail(szEmail, FALSE, TRUE, nullptr)) {
- if (dwFlags & MRIM_BLOG_STATUS_MUSIC)
- mraSetStringW(hContact, DBSETTING_BLOGSTATUSMUSIC, wszText);
- else {
- setDword(hContact, DBSETTING_BLOGSTATUSTIME, dwTime);
- mraWriteContactSettingBlob(hContact, DBSETTING_BLOGSTATUSID, &dwBlogStatusID, sizeof(DWORDLONG));
- mraSetStringW(hContact, DBSETTING_BLOGSTATUS, wszText);
- }
- SetExtraIcons(hContact);
- }
- return true;
-}
-
-bool CMraProto::MraCommandDispatcher(mrim_packet_header_t *pmaHeader)
-{
- WCHAR szBuff[4096] = { 0 };
- DWORD dwTemp, dwAckType;
- size_t dwSize;
- MCONTACT hContact = NULL;
- LPBYTE pByte;
-
- debugLogA("Received packet %x\n", pmaHeader->msg);
-
- BinBuffer buf((LPBYTE)pmaHeader + sizeof(mrim_packet_header_t), pmaHeader->dlen);
-
- switch (pmaHeader->msg) {
- case MRIM_CS_HELLO_ACK: return CmdHelloAck(buf);
- case MRIM_CS_LOGIN_ACK: return CmdLoginAck();
- case MRIM_CS_LOGIN_REJ: return CmdLoginRejected(buf);
- case MRIM_CS_MESSAGE_ACK: return CmdMessageAck(buf);
- case MRIM_CS_MESSAGE_STATUS: return CmdMessageStatus(pmaHeader->seq, buf);
- case MRIM_CS_USER_INFO: return CmdUserInfo(buf);
- case MRIM_CS_OFFLINE_MESSAGE_ACK: return CmdOfflineMessageAck(buf);
- case MRIM_CS_AUTHORIZE_ACK: return CmdAuthAck(buf);
- case MRIM_CS_MPOP_SESSION: return CmdPopSession(buf);
- case MRIM_CS_FILE_TRANSFER: return CmdFileTransfer(buf);
- case MRIM_CS_FILE_TRANSFER_ACK: return CmdFileTransferAck(buf);
- case MRIM_CS_USER_STATUS: return CmdUserStatus(buf);
- case MRIM_CS_ADD_CONTACT_ACK:
- case MRIM_CS_MODIFY_CONTACT_ACK: return CmdContactAck(pmaHeader->msg, pmaHeader->seq, buf);
- case MRIM_CS_ANKETA_INFO: return CmdAnketaInfo(pmaHeader->seq, buf);
- case MRIM_CS_GAME: return CmdGame(buf);
- case MRIM_CS_CONTACT_LIST2: return CmdClist2(buf);
- case MRIM_CS_PROXY: return CmdProxy(buf);
- case MRIM_CS_PROXY_ACK: return CmdProxyAck(buf);
- case MRIM_CS_NEW_MAIL: return CmdNewMail(buf);
- case MRIM_CS_USER_BLOG_STATUS: return CmdBlogStatus(buf);
-
- case MRIM_CS_CONNECTION_PARAMS:// Изменение параметров соединения
- buf >> m_dwPingPeriod;
- m_dwNextPingSendTickTime = 0; // force send ping
- MraSendCMD(MRIM_CS_PING, nullptr, 0);
- break;
-
- case MRIM_CS_LOGOUT:// Пользователь отключен из-за параллельного входа с его логином.
- buf >> dwTemp;
- if (dwTemp == LOGOUT_NO_RELOGIN_FLAG)
- ShowFormattedErrorMessage(L"Another user connected with your login", NO_ERROR);
- return false;
-
- case MRIM_CS_MAILBOX_STATUS:
- buf >> dwTemp;
- if (dwTemp > dwEmailMessagesTotal)
- dwEmailMessagesTotal += (dwTemp - m_dwEmailMessagesUnread);
-
- dwAckType = m_dwEmailMessagesUnread;// save old value
- m_dwEmailMessagesUnread = dwTemp;// store new value
- if (getByte("IncrementalNewMailNotify", MRA_DEFAULT_INC_NEW_MAIL_NOTIFY) == 0 || dwAckType < dwTemp || dwTemp == 0)
- MraUpdateEmailStatus("", "", false);
- break;
-
- case MRIM_CS_SMS_ACK:
- buf >> dwTemp;
- if (MraSendQueueFind(hSendQueueHandle, pmaHeader->seq, nullptr, &hContact, &dwAckType, &pByte, &dwSize) == NO_ERROR) {
- /* pByte point to phone number ansi string. */
- /* dwAckType = ICQACKTYPE_SMS */
- CMStringA szEmail;
- if (mraGetStringA(NULL, "e-mail", szEmail)) {
- mir_snprintf((LPSTR)szBuff, sizeof(szBuff),
- "<sms_response><source>Mail.ru</source><deliverable>Yes</deliverable><network>Mail.ru, Russia</network><message_id>%s-1-1955988055-%s</message_id><destination>%s</destination><messages_left>0</messages_left></sms_response>\r\n",
- szEmail.c_str(), (LPSTR)pByte, (LPSTR)pByte);
- ProtoBroadcastAck(NULL, ICQACKTYPE_SMS, ACKRESULT_SENTREQUEST, (HANDLE)pmaHeader->seq, (LPARAM)szBuff);
- }
- mir_free(pByte);
- MraSendQueueFree(hSendQueueHandle, pmaHeader->seq);
- }
- else MraPopupShowFromAgentW(MRA_POPUP_TYPE_DEBUG, TranslateT("MRIM_CS_SMS_ACK: not found in queue"));
- break;
-
- case MRIM_CS_PROXY_HELLO:
- _CrtDbgBreak();
- break;
-
- case MRIM_CS_PROXY_HELLO_ACK:
- _CrtDbgBreak();
- break;
-
- case MRIM_CS_UNKNOWN:
- case MRIM_CS_UNKNOWN2:
- case MRIM_CS_USER_GEO:
- case MRIM_CS_SERVER_SETTINGS:
- break;
-
- default:
- debugLogA("Uknown packet type: %d", pmaHeader->msg);
- break;
- }
- return true;
-}
-
-// Сообщение
-DWORD CMraProto::MraRecvCommand_Message(DWORD dwTime, DWORD dwFlags, CMStringA &plpsFrom, CMStringA &plpsText, CMStringA &plpsRFTText, CMStringA &plpsMultiChatData)
-{
- DWORD dwBackColour;
- CMStringA lpszMessageExt;
- CMStringW wszMessage;
-
- PROTORECVEVENT pre = { 0 };
- pre.timestamp = dwTime;
-
- // check flags and datas
- if ((dwFlags & MESSAGE_FLAG_RTF) && plpsRFTText.IsEmpty())
- dwFlags &= ~MESSAGE_FLAG_RTF;
-
- if ((dwFlags & MESSAGE_FLAG_MULTICHAT) && plpsMultiChatData.IsEmpty())
- dwFlags &= ~MESSAGE_FLAG_MULTICHAT;
-
- // pre processing - extracting/decoding
- if (dwFlags & MESSAGE_FLAG_AUTHORIZE) { // extract auth message из обычного текста
- size_t dwAuthDataSize;
- LPBYTE lpbAuthData = (LPBYTE)mir_base64_decode(plpsText, &dwAuthDataSize);
- if (lpbAuthData) {
- BinBuffer buf(lpbAuthData, dwAuthDataSize);
-
- DWORD dwAuthPartsCount;
- CMStringA lpsAuthFrom;
- buf >> dwAuthPartsCount >> lpsAuthFrom;
- if (dwFlags & MESSAGE_FLAG_v1p16 && (dwFlags & MESSAGE_FLAG_CP1251) == 0) { // unicode text
- CMStringW lpsAuthMessageW;
- buf >> lpsAuthMessageW;
- wszMessage = lpsAuthMessageW;
- }
- else { // преобразуем в юникод текст только если он в АНСИ и если это не Флэш мультик и будильник тоже не нуждается в этом
- CMStringA lpsAuthMessage;
- buf >> lpsAuthMessage;
- wszMessage = ptrW(mir_a2u_cp(lpsAuthMessage, MRA_CODE_PAGE));
- }
- mir_free(lpbAuthData);
- }
- }
- else {
- // unicode text
- if ((dwFlags & (MESSAGE_FLAG_ALARM | MESSAGE_FLAG_FLASH | MESSAGE_FLAG_v1p16)) && (dwFlags & MESSAGE_FLAG_CP1251) == 0) {
- plpsText.AppendChar(0); // compensate difference between ASCIIZ & WCHARZ
- wszMessage = (WCHAR*)plpsText.GetString();
- }
- else wszMessage = plpsText;
-
- if (dwFlags & (MESSAGE_FLAG_CONTACT | MESSAGE_FLAG_NOTIFY | MESSAGE_FLAG_SMS | MESSAGE_SMS_DELIVERY_REPORT | MESSAGE_FLAG_ALARM))
- ; // do nothing; there's no extra part in a message
- else {
- if ((dwFlags & MESSAGE_FLAG_RTF) && !plpsRFTText.IsEmpty()) { //MESSAGE_FLAG_FLASH there
- size_t dwRFTBuffSize = ((plpsRFTText.GetLength() * 16) + 8192);
-
- mir_ptr<BYTE> lpbRTFData((LPBYTE)mir_calloc(dwRFTBuffSize));
- if (lpbRTFData) {
- size_t dwCompressedSize;
- mir_ptr<BYTE> lpbCompressed((LPBYTE)mir_base64_decode(plpsRFTText, &dwCompressedSize));
- DWORD dwRTFDataSize = (DWORD)dwRFTBuffSize;
- if (uncompress(lpbRTFData, &dwRTFDataSize, lpbCompressed, (uLong)dwCompressedSize) == Z_OK) {
- BinBuffer buf(lpbRTFData, dwRTFDataSize);
-
- CMStringA lpsRTFString, lpsBackColour, szString;
- DWORD dwRTFPartsCount;
-
- // количество частей в некоторых случаях больше 2, тогда нужно игнорировать первый текст, тк там сообщения об ущербности
- buf >> dwRTFPartsCount >> lpsRTFString >> dwBackColour;
- if (dwFlags & MESSAGE_FLAG_FLASH) {
- if (dwRTFPartsCount == 4) {
- buf >> szString;
- dwRTFPartsCount--;
- }
- if (dwRTFPartsCount == 3) { // ansi text only
- buf >> szString;
- wszMessage = ptrW(mir_a2u_cp(szString, MRA_CODE_PAGE));
- }
- else _CrtDbgBreak();
- }
- else { // RTF text
- if (dwRTFPartsCount > 2) {
- buf >> szString;
- _CrtDbgBreak();
- }
-
- lpszMessageExt = lpsRTFString;
- }
- }
- else _CrtDbgBreak();
- }
- }
- }
- }
-
- debugLogA("Processing message: %08X, from '%s', text '%S'\n", dwFlags, plpsFrom.c_str(), wszMessage.c_str());
-
- // processing
- if (dwFlags & (MESSAGE_FLAG_SMS | MESSAGE_SMS_DELIVERY_REPORT)) { // SMS
- INTERNET_TIME itTime;
- InternetTimeGetCurrentTime(&itTime);
- CMStringA szTime = InternetTimeGetString(&itTime);
- CMStringA szPhone = CopyNumber(plpsFrom), szEmail;
- if (!mraGetStringA(NULL, "e-mail", szEmail))
- return 0;
-
- CMStringW wszMessageXMLEncoded = EncodeXML(wszMessage);
- ptrA lpszMessageUTF(mir_utf8encodeW(wszMessageXMLEncoded));
-
- CMStringA szText;
- if (dwFlags & MESSAGE_SMS_DELIVERY_REPORT) {
- szText.Format("<sms_delivery_receipt><message_id>%s-1-1955988055-%s</message_id><destination>%s</destination><delivered>No</delivered><submition_time>%s</submition_time><error_code>0</error_code><error><id>15</id><params><param>%s</param></params></error></sms_delivery_receipt>",
- szEmail.c_str(), szPhone.c_str(), szPhone.c_str(), szTime.c_str(), lpszMessageUTF);
- ProtoBroadcastAck(NULL, ICQACKTYPE_SMS, ACKRESULT_FAILED, nullptr, (LPARAM)szText.GetString());
- }
- else { // new sms
- szText.Format("<sms_message><source>Mail.ru</source><destination_UIN>%s</destination_UIN><sender>%s</sender><senders_network>Mail.ru</senders_network><text>%s</text><time>%s</time></sms_message>",
- szEmail.c_str(), szPhone.c_str(), lpszMessageUTF, szTime.c_str());
- ProtoBroadcastAck(NULL, ICQACKTYPE_SMS, ACKRESULT_SUCCESS, nullptr, (LPARAM)szText.GetString());
- }
- }
- else {
- BOOL bAdded;
- MCONTACT hContact = MraHContactFromEmail(plpsFrom, TRUE, TRUE, &bAdded);
- if (bAdded)
- MraUpdateContactInfo(hContact);
-
- // user typing
- if (dwFlags & MESSAGE_FLAG_NOTIFY)
- CallService(MS_PROTO_CONTACTISTYPING, hContact, MAILRU_CONTACTISTYPING_TIMEOUT);
- else { // text/contact/auth // typing OFF
- CallService(MS_PROTO_CONTACTISTYPING, hContact, PROTOTYPE_CONTACTTYPING_OFF);
-
- if (dwFlags & MESSAGE_FLAG_MULTICHAT) {
- DWORD dwMultiChatEventType;
- CMStringA lpsEMailInMultiChat, szString;
- CMStringW lpsMultichatName;
-
- BinBuffer buf((PBYTE)plpsMultiChatData.GetString(), plpsMultiChatData.GetLength());
- buf >> dwMultiChatEventType >> lpsMultichatName >> lpsEMailInMultiChat;
-
- switch (dwMultiChatEventType) {
- case MULTICHAT_MESSAGE:
- MraChatSessionMessageAdd(hContact, lpsEMailInMultiChat, wszMessage, dwTime);// LPS sender
- break;
- case MULTICHAT_ADD_MEMBERS:
- MraChatSessionMembersAdd(hContact, lpsEMailInMultiChat, dwTime);// LPS sender
- buf >> szString;// CLPS members
- MraChatSessionSetIviter(hContact, lpsEMailInMultiChat);
- case MULTICHAT_MEMBERS:
- {
- DWORD dwMultiChatMembersCount;
- BinBuffer binBuf((PBYTE)lpsEMailInMultiChat.GetString(), lpsEMailInMultiChat.GetLength());
- binBuf >> dwMultiChatMembersCount;// count
- for (unsigned i = 0; i < dwMultiChatMembersCount && !binBuf.eof(); i++) {
- binBuf >> szString;
- MraChatSessionJoinUser(hContact, szString, ((dwMultiChatEventType == MULTICHAT_MEMBERS) ? 0 : dwTime));
- }
-
- if (dwMultiChatEventType == MULTICHAT_MEMBERS) {
- binBuf >> szString; // [ LPS owner ]
- MraChatSessionSetOwner(hContact, szString);
- }
- }
- break;
- case MULTICHAT_ATTACHED:
- MraChatSessionJoinUser(hContact, lpsEMailInMultiChat, dwTime);// LPS member
- break;
- case MULTICHAT_DETACHED:
- MraChatSessionLeftUser(hContact, lpsEMailInMultiChat, dwTime);// LPS member
- break;
- case MULTICHAT_INVITE:
- MraChatSessionInvite(hContact, lpsEMailInMultiChat, dwTime);// LPS sender
- MraAddContact(hContact, (CONTACT_FLAG_VISIBLE | CONTACT_FLAG_MULTICHAT | CONTACT_FLAG_UNICODE_NAME), -1, plpsFrom, lpsMultichatName);
- break;
- default:
- _CrtDbgBreak();
- break;
- }
- }
- else if (dwFlags & MESSAGE_FLAG_AUTHORIZE) { // auth request
- BOOL bAutoGrantAuth = FALSE;
-
- if (IsEMailChatAgent(plpsFrom))
- bAutoGrantAuth = FALSE;
- else {
- // temporary contact
- if (db_get_b(hContact, "CList", "NotOnList", 0)) {
- if (getByte("AutoAuthGrandNewUsers", MRA_DEFAULT_AUTO_AUTH_GRAND_NEW_USERS))
- bAutoGrantAuth = TRUE;
- }
- else if (getByte("AutoAuthGrandUsersInCList", MRA_DEFAULT_AUTO_AUTH_GRAND_IN_CLIST))
- bAutoGrantAuth = TRUE;
- }
-
- CMStringA szBlob = CreateBlobFromContact(hContact, wszMessage);
- if (bAutoGrantAuth) { // auto grant auth
- DBEVENTINFO dbei = {};
- dbei.szModule = m_szModuleName;
- dbei.timestamp = _time32(nullptr);
- dbei.flags = DBEF_READ | DBEF_UTF;
- dbei.eventType = EVENTTYPE_AUTHREQUEST;
- dbei.pBlob = (PBYTE)szBlob.c_str();
- dbei.cbBlob = szBlob.GetLength();
- db_event_add(0, &dbei);
- MraAuthorize(plpsFrom);
- }
- else {
- pre.szMessage = (LPSTR)szBlob.GetString();
- pre.lParam = szBlob.GetLength();
- ProtoChainRecv(hContact, PSR_AUTH, 0, (LPARAM)&pre);
- }
- }
- else {
- db_unset(hContact, "CList", "Hidden");
-
- if (dwFlags & MESSAGE_FLAG_CONTACT) { // contacts received
- ptrA lpbBuffer(mir_u2a_cp(wszMessage, MRA_CODE_PAGE));
- pre.flags = 0;
- pre.szMessage = (LPSTR)lpbBuffer;
- pre.lParam = mir_strlen(lpbBuffer);
-
- LPSTR lpbBufferCurPos = lpbBuffer;
- while (TRUE) { // цикл замены ; на 0
- lpbBufferCurPos = (LPSTR)MemoryFindByte((lpbBufferCurPos - (LPSTR)lpbBuffer), lpbBuffer, pre.lParam, ';');
- if (!lpbBufferCurPos)
- break;
-
- // found
- (*lpbBufferCurPos) = 0;
- lpbBufferCurPos ++;
- }
- ProtoChainRecv(hContact, PSR_CONTACTS, 0, (LPARAM)&pre);
- }
- else if (dwFlags & MESSAGE_FLAG_ALARM) { // alarm
- if (m_heNudgeReceived)
- NotifyEventHooks(m_heNudgeReceived, hContact, NULL);
- else {
- T2Utf szMsg(TranslateW(MRA_ALARM_MESSAGE));
- pre.szMessage = szMsg;
- ProtoChainRecvMsg(hContact, &pre);
- }
- }
- else { // standart message// flash animation
- // пишем в ANSI, всё равно RTF
- if ((dwFlags & MESSAGE_FLAG_RTF) && (dwFlags & MESSAGE_FLAG_FLASH) == 0 && !lpszMessageExt.IsEmpty() && getByte("RTFReceiveEnable", MRA_DEFAULT_RTF_RECEIVE_ENABLE)) {
- pre.flags = 0;
- pre.szMessage = (LPSTR)lpszMessageExt.GetString();
- ProtoChainRecvMsg(hContact, &pre);
- }
- else {
- // some plugins can change pre.szMessage pointer and we failed to free it
- ptrA lpszMessageUTF(mir_utf8encodeW(wszMessage));
- pre.szMessage = lpszMessageUTF;
- ProtoChainRecvMsg(hContact, &pre);
- }
-
- if (dwFlags & MESSAGE_FLAG_SYSTEM)
- MraPopupShowW(hContact, MRA_POPUP_TYPE_INFORMATION, TranslateT("Mail.ru System notify"), (LPWSTR)pre.szMessage);
- }
- }
- }
- }
-
- return NO_ERROR;
-}
-
-DWORD GetMraXStatusIDFromMraUriStatus(const char *szStatusUri)
-{
- if (szStatusUri)
- for (DWORD i = 0; lpcszStatusUri[i]; i++)
- if (!_stricmp(lpcszStatusUri[i], szStatusUri))
- return i;
-
- return MRA_XSTATUS_UNKNOWN;
-}
-
-DWORD GetMraStatusFromMiradaStatus(DWORD dwMirandaStatus, DWORD dwXStatusMir, DWORD *pdwXStatusMra)
-{
- if (IsXStatusValid(dwXStatusMir)) {
- if (pdwXStatusMra)
- *pdwXStatusMra = (dwXStatusMir + MRA_XSTATUS_INDEX_OFFSET - 1);
- return STATUS_USER_DEFINED;
- }
-
- switch (dwMirandaStatus) {
- case ID_STATUS_OFFLINE:
- if (pdwXStatusMra) *pdwXStatusMra = MRA_XSTATUS_OFFLINE;
- return STATUS_OFFLINE;
-
- case ID_STATUS_ONLINE:
- if (pdwXStatusMra) *pdwXStatusMra = MRA_XSTATUS_ONLINE;
- return STATUS_ONLINE;
-
- case ID_STATUS_AWAY:
- case ID_STATUS_NA:
- case ID_STATUS_ONTHEPHONE:
- case ID_STATUS_OUTTOLUNCH:
- if (pdwXStatusMra) *pdwXStatusMra = MRA_XSTATUS_AWAY;
- return STATUS_AWAY;
-
- case ID_STATUS_DND:
- case ID_STATUS_OCCUPIED:
- if (pdwXStatusMra) *pdwXStatusMra = MRA_XSTATUS_DND;
- return STATUS_USER_DEFINED;
-
- case ID_STATUS_FREECHAT:
- if (pdwXStatusMra) *pdwXStatusMra = MRA_XSTATUS_CHAT;
- return STATUS_USER_DEFINED;
-
- case ID_STATUS_INVISIBLE:
- if (pdwXStatusMra) *pdwXStatusMra = MRA_XSTATUS_INVISIBLE;
- return (STATUS_ONLINE | STATUS_FLAG_INVISIBLE);
- }
-
- if (pdwXStatusMra) *pdwXStatusMra = MRA_XSTATUS_OFFLINE;
- return STATUS_OFFLINE;
-}
-
-DWORD GetMirandaStatusFromMraStatus(DWORD dwMraStatus, DWORD dwXStatusMra, DWORD *pdwXStatusMir)
-{
- if (pdwXStatusMir) *pdwXStatusMir = 0;
-
- switch (dwMraStatus) {
- case STATUS_OFFLINE: return ID_STATUS_OFFLINE;
- case STATUS_ONLINE: return ID_STATUS_ONLINE;
- case STATUS_AWAY: return ID_STATUS_AWAY;
- case STATUS_UNDETERMINATED: return ID_STATUS_OFFLINE;
- case STATUS_USER_DEFINED:
- switch (dwXStatusMra) {
- case MRA_XSTATUS_DND: return ID_STATUS_DND;
- case MRA_XSTATUS_CHAT: return ID_STATUS_FREECHAT;
- case MRA_XSTATUS_MOBILE: return ID_STATUS_ONTHEPHONE;
- case MRA_XSTATUS_UNKNOWN:
- if (pdwXStatusMir) *pdwXStatusMir = MRA_MIR_XSTATUS_UNKNOWN;
- return ID_STATUS_ONLINE;
- }
- if (pdwXStatusMir) *pdwXStatusMir = dwXStatusMra - MRA_XSTATUS_INDEX_OFFSET + 1;
- return ID_STATUS_ONLINE;
- default:
- if (dwMraStatus & STATUS_FLAG_INVISIBLE)
- return ID_STATUS_INVISIBLE;
- }
-
- return ID_STATUS_OFFLINE;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////////////
-
-DWORD BinBuffer::getDword()
-{
- if (m_len >= sizeof(DWORD)) {
- DWORD ret = *(DWORD*)m_data;
- m_data += sizeof(DWORD);
- m_len -= sizeof(DWORD);
- return ret;
- }
- return 0;
-}
-
-DWORDLONG BinBuffer::getInt64()
-{
- if (m_len >= sizeof(DWORDLONG)) {
- DWORDLONG ret = *(DWORDLONG*)m_data;
- m_data += sizeof(DWORDLONG);
- m_len -= sizeof(DWORDLONG);
- return ret;
- }
- return 0;
-}
-
-MRA_GUID BinBuffer::getGuid()
-{
- MRA_GUID ret;
- if (m_len >= sizeof(MRA_GUID)) {
- ret = *(MRA_GUID*)m_data;
- m_data += sizeof(MRA_GUID);
- m_len -= sizeof(MRA_GUID);
- return ret;
- }
- else memset(&ret, 0, sizeof(ret));
- return ret;
-}
-
-void BinBuffer::getStringA(CMStringA& ret)
-{
- if (m_len >= sizeof(DWORD)) {
- DWORD dwLen = *(DWORD*)m_data;
- m_data += sizeof(DWORD);
- m_len -= sizeof(DWORD);
- if (m_len >= dwLen) {
- ret = CMStringA((LPSTR)m_data, dwLen);
- m_data += dwLen;
- m_len -= dwLen;
- return;
- }
- }
- ret.Empty();
-}
-
-void BinBuffer::getStringW(CMStringW& ret)
-{
- if (m_len >= sizeof(DWORD)) {
- DWORD dwLen = *(DWORD*)m_data;
- m_data += sizeof(DWORD);
- m_len -= sizeof(DWORD);
- if (m_len >= dwLen) {
- ret = CMStringW((LPWSTR)m_data, dwLen / 2);
- m_data += dwLen;
- m_len -= dwLen;
- return;
- }
- }
- ret.Empty();
-}