diff options
Diffstat (limited to 'protocols/Discord/src/server.cpp')
-rw-r--r-- | protocols/Discord/src/server.cpp | 91 |
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); } - -///////////////////////////////////////////////////////////////////////////////////////// |