int CVkProto::OnDbEventRead(WPARAM, LPARAM hDbEvent) { debugLogA("CVkProto::OnDbEventRead"); MCONTACT hContact = db_event_getContact(hDbEvent); if (!hContact) return 0; CMStringA szProto(ptrA(db_get_sa(hContact, "Protocol", "p"))); if (szProto.IsEmpty() || szProto != m_szModuleName) return 0; if (m_vkOptions.iMarkMessageReadOn == MarkMsgReadOn::markOnRead) MarkMessagesRead(hContact); return 0; }
void CVkProto::OnSendMessage(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) { int iResult = ACKRESULT_FAILED; if (pReq->pUserInfo == NULL) { debugLogA("CVkProto::OnSendMessage failed! (pUserInfo == NULL)"); return; } CVkSendMsgParam *param = (CVkSendMsgParam *)pReq->pUserInfo; debugLogA("CVkProto::OnSendMessage %d", reply->resultCode); if (reply->resultCode == 200) { JSONNode jnRoot; const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot); if (jnResponse) { UINT mid; if (jnResponse.type() != JSON_STRING) mid = jnResponse.as_int(); else if (_stscanf(jnResponse.as_mstring(), _T("%d"), &mid) != 1) mid = 0; if (param->iMsgID != -1) m_sendIds.insert((HANDLE)mid); if (mid > getDword(param->hContact, "lastmsgid")) setDword(param->hContact, "lastmsgid", mid); if (m_vkOptions.iMarkMessageReadOn >= MarkMsgReadOn::markOnReply) MarkMessagesRead(param->hContact); iResult = ACKRESULT_SUCCESS; } } if (param->pFUP) { ProtoBroadcastAck(param->hContact, ACKTYPE_FILE, iResult, (HANDLE)(param->pFUP)); if (!pReq->bNeedsRestart || m_bTerminated) delete param->pFUP; } else if (m_bServerDelivery) ProtoBroadcastAck(param->hContact, ACKTYPE_MESSAGE, iResult, (HANDLE)(param->iMsgID)); if (!pReq->bNeedsRestart || m_bTerminated) { delete param; pReq->pUserInfo = NULL; } }
int CVkProto::UserIsTyping(MCONTACT hContact, int type) { debugLogA("CVkProto::UserIsTyping"); if (PROTOTYPE_SELFTYPING_ON == type) { LONG userID = getDword(hContact, "ID", -1); if (userID == -1 || !IsOnline() || userID == VK_FEED_USER) return 1; if (m_iMarkMessageReadOn == markOnTyping) MarkMessagesRead(hContact); Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/messages.setActivity.json", true, &CVkProto::OnReceiveSmth, AsyncHttpRequest::rpLow) << INT_PARAM("user_id", userID) << CHAR_PARAM("type", "typing") << VER_API); return 0; } return 1; }
void CVkProto::OnReceiveDlgs(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) { debugLogA("CVkProto::OnReceiveDlgs %d", reply->resultCode); if (reply->resultCode != 200) return; JSONNode jnRoot; const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot); if (!jnResponse) return; const JSONNode &jnDlgs = jnResponse["items"]; if (!jnDlgs) return; for (auto it = jnDlgs.begin(); it != jnDlgs.end(); ++it) { if (!(*it)) break; int numUnread = (*it)["unread"].as_int(); const JSONNode &jnDlg = (*it)["message"]; if (jnDlg == NULL) break; int uid = 0; MCONTACT hContact(NULL); int chatid = jnDlg["chat_id"].as_int(); if (!chatid) { uid = jnDlg["user_id"].as_int(); hContact = FindUser(uid, true); if (ServiceExists(MS_MESSAGESTATE_UPDATE)) { time_t tLastReadMessageTime = jnDlg["date"].as_int(); bool isOut = jnDlg["out"].as_bool(); bool isRead = jnDlg["read_state"].as_bool(); if (isRead && isOut) { MessageReadData data(tLastReadMessageTime, MRD_TYPE_MESSAGETIME); CallService(MS_MESSAGESTATE_UPDATE, hContact, (LPARAM)&data); } } } if (chatid) { debugLogA("CVkProto::OnReceiveDlgs chatid = %d", chatid); if (m_chats.find((CVkChatInfo*)&chatid) == NULL) AppendChat(chatid, jnDlg); } else if (m_vkOptions.iSyncHistoryMetod) { int mid = jnDlg["id"].as_int(); m_bNotifyForEndLoadingHistory = false; if (getDword(hContact, "lastmsgid", -1) == -1 && numUnread) GetServerHistory(hContact, 0, numUnread, 0, 0, true); else GetHistoryDlg(hContact, mid); if (m_vkOptions.iMarkMessageReadOn == MarkMsgReadOn::markOnReceive && numUnread) MarkMessagesRead(hContact); } else if (numUnread) { m_bNotifyForEndLoadingHistory = false; GetServerHistory(hContact, 0, numUnread, 0, 0, true); if (m_vkOptions.iMarkMessageReadOn == MarkMsgReadOn::markOnReceive) MarkMessagesRead(hContact); } } RetrieveUsersInfo(); }
void CVkProto::OnReceiveMessages(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) { debugLogA("CVkProto::OnReceiveMessages %d", reply->resultCode); if (reply->resultCode != 200) return; JSONNode jnRoot; const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot); if (!jnResponse) return; if (!jnResponse["Msgs"]) return; CMStringA mids; int numMessages = jnResponse["Msgs"]["count"].as_int(); const JSONNode &jnMsgs = jnResponse["Msgs"]["items"]; const JSONNode &jnFUsers = jnResponse["fwd_users"]; debugLogA("CVkProto::OnReceiveMessages numMessages = %d", numMessages); for (auto it = jnMsgs.begin(); it != jnMsgs.end(); ++it) { const JSONNode &jnMsg = (*it); if (!jnMsg) { debugLogA("CVkProto::OnReceiveMessages pMsg == NULL"); break; } UINT mid = jnMsg["id"].as_int(); CMString tszBody(jnMsg["body"].as_mstring()); int datetime = jnMsg["date"].as_int(); int isOut = jnMsg["out"].as_int(); int isRead = jnMsg["read_state"].as_int(); int uid = jnMsg["user_id"].as_int(); const JSONNode &jnFwdMessages = jnMsg["fwd_messages"]; if (jnFwdMessages) { CMString tszFwdMessages = GetFwdMessages(jnFwdMessages, jnFUsers, m_vkOptions.BBCForAttachments()); if (!tszBody.IsEmpty()) tszFwdMessages = _T("\n") + tszFwdMessages; tszBody += tszFwdMessages; } CMString tszAttachmentDescr; const JSONNode &jnAttachments = jnMsg["attachments"]; if (jnAttachments) { tszAttachmentDescr = GetAttachmentDescr(jnAttachments, m_vkOptions.BBCForAttachments()); if (!tszBody.IsEmpty()) tszBody += _T("\n"); tszBody += tszAttachmentDescr; } MCONTACT hContact = NULL; int chat_id = jnMsg["chat_id"].as_int(); if (chat_id == 0) hContact = FindUser(uid, true); char szMid[40]; _itoa(mid, szMid, 10); if (m_vkOptions.iMarkMessageReadOn == MarkMsgReadOn::markOnReceive || chat_id != 0) { if (!mids.IsEmpty()) mids.AppendChar(','); mids.Append(szMid); } if (chat_id != 0) { debugLogA("CVkProto::OnReceiveMessages chat_id != 0"); CMString action_chat = jnMsg["action"].as_mstring(); int action_mid = _ttoi(jnMsg["action_mid"].as_mstring()); if ((action_chat == "chat_kick_user") && (action_mid == m_myUserId)) KickFromChat(chat_id, uid, jnMsg, jnFUsers); else { MCONTACT chatContact = FindChat(chat_id); if (chatContact && getBool(chatContact, "kicked", true)) db_unset(chatContact, m_szModuleName, "kicked"); AppendChatMessage(chat_id, jnMsg, jnFUsers, false); } continue; } PROTORECVEVENT recv = { 0 }; bool bUseServerReadFlag = m_vkOptions.bSyncReadMessageStatusFromServer ? true : !m_vkOptions.bMesAsUnread; if (isRead && bUseServerReadFlag) recv.flags |= PREF_CREATEREAD; if (isOut) recv.flags |= PREF_SENT; else if (m_vkOptions.bUserForceInvisibleOnActivity && time(NULL) - datetime < 60 * m_vkOptions.iInvisibleInterval) SetInvisible(hContact); T2Utf pszBody(tszBody); recv.timestamp = m_vkOptions.bUseLocalTime ? time(NULL) : datetime; recv.szMessage = pszBody; recv.lParam = isOut; recv.pCustomData = szMid; recv.cbCustomDataSize = (int)mir_strlen(szMid); Sleep(100); debugLogA("CVkProto::OnReceiveMessages mid = %d, datetime = %d, isOut = %d, isRead = %d, uid = %d", mid, datetime, isOut, isRead, uid); if (!CheckMid(m_sendIds, mid)) { debugLogA("CVkProto::OnReceiveMessages ProtoChainRecvMsg"); ProtoChainRecvMsg(hContact, &recv); if (mid > getDword(hContact, "lastmsgid", -1)) setDword(hContact, "lastmsgid", mid); if (!isOut) m_incIds.insert((HANDLE)mid); } else if (m_vkOptions.bLoadSentAttachments && !tszAttachmentDescr.IsEmpty() && isOut) { T2Utf pszAttach(tszAttachmentDescr); recv.timestamp = time(NULL); // only local time recv.szMessage = pszAttach; ProtoChainRecvMsg(hContact, &recv); } } if (!mids.IsEmpty()) MarkMessagesRead(mids); }
INT_PTR CVkProto::SvcMarkMessagesAsRead(WPARAM hContact, LPARAM) { MarkDialogAsRead(hContact); MarkMessagesRead(hContact); return 0; }
void CVkProto::OnReceiveMessages(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) { debugLogA("CVkProto::OnReceiveMessages %d", reply->resultCode); if (reply->resultCode != 200) return; JSONROOT pRoot; JSONNODE *pResponse = CheckJsonResponse(pReq, reply, pRoot); if (pResponse == NULL) return; JSONNODE *pDlgs = json_as_array(json_get(pResponse, "dlgs")); if (pDlgs != NULL) { int numDialogs = json_as_int(json_at(pDlgs, 0)); for (int i = 1; i <= numDialogs; i++) { JSONNODE *pDlg = json_at(pDlgs, i); if (pDlg == NULL) continue; int chatid = json_as_int(json_get(pDlg, "chat_id")); if (chatid != 0) if (m_chats.find((CVkChatInfo*)&chatid) == NULL) { AppendChat(chatid, pDlg); } } } CMStringA mids, lmids; bool bDirectArray = false; JSONNODE *pMsgs = json_as_array(json_get(pResponse, "msgs")); if (pMsgs == NULL) { pMsgs = pResponse; bDirectArray = true; } int numMessages = json_as_int(json_at(pMsgs, 0)); for (int i = 1; i <= numMessages; i++) { JSONNODE *pMsg = json_at(pMsgs, i); if (pMsg == NULL) continue; char szMid[40]; int mid = json_as_int(json_get(pMsg, "mid")); _itoa(mid, szMid, 10); if (!mids.IsEmpty()) mids.AppendChar(','); mids.Append(szMid); int chat_id = json_as_int(json_get(pMsg, "chat_id")); if (chat_id != 0) { AppendChatMessage(chat_id, pMsg, false); continue; } // VK documentation lies: even if you specified preview_length=0, // long messages get cut out. So we need to retrieve them from scratch ptrT ptszBody(json_as_string(json_get(pMsg, "body"))); if (!bDirectArray && _tcslen(ptszBody) > 1000) { if (!lmids.IsEmpty()) lmids.AppendChar(','); lmids.Append(szMid); continue; } int datetime = json_as_int(json_get(pMsg, "date")); int isOut = json_as_int(json_get(pMsg, "out")); int uid = json_as_int(json_get(pMsg, "uid")); int isRead = json_as_int(json_get(pMsg, "read_state")); JSONNODE *pAttachments = json_get(pMsg, "attachments"); if (pAttachments != NULL) ptszBody = mir_tstrdup(CMString(ptszBody) + GetAttachmentDescr(pAttachments)); MCONTACT hContact = FindUser(uid, true); PROTORECVEVENT recv = { 0 }; recv.flags = PREF_TCHAR; if (isRead) recv.flags |= PREF_CREATEREAD; if (isOut) recv.flags |= PREF_SENT; recv.timestamp = datetime; recv.tszMessage = ptszBody; recv.lParam = isOut; recv.pCustomData = szMid; recv.cbCustomDataSize = (int)strlen(szMid); ProtoChainRecvMsg(hContact, &recv); } MarkMessagesRead(mids); RetrieveMessagesByIds(lmids); }