From a1e85579f746d778c874cf083d154caa09965eea Mon Sep 17 00:00:00 2001 From: ElzorFox Date: Mon, 18 Dec 2017 15:35:14 +0500 Subject: VKontakte: add edited message support (only from vk to miranda) update VK_API to 5.68 version bump --- protocols/VKontakte/src/misc.cpp | 38 +++++++++++++++++++++++++++++++ protocols/VKontakte/src/version.h | 2 +- protocols/VKontakte/src/vk.h | 5 +++- protocols/VKontakte/src/vk_messages.cpp | 17 ++++++++++++-- protocols/VKontakte/src/vk_pollserver.cpp | 11 ++++++++- protocols/VKontakte/src/vk_proto.cpp | 1 + protocols/VKontakte/src/vk_proto.h | 2 ++ 7 files changed, 71 insertions(+), 5 deletions(-) diff --git a/protocols/VKontakte/src/misc.cpp b/protocols/VKontakte/src/misc.cpp index 67c1ff428a..27a8a8a8a2 100644 --- a/protocols/VKontakte/src/misc.cpp +++ b/protocols/VKontakte/src/misc.cpp @@ -343,6 +343,9 @@ bool CVkProto::CheckJsonResult(AsyncHttpRequest *pReq, const JSONNode &jnNode) case VKERR_CANT_SEND_YOU_ON_BLACKLIST: MsgPopup(TranslateT("Can't send messages to this user due to their privacy settings"), TranslateT("Error"), true); break; + case VKERR_MESSAGE_IS_TOO_LONG: + MsgPopup(TranslateT("Message is too long"), TranslateT("Error"), true); + break; case VKERR_COULD_NOT_SAVE_FILE: case VKERR_INVALID_ALBUM_ID: case VKERR_INVALID_SERVER: @@ -1515,6 +1518,41 @@ void CVkProto::AddVkDeactivateEvent(MCONTACT hContact, CMStringW& wszType) db_event_add(hContact, &dbei); } +MEVENT CVkProto::GetMessageFromDb(MCONTACT hContact, const char *messageId, UINT ×tamp, CMStringW &msg) +{ + if (messageId == nullptr) + return 0; + + size_t messageIdLength = mir_strlen(messageId); + + for (MEVENT hDbEvent = db_event_last(hContact); hDbEvent; hDbEvent = db_event_prev(hContact, hDbEvent)) { + DBEVENTINFO dbei = {}; + dbei.cbBlob = db_event_getBlobSize(hDbEvent); + + if (dbei.cbBlob < messageIdLength) + continue; + + mir_ptr blob((PBYTE)mir_alloc(dbei.cbBlob)); + dbei.pBlob = blob; + db_event_get(hDbEvent, &dbei); + + size_t cbLen = mir_strlen((char*)dbei.pBlob); + if ((dbei.eventType != EVENTTYPE_MESSAGE) || (cbLen + messageIdLength + 1 > dbei.cbBlob)) + continue; + + if (memcmp(&dbei.pBlob[cbLen + 1], messageId, messageIdLength) == 0) { + msg = ptrW(mir_utf8decodeW((char*)dbei.pBlob)); + timestamp = dbei.timestamp; + return hDbEvent; + } + + if (dbei.timestamp < timestamp) + break; + } + + return 0; +} + int CVkProto::DeleteContact(MCONTACT hContact) { setByte(hContact, "SilentDelete", 1); diff --git a/protocols/VKontakte/src/version.h b/protocols/VKontakte/src/version.h index b05e0437fd..9cbd3b1713 100644 --- a/protocols/VKontakte/src/version.h +++ b/protocols/VKontakte/src/version.h @@ -1,6 +1,6 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 1 -#define __RELEASE_NUM 3 +#define __RELEASE_NUM 4 #define __BUILD_NUM 0 #include diff --git a/protocols/VKontakte/src/vk.h b/protocols/VKontakte/src/vk.h index 148ffc5799..e4cbd127a6 100644 --- a/protocols/VKontakte/src/vk.h +++ b/protocols/VKontakte/src/vk.h @@ -25,6 +25,7 @@ along with this program. If not, see . #define VKPOLL_MSG_ADDFLAGS 2 #define VKPOLL_MSG_DELFLAGS 3 #define VKPOLL_MSG_ADDED 4 +#define VKPOLL_MSG_EDITED 5 #define VKPOLL_READ_ALL_IN 6 #define VKPOLL_READ_ALL_OUT 7 #define VKPOLL_USR_ONLINE 8 @@ -74,6 +75,8 @@ along with this program. If not, see . #define VKERR_CANT_SEND_USER_ON_BLACKLIST 900 // Can't send messages for users from blacklist #define VKERR_CANT_SEND_USER_WITHOUT_DIALOGS 901 // Can't send messages for users without dialogs #define VKERR_CANT_SEND_YOU_ON_BLACKLIST 902 // Can't send messages to this user due to their privacy settings +#define VKERR_MESSAGE_IS_TOO_LONG 914 // Message is too long + // File upload custom error #define VKERR_FILE_NOT_EXIST 10100 // File does not exist #define VKERR_FTYPE_NOT_SUPPORTED 10101 // File type not supported @@ -85,7 +88,7 @@ along with this program. If not, see . #define VK_USER_DEACTIVATE_ACTION 9321 -#define VK_API_VER "5.68" +#define VK_API_VER "5.69" #define VER_API CHAR_PARAM("v", VK_API_VER) #define VK_FEED_USER 2147483647L diff --git a/protocols/VKontakte/src/vk_messages.cpp b/protocols/VKontakte/src/vk_messages.cpp index 56d3b4edda..2c0bead07c 100644 --- a/protocols/VKontakte/src/vk_messages.cpp +++ b/protocols/VKontakte/src/vk_messages.cpp @@ -250,7 +250,7 @@ void CVkProto::OnReceiveMessages(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pRe UINT mid = jnMsg["id"].as_int(); CMStringW wszBody(jnMsg["body"].as_mstring()); - int datetime = jnMsg["date"].as_int(); + UINT 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(); @@ -313,8 +313,21 @@ void CVkProto::OnReceiveMessages(NETLIBHTTPREQUEST *reply, AsyncHttpRequest *pRe else if (m_vkOptions.bUserForceInvisibleOnActivity && time(nullptr) - datetime < 60 * m_vkOptions.iInvisibleInterval) SetInvisible(hContact); + bool bEdited = CheckMid(m_editedIds, mid); + if (bEdited) { + CMStringW wszOldMsg; + MEVENT hDbEvent = GetMessageFromDb(hContact, szMid, datetime, wszOldMsg); + if (hDbEvent) { + wszBody = SetBBCString(TranslateT("Edited message:\n"), m_vkOptions.BBCForAttachments(), vkbbcB) + + wszBody + + SetBBCString(TranslateT("\nOriginal message:\n"), m_vkOptions.BBCForAttachments(), vkbbcB) + + wszOldMsg; + db_event_delete(hContact, hDbEvent); + } + } + T2Utf pszBody(wszBody); - recv.timestamp = m_vkOptions.bUseLocalTime ? time(nullptr) : datetime; + recv.timestamp = bEdited ? datetime : (m_vkOptions.bUseLocalTime ? time(nullptr) : datetime); recv.szMessage = pszBody; recv.lParam = isOut; recv.pCustomData = szMid; diff --git a/protocols/VKontakte/src/vk_pollserver.cpp b/protocols/VKontakte/src/vk_pollserver.cpp index 56a9d85715..af49875118 100644 --- a/protocols/VKontakte/src/vk_pollserver.cpp +++ b/protocols/VKontakte/src/vk_pollserver.cpp @@ -78,6 +78,7 @@ void CVkProto::PollUpdates(const JSONNode &jnUpdates) debugLogA("CVkProto::PollUpdates"); CMStringA mids; int msgid, uid, flags, platform; + bool bNonEdited = true; MCONTACT hContact; for (auto it = jnUpdates.begin(); it != jnUpdates.end(); ++it) { @@ -106,17 +107,25 @@ void CVkProto::PollUpdates(const JSONNode &jnUpdates) } break; + case VKPOLL_MSG_EDITED: + bNonEdited = false; + case VKPOLL_MSG_ADDED: // new message msgid = jnChild[1].as_int(); // skip outgoing messages sent from a client flags = jnChild[2].as_int(); - if (flags & VKFLAG_MSGOUTBOX && !(flags & VKFLAG_MSGCHAT) && !m_vkOptions.bSendVKLinksAsAttachments && CheckMid(m_sendIds, msgid)) + if (bNonEdited && (flags & VKFLAG_MSGOUTBOX && !(flags & VKFLAG_MSGCHAT) && !m_vkOptions.bSendVKLinksAsAttachments && CheckMid(m_sendIds, msgid))) break; if (!mids.IsEmpty()) mids.AppendChar(','); mids.AppendFormat("%d", msgid); + + if(!bNonEdited) + m_editedIds.insert((HANDLE)msgid); + + bNonEdited = true; break; case VKPOLL_READ_ALL_OUT: diff --git a/protocols/VKontakte/src/vk_proto.cpp b/protocols/VKontakte/src/vk_proto.cpp index 85b403de7a..1c60842c5a 100644 --- a/protocols/VKontakte/src/vk_proto.cpp +++ b/protocols/VKontakte/src/vk_proto.cpp @@ -36,6 +36,7 @@ CVkProto::CVkProto(const char *szModuleName, const wchar_t *pwszUserName) : PROTO(szModuleName, pwszUserName), m_arRequestsQueue(10, sttCompareAsyncHttpRequest), m_sendIds(3, PtrKeySortT), + m_editedIds(1, PtrKeySortT), m_incIds(3, PtrKeySortT), m_cookies(5), m_msgId(1), diff --git a/protocols/VKontakte/src/vk_proto.h b/protocols/VKontakte/src/vk_proto.h index d1e00cdb6e..90f5f1ece3 100644 --- a/protocols/VKontakte/src/vk_proto.h +++ b/protocols/VKontakte/src/vk_proto.h @@ -212,6 +212,7 @@ private: LIST m_sendIds, + m_editedIds, m_incIds; OBJLIST m_chats; @@ -358,6 +359,7 @@ private: void SetInvisible(MCONTACT hContact); CMStringW RemoveBBC(CMStringW& wszSrc); void AddVkDeactivateEvent(MCONTACT hContact, CMStringW & wszType); + MEVENT GetMessageFromDb(MCONTACT hContact, const char * messageId, UINT ×tamp, CMStringW &msg); int DeleteContact(MCONTACT hContact); void InitQueue(); void UninitQueue(); -- cgit v1.2.3