summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2020-02-13 12:49:50 +0300
committerGeorge Hazan <ghazan@miranda.im>2020-02-13 12:49:56 +0300
commit7ce0cbd1578ef39496f1eacb5d04186695b1e2a6 (patch)
treef719e0d8d4f049cbcca10c2bd03b6a08d9d19fb3
parent653ab55904ef5e7c17eb3efa459136578d3a6859 (diff)
fixes #2209 (Discord: missing API for guilds and chats)
-rw-r--r--protocols/Discord/src/dispatch.cpp4
-rw-r--r--protocols/Discord/src/guilds.cpp152
-rw-r--r--protocols/Discord/src/proto.h4
3 files changed, 60 insertions, 100 deletions
diff --git a/protocols/Discord/src/dispatch.cpp b/protocols/Discord/src/dispatch.cpp
index a7276722c0..801bdd396c 100644
--- a/protocols/Discord/src/dispatch.cpp
+++ b/protocols/Discord/src/dispatch.cpp
@@ -239,9 +239,7 @@ void CDiscordProto::OnCommandFriendRemoved(const JSONNode &pRoot)
void CDiscordProto::OnCommandGuildCreated(const JSONNode &pRoot)
{
- auto *pGuild = ProcessGuild(pRoot);
- if (pGuild != nullptr)
- ParseGuildContents(pGuild, pRoot);
+ ProcessGuild(pRoot);
}
void CDiscordProto::OnCommandGuildDeleted(const JSONNode &pRoot)
diff --git a/protocols/Discord/src/guilds.cpp b/protocols/Discord/src/guilds.cpp
index d517e9af0e..37eb5a3e5c 100644
--- a/protocols/Discord/src/guilds.cpp
+++ b/protocols/Discord/src/guilds.cpp
@@ -120,9 +120,9 @@ void CDiscordProto::CreateChat(CDiscordGuild *pGuild, CDiscordUser *pUser)
}
}
-CDiscordGuild* CDiscordProto::ProcessGuild(const JSONNode &p)
+void CDiscordProto::ProcessGuild(const JSONNode &pRoot)
{
- SnowFlake guildId = ::getId(p["id"]);
+ SnowFlake guildId = ::getId(pRoot["id"]);
CDiscordGuild *pGuild = FindGuild(guildId);
if (pGuild == nullptr) {
@@ -130,8 +130,8 @@ CDiscordGuild* CDiscordProto::ProcessGuild(const JSONNode &p)
arGuilds.insert(pGuild);
}
- pGuild->ownerId = ::getId(p["owner_id"]);
- pGuild->wszName = p["name"].as_mstring();
+ pGuild->ownerId = ::getId(pRoot["owner_id"]);
+ pGuild->wszName = pRoot["name"].as_mstring();
if (m_bUseGuildGroups)
pGuild->groupId = Clist_GroupCreate(Clist_GroupExists(m_wszDefaultGroup), pGuild->wszName);
@@ -146,21 +146,69 @@ CDiscordGuild* CDiscordProto::ProcessGuild(const JSONNode &p)
Chat_Control(m_szModuleName, pGuild->wszName, WINDOW_HIDDEN);
Chat_Control(m_szModuleName, pGuild->wszName, SESSION_ONLINE);
- for (auto &it : p["roles"])
+ for (auto &it : pRoot["roles"])
ProcessRole(pGuild, it);
BuildStatusList(pGuild, si);
+ // store all guild members
+ for (auto &it : pRoot["members"]) {
+ CMStringW wszUserId = it["user"]["id"].as_mstring();
+ SnowFlake userId = _wtoi64(wszUserId);
+ CDiscordGuildMember *pm = pGuild->FindUser(userId);
+ if (pm == nullptr) {
+ pm = new CDiscordGuildMember(userId);
+ pGuild->arChatUsers.insert(pm);
+ }
+
+ pm->wszNick = it["nick"].as_mstring();
+ if (pm->wszNick.IsEmpty())
+ pm->wszNick = it["user"]["username"].as_mstring() + L"#" + it["user"]["discriminator"].as_mstring();
+
+ if (userId == pGuild->ownerId)
+ pm->wszRole = L"@owner";
+ else {
+ CDiscordRole *pRole = nullptr;
+ for (auto &itr : it["roles"]) {
+ SnowFlake roleId = ::getId(itr);
+ if (pRole = pGuild->arRoles.find((CDiscordRole *)&roleId))
+ break;
+ }
+ pm->wszRole = (pRole == nullptr) ? L"@everyone" : pRole->wszName;
+ }
+ pm->iStatus = ID_STATUS_OFFLINE;
+ }
+
+ // parse online statuses
+ for (auto &it : pRoot["presences"]) {
+ CDiscordGuildMember *gm = pGuild->FindUser(::getId(it["user"]["id"]));
+ if (gm != nullptr)
+ gm->iStatus = StrToStatus(it["status"].as_mstring());
+ }
+
for (auto &it : pGuild->arChatUsers)
AddGuildUser(pGuild, *it);
- for (auto &it : p["channels"])
+ for (auto &it : pRoot["channels"])
ProcessGuildChannel(pGuild, it);
if (m_bUseGroupchats)
ForkThread(&CDiscordProto::BatchChatCreate, pGuild);
- return pGuild;
+ // retrieve missing histories
+ for (auto &it : pGuild->arChannels) {
+ if (it->bIsPrivate)
+ continue;
+
+ if (!it->bSynced) {
+ it->bSynced = true;
+ SnowFlake oldMsgId = getId(it->hContact, DB_KEY_LASTMSGID);
+ if (oldMsgId != 0 && it->lastMsgId > oldMsgId)
+ RetrieveHistory(it, MSG_AFTER, oldMsgId, 99);
+ }
+ }
+
+ pGuild->bSynced = true;
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -249,10 +297,10 @@ void CDiscordProto::AddGuildUser(CDiscordGuild *pGuild, const CDiscordGuildMembe
wchar_t wszUserId[100];
_i64tow_s(pUser.userId, wszUserId, _countof(wszUserId), 10);
- auto *p = g_chatApi.UM_AddUser(pGuild->pParentSi, wszUserId, pUser.wszNick, (pStatus) ? pStatus->iStatus : 0);
- p->iStatusEx = flags;
+ auto *pu = g_chatApi.UM_AddUser(pGuild->pParentSi, wszUserId, pUser.wszNick, (pStatus) ? pStatus->iStatus : 0);
+ pu->iStatusEx = flags;
if (pUser.userId == m_ownId)
- pGuild->pParentSi->pMe = p;
+ pGuild->pParentSi->pMe = pu;
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -285,88 +333,4 @@ void CDiscordProto::LoadGuildInfo(CDiscordGuild *pGuild)
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);
-
- // store all guild members
- for (auto &it : pRoot["members"]) {
- CMStringW wszUserId = it["user"]["id"].as_mstring();
- SnowFlake userId = _wtoi64(wszUserId);
- CDiscordGuildMember *pm = pGuild->FindUser(userId);
- if (pm == nullptr) {
- pm = new CDiscordGuildMember(userId);
- pGuild->arChatUsers.insert(pm);
- newMembers.insert(pm);
- }
-
- pm->wszNick = it["nick"].as_mstring();
- if (pm->wszNick.IsEmpty())
- pm->wszNick = it["user"]["username"].as_mstring() + L"#" + it["user"]["discriminator"].as_mstring();
-
- if (userId == pGuild->ownerId)
- pm->wszRole = L"@owner";
- else {
- CDiscordRole *pRole = nullptr;
- for (auto &itr : it["roles"]) {
- SnowFlake roleId = ::getId(itr);
- if (pRole = pGuild->arRoles.find((CDiscordRole*)&roleId))
- break;
- }
- pm->wszRole = (pRole == nullptr) ? L"@everyone" : pRole->wszName;
- }
- pm->iStatus = ID_STATUS_OFFLINE;
- }
-
- // parse online statuses
- for (auto &it : pRoot["presences"]) {
- CDiscordGuildMember *gm = pGuild->FindUser(::getId(it["user"]["id"]));
- if (gm != nullptr)
- gm->iStatus = StrToStatus(it["status"].as_mstring());
- }
-
- for (auto &pm : newMembers)
- AddGuildUser(pGuild, *pm);
-
- // retrieve missing histories
- for (auto &it : pGuild->arChannels) {
- if (it->bIsPrivate)
- continue;
-
- if (newMembers.getCount()) {
- auto *si = g_chatApi.SM_FindSession(it->wszUsername, m_szModuleName);
- if (si && si->pDlg)
- si->pDlg->UpdateNickList();
- }
-
- if (!it->bSynced) {
- it->bSynced = true;
- SnowFlake oldMsgId = getId(it->hContact, DB_KEY_LASTMSGID);
- if (oldMsgId != 0 && it->lastMsgId > oldMsgId)
- RetrieveHistory(it, MSG_AFTER, oldMsgId, 99);
- }
- }
-
- pGuild->bSynced = true;
}
diff --git a/protocols/Discord/src/proto.h b/protocols/Discord/src/proto.h
index 42a7e4dc77..f165ca40c2 100644
--- a/protocols/Discord/src/proto.h
+++ b/protocols/Discord/src/proto.h
@@ -269,9 +269,8 @@ class CDiscordProto : public PROTO<CDiscordProto>
void AddGuildUser(CDiscordGuild *guild, const CDiscordGuildMember &pUser);
void LoadGuildInfo(CDiscordGuild *guild);
- void ParseGuildContents(CDiscordGuild *guild, const JSONNode &);
- CDiscordGuild* ProcessGuild(const JSONNode &json);
+ void 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);
@@ -387,7 +386,6 @@ 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*);