diff options
author | George Hazan <ghazan@miranda.im> | 2020-01-15 23:27:07 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2020-01-15 23:27:07 +0300 |
commit | 28880a272962ca55298b4304bf6f5512bda901d2 (patch) | |
tree | bb7e23bf6daa82456981084ff6d96c7d9f6e4746 /protocols | |
parent | 53aab07f1ee1dc3fe8c48dbe95a434079013f260 (diff) |
Discord voice calls - packet processing
Diffstat (limited to 'protocols')
-rw-r--r-- | protocols/Discord/res/discord.rc | 3 | ||||
-rw-r--r-- | protocols/Discord/res/voiceCall.ico | bin | 0 -> 2038 bytes | |||
-rw-r--r-- | protocols/Discord/res/voiceEnded.ico | bin | 0 -> 2038 bytes | |||
-rw-r--r-- | protocols/Discord/src/dispatch.cpp | 72 | ||||
-rw-r--r-- | protocols/Discord/src/main.cpp | 4 | ||||
-rw-r--r-- | protocols/Discord/src/proto.cpp | 16 | ||||
-rw-r--r-- | protocols/Discord/src/proto.h | 57 | ||||
-rw-r--r-- | protocols/Discord/src/resource.h | 2 |
8 files changed, 132 insertions, 22 deletions
diff --git a/protocols/Discord/res/discord.rc b/protocols/Discord/res/discord.rc index 47156ab6c7..93febddec9 100644 --- a/protocols/Discord/res/discord.rc +++ b/protocols/Discord/res/discord.rc @@ -56,6 +56,9 @@ IDI_MAIN ICON "discord.ico" IDI_GROUPCHAT ICON "groupchat.ico" +IDI_VOICE_CALL ICON "voiceCall.ico" + +IDI_VOICE_ENDED ICON "voiceEnded.ico" ///////////////////////////////////////////////////////////////////////////// // diff --git a/protocols/Discord/res/voiceCall.ico b/protocols/Discord/res/voiceCall.ico Binary files differnew file mode 100644 index 0000000000..6559874da9 --- /dev/null +++ b/protocols/Discord/res/voiceCall.ico diff --git a/protocols/Discord/res/voiceEnded.ico b/protocols/Discord/res/voiceEnded.ico Binary files differnew file mode 100644 index 0000000000..397ecb2b12 --- /dev/null +++ b/protocols/Discord/res/voiceEnded.ico diff --git a/protocols/Discord/src/dispatch.cpp b/protocols/Discord/src/dispatch.cpp index 3766361a4b..b22e76f583 100644 --- a/protocols/Discord/src/dispatch.cpp +++ b/protocols/Discord/src/dispatch.cpp @@ -28,6 +28,10 @@ struct CDiscordCommand } static handlers[] = // these structures must me sorted alphabetically { + { L"CALL_CREATE", &CDiscordProto::OnCommandCallCreated }, + { L"CALL_DELETE", &CDiscordProto::OnCommandCallDeleted }, + { L"CALL_UPDATE", &CDiscordProto::OnCommandCallUpdated }, + { L"CHANNEL_CREATE", &CDiscordProto::OnCommandChannelCreated }, { L"CHANNEL_DELETE", &CDiscordProto::OnCommandChannelDeleted }, { L"CHANNEL_UPDATE", &CDiscordProto::OnCommandChannelUpdated }, @@ -72,6 +76,74 @@ GatewayHandlerFunc CDiscordProto::GetHandler(const wchar_t *pwszCommand) } ///////////////////////////////////////////////////////////////////////////////////////// +// call operations (voice & video) + +void CDiscordProto::OnCommandCallCreated(const JSONNode &pRoot) +{ + for (auto &it : pRoot["voice_states"]) { + SnowFlake channelId = ::getId(pRoot["channel_id"]); + auto *pUser = FindUserByChannel(channelId); + if (pUser == nullptr) { + debugLogA("Call from unknown channel %lld, skipping", channelId); + continue; + } + + auto *pCall = new CDiscordVoiceCall(); + pCall->szId = it["session_id"].as_mstring(); + pCall->channelId = channelId; + pCall->startTime = time(0); + arVoiceCalls.insert(pCall); + + char *szMessage = TranslateU("Incoming voice call"); + DBEVENTINFO dbei = {}; + dbei.szModule = m_szModuleName; + dbei.timestamp = pCall->startTime; + dbei.eventType = EVENT_INCOMING_CALL; + dbei.cbBlob = DWORD(mir_strlen(szMessage)+1); + dbei.pBlob = (BYTE*)szMessage; + dbei.flags = DBEF_UTF; + db_event_add(pUser->hContact, &dbei); + } +} + +void CDiscordProto::OnCommandCallDeleted(const JSONNode &pRoot) +{ + SnowFlake channelId = ::getId(pRoot["channel_id"]); + auto *pUser = FindUserByChannel(channelId); + if (pUser == nullptr) { + debugLogA("Call from unknown channel %lld, skipping", channelId); + return; + } + + int elapsed = 0, currTime = time(0); + for (auto &call : arVoiceCalls.rev_iter()) + if (call->channelId == channelId) { + elapsed = currTime - call->startTime; + arVoiceCalls.remove(arVoiceCalls.indexOf(&call)); + break; + } + + if (!elapsed) { + debugLogA("Call from channel %lld isn't registered, skipping", channelId); + return; + } + + CMStringA szMessage(FORMAT, TranslateU("Voice call ended, %d seconds long"), elapsed); + DBEVENTINFO dbei = {}; + dbei.szModule = m_szModuleName; + dbei.timestamp = currTime; + dbei.eventType = EVENT_CALL_FINISHED; + dbei.cbBlob = DWORD(szMessage.GetLength() + 1); + dbei.pBlob = (BYTE *)szMessage.c_str(); + dbei.flags = DBEF_UTF; + db_event_add(pUser->hContact, &dbei); +} + +void CDiscordProto::OnCommandCallUpdated(const JSONNode &pRoot) +{ +} + +///////////////////////////////////////////////////////////////////////////////////////// // channel operations void CDiscordProto::OnCommandChannelCreated(const JSONNode &pRoot) diff --git a/protocols/Discord/src/main.cpp b/protocols/Discord/src/main.cpp index 559a0da4da..80d45c62f0 100644 --- a/protocols/Discord/src/main.cpp +++ b/protocols/Discord/src/main.cpp @@ -51,7 +51,9 @@ extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_PROTOC IconItem g_iconList[] = { { LPGEN("Main icon"), "main", IDI_MAIN }, - { LPGEN("Group chats"), "groupchat", IDI_GROUPCHAT } + { LPGEN("Group chats"), "groupchat", IDI_GROUPCHAT }, + { LPGEN("Voice call"), "voicecall", IDI_VOICE_CALL }, + { LPGEN("Call ended"), "voiceend", IDI_VOICE_ENDED } }; int CMPlugin::Load() diff --git a/protocols/Discord/src/proto.cpp b/protocols/Discord/src/proto.cpp index 1051b57005..f07fa1bfab 100644 --- a/protocols/Discord/src/proto.cpp +++ b/protocols/Discord/src/proto.cpp @@ -46,6 +46,7 @@ CDiscordProto::CDiscordProto(const char *proto_name, const wchar_t *username) : arGuilds(1, compareGuilds), arMarkReadQueue(1, compareUsers), arOwnMessages(1, compareMessages), + arVoiceCalls(1), m_wszEmail(this, "Email", L""), m_wszDefaultGroup(this, "GroupName", DB_KEYVAL_GROUP), @@ -71,6 +72,21 @@ CDiscordProto::CDiscordProto(const char *proto_name, const wchar_t *username) : // database db_set_resident(m_szModuleName, "XStatusMsg"); + // custom events + DBEVENTTYPEDESCR dbEventType = {}; + dbEventType.module = m_szModuleName; + dbEventType.flags = DETF_HISTORY | DETF_MSGWINDOW; + + dbEventType.eventType = EVENT_INCOMING_CALL; + dbEventType.descr = Translate("Incoming voice call"); + dbEventType.eventIcon = g_plugin.getIconHandle(IDI_VOICE_CALL); + DbEvent_RegisterType(&dbEventType); + + dbEventType.eventType = EVENT_CALL_FINISHED; + dbEventType.descr = Translate("Voice call ended"); + dbEventType.eventIcon = g_plugin.getIconHandle(IDI_VOICE_ENDED); + DbEvent_RegisterType(&dbEventType); + // Network initialization CMStringW descr; NETLIBUSER nlu = {}; diff --git a/protocols/Discord/src/proto.h b/protocols/Discord/src/proto.h index a25da70c5d..95e6f48d6b 100644 --- a/protocols/Discord/src/proto.h +++ b/protocols/Discord/src/proto.h @@ -1,5 +1,8 @@ #pragma once +#define EVENT_INCOMING_CALL 10001 +#define EVENT_CALL_FINISHED 10002 + typedef __int64 SnowFlake; __forceinline int compareInt64(const SnowFlake i1, const SnowFlake i2) @@ -111,6 +114,13 @@ struct CDiscordGuild : public MZeroedObject OBJLIST<CDiscordRole> arRoles; // guild roles }; +struct CDiscordVoiceCall +{ + CMStringA szId; + SnowFlake channelId; + time_t startTime; +}; + ///////////////////////////////////////////////////////////////////////////////////////// class CDiscordProto : public PROTO<CDiscordProto> @@ -223,6 +233,7 @@ class CDiscordProto : public PROTO<CDiscordProto> OBJLIST<CDiscordUser> arUsers; OBJLIST<COwnMessage> arOwnMessages; + OBJLIST<CDiscordVoiceCall> arVoiceCalls; CDiscordUser* FindUser(SnowFlake id); CDiscordUser* FindUser(const wchar_t *pwszUsername, int iDiscriminator); @@ -326,6 +337,7 @@ public: INT_PTR __cdecl RequestFriendship(WPARAM, LPARAM); INT_PTR __cdecl SvcCreateAccMgrUI(WPARAM, LPARAM); + INT_PTR __cdecl SvcGetEventIcon(WPARAM, LPARAM); INT_PTR __cdecl GetAvatarCaps(WPARAM, LPARAM); INT_PTR __cdecl GetAvatarInfo(WPARAM, LPARAM); @@ -342,28 +354,31 @@ public: ////////////////////////////////////////////////////////////////////////////////////// // dispatch commands - void OnCommandChannelCreated(const JSONNode&); - void OnCommandChannelDeleted(const JSONNode&); - void OnCommandChannelUpdated(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&); + void OnCommandCallCreated(const JSONNode &json); + void OnCommandCallDeleted(const JSONNode &json); + void OnCommandCallUpdated(const JSONNode &json); + void OnCommandChannelCreated(const JSONNode &json); + void OnCommandChannelDeleted(const JSONNode &json); + void OnCommandChannelUpdated(const JSONNode &json); + void OnCommandGuildCreated(const JSONNode &json); + void OnCommandGuildDeleted(const JSONNode &json); + 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); - void OnCommandMessageCreate(const JSONNode&); - void OnCommandMessageUpdate(const JSONNode&); - 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&); + void OnCommandMessageCreate(const JSONNode &json); + void OnCommandMessageUpdate(const JSONNode &json); + void OnCommandMessageAck(const JSONNode &json); + void OnCommandPresence(const JSONNode &json); + void OnCommandReady(const JSONNode &json); + void OnCommandRoleCreated(const JSONNode &json); + void OnCommandRoleDeleted(const JSONNode &json); + void OnCommandTyping(const JSONNode &json); + void OnCommandUserUpdate(const JSONNode &json); + void OnCommandUserSettingsUpdate(const JSONNode &json); void OnLoggedIn(); void OnLoggedOut(); diff --git a/protocols/Discord/src/resource.h b/protocols/Discord/src/resource.h index a434f423de..b979e4775b 100644 --- a/protocols/Discord/src/resource.h +++ b/protocols/Discord/src/resource.h @@ -7,6 +7,8 @@ #define IDD_OPTIONS_ACCOUNT 103 #define IDD_EXTSEARCH 104 #define IDD_OPTIONS_ACCMGR 105 +#define IDI_VOICE_CALL 106 +#define IDI_VOICE_ENDED 107 #define IDC_PASSWORD 1001 #define IDC_USERNAME 1002 #define IDC_GROUP 1003 |