summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--protocols/VKontakte/src/vk_messages.cpp346
-rw-r--r--protocols/VKontakte/src/vk_pollserver.cpp239
-rw-r--r--protocols/VKontakte/src/vk_proto.cpp107
-rw-r--r--protocols/VKontakte/src/vk_thread.cpp444
-rw-r--r--protocols/VKontakte/vk_10.vcxproj2
-rw-r--r--protocols/VKontakte/vk_10.vcxproj.filters6
-rw-r--r--protocols/VKontakte/vk_12.vcxproj2
-rw-r--r--protocols/VKontakte/vk_12.vcxproj.filters6
8 files changed, 601 insertions, 551 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();
+}
diff --git a/protocols/VKontakte/src/vk_pollserver.cpp b/protocols/VKontakte/src/vk_pollserver.cpp
new file mode 100644
index 0000000000..e4ea16302f
--- /dev/null
+++ b/protocols/VKontakte/src/vk_pollserver.cpp
@@ -0,0 +1,239 @@
+/*
+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"
+
+void CVkProto::RetrievePollingInfo()
+{
+ debugLogA("CVkProto::RetrievePollingInfo");
+ if (!IsOnline())
+ return;
+ Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/messages.getLongPollServer.json", true, &CVkProto::OnReceivePollingInfo)
+ << INT_PARAM("use_ssl", 1)
+ << VER_API);
+}
+
+void CVkProto::OnReceivePollingInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
+{
+ debugLogA("CVkProto::OnReceivePollingInfo %d", reply->resultCode);
+ if (reply->resultCode != 200)
+ return;
+
+ JSONROOT pRoot;
+ JSONNODE *pResponse = CheckJsonResponse(pReq, reply, pRoot);
+ if (pResponse == NULL)
+ return;
+
+ m_pollingTs = mir_t2a(ptrT(json_as_string(json_get(pResponse, "ts"))));
+ m_pollingKey = mir_t2a(ptrT(json_as_string(json_get(pResponse, "key"))));
+ m_pollingServer = mir_t2a(ptrT(json_as_string(json_get(pResponse, "server"))));
+ if (!m_hPollingThread) {
+ debugLogA("CVkProto::OnReceivePollingInfo m_hPollingThread is NULL");
+ debugLogA("CVkProto::OnReceivePollingInfo m_pollingTs = \'%s' m_pollingKey = \'%s\' m_pollingServer = \'%s\'",
+ m_pollingTs ? m_pollingTs : "<NULL>",
+ m_pollingKey ? m_pollingKey : "<NULL>",
+ m_pollingServer ? m_pollingServer : "<NULL>");
+ if (m_pollingTs != NULL && m_pollingKey != NULL && m_pollingServer != NULL) {
+ debugLogA("CVkProto::OnReceivePollingInfo PollingThread starting...");
+ m_hPollingThread = ForkThreadEx(&CVkProto::PollingThread, NULL, NULL);
+ }
+ else {
+ debugLogA("CVkProto::OnReceivePollingInfo PollingThread not start");
+ m_pollingConn = NULL;
+ ShutdownSession();
+ return;
+ }
+ }
+ else
+ debugLogA("CVkProto::OnReceivePollingInfo m_hPollingThread is not NULL");
+}
+
+void CVkProto::PollUpdates(JSONNODE *pUpdates)
+{
+ debugLogA("CVkProto::PollUpdates");
+ CMStringA mids;
+ int msgid, uid, flags, platform;
+ MCONTACT hContact;
+
+ JSONNODE *pChild;
+ for (int i = 0; (pChild = json_at(pUpdates, i)) != NULL; i++) {
+ switch (json_as_int(json_at(pChild, 0))) {
+ case VKPOLL_MSG_DELFLAGS:
+ msgid = json_as_int(json_at(pChild, 1));
+ flags = json_as_int(json_at(pChild, 2));
+ uid = json_as_int(json_at(pChild, 3));
+ hContact = FindUser(uid);
+
+ if (hContact != NULL && (flags & VKFLAG_MSGUNREAD) && !CheckMid(m_incIds, msgid)) {
+ setDword(hContact, "LastMsgReadTime", time(NULL));
+ SetSrmmReadStatus(hContact);
+ if (m_bUserForceOnlineOnActivity)
+ SetInvisible(hContact);
+ }
+ break;
+
+ case VKPOLL_MSG_ADDED: // new message
+ msgid = json_as_int(json_at(pChild, 1));
+
+ // skip outgoing messages sent from a client
+ flags = json_as_int(json_at(pChild, 2));
+ if (flags & VKFLAG_MSGOUTBOX && !(flags & VKFLAG_MSGCHAT))
+ if (CheckMid(m_sendIds, msgid))
+ break;
+
+ if (!mids.IsEmpty())
+ mids.AppendChar(',');
+ mids.AppendFormat("%d", msgid);
+ break;
+
+ case VKPOLL_READ_ALL_OUT:
+ uid = json_as_int(json_at(pChild, 1));
+ hContact = FindUser(uid);
+ if (hContact != NULL) {
+ setDword(hContact, "LastMsgReadTime", time(NULL));
+ SetSrmmReadStatus(hContact);
+ if (m_bUserForceOnlineOnActivity)
+ SetInvisible(hContact);
+ }
+ break;
+
+ case VKPOLL_USR_ONLINE:
+ uid = -json_as_int(json_at(pChild, 1));
+ if ((hContact = FindUser(uid)) != NULL) {
+ setWord(hContact, "Status", ID_STATUS_ONLINE);
+ platform = json_as_int(json_at(pChild, 2));
+ SetMirVer(hContact, platform);
+ }
+ break;
+
+ case VKPOLL_USR_OFFLINE:
+ uid = -json_as_int(json_at(pChild, 1));
+ if ((hContact = FindUser(uid)) != NULL) {
+ setWord(hContact, "Status", ID_STATUS_OFFLINE);
+ db_unset(hContact, m_szModuleName, "ListeningTo");
+ SetMirVer(hContact, -1);
+ }
+ break;
+
+ case VKPOLL_USR_UTN:
+ uid = json_as_int(json_at(pChild, 1));
+ hContact = FindUser(uid);
+ if (hContact != NULL) {
+ ForkThread(&CVkProto::ContactTypingThread, (void *)hContact);
+ if (m_bUserForceOnlineOnActivity)
+ SetInvisible(hContact);
+ }
+ break;
+
+ case VKPOLL_CHAT_CHANGED:
+ int chat_id = json_as_int(json_at(pChild, 1));
+ CVkChatInfo *cc = m_chats.find((CVkChatInfo*)&chat_id);
+ if (cc)
+ RetrieveChatInfo(cc);
+ break;
+ }
+ }
+
+ RetrieveMessagesByIds(mids);
+}
+
+int CVkProto::PollServer()
+{
+ debugLogA("CVkProto::PollServer");
+ if (!IsOnline()) {
+ debugLogA("CVkProto::PollServer is dead (not online)");
+ m_pollingConn = NULL;
+ ShutdownSession();
+ return 0;
+ }
+
+ debugLogA("CVkProto::PollServer (online)");
+ int iPollConnRetry = MAX_RETRIES;
+ NETLIBHTTPREQUEST *reply;
+ CMStringA szReqUrl;
+ szReqUrl.AppendFormat("https://%s?act=a_check&key=%s&ts=%s&wait=25&access_token=%s&mode=%d", m_pollingServer, m_pollingKey, m_pollingTs, m_szAccessToken, 106);
+ // see mode parametr description on https://vk.com/dev/using_longpoll (Russian version)
+ NETLIBHTTPREQUEST req = { sizeof(req) };
+ req.requestType = REQUEST_GET;
+ req.szUrl = mir_strdup(szReqUrl.GetBuffer());
+ req.flags = VK_NODUMPHEADERS | NLHRF_PERSISTENT | NLHRF_HTTP11;
+ req.timeout = 30000;
+ req.nlc = m_pollingConn;
+
+ while ((reply = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNetlibUser, (LPARAM)&req)) == NULL) {
+ debugLogA("CVkProto::PollServer is dead");
+ m_pollingConn = NULL;
+ if (iPollConnRetry && !m_bTerminated) {
+ iPollConnRetry--;
+ debugLogA("CVkProto::PollServer restarting %d", MAX_RETRIES - iPollConnRetry);
+ Sleep(1000);
+ }
+ else {
+ debugLogA("CVkProto::PollServer => ShutdownSession");
+ mir_free(req.szUrl);
+ ShutdownSession();
+ return 0;
+ }
+ }
+
+ mir_free(req.szUrl);
+
+ int retVal = 0;
+ if (reply->resultCode == 200) {
+ JSONROOT pRoot(reply->pData);
+ JSONNODE *pFailed = json_get(pRoot, "failed");
+ if (pFailed != NULL && json_as_int(pFailed) == 2) {
+ RetrievePollingInfo();
+ retVal = -1;
+ debugLogA("Polling key expired, restarting polling thread");
+ }
+ else if (CheckJsonResult(NULL, pRoot)) {
+ m_pollingTs = mir_t2a(ptrT(json_as_string(json_get(pRoot, "ts"))));
+ JSONNODE *pUpdates = json_get(pRoot, "updates");
+ if (pUpdates != NULL)
+ PollUpdates(pUpdates);
+ retVal = 1;
+ }
+ }
+ else if ((reply->resultCode >= 400 && reply->resultCode <= 417)
+ || (reply->resultCode >= 500 && reply->resultCode <= 509)) {
+ debugLogA("CVkProto::PollServer is dead. Error code - %d", reply->resultCode);
+ m_pollingConn = NULL;
+ CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)reply);
+ ShutdownSession();
+ return 0;
+ }
+
+ m_pollingConn = reply->nlc;
+
+ CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)reply);
+ debugLogA("CVkProto::PollServer return %d", retVal);
+ return retVal;
+}
+
+void CVkProto::PollingThread(void*)
+{
+ debugLogA("CVkProto::PollingThread: entering");
+
+ while (!m_bTerminated)
+ if (PollServer() == -1)
+ break;
+
+ m_hPollingThread = NULL;
+ m_pollingConn = NULL;
+ debugLogA("CVkProto::PollingThread: leaving");
+} \ No newline at end of file
diff --git a/protocols/VKontakte/src/vk_proto.cpp b/protocols/VKontakte/src/vk_proto.cpp
index a73b2e8267..a1b13558ad 100644
--- a/protocols/VKontakte/src/vk_proto.cpp
+++ b/protocols/VKontakte/src/vk_proto.cpp
@@ -453,113 +453,6 @@ DWORD_PTR CVkProto::GetCaps(int type, MCONTACT)
//////////////////////////////////////////////////////////////////////////////
-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::OnEvent(PROTOEVENTTYPE event, WPARAM wParam, LPARAM lParam)
{
switch (event) {
diff --git a/protocols/VKontakte/src/vk_thread.cpp b/protocols/VKontakte/src/vk_thread.cpp
index 306fda8600..cd02bc11e1 100644
--- a/protocols/VKontakte/src/vk_thread.cpp
+++ b/protocols/VKontakte/src/vk_thread.cpp
@@ -536,450 +536,6 @@ void CVkProto::OnReceiveFriends(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq
/////////////////////////////////////////////////////////////////////////////////////////
-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();
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CVkProto::RetrievePollingInfo()
-{
- debugLogA("CVkProto::RetrievePollingInfo");
- if (!IsOnline())
- return;
- Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/messages.getLongPollServer.json", true, &CVkProto::OnReceivePollingInfo)
- << INT_PARAM("use_ssl", 1)
- << VER_API);
-}
-
-void CVkProto::OnReceivePollingInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq)
-{
- debugLogA("CVkProto::OnReceivePollingInfo %d", reply->resultCode);
- if (reply->resultCode != 200)
- return;
-
- JSONROOT pRoot;
- JSONNODE *pResponse = CheckJsonResponse(pReq, reply, pRoot);
- if (pResponse == NULL)
- return;
-
- m_pollingTs = mir_t2a(ptrT(json_as_string(json_get(pResponse, "ts"))));
- m_pollingKey = mir_t2a(ptrT(json_as_string(json_get(pResponse, "key"))));
- m_pollingServer = mir_t2a(ptrT(json_as_string(json_get(pResponse, "server"))));
- if (!m_hPollingThread) {
- debugLogA("CVkProto::OnReceivePollingInfo m_hPollingThread is NULL");
- debugLogA("CVkProto::OnReceivePollingInfo m_pollingTs = \'%s' m_pollingKey = \'%s\' m_pollingServer = \'%s\'",
- m_pollingTs ? m_pollingTs : "<NULL>",
- m_pollingKey ? m_pollingKey : "<NULL>",
- m_pollingServer ? m_pollingServer : "<NULL>");
- if (m_pollingTs != NULL && m_pollingKey != NULL && m_pollingServer != NULL) {
- debugLogA("CVkProto::OnReceivePollingInfo PollingThread starting...");
- m_hPollingThread = ForkThreadEx(&CVkProto::PollingThread, NULL, NULL);
- }
- else {
- debugLogA("CVkProto::OnReceivePollingInfo PollingThread not start");
- m_pollingConn = NULL;
- ShutdownSession();
- return;
- }
- }
- else
- debugLogA("CVkProto::OnReceivePollingInfo m_hPollingThread is not NULL");
-}
-
-void CVkProto::PollUpdates(JSONNODE *pUpdates)
-{
- debugLogA("CVkProto::PollUpdates");
- CMStringA mids;
- int msgid, uid, flags, platform;
- MCONTACT hContact;
-
- JSONNODE *pChild;
- for (int i = 0; (pChild = json_at(pUpdates, i)) != NULL; i++) {
- switch (json_as_int(json_at(pChild, 0))) {
- case VKPOLL_MSG_DELFLAGS:
- msgid = json_as_int(json_at(pChild, 1));
- flags = json_as_int(json_at(pChild, 2));
- uid = json_as_int(json_at(pChild, 3));
- hContact = FindUser(uid);
-
- if (hContact != NULL && (flags & VKFLAG_MSGUNREAD) && !CheckMid(m_incIds, msgid)) {
- setDword(hContact, "LastMsgReadTime", time(NULL));
- SetSrmmReadStatus(hContact);
- if (m_bUserForceOnlineOnActivity)
- SetInvisible(hContact);
- }
- break;
-
- case VKPOLL_MSG_ADDED: // new message
- msgid = json_as_int(json_at(pChild, 1));
-
- // skip outgoing messages sent from a client
- flags = json_as_int(json_at(pChild, 2));
- if (flags & VKFLAG_MSGOUTBOX && !(flags & VKFLAG_MSGCHAT))
- if (CheckMid(m_sendIds, msgid))
- break;
-
- if (!mids.IsEmpty())
- mids.AppendChar(',');
- mids.AppendFormat("%d", msgid);
- break;
-
- case VKPOLL_READ_ALL_OUT:
- uid = json_as_int(json_at(pChild, 1));
- hContact = FindUser(uid);
- if (hContact != NULL) {
- setDword(hContact, "LastMsgReadTime", time(NULL));
- SetSrmmReadStatus(hContact);
- if (m_bUserForceOnlineOnActivity)
- SetInvisible(hContact);
- }
- break;
-
- case VKPOLL_USR_ONLINE:
- uid = -json_as_int(json_at(pChild, 1));
- if ((hContact = FindUser(uid)) != NULL) {
- setWord(hContact, "Status", ID_STATUS_ONLINE);
- platform = json_as_int(json_at(pChild, 2));
- SetMirVer(hContact, platform);
- }
- break;
-
- case VKPOLL_USR_OFFLINE:
- uid = -json_as_int(json_at(pChild, 1));
- if ((hContact = FindUser(uid)) != NULL) {
- setWord(hContact, "Status", ID_STATUS_OFFLINE);
- db_unset(hContact, m_szModuleName, "ListeningTo");
- SetMirVer(hContact, -1);
- }
- break;
-
- case VKPOLL_USR_UTN:
- uid = json_as_int(json_at(pChild, 1));
- hContact = FindUser(uid);
- if (hContact != NULL) {
- ForkThread(&CVkProto::ContactTypingThread, (void *)hContact);
- if (m_bUserForceOnlineOnActivity)
- SetInvisible(hContact);
- }
- break;
-
- case VKPOLL_CHAT_CHANGED:
- int chat_id = json_as_int(json_at(pChild, 1));
- CVkChatInfo *cc = m_chats.find((CVkChatInfo*)&chat_id);
- if (cc)
- RetrieveChatInfo(cc);
- break;
- }
- }
-
- RetrieveMessagesByIds(mids);
-}
-
-int CVkProto::PollServer()
-{
- debugLogA("CVkProto::PollServer");
- if (!IsOnline()) {
- debugLogA("CVkProto::PollServer is dead (not online)");
- m_pollingConn = NULL;
- ShutdownSession();
- return 0;
- }
-
- debugLogA("CVkProto::PollServer (online)");
- int iPollConnRetry = MAX_RETRIES;
- NETLIBHTTPREQUEST *reply;
- CMStringA szReqUrl;
- szReqUrl.AppendFormat("https://%s?act=a_check&key=%s&ts=%s&wait=25&access_token=%s&mode=%d", m_pollingServer, m_pollingKey, m_pollingTs, m_szAccessToken, 106);
- // see mode parametr description on https://vk.com/dev/using_longpoll (Russian version)
- NETLIBHTTPREQUEST req = { sizeof(req) };
- req.requestType = REQUEST_GET;
- req.szUrl = mir_strdup(szReqUrl.GetBuffer());
- req.flags = VK_NODUMPHEADERS | NLHRF_PERSISTENT | NLHRF_HTTP11;
- req.timeout = 30000;
- req.nlc = m_pollingConn;
-
- while ((reply = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNetlibUser, (LPARAM)&req)) == NULL) {
- debugLogA("CVkProto::PollServer is dead");
- m_pollingConn = NULL;
- if (iPollConnRetry && !m_bTerminated) {
- iPollConnRetry--;
- debugLogA("CVkProto::PollServer restarting %d", MAX_RETRIES - iPollConnRetry);
- Sleep(1000);
- }
- else {
- debugLogA("CVkProto::PollServer => ShutdownSession");
- mir_free(req.szUrl);
- ShutdownSession();
- return 0;
- }
- }
-
- mir_free(req.szUrl);
-
- int retVal = 0;
- if (reply->resultCode == 200) {
- JSONROOT pRoot(reply->pData);
- JSONNODE *pFailed = json_get(pRoot, "failed");
- if (pFailed != NULL && json_as_int(pFailed) == 2) {
- RetrievePollingInfo();
- retVal = -1;
- debugLogA("Polling key expired, restarting polling thread");
- }
- else if (CheckJsonResult(NULL, pRoot)) {
- m_pollingTs = mir_t2a(ptrT(json_as_string(json_get(pRoot, "ts"))));
- JSONNODE *pUpdates = json_get(pRoot, "updates");
- if (pUpdates != NULL)
- PollUpdates(pUpdates);
- retVal = 1;
- }
- }
- else if ((reply->resultCode >= 400 && reply->resultCode <= 417)
- || (reply->resultCode >= 500 && reply->resultCode <= 509)) {
- debugLogA("CVkProto::PollServer is dead. Error code - %d", reply->resultCode);
- m_pollingConn = NULL;
- CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)reply);
- ShutdownSession();
- return 0;
- }
-
- m_pollingConn = reply->nlc;
-
- CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)reply);
- debugLogA("CVkProto::PollServer return %d", retVal);
- return retVal;
-}
-
-void CVkProto::PollingThread(void*)
-{
- debugLogA("CVkProto::PollingThread: entering");
-
- while (!m_bTerminated)
- if (PollServer() == -1)
- break;
-
- m_hPollingThread = NULL;
- m_pollingConn = NULL;
- debugLogA("CVkProto::PollingThread: leaving");
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
INT_PTR __cdecl CVkProto::SvcAddAsFriend(WPARAM hContact, LPARAM)
{
debugLogA("CVkProto::SvcAddAsFriend");
diff --git a/protocols/VKontakte/vk_10.vcxproj b/protocols/VKontakte/vk_10.vcxproj
index b4d79e134d..0a4ad33b08 100644
--- a/protocols/VKontakte/vk_10.vcxproj
+++ b/protocols/VKontakte/vk_10.vcxproj
@@ -186,7 +186,9 @@
<ClCompile Include="src\vk_feed.cpp" />
<ClCompile Include="src\vk_files.cpp" />
<ClCompile Include="src\vk_history.cpp" />
+ <ClCompile Include="src\vk_messages.cpp" />
<ClCompile Include="src\vk_options.cpp" />
+ <ClCompile Include="src\vk_pollserver.cpp" />
<ClCompile Include="src\vk_proto.cpp" />
<ClCompile Include="src\vk_queue.cpp" />
<ClCompile Include="src\vk_search.cpp" />
diff --git a/protocols/VKontakte/vk_10.vcxproj.filters b/protocols/VKontakte/vk_10.vcxproj.filters
index c16159b9b3..8127a6664d 100644
--- a/protocols/VKontakte/vk_10.vcxproj.filters
+++ b/protocols/VKontakte/vk_10.vcxproj.filters
@@ -63,6 +63,12 @@
<ClCompile Include="src\vk_status.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="src\vk_messages.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\vk_pollserver.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\version.h">
diff --git a/protocols/VKontakte/vk_12.vcxproj b/protocols/VKontakte/vk_12.vcxproj
index f476303ed3..0676ebf4ab 100644
--- a/protocols/VKontakte/vk_12.vcxproj
+++ b/protocols/VKontakte/vk_12.vcxproj
@@ -187,7 +187,9 @@
<ClCompile Include="src\vk_captcha.cpp" />
<ClCompile Include="src\vk_chats.cpp" />
<ClCompile Include="src\vk_files.cpp" />
+ <ClCompile Include="src\vk_messages.cpp" />
<ClCompile Include="src\vk_options.cpp" />
+ <ClCompile Include="src\vk_pollserver.cpp" />
<ClCompile Include="src\vk_proto.cpp" />
<ClCompile Include="src\vk_queue.cpp" />
<ClCompile Include="src\vk_search.cpp" />
diff --git a/protocols/VKontakte/vk_12.vcxproj.filters b/protocols/VKontakte/vk_12.vcxproj.filters
index 9d5568ee1a..194a5b0c0d 100644
--- a/protocols/VKontakte/vk_12.vcxproj.filters
+++ b/protocols/VKontakte/vk_12.vcxproj.filters
@@ -63,6 +63,12 @@
<ClCompile Include="src\vk_status.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="src\vk_messages.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\vk_pollserver.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\version.h">