diff options
author | George Hazan <ghazan@miranda.im> | 2017-02-22 13:29:14 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2017-02-22 13:29:14 +0300 |
commit | e940fb548345fb5e926a0d87f8024257c692726d (patch) | |
tree | 4c28cece4d305f9ca34ae56f6edf96b0e57c5e1b | |
parent | 87b6b08235a1999ed3734c78af11f4b325b07663 (diff) |
Discord: a rusty crutch to receive updates for sent messages
-rw-r--r-- | protocols/Discord/src/dispatch.cpp | 48 | ||||
-rw-r--r-- | protocols/Discord/src/proto.cpp | 4 | ||||
-rw-r--r-- | protocols/Discord/src/proto.h | 19 | ||||
-rw-r--r-- | protocols/Discord/src/server.cpp | 62 | ||||
-rw-r--r-- | protocols/Discord/src/version.h | 2 |
5 files changed, 49 insertions, 86 deletions
diff --git a/protocols/Discord/src/dispatch.cpp b/protocols/Discord/src/dispatch.cpp index e43b70d0fc..46af932fbf 100644 --- a/protocols/Discord/src/dispatch.cpp +++ b/protocols/Discord/src/dispatch.cpp @@ -79,7 +79,7 @@ void CDiscordProto::OnCommandChannelCreated(const JSONNode &pRoot) const JSONNode &members = pRoot["recipients"]; for (auto it = members.begin(); it != members.end(); ++it) { CDiscordUser *pUser = PrepareUser(*it); - pUser->lastMessageId = ::getId(pRoot["last_message_id"]); + pUser->lastMsg = CDiscordMessage(::getId(pRoot["last_message_id"])); pUser->channelId = ::getId(pRoot["id"]); setId(pUser->hContact, DB_KEY_CHANNELID, pUser->channelId); } @@ -89,7 +89,8 @@ void CDiscordProto::OnCommandChannelDeleted(const JSONNode &pRoot) { CDiscordUser *pUser = FindUserByChannel(::getId(pRoot["id"])); if (pUser != NULL) { - pUser->channelId = pUser->lastMessageId = 0; + pUser->channelId = 0; + pUser->lastMsg = CDiscordMessage(); delSetting(pUser->hContact, DB_KEY_CHANNELID); } } @@ -100,7 +101,7 @@ void CDiscordProto::OnCommandChannelUpdated(const JSONNode &pRoot) if (pUser == NULL) return; - pUser->lastMessageId = ::getId(pRoot["last_message_id"]); + pUser->lastMsg = CDiscordMessage(::getId(pRoot["last_message_id"])); CMStringW wszTopic = pRoot["topic"].as_mstring(); if (!wszTopic.IsEmpty()) { @@ -235,14 +236,14 @@ void CDiscordProto::ProcessGuild(const JSONNode &readState, const JSONNode &p) } pUser->wszUsername = wszChannelId; pUser->guildId = guildId; - pUser->lastMessageId = ::getId(pch["last_message_id"]); + pUser->lastMsg = CDiscordMessage(::getId(pch["last_message_id"])); pUser->lastReadId = sttGetLastRead(readState, wszChannelId); setId(pUser->hContact, DB_KEY_ID, channelId); setId(pUser->hContact, DB_KEY_CHANNELID, channelId); SnowFlake oldMsgId = getId(pUser->hContact, DB_KEY_LASTMSGID); - if (oldMsgId != 0 && pUser->lastMessageId > oldMsgId) + if (oldMsgId != 0 && pUser->lastMsg.id > oldMsgId) RetrieveHistory(pUser->hContact, MSG_AFTER, oldMsgId, 99); } } @@ -419,29 +420,32 @@ void CDiscordProto::OnCommandRoleDeleted(const JSONNode &pRoot) void CDiscordProto::OnCommandMessage(const JSONNode &pRoot) { - PROTORECVEVENT recv = {}; CMStringW wszMessageId = pRoot["id"].as_mstring(); - SnowFlake messageId = _wtoi64(wszMessageId); - SnowFlake nonce = ::getId(pRoot["nonce"]); + CMStringW wszUserId = pRoot["author"]["id"].as_mstring(); + CDiscordMessage msg(_wtoi64(wszMessageId), _wtoi64(wszUserId)); + SnowFlake nonce = ::getId(pRoot["nonce"]); SnowFlake *p = arOwnMessages.find(&nonce); if (p != NULL) { // own message? skip it - debugLogA("skipping own message with nonce=%lld, id=%lld", nonce, messageId); + debugLogA("skipping own message with nonce=%lld, id=%lld", nonce, msg.id); return; } // try to find a sender by his channel - CMStringW wszChannelId = pRoot["channel_id"].as_mstring(); - SnowFlake channelId = _wtoi64(wszChannelId); + SnowFlake channelId = ::getId(pRoot["channel_id"]); CDiscordUser *pUser = FindUserByChannel(channelId); if (pUser == NULL) { debugLogA("skipping message with unknown channel id=%lld", channelId); return; } + // restore partially received updated message + if (pUser->lastMsg.id == msg.id) + msg = pUser->lastMsg; + // if a message has myself as an author, add some flags - CMStringW wszUserId = pRoot["author"]["id"].as_mstring(); - if (_wtoi64(wszUserId) == m_ownId) + PROTORECVEVENT recv = {}; + if (msg.authorId == m_ownId) recv.flags = PREF_CREATEREAD | PREF_SENT; CMStringW wszText = PrepareMessageText(pRoot); @@ -461,7 +465,7 @@ void CDiscordProto::OnCommandMessage(const JSONNode &pRoot) else { debugLogA("store a message into the group channel id %lld", channelId); - SESSION_INFO *si = pci->SM_FindSession(wszChannelId, m_szModuleName); + SESSION_INFO *si = pci->SM_FindSession(pUser->wszUsername, m_szModuleName); if (si == NULL) { debugLogA("nessage to unknown channal %lld ignored", channelId); return; @@ -469,19 +473,21 @@ void CDiscordProto::OnCommandMessage(const JSONNode &pRoot) ParseSpecialChars(si, wszText); - GCDEST gcd = { m_szModuleName, wszChannelId, GC_EVENT_MESSAGE }; + GCDEST gcd = { m_szModuleName, pUser->wszUsername, GC_EVENT_MESSAGE }; GCEVENT gce = { &gcd }; gce.dwFlags = GCEF_ADDTOLOG; gce.ptszUID = wszUserId; gce.ptszText = wszText; gce.time = (DWORD)StringToDate(pRoot["timestamp"].as_mstring()); - gce.bIsMe = _wtoi64(wszUserId) == m_ownId; + gce.bIsMe = msg.authorId == m_ownId; Chat_Event(&gce); } + pUser->lastMsg = msg; + SnowFlake lastId = getId(pUser->hContact, DB_KEY_LASTMSGID); // as stored in a database - if (lastId < messageId) - setId(pUser->hContact, DB_KEY_LASTMSGID, messageId); + if (lastId < msg.id) + setId(pUser->hContact, DB_KEY_LASTMSGID, msg.id); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -491,7 +497,7 @@ void CDiscordProto::OnCommandMessageAck(const JSONNode &pRoot) { CDiscordUser *pUser = FindUserByChannel(pRoot["channel_id"]); if (pUser != NULL) - pUser->lastMessageId = ::getId(pRoot["message_id"]); + pUser->lastMsg = CDiscordMessage(::getId(pRoot["message_id"])); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -568,14 +574,14 @@ void CDiscordProto::OnCommandReady(const JSONNode &pRoot) CMStringW wszChannelId = p["id"].as_mstring(); pUser->channelId = _wtoi64(wszChannelId); - pUser->lastMessageId = ::getId(p["last_message_id"]); + pUser->lastMsg = CDiscordMessage(::getId(p["last_message_id"])); pUser->lastReadId = sttGetLastRead(readState, wszChannelId); pUser->bIsPrivate = true; setId(pUser->hContact, DB_KEY_CHANNELID, pUser->channelId); SnowFlake oldMsgId = getId(pUser->hContact, DB_KEY_LASTMSGID); - if (pUser->lastMessageId > oldMsgId) + if (pUser->lastMsg.id > oldMsgId) RetrieveHistory(pUser->hContact, MSG_AFTER, oldMsgId, 99); } } diff --git a/protocols/Discord/src/proto.cpp b/protocols/Discord/src/proto.cpp index d4ac7c11da..80331edbda 100644 --- a/protocols/Discord/src/proto.cpp +++ b/protocols/Discord/src/proto.cpp @@ -72,7 +72,7 @@ CDiscordProto::CDiscordProto(const char *proto_name, const wchar_t *username) : CDiscordUser *pNew = new CDiscordUser(getId(hContact, DB_KEY_ID)); pNew->hContact = hContact; pNew->channelId = getId(hContact, DB_KEY_CHANNELID); - pNew->lastMessageId = getId(hContact, DB_KEY_LASTMSGID); + pNew->lastMsg.id = getId(hContact, DB_KEY_LASTMSGID); pNew->wszUsername = ptrW(getWStringA(hContact, DB_KEY_NICK)); pNew->iDiscriminator = getDword(hContact, DB_KEY_DISCR); arUsers.insert(pNew); @@ -413,7 +413,7 @@ void CDiscordProto::MarkReadTimerProc(HWND hwnd, UINT, UINT_PTR id, DWORD) mir_cslock lck(ppro->csMarkReadQueue); while (ppro->arMarkReadQueue.getCount()) { CDiscordUser *pUser = ppro->arMarkReadQueue[0]; - CMStringA szUrl(FORMAT, "/channels/%lld/messages/%lld/ack", pUser->channelId, pUser->lastMessageId); + CMStringA szUrl(FORMAT, "/channels/%lld/messages/%lld/ack", pUser->channelId, pUser->lastMsg.id); ppro->Push(new AsyncHttpRequest(ppro, REQUEST_POST, szUrl, nullptr)); ppro->arMarkReadQueue.remove(0); } diff --git a/protocols/Discord/src/proto.h b/protocols/Discord/src/proto.h index fbe1b9d2b3..9ab553e5a4 100644 --- a/protocols/Discord/src/proto.h +++ b/protocols/Discord/src/proto.h @@ -92,6 +92,18 @@ struct CDiscordRole : public MZeroedObject ///////////////////////////////////////////////////////////////////////////////////////// +struct CDiscordMessage +{ + SnowFlake id, authorId; + + CDiscordMessage(SnowFlake _id = 0, SnowFlake _authorId = 0) : + id(_id), + authorId(_authorId) + {} +}; + +///////////////////////////////////////////////////////////////////////////////////////// + enum CDiscordHistoryOp { MSG_NOFILTER, MSG_AFTER, MSG_BEFORE @@ -108,9 +120,11 @@ struct CDiscordUser : public MZeroedObject SnowFlake guildId; SnowFlake channelId; - SnowFlake lastMessageId, lastReadId; + SnowFlake lastReadId; bool bIsPrivate; + CDiscordMessage lastMsg; + CMStringW wszUsername; int iDiscriminator; }; @@ -303,11 +317,8 @@ public: void OnReceiveCreateChannel(NETLIBHTTPREQUEST*, AsyncHttpRequest*); void OnReceiveAuth(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - void OnReceiveChannels(NETLIBHTTPREQUEST*, AsyncHttpRequest*); void OnReceiveFile(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - void OnReceiveFriends(NETLIBHTTPREQUEST*, AsyncHttpRequest*); void OnReceiveGateway(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - void OnReceiveGuilds(NETLIBHTTPREQUEST*, AsyncHttpRequest*); void OnReceiveMessage(NETLIBHTTPREQUEST*, AsyncHttpRequest*); void OnReceiveMessageAck(NETLIBHTTPREQUEST*, AsyncHttpRequest*); void OnReceiveToken(NETLIBHTTPREQUEST*, AsyncHttpRequest*); diff --git a/protocols/Discord/src/server.cpp b/protocols/Discord/src/server.cpp index 1765d2b610..169827044c 100644 --- a/protocols/Discord/src/server.cpp +++ b/protocols/Discord/src/server.cpp @@ -134,7 +134,7 @@ void CDiscordProto::OnReceiveHistory(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest setId(pUser->hContact, DB_KEY_LASTMSGID, lastId); // if we fetched 99 messages, but have smth more to go, continue fetching - if (iNumMessages == 99 && lastId < pUser->lastMessageId) + if (iNumMessages == 99 && lastId < pUser->lastMsg.id) RetrieveHistory(pUser->hContact, MSG_AFTER, lastId, 99); } @@ -263,59 +263,6 @@ void CDiscordProto::OnReceiveCreateChannel(NETLIBHTTPREQUEST *pReply, AsyncHttpR OnCommandChannelCreated(root); } -void CDiscordProto::OnReceiveChannels(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*) -{ - if (pReply->resultCode != 200) - return; - - JSONNode root = JSONNode::parse(pReply->pData); - if (!root) - return; - - for (auto it = root.begin(); it != root.end(); ++it) { - const JSONNode &p = *it; - - const JSONNode &user = p["recipient"]; - if (!user) - continue; - - CDiscordUser *pUser = PrepareUser(user); - pUser->lastMessageId = ::getId(p["last_message_id"]); - pUser->channelId = ::getId(p["id"]); - pUser->bIsPrivate = p["is_private"].as_bool(); - - setId(pUser->hContact, DB_KEY_CHANNELID, pUser->channelId); - } -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void CDiscordProto::OnReceiveFriends(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*) -{ - if (pReply->resultCode != 200) - return; - - JSONNode root = JSONNode::parse(pReply->pData); - if (!root) - return; - - for (auto it = root.begin(); it != root.end(); ++it) { - JSONNode &p = *it; - - JSONNode &user = p["user"]; - if (user) - PrepareUser(user); - } -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void CDiscordProto::OnReceiveGuilds(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*) -{ - if (pReply->resultCode != 200) - return; -} - ///////////////////////////////////////////////////////////////////////////////////////// void CDiscordProto::OnReceiveMessage(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq) @@ -328,10 +275,9 @@ void CDiscordProto::OnReceiveMessage(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest JSONNode root = JSONNode::parse(pReply->pData); if (root) { - SnowFlake newLastId = ::getId(root["id"]); - SnowFlake oldLastId = getId(hContact, DB_KEY_LASTMSGID); // as stored in a database - if (oldLastId < newLastId) - setId(hContact, DB_KEY_LASTMSGID, newLastId); + CDiscordUser *pUser = FindUserByChannel(::getId(root["channel_id"])); + if (pUser != nullptr) + pUser->lastMsg = CDiscordMessage(::getId(root["id"]), ::getId(root["author"]["id"])); } ProtoBroadcastAck(hContact, ACKTYPE_MESSAGE, bSucceeded ? ACKRESULT_SUCCESS : ACKRESULT_FAILED, (HANDLE)pReq->m_iReqNum, 0); diff --git a/protocols/Discord/src/version.h b/protocols/Discord/src/version.h index 1232d84168..ebddf302fd 100644 --- a/protocols/Discord/src/version.h +++ b/protocols/Discord/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 4 #define __RELEASE_NUM 0 -#define __BUILD_NUM 2 +#define __BUILD_NUM 3 #include <stdver.h> |