From 5f310e19fd9b3ab199682fda1e4874e1fc2cc158 Mon Sep 17 00:00:00 2001 From: Sergey Bolhovskoy Date: Fri, 5 Aug 2016 08:37:43 +0000 Subject: =?UTF-8?q?VKontakte:=20fix(=3F=3F=3F)=20=E2=80=98validation=20req?= =?UTF-8?q?uired=E2=80=99=20error=20add=20support=20vk-groups=20contacts?= =?UTF-8?q?=20fix=20(=3F=3F=3F)=20rare=20error=20with=20WorkerThread=20on?= =?UTF-8?q?=20connection=20lost=20version=20bump?= 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@17159 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/VKontakte/src/misc.cpp | 35 ++++++-- protocols/VKontakte/src/version.h | 2 +- protocols/VKontakte/src/vk.h | 1 + protocols/VKontakte/src/vk_avatars.cpp | 2 +- protocols/VKontakte/src/vk_chats.cpp | 12 +-- protocols/VKontakte/src/vk_files.cpp | 8 +- protocols/VKontakte/src/vk_history.cpp | 12 +-- protocols/VKontakte/src/vk_messages.cpp | 14 +++- protocols/VKontakte/src/vk_proto.cpp | 23 +++--- protocols/VKontakte/src/vk_proto.h | 4 + protocols/VKontakte/src/vk_queue.cpp | 4 +- protocols/VKontakte/src/vk_thread.cpp | 138 ++++++++++++++++++++++++++++---- protocols/VKontakte/src/vk_wallpost.cpp | 4 +- 13 files changed, 198 insertions(+), 61 deletions(-) (limited to 'protocols/VKontakte') diff --git a/protocols/VKontakte/src/misc.cpp b/protocols/VKontakte/src/misc.cpp index 4f1a9c6cb4..4bbb24b730 100644 --- a/protocols/VKontakte/src/misc.cpp +++ b/protocols/VKontakte/src/misc.cpp @@ -179,8 +179,8 @@ MCONTACT CVkProto::FindUser(LONG dwUserid, bool bCreate) return NULL; for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) { - LONG dbUserid = getDword(hContact, "ID", -1); - if (dbUserid == -1) + LONG dbUserid = getDword(hContact, "ID", VK_INVALID_USER); + if (dbUserid == VK_INVALID_USER) continue; if (dbUserid == dwUserid) @@ -194,6 +194,8 @@ MCONTACT CVkProto::FindUser(LONG dwUserid, bool bCreate) Proto_AddToContact(hNewContact, m_szModuleName); setDword(hNewContact, "ID", dwUserid); db_set_ws(hNewContact, "CList", "Group", m_vkOptions.pwszDefaultGroup); + if (dwUserid < 0) + setByte(hNewContact, "IsGroup", 1); return hNewContact; } @@ -203,8 +205,8 @@ MCONTACT CVkProto::FindChat(LONG dwUserid) return NULL; for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) { - LONG dbUserid = getDword(hContact, "vk_chat_id", -1); - if (dbUserid == -1) + LONG dbUserid = getDword(hContact, "vk_chat_id", VK_INVALID_USER); + if (dbUserid == VK_INVALID_USER) continue; if (dbUserid == dwUserid) @@ -214,6 +216,15 @@ MCONTACT CVkProto::FindChat(LONG dwUserid) return NULL; } +bool CVkProto::IsGroupUser(MCONTACT hContact) +{ + if (getBool(hContact, "IsGroup", false)) + return true; + + LONG userID = getDword(hContact, "ID", VK_INVALID_USER); + return (userID < 0); +} + ///////////////////////////////////////////////////////////////////////////////////////// bool CVkProto::CheckMid(LIST &lList, int guid) @@ -254,6 +265,7 @@ bool CVkProto::CheckJsonResult(AsyncHttpRequest *pReq, const JSONNode &jnNode) const JSONNode &jnError = jnNode["error"]; const JSONNode &jnErrorCode = jnError["error_code"]; + const JSONNode &jnRedirectUri = jnError["redirect_uri"]; if (!jnError || !jnErrorCode) return true; @@ -278,6 +290,13 @@ bool CVkProto::CheckJsonResult(AsyncHttpRequest *pReq, const JSONNode &jnNode) break; case VKERR_VALIDATION_REQUIRED: // Validation Required MsgPopup(NULL, TranslateT("You must validate your account before use VK in Miranda NG"), TranslateT("Error"), true); + if (jnRedirectUri) { + T2Utf szRedirectUri(jnRedirectUri.as_mstring()); + AsyncHttpRequest *pRedirectReq = new AsyncHttpRequest(this, REQUEST_GET, szRedirectUri, false, &CVkProto::OnOAuthAuthorize); + pRedirectReq->m_bApiReq = false; + pRedirectReq->bIsMainConn = true; + Push(pRedirectReq); + } break; case VKERR_FLOOD_CONTROL: pReq->m_iRetry = 0; @@ -695,8 +714,8 @@ void CVkProto::MarkDialogAsRead(MCONTACT hContact) if (!IsOnline()) return; - LONG userID = getDword(hContact, "ID", -1); - if (userID == -1 || userID == VK_FEED_USER) + LONG userID = getDword(hContact, "ID", VK_INVALID_USER); + if (userID == VK_INVALID_USER || userID == VK_FEED_USER) return; MEVENT hDBEvent = NULL; @@ -1298,12 +1317,12 @@ CMStringW CVkProto::GetFwdMessages(const JSONNode &jnMessages, const JSONNode &j void CVkProto::SetInvisible(MCONTACT hContact) { - debugLogA("CVkProto::SetInvisible %d", getDword(hContact, "ID", -1)); + debugLogA("CVkProto::SetInvisible %d", getDword(hContact, "ID", VK_INVALID_USER)); if (getWord(hContact, "Status", ID_STATUS_OFFLINE) == ID_STATUS_OFFLINE) { setWord(hContact, "Status", ID_STATUS_INVISIBLE); SetMirVer(hContact, 1); db_set_dw(hContact, "BuddyExpectator", "LastStatus", ID_STATUS_INVISIBLE); - debugLogA("CVkProto::SetInvisible %d set ID_STATUS_INVISIBLE", getDword(hContact, "ID", -1)); + debugLogA("CVkProto::SetInvisible %d set ID_STATUS_INVISIBLE", getDword(hContact, "ID", VK_INVALID_USER)); } time_t now = time(NULL); db_set_dw(hContact, "BuddyExpectator", "LastSeen", (DWORD)now); diff --git a/protocols/VKontakte/src/version.h b/protocols/VKontakte/src/version.h index b3fb9bd6de..340078e558 100644 --- a/protocols/VKontakte/src/version.h +++ b/protocols/VKontakte/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 1 #define __RELEASE_NUM 2 -#define __BUILD_NUM 4 +#define __BUILD_NUM 5 #include diff --git a/protocols/VKontakte/src/vk.h b/protocols/VKontakte/src/vk.h index 01951832cf..fa34671daa 100644 --- a/protocols/VKontakte/src/vk.h +++ b/protocols/VKontakte/src/vk.h @@ -84,6 +84,7 @@ along with this program. If not, see . #define VER_API CHAR_PARAM("v", VK_API_VER) #define VK_FEED_USER 2147483647L +#define VK_INVALID_USER 0L #if defined(_DEBUG) #define VK_NODUMPHEADERS 0 diff --git a/protocols/VKontakte/src/vk_avatars.cpp b/protocols/VKontakte/src/vk_avatars.cpp index 1bb02b1287..877bf841a2 100644 --- a/protocols/VKontakte/src/vk_avatars.cpp +++ b/protocols/VKontakte/src/vk_avatars.cpp @@ -146,7 +146,7 @@ void CVkProto::GetAvatarFileName(MCONTACT hContact, wchar_t *pwszDest, size_t cb szFileType = p; } - LONG id = getDword(hContact, "ID", -1); + LONG id = getDword(hContact, "ID", VK_INVALID_USER); mir_snwprintf(pwszDest + tPathLen, MAX_PATH - tPathLen, L"%d%s", id, szFileType); } diff --git a/protocols/VKontakte/src/vk_chats.cpp b/protocols/VKontakte/src/vk_chats.cpp index 4b0853d9d2..a60a8c3274 100644 --- a/protocols/VKontakte/src/vk_chats.cpp +++ b/protocols/VKontakte/src/vk_chats.cpp @@ -581,8 +581,8 @@ void CVkProto::LogMenuHook(CVkChatInfo *cc, GCHOOK *gch) { CVkInviteChatForm dlg(this); if (dlg.DoModal() && dlg.m_hContact != NULL) { - int uid = getDword(dlg.m_hContact, "ID", -1); - if (uid != -1) + int uid = getDword(dlg.m_hContact, "ID", VK_INVALID_USER); + if (uid != VK_INVALID_USER) Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/messages.addChatUser.json", true, &CVkProto::OnReceiveSmth) << INT_PARAM("user_id", uid) << INT_PARAM("chat_id", cc->m_chatid)); @@ -621,9 +621,9 @@ INT_PTR __cdecl CVkProto::OnJoinChat(WPARAM hContact, LPARAM) if (!getBool(hContact, "off")) return 1; - int chat_id = getDword(hContact, "vk_chat_id", -1); + int chat_id = getDword(hContact, "vk_chat_id", VK_INVALID_USER); - if (chat_id == -1) + if (chat_id == VK_INVALID_USER) return 1; AsyncHttpRequest *pReq = new AsyncHttpRequest(this, REQUEST_POST, "/method/messages.send.json", true, &CVkProto::OnSendChatMsg, AsyncHttpRequest::rpHigh) @@ -726,8 +726,8 @@ INT_PTR __cdecl CVkProto::SvcDestroyKickChat(WPARAM hContact, LPARAM) if (!getBool(hContact, "off")) return 1; - int chat_id = getDword(hContact, "vk_chat_id", -1); - if (chat_id == -1) + int chat_id = getDword(hContact, "vk_chat_id", VK_INVALID_USER); + if (chat_id == VK_INVALID_USER) return 1; CMStringA code; diff --git a/protocols/VKontakte/src/vk_files.cpp b/protocols/VKontakte/src/vk_files.cpp index 2d977768fb..327e1c700e 100644 --- a/protocols/VKontakte/src/vk_files.cpp +++ b/protocols/VKontakte/src/vk_files.cpp @@ -21,8 +21,8 @@ HANDLE CVkProto::SendFile(MCONTACT hContact, const wchar_t *desc, wchar_t **file { debugLogA("CVkProto::SendFile"); - LONG userID = getDword(hContact, "ID", -1); - if (!IsOnline() || ((userID == -1 || userID == VK_FEED_USER) && !isChatRoom(hContact))) + LONG userID = getDword(hContact, "ID", VK_INVALID_USER); + if (!IsOnline() || ((userID == VK_INVALID_USER || userID == VK_FEED_USER) && !isChatRoom(hContact))) return (HANDLE)0; CVkFileUploadParam *fup = new CVkFileUploadParam(hContact, desc, files); @@ -369,8 +369,8 @@ void CVkProto::OnReciveUploadFile(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pR } else { - LONG userID = getDword(fup->hContact, "ID", -1); - if (userID == -1 || userID == VK_FEED_USER) { + LONG userID = getDword(fup->hContact, "ID", VK_INVALID_USER); + if (userID == VK_INVALID_USER || userID == VK_FEED_USER) { SendFileFiled(fup, VKERR_INVALID_USER); return; } diff --git a/protocols/VKontakte/src/vk_history.cpp b/protocols/VKontakte/src/vk_history.cpp index 706f38568e..756e6f6cbf 100644 --- a/protocols/VKontakte/src/vk_history.cpp +++ b/protocols/VKontakte/src/vk_history.cpp @@ -28,8 +28,8 @@ INT_PTR __cdecl CVkProto::SvcGetAllServerHistoryForContact(WPARAM hContact, LPAR if (IDNO == MessageBox(NULL, str, TranslateT("Attention!"), MB_ICONWARNING | MB_YESNO)) return 0; - LONG userID = getDword(hContact, "ID", -1); - if (userID == -1 || userID == VK_FEED_USER) + LONG userID = getDword(hContact, "ID", VK_INVALID_USER); + if (userID == VK_INVALID_USER || userID == VK_FEED_USER) return 0; MEVENT hDBEvent = db_event_first(hContact); @@ -56,8 +56,8 @@ INT_PTR __cdecl CVkProto::SvcGetAllServerHistory(WPARAM, LPARAM) return 0; 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 || userID == VK_FEED_USER) + LONG userID = getDword(hContact, "ID", VK_INVALID_USER); + if (userID == VK_INVALID_USER || userID == VK_FEED_USER) continue; @@ -118,8 +118,8 @@ void CVkProto::GetServerHistory(MCONTACT hContact, int iOffset, int iCount, int if (!IsOnline()) return; - LONG userID = getDword(hContact, "ID", -1); - if (-1 == userID || userID == VK_FEED_USER) + LONG userID = getDword(hContact, "ID", VK_INVALID_USER); + if (VK_INVALID_USER == userID || userID == VK_FEED_USER) return; CMStringA code(FORMAT, "var iOffset=%d;var iReqCount=%d;var userID=%d;var iTime=%d;var lastMid=%d;" diff --git a/protocols/VKontakte/src/vk_messages.cpp b/protocols/VKontakte/src/vk_messages.cpp index 1ebed06e69..a805c7f14f 100644 --- a/protocols/VKontakte/src/vk_messages.cpp +++ b/protocols/VKontakte/src/vk_messages.cpp @@ -44,9 +44,9 @@ int CVkProto::SendMsg(MCONTACT hContact, int, const char *szMsg) return 0; bool bIsChat = isChatRoom(hContact); - LONG iUserID = getDword(hContact, bIsChat ? "vk_chat_id" : "ID" , -1); + LONG iUserID = getDword(hContact, bIsChat ? "vk_chat_id" : "ID" , VK_INVALID_USER); - if (iUserID == -1 || iUserID == VK_FEED_USER) { + if (iUserID == VK_INVALID_USER || iUserID == VK_FEED_USER) { ForkThread(&CVkProto::SendMsgAck, new CVkSendMsgParam(hContact)); return 0; } @@ -174,8 +174,8 @@ void CVkProto::MarkMessagesRead(const MCONTACT hContact) debugLogA("CVkProto::MarkMessagesRead (hContact)"); if (!IsOnline() || !hContact) return; - LONG userID = getDword(hContact, "ID", -1); - if (userID == -1 || userID == VK_FEED_USER) + LONG userID = getDword(hContact, "ID", VK_INVALID_USER); + if (userID == VK_INVALID_USER || userID == VK_FEED_USER) return; Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/messages.markAsRead.json", true, &CVkProto::OnReceiveSmth, AsyncHttpRequest::rpLow) @@ -347,6 +347,8 @@ void CVkProto::OnReceiveDlgs(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) if (!jnDlgs) return; + CMStringA szGroupIds; + for (auto it = jnDlgs.begin(); it != jnDlgs.end(); ++it) { if (!(*it)) break; @@ -364,6 +366,9 @@ void CVkProto::OnReceiveDlgs(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) uid = jnDlg["user_id"].as_int(); hContact = FindUser(uid, true); + if (IsGroupUser(hContact)) + szGroupIds.AppendFormat(szGroupIds.IsEmpty() ? "%d" : ",%d", -1 * uid); + if (ServiceExists(MS_MESSAGESTATE_UPDATE)) { time_t tLastReadMessageTime = jnDlg["date"].as_int(); bool isOut = jnDlg["out"].as_bool(); @@ -402,4 +407,5 @@ void CVkProto::OnReceiveDlgs(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) } } RetrieveUsersInfo(); + RetrieveGroupInfo(szGroupIds); } \ No newline at end of file diff --git a/protocols/VKontakte/src/vk_proto.cpp b/protocols/VKontakte/src/vk_proto.cpp index 0ebfaf6079..77388d3a51 100644 --- a/protocols/VKontakte/src/vk_proto.cpp +++ b/protocols/VKontakte/src/vk_proto.cpp @@ -355,16 +355,17 @@ void CVkProto::InitMenus() int CVkProto::OnPreBuildContactMenu(WPARAM hContact, LPARAM) { - LONG userID = getDword(hContact, "ID", -1); + LONG userID = getDword(hContact, "ID", VK_INVALID_USER); bool bisFriend = (getBool(hContact, "Auth", true) == 0); bool bisBroadcast = !(IsEmpty(ptrW(db_get_wsa(hContact, m_szModuleName, "AudioUrl")))); + bool bIsGroup = IsGroupUser(hContact); Menu_ShowItem(m_hContactMenuItems[CMI_VISITPROFILE], userID != VK_FEED_USER); Menu_ShowItem(m_hContactMenuItems[CMI_MARKMESSAGESASREAD], !isChatRoom(hContact) && userID != VK_FEED_USER); Menu_ShowItem(m_hContactMenuItems[CMI_WALLPOST], !isChatRoom(hContact)); - Menu_ShowItem(m_hContactMenuItems[CMI_ADDASFRIEND], !bisFriend && !isChatRoom(hContact) && userID != VK_FEED_USER); - Menu_ShowItem(m_hContactMenuItems[CMI_DELETEFRIEND], bisFriend && userID != VK_FEED_USER); - Menu_ShowItem(m_hContactMenuItems[CMI_BANUSER], !isChatRoom(hContact) && userID != VK_FEED_USER); - Menu_ShowItem(m_hContactMenuItems[CMI_REPORTABUSE], !isChatRoom(hContact) && userID != VK_FEED_USER); + Menu_ShowItem(m_hContactMenuItems[CMI_ADDASFRIEND], !bisFriend && !isChatRoom(hContact) && userID != VK_FEED_USER && !bIsGroup); + Menu_ShowItem(m_hContactMenuItems[CMI_DELETEFRIEND], bisFriend && userID != VK_FEED_USER && !bIsGroup); + Menu_ShowItem(m_hContactMenuItems[CMI_BANUSER], !isChatRoom(hContact) && userID != VK_FEED_USER && !bIsGroup); + Menu_ShowItem(m_hContactMenuItems[CMI_REPORTABUSE], !isChatRoom(hContact) && userID != VK_FEED_USER && !bIsGroup); Menu_ShowItem(m_hContactMenuItems[CMI_DESTROYKICKCHAT], isChatRoom(hContact) && getBool(hContact, "off")); Menu_ShowItem(m_hContactMenuItems[CMI_OPENBROADCAST], !isChatRoom(hContact) && bisBroadcast); Menu_ShowItem(m_hContactMenuItems[CMI_GETSERVERHISTORY], !isChatRoom(hContact) && userID != VK_FEED_USER); @@ -549,8 +550,8 @@ int CVkProto::AuthRequest(MCONTACT hContact, const wchar_t *message) if (!IsOnline()) return 1; - LONG userID = getDword(hContact, "ID", -1); - if (userID == -1 || !hContact || userID == VK_FEED_USER) + LONG userID = getDword(hContact, "ID", VK_INVALID_USER); + if (userID == VK_INVALID_USER || !hContact || userID == VK_FEED_USER) return 1; wchar_t msg[501] = {0}; @@ -632,8 +633,8 @@ 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() || userID == VK_FEED_USER) + LONG userID = getDword(hContact, "ID", VK_INVALID_USER); + if (userID == VK_INVALID_USER || !IsOnline() || userID == VK_FEED_USER) return 1; if (m_vkOptions.iMarkMessageReadOn == MarkMsgReadOn::markOnTyping) @@ -650,8 +651,8 @@ int CVkProto::UserIsTyping(MCONTACT hContact, int type) int CVkProto::GetInfo(MCONTACT hContact, int) { debugLogA("CVkProto::GetInfo"); - LONG userID = getDword(hContact, "ID", -1); - if (userID == -1 || userID == VK_FEED_USER) + LONG userID = getDword(hContact, "ID", VK_INVALID_USER); + if (userID == VK_INVALID_USER || 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 ae91f9d5f0..401e6b213e 100644 --- a/protocols/VKontakte/src/vk_proto.h +++ b/protocols/VKontakte/src/vk_proto.h @@ -292,7 +292,10 @@ private: void RetrieveMyInfo(void); void OnReceiveMyInfo(NETLIBHTTPREQUEST*, AsyncHttpRequest*); void RetrieveUserInfo(LONG userId); + void RetrieveGroupInfo(LONG groupID); + void RetrieveGroupInfo(CMStringA & groupIDs); void OnReceiveUserInfo(NETLIBHTTPREQUEST*, AsyncHttpRequest*); + void OnReceiveGroupInfo(NETLIBHTTPREQUEST * reply, AsyncHttpRequest * pReq); void RetrieveFriends(bool bCleanNonFriendContacts = false); void OnReceiveFriends(NETLIBHTTPREQUEST*, AsyncHttpRequest*); void MarkMessagesRead(const CMStringA &mids); @@ -320,6 +323,7 @@ private: void SetAllContactStatuses(int status); MCONTACT FindUser(LONG userid, bool bCreate = false); MCONTACT FindChat(LONG dwUserid); + bool IsGroupUser(MCONTACT hContact); bool CheckMid(LIST &lList, int guid); JSONNode& CheckJsonResponse(AsyncHttpRequest *pReq, NETLIBHTTPREQUEST *reply, JSONNode &root); bool CheckJsonResult(AsyncHttpRequest *pReq, const JSONNode &Node); diff --git a/protocols/VKontakte/src/vk_queue.cpp b/protocols/VKontakte/src/vk_queue.cpp index fed6cd6ab4..57f71ceeb7 100644 --- a/protocols/VKontakte/src/vk_queue.cpp +++ b/protocols/VKontakte/src/vk_queue.cpp @@ -172,14 +172,14 @@ void CVkProto::WorkerThread(void*) } } + m_hWorkerThread = 0; if (m_hAPIConnection) { debugLogA("CVkProto::WorkerThread: Netlib_CloseHandle(m_hAPIConnection) beg"); Netlib_CloseHandle(m_hAPIConnection); debugLogA("CVkProto::WorkerThread: Netlib_CloseHandle(m_hAPIConnection) end"); + m_hAPIConnection = NULL; } - m_hAPIConnection = NULL; - m_hWorkerThread = 0; debugLogA("CVkProto::WorkerThread: leaving m_bTerminated = %d", m_bTerminated ? 1 : 0); } diff --git a/protocols/VKontakte/src/vk_thread.cpp b/protocols/VKontakte/src/vk_thread.cpp index d2022cb2df..fafc9be71b 100644 --- a/protocols/VKontakte/src/vk_thread.cpp +++ b/protocols/VKontakte/src/vk_thread.cpp @@ -461,12 +461,39 @@ void CVkProto::RetrieveUserInfo(LONG userID) if (userID == VK_FEED_USER || !IsOnline()) return; + if (userID < 0) { + RetrieveGroupInfo(userID); + return; + } + CMStringW code(FORMAT, L"var userIDs=\"%i\";var res=API.users.get({\"user_ids\":userIDs,\"fields\":\"%s\",\"name_case\":\"nom\"});return{\"freeoffline\":0,\"norepeat\":1,\"usercount\":res.length,\"users\":res};", userID, CMStringW(fieldsName)); Push(new AsyncHttpRequest(this, REQUEST_POST, "/method/execute.json", true, &CVkProto::OnReceiveUserInfo) << WCHAR_PARAM("code", code)); } +void CVkProto::RetrieveGroupInfo(LONG groupID) +{ + debugLogA("CVkProto::RetrieveGroupInfo (%d)", groupID); + if (groupID >= VK_INVALID_USER || !IsOnline()) + return; + + Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/groups.getById.json", true, &CVkProto::OnReceiveGroupInfo) + << CHAR_PARAM("fields", "description") + << INT_PARAM("group_id", -1*groupID)); +} + +void CVkProto::RetrieveGroupInfo(CMStringA& groupIDs) +{ + debugLogA("CVkProto::RetrieveGroupInfo (%s)", groupIDs); + if (groupIDs.IsEmpty() || !IsOnline()) + return; + + Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/groups.getById.json", true, &CVkProto::OnReceiveGroupInfo) + << CHAR_PARAM("fields", "description,status") + << CHAR_PARAM("group_ids", groupIDs)); +} + void CVkProto::RetrieveUsersInfo(bool bFreeOffline, bool bRepeat) { debugLogA("CVkProto::RetrieveUsersInfo"); @@ -476,8 +503,8 @@ void CVkProto::RetrieveUsersInfo(bool bFreeOffline, bool bRepeat) CMStringW userIDs, code; int i = 0; 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 || userID == VK_FEED_USER) + LONG userID = getDword(hContact, "ID", VK_INVALID_USER); + if (userID == VK_INVALID_USER || userID == VK_FEED_USER || userID < 0) continue; if (!userIDs.IsEmpty()) userIDs.AppendChar(','); @@ -534,7 +561,7 @@ void CVkProto::OnReceiveUserInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pRe LIST arContacts(10, PtrKeySortT); for (hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) - if (!isChatRoom(hContact)) + if (!isChatRoom(hContact) && !IsGroupUser(hContact)) arContacts.insert((HANDLE)hContact); for (auto it = jnUsers.begin(); it != jnUsers.end(); ++it) { @@ -546,7 +573,7 @@ void CVkProto::OnReceiveUserInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pRe if (jnResponse["freeoffline"].as_bool()) for (int i = 0; i < arContacts.getCount(); i++) { hContact = (UINT_PTR)arContacts[i]; - LONG userID = getDword(hContact, "ID", -1); + LONG userID = getDword(hContact, "ID", VK_INVALID_USER); if (userID == m_myUserId || userID == VK_FEED_USER) continue; @@ -587,6 +614,84 @@ void CVkProto::OnReceiveUserInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pRe } } +void CVkProto::OnReceiveGroupInfo(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) +{ + debugLogA("CVkProto::OnReceiveUserInfo %d", reply->resultCode); + + if (reply->resultCode != 200 || !IsOnline()) + return; + + JSONNode jnRoot; + const JSONNode &jnResponse = CheckJsonResponse(pReq, reply, jnRoot); + if (!jnResponse) + return; + + for (auto it = jnResponse.begin(); it != jnResponse.end(); ++it) { + const JSONNode &jnItem = (*it); + + int iGroupId = (-1)*jnItem["id"].as_int(); + MCONTACT hContact = FindUser(iGroupId, true); + + if (!hContact) + continue; + + CMStringW wszValue; + + wszValue = jnItem["name"].as_mstring(); + if (!wszValue.IsEmpty()) + setWString(hContact, "Nick", wszValue); + + if (getWord(hContact, "Status", ID_STATUS_OFFLINE) != ID_STATUS_ONLINE) + setWord(hContact, "Status", ID_STATUS_ONLINE); + + setByte(hContact, "IsGroup", 1); + + bool bIsMember = jnItem["is_member"].as_bool(); + setByte(hContact, "Auth", !bIsMember); + setByte(hContact, "friend", bIsMember); + + wszValue = jnItem["screen_name"].as_mstring(); + if (!wszValue.IsEmpty()) { + setWString(hContact, "domain", wszValue); + wszValue = L"https://vk.com/" + wszValue; + setWString(hContact, "Homepage", wszValue); + } + + wszValue = jnItem["description"].as_mstring(); + if (!wszValue.IsEmpty()) + setWString(hContact, "About", wszValue); + + wszValue = jnItem["photo_100"].as_mstring(); + if (!wszValue.IsEmpty()) { + SetAvatarUrl(hContact, wszValue); + ReloadAvatarInfo(hContact); + } + + wszValue = jnItem["status"].as_mstring(); + CMStringW wszOldStatus(ptrW(db_get_wsa(hContact, hContact ? "CList" : m_szModuleName, "StatusMsg"))); + if (wszValue != wszOldStatus) + db_set_ws(hContact, hContact ? "CList" : m_szModuleName, "StatusMsg", wszValue); + + CMStringW wszOldListeningTo(ptrW(db_get_wsa(hContact, m_szModuleName, "ListeningTo"))); + const JSONNode &jnAudio = jnItem["status_audio"]; + if (jnAudio) { + CMStringW wszListeningTo(FORMAT, L"%s - %s", jnAudio["artist"].as_mstring(), jnAudio["title"].as_mstring()); + if (wszListeningTo != wszOldListeningTo) { + setWString(hContact, "ListeningTo", wszListeningTo); + setWString(hContact, "AudioUrl", jnAudio["url"].as_mstring()); + } + } + else if (wszValue[0] == wchar_t(9835) && wszValue.GetLength() > 2) { + setWString(hContact, "ListeningTo", &(wszValue.GetBuffer())[2]); + db_unset(hContact, m_szModuleName, "AudioUrl"); + } + else { + db_unset(hContact, m_szModuleName, "ListeningTo"); + db_unset(hContact, m_szModuleName, "AudioUrl"); + } + } +} + void CVkProto::RetrieveFriends(bool bCleanNonFriendContacts) { debugLogA("CVkProto::RetrieveFriends"); @@ -615,7 +720,7 @@ void CVkProto::OnReceiveFriends(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq LIST arContacts(10, PtrKeySortT); for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) { - if (!isChatRoom(hContact)) + if (!isChatRoom(hContact) && !IsGroupUser(hContact)) setByte(hContact, "Auth", 1); db_unset(hContact, m_szModuleName, "ReqAuth"); SetMirVer(hContact, -1); @@ -639,8 +744,9 @@ void CVkProto::OnReceiveFriends(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq if (bCleanContacts) for (int i = 0; i < arContacts.getCount(); i++) { MCONTACT hContact = (UINT_PTR)arContacts[i]; - LONG userID = getDword(hContact, "ID", -1); - if (userID == m_myUserId || userID == VK_FEED_USER) + LONG userID = getDword(hContact, "ID", VK_INVALID_USER); + bool bIsFriendGroup = IsGroupUser(hContact) && getBool(hContact, "friend"); + if (userID == m_myUserId || userID == VK_FEED_USER || bIsFriendGroup) continue; CallService(MS_DB_CONTACT_DELETE, (WPARAM)hContact); } @@ -653,8 +759,8 @@ void CVkProto::OnReceiveFriends(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq INT_PTR __cdecl CVkProto::SvcAddAsFriend(WPARAM hContact, LPARAM) { debugLogA("CVkProto::SvcAddAsFriend"); - LONG userID = getDword(hContact, "ID", -1); - if (!IsOnline() || userID == -1 || userID == VK_FEED_USER) + LONG userID = getDword(hContact, "ID", VK_INVALID_USER); + if (!IsOnline() || userID == VK_INVALID_USER || userID == VK_FEED_USER) return 1; ProtoChainSend(hContact, PSS_AUTHREQUEST, 0, (LPARAM)TranslateT("Please authorize me to add you to my friend list.")); return 0; @@ -674,8 +780,8 @@ INT_PTR CVkProto::SvcWipeNonFriendContacts(WPARAM, LPARAM) INT_PTR __cdecl CVkProto::SvcDeleteFriend(WPARAM hContact, LPARAM flag) { debugLogA("CVkProto::SvcDeleteFriend"); - LONG userID = getDword(hContact, "ID", -1); - if (!IsOnline() || userID == -1 || userID == VK_FEED_USER) + LONG userID = getDword(hContact, "ID", VK_INVALID_USER); + if (!IsOnline() || userID == VK_INVALID_USER || userID == VK_FEED_USER) return 1; ptrW pwszNick(db_get_wsa(hContact, m_szModuleName, "Nick")); @@ -734,8 +840,8 @@ void CVkProto::OnReceiveDeleteFriend(NETLIBHTTPREQUEST *reply, AsyncHttpRequest INT_PTR __cdecl CVkProto::SvcBanUser(WPARAM hContact, LPARAM) { debugLogA("CVkProto::SvcBanUser"); - LONG userID = getDword(hContact, "ID", -1); - if (!IsOnline() || userID == -1 || userID == VK_FEED_USER) + LONG userID = getDword(hContact, "ID", VK_INVALID_USER); + if (!IsOnline() || userID == VK_INVALID_USER || userID == VK_FEED_USER) return 1; CMStringA code(FORMAT, "var userID=\"%d\";API.account.banUser({\"user_id\":userID});", userID); @@ -792,8 +898,8 @@ INT_PTR __cdecl CVkProto::SvcBanUser(WPARAM hContact, LPARAM) INT_PTR __cdecl CVkProto::SvcReportAbuse(WPARAM hContact, LPARAM) { debugLogA("CVkProto::SvcReportAbuse"); - LONG userID = getDword(hContact, "ID", -1); - if (!IsOnline() || userID == -1 || userID == VK_FEED_USER) + LONG userID = getDword(hContact, "ID", VK_INVALID_USER); + if (!IsOnline() || userID == VK_INVALID_USER || userID == VK_FEED_USER) return 1; CMStringW wszNick(ptrW(db_get_wsa(hContact, m_szModuleName, "Nick"))), @@ -829,7 +935,7 @@ INT_PTR __cdecl CVkProto::SvcVisitProfile(WPARAM hContact, LPARAM) return 0; } - LONG userID = getDword(hContact, "ID", -1); + LONG userID = getDword(hContact, "ID", VK_INVALID_USER); ptrW wszDomain(db_get_wsa(hContact, m_szModuleName, "domain")); CMStringW wszUrl("https://vk.com/"); diff --git a/protocols/VKontakte/src/vk_wallpost.cpp b/protocols/VKontakte/src/vk_wallpost.cpp index 3f91ebab3a..3783fce1ab 100644 --- a/protocols/VKontakte/src/vk_wallpost.cpp +++ b/protocols/VKontakte/src/vk_wallpost.cpp @@ -36,8 +36,8 @@ void CVkProto::WallPost(MCONTACT hContact, wchar_t *pwszMsg, wchar_t *pwszUrl, b if (!IsOnline() || (IsEmpty(pwszMsg) && IsEmpty(pwszUrl))) return; - LONG userID = hContact ? m_myUserId : getDword(hContact, "ID", -1); - if (userID == -1 || userID == VK_FEED_USER) + LONG userID = hContact ? m_myUserId : getDword(hContact, "ID", VK_INVALID_USER); + if (userID == VK_INVALID_USER || userID == VK_FEED_USER) return; AsyncHttpRequest *pReq = new AsyncHttpRequest(this, REQUEST_POST, "/method/wall.post.json", true, &CVkProto::OnReceiveSmth) -- cgit v1.2.3