summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2020-02-11 11:38:25 +0300
committerGeorge Hazan <ghazan@miranda.im>2020-02-11 11:38:25 +0300
commite461037d7941988ec2d6f83742dd10eb375a1578 (patch)
tree8dab240c6a3068a5ad00b7f458ba80a08f82ed02
parent968c4a1f08396b1734114e589f6abd54abe2c43d (diff)
Discord:
- gateway command 12 isn't available since Jan 13th, 2020; - GUILD_SYNC is also not available anymore; - better cookie control; - version bump
-rw-r--r--protocols/Discord/src/connection.cpp4
-rw-r--r--protocols/Discord/src/dispatch.cpp11
-rw-r--r--protocols/Discord/src/gateway.cpp19
-rw-r--r--protocols/Discord/src/guilds.cpp55
-rw-r--r--protocols/Discord/src/http.cpp2
-rw-r--r--protocols/Discord/src/menus.cpp3
-rw-r--r--protocols/Discord/src/proto.h17
-rw-r--r--protocols/Discord/src/server.cpp15
-rw-r--r--protocols/Discord/src/stdafx.h1
-rw-r--r--protocols/Discord/src/version.h2
10 files changed, 82 insertions, 47 deletions
diff --git a/protocols/Discord/src/connection.cpp b/protocols/Discord/src/connection.cpp
index aa11ff9af2..8c491d5a65 100644
--- a/protocols/Discord/src/connection.cpp
+++ b/protocols/Discord/src/connection.cpp
@@ -36,8 +36,7 @@ void CDiscordProto::ExecuteRequest(AsyncHttpRequest *pReq)
if (pReq->m_bMainSite) {
pReq->flags |= NLHRF_PERSISTENT;
pReq->nlc = m_hAPIConnection;
- if (m_szAccessCookie)
- pReq->AddHeader("Cookie", m_szAccessCookie);
+ pReq->AddHeader("Cookie", m_szCookie);
}
debugLogA("Executing request #%d:\n%s", pReq->m_iReqNum, pReq->szUrl);
@@ -79,6 +78,7 @@ void CDiscordProto::OnLoggedOut()
m_bOnline = false;
m_bTerminated = true;
m_iGatewaySeq = 0;
+ m_szCookie.Empty();
m_impl.m_heartBeat.StopSafe();
diff --git a/protocols/Discord/src/dispatch.cpp b/protocols/Discord/src/dispatch.cpp
index 2841b481a4..a7276722c0 100644
--- a/protocols/Discord/src/dispatch.cpp
+++ b/protocols/Discord/src/dispatch.cpp
@@ -44,8 +44,7 @@ static handlers[] = // these structures must me sorted alphabetically
{ L"GUILD_ROLE_CREATE", &CDiscordProto::OnCommandRoleCreated },
{ L"GUILD_ROLE_DELETE", &CDiscordProto::OnCommandRoleDeleted },
{ L"GUILD_ROLE_UPDATE", &CDiscordProto::OnCommandRoleCreated },
- { L"GUILD_SYNC", &CDiscordProto::OnCommandGuildSync },
-
+
{ L"MESSAGE_ACK", &CDiscordProto::OnCommandMessageAck },
{ L"MESSAGE_CREATE", &CDiscordProto::OnCommandMessageCreate },
{ L"MESSAGE_DELETE", &CDiscordProto::OnCommandMessageDelete },
@@ -240,13 +239,7 @@ void CDiscordProto::OnCommandFriendRemoved(const JSONNode &pRoot)
void CDiscordProto::OnCommandGuildCreated(const JSONNode &pRoot)
{
- ProcessGuild(pRoot);
- OnCommandGuildSync(pRoot);
-}
-
-void CDiscordProto::OnCommandGuildSync(const JSONNode &pRoot)
-{
- CDiscordGuild *pGuild = FindGuild(::getId(pRoot["id"]));
+ auto *pGuild = ProcessGuild(pRoot);
if (pGuild != nullptr)
ParseGuildContents(pGuild, pRoot);
}
diff --git a/protocols/Discord/src/gateway.cpp b/protocols/Discord/src/gateway.cpp
index fe3bf8e800..46b7586539 100644
--- a/protocols/Discord/src/gateway.cpp
+++ b/protocols/Discord/src/gateway.cpp
@@ -26,6 +26,7 @@ void CDiscordProto::GatewaySend(const JSONNode &pRoot)
return;
json_string szText = pRoot.write();
+ debugLogA("Gateway send: %s", szText.c_str());
WebSocket_Send(m_hGatewayConnection, szText.c_str(), szText.length());
}
@@ -55,14 +56,6 @@ bool CDiscordProto::GatewayThreadWorker()
debugLogA("Gateway connection succeeded");
m_hGatewayConnection = pReply->nlc;
-
- if (auto *pszHdr = Netlib_GetHeader(pReply, "Set-Cookie")) {
- m_szCookie = pszHdr;
-
- int idx = m_szCookie.Find(';');
- if (idx != -1)
- m_szCookie.Truncate(idx);
- }
Netlib_FreeHttpRequest(pReply);
bool bExit = false;
@@ -256,16 +249,6 @@ void CDiscordProto::GatewaySendIdentify()
GatewaySend(root);
}
-void CDiscordProto::GatewaySendGuildInfo(SnowFlake id)
-{
- JSONNode payload(JSON_ARRAY); payload.set_name("d");
- payload << SINT64_PARAM("", id);
-
- JSONNode root;
- root << INT_PARAM("op", 12) << payload;
- GatewaySend(root);
-}
-
void CDiscordProto::GatewaySendResume()
{
char szRandom[40];
diff --git a/protocols/Discord/src/guilds.cpp b/protocols/Discord/src/guilds.cpp
index c19237c7e4..d517e9af0e 100644
--- a/protocols/Discord/src/guilds.cpp
+++ b/protocols/Discord/src/guilds.cpp
@@ -120,7 +120,7 @@ void CDiscordProto::CreateChat(CDiscordGuild *pGuild, CDiscordUser *pUser)
}
}
-void CDiscordProto::ProcessGuild(const JSONNode &p)
+CDiscordGuild* CDiscordProto::ProcessGuild(const JSONNode &p)
{
SnowFlake guildId = ::getId(p["id"]);
@@ -141,7 +141,7 @@ void CDiscordProto::ProcessGuild(const JSONNode &p)
setId(pGuild->hContact, DB_KEY_CHANNELID, guildId);
if (!pGuild->bSynced && getByte(si->hContact, "EnableSync"))
- GatewaySendGuildInfo(guildId);
+ LoadGuildInfo(pGuild);
Chat_Control(m_szModuleName, pGuild->wszName, WINDOW_HIDDEN);
Chat_Control(m_szModuleName, pGuild->wszName, SESSION_ONLINE);
@@ -159,6 +159,8 @@ void CDiscordProto::ProcessGuild(const JSONNode &p)
if (m_bUseGroupchats)
ForkThread(&CDiscordProto::BatchChatCreate, pGuild);
+
+ return pGuild;
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -255,6 +257,55 @@ void CDiscordProto::AddGuildUser(CDiscordGuild *pGuild, const CDiscordGuildMembe
/////////////////////////////////////////////////////////////////////////////////////////
+static CMStringW GetCacheFileName(SnowFlake guildId)
+{
+ VARSW wszCacheDir(L"%miranda_userdata%\\Discord");
+ CreateDirectoryTreeW(wszCacheDir);
+
+ return CMStringW(FORMAT, L"%s\\%lld.cache", wszCacheDir.get(), guildId);
+}
+
+void CDiscordProto::LoadGuildInfo(CDiscordGuild *pGuild)
+{
+ CMStringW wszCacheFile(GetCacheFileName(pGuild->id));
+ int fileId = _wopen(wszCacheFile, _O_BINARY | _O_RDONLY);
+ if (fileId != -1) {
+ size_t length = _filelength(fileId);
+ ptrA buf((char *)mir_alloc(length+1));
+ _read(fileId, buf, (unsigned)length);
+ _close(fileId);
+
+ JSONNode root(JSONNode::parse(buf));
+ for (auto &cc : root) {
+ auto *pUser = new CDiscordGuildMember(_wtoi64(cc["id"].as_mstring()));
+ pUser->wszNick = cc["nick"].as_mstring();
+ pUser->wszRole = cc["role"].as_mstring();
+ pGuild->arChatUsers.insert(pUser);
+
+ AddGuildUser(pGuild, *pUser);
+ }
+ }
+ else {
+ CMStringA szUrl(FORMAT, "/guilds/%lld/members", pGuild->id);
+ auto *pReq = new AsyncHttpRequest(this, REQUEST_GET, szUrl, &CDiscordProto::OnReceiveGuildInfo);
+ pReq << INT_PARAM("limit", 1000);
+ pReq->pUserInfo = pGuild;
+ // Push(pReq);
+ }
+}
+
+void CDiscordProto::OnReceiveGuildInfo(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
+{
+ if (pReply->resultCode != 200)
+ return;
+
+ JSONNode root = JSONNode::parse(pReply->pData);
+ if (root)
+ ParseGuildContents((CDiscordGuild*)pReq->pUserInfo, root);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
void CDiscordProto::ParseGuildContents(CDiscordGuild *pGuild, const JSONNode &pRoot)
{
LIST<CDiscordGuildMember> newMembers(100);
diff --git a/protocols/Discord/src/http.cpp b/protocols/Discord/src/http.cpp
index 215df90e92..7dda5ae565 100644
--- a/protocols/Discord/src/http.cpp
+++ b/protocols/Discord/src/http.cpp
@@ -56,8 +56,6 @@ AsyncHttpRequest::AsyncHttpRequest(CDiscordProto *ppro, int iRequestType, LPCSTR
dataLength = (int)mir_strlen(pData);
}
- if (!ppro->m_szCookie.IsEmpty())
- AddHeader("Cookie", ppro->m_szCookie);
AddHeader("Content-Type", "application/json");
m_pFunc = pFunc;
diff --git a/protocols/Discord/src/menus.cpp b/protocols/Discord/src/menus.cpp
index a4734e8d57..311e002717 100644
--- a/protocols/Discord/src/menus.cpp
+++ b/protocols/Discord/src/menus.cpp
@@ -94,7 +94,8 @@ INT_PTR CDiscordProto::OnMenuToggleSync(WPARAM hContact, LPARAM)
setByte(hContact, "EnableSync", bEnabled);
if (bEnabled)
- GatewaySendGuildInfo(getId(hContact, DB_KEY_CHANNELID));
+ if (auto *pGuild = FindGuild(getId(hContact, DB_KEY_CHANNELID)))
+ LoadGuildInfo(pGuild);
return 0;
}
diff --git a/protocols/Discord/src/proto.h b/protocols/Discord/src/proto.h
index b4022284eb..42a7e4dc77 100644
--- a/protocols/Discord/src/proto.h
+++ b/protocols/Discord/src/proto.h
@@ -171,7 +171,7 @@ class CDiscordProto : public PROTO<CDiscordProto>
wchar_t *m_wszStatusMsg[MAX_STATUS_COUNT];
- ptrA m_szAccessToken, m_szAccessCookie;
+ ptrA m_szAccessToken;
mir_cs m_csHttpQueue;
HANDLE m_evRequestsQueue;
@@ -193,7 +193,7 @@ class CDiscordProto : public PROTO<CDiscordProto>
CMStringA
m_szGateway, // gateway url
m_szGatewaySessionId, // current session id
- m_szCookie; // a cookie to be passed into all http queries
+ m_szCookie; // cookie used for all http queries
HNETLIBUSER m_hGatewayNetlibUser; // the separate netlib user handle for gateways
HNETLIBCONN m_hGatewayConnection; // gateway connection
@@ -206,7 +206,6 @@ class CDiscordProto : public PROTO<CDiscordProto>
void GatewaySendHeartbeat(void);
void GatewaySendIdentify(void);
- void GatewaySendGuildInfo(SnowFlake id);
void GatewaySendResume(void);
GatewayHandlerFunc GetHandler(const wchar_t*);
@@ -268,12 +267,14 @@ class CDiscordProto : public PROTO<CDiscordProto>
return arGuilds.find((CDiscordGuild*)&id);
}
- void ProcessGuild(const JSONNode&);
void AddGuildUser(CDiscordGuild *guild, const CDiscordGuildMember &pUser);
+ void LoadGuildInfo(CDiscordGuild *guild);
void ParseGuildContents(CDiscordGuild *guild, const JSONNode &);
- CDiscordUser* ProcessGuildChannel(CDiscordGuild *guild, const JSONNode&);
- void ProcessRole(CDiscordGuild *guild, const JSONNode&);
- void ProcessType(CDiscordUser *pUser, const JSONNode&);
+
+ CDiscordGuild* ProcessGuild(const JSONNode &json);
+ CDiscordUser* ProcessGuildChannel(CDiscordGuild *guild, const JSONNode &json);
+ void ProcessRole(CDiscordGuild *guild, const JSONNode &json);
+ void ProcessType(CDiscordUser *pUser, const JSONNode &json);
//////////////////////////////////////////////////////////////////////////////////////
// group chats
@@ -365,7 +366,6 @@ public:
void OnCommandGuildMemberAdded(const JSONNode &json);
void OnCommandGuildMemberRemoved(const JSONNode &json);
void OnCommandGuildMemberUpdated(const JSONNode &json);
- void OnCommandGuildSync(const JSONNode &json);
void OnCommandFriendAdded(const JSONNode &json);
void OnCommandFriendRemoved(const JSONNode &json);
void OnCommandMessage(const JSONNode&, bool);
@@ -387,6 +387,7 @@ public:
void OnReceiveCreateChannel(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
void OnReceiveFile(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
void OnReceiveGateway(NETLIBHTTPREQUEST*, AsyncHttpRequest*);
+ void OnReceiveGuildInfo(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 2ce92b2281..3afe70de99 100644
--- a/protocols/Discord/src/server.cpp
+++ b/protocols/Discord/src/server.cpp
@@ -173,10 +173,17 @@ void CDiscordProto::OnReceiveMyInfo(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*
m_wszEmail = root["email"].as_mstring();
m_ownId = id;
- if (auto *pszHdr = Netlib_GetHeader(pReply, "Set-Cookie")) {
- char *p = strchr(pszHdr, ';');
- if (p) *p = 0;
- m_szAccessCookie = mir_strdup(pszHdr);
+
+ m_szCookie.Empty();
+ for (int i=0; i < pReply->headersCount; i++) {
+ if (!mir_strcmpi(pReply->headers[i].szName, "Set-Cookie")) {
+ char *p = strchr(pReply->headers[i].szValue, ';');
+ if (p) *p = 0;
+ if (!m_szCookie.IsEmpty())
+ m_szCookie.Append("; ");
+
+ m_szCookie.Append(pReply->headers[i].szValue);
+ }
}
OnLoggedIn();
diff --git a/protocols/Discord/src/stdafx.h b/protocols/Discord/src/stdafx.h
index 4d9ba98487..c05bfb8167 100644
--- a/protocols/Discord/src/stdafx.h
+++ b/protocols/Discord/src/stdafx.h
@@ -12,6 +12,7 @@
#include <malloc.h>
#include <stdio.h>
#include <io.h>
+#include <fcntl.h>
#include <direct.h>
#include <time.h>
diff --git a/protocols/Discord/src/version.h b/protocols/Discord/src/version.h
index 5d3006af8d..bdc120275b 100644
--- a/protocols/Discord/src/version.h
+++ b/protocols/Discord/src/version.h
@@ -1,7 +1,7 @@
#define __MAJOR_VERSION 0
#define __MINOR_VERSION 6
#define __RELEASE_NUM 2
-#define __BUILD_NUM 2
+#define __BUILD_NUM 3
#include <stdver.h>