summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--protocols/Discord/src/dispatch.cpp31
-rw-r--r--protocols/Discord/src/proto.cpp10
-rw-r--r--protocols/Discord/src/proto.h2
-rw-r--r--protocols/Discord/src/utils.cpp8
-rw-r--r--protocols/Discord/src/version.h2
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 &param);
+JSONNode& operator<<(JSONNode &json, const INT64_PARAM &param);
JSONNode& operator<<(JSONNode &json, const BOOL_PARAM &param);
JSONNode& operator<<(JSONNode &json, const CHAR_PARAM &param);
JSONNode& operator<<(JSONNode &json, const WCHAR_PARAM &param);
@@ -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 &param)
return json;
}
+JSONNode& operator<<(JSONNode &json, const INT64_PARAM &param)
+{
+ 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 &param)
{
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>