summaryrefslogtreecommitdiff
path: root/protocols
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2021-04-17 18:44:57 +0300
committerGeorge Hazan <ghazan@miranda.im>2021-04-17 18:45:04 +0300
commitdaa4afc8e433fe9c9efd74f381df954591fded70 (patch)
treef371997f5bdb79950b4ccb55098eb675726371d6 /protocols
parent4436a046a3cf90234ea19dae5e6c8d9906f2d79a (diff)
WhatsApp: basic contacts operations + block list analysis
Diffstat (limited to 'protocols')
-rw-r--r--protocols/WhatsAppWeb/WhatsAppWeb.vcxproj1
-rw-r--r--protocols/WhatsAppWeb/WhatsAppWeb.vcxproj.filters3
-rw-r--r--protocols/WhatsAppWeb/src/proto.cpp61
-rw-r--r--protocols/WhatsAppWeb/src/proto.h39
-rw-r--r--protocols/WhatsAppWeb/src/server.cpp11
-rw-r--r--protocols/WhatsAppWeb/src/stdafx.h4
-rw-r--r--protocols/WhatsAppWeb/src/utils.cpp36
7 files changed, 119 insertions, 36 deletions
diff --git a/protocols/WhatsAppWeb/WhatsAppWeb.vcxproj b/protocols/WhatsAppWeb/WhatsAppWeb.vcxproj
index ccc8d2ae3a..9439401cf7 100644
--- a/protocols/WhatsAppWeb/WhatsAppWeb.vcxproj
+++ b/protocols/WhatsAppWeb/WhatsAppWeb.vcxproj
@@ -51,6 +51,7 @@
<ClCompile Include="src\stdafx.cxx">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
+ <ClCompile Include="src\utils.cpp" />
<ClInclude Include="src\db.h" />
<ClInclude Include="src\proto.h" />
<ClInclude Include="src\resource.h" />
diff --git a/protocols/WhatsAppWeb/WhatsAppWeb.vcxproj.filters b/protocols/WhatsAppWeb/WhatsAppWeb.vcxproj.filters
index 81c15c821b..956e44e8eb 100644
--- a/protocols/WhatsAppWeb/WhatsAppWeb.vcxproj.filters
+++ b/protocols/WhatsAppWeb/WhatsAppWeb.vcxproj.filters
@@ -23,6 +23,9 @@
<ClCompile Include="src\qrcode.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="src\utils.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\db.h">
diff --git a/protocols/WhatsAppWeb/src/proto.cpp b/protocols/WhatsAppWeb/src/proto.cpp
index 19eeddc602..6afd3da618 100644
--- a/protocols/WhatsAppWeb/src/proto.cpp
+++ b/protocols/WhatsAppWeb/src/proto.cpp
@@ -17,10 +17,17 @@ struct SearchParam
LONG id;
};
-WhatsAppProto::WhatsAppProto(const char *proto_name, const wchar_t *username)
- : PROTO<WhatsAppProto>(proto_name, username),
+static int CompareUsers(const WAUser *p1, const WAUser *p2)
+{
+ return strcmp(p1->szId, p2->szId);
+}
+
+WhatsAppProto::WhatsAppProto(const char *proto_name, const wchar_t *username) :
+ PROTO<WhatsAppProto>(proto_name, username),
m_tszDefaultGroup(getWStringA(DBKEY_DEF_GROUP)),
- m_arPacketQueue(10, NumericKeySortT)
+ m_arUsers(10, CompareUsers),
+ m_arPacketQueue(10, NumericKeySortT),
+ m_wszDefaultGroup(this, "DefaultGroup", L"WhatsApp")
{
db_set_resident(m_szModuleName, "StatusMsg");
@@ -73,13 +80,29 @@ WhatsAppProto::~WhatsAppProto()
{
}
+/////////////////////////////////////////////////////////////////////////////////////////
+// OnModulesLoaded emulator for an account
+
+void WhatsAppProto::OnModulesLoaded()
+{
+ // initialize contacts cache
+ for (auto &cc : AccContacts()) {
+ CMStringA szId(getMStringA(cc, DBKEY_ID));
+ if (!szId.IsEmpty())
+ m_arUsers.insert(new WAUser(cc, szId));
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// PROTO_INTERFACE implementation
+
MCONTACT WhatsAppProto::AddToList(int flags, PROTOSEARCHRESULT *psr)
{
if (psr->id.w == nullptr)
return NULL;
std::string phone(T2Utf(psr->id.w));
- std::string jid(phone + "@s.whatsapp.net");
+ std::string jid(phone + "@c.us");
/* MCONTACT hContact = AddToContactList(jid, phone.c_str());
if (!(flags & PALF_TEMPORARY))
@@ -92,7 +115,7 @@ INT_PTR WhatsAppProto::GetCaps(int type, MCONTACT)
{
switch (type) {
case PFLAGNUM_1:
- return PF1_IM | PF1_FILESEND | PF1_CHAT | PF1_BASICSEARCH | PF1_ADDSEARCHRES | PF1_MODEMSGRECV;
+ return PF1_IM | PF1_FILE | PF1_CHAT | PF1_BASICSEARCH | PF1_ADDSEARCHRES | PF1_MODEMSGRECV;
case PFLAGNUM_2:
return PF2_ONLINE | PF2_INVISIBLE;
case PFLAGNUM_3:
@@ -162,7 +185,7 @@ int WhatsAppProto::SetStatus(int new_status)
int WhatsAppProto::SendMsg(MCONTACT hContact, int, const char *msg)
{
- ptrA jid(getStringA(hContact, "ID"));
+ ptrA jid(getStringA(hContact, DBKEY_ID));
if (jid == NULL)
return 0;
@@ -186,13 +209,14 @@ int WhatsAppProto::UserIsTyping(MCONTACT hContact, int type)
}
/////////////////////////////////////////////////////////////////////////////////////////
+// contacts search
void WhatsAppProto::SearchAckThread(void *targ)
{
Sleep(100);
SearchParam *param = (SearchParam*)targ;
- PROTOSEARCHRESULT psr = { 0 };
+ PROTOSEARCHRESULT psr = {};
psr.cbSize = sizeof(psr);
psr.flags = PSR_UNICODE;
psr.nick.w = psr.firstName.w = psr.lastName.w = L"";
@@ -218,27 +242,6 @@ HANDLE WhatsAppProto::SearchBasic(const wchar_t* id)
//////////////////////////////////////////////////////////////////////////////
// EVENTS
-int WhatsAppProto::OnUserInfo(WPARAM, LPARAM hContact)
-{
-/* ptrA jid(getStringA(hContact, WHATSAPP_KEY_ID));
- if (jid && isOnline()) {
- m_pConnection->sendGetPicture((char*)jid, "image");
- m_pConnection->sendPresenceSubscriptionRequest((char*)jid);
- }
-*/
- return 0;
-}
-
-void WhatsAppProto::RequestFriendship(MCONTACT hContact)
-{
- if (hContact == NULL || isOffline())
- return;
-
-/* ptrA jid(getStringA(hContact, WHATSAPP_KEY_ID));
- if (jid)
- m_pConnection->sendPresenceSubscriptionRequest((char*)jid); */
-}
-
LRESULT CALLBACK PopupDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
@@ -258,4 +261,4 @@ LRESULT CALLBACK PopupDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
}
return DefWindowProc(hwnd, message, wParam, lParam);
-};
+}
diff --git a/protocols/WhatsAppWeb/src/proto.h b/protocols/WhatsAppWeb/src/proto.h
index 1d80ec328f..1ba9d27257 100644
--- a/protocols/WhatsAppWeb/src/proto.h
+++ b/protocols/WhatsAppWeb/src/proto.h
@@ -32,6 +32,22 @@ struct WARequest
WA_PKT_HANDLER pHandler;
};
+struct WAUser
+{
+ WAUser(MCONTACT _1, const char *_2) :
+ hContact(_1),
+ szId(mir_strdup(_2))
+ {}
+
+ ~WAUser()
+ {
+ mir_free(szId);
+ }
+
+ MCONTACT hContact;
+ char *szId;
+};
+
class WhatsAppProto : public PROTO<WhatsAppProto>
{
bool m_bTerminated, m_bOnline;
@@ -40,10 +56,19 @@ class WhatsAppProto : public PROTO<WhatsAppProto>
CMStringA m_szJid, m_szClientId, m_szClientToken;
CMStringW m_tszAvatarFolder;
+ EVP_PKEY *m_pKeys; // private & public keys
MBinBuffer mac_key, enc_key;
bool getBlob(const char *pSetting, MBinBuffer &buf);
- EVP_PKEY *m_pKeys; // private & public keys
+ // Contacts management /////////////////////////////////////////////////////////////////
+
+ mir_cs m_csUsers;
+ OBJLIST<WAUser> m_arUsers;
+
+ WAUser* FindUser(const char *szId);
+ WAUser* AddUser(const char *szId, bool bTemporary);
+
+ // UI //////////////////////////////////////////////////////////////////////////////////
void CloseQrDialog();
bool ShowQrCode(const CMStringA &ref);
@@ -75,6 +100,7 @@ class WhatsAppProto : public PROTO<WhatsAppProto>
void OnStartSession(const JSONNode &node);
void ProcessPacket(const JSONNode &node);
+ void ProcessBlocked(const JSONNode &node);
void ProcessCmd(const JSONNode &node);
void ProcessConn(const JSONNode &node);
@@ -113,6 +139,8 @@ public:
int SetStatus(int iNewStatus) override;
int UserIsTyping(MCONTACT hContact, int type) override;
+ void OnModulesLoaded() override;
+
// Services ////////////////////////////////////////////////////////////////////////////
INT_PTR __cdecl SvcCreateAccMgrUI(WPARAM, LPARAM);
@@ -120,17 +148,16 @@ public:
// Events //////////////////////////////////////////////////////////////////////////////
int __cdecl OnOptionsInit(WPARAM, LPARAM);
- int __cdecl OnUserInfo(WPARAM, LPARAM);
int __cdecl OnBuildStatusMenu(WPARAM, LPARAM);
+ // Options /////////////////////////////////////////////////////////////////////////////
+
+ CMOption<wchar_t*> m_wszDefaultGroup; // clist group to store contacts
+
// Processing Threads //////////////////////////////////////////////////////////////////
void __cdecl SearchAckThread(void*);
void __cdecl ServerThread(void*);
-
- // Contacts handling ///////////////////////////////////////////////////////////////////
-
- void RequestFriendship(MCONTACT hContact);
};
struct CMPlugin : public ACCPROTOPLUGIN<WhatsAppProto>
diff --git a/protocols/WhatsAppWeb/src/server.cpp b/protocols/WhatsAppWeb/src/server.cpp
index ca470d9279..e46a3b62a6 100644
--- a/protocols/WhatsAppWeb/src/server.cpp
+++ b/protocols/WhatsAppWeb/src/server.cpp
@@ -413,6 +413,17 @@ void WhatsAppProto::ProcessPacket(const JSONNode &root)
ProcessConn(content);
else if (szType == "Cmd")
ProcessCmd(content);
+ else if (szType == "Blocklist")
+ ProcessBlocked(content);
+}
+
+void WhatsAppProto::ProcessBlocked(const JSONNode &node)
+{
+ for (auto &it : node["blocklist"]) {
+ auto *pUser = AddUser(it.as_string().c_str(), false);
+ Ignore_Ignore(pUser->hContact, IGNOREEVENT_ALL);
+ Contact_RemoveFromList(pUser->hContact);
+ }
}
void WhatsAppProto::ProcessCmd(const JSONNode &root)
diff --git a/protocols/WhatsAppWeb/src/stdafx.h b/protocols/WhatsAppWeb/src/stdafx.h
index ba0d248a5a..c831328858 100644
--- a/protocols/WhatsAppWeb/src/stdafx.h
+++ b/protocols/WhatsAppWeb/src/stdafx.h
@@ -10,6 +10,7 @@ Copyright © 2019-21 George Hazan
#pragma warning(disable:4996)
#pragma warning(disable:4290)
+#include <malloc.h>
#include <time.h>
#include <windows.h>
@@ -17,6 +18,7 @@ Copyright © 2019-21 George Hazan
#include <m_avatars.h>
#include <m_chat.h>
#include <m_clist.h>
+#include <m_contacts.h>
#include <m_database.h>
#include <m_history.h>
#include <m_imgsrvc.h>
@@ -77,4 +79,4 @@ struct ec_private_key : public signal_type_base
#include "proto.h"
#include "resource.h"
-#pragma comment(lib, "libcrypto.lib") \ No newline at end of file
+#pragma comment(lib, "libcrypto.lib")
diff --git a/protocols/WhatsAppWeb/src/utils.cpp b/protocols/WhatsAppWeb/src/utils.cpp
new file mode 100644
index 0000000000..49ece0557a
--- /dev/null
+++ b/protocols/WhatsAppWeb/src/utils.cpp
@@ -0,0 +1,36 @@
+/*
+
+WhatsAppWeb plugin for Miranda NG
+Copyright © 2019 George Hazan
+
+*/
+
+#include "stdafx.h"
+
+WAUser* WhatsAppProto::FindUser(const char *szId)
+{
+ mir_cslock lck(m_csUsers);
+ auto *tmp = (WAUser *)_alloca(sizeof(WAUser));
+ tmp->szId = (char*)szId;
+ return m_arUsers.find(tmp);
+}
+
+WAUser* WhatsAppProto::AddUser(const char *szId, bool bTemporary)
+{
+ auto *pUser = FindUser(szId);
+ if (pUser != nullptr)
+ return pUser;
+
+ MCONTACT hContact = db_add_contact();
+ Proto_AddToContact(hContact, m_szModuleName);
+ setString(hContact, DBKEY_ID, szId);
+ pUser = new WAUser(hContact, mir_strdup(szId));
+ if (bTemporary)
+ Contact_RemoveFromList(hContact);
+ if (m_wszDefaultGroup)
+ Clist_SetGroup(hContact, m_wszDefaultGroup);
+
+ mir_cslock lck(m_csUsers);
+ m_arUsers.insert(pUser);
+ return pUser;
+}