From 27a37d3d9753b378fa85cce0f7fa3e2de8e35a57 Mon Sep 17 00:00:00 2001 From: Sergey Bolhovskoy Date: Mon, 15 Dec 2014 06:12:18 +0000 Subject: =?UTF-8?q?VKontakte:=20fix=20for=20warning=20C4121=20in=20AsyncHt?= =?UTF-8?q?tpRequest=20struct=20fix=20for=20TCHAR=20in=20SetMirVer=20add?= =?UTF-8?q?=20vk=20feeds=20support=20(wall)=20=E2=80=93=20part=201?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.miranda-ng.org/main/trunk@11430 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/VKontakte/src/misc.cpp | 20 +-- protocols/VKontakte/src/vk.h | 1 + protocols/VKontakte/src/vk_feed.cpp | 283 ++++++++++++++++++++++++++++++ protocols/VKontakte/src/vk_files.cpp | 5 +- protocols/VKontakte/src/vk_history.cpp | 4 +- protocols/VKontakte/src/vk_proto.cpp | 24 +-- protocols/VKontakte/src/vk_proto.h | 39 +++- protocols/VKontakte/src/vk_thread.cpp | 34 ++-- protocols/VKontakte/vk_10.vcxproj | 1 + protocols/VKontakte/vk_10.vcxproj.filters | 3 + protocols/VKontakte/vk_12.vcxproj | 1 + protocols/VKontakte/vk_12.vcxproj.filters | 9 +- 12 files changed, 382 insertions(+), 42 deletions(-) create mode 100644 protocols/VKontakte/src/vk_feed.cpp (limited to 'protocols') diff --git a/protocols/VKontakte/src/misc.cpp b/protocols/VKontakte/src/misc.cpp index 3525ce9692..31124b26b3 100644 --- a/protocols/VKontakte/src/misc.cpp +++ b/protocols/VKontakte/src/misc.cpp @@ -488,44 +488,44 @@ void CVkProto::SetMirVer(MCONTACT hContact, int platform) switch (platform) { case VK_APP_ID: - MirVer = "Miranda NG VKontakte"; + MirVer = _T("Miranda NG VKontakte"); break; case 2386311: - MirVer = "QIP 2012 VKontakte"; + MirVer = _T("QIP 2012 VKontakte"); break; case 1: - MirVer = "VKontakte (mobile)"; + MirVer = _T("VKontakte (mobile)"); break; case 3087106: // iPhone case 3140623: case 2: - MirVer = "VKontakte (iphone)"; + MirVer = _T("VKontakte (iphone)"); break; case 3682744: // iPad case 3: - MirVer = "VKontakte (ipad)"; + MirVer = _T("VKontakte (ipad)"); break; case 2685278: // Android - Kate case 2890984: // Android case 2274003: case 4: - MirVer = "VKontakte (android)"; + MirVer = _T("VKontakte (android)"); break; case 3059453: // Windows Phone case 2424737: case 3502561: case 5: - MirVer = "VKontakte (wphone)"; + MirVer = _T("VKontakte (wphone)"); break; case 3584591: // Windows 8.x case 6: - MirVer = "VKontakte (windows)"; + MirVer = _T("VKontakte (windows)"); break; case 7: - MirVer = "VKontakte (website)"; + MirVer = _T("VKontakte (website)"); break; default: - MirVer = "VKontakte (other)"; + MirVer = _T("VKontakte (other)"); bSetFlag = OldMirVer.IsEmpty(); } diff --git a/protocols/VKontakte/src/vk.h b/protocols/VKontakte/src/vk.h index fddb6aebb1..ff1914446f 100644 --- a/protocols/VKontakte/src/vk.h +++ b/protocols/VKontakte/src/vk.h @@ -67,6 +67,7 @@ along with this program. If not, see . #define VK_API_VER "5.27" #define VER_API CHAR_PARAM("v", VK_API_VER) +#define VK_FEED_USER 2147483647L #if defined(_DEBUG) #define VK_NODUMPHEADERS 0 diff --git a/protocols/VKontakte/src/vk_feed.cpp b/protocols/VKontakte/src/vk_feed.cpp new file mode 100644 index 0000000000..d2d22e21bd --- /dev/null +++ b/protocols/VKontakte/src/vk_feed.cpp @@ -0,0 +1,283 @@ +/* +Copyright (c) 2013-14 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 . +*/ + +#include "stdafx.h" + +#define VK_EVENTTYPE_FEED 10001 +static char* szImageTypes[] = { "photo_2560", "photo_1280", "photo_807", "photo_604", "photo_256", "photo_130", "photo_128", "photo_75", "photo_64" }; + +void CVkProto::AddFeedSpecialUser() +{ + MCONTACT hContact = FindUser(VK_FEED_USER, m_bNewsEnabled); + if (!m_bNewsEnabled) { + if (hContact) + CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0); + return; + } + + CMString tszNick = TranslateT("VKontakte"); + setTString(hContact, "Nick", tszNick.GetBuffer()); + CMString url = _T("https://vk.com/press/Simple.png"); + SetAvatarUrl(hContact, url); + ReloadAvatarInfo(hContact); + + if (getWord(hContact, "Status", 0) != ID_STATUS_ONLINE) + setWord(hContact, "Status", ID_STATUS_ONLINE); + SetMirVer(hContact, 7); + + setTString(hContact, "domain", _T("feed")); + setTString(hContact, "Homepage", _T("https://vk.com/feed")); +} + +void CVkProto::AddFeedEvent(CMString& tszBody, time_t tTime) +{ + + MCONTACT hContact = FindUser(VK_FEED_USER, true); + ptrT ptszBody; + PROTORECVEVENT recv = { 0 }; + + ptszBody = mir_tstrdup(tszBody.GetBuffer()); + recv.flags = PREF_TCHAR; + recv.timestamp = tTime; + recv.tszMessage = ptszBody; + recv.lParam = 0; + recv.pCustomData = NULL; + recv.cbCustomDataSize = 0; + + ProtoChainRecvMsg(hContact, &recv); +} + +void CVkProto::RetrieveUnreadNews() +{ + debugLogA("CVkProto::RetrieveUnreadNews"); + if (!IsOnline() || !m_bNewsEnabled) + return; + + time_t tLastNewsTime = getDword("LastNewsTime", time(NULL) - 24 * 60 * 60); + if (time(NULL) - tLastNewsTime <= m_iNewsInterval * 60 ) + return; + + Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/newsfeed.get.json", true, &CVkProto::OnReceiveUnreadNews) + << INT_PARAM("count", 100) + << INT_PARAM("return_banned", 0) + << INT_PARAM("max_photos", 100) + << INT_PARAM("start_time", tLastNewsTime + 1) + << CHAR_PARAM("filters", "post,photo,photo_tag,wall_photo") + << VER_API); +} + +void CVkProto::CreateVkUserInfoList(OBJLIST &vkUsers, JSONNODE *pResponse) +{ + debugLogA("CVkProto::CreateVkUserInfoList"); + if (pResponse == NULL) + return; + + JSONNODE *pProfiles = json_get(pResponse, "profiles"); + JSONNODE *pProfile; + if (pProfiles != NULL) + for (size_t i = 0; (pProfile = json_at(pProfiles, i)) != NULL; i++){ + LONG UserId = json_as_int(json_get(pProfile, "id")); + if (!UserId) + continue; + + CMString tszNick = json_as_string(json_get(pProfile, "first_name")); + tszNick.AppendChar(' '); + tszNick += json_as_string(json_get(pProfile, "last_name")); + CMString tszLink = _T("https://vk.com/"); + tszLink += json_as_string(json_get(pProfile, "screen_name")); + CVkUserInfo * vkUser = new CVkUserInfo(UserId, false, tszNick, tszLink); + debugLog(_T("CVkProto::CreateVkUserInfoList %d %d %s %s"), UserId, false, tszNick.GetBuffer(), tszLink.GetBuffer()); + vkUsers.insert(vkUser); + } + + JSONNODE *pGroups = json_get(pResponse, "groups"); + if (pGroups != NULL) + for (size_t i = 0; (pProfile = json_at(pGroups, i)) != NULL; i++){ + LONG UserId = -json_as_int(json_get(pProfile, "id")); + if (!UserId) + continue; + + CMString tszNick = json_as_string(json_get(pProfile, "name")); + CMString tszLink = _T("https://vk.com/"); + tszLink += json_as_string(json_get(pProfile, "screen_name")); + CVkUserInfo * vkUser = new CVkUserInfo(UserId, true, tszNick, tszLink); + debugLog(_T("CVkProto::CreateVkUserInfoList %d %d %s %s"), UserId, true, tszNick.GetBuffer(), tszLink.GetBuffer()); + vkUsers.insert(vkUser); + } +} + +CMString CVkProto::GetVkPhotoItem(JSONNODE *pPhoto) +{ + CMString tszRes; + + if (pPhoto == NULL) + return tszRes; + + ptrT ptszLink; + for (int i = 0; i < SIZEOF(szImageTypes); i++) { + JSONNODE *n = json_get(pPhoto, szImageTypes[i]); + if (n != NULL) { + ptszLink = json_as_string(n); + break; + } + } + + int iWidth = json_as_int(json_get(pPhoto, "width")); + int iHeight = json_as_int(json_get(pPhoto, "height")); + tszRes.AppendFormat(_T("%s: %s (%dx%d)"), TranslateT("Photo"), ptszLink, iWidth, iHeight); + if (m_bAddImgBbc) + tszRes.AppendFormat(_T("\n\t[img]%s[/img]"), ptszLink); + CMString tszText = json_as_string(json_get(pPhoto, "text")); + if (!tszText.IsEmpty()) + tszRes += "\n" + tszText; + + return tszRes; +} + +CMString CVkProto::GetVkNewsItem(JSONNODE *pItem, OBJLIST &vkUsers, time_t &tDate) +{ + debugLogA("CVkProto::GetVkNewsItem"); + bool m_bBBCOnNews = true; //!!! + bool bPostLink = true; + CMString tszRes; + if (pItem == NULL) + return tszRes; + + CMString tszType = json_as_string(json_get(pItem, "type")); + + LONG iSourceId = json_as_int(json_get(pItem, "source_id")); + iSourceId = iSourceId ? iSourceId : json_as_int(json_get(pItem, "owner_id")); + + bool bIsGroup = (iSourceId < 0); + CVkUserInfo * vkUser = vkUsers.find((CVkUserInfo *)&iSourceId); + + if (vkUser == NULL) { + CMString tszNick = TranslateT("Unknown"); + CMString tszLink = _T("https://vk.com/"); + if (iSourceId){ + tszLink += bIsGroup ? "club" : "id"; + tszLink.AppendFormat(_T("%d"), bIsGroup ? -iSourceId : iSourceId); + } + vkUser = new CVkUserInfo(iSourceId, bIsGroup, tszNick, tszLink); + vkUsers.insert(vkUser); + } + + LONG iPostId = json_as_int(json_get(pItem, "post_id")); + tDate = json_as_int(json_get(pItem, "date")); + CMString tszText = json_as_string(json_get(pItem, "text")); + if (!tszText.IsEmpty()) + tszText += _T("\n"); + + if (tszType == _T("photo_tag")){ + bPostLink = false; + JSONNODE *pPhotos = json_get(pItem, "photo_tags"); + if (pPhotos){ + JSONNODE *pPhotoItems = json_get(pPhotos, "items"); + if (pPhotoItems){ + JSONNODE *pPhotoItem; + tszText = TranslateT("User was tagged in these photos:"); + for (size_t i = 0; (pPhotoItem = json_at(pPhotoItems, i)) != NULL; i++) + tszText += _T("\n") + GetVkPhotoItem(pPhotoItem); + } + } + } + else if (tszType == _T("photo") || tszType == _T("wall_photo")){ + bPostLink = false; + JSONNODE *pPhotos = json_get(pItem, "photos"); + if (pPhotos){ + JSONNODE *pPhotoItems = json_get(pPhotos, "items"); + if (pPhotoItems){ + JSONNODE *pPhotoItem; + for (size_t i = 0; (pPhotoItem = json_at(pPhotoItems, i)) != NULL; i++){ + + tszText += GetVkPhotoItem(pPhotoItem) + _T("\n"); + if (i == 0 && tszType == _T("wall_photo")){ + iPostId = json_as_int(json_get(pPhotoItem, "post_id")); + bPostLink = true; + break; // Max 1 wall_photo + } + } + } + } + } else if (tszType == _T("post") || tszType.IsEmpty()) { + bPostLink = true; + JSONNODE * pRepost = json_get(pItem, "copy_history"); + if (pRepost){ + time_t tRDate; + CMString tszRepostText = GetVkNewsItem(json_at(pRepost, 0), vkUsers, tRDate); + tszRepostText.Replace(_T("\n"), _T("\n\t")); + tszText += tszRepostText; + tszText += _T("\n"); + } + + JSONNODE *pAttachments = json_get(pItem, "attachments"); + if (pAttachments) + tszText += GetAttachmentDescr(pAttachments); + } + + CMString tszResFormat; + CMString tszBBCIn, tszBBCOut; + CMString tszUrl; + + if (iPostId) + tszResFormat = Translate("News from %s%s%s (%s)\n%s"); + else { + tszResFormat = Translate("\tRepost from %s%s%s (%s)\n%s"); + bPostLink = false; + } + + tszBBCIn = m_bBBCOnNews ? "[b]" : "["; + tszBBCOut = m_bBBCOnNews ? "[/b]" : "]"; + tszRes.AppendFormat(tszResFormat, tszBBCIn.GetBuffer(), vkUser->m_tszUserNick.GetBuffer(), tszBBCOut.GetBuffer(), vkUser->m_tszLink.GetBuffer(), tszText.GetBuffer()); + + if (bPostLink) { + tszUrl.AppendFormat(_T("%d_%d"), vkUser->m_UserId, iPostId); + tszUrl = CMString(_T("https://vk.com/wall")) + tszUrl; + tszRes.AppendFormat(TranslateT("\nNews link: %s"), tszUrl.GetBuffer()); + } + + return tszRes; +} + +void CVkProto::OnReceiveUnreadNews(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) +{ + debugLogA("CVkProto::OnReceiveUnreadNews %d", reply->resultCode); + if (reply->resultCode != 200) + return; + + JSONROOT pRoot; + JSONNODE *pResponse = CheckJsonResponse(pReq, reply, pRoot); + if (pResponse == NULL) + return; + + OBJLIST vkUsers(5, NumericKeySortT); + CreateVkUserInfoList(vkUsers, pResponse); + + JSONNODE *pItems = json_get(pResponse, "items"); + JSONNODE *pItem; + + if (pItems != NULL) + for (int i = 0; (pItem = json_at(pItems, i)) != NULL; i++){ + time_t tDate; + CMString tszText = GetVkNewsItem(pItem, vkUsers, tDate); + AddFeedEvent(tszText, tDate); + } + + + setDword("LastNewsTime", time(NULL)); + vkUsers.destroy(); +} diff --git a/protocols/VKontakte/src/vk_files.cpp b/protocols/VKontakte/src/vk_files.cpp index f20fc3760d..5399ba4b04 100644 --- a/protocols/VKontakte/src/vk_files.cpp +++ b/protocols/VKontakte/src/vk_files.cpp @@ -72,7 +72,8 @@ CVkFileUploadParam::VKFileType CVkFileUploadParam::GetType() HANDLE CVkProto::SendFile(MCONTACT hContact, const PROTOCHAR *desc, PROTOCHAR **files) { debugLogA("CVkProto::SendFile"); - if (!IsOnline()) + LONG userID = getDword(hContact, "ID", -1); + if (!IsOnline() || userID == -1 || userID == VK_FEED_USER) return (HANDLE)0; CVkFileUploadParam *fup = new CVkFileUploadParam(hContact, desc, files); ForkThread(&CVkProto::SendFileThread, (void *)fup); @@ -348,7 +349,7 @@ void CVkProto::OnReciveUploadFile(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pR } LONG userID = getDword(fup->hContact, "ID", -1); - if (userID == -1) { + if (userID == -1 || userID == VK_FEED_USER) { SendFileFiled(fup); return; } diff --git a/protocols/VKontakte/src/vk_history.cpp b/protocols/VKontakte/src/vk_history.cpp index 2ce58429ee..7474b512ea 100644 --- a/protocols/VKontakte/src/vk_history.cpp +++ b/protocols/VKontakte/src/vk_history.cpp @@ -29,7 +29,7 @@ INT_PTR __cdecl CVkProto::SvcGetAllServerHistory(WPARAM hContact, LPARAM) return 0; LONG userID = getDword(hContact, "ID", -1); - if (userID == -1) + if (userID == -1 || userID == VK_FEED_USER) return 0; HANDLE hDBEvent = db_event_first(hContact); @@ -125,7 +125,7 @@ void CVkProto::GetServerHistory(MCONTACT hContact, int iOffset, int iCount, int return; LONG userID = getDword(hContact, "ID", -1); - if (-1 == userID) + if (-1 == userID || userID == VK_FEED_USER) return; CMStringA code, formatcode = "var iOffset=%d;var iReqCount=%d;var userID=%d;var iTime=%d;var lastMid=%d;" diff --git a/protocols/VKontakte/src/vk_proto.cpp b/protocols/VKontakte/src/vk_proto.cpp index e5a1ec9c14..6238e399a5 100644 --- a/protocols/VKontakte/src/vk_proto.cpp +++ b/protocols/VKontakte/src/vk_proto.cpp @@ -78,6 +78,9 @@ CVkProto::CVkProto(const char *szModuleName, const TCHAR *ptszUserName) : CMStringA szListeningTo(m_szModuleName); szListeningTo += "Enabled"; db_set_b(NULL, "ListeningTo", szListeningTo.GetBuffer(), m_iMusicSendMetod == 0 ? 0 : 1); + m_bNewsEnabled = getBool("NewsEnabled", false); + m_bBBCOnNews = getBool("BBCOnNews", false); + m_iNewsInterval = getDword("NewsInterval", 15); // Set all contacts offline -- in case we crashed SetAllContactStatuses(ID_STATUS_OFFLINE); @@ -272,18 +275,19 @@ void CVkProto::InitMenus() int CVkProto::OnPreBuildContactMenu(WPARAM hContact, LPARAM) { + LONG userID = getDword(hContact, "ID", -1); bool bisFriend = (getByte(hContact, "Auth", -1) == 0); bool bisBroadcast = !(CMString(db_get_tsa(hContact, m_szModuleName, "AudioUrl")).IsEmpty()); Menu_ShowItem(g_hContactMenuItems[CMI_VISITPROFILE], !isChatRoom(hContact)); - Menu_ShowItem(g_hContactMenuItems[CMI_ADDASFRIEND], !bisFriend && !isChatRoom(hContact)); - Menu_ShowItem(g_hContactMenuItems[CMI_DELETEFRIEND], bisFriend); - Menu_ShowItem(g_hContactMenuItems[CMI_BANUSER], !isChatRoom(hContact)); - Menu_ShowItem(g_hContactMenuItems[CMI_REPORTABUSE], !isChatRoom(hContact)); + Menu_ShowItem(g_hContactMenuItems[CMI_ADDASFRIEND], !bisFriend && !isChatRoom(hContact) && userID != VK_FEED_USER); + Menu_ShowItem(g_hContactMenuItems[CMI_DELETEFRIEND], bisFriend && userID != VK_FEED_USER); + Menu_ShowItem(g_hContactMenuItems[CMI_BANUSER], !isChatRoom(hContact) && userID != VK_FEED_USER); + Menu_ShowItem(g_hContactMenuItems[CMI_REPORTABUSE], !isChatRoom(hContact) && userID != VK_FEED_USER); Menu_ShowItem(g_hContactMenuItems[CMI_DESTROYKICKCHAT], isChatRoom(hContact) && getBool(hContact, "off", false)); Menu_ShowItem(g_hContactMenuItems[CMI_OPENBROADCAST], !isChatRoom(hContact) && bisBroadcast); - Menu_ShowItem(g_hContactMenuItems[CMI_GETSERVERHISTORY], !isChatRoom(hContact)); + Menu_ShowItem(g_hContactMenuItems[CMI_GETSERVERHISTORY], !isChatRoom(hContact) && userID != VK_FEED_USER); for (int i = 0; i < CHMI_COUNT; i++) - Menu_ShowItem(g_hContactHistoryMenuItems[i], !isChatRoom(hContact)); + Menu_ShowItem(g_hContactHistoryMenuItems[i], !isChatRoom(hContact) && userID != VK_FEED_USER); return 0; } @@ -420,7 +424,7 @@ int CVkProto::SendMsg(MCONTACT hContact, int flags, const char *msg) if (!IsOnline()) return 0; LONG userID = getDword(hContact, "ID", -1); - if (userID == -1) + if (userID == -1 || userID == VK_FEED_USER) return 0; ptrA szMsg; @@ -568,7 +572,7 @@ int CVkProto::AuthRequest(MCONTACT hContact,const PROTOCHAR* message) return 1; LONG userID = getDword(hContact, "ID", -1); - if ((userID == -1) || !hContact) + if (userID == -1 || !hContact || userID == VK_FEED_USER) return 1; TCHAR msg[501] = {0}; @@ -649,7 +653,7 @@ 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()) + if (userID == -1 || !IsOnline() || userID == VK_FEED_USER) return 1; if (m_iMarkMessageReadOn == markOnTyping) @@ -678,7 +682,7 @@ int CVkProto::GetInfo(MCONTACT hContact, int) { debugLogA("CVkProto::GetInfo"); LONG userID = getDword(hContact, "ID", -1); - if (userID == -1) + if (userID == -1 || userID == VK_FEED_USER) return 1; RetrieveUserInfo(userID); return 0; diff --git a/protocols/VKontakte/src/vk_proto.h b/protocols/VKontakte/src/vk_proto.h index 5c7be266a0..2e906bb011 100644 --- a/protocols/VKontakte/src/vk_proto.h +++ b/protocols/VKontakte/src/vk_proto.h @@ -47,11 +47,11 @@ struct AsyncHttpRequest : public NETLIBHTTPREQUEST, public MZeroedObject CMStringA m_szUrl; CMStringA m_szParam; - bool bNeedsRestart, bIsMainConn; VK_REQUEST_HANDLER m_pFunc; void *pUserInfo; - bool m_bApiReq; int m_iRetry; + bool m_bApiReq; + bool bNeedsRestart, bIsMainConn; }; struct PARAM @@ -157,6 +157,25 @@ struct CVkFileUploadParam { __forceinline char* fileName() { return fname; } }; +struct CVkUserInfo : public MZeroedObject{ + CVkUserInfo(LONG _UserId) : + m_UserId(_UserId), + m_bIsGroup(false) + {} + + CVkUserInfo(LONG _UserId, bool _bIsGroup, CMString& _tszUserNick, CMString& _tszLink) : + m_UserId(_UserId), + m_bIsGroup(_bIsGroup), + m_tszUserNick(_tszUserNick), + m_tszLink(_tszLink) + {} + LONG m_UserId; + + CMString m_tszUserNick; + CMString m_tszLink; + bool m_bIsGroup; +}; + struct TFakeAckParams { __inline TFakeAckParams(MCONTACT _hContact, int _msgid) : @@ -286,6 +305,16 @@ struct CVkProto : public PROTO void OnReciveUpload(NETLIBHTTPREQUEST*, AsyncHttpRequest*); void OnReciveUploadFile(NETLIBHTTPREQUEST*, AsyncHttpRequest*); + //==== Feed ========================================================================== + + void AddFeedSpecialUser(); + void AddFeedEvent(CMString& tszBody, time_t tTime); + void CreateVkUserInfoList(OBJLIST &vkUsers, JSONNODE *pResponse); + CMString GetVkPhotoItem(JSONNODE *pPhotoItem); + CMString GetVkNewsItem(JSONNODE *pItem, OBJLIST &vkUsers, time_t &tDate); + void RetrieveUnreadNews(); + void OnReceiveUnreadNews(NETLIBHTTPREQUEST*, AsyncHttpRequest*); + //==== Misc ========================================================================== TCHAR* GetUserStoredPassword(void); @@ -445,7 +474,11 @@ private: m_bPopUpSyncHistory, m_bAddImgBbc, m_bStikersAsSmyles, - m_bUserForceOnlineOnActivity; + m_bUserForceOnlineOnActivity, + m_bNewsEnabled, + m_bBBCOnNews; + + int m_iNewsInterval; enum MarkMsgReadOn{ markOnRead, markOnReceive, markOnReply, markOnTyping }; int m_iMarkMessageReadOn; diff --git a/protocols/VKontakte/src/vk_thread.cpp b/protocols/VKontakte/src/vk_thread.cpp index 2bb05aa571..39dc6b304a 100644 --- a/protocols/VKontakte/src/vk_thread.cpp +++ b/protocols/VKontakte/src/vk_thread.cpp @@ -54,6 +54,7 @@ static VOID CALLBACK TimerProc(HWND, UINT, UINT_PTR, DWORD) if (vk_Instances[i]->IsOnline()) { vk_Instances[i]->SetServerStatus(vk_Instances[i]->m_iDesiredStatus); vk_Instances[i]->RetrieveUsersInfo(true); + vk_Instances[i]->RetrieveUnreadNews(); } } @@ -244,7 +245,7 @@ void CVkProto::OnReceiveMyInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) RetrieveUserInfo(m_myUserId); RetrieveUnreadMessages(); RetrieveFriends(); - RetrievePollingInfo(); + RetrievePollingInfo(); } MCONTACT CVkProto::SetContactInfo(JSONNODE* pItem, bool flag, bool self) @@ -256,7 +257,7 @@ MCONTACT CVkProto::SetContactInfo(JSONNODE* pItem, bool flag, bool self) LONG userid = json_as_int(json_get(pItem, "id")); debugLogA("CVkProto::SetContactInfo %d", userid); - if (userid == 0) + if (userid == 0 || userid == VK_FEED_USER) return NULL; MCONTACT hContact = FindUser(userid, flag); @@ -377,7 +378,7 @@ MCONTACT CVkProto::SetContactInfo(JSONNODE* pItem, bool flag, bool self) void CVkProto::RetrieveUserInfo(LONG userID) { debugLogA("CVkProto::RetrieveUserInfo (%d)", userID); - if (!IsOnline()) + if (userID == VK_FEED_USER || !IsOnline()) return; CMString userIDs, code; @@ -400,7 +401,7 @@ void CVkProto::RetrieveUsersInfo(bool flag) CMString userIDs, code; for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) { LONG userID = getDword(hContact, "ID", -1); - if (userID == -1) + if (userID == -1 || userID == VK_FEED_USER) continue; if (!userIDs.IsEmpty()) userIDs.AppendChar(','); @@ -448,10 +449,12 @@ void CVkProto::OnReceiveUserInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pRe for (size_t i = 0; (hContact = SetContactInfo(json_at(pUsers, i))) != INVALID_CONTACT_ID; i++) if (hContact) arContacts.remove((HANDLE)hContact); + if (json_as_int(json_get(pResponse, "freeoffline"))) for (int i = 0; i < arContacts.getCount(); i++) { hContact = (MCONTACT)arContacts[i]; - if (getDword(hContact, "ID", -1) == (DWORD)m_myUserId) + LONG userID = getDword(hContact, "ID", -1); + if (userID == m_myUserId || userID == VK_FEED_USER) continue; if (getWord(hContact, "Status", 0) != ID_STATUS_OFFLINE) { setWord(hContact, "Status", ID_STATUS_OFFLINE); @@ -459,6 +462,7 @@ void CVkProto::OnReceiveUserInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pRe } } arContacts.destroy(); + AddFeedSpecialUser(); JSONNODE *pRequests = json_get(pResponse, "requests"); if (pRequests == NULL) @@ -533,8 +537,13 @@ void CVkProto::OnReceiveFriends(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq } if (bCleanContacts) - for (int i = 0; i < arContacts.getCount(); i++) - CallService(MS_DB_CONTACT_DELETE, (WPARAM)arContacts[i], 0); + for (int i = 0; i < arContacts.getCount(); i++) { + MCONTACT hContact = (MCONTACT)arContacts[i]; + LONG userID = getDword(hContact, "ID", -1); + if (userID == m_myUserId || userID == VK_FEED_USER) + continue; + CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact, 0); + } arContacts.destroy(); } @@ -568,7 +577,7 @@ void CVkProto::MarkMessagesRead(const MCONTACT hContact) if (!IsOnline()) return; LONG userID = getDword(hContact, "ID", -1); - if (userID == -1) + if (userID == -1 || userID == VK_FEED_USER) return; Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/messages.markAsRead.json", true, &CVkProto::OnReceiveSmth) @@ -1066,7 +1075,8 @@ INT_PTR __cdecl CVkProto::SvcSetListeningTo(WPARAM, LPARAM lParam) INT_PTR __cdecl CVkProto::SvcAddAsFriend(WPARAM hContact, LPARAM) { debugLogA("CVkProto::SvcAddAsFriend"); - if (!IsOnline()) + LONG userID = getDword(hContact, "ID", -1); + if (!IsOnline() || userID == -1 || userID == VK_FEED_USER) return 1; CallContactService(hContact, PSS_AUTHREQUESTW, 0, (LPARAM)TranslateT("Please authorize me to add you to my friend list.")); return 0; @@ -1076,7 +1086,7 @@ INT_PTR __cdecl CVkProto::SvcDeleteFriend(WPARAM hContact, LPARAM flag) { debugLogA("CVkProto::SvcDeleteFriend"); LONG userID = getDword(hContact, "ID", -1); - if (!IsOnline() ||(userID == -1)) + if (!IsOnline() || userID == -1 || userID == VK_FEED_USER) return 1; CMString formatstr = TranslateT("Are you sure to delete %s from your friend list?"), @@ -1131,7 +1141,7 @@ INT_PTR __cdecl CVkProto::SvcBanUser(WPARAM hContact, LPARAM) { debugLogA("CVkProto::SvcBanUser"); LONG userID = getDword(hContact, "ID", -1); - if (!IsOnline() || userID == -1) + if (!IsOnline() || userID == -1 || userID == VK_FEED_USER) return 1; CMStringA code; @@ -1194,7 +1204,7 @@ INT_PTR __cdecl CVkProto::SvcReportAbuse(WPARAM hContact, LPARAM) { debugLogA("CVkProto::SvcReportAbuse"); LONG userID = getDword(hContact, "ID", -1); - if (!IsOnline() || userID == -1) + if (!IsOnline() || userID == -1 || userID == VK_FEED_USER) return 1; CMString formatstr = TranslateT("Are you sure to report abuse on %s?"), diff --git a/protocols/VKontakte/vk_10.vcxproj b/protocols/VKontakte/vk_10.vcxproj index 6fc27a66be..3fe519c80d 100644 --- a/protocols/VKontakte/vk_10.vcxproj +++ b/protocols/VKontakte/vk_10.vcxproj @@ -183,6 +183,7 @@ + diff --git a/protocols/VKontakte/vk_10.vcxproj.filters b/protocols/VKontakte/vk_10.vcxproj.filters index 13f571045a..252f7625db 100644 --- a/protocols/VKontakte/vk_10.vcxproj.filters +++ b/protocols/VKontakte/vk_10.vcxproj.filters @@ -57,6 +57,9 @@ Source Files + + Source Files + diff --git a/protocols/VKontakte/vk_12.vcxproj b/protocols/VKontakte/vk_12.vcxproj index ec614a89a8..aaf94fb2e4 100644 --- a/protocols/VKontakte/vk_12.vcxproj +++ b/protocols/VKontakte/vk_12.vcxproj @@ -193,6 +193,7 @@ + diff --git a/protocols/VKontakte/vk_12.vcxproj.filters b/protocols/VKontakte/vk_12.vcxproj.filters index 61165d6b0e..6ce39b7884 100644 --- a/protocols/VKontakte/vk_12.vcxproj.filters +++ b/protocols/VKontakte/vk_12.vcxproj.filters @@ -33,9 +33,6 @@ Source Files - - Source Files - Source Files @@ -57,6 +54,12 @@ Source Files + + Source Files + + + Source Files + -- cgit v1.2.3