From 2ddaa0bcf64f3c1cd8e6bc7c16e4f009d0ff5b93 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Fri, 11 Oct 2013 21:14:01 +0000 Subject: VK: message reading git-svn-id: http://svn.miranda-ng.org/main/trunk@6451 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/VKontakte/src/vk_proto.cpp | 15 ++-- protocols/VKontakte/src/vk_proto.h | 7 +- protocols/VKontakte/src/vk_thread.cpp | 143 ++++++++++++++++++++++++++-------- 3 files changed, 124 insertions(+), 41 deletions(-) (limited to 'protocols') diff --git a/protocols/VKontakte/src/vk_proto.cpp b/protocols/VKontakte/src/vk_proto.cpp index c544fbd5f1..78ca6fbdc4 100644 --- a/protocols/VKontakte/src/vk_proto.cpp +++ b/protocols/VKontakte/src/vk_proto.cpp @@ -62,6 +62,8 @@ int CVkProto::OnPreShutdown(WPARAM wParam, LPARAM lParam) { m_bTerminated = true; SetEvent(m_evRequestsQueue); + if (m_hPollingThread) + TerminateThread(m_hPollingThread, 0); return 0; } @@ -99,6 +101,14 @@ DWORD_PTR CVkProto::GetCaps(int type, HANDLE hContact) ////////////////////////////////////////////////////////////////////////////// +int CVkProto::RecvMsg(HANDLE hContact, PROTORECVEVENT *pre) +{ + Proto_RecvMessage(hContact, pre); + return 0; +} + +////////////////////////////////////////////////////////////////////////////// + int CVkProto::SetStatus(int iNewStatus) { if (m_iDesiredStatus == iNewStatus) @@ -183,11 +193,6 @@ int CVkProto::AuthDeny(HANDLE hDbEvent, const PROTOCHAR *reason) return 1; } -int CVkProto::RecvMsg(HANDLE hContact, PROTORECVEVENT *pre) -{ - return 0; -} - int CVkProto::SendMsg(HANDLE hContact, int flags, const char *msg) { return 0; diff --git a/protocols/VKontakte/src/vk_proto.h b/protocols/VKontakte/src/vk_proto.h index 23e3144b81..3f5d8df4e0 100644 --- a/protocols/VKontakte/src/vk_proto.h +++ b/protocols/VKontakte/src/vk_proto.h @@ -98,11 +98,14 @@ struct CVkProto : public PROTO void RetrieveFriends(); void OnReceiveFriends(NETLIBHTTPREQUEST*, void*); + void RetrieveUnreadMessages(); + void OnReceiveMessages(NETLIBHTTPREQUEST*, void*); + void RetrievePollingInfo(); void OnReceivePollingInfo(NETLIBHTTPREQUEST*, void*); void __cdecl PollingThread(void*); - void PollServer(); + int PollServer(); void OnReceivePolling(NETLIBHTTPREQUEST*, void*); int SetServerStatus(int); @@ -157,5 +160,5 @@ private: UINT_PTR m_timer; ptrA m_pollingServer, m_pollingKey, m_pollingTs; - HANDLE m_pollingConn; + HANDLE m_hPollingThread; }; diff --git a/protocols/VKontakte/src/vk_thread.cpp b/protocols/VKontakte/src/vk_thread.cpp index d191f70b2c..dfb430cc2b 100644 --- a/protocols/VKontakte/src/vk_thread.cpp +++ b/protocols/VKontakte/src/vk_thread.cpp @@ -319,6 +319,82 @@ void CVkProto::OnReceiveFriends(NETLIBHTTPREQUEST *reply, void*) ///////////////////////////////////////////////////////////////////////////////////////// +void CVkProto::RetrieveUnreadMessages() +{ + Netlib_Logf(m_hNetlibUser, "CVkProto::RetrieveMessages"); + + HttpParam params[] = { + { "code", "return{\"msgs\":API.messages.get({\"filters\":1})};" }, + { "access_token", m_szAccessToken } + }; + PushAsyncHttpRequest(REQUEST_GET, "/method/execute.json", true, &CVkProto::OnReceiveMessages, SIZEOF(params), params); +} + +void CVkProto::OnReceiveMessages(NETLIBHTTPREQUEST *reply, void*) +{ + Netlib_Logf(m_hNetlibUser, "CVkProto::OnReceiveMessages %d", reply->resultCode); + if (reply->resultCode != 200) + return; + + JSONROOT pRoot(reply->pData); + if ( !CheckJsonResult(pRoot)) + return; + + JSONNODE *pResponse = json_get(pRoot, "response"); + if (pResponse == NULL) + return; + + JSONNODE *pMsgs = json_as_array( json_get(pResponse, "msgs")); + if (pMsgs == NULL) + return; + + CMStringA mids; + + 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; + + int mid = json_as_int( json_get(pMsg, "mid")); + 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, "uid")); + ptrT ptszBody( json_as_string( json_get(pMsg, "body"))); + + char szUserid[40], szMid[40]; + _itoa(uid, szUserid, 10); + _itoa(mid, szMid, 10); + HANDLE hContact = FindUser(szUserid, true); + + PROTORECVEVENT recv = { 0 }; + recv.flags = PREF_TCHAR; + if (isRead) + recv.flags |= PREF_CREATEREAD; + recv.timestamp = datetime; + recv.tszMessage = ptszBody; + recv.lParam = isOut; + recv.pCustomData = szMid; + recv.cbCustomDataSize = (int)strlen(szMid); + ProtoChainRecvMsg(hContact, &recv); + + if (!mids.IsEmpty()) + mids.AppendChar(','); + mids.Append(szMid); + } + + if (!mids.IsEmpty()) { + HttpParam params[] = { + { "mids", mids }, + { "access_token", m_szAccessToken } + }; + PushAsyncHttpRequest(REQUEST_GET, "/method/messages.markAsRead.json", true, NULL, SIZEOF(params), params); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + void CVkProto::RetrievePollingInfo() { Netlib_Logf(m_hNetlibUser, "CVkProto::RetrievePollingInfo"); @@ -346,53 +422,52 @@ void CVkProto::OnReceivePollingInfo(NETLIBHTTPREQUEST *reply, void*) m_pollingServer = mir_t2a( ptrT( json_as_string( json_get(pResponse, "server")))); if (m_pollingTs != NULL && m_pollingKey != NULL && m_pollingServer != NULL) ForkThread(&CVkProto::PollingThread, 0); + + RetrieveUnreadMessages(); } ///////////////////////////////////////////////////////////////////////////////////////// -void CVkProto::PollServer() +int CVkProto::PollServer() { Netlib_Logf(m_hNetlibUser, "CVkProto::PollServer"); - HttpParam params[] = { - { "act", "a_check" }, - { "key", m_pollingKey }, - { "ts", m_pollingTs }, - { "wait", "25" }, - { "access_token", m_szAccessToken } - }; - PushAsyncHttpRequest(REQUEST_GET, m_pollingServer, true, &CVkProto::OnReceivePolling, SIZEOF(params), params); -} - -void CVkProto::OnReceivePolling(NETLIBHTTPREQUEST *reply, void*) -{ - Netlib_Logf(m_hNetlibUser, "CVkProto::OnReceivePolling %d", reply->resultCode); - if (reply->resultCode != 200) - return; - - JSONROOT pRoot(reply->pData); - if ( !CheckJsonResult(pRoot)) - return; + NETLIBHTTPREQUEST req = { sizeof(req) }; + req.requestType = REQUEST_GET; + req.szUrl = NEWSTR_ALLOCA(CMStringA().Format("%s?act=a_check&key=%s&ts=%s&wait=25&access_token=%s", m_pollingServer, m_pollingKey, m_pollingTs, m_szAccessToken)); + req.flags = NLHRF_SSL | NLHRF_PERSISTENT | NLHRF_HTTP11; + req.timeout = 30; + + NETLIBHTTPREQUEST *reply = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)m_hNetlibUser, (LPARAM)&req); + if (reply == NULL) + return 0; + + RetrieveUnreadMessages(); + + int retVal = -1; + if (reply->resultCode = 200) { + JSONROOT pRoot(reply->pData); + if ( CheckJsonResult(pRoot)) { + JSONNODE *pResponse = json_get(pRoot, "response"); + if (pResponse != NULL) { + m_pollingTs = mir_t2a( ptrT( json_as_string( json_get(pResponse, "ts")))); + retVal = 1; + } + } + else retVal = 0; + } - JSONNODE *pResponse = json_get(pRoot, "response"); - if (pResponse != NULL) - m_pollingTs = mir_t2a( ptrT( json_as_string( json_get(pResponse, "ts")))); + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)reply); + return retVal; } void CVkProto::PollingThread(void*) { - NETLIBOPENCONNECTION nloc = { sizeof(nloc) }; - nloc.flags = NLOCF_SSL | NLOCF_HTTP | NLOCF_V2; - nloc.szHost = VK_API_URL; - nloc.wPort = 443; - nloc.timeout = 60*1000; - m_pollingConn = (HANDLE)CallService(MS_NETLIB_OPENCONNECTION, (WPARAM)m_hNetlibUser, (LPARAM)&nloc); - if (m_pollingConn == NULL) - return; + m_hPollingThread = GetCurrentThread(); while (!m_bTerminated) - PollServer(); + if (PollServer() == -1) + break; - CallService(MS_NETLIB_CLOSEHANDLE, (WPARAM)m_pollingConn, 0); - m_pollingConn = NULL; + m_hPollingThread = NULL; } -- cgit v1.2.3