summaryrefslogtreecommitdiff
path: root/protocols/Discord/src/server.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Discord/src/server.cpp')
-rw-r--r--protocols/Discord/src/server.cpp91
1 files changed, 85 insertions, 6 deletions
diff --git a/protocols/Discord/src/server.cpp b/protocols/Discord/src/server.cpp
index a5ac8e215a..858be58c55 100644
--- a/protocols/Discord/src/server.cpp
+++ b/protocols/Discord/src/server.cpp
@@ -31,9 +31,9 @@ void CDiscordProto::RetrieveHistory(MCONTACT hContact, CDiscordHitoryOp iOp, Sno
pReq << INT_PARAM("limit", iLimit);
switch (iOp) {
case MSG_AFTER:
- pReq << CHAR_PARAM("after", CMStringA(FORMAT, "%lld", msgid)); break;
+ pReq << INT64_PARAM("after", msgid); break;
case MSG_BEFORE:
- pReq << CHAR_PARAM("before", CMStringA(FORMAT, "%lld", msgid)); break;
+ pReq << INT64_PARAM("before", msgid); break;
}
pReq->pUserInfo = pUser;
Push(pReq);
@@ -110,17 +110,46 @@ void CDiscordProto::OnReceiveUserInfo(NETLIBHTTPREQUEST *pReply, AsyncHttpReques
return;
}
+ ptrW wszOldAvatar(getWStringA(hContact, DB_KEY_AVHASH));
+
m_ownId = _wtoi64(root["id"].as_mstring());
setId(hContact, DB_KEY_ID, m_ownId);
setByte(hContact, DB_KEY_MFA, root["mfa_enabled"].as_bool());
setDword(hContact, DB_KEY_DISCR, root["discriminator"].as_int());
setWString(hContact, DB_KEY_NICK, root["username"].as_mstring());
- setWString(hContact, DB_KEY_AVHASH, root["avatar"].as_mstring());
setWString(hContact, DB_KEY_EMAIL, root["email"].as_mstring());
- if (hContact == NULL)
+ CMStringW wszNewAvatar(root["avatar"].as_mstring());
+ setWString(hContact, DB_KEY_AVHASH, wszNewAvatar);
+
+ if (hContact == NULL) {
+ // if avatar's hash changed, we need to request a new one
+ if (mir_wstrcmp(wszNewAvatar, wszOldAvatar))
+ RetrieveAvatar(NULL);
+
OnLoggedIn();
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// finds a gateway address
+
+void CDiscordProto::OnReceiveGateway(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
+{
+ if (pReply->resultCode != 200) {
+ ShutdownSession();
+ return;
+ }
+
+ JSONNode root = JSONNode::parse(pReply->pData);
+ if (!root) {
+ ShutdownSession();
+ return;
+ }
+
+ m_szGateway = root["url"].as_mstring();
+ ForkThread(&CDiscordProto::GatewayThread, NULL);
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -132,6 +161,17 @@ void CDiscordProto::SetServerStatus(int iStatus)
if (iStatus == ID_STATUS_OFFLINE)
Push(new AsyncHttpRequest(this, REQUEST_POST, "/auth/logout", NULL));
+ else {
+ const char *pszStatus;
+ switch (iStatus) {
+ case ID_STATUS_NA: pszStatus = "idle"; break;
+ case ID_STATUS_DND: pszStatus = "dnd"; break;
+ case ID_STATUS_INVISIBLE: pszStatus = "invisible"; break;
+ default: pszStatus = "online"; break;
+ }
+ JSONNode root; root << CHAR_PARAM("status", pszStatus);
+ Push(new AsyncHttpRequest(this, REQUEST_PATCH, "/users/@me/settings", NULL, &root));
+ }
int iOldStatus = m_iStatus; m_iStatus = iStatus;
ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)iOldStatus, m_iStatus);
@@ -201,6 +241,47 @@ void CDiscordProto::OnReceiveGuilds(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*
/////////////////////////////////////////////////////////////////////////////////////////
+void CDiscordProto::OnReceiveMessage(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+{
+ MCONTACT hContact = (MCONTACT)pReq->pUserInfo;
+
+ bool bSucceeded = true;
+ if (pReply->resultCode != 200 && pReply->resultCode != 204)
+ bSucceeded = false;
+
+ JSONNode root = JSONNode::parse(pReply->pData);
+ if (root) {
+ SnowFlake newLastId = _wtoi64(root["id"].as_mstring());
+ SnowFlake oldLastId = getId(hContact, DB_KEY_LASTMSGID); // as stored in a database
+ if (oldLastId < newLastId)
+ setId(hContact, DB_KEY_LASTMSGID, newLastId);
+ }
+
+ ProtoBroadcastAck(hContact, ACKTYPE_MESSAGE, bSucceeded ? ACKRESULT_SUCCESS : ACKRESULT_FAILED, (HANDLE)pReq->m_iReqNum, 0);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CDiscordProto::OnReceiveMessageAck(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
+{
+ if (pReply->resultCode != 200)
+ return;
+
+ JSONNode root = JSONNode::parse(pReply->pData);
+ if (!root)
+ return;
+
+ CMStringW wszToken(root["token"].as_mstring());
+ if (!wszToken.IsEmpty()) {
+ JSONNode props; props.set_name("properties");
+ JSONNode reply; reply << props;
+ reply << CHAR_PARAM("event", "ack_messages") << WCHAR_PARAM("token", root["token"].as_mstring());
+ Push(new AsyncHttpRequest(this, REQUEST_POST, "/track", NULL, &reply));
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
void CDiscordProto::OnReceiveToken(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
{
if (pReply->resultCode != 200) {
@@ -224,5 +305,3 @@ LBL_Error:
RetrieveUserInfo(NULL);
}
-
-/////////////////////////////////////////////////////////////////////////////////////////