From f0d86d413859d402331b49b98db7d61fef801489 Mon Sep 17 00:00:00 2001 From: ElzorFox Date: Mon, 15 Jun 2020 16:04:53 +0500 Subject: VKontakte: prepare for upgrade VK API version - part 2 --- protocols/VKontakte/src/vk_chats.cpp | 83 +++++++++++++++++++++++++++++++++ protocols/VKontakte/src/vk_history.cpp | 30 ++++++++++-- protocols/VKontakte/src/vk_messages.cpp | 80 +++++++++++++++++++++++++++++++ protocols/VKontakte/src/vk_proto.h | 1 + protocols/VKontakte/src/vkjs.js | 44 +++++++++++++++++ 5 files changed, 233 insertions(+), 5 deletions(-) (limited to 'protocols/VKontakte') diff --git a/protocols/VKontakte/src/vk_chats.cpp b/protocols/VKontakte/src/vk_chats.cpp index bc39f6cc40..cf385b0644 100644 --- a/protocols/VKontakte/src/vk_chats.cpp +++ b/protocols/VKontakte/src/vk_chats.cpp @@ -28,6 +28,89 @@ static LPCWSTR sttStatuses[] = { LPGENW("Participants"), LPGENW("Owners") }; extern JSONNode nullNode; + +CVkChatInfo* CVkProto::AppendConversationChat(int iChatId, const JSONNode& jnItem) +{ + debugLogW(L"CVkProto::AppendConversationChat %d", iChatId); + if (iChatId == 0) + return nullptr; + + + if (!jnItem) + return nullptr; + + + const JSONNode& jnLastMessage = jnItem["last_message"]; + const JSONNode& jnChatSettings = jnItem["chat_settings"]; + + if (jnLastMessage) { + const JSONNode& jnAction = jnLastMessage["action"]; + if (jnAction) { + CMStringW wszActionType(jnAction["type"].as_mstring()); + if ((wszActionType == L"chat_kick_user") && (jnAction["member_id"].as_int() == m_myUserId)) { + return nullptr; + } + } + } + + MCONTACT hChatContact = FindChat(iChatId); + if (hChatContact && getBool(hChatContact, "kicked")) + return nullptr; + + + + CVkChatInfo* vkChatInfo = m_chats.find((CVkChatInfo*)&iChatId); + if (vkChatInfo != nullptr) + return vkChatInfo; + + CMStringW wszTitle, wszState; + vkChatInfo = new CVkChatInfo(iChatId); + if (jnChatSettings) { + wszTitle = jnChatSettings["title"].as_mstring(); + vkChatInfo->m_wszTopic = mir_wstrdup(!wszTitle.IsEmpty() ? wszTitle : L""); + wszState = jnChatSettings["state"].as_mstring(); + } + + CMStringW sid; + sid.Format(L"%S_%d", m_szModuleName, iChatId); + vkChatInfo->m_wszId = mir_wstrdup(sid); + + + SESSION_INFO* si = Chat_NewSession(GCW_CHATROOM, m_szModuleName, sid, wszTitle); + if (si == nullptr) { + delete vkChatInfo; + return nullptr; + } + + vkChatInfo->m_hContact = si->hContact; + setWString(si->hContact, "Nick", wszTitle); + m_chats.insert(vkChatInfo); + + for (int i = _countof(sttStatuses) - 1; i >= 0; i--) + Chat_AddGroup(si, TranslateW(sttStatuses[i])); + + setDword(si->hContact, "vk_chat_id", iChatId); + + CMStringW wszHomepage(FORMAT, L"https://vk.com/im?sel=c%d", iChatId); + setWString(si->hContact, "Homepage", wszHomepage); + + db_unset(si->hContact, m_szModuleName, "off"); + + if (wszState != L"in") { + setByte(si->hContact, "off", 1); + m_chats.remove(vkChatInfo); + return nullptr; + } + + Chat_Control(m_szModuleName, sid, (m_vkOptions.bHideChats) ? WINDOW_HIDDEN : SESSION_INITDONE); + Chat_Control(m_szModuleName, sid, SESSION_ONLINE); + + RetrieveChatInfo(vkChatInfo); + + return vkChatInfo; + +} + CVkChatInfo* CVkProto::AppendChat(int id, const JSONNode &jnDlg) { debugLogW(L"CVkProto::AppendChat"); diff --git a/protocols/VKontakte/src/vk_history.cpp b/protocols/VKontakte/src/vk_history.cpp index 3e7a05a8e7..7695e33859 100644 --- a/protocols/VKontakte/src/vk_history.cpp +++ b/protocols/VKontakte/src/vk_history.cpp @@ -130,6 +130,7 @@ void CVkProto::GetServerHistory(MCONTACT hContact, int iOffset, int iCount, int if (VK_INVALID_USER == userID || userID == VK_FEED_USER) return; +#if (VK_NEW_API == 0) Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/execute.GetServerHistory", true, &CVkProto::OnReceiveHistoryMessages, AsyncHttpRequest::rpLow) << INT_PARAM("reqcount", iCount) << INT_PARAM("offset", iOffset) @@ -138,7 +139,16 @@ void CVkProto::GetServerHistory(MCONTACT hContact, int iOffset, int iCount, int << INT_PARAM("lastmid", iLastMsgId) << INT_PARAM("once", (int)once) )->pUserInfo = new CVkSendMsgParam(hContact, iLastMsgId, iOffset); - +#else + Push(new AsyncHttpRequest(this, REQUEST_GET, "/method/execute.GetServerConversationHistory", true, &CVkProto::OnReceiveHistoryMessages, AsyncHttpRequest::rpLow) + << INT_PARAM("reqcount", iCount) + << INT_PARAM("offset", iOffset) + << INT_PARAM("userid", userID) + << INT_PARAM("time", iTime) + << INT_PARAM("lastmid", iLastMsgId) + << INT_PARAM("once", (int)once) + )->pUserInfo = new CVkSendMsgParam(hContact, iLastMsgId, iOffset); +#endif } void CVkProto::GetHistoryDlg(MCONTACT hContact, int iLastMsg) @@ -224,21 +234,31 @@ void CVkProto::OnReceiveHistoryMessages(NETLIBHTTPREQUEST *reply, AsyncHttpReque for (auto it = jnMsgs.rbegin(); it != jnMsgs.rend(); ++it) { const JSONNode &jnMsg = (*it); +#if (VK_NEW_API == 1) + int mid = jnMsg["conversation_message_id"].as_int(); +#else int mid = jnMsg["id"].as_int(); +#endif + if (iLastMsgId < mid) iLastMsgId = mid; char szMid[40]; _itoa(mid, szMid, 10); - +#if (VK_NEW_API == 1) + CMStringW wszBody(jnMsg["text"].as_mstring()); + int uid = jnMsg["peer_id"].as_int(); +#else CMStringW wszBody(jnMsg["body"].as_mstring()); + int uid = jnMsg["user_id"].as_int(); +#endif + int datetime = jnMsg["date"].as_int(); int isOut = jnMsg["out"].as_int(); int isRead = jnMsg["read_state"].as_int(); - int uid = jnMsg["user_id"].as_int(); const JSONNode &jnFwdMessages = jnMsg["fwd_messages"]; - if (jnFwdMessages) { + if (jnFwdMessages && !jnFwdMessages.empty()) { CMStringW wszFwdMessages = GetFwdMessages(jnFwdMessages, jnFUsers, m_vkOptions.BBCForAttachments()); if (!wszBody.IsEmpty()) wszFwdMessages = L"\n" + wszFwdMessages; @@ -246,7 +266,7 @@ void CVkProto::OnReceiveHistoryMessages(NETLIBHTTPREQUEST *reply, AsyncHttpReque } const JSONNode &jnAttachments = jnMsg["attachments"]; - if (jnAttachments) { + if (jnAttachments && !jnAttachments.empty()) { CMStringW wszAttachmentDescr = GetAttachmentDescr(jnAttachments, m_vkOptions.BBCForAttachments()); if (wszAttachmentDescr == L"== FilterAudioMessages ==") { diff --git a/protocols/VKontakte/src/vk_messages.cpp b/protocols/VKontakte/src/vk_messages.cpp index 11c0b96c8d..bb020a3594 100644 --- a/protocols/VKontakte/src/vk_messages.cpp +++ b/protocols/VKontakte/src/vk_messages.cpp @@ -413,6 +413,85 @@ void CVkProto::OnReceiveDlgs(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) CMStringA szGroupIds; +#if (VK_NEW_API == 1) + for (auto& it : jnDlgs) { + if (!it) + break; + + const JSONNode& jnConversation = it["conversation"]; + const JSONNode& jnLastMessage = it["last_message"]; + + if (!jnConversation) + break; + + int iUnreadCount = jnConversation["unread_count"].as_int(); + + const JSONNode& jnPeer = jnConversation["peer"]; + if (!jnPeer) + break; + + int iUserId = 0; + MCONTACT hContact(0); + CMStringW wszPeerType(jnPeer["type"].as_mstring()); + + if (wszPeerType == L"user" || wszPeerType == L"group") { + iUserId = jnPeer["id"].as_int(); + int iSearchId = (wszPeerType == L"group") ? (1000000000 - iUserId) : iUserId; + int iIndex = lufUsers.indexOf((HANDLE)iSearchId); + + debugLogA("CVkProto::OnReceiveDlgs UserId = %d, iIndex = %d, numUnread = %d", iUserId, iIndex, iUnreadCount); + + if (m_vkOptions.bLoadOnlyFriends && iUnreadCount == 0 && iIndex == -1) + continue; + + hContact = FindUser(iUserId, true); + debugLogA("CVkProto::OnReceiveDlgs add UserId = %d", iUserId); + + if (IsGroupUser(hContact)) + szGroupIds.AppendFormat(szGroupIds.IsEmpty() ? "%d" : ",%d", -1 * iUserId); + +/* + if (g_bMessageState) { + bool bIsOut = jnLastMessage["out"].as_bool(); + bool bIsRead = jnLastMessage["read_state"].as_bool(); + + if (bIsRead && bIsOut) + CallService(MS_MESSAGESTATE_UPDATE, hContact, MRD_TYPE_DELIVERED); + } +*/ + } + + if (wszPeerType == L"chat") { + int iChatId = jnPeer["local_id"].as_int(); + debugLogA("CVkProto::OnReceiveDlgs chatid = %d", iChatId); + if (m_chats.find((CVkChatInfo*)&iChatId) == nullptr) + AppendConversationChat(iChatId, it); + } + else if (m_vkOptions.iSyncHistoryMetod) { + int iMessageId = jnLastMessage["id"].as_int(); + m_bNotifyForEndLoadingHistory = false; + + if (getDword(hContact, "lastmsgid", -1) == -1 && iUnreadCount && !getBool(hContact, "ActiveHistoryTask")) { + setByte(hContact, "ActiveHistoryTask", 1); + GetServerHistory(hContact, 0, iUnreadCount, 0, 0, true); + } + else + GetHistoryDlg(hContact, iMessageId); + + if (m_vkOptions.iMarkMessageReadOn == MarkMsgReadOn::markOnReceive && iUnreadCount) + MarkMessagesRead(hContact); + } + else if (iUnreadCount && !getBool(hContact, "ActiveHistoryTask")) { + + m_bNotifyForEndLoadingHistory = false; + setByte(hContact, "ActiveHistoryTask", 1); + GetServerHistory(hContact, 0, iUnreadCount, 0, 0, true); + + if (m_vkOptions.iMarkMessageReadOn == MarkMsgReadOn::markOnReceive) + MarkMessagesRead(hContact); + } + } +#else for (auto &it : jnDlgs) { if (!it) break; @@ -480,6 +559,7 @@ void CVkProto::OnReceiveDlgs(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pReq) } } +#endif lufUsers.destroy(); RetrieveUsersInfo(); RetrieveGroupInfo(szGroupIds); diff --git a/protocols/VKontakte/src/vk_proto.h b/protocols/VKontakte/src/vk_proto.h index bad4617a4b..11602452ca 100644 --- a/protocols/VKontakte/src/vk_proto.h +++ b/protocols/VKontakte/src/vk_proto.h @@ -388,6 +388,7 @@ private: void __cdecl ChatContactTypingThread(void *p); void StopChatContactTyping(int iChatId, LONG iUserId); void OnCreateNewChat(NETLIBHTTPREQUEST*, AsyncHttpRequest*); + CVkChatInfo* AppendConversationChat(int iChatId, const JSONNode& jnItem); CVkChatInfo* AppendChat(int id, const JSONNode &jnNode); void SetChatTitle(CVkChatInfo *cc, LPCWSTR wszTopic); void AppendChatMessage(int id, const JSONNode &jnMsg, const JSONNode &jnFUsers, bool bIsHistory); diff --git a/protocols/VKontakte/src/vkjs.js b/protocols/VKontakte/src/vkjs.js index 8a95f260b5..8741b09024 100644 --- a/protocols/VKontakte/src/vkjs.js +++ b/protocols/VKontakte/src/vkjs.js @@ -104,6 +104,50 @@ if (index > 0) { }; // Stored procedure name: GetServerHistory = End + +// Stored procedure name: GetServerConversationHistory = Begin +// Arguments: +// Args.userid +// Args.offset +// Args.reqcount +// Args.time +// Args.lastmid +// Args.once + +var Hist = API.messages.getHistory({ "user_id": Args.userid, "count": Args.reqcount, "offset": Args.offset }); +var ext = Hist.items.length; +var index = 0; +while (ext != 0) { + if (Hist.items[index].date > Args.time) { + if (Hist.items[index].conversation_message_id > Args.lastmid) { + index = index + 1; + ext = ext - 1; + } else + ext = 0; + } else + ext = 0; +}; +if (index > 0) { + var ret = Hist.items.slice(0, index); + var FMsgs = ret@.fwd_messages; + var Idx = 0; + var Uids = []; + while (Idx < FMsgs.length) { + var Jdx = 0; + var CFMsgs = parseInt(FMsgs[Idx].length); + while (Jdx < CFMsgs) { + Uids.unshift(FMsgs[Idx][Jdx].peer_id); + Jdx = Jdx + 1; + }; + Idx = Idx + 1; + }; + var FUsers = API.users.get({ "user_ids": Uids, "name_case": "gen" }); + return { "count": index, "datetime": parseInt(Args.time), "items": ret, "fwd_users": FUsers, "once": parseInt(Args.once), "rcount": parseInt(Args.reqcount) }; +} else { + return{"count":0,"datetime":parseInt(Args.time),"items":[],"fwd_users":[],"once":parseInt(Args.once),"rcount":parseInt(Args.reqcount)}; +}; +// Stored procedure name: GetServerConversationHistory = End + // Stored procedure name: RetrieveMessagesByIds = Begin // Arguments: // Args.mids -- cgit v1.2.3