diff options
author | George Hazan <ghazan@miranda.im> | 2020-02-13 12:49:50 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2020-02-13 12:49:56 +0300 |
commit | 7ce0cbd1578ef39496f1eacb5d04186695b1e2a6 (patch) | |
tree | f719e0d8d4f049cbcca10c2bd03b6a08d9d19fb3 | |
parent | 653ab55904ef5e7c17eb3efa459136578d3a6859 (diff) |
fixes #2209 (Discord: missing API for guilds and chats)
-rw-r--r-- | protocols/Discord/src/dispatch.cpp | 4 | ||||
-rw-r--r-- | protocols/Discord/src/guilds.cpp | 152 | ||||
-rw-r--r-- | protocols/Discord/src/proto.h | 4 |
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*); |