summaryrefslogtreecommitdiff
path: root/protocols/Discord/src/proto.cpp
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2016-12-30 00:49:15 +0300
committerGeorge Hazan <ghazan@miranda.im>2016-12-30 00:49:15 +0300
commit37ae1c46680e624dddddfee816f19cf920f95348 (patch)
tree0a32c5252055340cc8b11c6833173706902eee1d /protocols/Discord/src/proto.cpp
parent50e87bcbf1b3a716f155e504a09df1c0ff1a66f5 (diff)
Discord:
- user search works; - friend list support; - channel list support; - various fixes
Diffstat (limited to 'protocols/Discord/src/proto.cpp')
-rw-r--r--protocols/Discord/src/proto.cpp145
1 files changed, 139 insertions, 6 deletions
diff --git a/protocols/Discord/src/proto.cpp b/protocols/Discord/src/proto.cpp
index 39ec101779..e2947e0594 100644
--- a/protocols/Discord/src/proto.cpp
+++ b/protocols/Discord/src/proto.cpp
@@ -22,12 +22,18 @@ static int compareRequests(const AsyncHttpRequest *p1, const AsyncHttpRequest *p
return p1->m_iReqNum - p2->m_iReqNum;
}
+static int compareUsers(const CDiscordUser *p1, const CDiscordUser *p2)
+{
+ return p1->id - p2->id;
+}
+
CDiscordProto::CDiscordProto(const char *proto_name, const wchar_t *username) :
PROTO<CDiscordProto>(proto_name, username),
m_arHttpQueue(10, compareRequests),
m_evRequestsQueue(CreateEvent(NULL, FALSE, FALSE, NULL)),
m_wszDefaultGroup(this, DB_KEY_GROUP, DB_KEYVAL_GROUP),
- m_wszEmail(this, DB_KEY_EMAIL, L"")
+ m_wszEmail(this, DB_KEY_EMAIL, L""),
+ arUsers(50, compareUsers)
{
// Services
CreateProtoService(PS_GETNAME, &CDiscordProto::GetName);
@@ -39,6 +45,17 @@ CDiscordProto::CDiscordProto(const char *proto_name, const wchar_t *username) :
// Clist
Clist_GroupCreate(NULL, m_wszDefaultGroup);
+ // Fill users list
+ for (MCONTACT hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) {
+ CDiscordUser *pNew = new CDiscordUser(getId(hContact, DB_KEY_ID));
+ pNew->hContact = hContact;
+ pNew->channelId = getId(hContact, DB_KEY_CHANNELID);
+ pNew->lastMessageId = getId(hContact, DB_KEY_LASTMSGID);
+ pNew->wszUsername = ptrW(getWStringA(hContact, DB_KEY_NICK));
+ pNew->iDiscriminator = getDword(hContact, DB_KEY_DISCR);
+ arUsers.insert(pNew);
+ }
+
// Network initialization
CMStringW descr(FORMAT, TranslateT("%s server connection"), m_tszUserName);
@@ -63,15 +80,14 @@ DWORD_PTR CDiscordProto::GetCaps(int type, MCONTACT)
{
switch (type) {
case PFLAGNUM_1:
- return PF1_IM | PF1_MODEMSGRECV | PF1_SERVERCLIST;
+ return PF1_IM | PF1_MODEMSGRECV | PF1_SERVERCLIST | PF1_BASICSEARCH | PF1_EXTSEARCH | PF1_ADDSEARCHRES;
case PFLAGNUM_2:
- return PF2_ONLINE;
case PFLAGNUM_3:
- return PF2_ONLINE;
+ return PF2_ONLINE | PF2_HEAVYDND | PF2_INVISIBLE | PF2_IDLE;
case PFLAGNUM_4:
- return PF4_NOCUSTOMAUTH | PF4_AVATARS;
+ return PF4_FORCEADDED | PF4_FORCEAUTH | PF4_NOCUSTOMAUTH | PF4_NOAUTHDENYREASON | PF4_SUPPORTTYPING | PF4_SUPPORTIDLE | PF4_AVATARS | PF4_IMSENDOFFLINE;
case PFLAG_UNIQUEIDTEXT:
- return (DWORD_PTR)"E-mail";
+ return (DWORD_PTR)Translate("User ID");
case PFLAG_UNIQUEIDSETTING:
return (DWORD_PTR)DB_KEY_EMAIL;
}
@@ -125,6 +141,123 @@ int CDiscordProto::SetStatus(int iNewStatus)
/////////////////////////////////////////////////////////////////////////////////////////
+static INT_PTR CALLBACK AdvancedSearchDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM)
+{
+ switch (msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ SetFocus(GetDlgItem(hwndDlg, IDC_NICK));
+ return TRUE;
+
+ case WM_COMMAND:
+ if (HIWORD(wParam) == EN_SETFOCUS)
+ PostMessage(GetParent(hwndDlg), WM_COMMAND, MAKEWPARAM(0, EN_SETFOCUS), (LPARAM)hwndDlg);
+ }
+ return FALSE;
+}
+
+HWND CDiscordProto::CreateExtendedSearchUI(HWND hwndParent)
+{
+ if (hwndParent)
+ return CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_EXTSEARCH), hwndParent, AdvancedSearchDlgProc, 0);
+
+ return NULL;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CDiscordProto::SearchThread(void *param)
+{
+ Sleep(100);
+
+ PROTOSEARCHRESULT psr = { 0 };
+ psr.cbSize = sizeof(psr);
+ psr.flags = PSR_UNICODE;
+ psr.nick.w = (wchar_t*)param;
+ psr.firstName.w = L"";
+ psr.lastName.w = L"";
+ psr.id.w = (wchar_t*)param;
+ ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)param, (LPARAM)&psr);
+
+ ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)param, 0);
+ mir_free(param);
+}
+
+HWND CDiscordProto::SearchAdvanced(HWND hwndDlg)
+{
+ if (!m_bOnline || !IsWindow(hwndDlg))
+ return NULL;
+
+ wchar_t wszNick[200];
+ GetDlgItemTextW(hwndDlg, IDC_NICK, wszNick, _countof(wszNick));
+ if (wszNick[0] == 0) // empty string? reject
+ return NULL;
+
+ wchar_t *p = wcschr(wszNick, '#');
+ if (p == NULL) // wrong user id
+ return NULL;
+
+ p = mir_wstrdup(wszNick);
+ ForkThread(&CDiscordProto::SearchThread, p);
+ return (HWND)p;
+}
+
+HANDLE CDiscordProto::SearchBasic(const wchar_t *wszId)
+{
+ if (!m_bOnline)
+ return NULL;
+
+ CMStringA szUrl = "/users/";
+ szUrl.AppendFormat(ptrA(mir_utf8encodeW(wszId)));
+ AsyncHttpRequest *pReq = new AsyncHttpRequest(this, REQUEST_GET, szUrl, &CDiscordProto::OnReceiveUserInfo);
+ pReq->pUserInfo = (void*)-1;
+ Push(pReq);
+ return (HANDLE)1; // Success
+}
+
+int CDiscordProto::AuthRequest(MCONTACT hContact, const wchar_t*)
+{
+ ptrW wszUsername(getWStringA(hContact, DB_KEY_NICK));
+ int iDiscriminator(getDword(hContact, DB_KEY_DISCR, -1));
+ if (wszUsername == NULL || iDiscriminator == -1)
+ return 1; // error
+
+ JSONNode root; root << WCHAR_PARAM("username", wszUsername) << INT_PARAM("discriminator", iDiscriminator);
+ AsyncHttpRequest *pReq = new AsyncHttpRequest(this, REQUEST_POST, "/users/@me/relationships", &CDiscordProto::OnReceiveAuth, &root);
+ pReq->pUserInfo = (void*)hContact;
+ Push(pReq);
+ return 0;
+}
+
+MCONTACT CDiscordProto::AddToList(int flags, PROTOSEARCHRESULT *psr)
+{
+ if (psr->id.w == NULL)
+ return 0;
+
+ wchar_t *p = wcschr(psr->id.w, '#');
+ if (p == NULL)
+ return 0;
+
+ MCONTACT hContact = db_add_contact();
+ Proto_AddToContact(hContact, m_szModuleName);
+ if (flags & PALF_TEMPORARY)
+ db_set_b(hContact, "CList", "NotOnList", 1);
+
+ *p = 0;
+ CDiscordUser *pUser = new CDiscordUser(0);
+ pUser->hContact = hContact;
+ pUser->wszUsername = psr->id.w;
+ pUser->iDiscriminator = _wtoi(p + 1);
+ *p = '#';
+
+ setWString(hContact, DB_KEY_NICK, pUser->wszUsername);
+ setDword(hContact, DB_KEY_DISCR, pUser->iDiscriminator);
+
+ return hContact;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
int CDiscordProto::OnModulesLoaded(WPARAM, LPARAM)
{
return 0;