diff options
author | George Hazan <ghazan@miranda.im> | 2017-02-13 23:05:38 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2017-02-13 23:05:46 +0300 |
commit | a727a5f4cb61f721cef5a6afa6c2054a06659fea (patch) | |
tree | 3f9bf1677486c0cdbe38ccfba3de72b0f4030d1e /protocols/Discord | |
parent | 653fe9968498470fddda828959c26b886efecbac (diff) |
Discord: displaying roles correctly
Diffstat (limited to 'protocols/Discord')
-rw-r--r-- | protocols/Discord/src/dispatch.cpp | 103 | ||||
-rw-r--r-- | protocols/Discord/src/groupchat.cpp | 15 | ||||
-rw-r--r-- | protocols/Discord/src/proto.cpp | 6 | ||||
-rw-r--r-- | protocols/Discord/src/proto.h | 30 | ||||
-rw-r--r-- | protocols/Discord/src/server.cpp | 2 | ||||
-rw-r--r-- | protocols/Discord/src/stdafx.h | 1 | ||||
-rw-r--r-- | protocols/Discord/src/version.h | 2 |
7 files changed, 139 insertions, 20 deletions
diff --git a/protocols/Discord/src/dispatch.cpp b/protocols/Discord/src/dispatch.cpp index 0da160b973..dbbd4e41e4 100644 --- a/protocols/Discord/src/dispatch.cpp +++ b/protocols/Discord/src/dispatch.cpp @@ -32,10 +32,14 @@ static handlers[] = // these structures must me sorted alphabetically { L"CHANNEL_DELETE", &CDiscordProto::OnCommandChannelDeleted }, { L"CHANNEL_UPDATE", &CDiscordProto::OnCommandChannelUpdated }, - { L"GUILD_CREATE", &CDiscordProto::OnCommandGuildCreate }, - { L"GUILD_DELETE", &CDiscordProto::OnCommandGuildDelete }, - { L"GUILD_MEMBER_REMOVE", &CDiscordProto::OnCommandGuildRemoveMember }, - { L"GUILD_MEMBER_UPDATE", &CDiscordProto::OnCommandGuildUpdateMember }, + { L"GUILD_CREATE", &CDiscordProto::OnCommandGuildCreated }, + { L"GUILD_DELETE", &CDiscordProto::OnCommandGuildDeleted }, + { L"GUILD_MEMBER_ADD", &CDiscordProto::OnCommandGuildMemberAdded }, + { L"GUILD_MEMBER_REMOVE", &CDiscordProto::OnCommandGuildMemberRemoved }, + { L"GUILD_MEMBER_UPDATE", &CDiscordProto::OnCommandGuildMemberUpdated }, + { 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 }, @@ -159,9 +163,25 @@ static SnowFlake sttGetLastRead(const JSONNode &reads, const wchar_t *wszChannel return 0; } +void CDiscordProto::ProcessRole(SnowFlake guildId, const JSONNode &role) +{ + SnowFlake id = ::getId(role["id"]); + CDiscordRole *p = arRoles.find((CDiscordRole*)&id); + if (p == nullptr) { + p = new CDiscordRole(); + p->id = id; + arRoles.insert(p); + } + p->guildId = guildId; + p->color = role["color"].as_int(); + p->position = role["position"].as_int(); + p->permissions = role["permissions"].as_int(); + p->wszName = role["name"].as_mstring(); +} + void CDiscordProto::ProcessGuild(const JSONNode &readState, const JSONNode &p) { - SnowFlake guildId = ::getId(p["id"]); + SnowFlake guildId = ::getId(p["id"]), ownerId = ::getId(p["owner_id"]); GatewaySendGuildInfo(guildId); CMStringW wszGuildName = p["name"].as_mstring(); @@ -170,6 +190,10 @@ void CDiscordProto::ProcessGuild(const JSONNode &readState, const JSONNode &p) Chat_Control(m_szModuleName, wszGuildName, SESSION_ONLINE); setId(si->hContact, DB_KEY_CHANNELID, guildId); + const JSONNode &roles = p["roles"]; + for (auto itr = roles.begin(); itr != roles.end(); ++itr) + ProcessRole(guildId, *itr); + const JSONNode &channels = p["channels"]; for (auto itc = channels.begin(); itc != channels.end(); ++itc) { const JSONNode &pch = *itc; @@ -182,7 +206,9 @@ void CDiscordProto::ProcessGuild(const JSONNode &readState, const JSONNode &p) SnowFlake channelId = _wtoi64(wszChannelId); si = Chat_NewSession(GCW_CHATROOM, m_szModuleName, wszChannelId, wszGuildName + L"#" + wszChannelName); - Chat_AddGroup(m_szModuleName, wszChannelId, TranslateT("User")); + setId(si->hContact, DB_KEY_OWNERID, ownerId); + BuildStatusList(guildId, wszChannelId); + Chat_Control(m_szModuleName, wszChannelId, WINDOW_HIDDEN); Chat_Control(m_szModuleName, wszChannelId, SESSION_ONLINE); @@ -213,7 +239,7 @@ void CDiscordProto::ProcessGuild(const JSONNode &readState, const JSONNode &p) } } -void CDiscordProto::OnCommandGuildCreate(const JSONNode &pRoot) +void CDiscordProto::OnCommandGuildCreated(const JSONNode &pRoot) { ProcessGuild(JSONNode(), pRoot); OnCommandGuildSync(pRoot); @@ -234,14 +260,27 @@ void CDiscordProto::OnCommandGuildSync(const JSONNode &pRoot) if (pUser.guildId != guildId) continue; + CDiscordRole *pRole = nullptr; + const JSONNode &pRoles = m["roles"]; + for (auto itr = pRoles.begin(); itr != pRoles.end(); ++itr) { + SnowFlake roleId = ::getId(*itr); + if (pRole = arRoles.find((CDiscordRole*)&roleId)) + break; + } + GCDEST gcd = { m_szModuleName, pUser.wszUsername, GC_EVENT_JOIN }; GCEVENT gce = { &gcd }; CMStringW wszNick = m["nick"].as_mstring(); CMStringW wszUsername = m["user"]["username"].as_mstring() + L"#" + m["user"]["discriminator"].as_mstring(); CMStringW wszUserId = m["user"]["id"].as_mstring(); - SnowFlake userid = _wtoi64(wszUserId); - gce.bIsMe = (userid == m_ownId); + SnowFlake userId = _wtoi64(wszUserId); + if (userId == getId(pUser.hContact, DB_KEY_OWNERID)) + gce.ptszStatus = L"@owner"; + else + gce.ptszStatus = (pRole == nullptr) ? L"@everyone" : pRole->wszName; + + gce.bIsMe = (userId == m_ownId); gce.ptszUID = wszUserId; gce.ptszNick = wszNick.IsEmpty() ? wszUsername : wszNick; Chat_Event(&gce); @@ -259,7 +298,7 @@ void CDiscordProto::OnCommandGuildSync(const JSONNode &pRoot) } } -void CDiscordProto::OnCommandGuildDelete(const JSONNode &pRoot) +void CDiscordProto::OnCommandGuildDeleted(const JSONNode &pRoot) { SnowFlake guildId = ::getId(pRoot["id"]); @@ -274,7 +313,11 @@ void CDiscordProto::OnCommandGuildDelete(const JSONNode &pRoot) Chat_Terminate(m_szModuleName, pRoot["name"].as_mstring(), true); } -void CDiscordProto::OnCommandGuildRemoveMember(const JSONNode &pRoot) +void CDiscordProto::OnCommandGuildMemberAdded(const JSONNode &pRoot) +{ +} + +void CDiscordProto::OnCommandGuildMemberRemoved(const JSONNode &pRoot) { SnowFlake guildId = ::getId(pRoot["guild_id"]); CMStringW wszUserId = pRoot["user"]["id"].as_mstring(); @@ -291,7 +334,7 @@ void CDiscordProto::OnCommandGuildRemoveMember(const JSONNode &pRoot) } } -void CDiscordProto::OnCommandGuildUpdateMember(const JSONNode &pRoot) +void CDiscordProto::OnCommandGuildMemberUpdated(const JSONNode &pRoot) { SnowFlake guildId = ::getId(pRoot["guild_id"]); CMStringW wszUserId = pRoot["user"]["id"].as_mstring(); @@ -318,6 +361,42 @@ void CDiscordProto::OnCommandGuildUpdateMember(const JSONNode &pRoot) } } +///////////////////////////////////////////////////////////////////////////////////////// +// roles + +void CDiscordProto::OnCommandRoleCreated(const JSONNode &pRoot) +{ + ProcessRole(::getId(pRoot["guild_id"]), pRoot["role"]); +} + +void CDiscordProto::OnCommandRoleDeleted(const JSONNode &pRoot) +{ + SnowFlake id = ::getId(pRoot["role_id"]), guildId = ::getId(pRoot["guild_id"]); + CDiscordRole *pRole = arRoles.find((CDiscordRole*)&id); + if (pRole == nullptr) + return; + + int iOldPosition = pRole->position; + arRoles.remove(pRole); + + for (int i = 0; i < arRoles.getCount(); i++) { + CDiscordRole &p = arRoles[i]; + if (p.guildId == guildId && p.position > iOldPosition) + p.position--; + } + + for (int i = 0; i < arUsers.getCount(); i++) { + CDiscordUser &p = arUsers[i]; + if (p.guildId != guildId) + continue; + + SESSION_INFO *si = pci->SM_FindSession(p.wszUsername, m_szModuleName); + if (si != nullptr) { + pci->TM_RemoveAll(&si->pStatuses); + BuildStatusList(guildId, p.wszUsername); + } + } +} ///////////////////////////////////////////////////////////////////////////////////////// // reading a new message diff --git a/protocols/Discord/src/groupchat.cpp b/protocols/Discord/src/groupchat.cpp index 5525f6658f..6641a4fd88 100644 --- a/protocols/Discord/src/groupchat.cpp +++ b/protocols/Discord/src/groupchat.cpp @@ -23,6 +23,21 @@ enum { IDM_CHANGENICK, IDM_CHANGETOPIC, IDM_INVITE }; +///////////////////////////////////////////////////////////////////////////////////////// + +void CDiscordProto::BuildStatusList(SnowFlake guildId, const CMStringW &wszChannelId) +{ + Chat_AddGroup(m_szModuleName, wszChannelId, L"@owner"); + + for (int i = 0; i < arRoles.getCount(); i++) { + CDiscordRole &r = arRoles[i]; + if (r.guildId == guildId) + Chat_AddGroup(m_szModuleName, wszChannelId, r.wszName); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// + static gc_item sttLogListItems[] = { { LPGENW("Change &nickname"), IDM_CHANGENICK, MENU_ITEM }, diff --git a/protocols/Discord/src/proto.cpp b/protocols/Discord/src/proto.cpp index e102d86fb1..ed5d9fe3e7 100644 --- a/protocols/Discord/src/proto.cpp +++ b/protocols/Discord/src/proto.cpp @@ -27,6 +27,11 @@ static int compareRequests(const AsyncHttpRequest *p1, const AsyncHttpRequest *p return p1->m_iReqNum - p2->m_iReqNum; } +static int compareRoles(const CDiscordRole *p1, const CDiscordRole *p2) +{ + return p1->id - p2->id; +} + static int compareUsers(const CDiscordUser *p1, const CDiscordUser *p2) { return p1->id - p2->id; @@ -40,6 +45,7 @@ CDiscordProto::CDiscordProto(const char *proto_name, const wchar_t *username) : m_wszEmail(this, DB_KEY_EMAIL, L""), arMarkReadQueue(1, compareUsers), arOwnMessages(1, compareMessages), + arRoles(10, compareRoles), arUsers(50, compareUsers) { // Services diff --git a/protocols/Discord/src/proto.h b/protocols/Discord/src/proto.h index 133ff1f40c..122b3a9e40 100644 --- a/protocols/Discord/src/proto.h +++ b/protocols/Discord/src/proto.h @@ -81,7 +81,18 @@ JSONNode& operator<<(JSONNode &json, const WCHAR_PARAM ¶m); ///////////////////////////////////////////////////////////////////////////////////////// -enum CDiscordHitoryOp +struct CDiscordRole : public MZeroedObject +{ + SnowFlake id, guildId; + COLORREF color; + DWORD permissions; + int position; + CMStringW wszName; +}; + +///////////////////////////////////////////////////////////////////////////////////////// + +enum CDiscordHistoryOp { MSG_NOFILTER, MSG_AFTER, MSG_BEFORE }; @@ -179,6 +190,7 @@ class CDiscordProto : public PROTO<CDiscordProto> mir_cs csMarkReadQueue; LIST<CDiscordUser> arMarkReadQueue; + OBJLIST<CDiscordRole> arRoles; OBJLIST<CDiscordUser> arUsers; OBJLIST<SnowFlake> arOwnMessages; CDiscordUser* FindUser(SnowFlake id); @@ -206,6 +218,8 @@ class CDiscordProto : public PROTO<CDiscordProto> void Chat_SendPrivateMessage(GCHOOK *gch); void Chat_ProcessLogMenu(GCHOOK *gch); + + void BuildStatusList(SnowFlake guildId, const CMStringW &wszChannelId); void ParseSpecialChars(SESSION_INFO *si, CMStringW &str); ////////////////////////////////////////////////////////////////////////////////////// @@ -262,10 +276,11 @@ public: void OnCommandChannelCreated(const JSONNode&); void OnCommandChannelDeleted(const JSONNode&); void OnCommandChannelUpdated(const JSONNode&); - void OnCommandGuildCreate(const JSONNode&); - void OnCommandGuildDelete(const JSONNode&); - void OnCommandGuildRemoveMember(const JSONNode&); - void OnCommandGuildUpdateMember(const JSONNode&); + void OnCommandGuildCreated(const JSONNode&); + void OnCommandGuildDeleted(const JSONNode&); + void OnCommandGuildMemberAdded(const JSONNode&); + void OnCommandGuildMemberRemoved(const JSONNode&); + void OnCommandGuildMemberUpdated(const JSONNode&); void OnCommandGuildSync(const JSONNode&); void OnCommandFriendAdded(const JSONNode&); void OnCommandFriendRemoved(const JSONNode&); @@ -273,6 +288,8 @@ public: void OnCommandMessageAck(const JSONNode&); void OnCommandPresence(const JSONNode&); void OnCommandReady(const JSONNode&); + void OnCommandRoleCreated(const JSONNode&); + void OnCommandRoleDeleted(const JSONNode&); void OnCommandTyping(const JSONNode&); void OnCommandUserUpdate(const JSONNode&); void OnCommandUserSettingsUpdate(const JSONNode&); @@ -296,7 +313,7 @@ public: void RetrieveUserInfo(MCONTACT hContact); void OnReceiveUserInfo(NETLIBHTTPREQUEST*, AsyncHttpRequest*); - void RetrieveHistory(MCONTACT hContact, CDiscordHitoryOp iOp = MSG_NOFILTER, SnowFlake msgid = 0, int iLimit = 50); + void RetrieveHistory(MCONTACT hContact, CDiscordHistoryOp iOp = MSG_NOFILTER, SnowFlake msgid = 0, int iLimit = 50); void OnReceiveHistory(NETLIBHTTPREQUEST*, AsyncHttpRequest*); bool RetrieveAvatar(MCONTACT hContact); @@ -304,6 +321,7 @@ public: // Misc void ProcessGuild(const JSONNode &pStatuses, const JSONNode &pRoot); + void ProcessRole(SnowFlake guildId, const JSONNode&); void ProcessType(CDiscordUser *pUser, const JSONNode&); void SetServerStatus(int iStatus); void RemoveFriend(SnowFlake id); diff --git a/protocols/Discord/src/server.cpp b/protocols/Discord/src/server.cpp index 5033e5aefd..bd23659b3e 100644 --- a/protocols/Discord/src/server.cpp +++ b/protocols/Discord/src/server.cpp @@ -28,7 +28,7 @@ void CDiscordProto::RemoveFriend(SnowFlake id) ///////////////////////////////////////////////////////////////////////////////////////// // retrieves server history -void CDiscordProto::RetrieveHistory(MCONTACT hContact, CDiscordHitoryOp iOp, SnowFlake msgid, int iLimit) +void CDiscordProto::RetrieveHistory(MCONTACT hContact, CDiscordHistoryOp iOp, SnowFlake msgid, int iLimit) { CDiscordUser *pUser = FindUser(getId(hContact, DB_KEY_ID)); if (pUser == NULL) diff --git a/protocols/Discord/src/stdafx.h b/protocols/Discord/src/stdafx.h index a5022fb7d6..0794bc5df3 100644 --- a/protocols/Discord/src/stdafx.h +++ b/protocols/Discord/src/stdafx.h @@ -58,6 +58,7 @@ extern HWND g_hwndHeartbeat; #define DB_KEY_NICK "Nick" #define DB_KEY_AVHASH "AvatarHash" #define DB_KEY_CHANNELID "ChannelID" +#define DB_KEY_OWNERID "OwnerID" #define DB_KEY_LASTMSGID "LastMessageID" #define DB_KEY_REQAUTH "ReqAuth" diff --git a/protocols/Discord/src/version.h b/protocols/Discord/src/version.h index 1844aa3c1e..b57f31665b 100644 --- a/protocols/Discord/src/version.h +++ b/protocols/Discord/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 3 #define __RELEASE_NUM 1 -#define __BUILD_NUM 2 +#define __BUILD_NUM 3 #include <stdver.h> |