diff options
-rw-r--r-- | protocols/Discord/src/dispatch.cpp | 31 | ||||
-rw-r--r-- | protocols/Discord/src/proto.cpp | 10 | ||||
-rw-r--r-- | protocols/Discord/src/proto.h | 2 | ||||
-rw-r--r-- | protocols/Discord/src/utils.cpp | 8 | ||||
-rw-r--r-- | protocols/Discord/src/version.h | 2 |
5 files changed, 43 insertions, 10 deletions
diff --git a/protocols/Discord/src/dispatch.cpp b/protocols/Discord/src/dispatch.cpp index 1886e9d106..80239a9b5e 100644 --- a/protocols/Discord/src/dispatch.cpp +++ b/protocols/Discord/src/dispatch.cpp @@ -81,15 +81,30 @@ void CDiscordProto::OnCommandFriendRemoved(const JSONNode &pRoot) void CDiscordProto::OnCommandMessage(const JSONNode &pRoot) { PROTORECVEVENT recv = {}; + CMStringW wszMessageId = pRoot["id"].as_mstring(); + SnowFlake messageId = _wtoi64(wszMessageId); + SnowFlake nonce = _wtoi64(pRoot["nonce"].as_mstring()); + + SnowFlake *p = arOwnMessages.find(&nonce); + if (p != NULL) { // own message? skip it + debugLogA("skipping own message with nonce=%lld, id=%lld", nonce, messageId); + return; + } CDiscordUser *pUser = PrepareUser(pRoot["author"]); SnowFlake channelId = _wtoi64(pRoot["channel_id"].as_mstring()); - CMStringW msgId = pRoot["id"].as_mstring(); - CMStringW wszText = pRoot["content"].as_mstring(); - // if a message has myself as an author, mark it as sent - if (pUser->id == 0) - return; + // if a message has myself as an author, find the author via channel id + if (pUser->id == 0) { + pUser = FindUserByChannel(channelId); + if (pUser == NULL) { + debugLogA("skipping message with unknown channel id=%lld", channelId); + return; + } + recv.flags = PREF_CREATEREAD | PREF_SENT; + } + + CMStringW wszText = pRoot["content"].as_mstring(); const JSONNode &edited = pRoot["edited_timestamp"]; if (!edited.isnull()) @@ -103,12 +118,12 @@ void CDiscordProto::OnCommandMessage(const JSONNode &pRoot) ptrA buf(mir_utf8encodeW(wszText)); recv.timestamp = (DWORD)StringToDate(pRoot["timestamp"].as_mstring()); recv.szMessage = buf; - recv.lParam = (LPARAM)msgId.c_str(); + recv.lParam = (LPARAM)wszMessageId.c_str(); ProtoChainRecvMsg(pUser->hContact, &recv); SnowFlake lastId = getId(pUser->hContact, DB_KEY_LASTMSGID); // as stored in a database - if (lastId < _wtoi64(msgId)) - setId(pUser->hContact, DB_KEY_LASTMSGID, _wtoi64(msgId)); + if (lastId < messageId) + setId(pUser->hContact, DB_KEY_LASTMSGID, messageId); } ////////////////////////////////////////////////////////////////////////////////////// diff --git a/protocols/Discord/src/proto.cpp b/protocols/Discord/src/proto.cpp index 814ca19c0d..f161d27e49 100644 --- a/protocols/Discord/src/proto.cpp +++ b/protocols/Discord/src/proto.cpp @@ -17,6 +17,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include "stdafx.h" +static int compareMessages(const SnowFlake *p1, const SnowFlake *p2) +{ + return *p1 - *p2; +} + static int compareRequests(const AsyncHttpRequest *p1, const AsyncHttpRequest *p2) { return p1->m_iReqNum - p2->m_iReqNum; @@ -34,6 +39,7 @@ CDiscordProto::CDiscordProto(const char *proto_name, const wchar_t *username) : m_wszDefaultGroup(this, DB_KEY_GROUP, DB_KEYVAL_GROUP), m_wszEmail(this, DB_KEY_EMAIL, L""), arMarkReadQueue(1, compareUsers), + arOwnMessages(1, compareMessages), arUsers(50, compareUsers) { // Services @@ -345,7 +351,9 @@ int CDiscordProto::SendMsg(MCONTACT hContact, int /*flags*/, const char *pszSrc) return 0; CMStringA szUrl(FORMAT, "/channels/%lld/messages", pUser->channelId); - JSONNode body; body << WCHAR_PARAM("content", wszText); + SnowFlake nonce; Utils_GetRandom(&nonce, sizeof(nonce)); + JSONNode body; body << WCHAR_PARAM("content", wszText) << INT64_PARAM("nonce", nonce); + arOwnMessages.insert(new SnowFlake(nonce)); AsyncHttpRequest *pReq = new AsyncHttpRequest(this, REQUEST_POST, szUrl, &CDiscordProto::OnReceiveMessage, &body); pReq->pUserInfo = (void*)hContact; Push(pReq); diff --git a/protocols/Discord/src/proto.h b/protocols/Discord/src/proto.h index 33a316c634..fec13c787c 100644 --- a/protocols/Discord/src/proto.h +++ b/protocols/Discord/src/proto.h @@ -74,6 +74,7 @@ struct WCHAR_PARAM : public PARAM AsyncHttpRequest* operator<<(AsyncHttpRequest*, const WCHAR_PARAM&); JSONNode& operator<<(JSONNode &json, const INT_PARAM ¶m); +JSONNode& operator<<(JSONNode &json, const INT64_PARAM ¶m); JSONNode& operator<<(JSONNode &json, const BOOL_PARAM ¶m); JSONNode& operator<<(JSONNode &json, const CHAR_PARAM ¶m); JSONNode& operator<<(JSONNode &json, const WCHAR_PARAM ¶m); @@ -176,6 +177,7 @@ class CDiscordProto : public PROTO<CDiscordProto> LIST<CDiscordUser> arMarkReadQueue; OBJLIST<CDiscordUser> arUsers; + OBJLIST<SnowFlake> arOwnMessages; CDiscordUser* FindUser(SnowFlake id); CDiscordUser* FindUser(const wchar_t *pwszUsername, int iDiscriminator); CDiscordUser* FindUserByChannel(SnowFlake channelId); diff --git a/protocols/Discord/src/utils.cpp b/protocols/Discord/src/utils.cpp index 15246ce46e..e63df2f826 100644 --- a/protocols/Discord/src/utils.cpp +++ b/protocols/Discord/src/utils.cpp @@ -32,6 +32,14 @@ JSONNode& operator<<(JSONNode &json, const INT_PARAM ¶m) return json; } +JSONNode& operator<<(JSONNode &json, const INT64_PARAM ¶m) +{ + char tmp[100]; + _i64toa_s(param.iValue, tmp, _countof(tmp), 10); + json.push_back(JSONNode(param.szName, tmp)); + return json; +} + JSONNode& operator<<(JSONNode &json, const BOOL_PARAM ¶m) { json.push_back(JSONNode(param.szName, param.bValue)); diff --git a/protocols/Discord/src/version.h b/protocols/Discord/src/version.h index 283aed187b..3c4a0e6d7d 100644 --- a/protocols/Discord/src/version.h +++ b/protocols/Discord/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 1 #define __RELEASE_NUM 0 -#define __BUILD_NUM 3 +#define __BUILD_NUM 4 #include <stdver.h> |