summaryrefslogtreecommitdiff
path: root/protocols/Discord
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2017-01-20 00:12:11 +0300
committerGeorge Hazan <ghazan@miranda.im>2017-01-20 00:12:11 +0300
commitfa78a351b86311df1e19cd5d0e835156a65d1fab (patch)
treedd38f650c4f6a9cdb545624262d8ea1876567c74 /protocols/Discord
parent92b173c3a8553b59077aa2757c9627cb4c73d29e (diff)
Discord: first version with groupchats
Diffstat (limited to 'protocols/Discord')
-rw-r--r--protocols/Discord/src/dispatch.cpp97
-rw-r--r--protocols/Discord/src/groupchat.cpp28
-rw-r--r--protocols/Discord/src/proto.cpp12
-rw-r--r--protocols/Discord/src/proto.h3
-rw-r--r--protocols/Discord/src/stdafx.h2
-rw-r--r--protocols/Discord/src/version.h4
6 files changed, 128 insertions, 18 deletions
diff --git a/protocols/Discord/src/dispatch.cpp b/protocols/Discord/src/dispatch.cpp
index 74672391ca..0011f3becb 100644
--- a/protocols/Discord/src/dispatch.cpp
+++ b/protocols/Discord/src/dispatch.cpp
@@ -117,7 +117,8 @@ void CDiscordProto::OnCommandMessage(const JSONNode &pRoot)
}
// try to find a sender by his channel
- SnowFlake channelId = _wtoi64(pRoot["channel_id"].as_mstring());
+ CMStringW wszChannelId = pRoot["channel_id"].as_mstring();
+ SnowFlake channelId = _wtoi64(wszChannelId);
CDiscordUser *pUser = FindUserByChannel(channelId);
if (pUser == NULL) {
debugLogA("skipping message with unknown channel id=%lld", channelId);
@@ -125,7 +126,8 @@ void CDiscordProto::OnCommandMessage(const JSONNode &pRoot)
}
// if a message has myself as an author, add some flags
- if (_wtoi64(pRoot["author"]["id"].as_mstring()) == m_ownId)
+ CMStringW wszUserId = pRoot["author"]["id"].as_mstring();
+ if (_wtoi64(wszUserId) == m_ownId)
recv.flags = PREF_CREATEREAD | PREF_SENT;
CMStringW wszText = pRoot["content"].as_mstring();
@@ -134,20 +136,31 @@ void CDiscordProto::OnCommandMessage(const JSONNode &pRoot)
if (!edited.isnull())
wszText.AppendFormat(L" (%s %s)", TranslateT("edited at"), edited.as_mstring().c_str());
- if (pUser->channelId != channelId) {
- debugLogA("failed to process a groupchat message, exiting");
- return;
+ if (pUser->bIsPrivate) {
+ ptrA buf(mir_utf8encodeW(wszText));
+ recv.timestamp = (DWORD)StringToDate(pRoot["timestamp"].as_mstring());
+ recv.szMessage = buf;
+ recv.lParam = (LPARAM)wszMessageId.c_str();
+ ProtoChainRecvMsg(pUser->hContact, &recv);
+
+ SnowFlake lastId = getId(pUser->hContact, DB_KEY_LASTMSGID); // as stored in a database
+ if (lastId < messageId)
+ setId(pUser->hContact, DB_KEY_LASTMSGID, messageId);
+ }
+ else {
+ CMStringW wszUserName = pRoot["author"]["id"].as_mstring();
+ CMStringW wszUserNick = pRoot["author"]["username"].as_mstring() + L"#" + pRoot["author"]["discriminator"].as_mstring();
+
+ GCDEST gcd = { m_szModuleName, wszChannelId, GC_EVENT_MESSAGE };
+ GCEVENT gce = { &gcd };
+ gce.dwFlags = GCEF_ADDTOLOG;
+ gce.ptszUID = wszUserId;
+ gce.ptszNick = wszUserNick;
+ gce.ptszText = wszText;
+ gce.time = (DWORD)StringToDate(pRoot["timestamp"].as_mstring());
+ gce.bIsMe = _wtoi64(wszUserId) == m_ownId;
+ Chat_Event(&gce);
}
-
- ptrA buf(mir_utf8encodeW(wszText));
- recv.timestamp = (DWORD)StringToDate(pRoot["timestamp"].as_mstring());
- recv.szMessage = buf;
- recv.lParam = (LPARAM)wszMessageId.c_str();
- ProtoChainRecvMsg(pUser->hContact, &recv);
-
- SnowFlake lastId = getId(pUser->hContact, DB_KEY_LASTMSGID); // as stored in a database
- if (lastId < messageId)
- setId(pUser->hContact, DB_KEY_LASTMSGID, messageId);
}
//////////////////////////////////////////////////////////////////////////////////////
@@ -211,6 +224,60 @@ void CDiscordProto::OnCommandReady(const JSONNode &pRoot)
m_szGatewaySessionId = pRoot["session_id"].as_mstring();
+ const JSONNode &guilds = pRoot["guilds"];
+ for (auto it = guilds.begin(); it != guilds.end(); ++it) {
+ const JSONNode &p = *it;
+
+ CMStringW wszGuildName = p["name"].as_mstring();
+
+ GCSessionInfoBase *si = Chat_NewSession(GCW_SERVER, m_szModuleName, wszGuildName, wszGuildName);
+ Chat_Control(m_szModuleName, wszGuildName, WINDOW_HIDDEN);
+ Chat_Control(m_szModuleName, wszGuildName, SESSION_ONLINE);
+
+ const JSONNode &members = p["members"];
+ const JSONNode &channels = p["channels"];
+ for (auto itc = channels.begin(); itc != channels.end(); ++itc) {
+ const JSONNode &pch = *itc;
+ if (pch["type"].as_int() != 0)
+ continue;
+
+ CMStringW wszChannelName = pch["name"].as_mstring();
+ CMStringW wszChannelId = pch["id"].as_mstring();
+ SnowFlake channelId = _wtoi64(wszChannelId);
+
+ si = Chat_NewSession(GCW_CHATROOM, m_szModuleName, wszChannelId, wszGuildName + L"#" + wszChannelName);
+ Chat_AddGroup(m_szModuleName, wszChannelId, TranslateT("User"));
+ Chat_Control(m_szModuleName, wszChannelId, WINDOW_HIDDEN);
+ Chat_Control(m_szModuleName, wszChannelId, SESSION_ONLINE);
+
+ CDiscordUser *pUser = FindUserByChannel(channelId);
+ if (pUser == NULL) {
+ // missing channel - create it
+ pUser = new CDiscordUser(channelId);
+ pUser->bIsPrivate = false;
+ pUser->hContact = si->hContact;
+ pUser->channelId = channelId;
+ arUsers.insert(pUser);
+ }
+ pUser->lastMessageId = _wtoi64(pch["last_message_id"].as_mstring());
+
+ setId(pUser->hContact, DB_KEY_CHANNELID, channelId);
+
+ GCDEST gcd = { m_szModuleName, wszChannelId, GC_EVENT_JOIN };
+ GCEVENT gce = { &gcd };
+ for (auto itu = members.begin(); itu != members.end(); ++itu) {
+ const JSONNode &pu = *itu;
+
+ CMStringW username = pu["user"]["username"].as_mstring() + L"#" + pu["user"]["discriminator"].as_mstring();
+ CMStringW userid = pu["user"]["id"].as_mstring();
+ gce.bIsMe = _wtoi64(userid) == m_ownId;
+ gce.ptszUID = userid;
+ gce.ptszNick = username;
+ Chat_Event(&gce);
+ }
+ }
+ }
+
const JSONNode &relations = pRoot["relationships"];
for (auto it = relations.begin(); it != relations.end(); ++it) {
const JSONNode &p = *it;
diff --git a/protocols/Discord/src/groupchat.cpp b/protocols/Discord/src/groupchat.cpp
new file mode 100644
index 0000000000..1285a40245
--- /dev/null
+++ b/protocols/Discord/src/groupchat.cpp
@@ -0,0 +1,28 @@
+/*
+Copyright © 2016-17 Miranda NG team
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "stdafx.h"
+
+int CDiscordProto::GroupchatEventHook(WPARAM, LPARAM)
+{
+ return 0;
+}
+
+int CDiscordProto::GroupchatMenuHook(WPARAM, LPARAM)
+{
+ return 0;
+}
diff --git a/protocols/Discord/src/proto.cpp b/protocols/Discord/src/proto.cpp
index 83cc7c1941..946a356441 100644
--- a/protocols/Discord/src/proto.cpp
+++ b/protocols/Discord/src/proto.cpp
@@ -425,8 +425,20 @@ int CDiscordProto::OnDeleteContact(MCONTACT hContact)
/////////////////////////////////////////////////////////////////////////////////////////
+static COLORREF crCols[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+
int CDiscordProto::OnModulesLoaded(WPARAM, LPARAM)
{
+ GCREGISTER gcr = {};
+ gcr.dwFlags = GC_TYPNOTIF | GC_CHANMGR;
+ gcr.nColors = _countof(crCols);
+ gcr.pColors = &crCols[0];
+ gcr.ptszDispName = m_tszUserName;
+ gcr.pszModule = m_szModuleName;
+ Chat_Register(&gcr);
+
+ HookProtoEvent(ME_GC_EVENT, &CDiscordProto::GroupchatEventHook);
+ HookProtoEvent(ME_GC_BUILDMENU, &CDiscordProto::GroupchatMenuHook);
return 0;
}
diff --git a/protocols/Discord/src/proto.h b/protocols/Discord/src/proto.h
index 3631c1237a..1b4e65d9b1 100644
--- a/protocols/Discord/src/proto.h
+++ b/protocols/Discord/src/proto.h
@@ -231,6 +231,9 @@ public:
int __cdecl OnOptionsInit(WPARAM, LPARAM);
int __cdecl OnDbEventRead(WPARAM, LPARAM);
+ int __cdecl GroupchatEventHook(WPARAM, LPARAM);
+ int __cdecl GroupchatMenuHook(WPARAM, LPARAM);
+
// dispatch commands
void OnChannelCreated(const JSONNode&);
void OnChannelDeleted(const JSONNode&);
diff --git a/protocols/Discord/src/stdafx.h b/protocols/Discord/src/stdafx.h
index 1db7e3f848..42bb766230 100644
--- a/protocols/Discord/src/stdafx.h
+++ b/protocols/Discord/src/stdafx.h
@@ -17,7 +17,7 @@
#include <m_system_cpp.h>
#include <newpluginapi.h>
-#include <m_chat.h>
+#include <m_chat_int.h>
#include <m_clist.h>
#include <m_database.h>
#include <m_folders.h>
diff --git a/protocols/Discord/src/version.h b/protocols/Discord/src/version.h
index 3c4a0e6d7d..cd73918a4b 100644
--- a/protocols/Discord/src/version.h
+++ b/protocols/Discord/src/version.h
@@ -1,7 +1,7 @@
#define __MAJOR_VERSION 0
-#define __MINOR_VERSION 1
+#define __MINOR_VERSION 2
#define __RELEASE_NUM 0
-#define __BUILD_NUM 4
+#define __BUILD_NUM 1
#include <stdver.h>