summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2019-10-07 20:40:13 +0300
committerGeorge Hazan <ghazan@miranda.im>2019-10-07 20:40:20 +0300
commit8d0500df234fc5b59ea7687bd5f55f19d7b8e28c (patch)
treea090b606b6e5fa25574c4836121cebae667de5cb
parent5ffd6fe3ab6f29444c699720b9ea588b57313c27 (diff)
WhatsAppWeb: QR code viewer
-rw-r--r--protocols/WhatsAppWeb/WhatsAppWeb.vcxproj11
-rw-r--r--protocols/WhatsAppWeb/WhatsAppWeb.vcxproj.filters53
-rw-r--r--protocols/WhatsAppWeb/res/version.rc48
-rw-r--r--protocols/WhatsAppWeb/res/whatsapp.rc118
-rw-r--r--protocols/WhatsAppWeb/src/avatars.cpp13
-rw-r--r--protocols/WhatsAppWeb/src/db.h61
-rw-r--r--protocols/WhatsAppWeb/src/main.cpp14
-rw-r--r--protocols/WhatsAppWeb/src/options.cpp8
-rw-r--r--protocols/WhatsAppWeb/src/proto.cpp68
-rw-r--r--protocols/WhatsAppWeb/src/proto.h31
-rw-r--r--protocols/WhatsAppWeb/src/resource.h8
-rw-r--r--protocols/WhatsAppWeb/src/server.cpp151
-rw-r--r--protocols/WhatsAppWeb/src/stdafx.cxx12
-rw-r--r--protocols/WhatsAppWeb/src/stdafx.h21
-rw-r--r--protocols/WhatsAppWeb/src/version.h2
15 files changed, 446 insertions, 173 deletions
diff --git a/protocols/WhatsAppWeb/WhatsAppWeb.vcxproj b/protocols/WhatsAppWeb/WhatsAppWeb.vcxproj
index ac48c7237b..276ea52570 100644
--- a/protocols/WhatsAppWeb/WhatsAppWeb.vcxproj
+++ b/protocols/WhatsAppWeb/WhatsAppWeb.vcxproj
@@ -18,6 +18,17 @@
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\libs\libqrencode\libqrencode.vcxproj">
+ <Project>{4d3554de-6e14-4f94-a909-a4b19151a47e}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\..\libs\libsignal\libsignal.vcxproj">
+ <Project>{620e0be7-3763-4f35-9dbd-4770104e269c}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Image Include="res\whatsapp.ico" />
+ </ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{13E796AD-BEA4-4213-A1B8-E18E2397E544}</ProjectGuid>
<ProjectName>WhatsAppWeb</ProjectName>
diff --git a/protocols/WhatsAppWeb/WhatsAppWeb.vcxproj.filters b/protocols/WhatsAppWeb/WhatsAppWeb.vcxproj.filters
index fcae13a9d8..e9b9de29a9 100644
--- a/protocols/WhatsAppWeb/WhatsAppWeb.vcxproj.filters
+++ b/protocols/WhatsAppWeb/WhatsAppWeb.vcxproj.filters
@@ -1,4 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(ProjectDir)..\..\build\vc.common\common.filters" />
+ <ItemGroup>
+ <ClCompile Include="src\stdafx.cxx">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\*.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\*.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\*.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\*.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\*.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="src\*.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\*.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\*.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\*.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\*.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="res\*.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ <ResourceCompile Include="res\whatsapp.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ <ResourceCompile Include="res\*.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <Image Include="res\whatsapp.ico">
+ <Filter>Resource Files</Filter>
+ </Image>
+ </ItemGroup>
</Project> \ No newline at end of file
diff --git a/protocols/WhatsAppWeb/res/version.rc b/protocols/WhatsAppWeb/res/version.rc
index 37934706a0..5a5ddd63ed 100644
--- a/protocols/WhatsAppWeb/res/version.rc
+++ b/protocols/WhatsAppWeb/res/version.rc
@@ -6,50 +6,4 @@
#include "..\src\version.h"
-#define APSTUDIO_READONLY_SYMBOLS
-#include "afxres.h"
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// English (U.S.) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-#ifdef _WIN32
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-#pragma code_page(1252)
-#endif //_WIN32
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION __FILEVERSION_STRING
- PRODUCTVERSION __FILEVERSION_STRING
- FILEFLAGSMASK 0x17L
-#ifdef _DEBUG
- FILEFLAGS 0x1L
-#else
- FILEFLAGS 0x0L
-#endif
- FILEOS 0x4L
- FILETYPE 0x2L
- FILESUBTYPE 0x0L
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "000004b0"
- BEGIN
- VALUE "Author", __AUTHOR
- VALUE "FileDescription", __DESCRIPTION
- VALUE "FileVersion", __VERSION_STRING
- VALUE "InternalName", __PLUGIN_NAME
- VALUE "LegalCopyright", __COPYRIGHT
- VALUE "OriginalFilename", __FILENAME
- VALUE "ProductName", __PLUGIN_NAME
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x0, 1200
- END
-END
-
-#endif // English (U.S.) resources
-/////////////////////////////////////////////////////////////////////////////
+#include "..\..\build\Version.rc"
diff --git a/protocols/WhatsAppWeb/res/whatsapp.rc b/protocols/WhatsAppWeb/res/whatsapp.rc
index e3d3cba800..b8718da79e 100644
--- a/protocols/WhatsAppWeb/res/whatsapp.rc
+++ b/protocols/WhatsAppWeb/res/whatsapp.rc
@@ -1,5 +1,7 @@
// Microsoft Visual C++ generated resource script.
//
+#pragma code_page(65001)
+
#include "..\src\resource.h"
#define APSTUDIO_READONLY_SYMBOLS
@@ -13,60 +15,25 @@
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
-// German (Germany) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
-LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
-#pragma code_page(1252)
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE
-BEGIN
- "..\\src\\resource.h\0"
-END
-
-2 TEXTINCLUDE
-BEGIN
- "#include ""afxres.h""\r\n"
- "\0"
-END
-
-3 TEXTINCLUDE
-BEGIN
- "\r\n"
- "\0"
-END
-
-#endif // APSTUDIO_INVOKED
+// English (United States) resources
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
/////////////////////////////////////////////////////////////////////////////
//
-// DESIGNINFO
+// Dialog
//
-#ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO
+IDD_SHOWQR DIALOGEX 0, 0, 318, 335
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Dialog"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
- IDD_WHATSAPOPTIONS, DIALOG
- BEGIN
- VERTGUIDE, 60
- VERTGUIDE, 178
- BOTTOMMARGIN, 126
- END
+ CONTROL "",IDC_QRPIC,"Static",SS_BITMAP | SS_NOTIFY | SS_CENTERIMAGE | SS_REALSIZEIMAGE | SS_SUNKEN,7,7,304,304
+ DEFPUSHBUTTON "OK",IDOK,205,316,50,14
+ PUSHBUTTON "Cancel",IDCANCEL,261,316,50,14
END
-#endif // APSTUDIO_INVOKED
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Dialog
-//
IDD_ACCMGRUI DIALOGEX 0, 0, 188, 144
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
@@ -81,7 +48,7 @@ BEGIN
LTEXT "Default group:",IDC_STATIC,4,37,55,10
EDITTEXT IDC_DEFGROUP,60,36,124,12,ES_AUTOHSCROLL
CONTROL "Use SSL connection (port 443)",IDC_SSL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,52,180,10
- CONTROL "Use remote message timestamps", IDC_REMOTE_TIME, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 4, 64, 180, 10
+ CONTROL "Use remote message timestamps",IDC_REMOTE_TIME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,64,180,10
CONTROL "Automatically open group chats",IDC_AUTORUN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,76,180,10
GROUPBOX "Registration",IDC_STATIC,4,92,184,48
LTEXT "Enter code",IDC_STATIC,8,123,47,10
@@ -107,7 +74,7 @@ BEGIN
LTEXT "Default group:",IDC_STATIC,4,57,55,10
EDITTEXT IDC_DEFGROUP,60,56,124,12,ES_AUTOHSCROLL
CONTROL "Use SSL connection (port 443)",IDC_SSL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,72,180,10
- CONTROL "Use remote message timestamps", IDC_REMOTE_TIME, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 4, 84, 180, 10
+ CONTROL "Use remote message timestamps",IDC_REMOTE_TIME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,84,180,10
CONTROL "Automatically open group chats",IDC_AUTORUN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,96,180,10
GROUPBOX "Registration",IDC_STATIC,4,112,184,48
LTEXT "Enter code",IDC_STATIC,8,143,47,10
@@ -142,7 +109,60 @@ END
// remains consistent on all systems.
IDI_WHATSAPP ICON "whatsapp.ico"
-#endif // German (Germany) resources
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "..\\src\\resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_SHOWQR, DIALOG
+ BEGIN
+ BOTTOMMARGIN, 330
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// AFX_DIALOG_LAYOUT
+//
+
+IDD_SHOWQR AFX_DIALOG_LAYOUT
+BEGIN
+ 0
+END
+
+#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
diff --git a/protocols/WhatsAppWeb/src/avatars.cpp b/protocols/WhatsAppWeb/src/avatars.cpp
index cacd251639..5c85c437d8 100644
--- a/protocols/WhatsAppWeb/src/avatars.cpp
+++ b/protocols/WhatsAppWeb/src/avatars.cpp
@@ -1,10 +1,17 @@
+/*
+
+WhatsAppWeb plugin for Miranda NG
+Copyright © 2019 George Hazan
+
+*/
+
#include "stdafx.h"
INT_PTR WhatsAppProto::GetAvatarInfo(WPARAM wParam, LPARAM lParam)
{
PROTO_AVATAR_INFORMATION *pai = (PROTO_AVATAR_INFORMATION*)lParam;
- ptrA id(getStringA(pai->hContact, isChatRoom(pai->hContact) ? "ChatRoomID" : WHATSAPP_KEY_ID));
+ ptrA id(getStringA(pai->hContact, isChatRoom(pai->hContact) ? "ChatRoomID" : DBKEY_ID));
if (id == NULL)
return GAIR_NOAVATAR;
@@ -12,7 +19,7 @@ INT_PTR WhatsAppProto::GetAvatarInfo(WPARAM wParam, LPARAM lParam)
wcsncpy_s(pai->filename, tszFileName.c_str(), _TRUNCATE);
pai->format = PA_FORMAT_JPEG;
- ptrA szAvatarId(getStringA(pai->hContact, WHATSAPP_KEY_AVATAR_ID));
+ ptrA szAvatarId(getStringA(pai->hContact, DBKEY_AVATAR_ID));
if (szAvatarId == NULL || (wParam & GAIF_FORCE) != 0)
if (pai->hContact != NULL && isOnline()) {
// m_pConnection->sendGetPicture(id, "image");
@@ -50,7 +57,7 @@ CMStringW WhatsAppProto::GetAvatarFileName(MCONTACT hContact)
CMStringA jid;
if (hContact != NULL) {
- ptrA szId(getStringA(hContact, isChatRoom(hContact) ? "ChatRoomID" : WHATSAPP_KEY_ID));
+ ptrA szId(getStringA(hContact, isChatRoom(hContact) ? "ChatRoomID" : DBKEY_ID));
if (szId == NULL)
return L"";
diff --git a/protocols/WhatsAppWeb/src/db.h b/protocols/WhatsAppWeb/src/db.h
index 3c73fb18e7..97dc165324 100644
--- a/protocols/WhatsAppWeb/src/db.h
+++ b/protocols/WhatsAppWeb/src/db.h
@@ -1,35 +1,34 @@
+/*
+
+WhatsAppWeb plugin for Miranda NG
+Copyright © 2019 George Hazan
+
+*/
+
#define MODULENAME "WhatsApp"
// DB keys
-#define WHATSAPP_KEY_ID "ID"
-#define WHATSAPP_KEY_LOGIN "Login"
-#define WHATSAPP_KEY_CC "CountryCode"
-#define WHATSAPP_KEY_NICK "Nick"
-#define WHATSAPP_KEY_PASS "Password"
-#define WHATSAPP_KEY_IDX "DeviceID"
-#define WHATSAPP_KEY_MAP_STATUSES "MapStatuses"
-#define WHATSAPP_KEY_LOGGING_ENABLE "LoggingEnable"
-#define WHATSAPP_KEY_NAME "RealName"
-#define WHATSAPP_KEY_LAST_SEEN "LastSeen"
-#define WHATSAPP_KEY_LAST_SEEN_DENIED "LastSeenDenied"
-#define WHATSAPP_KEY_AVATAR_ID "AvatarId"
-#define WHATSAPP_KEY_SYSTRAY_NOTIFY "UseSystrayNotify"
-#define WHATSAPP_KEY_DEF_GROUP "DefaultGroup"
-#define WHATSAPP_KEY_REG_CODE "RegistrationCode"
-#define WHATSAPP_KEY_SSL "UseSSL"
-#define WHATSAPP_KEY_AUTORUNCHATS "AutoRunChats"
-#define WHATSAPP_KEY_USE_REMOTE_TIME "UseRemoteTime"
-
-#define WHATSAPP_KEY_EVENT_CLIENT_ENABLE "EventClientEnable"
-#define WHATSAPP_KEY_EVENT_OTHER_ENABLE "EventOtherEnable"
-
-#define WHATSAPP_KEY_EVENT_CLIENT_COLBACK "PopupClientColorBack"
-#define WHATSAPP_KEY_EVENT_CLIENT_COLTEXT "PopupClientColorText"
-#define WHATSAPP_KEY_EVENT_CLIENT_TIMEOUT "PopupClientTimeout"
-#define WHATSAPP_KEY_EVENT_CLIENT_DEFAULT "PopupClientColorDefault"
-
-#define WHATSAPP_KEY_EVENT_OTHER_COLBACK "PopupOtherColorBack"
-#define WHATSAPP_KEY_EVENT_OTHER_COLTEXT "PopupOtherColorText"
-#define WHATSAPP_KEY_EVENT_OTHER_TIMEOUT "PopupOtherTimeout"
-#define WHATSAPP_KEY_EVENT_OTHER_DEFAULT "PopupOtherColorDefault"
+#define DBKEY_ID "ID"
+#define DBKEY_LOGIN "Login"
+#define DBKEY_CC "CountryCode"
+
+#define DBKEY_CLIENT_ID "ClientId"
+#define DBKEY_CLIENT_SECRET "ClientSecret"
+#define DBKEY_PUBKEY "PublicKey"
+#define DBKEY_PRIVATEKEY "PrivateKey"
+
+#define DBKEY_NAME "RealName"
+#define DBKEY_DEF_GROUP "DefaultGroup"
+#define DBKEY_AUTORUNCHATS "AutoRunChats"
+#define DBKEY_AVATAR_ID "AvatarId"
+
+#define DBKEY_EVENT_CLIENT_COLBACK "PopupClientColorBack"
+#define DBKEY_EVENT_CLIENT_COLTEXT "PopupClientColorText"
+#define DBKEY_EVENT_CLIENT_TIMEOUT "PopupClientTimeout"
+#define DBKEY_EVENT_CLIENT_DEFAULT "PopupClientColorDefault"
+
+#define DBKEY_EVENT_OTHER_COLBACK "PopupOtherColorBack"
+#define DBKEY_EVENT_OTHER_COLTEXT "PopupOtherColorText"
+#define DBKEY_EVENT_OTHER_TIMEOUT "PopupOtherTimeout"
+#define DBKEY_EVENT_OTHER_DEFAULT "PopupOtherColorDefault"
diff --git a/protocols/WhatsAppWeb/src/main.cpp b/protocols/WhatsAppWeb/src/main.cpp
index f414c61c19..0f63d3ba80 100644
--- a/protocols/WhatsAppWeb/src/main.cpp
+++ b/protocols/WhatsAppWeb/src/main.cpp
@@ -1,3 +1,10 @@
+/*
+
+WhatsAppWeb plugin for Miranda NG
+Copyright © 2019 George Hazan
+
+*/
+
#include "stdafx.h"
#include "version.h"
@@ -12,9 +19,8 @@ PLUGININFOEX pluginInfo = {
__AUTHOREMAIL,
__COPYRIGHT,
UNICODE_AWARE, //not transient
- // {4f1ff7fa-4d75-44b9-93b0-2ced2e4f9e3e}
- { 0x4f1ff7fa, 0x4d75, 0x44b9, { 0x93, 0xb0, 0x2c, 0xed, 0x2e, 0x4f, 0x9e, 0x3e } }
-
+ // {008B9CE1-154B-44E4-9823-97C1AAB00C3C}
+ { 0x8b9ce1, 0x154b, 0x44e4, { 0x98, 0x23, 0x97, 0xc1, 0xaa, 0xb0, 0xc, 0x3c }}
};
/////////////////////////////////////////////////////////////////////////////////////////
@@ -27,7 +33,7 @@ extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_PROTOC
CMPlugin::CMPlugin() :
ACCPROTOPLUGIN<WhatsAppProto>(MODULENAME, pluginInfo)
{
- SetUniqueId(WHATSAPP_KEY_ID);
+ SetUniqueId(DBKEY_ID);
}
/////////////////////////////////////////////////////////////////////////////////////////
diff --git a/protocols/WhatsAppWeb/src/options.cpp b/protocols/WhatsAppWeb/src/options.cpp
new file mode 100644
index 0000000000..07cbd9967a
--- /dev/null
+++ b/protocols/WhatsAppWeb/src/options.cpp
@@ -0,0 +1,8 @@
+/*
+
+WhatsAppWeb plugin for Miranda NG
+Copyright © 2019 George Hazan
+
+*/
+
+#include "stdafx.h"
diff --git a/protocols/WhatsAppWeb/src/proto.cpp b/protocols/WhatsAppWeb/src/proto.cpp
index ac7a5b2bff..a29e50d06f 100644
--- a/protocols/WhatsAppWeb/src/proto.cpp
+++ b/protocols/WhatsAppWeb/src/proto.cpp
@@ -1,3 +1,10 @@
+/*
+
+WhatsAppWeb plugin for Miranda NG
+Copyright © 2019 George Hazan
+
+*/
+
#include "stdafx.h"
struct SearchParam
@@ -12,7 +19,7 @@ struct SearchParam
WhatsAppProto::WhatsAppProto(const char *proto_name, const wchar_t *username)
: PROTO<WhatsAppProto>(proto_name, username),
- m_tszDefaultGroup(getWStringA(WHATSAPP_KEY_DEF_GROUP))
+ m_tszDefaultGroup(getWStringA(DBKEY_DEF_GROUP))
{
db_set_resident(m_szModuleName, "StatusMsg");
@@ -26,6 +33,16 @@ WhatsAppProto::WhatsAppProto(const char *proto_name, const wchar_t *username)
// HookProtoEvent(ME_OPT_INITIALISE, &WhatsAppProto::OnOptionsInit);
// HookProtoEvent(ME_CLIST_PREBUILDSTATUSMENU, &WhatsAppProto::OnBuildStatusMenu);
+ // Client id generation
+ m_szClientId = getMStringA(DBKEY_CLIENT_ID);
+ if (m_szClientId.IsEmpty()) {
+ int8_t randBytes[16];
+ Utils_GetRandom(randBytes, sizeof(randBytes));
+
+ m_szClientId = ptrA(mir_base64_encode(randBytes, sizeof(randBytes)));
+ setString(DBKEY_CLIENT_ID, m_szClientId);
+ }
+
// Create standard network connection
wchar_t descr[512];
mir_snwprintf(descr, TranslateT("%s server connection"), m_tszUserName);
@@ -55,6 +72,21 @@ WhatsAppProto::~WhatsAppProto()
{
}
+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");
+
+ /* MCONTACT hContact = AddToContactList(jid, phone.c_str());
+ if (!(flags & PALF_TEMPORARY))
+ db_unset(hContact, "CList", "NotOnList");
+
+ return hContact;*/
+}
+
INT_PTR WhatsAppProto::GetCaps(int type, MCONTACT)
{
switch (type) {
@@ -103,30 +135,30 @@ int WhatsAppProto::SetStatus(int new_status)
m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus);
}
- else if (!IsStatusConnecting(m_iStatus)) {
+ else if (m_pConn == nullptr && !IsStatusConnecting(m_iStatus)) {
m_iStatus = ID_STATUS_CONNECTING;
ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus);
+
+ ForkThread(&WhatsAppProto::ServerThread);
+ }
+ else if (m_pConn != nullptr) {
+ if (m_iDesiredStatus == ID_STATUS_ONLINE) {
+ // m_pConn->sendAvailableForChat();
+ m_iStatus = ID_STATUS_ONLINE;
+ ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus);
+ }
+ else if (m_iStatus == ID_STATUS_ONLINE && m_iDesiredStatus == ID_STATUS_INVISIBLE) {
+ // m_pConn->sendClose();
+ m_iStatus = ID_STATUS_INVISIBLE;
+ setAllContactStatuses(ID_STATUS_OFFLINE);
+ ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus);
+ }
}
else ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus);
return 0;
}
-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");
-
-/* MCONTACT hContact = AddToContactList(jid, phone.c_str());
- if (!(flags & PALF_TEMPORARY))
- db_unset(hContact, "CList", "NotOnList");
-
- return hContact;*/
-}
-
int WhatsAppProto::SendMsg(MCONTACT hContact, int, const char *msg)
{
ptrA jid(getStringA(hContact, "ID"));
@@ -144,7 +176,7 @@ int WhatsAppProto::SendMsg(MCONTACT hContact, int, const char *msg)
int WhatsAppProto::UserIsTyping(MCONTACT hContact, int type)
{
if (hContact && isOnline()) {
- ptrA jid(getStringA(hContact, WHATSAPP_KEY_ID));
+ ptrA jid(getStringA(hContact, DBKEY_ID));
if (jid && isOnline()) {
}
}
diff --git a/protocols/WhatsAppWeb/src/proto.h b/protocols/WhatsAppWeb/src/proto.h
index 564a31eb2e..610313ab0e 100644
--- a/protocols/WhatsAppWeb/src/proto.h
+++ b/protocols/WhatsAppWeb/src/proto.h
@@ -1,3 +1,10 @@
+/*
+
+WhatsAppWeb plugin for Miranda NG
+Copyright © 2019 George Hazan
+
+*/
+
#if !defined(PROTO_H)
#define PROTO_H
@@ -15,13 +22,22 @@ struct WAChatInfo
MCONTACT hContact;
};
+struct WAConnection : public MZeroedObject
+{
+ EVP_PKEY *m_pKeys; // private & public keys
+};
+
class WhatsAppProto : public PROTO<WhatsAppProto>
{
ptrW m_tszDefaultGroup;
- CMStringA m_szJid;
+ CMStringA m_szJid, m_szClientId;
CMStringW m_tszAvatarFolder;
+ WAConnection *m_pConn;
+
+ bool ShowQrCode(void);
+
/// Avatars //////////////////////////////////////////////////////////////////////////
CMStringW GetAvatarFileName(MCONTACT hContact);
@@ -48,12 +64,12 @@ public:
// PROTO_INTERFACE ///////////////////////////////////////////////////////////////////
- MCONTACT __cdecl AddToList(int flags, PROTOSEARCHRESULT *psr) override;
- INT_PTR __cdecl GetCaps(int type, MCONTACT hContact = NULL) override;
- HANDLE __cdecl SearchBasic(const wchar_t* id) override;
- int __cdecl SendMsg(MCONTACT hContact, int flags, const char* msg) override;
- int __cdecl SetStatus(int iNewStatus) override;
- int __cdecl UserIsTyping(MCONTACT hContact, int type) override;
+ MCONTACT AddToList(int flags, PROTOSEARCHRESULT *psr) override;
+ INT_PTR GetCaps(int type, MCONTACT hContact = NULL) override;
+ HANDLE SearchBasic(const wchar_t* id) override;
+ int SendMsg(MCONTACT hContact, int flags, const char* msg) override;
+ int SetStatus(int iNewStatus) override;
+ int UserIsTyping(MCONTACT hContact, int type) override;
// Services //////////////////////////////////////////////////////////////////////////
@@ -74,6 +90,7 @@ public:
void __cdecl ProcessBuddyList(void*);
void __cdecl SearchAckThread(void*);
+ void __cdecl ServerThread(void*);
// Contacts handling /////////////////////////////////////////////////////////////////
diff --git a/protocols/WhatsAppWeb/src/resource.h b/protocols/WhatsAppWeb/src/resource.h
index 67e976f3ca..42d8bf91fd 100644
--- a/protocols/WhatsAppWeb/src/resource.h
+++ b/protocols/WhatsAppWeb/src/resource.h
@@ -1,12 +1,13 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
-// Used by ..\res\whatsapp.rc
+// Used by w:\miranda-ng\protocols\WhatsAppWeb\res\whatsapp.rc
//
#define IDD_INPUTBOX 102
#define IDR_REGISTERUTILITY 103
#define IDD_ACCMGRUI 104
#define IDD_GROUPCHAT_INVITE 105
#define IDD_OPTIONS 106
+#define IDD_SHOWQR 107
#define IDI_WHATSAPP 203
#define IDI_ADD_GROUP 206
#define IDI_RENAME_GROUP 208
@@ -30,14 +31,15 @@
#define IDC_DEFGROUP 1017
#define IDC_REMOTE_TIME 1018
#define IDC_BUTTON_REQUEST_VOICE_CODE 1019
+#define IDC_QRPIC 1020
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 107
+#define _APS_NEXT_RESOURCE_VALUE 109
#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1020
+#define _APS_NEXT_CONTROL_VALUE 1021
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
diff --git a/protocols/WhatsAppWeb/src/server.cpp b/protocols/WhatsAppWeb/src/server.cpp
new file mode 100644
index 0000000000..8b94cb675c
--- /dev/null
+++ b/protocols/WhatsAppWeb/src/server.cpp
@@ -0,0 +1,151 @@
+/*
+
+WhatsAppWeb plugin for Miranda NG
+Copyright © 2019 George Hazan
+
+*/
+
+#include "stdafx.h"
+
+class CWhatsAppQRDlg : public CProtoDlgBase<WhatsAppProto>
+{
+ QRcode *m_qr;
+
+public:
+ CWhatsAppQRDlg(WhatsAppProto *ppro, const CMStringA &szData) :
+ CProtoDlgBase<WhatsAppProto>(ppro, IDD_SHOWQR)
+ {
+ m_qr = QRcode_encodeString(szData, 0, QR_ECLEVEL_L, QR_MODE_8, 1);
+ }
+
+ ~CWhatsAppQRDlg()
+ {
+ QRcode_free(m_qr);
+ }
+
+ bool OnInitDialog() override
+ {
+ HWND hwndRc = GetDlgItem(m_hwnd, IDC_QRPIC);
+ RECT rc;
+ GetClientRect(hwndRc, &rc);
+
+ ::SetForegroundWindow(m_hwnd);
+
+ int scale = 8; // (rc.bottom - rc.top) / m_qr->width;
+ int rowLen = m_qr->width * scale * 3;
+ if (rowLen % 4)
+ rowLen = (rowLen / 4 + 1) * 4;
+ int dataLen = rowLen * m_qr->width * scale;
+
+ mir_ptr<BYTE> pData((BYTE *)mir_alloc(dataLen));
+ if (pData == nullptr)
+ return false;
+
+ memset(pData, 0xFF, dataLen); // white background by default
+
+ const BYTE *s = m_qr->data;
+ for (int y = 0; y < m_qr->width; y++) {
+ BYTE *d = pData.get() + rowLen * y * scale;
+ for (int x = 0; x < m_qr->width; x++) {
+ if (*s & 1)
+ for (int i = 0; i < scale; i++)
+ for (int j = 0; j < scale; j++) {
+ d[j * 3 + i * rowLen] = 0;
+ d[1 + j * 3 + i * rowLen] = 0;
+ d[2 + j * 3 + i * rowLen] = 0;
+ }
+
+ d += scale * 3;
+ s++;
+ }
+ }
+
+ BITMAPFILEHEADER fih = {};
+ fih.bfType = 0x4d42; // "BM"
+ fih.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dataLen;
+ fih.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
+
+ BITMAPINFOHEADER bih = {};
+ bih.biSize = sizeof(BITMAPINFOHEADER);
+ bih.biWidth = m_qr->width * scale;
+ bih.biHeight = -bih.biWidth;
+ bih.biPlanes = 1;
+ bih.biBitCount = 24;
+ bih.biCompression = BI_RGB;
+
+ wchar_t wszTempPath[MAX_PATH], wszTempFile[MAX_PATH];
+ GetTempPathW(_countof(wszTempPath), wszTempPath);
+ GetTempFileNameW(wszTempPath, L"wa_", TRUE, wszTempFile);
+ FILE *f = _wfopen(wszTempFile, L"wb");
+ fwrite(&fih, sizeof(BITMAPFILEHEADER), 1, f);
+ fwrite(&bih, sizeof(BITMAPINFOHEADER), 1, f);
+ fwrite(pData, sizeof(unsigned char), dataLen, f);
+ fclose(f);
+
+ SendMessage(hwndRc, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)Image_Load(wszTempFile));
+
+ DeleteFileW(wszTempFile);
+ return true;
+ }
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static int random_func(uint8_t *pData, size_t size, void *)
+{
+ Utils_GetRandom(pData, size);
+ return 0;
+}
+
+bool WhatsAppProto::ShowQrCode()
+{
+ CMStringA szPubKey(getMStringA(DBKEY_PUBKEY));
+ if (szPubKey.IsEmpty()) {
+ // generate new pair of private & public keys for this account
+ signal_context *pTmpCtx;
+ signal_context_create(&pTmpCtx, nullptr);
+
+ signal_crypto_provider prov;
+ memset(&prov, 0xFF, sizeof(prov));
+ prov.random_func = random_func;
+ signal_context_set_crypto_provider(pTmpCtx, &prov);
+
+ ec_key_pair *pKeys;
+ if (curve_generate_key_pair(pTmpCtx, &pKeys)) {
+ signal_context_destroy(pTmpCtx);
+ return false;
+ }
+
+ auto *pPubKey = ec_key_pair_get_public(pKeys);
+ signal_buffer *pBuf;
+ ec_public_key_serialize(&pBuf, pPubKey);
+ szPubKey = ptrA(mir_base64_encode(&pBuf->data, pBuf->len));
+ signal_buffer_free(pBuf);
+ setString(DBKEY_PUBKEY, szPubKey);
+
+ auto *pPrivKey = ec_key_pair_get_private(pKeys);
+ ec_private_key_serialize(&pBuf, pPrivKey);
+ CMStringA szPrivKey(ptrA(mir_base64_encode(&pBuf->data, pBuf->len)));
+ signal_buffer_free(pBuf);
+ setString(DBKEY_PRIVATEKEY, szPrivKey);
+ }
+
+ CMStringA szQrData(FORMAT, "%s,%s,%s", m_szJid.c_str(), szPubKey.c_str(), m_szClientId.c_str());
+ CWhatsAppQRDlg(this, szQrData).DoModal();
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void WhatsAppProto::ServerThread(void *)
+{
+ m_pConn = new WAConnection();
+
+ ptrA szClientToken(getStringA(DBKEY_CLIENT_SECRET));
+ if (szClientToken == nullptr) {
+ if (!ShowQrCode()) {
+ delete m_pConn;
+ return;
+ }
+ }
+} \ No newline at end of file
diff --git a/protocols/WhatsAppWeb/src/stdafx.cxx b/protocols/WhatsAppWeb/src/stdafx.cxx
index 115d277c7a..46e6a71904 100644
--- a/protocols/WhatsAppWeb/src/stdafx.cxx
+++ b/protocols/WhatsAppWeb/src/stdafx.cxx
@@ -1,8 +1,8 @@
-// stdafx.cpp : Quelldatei, die nur die Standard-Includes einbindet.
-// WhatsAPI++.pch ist der vorkompilierte Header.
-// stdafx.obj enthдlt die vorkompilierten Typinformationen.
+/*
-#include "stdafx.h"
+WhatsAppWeb plugin for Miranda NG
+Copyright © 2019 George Hazan
+
+*/
-// TODO: Auf zusдtzliche Header verweisen, die in STDAFX.H
-// und nicht in dieser Datei erforderlich sind.
+#include "stdafx.h"
diff --git a/protocols/WhatsAppWeb/src/stdafx.h b/protocols/WhatsAppWeb/src/stdafx.h
index 1f3834b9bc..ee6c6a1156 100644
--- a/protocols/WhatsAppWeb/src/stdafx.h
+++ b/protocols/WhatsAppWeb/src/stdafx.h
@@ -1,14 +1,12 @@
/*
-WhatsApp plugin for Miranda NG
-Copyright © 2013-14 Uli Hecht
+WhatsAppWeb plugin for Miranda NG
+Copyright © 2019 George Hazan
*/
#pragma once
-//#pragma warning(push)
-//#pragma warning(disable:4312)
#pragma warning(disable:4996)
#pragma warning(disable:4290)
@@ -43,5 +41,20 @@ Copyright © 2013-14 Uli Hecht
#include <m_json.h>
#include <m_gui.h>
+#include <openssl/evp.h>
+
+#include "../../libs/libqrencode/src/qrencode.h"
+#include "../../libs/libsignal/src/curve.h"
+#include "../../libs/libsignal/src/signal_protocol.h"
+
+struct signal_buffer
+{
+ size_t len;
+ uint8_t data[];
+};
+
#include "db.h"
#include "proto.h"
+#include "resource.h"
+
+#pragma comment(lib, "libeay32.lib") \ No newline at end of file
diff --git a/protocols/WhatsAppWeb/src/version.h b/protocols/WhatsAppWeb/src/version.h
index 2aa4528fd5..4f09c6c183 100644
--- a/protocols/WhatsAppWeb/src/version.h
+++ b/protocols/WhatsAppWeb/src/version.h
@@ -6,7 +6,7 @@
#include <stdver.h>
#define __PLUGIN_NAME "WhatsAppWeb protocol"
-#define __FILENAME "WhatsApp.dll"
+#define __FILENAME "WhatsAppWeb.dll"
#define __DESCRIPTION "WhatsApp Web protocol support for Miranda NG."
#define __AUTHOR "George Hazan"
#define __AUTHOREMAIL ""