void CVkProto::AppendChatMessage(int id, JSONNODE *pMsg, bool bIsHistory) { CVkChatInfo *cc = AppendChat(id, NULL); if (cc == NULL) return; int mid = json_as_int(json_get(pMsg, "mid")); int isOut = json_as_int(json_get(pMsg, "out")); int uid = json_as_int(json_get(pMsg, "uid")); int msgTime = json_as_int(json_get(pMsg, "date")); time_t now = time(NULL); if (!msgTime || msgTime > now) msgTime = now; ptrT tszBody(json_as_string(json_get(pMsg, "body"))); JSONNODE *pAttachments = json_get(pMsg, "attachments"); if (pAttachments != NULL) tszBody = mir_tstrdup(CMString(tszBody) + GetAttachmentDescr(pAttachments)); if (cc->m_bHistoryRead) AppendChatMessage(cc, mid, uid, msgTime, tszBody, bIsHistory); else { CVkChatMessage *cm = cc->m_msgs.find((CVkChatMessage *)&mid); if (cm == NULL) cc->m_msgs.insert(cm = new CVkChatMessage(mid)); cm->m_uid = uid; cm->m_date = msgTime; cm->m_tszBody = tszBody.detouch(); cm->m_bHistory = bIsHistory; } }
void Netcode::ResetText() { m_messagesSent = 0; m_historyMessages.push_back(m_currentMessage); m_currentMessage = ""; AppendChatMessage(""); m_messagesSent++; }
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); }
void CVkProto::OnReceiveChatInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) { debugLogA("CVkProto::OnReceiveChatInfo %d", reply->resultCode); if (reply->resultCode != 200) return; JSONROOT pRoot; JSONNODE *pResponse = CheckJsonResponse(pReq, reply, pRoot); if (pResponse == NULL) return; CVkChatInfo *cc = (CVkChatInfo*)pReq->pUserInfo; if (m_chats.indexOf(cc) == -1) return; JSONNODE *info = json_get(pResponse, "info"); if (info != NULL) { ptrT tszTitle(json_as_string(json_get(info, "title"))); if (lstrcmp(tszTitle, cc->m_tszTopic)) { cc->m_tszTopic = mir_tstrdup(tszTitle); setTString(cc->m_hContact, "Nick", tszTitle); GCDEST gcd = { m_szModuleName, cc->m_tszId, GC_EVENT_CHANGESESSIONAME }; GCEVENT gce = { sizeof(GCEVENT), &gcd }; gce.ptszText = tszTitle; CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce); } cc->m_admin_id = json_as_int(json_get(info, "admin_id")); } JSONNODE *users = json_as_array(json_get(pResponse, "users")); if (users != NULL) { for (int i = 0; i < cc->m_users.getCount(); i++) cc->m_users[i].m_bDel = true; for (int i = 0;; i++) { JSONNODE *pUser = json_at(users, i); if (pUser == NULL) break; int uid = json_as_int(json_get(pUser, "uid")); TCHAR tszId[20]; _itot(uid, tszId, 10); bool bNew; CVkChatUser *cu = cc->m_users.find((CVkChatUser*)&uid); if (cu == NULL) { cc->m_users.insert(cu = new CVkChatUser(uid)); bNew = true; } else bNew = cu->m_bUnknown; cu->m_bDel = false; ptrT fName(json_as_string(json_get(pUser, "first_name"))); ptrT lName(json_as_string(json_get(pUser, "last_name"))); CMString tszNick = CMString(fName).Trim() + _T(" ") + CMString(lName).Trim(); cu->m_tszNick = mir_tstrdup(tszNick); cu->m_bUnknown = false; if (bNew) { GCDEST gcd = { m_szModuleName, cc->m_tszId, GC_EVENT_JOIN }; GCEVENT gce = { sizeof(GCEVENT), &gcd }; gce.bIsMe = uid == m_myUserId; gce.ptszUID = tszId; gce.ptszNick = tszNick; gce.ptszStatus = TranslateTS(sttStatuses[uid == cc->m_admin_id]); gce.dwItemData = (INT_PTR)cu; CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce); } } for (int i = cc->m_users.getCount() - 1; i >= 0; i--) { CVkChatUser &cu = cc->m_users[i]; if (!cu.m_bDel) continue; TCHAR tszId[20]; _itot(cu.m_uid, tszId, 10); GCDEST gcd = { m_szModuleName, cc->m_tszId, GC_EVENT_PART }; GCEVENT gce = { sizeof(GCEVENT), &gcd }; gce.ptszUID = tszId; CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce); cc->m_users.remove(i); } } JSONNODE *msgs = json_as_array(json_get(pResponse, "msgs")); if (msgs != NULL) { for (int i = 1;; i++) { JSONNODE *pMsg = json_at(msgs, i); if (pMsg == NULL) break; AppendChatMessage(cc->m_chatid, pMsg, true); } cc->m_bHistoryRead = true; } for (int j = 0; j < cc->m_msgs.getCount(); j++) { CVkChatMessage &p = cc->m_msgs[j]; AppendChatMessage(cc, p.m_mid, p.m_uid, p.m_date, p.m_tszBody, p.m_bHistory); } cc->m_msgs.destroy(); }
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); }