summaryrefslogtreecommitdiff
path: root/protocols/VKontakte/src/vk_messages.cpp
diff options
context:
space:
mode:
authorSergey Bolhovskoy <elzorfox@ya.ru>2015-02-27 08:21:24 +0000
committerSergey Bolhovskoy <elzorfox@ya.ru>2015-02-27 08:21:24 +0000
commitadb5cfe67a86c7340e337124c0b03d53c0d24fbb (patch)
treeb0c9eef92af2247360b832b4dfae4a55fbcb4991 /protocols/VKontakte/src/vk_messages.cpp
parent427c9ddf6b92e487f80b9856dbca6b71da5d8af7 (diff)
VKontakte: code reorganisation
git-svn-id: http://svn.miranda-ng.org/main/trunk@12277 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/VKontakte/src/vk_messages.cpp')
-rw-r--r--protocols/VKontakte/src/vk_messages.cpp346
1 files changed, 346 insertions, 0 deletions
diff --git a/protocols/VKontakte/src/vk_messages.cpp b/protocols/VKontakte/src/vk_messages.cpp
new file mode 100644
index 0000000000..b54c28fd73
--- /dev/null
+++ b/protocols/VKontakte/src/vk_messages.cpp
@@ -0,0 +1,346 @@
+/*
+Copyright (c) 2013-15 Miranda NG project (http://miranda-ng.org)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation version 2
+of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "stdafx.h"
+
+//////////////////////////////////////////////////////////////////////////////
+
+int CVkProto::RecvMsg(MCONTACT hContact, PROTORECVEVENT *pre)
+{
+ debugLogA("CVkProto::RecvMsg");
+ Proto_RecvMessage(hContact, pre);
+ return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+void CVkProto::SendMsgAck(void *param)
+{
+ debugLogA("CVkProto::SendMsgAck");
+ TFakeAckParams *ack = (TFakeAckParams*)param;
+ Sleep(100);
+ ProtoBroadcastAck(ack->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)ack->msgid, 0);
+ delete ack;
+}
+
+int CVkProto::SendMsg(MCONTACT hContact, int flags, const char *msg)
+{
+ debugLogA("CVkProto::SendMsg");
+ if (!IsOnline())
+ return 0;
+ LONG userID = getDword(hContact, "ID", -1);
+ if (userID == -1 || userID == VK_FEED_USER) {
+ ForkThread(&CVkProto::SendMsgAck, new TFakeAckParams(hContact, 0));
+ return 0;
+ }
+
+ ptrA szMsg;
+ if (flags & PREF_UTF)
+ szMsg = mir_strdup(msg);
+ else if (flags & PREF_UNICODE)
+ szMsg = mir_utf8encodeW((wchar_t*)&msg[mir_strlen(msg) + 1]);
+ else
+ szMsg = mir_utf8encode(msg);
+
+ int StickerId = 0;
+ ptrA retMsg(GetStickerId(szMsg, StickerId));
+
+ ULONG msgId = ::InterlockedIncrement(&m_msgId);
+ AsyncHttpRequest *pReq = new AsyncHttpRequest(this, REQUEST_POST, "/method/messages.send.json", true, &CVkProto::OnSendMessage)
+ << INT_PARAM("user_id", userID)
+ << VER_API;
+
+ if (StickerId != 0)
+ pReq << INT_PARAM("sticker_id", StickerId);
+ else
+ pReq << CHAR_PARAM("message", szMsg);
+
+ pReq->AddHeader("Content-Type", "application/x-www-form-urlencoded");
+ pReq->pUserInfo = new CVkSendMsgParam(hContact, msgId);
+ Push(pReq);
+
+ if (!m_bServerDelivery)
+ ForkThread(&CVkProto::SendMsgAck, new TFakeAckParams(hContact, msgId));
+
+ if (retMsg) {
+ int _flags = flags | PREF_UTF;
+ Sleep(330);
+ SendMsg(hContact, _flags, retMsg);
+ }
+ return msgId;
+}
+
+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) {
+ JSONROOT pRoot;
+ JSONNODE *pResponse = CheckJsonResponse(pReq, reply, pRoot);
+ if (pResponse != NULL) {
+ UINT mid = json_as_int(pResponse);
+ if (param->iMsgID != -1)
+ m_sendIds.insert((HANDLE)mid);
+ if (mid > getDword(param->hContact, "lastmsgid", 0))
+ setDword(param->hContact, "lastmsgid", mid);
+ if (m_iMarkMessageReadOn >= markOnReply)
+ MarkMessagesRead(param->hContact);
+ iResult = ACKRESULT_SUCCESS;
+ }
+ }
+
+ if (param->iMsgID == -1) {
+ CVkFileUploadParam *fup = (CVkFileUploadParam *)param->iCount;
+ ProtoBroadcastAck(fup->hContact, ACKTYPE_FILE, iResult, (HANDLE)fup, 0);
+ if (!pReq->bNeedsRestart)
+ delete fup;
+ return;
+ }
+ else if (m_bServerDelivery)
+ ProtoBroadcastAck(param->hContact, ACKTYPE_MESSAGE, iResult, HANDLE(param->iMsgID), 0);
+ if (!pReq->bNeedsRestart) {
+ delete param;
+ pReq->pUserInfo = NULL;
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+int CVkProto::OnDbEventRead(WPARAM hContact, LPARAM)
+{
+ debugLogA("CVkProto::OnDbEventRead");
+ if (m_iMarkMessageReadOn == markOnRead)
+ MarkMessagesRead(hContact);
+ return 0;
+}
+
+void CVkProto::MarkMessagesRead(const CMStringA &mids)
+{
+ debugLogA("CVkProto::MarkMessagesRead (mids)");
+ if (!IsOnline())
+ return;
+ if (mids.IsEmpty())
+ return;
+
+ Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/messages.markAsRead.json", true, &CVkProto::OnReceiveSmth)
+ << CHAR_PARAM("message_ids", mids)
+ << VER_API);
+}
+
+void CVkProto::MarkMessagesRead(const MCONTACT hContact)
+{
+ debugLogA("CVkProto::MarkMessagesRead (hContact)");
+ if (!IsOnline())
+ return;
+ LONG userID = getDword(hContact, "ID", -1);
+ if (userID == -1 || userID == VK_FEED_USER)
+ return;
+
+ Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/messages.markAsRead.json", true, &CVkProto::OnReceiveSmth)
+ << INT_PARAM("peer_id", userID)
+ << VER_API);
+}
+
+void CVkProto::RetrieveMessagesByIds(const CMStringA &mids)
+{
+ debugLogA("CVkProto::RetrieveMessagesByIds");
+ if (!IsOnline())
+ return;
+ if (mids.IsEmpty())
+ return;
+
+ Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/messages.getById.json", true, &CVkProto::OnReceiveMessages)
+ << CHAR_PARAM("message_ids", mids)
+ << VER_API);
+}
+
+void CVkProto::RetrieveUnreadMessages()
+{
+ debugLogA("CVkProto::RetrieveUnreadMessages");
+ if (!IsOnline())
+ return;
+ Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/messages.getDialogs.json", true, &CVkProto::OnReceiveDlgs)
+ << VER_API);
+}
+
+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;
+
+ CMStringA mids;
+ int numMessages = json_as_int(json_get(pResponse, "count"));
+ JSONNODE *pMsgs = json_get(pResponse, "items");
+
+ debugLogA("CVkProto::OnReceiveMessages numMessages = %d", numMessages);
+
+ for (int i = 0; i < numMessages; i++) {
+ JSONNODE *pMsg = json_at(pMsgs, i);
+ if (pMsg == NULL) {
+ debugLogA("CVkProto::OnReceiveMessages pMsg == NULL");
+ break;
+ }
+
+ UINT mid = json_as_int(json_get(pMsg, "id"));
+ ptrT ptszBody(json_as_string(json_get(pMsg, "body")));
+ int datetime = json_as_int(json_get(pMsg, "date"));
+ int isOut = json_as_int(json_get(pMsg, "out"));
+ int isRead = json_as_int(json_get(pMsg, "read_state"));
+ int uid = json_as_int(json_get(pMsg, "user_id"));
+
+ JSONNODE *pFwdMessages = json_get(pMsg, "fwd_messages");
+ if (pFwdMessages != NULL){
+ CMString tszFwdMessages = GetFwdMessages(pFwdMessages, m_iBBCForAttachments);
+ if (!IsEmpty(ptszBody))
+ tszFwdMessages = _T("\n") + tszFwdMessages;
+ ptszBody = mir_tstrdup(CMString(ptszBody) + tszFwdMessages);
+ }
+
+ JSONNODE *pAttachments = json_get(pMsg, "attachments");
+ if (pAttachments != NULL){
+ CMString tszAttachmentDescr = GetAttachmentDescr(pAttachments, m_iBBCForAttachments);
+ if (!IsEmpty(ptszBody))
+ tszAttachmentDescr = _T("\n") + tszAttachmentDescr;
+ ptszBody = mir_tstrdup(CMString(ptszBody) + tszAttachmentDescr);
+ }
+
+ MCONTACT hContact = NULL;
+ int chat_id = json_as_int(json_get(pMsg, "chat_id"));
+ if (chat_id == 0)
+ hContact = FindUser(uid, true);
+
+ char szMid[40];
+ _itoa(mid, szMid, 10);
+ if (m_iMarkMessageReadOn == 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 = json_as_CMString(json_get(pMsg, "action"));
+ int action_mid = _ttoi(json_as_CMString(json_get(pMsg, "action_mid")));
+ if ((action_chat == "chat_kick_user") && (action_mid == m_myUserId))
+ KickFromChat(chat_id, uid, pMsg);
+ else
+ AppendChatMessage(chat_id, pMsg, false);
+ continue;
+ }
+
+ PROTORECVEVENT recv = { 0 };
+ recv.flags = PREF_TCHAR;
+ if (isRead && !m_bMesAsUnread)
+ recv.flags |= PREF_CREATEREAD;
+ if (isOut)
+ recv.flags |= PREF_SENT;
+ else if (m_bUserForceOnlineOnActivity)
+ SetInvisible(hContact);
+
+ recv.timestamp = m_bUseLocalTime ? time(NULL) : datetime;
+ recv.tszMessage = ptszBody;
+ recv.lParam = isOut;
+ recv.pCustomData = szMid;
+ recv.cbCustomDataSize = (int)mir_strlen(szMid);
+ Sleep(100);
+
+ debugLogA("CVkProto::OnReceiveMessages i = %d, mid = %d, datetime = %d, isOut = %d, isRead = %d, uid = %d", i, 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);
+ }
+ }
+
+ if (!mids.IsEmpty())
+ MarkMessagesRead(mids);
+}
+
+void CVkProto::OnReceiveDlgs(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+{
+ debugLogA("CVkProto::OnReceiveDlgs %d", reply->resultCode);
+ if (reply->resultCode != 200)
+ return;
+
+ JSONROOT pRoot;
+ JSONNODE *pResponse = CheckJsonResponse(pReq, reply, pRoot);
+ if (pResponse == NULL)
+ return;
+
+ int numDlgs = json_as_int(json_get(pResponse, "count"));
+ JSONNODE *pDlgs = json_get(pResponse, "items");
+
+ if (pDlgs == NULL)
+ return;
+
+ for (int i = 0; i < numDlgs; i++) {
+ JSONNODE *pDlg = json_at(pDlgs, i);
+ if (pDlg == NULL)
+ break;
+
+ int numUnread = json_as_int(json_get(pDlg, "unread"));
+
+ pDlg = json_get(pDlg, "message");
+ if (pDlg == NULL)
+ break;
+
+ int chatid = json_as_int(json_get(pDlg, "chat_id"));
+ if (chatid != 0) {
+ debugLogA("CVkProto::OnReceiveDlgs chatid = %d", chatid);
+ if (m_chats.find((CVkChatInfo*)&chatid) == NULL)
+ AppendChat(chatid, pDlg);
+ }
+ else if (m_iSyncHistoryMetod) {
+ int mid = json_as_int(json_get(pDlg, "id"));
+ int uid = json_as_int(json_get(pDlg, "user_id"));
+ MCONTACT hContact = FindUser(uid, true);
+
+ if (getDword(hContact, "lastmsgid", -1) == -1 && numUnread)
+ GetServerHistory(hContact, 0, numUnread, 0, 0, true);
+ else
+ GetHistoryDlg(hContact, mid);
+
+ if (m_iMarkMessageReadOn == markOnReceive && numUnread)
+ MarkMessagesRead(hContact);
+ }
+ else if (numUnread) {
+ int uid = json_as_int(json_get(pDlg, "user_id"));
+ MCONTACT hContact = FindUser(uid, true);
+ GetServerHistory(hContact, 0, numUnread, 0, 0, true);
+
+ if (m_iMarkMessageReadOn == markOnReceive)
+ MarkMessagesRead(hContact);
+ }
+ }
+ RetrieveUsersInfo();
+}